From 515ed40f6644016460f2bd101caa83756f2e8b1d Mon Sep 17 00:00:00 2001 From: happyharryh Date: Wed, 28 Sep 2022 12:44:44 +0800 Subject: [PATCH 1/3] Add vertical mode for Nintendo Joy-Con * Added support for vertical mode for Joy-Con controllers * Added the hint SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS for switching to this mode * Added support for SL/SR buttons in combined/vertical mode and L/ZL/R/ZR buttons in mini-gamepad mode --- include/SDL_hints.h | 9 ++++++++ src/joystick/SDL_gamecontroller.c | 4 ++-- src/joystick/hidapi/SDL_hidapi_switch.c | 30 ++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 10171c445d4ba..3d1177e598ea3 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -672,6 +672,15 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS "SDL_JOYSTICK_HIDAPI_COMBINE_JOY_CONS" +/** + * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be in vertical mode when using the HIDAPI driver + * + * This variable can be set to the following values: + * "0" - Left and right Joy-Con controllers will not be in vertical mode (the default) + * "1" - Left and right Joy-Con controllers will be in vertical mode + */ +#define SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS "SDL_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS" + /** * \brief A variable controlling whether the HIDAPI driver for Amazon Luna controllers connected via Bluetooth should be used. * diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index b764980e9859f..afa9f40128655 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -607,7 +607,7 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI break; default: /* Mini gamepad mode */ - SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,misc1:b15,leftshoulder:b16,rightshoulder:b17,leftshoulder:b18,rightshoulder:b19,", sizeof(mapping_string)); break; } } else { @@ -625,7 +625,7 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI 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)); + SDL_strlcat(mapping_string, "misc1:b15,leftshoulder:b16,rightshoulder:b17,leftshoulder:b18,rightshoulder:b19,", sizeof(mapping_string)); } else { switch (SDL_GetJoystickGameControllerTypeFromGUID(guid, NULL)) { case SDL_CONTROLLER_TYPE_PS4: diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index f441c79c966b4..686e0fb2f152a 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -262,6 +262,7 @@ typedef struct { Uint32 m_unIMUSamples; Uint32 m_unIMUUpdateIntervalUS; Uint64 m_ulTimestampUS; + SDL_bool m_bVerticalMode; SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState; SwitchSimpleStatePacket_t m_lastSimpleState; @@ -691,6 +692,12 @@ static void SDLCALL SDL_HomeLEDHintChanged(void *userdata, const char *name, con } } +static void SDLCALL SDL_VerticalHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)userdata; + ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE); +} + static void UpdateSlotLED(SDL_DriverSwitch_Context *ctx) { if (!ctx->m_bInputOnly) { @@ -1410,7 +1417,7 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti SDL_PlayerLEDHintChanged, ctx); /* Initialize the joystick capabilities */ - joystick->nbuttons = 16; + joystick->nbuttons = 20; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->epowerlevel = device->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; @@ -1419,6 +1426,11 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti ctx->m_unLastIMUReset = ctx->m_unLastInput = SDL_GetTicks(); ctx->m_unIMUUpdateIntervalUS = 5 * 1000; /* Start off at 5 ms update rate */ + /* Set up for vertical mode */ + ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, + SDL_VerticalHintChanged, ctx); + return SDL_TRUE; } @@ -1824,6 +1836,8 @@ static void HandleCombinedControllerStateL(SDL_Joystick *joystick, SDL_DriverSwi SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE2, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); axis = (data & 0x80) ? 32767 : -32768; SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); @@ -1857,6 +1871,9 @@ static void HandleMiniControllerStateL(SDL_Joystick *joystick, SDL_DriverSwitch_ SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); } axis = packet->controllerState.rgucJoystickLeft[0] | ((packet->controllerState.rgucJoystickLeft[1] & 0xF) << 8); @@ -1878,6 +1895,8 @@ static void HandleCombinedControllerStateR(SDL_Joystick *joystick, SDL_DriverSwi SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE3, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); axis = (data & 0x80) ? 32767 : -32768; SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); @@ -1911,6 +1930,9 @@ static void HandleMiniControllerStateR(SDL_Joystick *joystick, SDL_DriverSwitch_ SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); } if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) { @@ -1932,13 +1954,13 @@ static void HandleMiniControllerStateR(SDL_Joystick *joystick, SDL_DriverSwitch_ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) { if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { - if (ctx->device->parent) { + if (ctx->device->parent || ctx->m_bVerticalMode) { HandleCombinedControllerStateL(joystick, ctx, packet); } else { HandleMiniControllerStateL(joystick, ctx, packet); } } else if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { - if (ctx->device->parent) { + if (ctx->device->parent || ctx->m_bVerticalMode) { HandleCombinedControllerStateR(joystick, ctx, packet); } else { HandleMiniControllerStateR(joystick, ctx, packet); @@ -2213,6 +2235,8 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, SDL_PlayerLEDHintChanged, ctx); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, + SDL_VerticalHintChanged, ctx); ctx->joystick = NULL; } From f48a23963c1c22f1b97a7cdb6a4b0397571a0b20 Mon Sep 17 00:00:00 2001 From: happyharryh Date: Fri, 30 Sep 2022 15:05:09 +0800 Subject: [PATCH 2/3] Update the mapping when SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS changes --- src/joystick/SDL_gamecontroller.c | 44 +++++++++++++++++++++++-- src/joystick/hidapi/SDL_hidapi_switch.c | 20 +++-------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index afa9f40128655..38a9796648c28 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -31,6 +31,7 @@ #include "controller_type.h" #include "usb_ids.h" #include "hidapi/SDL_hidapi_nintendo.h" +#include "../SDL_hints_c.h" #if !SDL_EVENTS_DISABLED #include "../events/SDL_events_c.h" @@ -115,6 +116,7 @@ static ControllerMapping_t *s_pSupportedControllers = NULL; static ControllerMapping_t *s_pDefaultMapping = NULL; static ControllerMapping_t *s_pXInputMapping = NULL; static char gamecontroller_magic; +SDL_bool SDL_HIDAPI_vertical_joycons = SDL_FALSE; /* The SDL game controller structure */ struct _SDL_GameController @@ -606,8 +608,22 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI } break; default: - /* Mini gamepad mode */ - SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,misc1:b15,leftshoulder:b16,rightshoulder:b17,leftshoulder:b18,rightshoulder:b19,", sizeof(mapping_string)); + if (SDL_HIDAPI_vertical_joycons) { + /* Vertical mode */ + if (guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + SDL_strlcat(mapping_string, "back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b15,leftshoulder:b16,rightshoulder:b17,", sizeof(mapping_string)); + } else { + SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,leftshoulder:b18,rightshoulder:b19,", sizeof(mapping_string)); + } + } else { + /* Mini gamepad mode */ + SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + if (guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + SDL_strlcat(mapping_string, "lefttrigger:a4,leftshoulder:b16,", sizeof(mapping_string)); + } else { + SDL_strlcat(mapping_string, "righttrigger:a5,rightshoulder:b19,", sizeof(mapping_string)); + } + } break; } } else { @@ -1798,6 +1814,26 @@ static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size) #endif } +static void SDLCALL +SDL_JoystickHidapiVerticalJoyConsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_HIDAPI_vertical_joycons = SDL_GetStringBoolean(hint, SDL_FALSE); + + Uint16 vendor; + Uint16 product; + for (SDL_GameController *controller = SDL_gamecontrollers; controller; controller = controller->next) { + if (SDL_IsJoystickHIDAPI(controller->joystick->guid)) { + SDL_GetJoystickGUIDInfo(controller->joystick->guid, &vendor, &product, NULL, NULL); + if (vendor == USB_VENDOR_NINTENDO && + (product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT || + product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT)) { + ControllerMapping_t* controllerMapping = SDL_CreateMappingForHIDAPIController(controller->joystick->guid); + SDL_PrivateLoadButtonMapping(controller, controllerMapping->name, controllerMapping->mapping); + } + } + } +} + /* * Initialize the game controller system, mostly load our DB of controller config mappings */ @@ -1826,6 +1862,8 @@ SDL_GameControllerInitMappings(void) SDL_GameControllerIgnoreDevicesChanged, NULL); SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, SDL_GameControllerIgnoreDevicesExceptChanged, NULL); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, + SDL_JoystickHidapiVerticalJoyConsChanged, NULL); return (0); } @@ -2866,6 +2904,8 @@ SDL_GameControllerQuitMappings(void) SDL_GameControllerIgnoreDevicesChanged, NULL); SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, SDL_GameControllerIgnoreDevicesExceptChanged, NULL); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, + SDL_JoystickHidapiVerticalJoyConsChanged, NULL); if (SDL_allowed_controllers.entries) { SDL_free(SDL_allowed_controllers.entries); diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 686e0fb2f152a..687b96072dfc6 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -262,7 +262,6 @@ typedef struct { Uint32 m_unIMUSamples; Uint32 m_unIMUUpdateIntervalUS; Uint64 m_ulTimestampUS; - SDL_bool m_bVerticalMode; SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState; SwitchSimpleStatePacket_t m_lastSimpleState; @@ -692,12 +691,6 @@ static void SDLCALL SDL_HomeLEDHintChanged(void *userdata, const char *name, con } } -static void SDLCALL SDL_VerticalHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) -{ - SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)userdata; - ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE); -} - static void UpdateSlotLED(SDL_DriverSwitch_Context *ctx) { if (!ctx->m_bInputOnly) { @@ -1426,11 +1419,6 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti ctx->m_unLastIMUReset = ctx->m_unLastInput = SDL_GetTicks(); ctx->m_unIMUUpdateIntervalUS = 5 * 1000; /* Start off at 5 ms update rate */ - /* Set up for vertical mode */ - ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE); - SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, - SDL_VerticalHintChanged, ctx); - return SDL_TRUE; } @@ -1953,14 +1941,16 @@ static void HandleMiniControllerStateR(SDL_Joystick *joystick, SDL_DriverSwitch_ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) { + extern SDL_bool SDL_HIDAPI_vertical_joycons; + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { - if (ctx->device->parent || ctx->m_bVerticalMode) { + if (ctx->device->parent || SDL_HIDAPI_vertical_joycons) { HandleCombinedControllerStateL(joystick, ctx, packet); } else { HandleMiniControllerStateL(joystick, ctx, packet); } } else if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { - if (ctx->device->parent || ctx->m_bVerticalMode) { + if (ctx->device->parent || SDL_HIDAPI_vertical_joycons) { HandleCombinedControllerStateR(joystick, ctx, packet); } else { HandleMiniControllerStateR(joystick, ctx, packet); @@ -2235,8 +2225,6 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, SDL_PlayerLEDHintChanged, ctx); - SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, - SDL_VerticalHintChanged, ctx); ctx->joystick = NULL; } From 63f33e08b0b3780a65a308a23298e8c613008b00 Mon Sep 17 00:00:00 2001 From: happyharryh Date: Sun, 2 Oct 2022 10:38:28 +0800 Subject: [PATCH 3/3] Remove the updating of mapping when the hint changes --- include/SDL_hints.h | 2 ++ src/joystick/SDL_gamecontroller.c | 39 +++---------------------- src/joystick/hidapi/SDL_hidapi_switch.c | 10 ++++--- 3 files changed, 12 insertions(+), 39 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 3d1177e598ea3..9e8295b48498d 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -678,6 +678,8 @@ extern "C" { * This variable can be set to the following values: * "0" - Left and right Joy-Con controllers will not be in vertical mode (the default) * "1" - Left and right Joy-Con controllers will be in vertical mode + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) */ #define SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS "SDL_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS" diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 38a9796648c28..60446877dc276 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -31,7 +31,6 @@ #include "controller_type.h" #include "usb_ids.h" #include "hidapi/SDL_hidapi_nintendo.h" -#include "../SDL_hints_c.h" #if !SDL_EVENTS_DISABLED #include "../events/SDL_events_c.h" @@ -116,7 +115,6 @@ static ControllerMapping_t *s_pSupportedControllers = NULL; static ControllerMapping_t *s_pDefaultMapping = NULL; static ControllerMapping_t *s_pXInputMapping = NULL; static char gamecontroller_magic; -SDL_bool SDL_HIDAPI_vertical_joycons = SDL_FALSE; /* The SDL game controller structure */ struct _SDL_GameController @@ -608,21 +606,16 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI } break; default: - if (SDL_HIDAPI_vertical_joycons) { + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE)) { /* Vertical mode */ if (guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft) { - SDL_strlcat(mapping_string, "back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b15,leftshoulder:b16,rightshoulder:b17,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b15,", sizeof(mapping_string)); } else { - SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,leftshoulder:b18,rightshoulder:b19,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string)); } } else { /* Mini gamepad mode */ SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,", sizeof(mapping_string)); - if (guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft) { - SDL_strlcat(mapping_string, "lefttrigger:a4,leftshoulder:b16,", sizeof(mapping_string)); - } else { - SDL_strlcat(mapping_string, "righttrigger:a5,rightshoulder:b19,", sizeof(mapping_string)); - } } break; } @@ -641,7 +634,7 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI 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,leftshoulder:b16,rightshoulder:b17,leftshoulder:b18,rightshoulder:b19,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); } else { switch (SDL_GetJoystickGameControllerTypeFromGUID(guid, NULL)) { case SDL_CONTROLLER_TYPE_PS4: @@ -1814,26 +1807,6 @@ static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size) #endif } -static void SDLCALL -SDL_JoystickHidapiVerticalJoyConsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) -{ - SDL_HIDAPI_vertical_joycons = SDL_GetStringBoolean(hint, SDL_FALSE); - - Uint16 vendor; - Uint16 product; - for (SDL_GameController *controller = SDL_gamecontrollers; controller; controller = controller->next) { - if (SDL_IsJoystickHIDAPI(controller->joystick->guid)) { - SDL_GetJoystickGUIDInfo(controller->joystick->guid, &vendor, &product, NULL, NULL); - if (vendor == USB_VENDOR_NINTENDO && - (product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT || - product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT)) { - ControllerMapping_t* controllerMapping = SDL_CreateMappingForHIDAPIController(controller->joystick->guid); - SDL_PrivateLoadButtonMapping(controller, controllerMapping->name, controllerMapping->mapping); - } - } - } -} - /* * Initialize the game controller system, mostly load our DB of controller config mappings */ @@ -1862,8 +1835,6 @@ SDL_GameControllerInitMappings(void) SDL_GameControllerIgnoreDevicesChanged, NULL); SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, SDL_GameControllerIgnoreDevicesExceptChanged, NULL); - SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, - SDL_JoystickHidapiVerticalJoyConsChanged, NULL); return (0); } @@ -2904,8 +2875,6 @@ SDL_GameControllerQuitMappings(void) SDL_GameControllerIgnoreDevicesChanged, NULL); SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, SDL_GameControllerIgnoreDevicesExceptChanged, NULL); - SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, - SDL_JoystickHidapiVerticalJoyConsChanged, NULL); if (SDL_allowed_controllers.entries) { SDL_free(SDL_allowed_controllers.entries); diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 687b96072dfc6..ff2930c3d3924 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -262,6 +262,7 @@ typedef struct { Uint32 m_unIMUSamples; Uint32 m_unIMUUpdateIntervalUS; Uint64 m_ulTimestampUS; + SDL_bool m_bVerticalMode; SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState; SwitchSimpleStatePacket_t m_lastSimpleState; @@ -1419,6 +1420,9 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti ctx->m_unLastIMUReset = ctx->m_unLastInput = SDL_GetTicks(); ctx->m_unIMUUpdateIntervalUS = 5 * 1000; /* Start off at 5 ms update rate */ + /* Set up for vertical mode */ + ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE); + return SDL_TRUE; } @@ -1941,16 +1945,14 @@ static void HandleMiniControllerStateR(SDL_Joystick *joystick, SDL_DriverSwitch_ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) { - extern SDL_bool SDL_HIDAPI_vertical_joycons; - if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { - if (ctx->device->parent || SDL_HIDAPI_vertical_joycons) { + if (ctx->device->parent || ctx->m_bVerticalMode) { HandleCombinedControllerStateL(joystick, ctx, packet); } else { HandleMiniControllerStateL(joystick, ctx, packet); } } else if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { - if (ctx->device->parent || SDL_HIDAPI_vertical_joycons) { + if (ctx->device->parent || ctx->m_bVerticalMode) { HandleCombinedControllerStateR(joystick, ctx, packet); } else { HandleMiniControllerStateR(joystick, ctx, packet);