From 7059a55ccca04b75145c3d23a317fbe1eb77039e Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 18 Sep 2023 11:50:56 -0700
Subject: [PATCH] Fixed sensor timestamp calculation for third-party PS5
controllers
---
src/joystick/hidapi/SDL_hidapi_ps5.c | 36 +++++++++++++++++++---------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c
index 16394ebb0e4b..e12397010a7e 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 */
@@ -1308,22 +1310,34 @@ static void HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL
SDL_SendJoystickAxis(timestamp, joystick, SDL_GAMEPAD_AXIS_RIGHTY, axis);
if (ctx->report_sensors) {
- Uint32 tick;
Uint32 delta;
Uint64 sensor_timestamp;
float data[3];
- tick = LOAD32(packet->rgucSensorTimestamp[0],
- packet->rgucSensorTimestamp[1],
- packet->rgucSensorTimestamp[2],
- packet->rgucSensorTimestamp[3]);
- if (ctx->last_tick < tick) {
- delta = (tick - ctx->last_tick);
+ if (ctx->use_alternate_report) {
+ /* 16-bit timestamp */
+ Uint16 tick = LOAD16(packet->rgucSensorTimestamp[0],
+ packet->rgucSensorTimestamp[1]);
+ if (ctx->last_tick < tick) {
+ delta = (tick - ctx->last_tick);
+ } else {
+ delta = (SDL_MAX_UINT16 - ctx->last_tick + tick + 1);
+ }
+ ctx->last_tick = tick;
} else {
- delta = (SDL_MAX_UINT32 - ctx->last_tick + tick + 1);
+ /* 32-bit timestamp */
+ Uint32 tick = LOAD32(packet->rgucSensorTimestamp[0],
+ packet->rgucSensorTimestamp[1],
+ packet->rgucSensorTimestamp[2],
+ packet->rgucSensorTimestamp[3]);
+ if (ctx->last_tick < tick) {
+ delta = (tick - ctx->last_tick);
+ } else {
+ delta = (SDL_MAX_UINT32 - ctx->last_tick + tick + 1);
+ }
+ ctx->last_tick = tick;
}
ctx->sensor_ticks += delta;
- ctx->last_tick = tick;
/* Sensor timestamp is in 0.33us units */
sensor_timestamp = (ctx->sensor_ticks * SDL_NS_PER_US) / 3;