Added support for the Nintendo Switch Joy-Con Charging Grip
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index 626f691..3c782a1 100644
--- a/src/joystick/SDL_gamecontroller.c
+++ b/src/joystick/SDL_gamecontroller.c
@@ -594,7 +594,8 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) {
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,", sizeof(mapping_string));
} else if (SDL_IsJoystickNintendoSwitchJoyConLeft(vendor, product) ||
- SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product)) {
+ SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product) ||
+ SDL_IsJoystickNintendoSwitchJoyConGrip(vendor, product)) {
switch (guid.data[15]) {
case 9:
case 10:
@@ -619,6 +620,9 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
} else if (SDL_IsJoystickSteamController(vendor, product)) {
/* Steam controllers have 2 back paddle buttons */
SDL_strlcat(mapping_string, "paddle1:b16,paddle2:b15,", sizeof(mapping_string));
+ } else if (SDL_IsJoystickNintendoSwitchJoyConPair(vendor, product)) {
+ /* The Nintendo Switch Joy-Con combined controller has a share button */
+ SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string));
} else {
switch (SDL_GetJoystickGameControllerTypeFromGUID(guid, NULL)) {
case SDL_CONTROLLER_TYPE_PS4:
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index d6f7e0c..931aa9e 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -2110,9 +2110,7 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id)
{
EControllerType eType = GuessControllerType(vendor_id, product_id);
return (eType == k_eControllerType_SwitchProController ||
- eType == k_eControllerType_SwitchInputOnlyController ||
- eType == k_eControllerType_SwitchJoyConPair ||
- (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP));
+ eType == k_eControllerType_SwitchInputOnlyController);
}
SDL_bool
@@ -2145,6 +2143,18 @@ SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 product_id)
}
SDL_bool
+SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id)
+{
+ return (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP);
+}
+
+SDL_bool
+SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id)
+{
+ return (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_PAIR);
+}
+
+SDL_bool
SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id)
{
EControllerType eType = GuessControllerType(vendor_id, product_id);
diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h
index 0e50758..db630c8 100644
--- a/src/joystick/SDL_joystick_c.h
+++ b/src/joystick/SDL_joystick_c.h
@@ -90,6 +90,8 @@ extern SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint1
extern SDL_bool SDL_IsJoystickNintendoSwitchJoyCon(Uint16 vendor_id, Uint16 product_id);
extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConLeft(Uint16 vendor_id, Uint16 product_id);
extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 product_id);
+extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id);
+extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick is a Steam Controller */
extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id);
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index d1271f1..4ff8eca 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -384,7 +384,8 @@ HIDAPI_DriverJoyCons_IsSupportedDevice(const char *name, SDL_GameControllerType
{
if (vendor_id == USB_VENDOR_NINTENDO) {
if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT ||
- product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) {
+ product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT ||
+ product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
return SDL_TRUE;
}
}
@@ -410,11 +411,6 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t
return SDL_FALSE;
}
- if (vendor_id == USB_VENDOR_NINTENDO) {
- if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
- return SDL_TRUE;
- }
- }
return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ? SDL_TRUE : SDL_FALSE;
}
@@ -1101,9 +1097,20 @@ HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
{
/* The NES controllers need additional fix up, since we can't detect them without opening the device */
if (device->vendor_id == USB_VENDOR_NINTENDO &&
- device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) {
+ (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT ||
+ device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP)) {
ESwitchDeviceInfoControllerType eControllerType = ReadJoyConControllerType(device);
switch (eControllerType) {
+ case k_eSwitchDeviceInfoControllerType_JoyConLeft:
+ SDL_free(device->name);
+ device->name = SDL_strdup("Nintendo Switch Joy-Con (L)");
+ device->guid.data[15] = eControllerType;
+ break;
+ case k_eSwitchDeviceInfoControllerType_JoyConRight:
+ SDL_free(device->name);
+ device->name = SDL_strdup("Nintendo Switch Joy-Con (R)");
+ device->guid.data[15] = eControllerType;
+ break;
case k_eSwitchDeviceInfoControllerType_NESLeft:
SDL_free(device->name);
device->name = SDL_strdup("NES Controller (L)");
@@ -1114,6 +1121,19 @@ HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
device->name = SDL_strdup("NES Controller (R)");
device->guid.data[15] = eControllerType;
break;
+ case k_eSwitchDeviceInfoControllerType_Unknown:
+ if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_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:
break;
}
@@ -1930,7 +1950,8 @@ HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
}
}
- if (!ctx->m_bInputOnly && !ctx->m_bUsingBluetooth) {
+ if (!ctx->m_bInputOnly && !ctx->m_bUsingBluetooth &&
+ ctx->device->product_id != USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP) {
const Uint32 INPUT_WAIT_TIMEOUT_MS = 100;
if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) {
/* Steam may have put the controller back into non-reporting mode */
diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index 188dac0..4a9b80f 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -746,10 +746,16 @@ HIDAPI_CreateCombinedJoyCons()
continue;
}
- if (!joycons[0] && SDL_IsJoystickNintendoSwitchJoyConLeft(device->vendor_id, device->product_id)) {
+ if (!joycons[0] &&
+ (SDL_IsJoystickNintendoSwitchJoyConLeft(device->vendor_id, device->product_id) ||
+ (SDL_IsJoystickNintendoSwitchJoyConGrip(device->vendor_id, device->product_id) &&
+ SDL_strstr(device->name, "(L)") != NULL))) {
joycons[0] = device;
}
- if (!joycons[1] && SDL_IsJoystickNintendoSwitchJoyConRight(device->vendor_id, device->product_id)) {
+ if (!joycons[1] &&
+ (SDL_IsJoystickNintendoSwitchJoyConRight(device->vendor_id, device->product_id) ||
+ (SDL_IsJoystickNintendoSwitchJoyConGrip(device->vendor_id, device->product_id) &&
+ SDL_strstr(device->name, "(R)") != NULL))) {
joycons[1] = device;
}
if (joycons[0] && joycons[1]) {