Fixed sensor timestamp calculation for third-party PS5 controllers (cherry picked from commit 7059a55ccca04b75145c3d23a317fbe1eb77039e) (cherry picked from commit fff3c2573a46b685f73646dc01937a88c35b3be6)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c
index 081c126..48b6b99 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps5.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps5.c
@@ -102,7 +102,7 @@ typedef struct
Uint8 rgucAccelX[2]; /* 21 */
Uint8 rgucAccelY[2]; /* 23 */
Uint8 rgucAccelZ[2]; /* 25 */
- Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
+ Uint8 rgucSensorTimestamp[2]; /* 27 - 16/32 bit little endian */
} PS5StatePacketCommon_t;
@@ -154,7 +154,9 @@ typedef struct
Uint8 rgucAccelX[2]; /* 21 */
Uint8 rgucAccelY[2]; /* 23 */
Uint8 rgucAccelZ[2]; /* 25 */
- Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
+ Uint8 rgucSensorTimestamp[2]; /* 27 - 16 bit little endian */
+ Uint8 ucBatteryLevel; /* 29 */
+ Uint8 ucUnknown; /* 30 */
Uint8 ucTouchpadCounter1; /* 31 - high bit clear + counter */
Uint8 rgucTouchpadData1[3]; /* 32 - X/Y, 12 bits per axis */
Uint8 ucTouchpadCounter2; /* 35 - high bit clear + counter */
@@ -1229,27 +1231,50 @@ static void HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
if (ctx->report_sensors) {
- Uint32 timestamp;
- Uint64 timestamp_us;
float data[3];
+ Uint64 timestamp_us;
+
+ if (ctx->use_alternate_report) {
+ /* 16-bit timestamp */
+ Uint16 timestamp;
- timestamp = LOAD32(packet->rgucSensorTimestamp[0],
- packet->rgucSensorTimestamp[1],
- packet->rgucSensorTimestamp[2],
- packet->rgucSensorTimestamp[3]);
- if (ctx->timestamp) {
- Uint32 delta;
+ timestamp = LOAD16(packet->rgucSensorTimestamp[0],
+ packet->rgucSensorTimestamp[1]);
+ if (ctx->timestamp) {
+ Uint16 delta;
- if (ctx->last_timestamp > timestamp) {
- delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1);
+ if (ctx->last_timestamp > timestamp) {
+ delta = (SDL_MAX_UINT16 - ctx->last_timestamp + timestamp + 1);
+ } else {
+ delta = (timestamp - ctx->last_timestamp);
+ }
+ ctx->timestamp += delta;
} else {
- delta = (timestamp - ctx->last_timestamp);
+ ctx->timestamp = timestamp;
}
- ctx->timestamp += delta;
+ ctx->last_timestamp = timestamp;
} else {
- ctx->timestamp = timestamp;
+ /* 32-bit timestamp */
+ Uint32 timestamp;
+
+ timestamp = LOAD32(packet->rgucSensorTimestamp[0],
+ packet->rgucSensorTimestamp[1],
+ packet->rgucSensorTimestamp[2],
+ packet->rgucSensorTimestamp[3]);
+ if (ctx->timestamp) {
+ Uint32 delta;
+
+ if (ctx->last_timestamp > timestamp) {
+ delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1);
+ } else {
+ delta = (timestamp - ctx->last_timestamp);
+ }
+ ctx->timestamp += delta;
+ } else {
+ ctx->timestamp = timestamp;
+ }
+ ctx->last_timestamp = timestamp;
}
- ctx->last_timestamp = timestamp;
/* Sensor timestamp is in 0.33us units */
timestamp_us = ctx->timestamp / 3;