Fixed handling simple mode PS4 reports Fixes https://github.com/libsdl-org/SDL/issues/7270 (cherry picked from commit 5925cd4ef377a2211fd057ef6fa9f41141999cb7)
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
diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c
index ab28835..858758e 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps4.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps4.c
@@ -822,7 +822,7 @@ static int HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device,
return 0;
}
-static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet)
+static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet, int size)
{
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
static const float TOUCHPAD_SCALEY = 1.0f / 920; /* This is noted as being 944 resolution, but 920 feels better */
@@ -925,7 +925,7 @@ static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d
axis = ((int)packet->ucRightJoystickY * 257) - 32768;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
- if (ctx->device->is_bluetooth && ctx->official_controller) {
+ if (size > 9 && ctx->device->is_bluetooth && ctx->official_controller) {
if (packet->ucBatteryLevel & 0x10) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
} else {
@@ -943,7 +943,7 @@ static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d
}
}
- if (ctx->report_touchpad) {
+ if (size > 9 && ctx->report_touchpad) {
touchpad_state = !(packet->ucTouchpadCounter1 & 0x80) ? SDL_PRESSED : SDL_RELEASED;
touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8);
touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4);
@@ -955,7 +955,7 @@ static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d
SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f);
}
- if (ctx->report_sensors) {
+ if (size > 9 && ctx->report_sensors) {
Uint16 timestamp;
Uint64 timestamp_us;
float data[3];
@@ -1011,6 +1011,11 @@ static SDL_bool HIDAPI_DriverPS4_IsPacketValid(SDL_DriverPS4_Context *ctx, Uint8
{
switch (data[0]) {
case k_EPS4ReportIdUsbState:
+ if (size == 10) {
+ /* This is non-enhanced mode, this packet is fine */
+ return SDL_TRUE;
+ }
+
/* In the case of a DS4 USB dongle, bit[2] of byte 31 indicates if a DS4 is actually connected (indicated by '0').
* For non-dongle, this bit is always 0 (connected).
* This is usually the ID over USB, but the DS4v2 that started shipping with the PS4 Slim will also send this
@@ -1070,7 +1075,7 @@ static SDL_bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
switch (data[0]) {
case k_EPS4ReportIdUsbState:
- HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[1]);
+ HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[1], size - 1);
break;
case k_EPS4ReportIdBluetoothState1:
case k_EPS4ReportIdBluetoothState2:
@@ -1086,7 +1091,7 @@ static SDL_bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
HIDAPI_DriverPS4_SetEnhancedMode(device, joystick);
}
/* Bluetooth state packets have two additional bytes at the beginning, the first notes if HID is present */
- HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[3]);
+ HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[3], size - 3);
break;
default:
#ifdef DEBUG_JOYSTICK