From 271e03f0d78155303efd454e699a36d71b290012 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 13 Jun 2023 22:20:58 -0700 Subject: [PATCH] Added support for the PowerA Fusion Pro Wireless Controller in Bluetooth mode This controller shows up with a VID/PID of 0, but has full functionality over Bluetooth (cherry picked from commit cdfc0c5a3314e4e0cd5152feddd8950c7eb797f1) --- src/joystick/SDL_gamecontroller.c | 13 +++++++++---- src/joystick/hidapi/SDL_hidapi_nintendo.h | 1 + src/joystick/hidapi/SDL_hidapi_switch.c | 13 +++++++------ src/joystick/hidapi/SDL_hidapijoystick.c | 10 ++++++++-- src/joystick/hidapi/SDL_hidapijoystick_c.h | 2 +- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 2f4235cba..2b35221c3 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -572,10 +572,15 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI /* GameCube driver has 12 buttons and 6 axes */ SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string)); } else if (vendor == USB_VENDOR_NINTENDO && - guid.data[15] != k_eSwitchDeviceInfoControllerType_Unknown && - guid.data[15] != k_eSwitchDeviceInfoControllerType_ProController && - guid.data[15] != k_eWiiExtensionControllerType_Gamepad && - guid.data[15] != k_eWiiExtensionControllerType_WiiUPro) { + (guid.data[15] == k_eSwitchDeviceInfoControllerType_NESLeft || + guid.data[15] == k_eSwitchDeviceInfoControllerType_NESRight || + guid.data[15] == k_eSwitchDeviceInfoControllerType_SNES || + guid.data[15] == k_eSwitchDeviceInfoControllerType_N64 || + guid.data[15] == k_eSwitchDeviceInfoControllerType_SEGA_Genesis || + guid.data[15] == k_eWiiExtensionControllerType_None || + guid.data[15] == k_eWiiExtensionControllerType_Nunchuk || + guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft || + guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConRight)) { switch (guid.data[15]) { case k_eSwitchDeviceInfoControllerType_NESLeft: case k_eSwitchDeviceInfoControllerType_NESRight: diff --git a/src/joystick/hidapi/SDL_hidapi_nintendo.h b/src/joystick/hidapi/SDL_hidapi_nintendo.h index 2cc5c7c77..f0edf970f 100644 --- a/src/joystick/hidapi/SDL_hidapi_nintendo.h +++ b/src/joystick/hidapi/SDL_hidapi_nintendo.h @@ -28,6 +28,7 @@ typedef enum k_eSwitchDeviceInfoControllerType_JoyConLeft = 1, k_eSwitchDeviceInfoControllerType_JoyConRight = 2, k_eSwitchDeviceInfoControllerType_ProController = 3, + k_eSwitchDeviceInfoControllerType_LicProController = 6, k_eSwitchDeviceInfoControllerType_NESLeft = 9, k_eSwitchDeviceInfoControllerType_NESRight = 10, k_eSwitchDeviceInfoControllerType_SNES = 11, diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index eeb1d2aad..3f588f6c3 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -1179,17 +1179,18 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device) switch (ctx->m_eControllerType) { case k_eSwitchDeviceInfoControllerType_JoyConLeft: HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (L)"); - HIDAPI_SetDeviceProduct(device, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT); device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT; break; case k_eSwitchDeviceInfoControllerType_JoyConRight: HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (R)"); - HIDAPI_SetDeviceProduct(device, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT); device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT; break; case k_eSwitchDeviceInfoControllerType_ProController: + case k_eSwitchDeviceInfoControllerType_LicProController: HIDAPI_SetDeviceName(device, "Nintendo Switch Pro Controller"); - HIDAPI_SetDeviceProduct(device, USB_PRODUCT_NINTENDO_SWITCH_PRO); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_PRO); device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; break; case k_eSwitchDeviceInfoControllerType_NESLeft: @@ -1202,17 +1203,17 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device) break; case k_eSwitchDeviceInfoControllerType_SNES: HIDAPI_SetDeviceName(device, "Nintendo SNES Controller"); - HIDAPI_SetDeviceProduct(device, USB_PRODUCT_NINTENDO_SNES_CONTROLLER); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SNES_CONTROLLER); device->type = SDL_CONTROLLER_TYPE_UNKNOWN; break; case k_eSwitchDeviceInfoControllerType_N64: HIDAPI_SetDeviceName(device, "Nintendo N64 Controller"); - HIDAPI_SetDeviceProduct(device, USB_PRODUCT_NINTENDO_N64_CONTROLLER); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_N64_CONTROLLER); device->type = SDL_CONTROLLER_TYPE_UNKNOWN; break; case k_eSwitchDeviceInfoControllerType_SEGA_Genesis: HIDAPI_SetDeviceName(device, "Nintendo SEGA Genesis Controller"); - HIDAPI_SetDeviceProduct(device, USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER); device->type = SDL_CONTROLLER_TYPE_UNKNOWN; break; default: diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index de9443ac6..a552d72bb 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -657,10 +657,16 @@ void HIDAPI_SetDeviceName(SDL_HIDAPI_Device *device, const char *name) } } -void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 product_id) +void HIDAPI_SetDeviceVendor(SDL_HIDAPI_Device *device, Uint16 vendor_id) +{ + /* Don't set the device vendor ID directly, or we'll constantly re-enumerate this device */ + SDL_SetJoystickGUIDVendor(&device->guid, vendor_id); +} + +void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 vendor_id, Uint16 product_id) { /* Don't set the device product ID directly, or we'll constantly re-enumerate this device */ - SDL_SetJoystickGUIDProduct(&device->guid, product_id); + device->guid = SDL_CreateJoystickGUID(device->guid.data[0], vendor_id, product_id, device->version, device->name, 'h', 0); } static void HIDAPI_UpdateJoystickSerial(SDL_HIDAPI_Device *device) diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 2f48aa760..d17203f43 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -152,7 +152,7 @@ extern SDL_GameControllerType HIDAPI_GetGameControllerTypeFromGUID(SDL_JoystickG extern void HIDAPI_UpdateDevices(void); extern void HIDAPI_SetDeviceName(SDL_HIDAPI_Device *device, const char *name); -extern void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 product_id); +extern void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 vendor_id, Uint16 product_id); extern void HIDAPI_SetDeviceSerial(SDL_HIDAPI_Device *device, const char *serial); extern SDL_bool HIDAPI_HasConnectedUSBDevice(const char *serial); extern void HIDAPI_DisconnectBluetoothDevice(const char *serial);