Skip to content

Commit 0a0ce0d

Browse files
committed
Added support for the Switch 2 Joy-Cons with charging grip
1 parent fdfde42 commit 0a0ce0d

File tree

8 files changed

+567
-40
lines changed

8 files changed

+567
-40
lines changed

src/hidapi/SDL_hidapi.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,8 +844,10 @@ static const struct {
844844
Uint16 product;
845845
} SDL_libusb_whitelist[] = {
846846
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER },
847-
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_PRO },
848847
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER },
848+
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT },
849+
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT },
850+
{ USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH2_PRO },
849851
};
850852

851853
static bool IsInWhitelist(Uint16 vendor, Uint16 product)

src/joystick/SDL_gamepad.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -716,12 +716,32 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
716716
// GameCube driver has 12 buttons and 6 axes
717717
SDL_strlcat(mapping_string, "a:b0,b:b2,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:b1,y:b3,misc3:b11,misc4:b10,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
718718
} else if (vendor == USB_VENDOR_NINTENDO &&
719-
(product == USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER)) {
720-
// Switch 2 GameCube has additional buttons for ZL and C
721-
SDL_strlcat(mapping_string, "a:b1,b:b3,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b13,lefttrigger:a4,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,misc3:b4,misc4:b12,rightshoulder:b5,righttrigger:a5,rightx:a2,righty:a3~,start:b6,x:b0,y:b2,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
719+
product == USB_PRODUCT_NINTENDO_SWITCH2_GAMECUBE_CONTROLLER) {
720+
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,rightx:a2,righty:a3,start:b5,x:b2,y:b3,misc1:b8,misc2:b9,misc3:b10,misc4:b11,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
722721
} else if (vendor == USB_VENDOR_NINTENDO &&
723-
(product == USB_PRODUCT_NINTENDO_SWITCH2_PRO)) {
724-
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b8,dpleft:b10,dpright:b9,dpup:b11,guide:b16,leftshoulder:b12,lefttrigger:b13,leftx:a0,lefty:a1~,misc1:b17,misc2:b20,rightshoulder:b4,righttrigger:b5,rightx:a2,righty:a3~,start:b6,back:b14,x:b2,y:b3,leftstick:b15,rightstick:b7,paddle1:b18,paddle2:b19,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
722+
product == USB_PRODUCT_NINTENDO_SWITCH2_PRO) {
723+
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:b11,misc2:b12,paddle1:b13,paddle2:b14,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
724+
} else if (vendor == USB_VENDOR_NINTENDO &&
725+
product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT) {
726+
if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, false)) {
727+
// Vertical mode
728+
SDL_strlcat(mapping_string, "back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b11,paddle2:b14,paddle4:b16,", sizeof(mapping_string));
729+
} else {
730+
// Mini gamepad mode
731+
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,paddle2:b14,paddle4:b16,", sizeof(mapping_string));
732+
}
733+
} else if (vendor == USB_VENDOR_NINTENDO &&
734+
product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT) {
735+
if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, false)) {
736+
// Vertical mode
737+
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,misc2:b12,paddle1:b13,paddle3:b15,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
738+
} else {
739+
// Mini gamepad mode
740+
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,misc2:b12,paddle1:b13,paddle3:b15,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
741+
}
742+
} else if (vendor == USB_VENDOR_NINTENDO &&
743+
product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_PAIR) {
744+
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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:b11,misc2:b12,paddle1:b13,paddle2:b14,paddle3:b15,paddle4:b16,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", sizeof(mapping_string));
725745
} else if (vendor == USB_VENDOR_NINTENDO &&
726746
(guid.data[15] == k_eSwitchDeviceInfoControllerType_HVCLeft ||
727747
guid.data[15] == k_eSwitchDeviceInfoControllerType_HVCRight ||
@@ -840,7 +860,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
840860
// GC Ultimate Primary Map
841861
SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b4,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b13,misc2:b14,rightshoulder:b7,rightstick:b5,righttrigger:a5,rightx:a2,righty:a3,start:b10,misc3:b8,misc4:b9,hint:!SDL_GAMECONTROLLER_USE_GAMECUBE_LABELS:=1,", sizeof(mapping_string));
842862
break;
843-
}
863+
}
844864
break;
845865
case USB_PRODUCT_HANDHELDLEGEND_SINPUT_GENERIC:
846866
switch (sub_type) {
@@ -850,7 +870,7 @@ static GamepadMapping_t *SDL_CreateMappingForHIDAPIGamepad(SDL_GUID guid)
850870
break;
851871
}
852872
break;
853-
873+
854874
case USB_PRODUCT_BONZIRICHANNEL_FIREBIRD:
855875
default:
856876
// Unmapped device

src/joystick/SDL_joystick.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,10 +2953,14 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons
29532953
} else if (vendor == 0x0001 && product == 0x0001) {
29542954
type = SDL_GAMEPAD_TYPE_STANDARD;
29552955

2956-
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT) {
2956+
} else if (vendor == USB_VENDOR_NINTENDO &&
2957+
(product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT ||
2958+
product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_LEFT)) {
29572959
type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT;
29582960

2959-
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) {
2961+
} else if (vendor == USB_VENDOR_NINTENDO &&
2962+
(product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT ||
2963+
product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_RIGHT)) {
29602964
if (name && SDL_strstr(name, "NES Controller") != NULL) {
29612965
// We don't have a type for the Nintendo Online NES Controller
29622966
type = SDL_GAMEPAD_TYPE_STANDARD;
@@ -2971,7 +2975,9 @@ SDL_GamepadType SDL_GetGamepadTypeFromVIDPID(Uint16 vendor, Uint16 product, cons
29712975
type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT;
29722976
}
29732977

2974-
} else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR) {
2978+
} else if (vendor == USB_VENDOR_NINTENDO &&
2979+
(product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR ||
2980+
product == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_PAIR)) {
29752981
type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR;
29762982

29772983
} else if (forUI && SDL_IsJoystickGameCube(vendor, product)) {
@@ -3161,7 +3167,9 @@ bool SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id)
31613167

31623168
bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id)
31633169
{
3164-
return vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR;
3170+
return vendor_id == USB_VENDOR_NINTENDO &&
3171+
(product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR ||
3172+
product_id == USB_PRODUCT_NINTENDO_SWITCH2_JOYCON_PAIR);
31653173
}
31663174

31673175
bool SDL_IsJoystickGameCube(Uint16 vendor_id, Uint16 product_id)

src/joystick/controller_list.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,11 @@ static const ControllerDescription_t arrControllers[] = {
540540
{ MAKE_CONTROLLER_ID( 0x05ac, 0x0002 ), k_eControllerType_AppleController, NULL }, // MFI Standard Gamepad (generic entry for iOS/tvOS)
541541

542542
{ MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left)
543+
{ MAKE_CONTROLLER_ID( 0x057e, 0x2067 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch 2 Joy-Con (Left)
543544
{ MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right)
545+
{ MAKE_CONTROLLER_ID( 0x057e, 0x2066 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch 2 Joy-Con (Right)
544546
{ MAKE_CONTROLLER_ID( 0x057e, 0x2008 ), k_eControllerType_SwitchJoyConPair, NULL }, // Nintendo Switch Joy-Con (Left+Right Combined)
547+
{ MAKE_CONTROLLER_ID( 0x057e, 0x2068 ), k_eControllerType_SwitchJoyConPair, NULL }, // Nintendo Switch 2 Joy-Con (Left+Right Combined)
545548

546549
// This same controller ID is spoofed by many 3rd-party Switch controllers.
547550
// The ones we currently know of are:
@@ -550,6 +553,7 @@ static const ControllerDescription_t arrControllers[] = {
550553
// * ZhiXu Gamepad Wireless
551554
// * Sunwaytek Wireless Motion Controller for Nintendo Switch
552555
{ MAKE_CONTROLLER_ID( 0x057e, 0x2009 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Switch Pro Controller
556+
{ MAKE_CONTROLLER_ID( 0x057e, 0x2069 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Switch 2 Pro Controller
553557
//{ MAKE_CONTROLLER_ID( 0x057e, 0x2017 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SNES Controller
554558
//{ MAKE_CONTROLLER_ID( 0x057e, 0x2019 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online N64 Controller
555559
//{ MAKE_CONTROLLER_ID( 0x057e, 0x201e ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SEGA Genesis Controller

src/joystick/hidapi/SDL_hidapi_switch.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,15 @@ static bool HIDAPI_DriverSwitch_IsSupportedDevice(SDL_HIDAPI_Device *device, con
13881388
return false;
13891389
}
13901390

1391-
return (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO);
1391+
if (type != SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO) {
1392+
return false;
1393+
}
1394+
1395+
// The Nintendo Switch 2 Pro uses another driver
1396+
if (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH2_PRO) {
1397+
return false;
1398+
}
1399+
return true;
13921400
}
13931401

13941402
static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)

0 commit comments

Comments
 (0)