From d48f9c4af4dcba7b97e7db031ddb815b6627da75 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 3 May 2023 09:47:16 -0700
Subject: [PATCH] Added support for the Saitek Cyborg V.3 Rumble Pad in PS3
mode
(cherry picked from commit b6ca3602289aa2b0c34856f31e0214d924bda2c9)
(cherry picked from commit e2f597de84be93351c22850f3cd78a7646756e98)
---
src/joystick/hidapi/SDL_hidapi_ps3.c | 93 +++++++++++++++-------------
src/joystick/usb_ids.h | 2 +
2 files changed, 53 insertions(+), 42 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapi_ps3.c b/src/joystick/hidapi/SDL_hidapi_ps3.c
index e9baf7e09ca84..c09909eb9bdbc 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps3.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps3.c
@@ -584,7 +584,8 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_IsSupportedDevice(SDL_HIDAPI_Device *
Uint8 data[USB_PACKET_LENGTH];
int size;
- if (HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) {
+ if ((type == SDL_CONTROLLER_TYPE_PS3 && vendor_id != USB_VENDOR_SONY) ||
+ HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) {
if (device && device->dev) {
size = ReadFeatureReport(device->dev, 0x03, data, sizeof(data));
if (size == 8 && data[2] == 0x26) {
@@ -813,48 +814,56 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(SDL_Joystick *joystic
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
}
- if (ctx->last_state[2] != data[2]) {
- SDL_bool dpad_up = SDL_FALSE;
- SDL_bool dpad_down = SDL_FALSE;
- SDL_bool dpad_left = SDL_FALSE;
- SDL_bool dpad_right = SDL_FALSE;
-
- switch (data[2] & 0x0f) {
- case 0:
- dpad_up = SDL_TRUE;
- break;
- case 1:
- dpad_up = SDL_TRUE;
- dpad_right = SDL_TRUE;
- break;
- case 2:
- dpad_right = SDL_TRUE;
- break;
- case 3:
- dpad_right = SDL_TRUE;
- dpad_down = SDL_TRUE;
- break;
- case 4:
- dpad_down = SDL_TRUE;
- break;
- case 5:
- dpad_left = SDL_TRUE;
- dpad_down = SDL_TRUE;
- break;
- case 6:
- dpad_left = SDL_TRUE;
- break;
- case 7:
- dpad_up = SDL_TRUE;
- dpad_left = SDL_TRUE;
- break;
- default:
- break;
+ if (ctx->device->vendor_id == USB_VENDOR_SAITEK && ctx->device->product_id == USB_PRODUCT_SAITEK_CYBORG_V3) {
+ /* Cyborg V.3 Rumble Pad doesn't set the dpad bits as expected, so use the axes instead */
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, data[10] ? SDL_PRESSED : SDL_RELEASED);
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, data[9] ? SDL_PRESSED : SDL_RELEASED);
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, data[7] ? SDL_PRESSED : SDL_RELEASED);
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, data[8] ? SDL_PRESSED : SDL_RELEASED);
+ } else {
+ if (ctx->last_state[2] != data[2]) {
+ SDL_bool dpad_up = SDL_FALSE;
+ SDL_bool dpad_down = SDL_FALSE;
+ SDL_bool dpad_left = SDL_FALSE;
+ SDL_bool dpad_right = SDL_FALSE;
+
+ switch (data[2] & 0x0f) {
+ case 0:
+ dpad_up = SDL_TRUE;
+ break;
+ case 1:
+ dpad_up = SDL_TRUE;
+ dpad_right = SDL_TRUE;
+ break;
+ case 2:
+ dpad_right = SDL_TRUE;
+ break;
+ case 3:
+ dpad_right = SDL_TRUE;
+ dpad_down = SDL_TRUE;
+ break;
+ case 4:
+ dpad_down = SDL_TRUE;
+ break;
+ case 5:
+ dpad_left = SDL_TRUE;
+ dpad_down = SDL_TRUE;
+ break;
+ case 6:
+ dpad_left = SDL_TRUE;
+ break;
+ case 7:
+ dpad_up = SDL_TRUE;
+ dpad_left = SDL_TRUE;
+ break;
+ default:
+ break;
+ }
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
+ SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
}
- SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down);
- SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up);
- SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right);
- SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left);
}
axis = ((int)data[17] * 257) - 32768;
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index ef6cdb843dc31..9cdcfa68ad7da 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -47,6 +47,7 @@
#define USB_VENDOR_POWERA_ALT 0x20d6
#define USB_VENDOR_QANBA 0x2c22
#define USB_VENDOR_RAZER 0x1532
+#define USB_VENDOR_SAITEK 0x06a3
#define USB_VENDOR_SHANWAN 0x2563
#define USB_VENDOR_SHANWAN_ALT 0x20bc
#define USB_VENDOR_SONY 0x054c
@@ -104,6 +105,7 @@
#define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRELESS 0x100c
#define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRED 0x1010
#define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRELESS 0x1011
+#define USB_PRODUCT_SAITEK_CYBORG_V3 0xf622
#define USB_PRODUCT_SHANWAN_DS3 0x0523
#define USB_PRODUCT_SONY_DS3 0x0268
#define USB_PRODUCT_SONY_DS4 0x05c4