Hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS added so we can recognise a Joy-Con as half a Pro Controller, so we can read its analog input and read its sensors just like we do a Pro Controller.
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
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 8575570..8c0a991 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -685,6 +685,17 @@ extern "C" {
*/
#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH"
+ /**
+ * \brief A variable controlling whether Switch Joy-Cons should be treated the same as Switch Pro Controllers when using the HIDAPI driver.
+ *
+ * This variable can be set to the following values:
+ * "0" - basic Joy-Con support with no analog input (the default)
+ * "1" - Joy-Cons treated as half full Pro Controllers with analog inputs and sensors
+ *
+ * This does not combine Joy-Cons into a single controller. That's up to the user.
+ */
+#define SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS "SDL_JOYSTICK_HIDAPI_JOY_CONS"
+
/**
* \brief A variable controlling whether the HIDAPI driver for XBox controllers should be used.
*
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 1cae14a..67fb10e 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -1888,6 +1888,10 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc
case k_eControllerType_SwitchInputOnlyController:
type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
break;
+ case k_eControllerType_SwitchJoyConLeft:
+ case k_eControllerType_SwitchJoyConRight:
+ type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN;
+ break;
default:
type = SDL_CONTROLLER_TYPE_UNKNOWN;
break;
@@ -1975,6 +1979,28 @@ SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id)
}
SDL_bool
+SDL_IsJoystickNintendoSwitchJoyCon(Uint16 vendor_id, Uint16 product_id)
+{
+ EControllerType eType = GuessControllerType(vendor_id, product_id);
+ return (eType == k_eControllerType_SwitchJoyConLeft ||
+ eType == k_eControllerType_SwitchJoyConRight);
+}
+
+SDL_bool
+SDL_IsJoystickNintendoSwitchJoyConLeft(Uint16 vendor_id, Uint16 product_id)
+{
+ EControllerType eType = GuessControllerType(vendor_id, product_id);
+ return (eType == k_eControllerType_SwitchJoyConLeft);
+}
+
+SDL_bool
+SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 product_id)
+{
+ EControllerType eType = GuessControllerType(vendor_id, product_id);
+ return (eType == k_eControllerType_SwitchJoyConRight);
+}
+
+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 5988364..c724d01 100644
--- a/src/joystick/SDL_joystick_c.h
+++ b/src/joystick/SDL_joystick_c.h
@@ -79,6 +79,9 @@ extern SDL_bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick is a Nintendo Switch Pro controller */
extern SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id);
extern SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id);
+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);
/* 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/controller_type.h b/src/joystick/controller_type.h
index 8887245..7fbed25 100644
--- a/src/joystick/controller_type.h
+++ b/src/joystick/controller_type.h
@@ -522,11 +522,9 @@ static const ControllerDescription_t arrControllers[] = {
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0001 ), k_eControllerType_AppleController, NULL }, // MFI Extended Gamepad (generic entry for iOS/tvOS)
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0002 ), k_eControllerType_AppleController, NULL }, // MFI Standard Gamepad (generic entry for iOS/tvOS)
- // We currently don't support using a pair of Switch Joy-Con's as a single
- // controller and we don't want to support using them individually for the
- // time being, so these should be disabled until one of the above is true
- // { MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left)
- // { MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right)
+ // We now support Joy-Cons if SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS is set to "1", but they won't be combined into one controller.
+ { MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left)
+ { MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right)
// This same controller ID is spoofed by many 3rd-party Switch controllers.
// The ones we currently know of are:
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 920fa67..9102b49 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -322,6 +322,16 @@ static const char *
HIDAPI_DriverSwitch_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
/* Give a user friendly name for this controller */
+ if (vendor_id == USB_VENDOR_NINTENDO) {
+ if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT) {
+ return "Nintendo Switch Joy-Con Left";
+ }
+
+ if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) {
+ return "Nintendo Switch Joy-Con Right";
+ }
+ }
+
return "Nintendo Switch Pro Controller";
}
@@ -840,7 +850,9 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
* level and we only care about battery level over bluetooth anyway.
*/
if (device->vendor_id == USB_VENDOR_NINTENDO &&
- device->product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO) {
+ (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO ||
+ device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT ||
+ device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT)) {
input_mode = k_eSwitchInputReportIDs_FullControllerState;
}
@@ -1358,6 +1370,12 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
data[0] /= -3.f;
data[1] /= 3.f;
data[2] /= -3.f;
+ /* Right Joy-Con flips some axes, so let's flip them back for consistency */
+ if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
+ data[0] = -data[0];
+ data[1] = -data[1];
+ }
+
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, data, 3);
data[0] = HIDAPI_DriverSwitch_ScaleAccel(packet->imuState[0].sAccelY);
@@ -1372,6 +1390,12 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
data[0] /= -3.f;
data[1] /= 3.f;
data[2] /= -3.f;
+ /* Right Joy-Con flips some axes, so let's flip them back for consistency */
+ if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) {
+ data[0] = -data[0];
+ data[1] = -data[1];
+ }
+
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, data, 3);
}
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index ed7c640..cea02f6 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -39,6 +39,8 @@
#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER 0x1846
#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337
#define USB_PRODUCT_NINTENDO_SWITCH_PRO 0x2009
+#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT 0x2006
+#define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT 0x2007
#define USB_PRODUCT_RAZER_PANTHERA 0x0401
#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008
#define USB_PRODUCT_RAZER_ATROX 0x0a00