Added separate hints for Nintendo Online classic controllers and Joy-Cons

This allows them to be enabled/disabled separately from Switch Pro HIDAPI support
This commit is contained in:
Sam Lantinga 2022-08-03 13:07:47 -07:00
parent 60d1944e46
commit bcdef4aaf9
5 changed files with 133 additions and 24 deletions

View file

@ -20,9 +20,11 @@ General:
the SDL 2.24.0 stable release. the SDL 2.24.0 stable release.
* Added SDL_bsearch() and SDL_utf8strnlen() to the stdlib routines * 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 * 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 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. * 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.
* Removed the hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS with the new Joy-Con functionality * 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: * Added functions to get the platform dependent name for a joystick or game controller:
* SDL_JoystickPathForIndex() * SDL_JoystickPathForIndex()
* SDL_JoystickPath() * SDL_JoystickPath()
@ -30,7 +32,7 @@ General:
* SDL_GameControllerPath() * SDL_GameControllerPath()
* Added SDL_GameControllerGetFirmwareVersion() and SDL_JoystickGetFirmwareVersion(), currently implemented for DualSense(tm) Wireless Controllers using HIDAPI * Added SDL_GameControllerGetFirmwareVersion() and SDL_JoystickGetFirmwareVersion(), currently implemented for DualSense(tm) Wireless Controllers using HIDAPI
* Added SDL_JoystickAttachVirtualEx() for extended virtual controller support * 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_GUIDToString() and SDL_GUIDFromString() to convert between SDL GUID and string
* Added SDL_HasLSX() and SDL_HasLASX() to detect LoongArch SIMD support * Added SDL_HasLSX() and SDL_HasLASX() to detect LoongArch SIMD support
* Added SDL_GetOriginalMemoryFunctions() * Added SDL_GetOriginalMemoryFunctions()
@ -42,8 +44,8 @@ General:
Windows: Windows:
* Added a D3D12 renderer implementation and SDL_RenderGetD3D12Device() to retrieve the D3D12 device associated with it * 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_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_SCALING to control whether the SDL coordinates are in DPI-scaled points or pixels
* Added support for SDL_GetAudioDeviceSpec to the DirectSound backend * Added support for SDL_GetAudioDeviceSpec to the DirectSound backend
Linux: Linux:
@ -52,7 +54,7 @@ Linux:
* Added the hint SDL_HINT_LINUX_HAT_DEADZONES to control whether to use deadzones on analog hats * Added the hint SDL_HINT_LINUX_HAT_DEADZONES to control whether to use deadzones on analog hats
macOS: macOS:
* Bumped minimum OS deployment version to macOS 10.9. * Bumped minimum OS deployment version to macOS 10.9
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
2.0.22: 2.0.22:

View file

@ -652,6 +652,26 @@ extern "C" {
*/ */
#define SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE "SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE" #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. * \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" #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. * \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" #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 * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch controller is opened
* *

View file

@ -353,6 +353,44 @@ IsGameCubeFormFactor(int vendor_id, int product_id)
return SDL_FALSE; 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 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) 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; return SDL_FALSE;
} }
/* We always support the Nintendo Online NES Controllers */ /* If it's handled by another driver, it's not handled here */
if (SDL_strncmp(name, "NES Controller", 14) == 0) { if (HIDAPI_DriverNintendoClassic_IsSupportedDevice(name, type, vendor_id, product_id, version, interface_number, interface_class, interface_subclass, interface_protocol) ||
return SDL_TRUE; 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; 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_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
{ {
SDL_HINT_JOYSTICK_HIDAPI_SWITCH, SDL_HINT_JOYSTICK_HIDAPI_SWITCH,

View file

@ -65,6 +65,8 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
&SDL_HIDAPI_DriverSteam, &SDL_HIDAPI_DriverSteam,
#endif #endif
#ifdef SDL_JOYSTICK_HIDAPI_SWITCH #ifdef SDL_JOYSTICK_HIDAPI_SWITCH
&SDL_HIDAPI_DriverNintendoClassic,
&SDL_HIDAPI_DriverJoyCons,
&SDL_HIDAPI_DriverSwitch, &SDL_HIDAPI_DriverSwitch,
#endif #endif
#ifdef SDL_JOYSTICK_HIDAPI_XBOX360 #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]; SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
driver->enabled = SDL_GetHintBoolean(driver->hint, enabled); 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; SDL_HIDAPI_combine_joycons = enabled;
} else { } else {
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { 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_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
SDL_AddHintCallback(driver->hint, SDL_HIDAPIDriverHintChanged, NULL); 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_HIDAPIDriverHintChanged, NULL);
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI, SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI,
SDL_HIDAPIDriverHintChanged, NULL); SDL_HIDAPIDriverHintChanged, NULL);
@ -1260,7 +1262,7 @@ HIDAPI_JoystickQuit(void)
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
SDL_DelHintCallback(driver->hint, SDL_HIDAPIDriverHintChanged, NULL); 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_HIDAPIDriverHintChanged, NULL);
SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI, SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI,
SDL_HIDAPIDriverHintChanged, NULL); SDL_HIDAPIDriverHintChanged, NULL);

View file

@ -116,10 +116,12 @@ typedef struct _SDL_HIDAPI_DeviceDriver
/* HIDAPI device support */ /* HIDAPI device support */
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverCombined; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverCombined;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube; 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_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_DriverPS4;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5; 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_DriverStadia;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam;
extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch;