From 948196448fced68629eca0f134516df00d185934 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 19 Aug 2024 16:30:04 -0700
Subject: [PATCH] Added support for the Retro-bit Controller in PS3 mode
Fixes https://github.com/libsdl-org/SDL/issues/10557
(cherry picked from commit e75175129f83c3d1e85572d03ec070177de8abc4)
(cherry picked from commit 0de601dc64d28d8e00b0bf98f1b198058386fc25)
---
src/joystick/controller_list.h | 2 +-
src/joystick/hidapi/SDL_hidapi_ps3.c | 43 ++++++++++++++++++++++------
src/joystick/usb_ids.h | 2 ++
3 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/src/joystick/controller_list.h b/src/joystick/controller_list.h
index fd77b2a9d5a1d..79446c5cae7b5 100644
--- a/src/joystick/controller_list.h
+++ b/src/joystick/controller_list.h
@@ -69,7 +69,7 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x20d6, 0x576d ), k_eControllerType_PS3Controller, NULL }, // Power A PS3
{ MAKE_CONTROLLER_ID( 0x20d6, 0xca6d ), k_eControllerType_PS3Controller, NULL }, // From SDL
{ MAKE_CONTROLLER_ID( 0x2563, 0x0523 ), k_eControllerType_PS3Controller, NULL }, // Digiflip GP006
- { MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller, NULL }, // From SDL
+ { MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller, "Retro-bit Controller" }, // SWITCH CO., LTD. Retro-bit Controller
{ MAKE_CONTROLLER_ID( 0x25f0, 0x83c3 ), k_eControllerType_PS3Controller, NULL }, // gioteck vx2
{ MAKE_CONTROLLER_ID( 0x25f0, 0xc121 ), k_eControllerType_PS3Controller, NULL }, //
{ MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_PS3Controller, NULL }, // Qanba Drone
diff --git a/src/joystick/hidapi/SDL_hidapi_ps3.c b/src/joystick/hidapi/SDL_hidapi_ps3.c
index 1b10e9ffbad8a..fdc21bb9e24d0 100644
--- a/src/joystick/hidapi/SDL_hidapi_ps3.c
+++ b/src/joystick/hidapi/SDL_hidapi_ps3.c
@@ -50,6 +50,7 @@ typedef struct
SDL_HIDAPI_Device *device;
SDL_Joystick *joystick;
SDL_bool is_shanwan;
+ SDL_bool has_analog_buttons;
SDL_bool report_sensors;
SDL_bool effects_updated;
int player_index;
@@ -145,6 +146,7 @@ static SDL_bool HIDAPI_DriverPS3_InitDevice(SDL_HIDAPI_Device *device)
}
ctx->device = device;
ctx->is_shanwan = is_shanwan;
+ ctx->has_analog_buttons = SDL_TRUE;
device->context = ctx;
@@ -247,7 +249,10 @@ static SDL_bool HIDAPI_DriverPS3_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy
/* Initialize the joystick capabilities */
joystick->nbuttons = 15;
- joystick->naxes = 16;
+ joystick->naxes = 6;
+ if (ctx->has_analog_buttons) {
+ joystick->naxes += 10;
+ }
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 100.0f);
@@ -432,7 +437,7 @@ static void HIDAPI_DriverPS3_HandleStatePacket(SDL_Joystick *joystick, SDL_Drive
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
/* Buttons are mapped as axes in the order they appear in the button enumeration */
- {
+ if (ctx->has_analog_buttons) {
static int button_axis_offsets[] = {
24, /* SDL_CONTROLLER_BUTTON_A */
23, /* SDL_CONTROLLER_BUTTON_B */
@@ -617,6 +622,11 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_InitDevice(SDL_HIDAPI_Device *device)
return SDL_FALSE;
}
ctx->device = device;
+ if (device->vendor_id == USB_VENDOR_SWITCH && device->product_id == USB_PRODUCT_SWITCH_RETROBIT_CONTROLLER) {
+ ctx->has_analog_buttons = SDL_FALSE;
+ } else {
+ ctx->has_analog_buttons = SDL_TRUE;
+ }
device->context = ctx;
@@ -650,8 +660,17 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_OpenJoystick(SDL_HIDAPI_Device *devic
/* Initialize the joystick capabilities */
joystick->nbuttons = 15;
- joystick->naxes = 16;
- joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
+ joystick->naxes = 6;
+ if (ctx->has_analog_buttons) {
+ joystick->naxes += 10;
+ }
+
+ if (device->vendor_id == USB_VENDOR_SWITCH && device->product_id == USB_PRODUCT_SWITCH_RETROBIT_CONTROLLER) {
+ // This is a wireless controller using a USB dongle
+ joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
+ } else {
+ joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
+ }
return SDL_TRUE;
}
@@ -762,7 +781,7 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket18(SDL_Joystick *joystic
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
/* Buttons are mapped as axes in the order they appear in the button enumeration */
- {
+ if (ctx->has_analog_buttons) {
static int button_axis_offsets[] = {
12, /* SDL_GAMEPAD_BUTTON_A */
11, /* SDL_GAMEPAD_BUTTON_B */
@@ -871,9 +890,17 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(SDL_Joystick *joystic
}
}
- axis = ((int)data[17] * 257) - 32768;
+ if (data[0] & 0x40) {
+ axis = 32767;
+ } else {
+ axis = ((int)data[17] * 257) - 32768;
+ }
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
- axis = ((int)data[18] * 257) - 32768;
+ if (data[0] & 0x80) {
+ axis = 32767;
+ } else {
+ axis = ((int)data[18] * 257) - 32768;
+ }
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
axis = ((int)data[3] * 257) - 32768;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
@@ -885,7 +912,7 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(SDL_Joystick *joystic
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
/* Buttons are mapped as axes in the order they appear in the button enumeration */
- {
+ if (ctx->has_analog_buttons) {
static int button_axis_offsets[] = {
13, /* SDL_CONTROLLER_BUTTON_A */
12, /* SDL_CONTROLLER_BUTTON_B */
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index d16605751b47d..8e7a4d63f75e9 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -54,6 +54,7 @@
#define USB_VENDOR_SONY 0x054c
#define USB_VENDOR_THRUSTMASTER 0x044f
#define USB_VENDOR_TURTLE_BEACH 0x10f5
+#define USB_VENDOR_SWITCH 0x2563
#define USB_VENDOR_VALVE 0x28de
#define USB_VENDOR_ZEROPLUS 0x0c12
@@ -116,6 +117,7 @@
#define USB_PRODUCT_SONY_DS4_STRIKEPAD 0x05c5
#define USB_PRODUCT_SONY_DS5 0x0ce6
#define USB_PRODUCT_SONY_DS5_EDGE 0x0df2
+#define USB_PRODUCT_SWITCH_RETROBIT_CONTROLLER 0x0575
#define USB_PRODUCT_THRUSTMASTER_ESWAPX_PRO 0xd012
#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_REACT_R 0x7013
#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_RECON 0x7009