From b2c3237b751b93eacc1de8dc847f29de15d2fc32 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 30 Aug 2022 14:14:38 -0700 Subject: [PATCH] Added support for the Kinvoca Joy-Cons These report their VID/PID as a Nintendo Switch Pro controller, but they are actually left/right Joy-Cons. We'll fix up the joystick GUID so applications can handle them appropriately. --- src/joystick/hidapi/SDL_hidapi_switch.c | 15 +++++++++------ src/joystick/hidapi/SDL_hidapijoystick.c | 12 ++++++++---- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 524b45f20..3b2c00366 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -1181,19 +1181,23 @@ ReadJoyConControllerType(SDL_HIDAPI_Device *device) } static void -UpdateDeviceName(SDL_HIDAPI_Device *device, ESwitchDeviceInfoControllerType eControllerType) +UpdateDeviceIdentity(SDL_HIDAPI_Device *device) { + ESwitchDeviceInfoControllerType eControllerType = (ESwitchDeviceInfoControllerType)device->guid.data[15]; const char *name = NULL; switch (eControllerType) { case k_eSwitchDeviceInfoControllerType_JoyConLeft: name = "Nintendo Switch Joy-Con (L)"; + SDL_SetJoystickGUIDProduct(&device->guid, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT); break; case k_eSwitchDeviceInfoControllerType_JoyConRight: name = "Nintendo Switch Joy-Con (R)"; + SDL_SetJoystickGUIDProduct(&device->guid, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT); break; case k_eSwitchDeviceInfoControllerType_ProController: name = "Nintendo Switch Pro Controller"; + SDL_SetJoystickGUIDProduct(&device->guid, USB_PRODUCT_NINTENDO_SWITCH_PRO); break; case k_eSwitchDeviceInfoControllerType_NESLeft: name = "Nintendo NES Controller (L)"; @@ -1203,12 +1207,15 @@ UpdateDeviceName(SDL_HIDAPI_Device *device, ESwitchDeviceInfoControllerType eCon break; case k_eSwitchDeviceInfoControllerType_SNES: name = "Nintendo SNES Controller"; + SDL_SetJoystickGUIDProduct(&device->guid, USB_PRODUCT_NINTENDO_SNES_CONTROLLER); break; case k_eSwitchDeviceInfoControllerType_N64: name = "Nintendo N64 Controller"; + device->product_id = USB_PRODUCT_NINTENDO_N64_CONTROLLER; break; case k_eSwitchDeviceInfoControllerType_SEGA_Genesis: name = "Nintendo SEGA Genesis Controller"; + SDL_SetJoystickGUIDProduct(&device->guid, USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER); break; default: break; @@ -1231,21 +1238,17 @@ HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device) /* This might be a Joy-Con that's missing from a charging grip slot */ if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) { if (device->interface_number == 1) { - SDL_free(device->name); - device->name = SDL_strdup("Nintendo Switch Joy-Con (L)"); device->guid.data[15] = k_eSwitchDeviceInfoControllerType_JoyConLeft; } else { - SDL_free(device->name); - device->name = SDL_strdup("Nintendo Switch Joy-Con (R)"); device->guid.data[15] = k_eSwitchDeviceInfoControllerType_JoyConRight; } } break; default: - UpdateDeviceName(device, eControllerType); device->guid.data[15] = eControllerType; break; } + UpdateDeviceIdentity(device); } return HIDAPI_JoystickConnected(device, NULL); } diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 275db1734..ebe666d32 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -712,6 +712,8 @@ HIDAPI_CreateCombinedJoyCons() } for (device = SDL_HIDAPI_devices; device; device = device->next) { + Uint16 vendor, product; + if (!device->driver) { /* Unsupported device */ continue; @@ -721,15 +723,17 @@ HIDAPI_CreateCombinedJoyCons() continue; } + SDL_GetJoystickGUIDInfo(device->guid, &vendor, &product, NULL, NULL); + if (!joycons[0] && - (SDL_IsJoystickNintendoSwitchJoyConLeft(device->vendor_id, device->product_id) || - (SDL_IsJoystickNintendoSwitchJoyConGrip(device->vendor_id, device->product_id) && + (SDL_IsJoystickNintendoSwitchJoyConLeft(vendor, product) || + (SDL_IsJoystickNintendoSwitchJoyConGrip(vendor, product) && SDL_strstr(device->name, "(L)") != NULL))) { joycons[0] = device; } if (!joycons[1] && - (SDL_IsJoystickNintendoSwitchJoyConRight(device->vendor_id, device->product_id) || - (SDL_IsJoystickNintendoSwitchJoyConGrip(device->vendor_id, device->product_id) && + (SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product) || + (SDL_IsJoystickNintendoSwitchJoyConGrip(vendor, product) && SDL_strstr(device->name, "(R)") != NULL))) { joycons[1] = device; }