diff --git a/WhatsNew.txt b/WhatsNew.txt index 0ad5698ce..feb4aaca3 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -20,9 +20,11 @@ General: the SDL 2.24.0 stable release. * Added SDL_bsearch() and SDL_utf8strnlen() to the stdlib routines * Added SDL_size_mul_overflow() and SDL_size_add_overflow() for better size overflow protection +* The hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS now defaults on * Added support for mini-gamepad mode for Nintendo Joy-Con controllers using the HIDAPI driver -* Added the hint SDL_HINT_JOYSTICK_HIDAPI_SWITCH_COMBINE_JOY_CONS to control whether Joy-Con controllers are automatically merged into a unified gamepad when using the HIDAPI driver. This hint defaults on. -* Removed the hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS with the new Joy-Con functionality +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS to control whether Joy-Con controllers are automatically merged into a unified gamepad when using the HIDAPI driver. This hint defaults on. +* Added support for Nintendo Online classic controllers using the HIDAPI driver +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC to control whether the HIDAPI driver for Nintendo Online classic controllers should be used * Added functions to get the platform dependent name for a joystick or game controller: * SDL_JoystickPathForIndex() * SDL_JoystickPath() @@ -30,7 +32,7 @@ General: * SDL_GameControllerPath() * Added SDL_GameControllerGetFirmwareVersion() and SDL_JoystickGetFirmwareVersion(), currently implemented for DualSense(tm) Wireless Controllers using HIDAPI * Added SDL_JoystickAttachVirtualEx() for extended virtual controller support -* Added joystick event SDL_JOYBATTERYUPDATED for when battery status changes. +* Added joystick event SDL_JOYBATTERYUPDATED for when battery status changes * Added SDL_GUIDToString() and SDL_GUIDFromString() to convert between SDL GUID and string * Added SDL_HasLSX() and SDL_HasLASX() to detect LoongArch SIMD support * Added SDL_GetOriginalMemoryFunctions() @@ -42,8 +44,8 @@ General: Windows: * Added a D3D12 renderer implementation and SDL_RenderGetD3D12Device() to retrieve the D3D12 device associated with it -* Added the hint SDL_HINT_WINDOWS_DPI_AWARENESS to set whether the application is DPI-aware. This hint must be set before initializing the video subsystem. -* Added the hint SDL_HINT_WINDOWS_DPI_SCALING to control whether the SDL coordinates are in DPI-scaled points or pixels. +* Added the hint SDL_HINT_WINDOWS_DPI_AWARENESS to set whether the application is DPI-aware. This hint must be set before initializing the video subsystem +* Added the hint SDL_HINT_WINDOWS_DPI_SCALING to control whether the SDL coordinates are in DPI-scaled points or pixels * Added support for SDL_GetAudioDeviceSpec to the DirectSound backend Linux: @@ -52,7 +54,7 @@ Linux: * Added the hint SDL_HINT_LINUX_HAT_DEADZONES to control whether to use deadzones on analog hats macOS: -* Bumped minimum OS deployment version to macOS 10.9. +* Bumped minimum OS deployment version to macOS 10.9 --------------------------------------------------------------------------- 2.0.22: diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 854d44ceb..368cb0a3c 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -652,6 +652,26 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE "SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE" +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch Joy-Cons should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS "SDL_JOYSTICK_HIDAPI_JOY_CONS" + +/** + * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be combined into a single Pro-like controller when using the HIDAPI driver + * + * This variable can be set to the following values: + * "0" - Left and right Joy-Con controllers will not be combined and each will be a mini-gamepad + * "1" - Left and right Joy-Con controllers will be combined into a single controller (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS "SDL_JOYSTICK_HIDAPI_COMBINE_JOY_CONS" + /** * \brief A variable controlling whether the HIDAPI driver for Amazon Luna controllers connected via Bluetooth should be used. * @@ -663,6 +683,17 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_HIDAPI_LUNA "SDL_JOYSTICK_HIDAPI_LUNA" +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Online classic controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC "SDL_JOYSTICK_HIDAPI_NINTENDO_CLASSIC" + /** * \brief A variable controlling whether the HIDAPI driver for NVIDIA SHIELD controllers should be used. * @@ -778,17 +809,6 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH" -/** - * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be combined into a single Pro-like controller when using the HIDAPI driver - * - * This variable can be set to the following values: - * "0" - Left and right Joy-Con controllers will not be combined and each will be a mini-gamepad - * "1" - Left and right Joy-Con controllers will be combined into a single controller (the default) - * - * The default is "1" - */ -#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_COMBINE_JOY_CONS "SDL_JOYSTICK_HIDAPI_SWITCH_COMBINE_JOY_CONS" - /** * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch controller is opened * diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index f9f30c5fb..1851e9979 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -353,6 +353,44 @@ IsGameCubeFormFactor(int vendor_id, int product_id) return SDL_FALSE; } +static SDL_bool +HIDAPI_DriverNintendoClassic_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + if (vendor_id == USB_VENDOR_NINTENDO) { + if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) { + if (SDL_strncmp(name, "NES Controller", 14) == 0) { + return SDL_TRUE; + } + } + + if (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER) { + return SDL_TRUE; + } + + if (product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) { + return SDL_TRUE; + } + + if (product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) { + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +static SDL_bool +HIDAPI_DriverJoyCons_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + 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) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + static SDL_bool HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) { @@ -366,9 +404,10 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t return SDL_FALSE; } - /* We always support the Nintendo Online NES Controllers */ - if (SDL_strncmp(name, "NES Controller", 14) == 0) { - return SDL_TRUE; + /* If it's handled by another driver, it's not handled here */ + if (HIDAPI_DriverNintendoClassic_IsSupportedDevice(name, type, vendor_id, product_id, version, interface_number, interface_class, interface_subclass, interface_protocol) || + HIDAPI_DriverJoyCons_IsSupportedDevice(name, type, vendor_id, product_id, version, interface_number, interface_class, interface_subclass, interface_protocol)) { + return SDL_FALSE; } return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ? SDL_TRUE : SDL_FALSE; @@ -1943,6 +1982,50 @@ HIDAPI_DriverSwitch_FreeDevice(SDL_HIDAPI_Device *device) { } +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverNintendoClassic = +{ + SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC, + SDL_TRUE, + SDL_TRUE, + HIDAPI_DriverNintendoClassic_IsSupportedDevice, + HIDAPI_DriverSwitch_GetDeviceName, + HIDAPI_DriverSwitch_InitDevice, + HIDAPI_DriverSwitch_GetDevicePlayerIndex, + HIDAPI_DriverSwitch_SetDevicePlayerIndex, + HIDAPI_DriverSwitch_UpdateDevice, + HIDAPI_DriverSwitch_OpenJoystick, + HIDAPI_DriverSwitch_RumbleJoystick, + HIDAPI_DriverSwitch_RumbleJoystickTriggers, + HIDAPI_DriverSwitch_GetJoystickCapabilities, + HIDAPI_DriverSwitch_SetJoystickLED, + HIDAPI_DriverSwitch_SendJoystickEffect, + HIDAPI_DriverSwitch_SetJoystickSensorsEnabled, + HIDAPI_DriverSwitch_CloseJoystick, + HIDAPI_DriverSwitch_FreeDevice, +}; + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverJoyCons = +{ + SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, + SDL_TRUE, + SDL_TRUE, + HIDAPI_DriverJoyCons_IsSupportedDevice, + HIDAPI_DriverSwitch_GetDeviceName, + HIDAPI_DriverSwitch_InitDevice, + HIDAPI_DriverSwitch_GetDevicePlayerIndex, + HIDAPI_DriverSwitch_SetDevicePlayerIndex, + HIDAPI_DriverSwitch_UpdateDevice, + HIDAPI_DriverSwitch_OpenJoystick, + HIDAPI_DriverSwitch_RumbleJoystick, + HIDAPI_DriverSwitch_RumbleJoystickTriggers, + HIDAPI_DriverSwitch_GetJoystickCapabilities, + HIDAPI_DriverSwitch_SetJoystickLED, + HIDAPI_DriverSwitch_SendJoystickEffect, + HIDAPI_DriverSwitch_SetJoystickSensorsEnabled, + HIDAPI_DriverSwitch_CloseJoystick, + HIDAPI_DriverSwitch_FreeDevice, +}; + SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch = { SDL_HINT_JOYSTICK_HIDAPI_SWITCH, diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 63ef7b043..a7ac1f8e5 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -65,6 +65,8 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = { &SDL_HIDAPI_DriverSteam, #endif #ifdef SDL_JOYSTICK_HIDAPI_SWITCH + &SDL_HIDAPI_DriverNintendoClassic, + &SDL_HIDAPI_DriverJoyCons, &SDL_HIDAPI_DriverSwitch, #endif #ifdef SDL_JOYSTICK_HIDAPI_XBOX360 @@ -348,7 +350,7 @@ SDL_HIDAPIDriverHintChanged(void *userdata, const char *name, const char *oldVal SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; driver->enabled = SDL_GetHintBoolean(driver->hint, enabled); } - } else if (SDL_strcmp(name, SDL_HINT_JOYSTICK_HIDAPI_SWITCH_COMBINE_JOY_CONS) == 0) { + } else if (SDL_strcmp(name, SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS) == 0) { SDL_HIDAPI_combine_joycons = enabled; } else { for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { @@ -419,7 +421,7 @@ HIDAPI_JoystickInit(void) SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; SDL_AddHintCallback(driver->hint, SDL_HIDAPIDriverHintChanged, NULL); } - SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_COMBINE_JOY_CONS, + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, SDL_HIDAPIDriverHintChanged, NULL); SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPIDriverHintChanged, NULL); @@ -1260,7 +1262,7 @@ HIDAPI_JoystickQuit(void) SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; SDL_DelHintCallback(driver->hint, SDL_HIDAPIDriverHintChanged, NULL); } - SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_COMBINE_JOY_CONS, + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, SDL_HIDAPIDriverHintChanged, NULL); SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPIDriverHintChanged, NULL); diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 3f10bf384..3180de518 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -116,10 +116,12 @@ typedef struct _SDL_HIDAPI_DeviceDriver /* HIDAPI device support */ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverCombined; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverJoyCons; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna; -extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverShield; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverNintendoClassic; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverShield; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch;