diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 97aeaa73e..2472695a8 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -587,6 +587,12 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI (vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) { /* GameCube driver has 12 buttons and 6 axes */ SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string)); + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_N64_CONTROLLER) { + 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,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string)); + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) { + SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,rightshoulder:b10,righttrigger:a5,start:b6,misc1:b15,", sizeof(mapping_string)); + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) { + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,", sizeof(mapping_string)); } else { /* All other controllers have the standard set of 19 buttons and 6 axes */ 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,", sizeof(mapping_string)); diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 2d31578e8..e96de4cc0 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1810,6 +1810,11 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c char *name; size_t i, len; + /* Use the given name for the Nintendo Online NES Controllers */ + if (SDL_strncmp(product_name, "NES Controller", 14) == 0) { + return SDL_strdup(product_name); + } + custom_name = GuessControllerName(vendor, product); if (custom_name) { return SDL_strdup(custom_name); @@ -2051,6 +2056,10 @@ SDL_GetJoystickGameControllerType(const char *name, Uint16 vendor, Uint16 produc break; case k_eControllerType_SwitchJoyConLeft: case k_eControllerType_SwitchJoyConRight: + /* We always support the Nintendo Online NES Controllers */ + if (name && SDL_strncmp(name, "NES Controller", 14) == 0) { + return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; + } type = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_FALSE) ? SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO : SDL_CONTROLLER_TYPE_UNKNOWN; break; default: diff --git a/src/joystick/controller_type.c b/src/joystick/controller_type.c index 45648e4e2..187e9c47b 100644 --- a/src/joystick/controller_type.c +++ b/src/joystick/controller_type.c @@ -531,6 +531,9 @@ static const ControllerDescription_t arrControllers[] = { // * ZhiXu Gamepad Wireless // * Sunwaytek Wireless Motion Controller for Nintendo Switch { MAKE_CONTROLLER_ID( 0x057e, 0x2009 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Switch Pro Controller + { MAKE_CONTROLLER_ID( 0x057e, 0x2017 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SNES Controller + { MAKE_CONTROLLER_ID( 0x057e, 0x2019 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online N64 Controller + { MAKE_CONTROLLER_ID( 0x057e, 0x201e ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SEGA Genesis Controller { MAKE_CONTROLLER_ID( 0x0f0d, 0x00c1 ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORIPAD for Nintendo Switch { MAKE_CONTROLLER_ID( 0x0f0d, 0x0092 ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Pokken Tournament DX Pro Pad diff --git a/src/joystick/hidapi/SDL_hidapi_gamecube.c b/src/joystick/hidapi/SDL_hidapi_gamecube.c index 694556482..dad4daeaa 100644 --- a/src/joystick/hidapi/SDL_hidapi_gamecube.c +++ b/src/joystick/hidapi/SDL_hidapi_gamecube.c @@ -71,7 +71,7 @@ HIDAPI_DriverGameCube_IsSupportedDevice(const char *name, SDL_GameControllerType } static const char * -HIDAPI_DriverGameCube_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverGameCube_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { return "Nintendo GameCube Controller"; } diff --git a/src/joystick/hidapi/SDL_hidapi_luna.c b/src/joystick/hidapi/SDL_hidapi_luna.c index bf497d224..4b283e284 100644 --- a/src/joystick/hidapi/SDL_hidapi_luna.c +++ b/src/joystick/hidapi/SDL_hidapi_luna.c @@ -54,7 +54,7 @@ HIDAPI_DriverLuna_IsSupportedDevice(const char *name, SDL_GameControllerType typ } static const char * -HIDAPI_DriverLuna_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverLuna_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { return "Amazon Luna Controller"; } diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index c11dfb364..7c87043cf 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -155,7 +155,7 @@ HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type } static const char * -HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverPS4_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { if (vendor_id == USB_VENDOR_SONY) { return "PS4 Controller"; diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c index 3f1b62cc4..ed9ab7886 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -185,7 +185,7 @@ HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type } static const char * -HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverPS5_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { if (vendor_id == USB_VENDOR_SONY) { return "PS5 Controller"; diff --git a/src/joystick/hidapi/SDL_hidapi_stadia.c b/src/joystick/hidapi/SDL_hidapi_stadia.c index 0a5c2584f..35025db9e 100644 --- a/src/joystick/hidapi/SDL_hidapi_stadia.c +++ b/src/joystick/hidapi/SDL_hidapi_stadia.c @@ -55,7 +55,7 @@ HIDAPI_DriverStadia_IsSupportedDevice(const char *name, SDL_GameControllerType t } static const char * -HIDAPI_DriverStadia_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverStadia_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { return "Google Stadia Controller"; } diff --git a/src/joystick/hidapi/SDL_hidapi_steam.c b/src/joystick/hidapi/SDL_hidapi_steam.c index b69c598dc..bbf1f0e2b 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam.c +++ b/src/joystick/hidapi/SDL_hidapi_steam.c @@ -1004,7 +1004,7 @@ HIDAPI_DriverSteam_IsSupportedDevice(const char *name, SDL_GameControllerType ty } static const char * -HIDAPI_DriverSteam_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverSteam_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { return "Steam Controller"; } diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 13b5e29d0..3fbd91e02 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -305,9 +305,29 @@ HasHomeLED(int vendor_id, int product_id) return SDL_FALSE; } + /* The Nintendo Online classic controllers don't have a Home LED */ + if (vendor_id == USB_VENDOR_NINTENDO && + (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER || + product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER || + product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER)) { + return SDL_FALSE; + } + return SDL_TRUE; } +static SDL_bool +AlwaysUsesLabels(int vendor_id, int product_id) +{ + /* These controllers don't have a diamond button configuration, so always use labels */ + if (vendor_id == USB_VENDOR_NINTENDO && + (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER || + product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER)) { + return SDL_TRUE; + } + return SDL_FALSE; +} + static SDL_bool IsGameCubeFormFactor(int vendor_id, int product_id) { @@ -342,7 +362,7 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t } static const char * -HIDAPI_DriverSwitch_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverSwitch_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { /* Give a user friendly name for this controller */ if (vendor_id == USB_VENDOR_NINTENDO) { @@ -355,8 +375,24 @@ HIDAPI_DriverSwitch_GetDeviceName(Uint16 vendor_id, Uint16 product_id) } if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) { + /* Use the given name for the Nintendo Online NES Controllers */ + if (SDL_strncmp(name, "NES Controller", 14) == 0) { + return name; + } return "Nintendo Switch Joy-Con Right"; } + + if (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER) { + return "Nintendo N64 Controller"; + } + + if (product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) { + return "Nintendo SEGA Genesis Controller"; + } + + if (product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) { + return "Nintendo SNES Controller"; + } } return "Nintendo Switch Pro Controller"; @@ -1061,8 +1097,12 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti ctx->m_bIsGameCube = SDL_TRUE; } - SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, - SDL_GameControllerButtonReportingHintChanged, ctx); + if (AlwaysUsesLabels(device->vendor_id, device->product_id)) { + ctx->m_bUseButtonLabels = SDL_TRUE; + } else { + SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + } /* Initialize the joystick capabilities */ if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft || diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360.c b/src/joystick/hidapi/SDL_hidapi_xbox360.c index da7aa240f..28e04cfa4 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c @@ -83,7 +83,7 @@ HIDAPI_DriverXbox360_IsSupportedDevice(const char *name, SDL_GameControllerType } static const char * -HIDAPI_DriverXbox360_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverXbox360_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { return NULL; } diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/src/joystick/hidapi/SDL_hidapi_xbox360w.c index 91c15a73b..0c7dfef93 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360w.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360w.c @@ -57,7 +57,7 @@ HIDAPI_DriverXbox360W_IsSupportedDevice(const char *name, SDL_GameControllerType } static const char * -HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverXbox360W_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { return "Xbox 360 Wireless Controller"; } diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 1f0cf5b5a..b549ef6d6 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -285,7 +285,7 @@ HIDAPI_DriverXboxOne_IsSupportedDevice(const char *name, SDL_GameControllerType } static const char * -HIDAPI_DriverXboxOne_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +HIDAPI_DriverXboxOne_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id) { return NULL; } diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index a72e6a2cd..0c5dc1ee4 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -200,8 +200,8 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device) device->driver = HIDAPI_GetDeviceDriver(device); if (device->driver) { - const char *name = device->driver->GetDeviceName(device->vendor_id, device->product_id); - if (name) { + const char *name = device->driver->GetDeviceName(device->name, device->vendor_id, device->product_id); + if (name && name != device->name) { SDL_free(device->name); device->name = SDL_strdup(name); } diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index c1b75d8db..73c2ad922 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -90,7 +90,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver SDL_bool enabled; SDL_bool enabled_default; SDL_bool (*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); - const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id); + const char *(*GetDeviceName)(const char *name, Uint16 vendor_id, Uint16 product_id); SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device); int (*GetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id); void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index); diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h index 97f37b0f8..14c84e5df 100644 --- a/src/joystick/usb_ids.h +++ b/src/joystick/usb_ids.h @@ -47,6 +47,9 @@ #define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT 0x2006 #define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT 0x2007 #define USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP 0x200e +#define USB_PRODUCT_NINTENDO_N64_CONTROLLER 0x2019 +#define USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER 0x201e +#define USB_PRODUCT_NINTENDO_SNES_CONTROLLER 0x2017 #define USB_PRODUCT_RAZER_PANTHERA 0x0401 #define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008 #define USB_PRODUCT_RAZER_ATROX 0x0a00