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.
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 @@
*/
#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 @@
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_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 @@
/* 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 @@
{ 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 @@
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 @@
* 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 @@
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 @@
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