SDL: Added support for the Kinvoca Joy-Cons

From b2c3237b751b93eacc1de8dc847f29de15d2fc32 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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 524b45f201d..3b2c0036655 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 275db1734f7..ebe666d32ff 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;
         }