From afd100f02b7689e3b1cf441f7abf40f0313f328b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 18 Jun 2021 17:37:46 -0700 Subject: [PATCH] Added support for the PowerA Fusion Pro 2 and the PDP Xbox Series X Afterglow and Blue controllers --- src/joystick/SDL_gamecontroller.c | 4 +-- src/joystick/SDL_gamecontrollerdb.h | 4 +-- src/joystick/SDL_joystick.c | 39 ++++++++++++++---------- src/joystick/SDL_joystick_c.h | 4 +-- src/joystick/controller_type.h | 9 ++++-- src/joystick/hidapi/SDL_hidapi_xboxone.c | 4 +-- src/joystick/usb_ids.h | 11 ++++--- 7 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 708afe80b..8829c77d6 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -590,8 +590,8 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI /* All other controllers have the standard set of 19 buttons and 6 axes */ SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string)); - if (SDL_IsJoystickXboxOneSeriesX(vendor, product)) { - /* XBox One Series X Controllers have a share button under the guide button */ + if (SDL_IsJoystickXboxSeriesX(vendor, product)) { + /* XBox Series X Controllers have a share button under the guide button */ SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); } else if (SDL_IsJoystickXboxOneElite(vendor, product)) { /* XBox One Elite Controllers have 4 back paddle buttons */ diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 6e9d667e6..035745f64 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -834,8 +834,8 @@ static const char *s_ControllerMappings [] = "050000005e040000e002000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005e040000ea02000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", - "050000005e040000120b000000783f00,Xbox One Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", - "050000005e040000130b0000ffff3f00,Xbox One Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e040000120b000000783f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", + "050000005e040000130b0000ffff3f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,", "050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", /* The DPAD doesn't seem to work on this controller on Android TV? */ diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 5868d00f3..ab62d7640 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1732,6 +1732,17 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c } } + /* Perform any manufacturer replacements */ + for (i = 0; i < SDL_arraysize(replacements); ++i) { + size_t prefixlen = SDL_strlen(replacements[i].prefix); + if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) { + size_t replacementlen = SDL_strlen(replacements[i].replacement); + SDL_memcpy(name, replacements[i].replacement, replacementlen); + SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1)); + break; + } + } + /* Remove duplicate manufacturer or product in the name */ for (i = 1; i < (len - 1); ++i) { int matchlen = PrefixMatch(name, &name[i]); @@ -1746,17 +1757,6 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c } } - /* Perform any manufacturer replacements */ - for (i = 0; i < SDL_arraysize(replacements); ++i) { - size_t prefixlen = SDL_strlen(replacements[i].prefix); - if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) { - size_t replacementlen = SDL_strlen(replacements[i].replacement); - SDL_memcpy(name, replacements[i].replacement, replacementlen); - SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1)); - break; - } - } - return name; } @@ -1927,16 +1927,23 @@ SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id) } SDL_bool -SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id) +SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id) { if (vendor_id == USB_VENDOR_MICROSOFT) { - if (product_id == USB_PRODUCT_XBOX_ONE_SERIES_X || - product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) { + if (product_id == USB_PRODUCT_XBOX_SERIES_X || + product_id == USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_PDP) { + if (product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW || + product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE) { return SDL_TRUE; } } if (vendor_id == USB_VENDOR_POWERA_ALT) { - if (product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_POWERA) { + if (product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA || + product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2) { return SDL_TRUE; } } @@ -1950,7 +1957,7 @@ SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id) if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH || product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH || product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH || - product_id == USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH) { + product_id == USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH) { return SDL_TRUE; } } diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 8e634ac38..6db09a60c 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -65,8 +65,8 @@ extern SDL_GameControllerType SDL_GetJoystickGameControllerType(const char *name /* Function to return whether a joystick is an Xbox One Elite controller */ extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id); -/* Function to return whether a joystick is an Xbox One Series X controller */ -extern SDL_bool SDL_IsJoystickXboxOneSeriesX(Uint16 vendor_id, Uint16 product_id); +/* Function to return whether a joystick is an Xbox Series X controller */ +extern SDL_bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id); /* Function to return whether a joystick is an Xbox One controller connected via Bluetooth */ extern SDL_bool SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id); diff --git a/src/joystick/controller_type.h b/src/joystick/controller_type.h index d9c73cd43..531bc29bc 100644 --- a/src/joystick/controller_type.h +++ b/src/joystick/controller_type.h @@ -325,8 +325,8 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, NULL }, // Microsoft X-Box One controller with XBOXGIP driver on Windows { MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad { MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth) - { MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Series X pad - { MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox One Series X Controller" }, // Microsoft X-Box One Series X pad (Bluetooth) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad + { MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad (Bluetooth) { MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2 { MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One @@ -392,6 +392,8 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d5 ), k_eControllerType_XBoxOneController, "PDP Xbox One Red Camo" }, // PDP Wired Controller for Xbox One - Red Camo { MAKE_CONTROLLER_ID( 0x0e6f, 0x0346 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x0446 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02da ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Afterglow" }, // PDP Xbox Series X Afterglow + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d9 ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Midnight Blue" }, // PDP Xbox Series X Midnight Blue { MAKE_CONTROLLER_ID( 0x0f0d, 0x0063 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro Hayabusa (USA) Xbox One { MAKE_CONTROLLER_ID( 0x0f0d, 0x0067 ), k_eControllerType_XBoxOneController, NULL }, // HORIPAD ONE { MAKE_CONTROLLER_ID( 0x0f0d, 0x0078 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro V Kai Xbox One @@ -399,7 +401,8 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1532, 0x0a00 ), k_eControllerType_XBoxOneController, NULL }, // Razer Atrox Arcade Stick { MAKE_CONTROLLER_ID( 0x1532, 0x0a03 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wildcat { MAKE_CONTROLLER_ID( 0x1532, 0x0a14 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Ultimate - { MAKE_CONTROLLER_ID( 0x20d6, 0x2001 ), k_eControllerType_XBoxOneController, "PowerA Xbox One Series X Controller" }, // PowerA Xbox One Series X Wired Controller + { MAKE_CONTROLLER_ID( 0x20d6, 0x2001 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller + { MAKE_CONTROLLER_ID( 0x20d6, 0x4001 ), k_eControllerType_XBoxOneController, "PowerA Fusion Pro 2 Controller" }, // PowerA Fusion Pro 2 Wired Controller (Xbox Series X style) { MAKE_CONTROLLER_ID( 0x24c6, 0x541a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Xbox One Mini Wired Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x542a ), k_eControllerType_XBoxOneController, NULL }, // Xbox ONE spectra { MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController, "PowerA Xbox One Controller" }, // PowerA Xbox ONE liquid metal controller diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 3b6597926..12d78078c 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -145,7 +145,7 @@ ControllerHasTriggerRumble(Uint16 vendor_id, Uint16 product_id) static SDL_bool ControllerHasShareButton(Uint16 vendor_id, Uint16 product_id) { - return SDL_IsJoystickXboxOneSeriesX(vendor_id, product_id); + return SDL_IsJoystickXboxSeriesX(vendor_id, product_id); } static void @@ -618,7 +618,7 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons16(SDL_Joystick *joystick, SDL_Driver * Xbox One S with firmware 4.8.1923 uses a 17 byte packet with BACK button in byte 16 and the GUIDE button in a separate packet (on Windows), or in byte 15 (on Linux) * Xbox One Elite Series 2 with firmware 4.7.1872 uses a 55 byte packet with BACK button in byte 16, paddles starting at byte 33, and the GUIDE button in a separate packet * Xbox One Elite Series 2 with firmware 4.8.1908 uses a 33 byte packet with BACK button in byte 16, paddles starting at byte 17, and the GUIDE button in a separate packet - * Xbox One Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17 + * Xbox Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17 */ static void HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h index b823f1b2d..b7e0b6809 100644 --- a/src/joystick/usb_ids.h +++ b/src/joystick/usb_ids.h @@ -31,8 +31,8 @@ #define USB_VENDOR_NINTENDO 0x057e #define USB_VENDOR_NVIDIA 0x0955 #define USB_VENDOR_PDP 0x0e6f -#define USB_VENDOR_POWERA_ALT 0x20d6 #define USB_VENDOR_POWERA 0x24c6 +#define USB_VENDOR_POWERA_ALT 0x20d6 #define USB_VENDOR_RAZER 0x1532 #define USB_VENDOR_SHENZHEN 0x0079 #define USB_VENDOR_SONY 0x054c @@ -59,9 +59,12 @@ #define USB_PRODUCT_XBOX_ONE_S 0x02ea #define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0 #define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd -#define USB_PRODUCT_XBOX_ONE_SERIES_X 0x0b12 -#define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH 0x0b13 -#define USB_PRODUCT_XBOX_ONE_SERIES_X_POWERA 0x2001 +#define USB_PRODUCT_XBOX_SERIES_X 0x0b12 +#define USB_PRODUCT_XBOX_SERIES_X_BLUETOOTH 0x0b13 +#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da +#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9 +#define USB_PRODUCT_XBOX_SERIES_X_POWERA 0x2001 +#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001 #define USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER 0x02ff /* XBOXGIP driver software PID */ #define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER 0x02fe /* Made up product ID for XInput */