# HG changeset patch # User JibbSmart # Date 1610971049 -28800 # Mon Jan 18 19:57:29 2021 +0800 # Node ID 6913b73a14b91afc10f513a084f1f132b455ac0b # Parent c3b1b429b80b992059573193dc61524247f82369 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 -r c3b1b429b80b -r 6913b73a14b9 include/SDL_hints.h --- a/include/SDL_hints.h Sun Jan 17 21:33:51 2021 +0100 +++ b/include/SDL_hints.h Mon Jan 18 19:57:29 2021 +0800 @@ -676,6 +676,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 -r c3b1b429b80b -r 6913b73a14b9 src/joystick/SDL_joystick.c --- a/src/joystick/SDL_joystick.c Sun Jan 17 21:33:51 2021 +0100 +++ b/src/joystick/SDL_joystick.c Mon Jan 18 19:57:29 2021 +0800 @@ -1880,6 +1880,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; @@ -1944,6 +1948,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 -r c3b1b429b80b -r 6913b73a14b9 src/joystick/SDL_joystick_c.h --- a/src/joystick/SDL_joystick_c.h Sun Jan 17 21:33:51 2021 +0100 +++ b/src/joystick/SDL_joystick_c.h Mon Jan 18 19:57:29 2021 +0800 @@ -77,6 +77,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 -r c3b1b429b80b -r 6913b73a14b9 src/joystick/controller_type.h --- a/src/joystick/controller_type.h Sun Jan 17 21:33:51 2021 +0100 +++ b/src/joystick/controller_type.h Mon Jan 18 19:57:29 2021 +0800 @@ -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 -r c3b1b429b80b -r 6913b73a14b9 src/joystick/hidapi/SDL_hidapi_switch.c --- a/src/joystick/hidapi/SDL_hidapi_switch.c Sun Jan 17 21:33:51 2021 +0100 +++ b/src/joystick/hidapi/SDL_hidapi_switch.c Mon Jan 18 19:57:29 2021 +0800 @@ -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 -r c3b1b429b80b -r 6913b73a14b9 src/joystick/usb_ids.h --- a/src/joystick/usb_ids.h Sun Jan 17 21:33:51 2021 +0100 +++ b/src/joystick/usb_ids.h Mon Jan 18 19:57:29 2021 +0800 @@ -37,6 +37,8 @@ #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