diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 1fa034747..1e7f1f43f 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -913,6 +913,11 @@ static const char *s_ControllerMappings [] = "05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,", + "050000007e050000062000004f060000,Nintendo Switch Joy-Con (L),+leftx:h0.1,+lefty:h0.2,-leftx:h0.4,-lefty:h0.8,dpdown:b2,dpleft:b0,dpright:b3,dpup:b1,leftshoulder:b4,misc1:b6,rightshoulder:b5,", + "050000007e0500000e200000df070000,Nintendo Switch Joy-Con (L/R),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000e200000df070000,Nintendo Switch Joy-Con (L/R),a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+rightx:h0.4,+righty:h0.8,-rightx:h0.1,-righty:h0.2,a:b0,b:b1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+rightx:h0.4,+righty:h0.8,-rightx:h0.1,-righty:h0.2,a:b1,b:b0,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", diff --git a/src/joystick/iphoneos/SDL_mfijoystick.m b/src/joystick/iphoneos/SDL_mfijoystick.m index 639ee2797..ad542848c 100644 --- a/src/joystick/iphoneos/SDL_mfijoystick.m +++ b/src/joystick/iphoneos/SDL_mfijoystick.m @@ -188,6 +188,36 @@ IsControllerSwitchPro(GCController *controller) return FALSE; } static BOOL +IsControllerSwitchJoyConL(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (L)"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL +IsControllerSwitchJoyConR(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (R)"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL +IsControllerSwitchJoyConPair(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (L/R)"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller) { Uint16 *guid16 = (Uint16 *)device->guid.data; @@ -222,8 +252,9 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle BOOL is_ps4 = IsControllerPS4(controller); BOOL is_ps5 = IsControllerPS5(controller); BOOL is_switch_pro = IsControllerSwitchPro(controller); + BOOL is_switch_joycon_pair = IsControllerSwitchJoyConPair(controller); #if TARGET_OS_TV - BOOL is_MFi = (!is_xbox && !is_ps4 && !is_ps5 && !is_switch_pro); + BOOL is_MFi = (!is_xbox && !is_ps4 && !is_ps5 && !is_switch_pro && !is_switch_joycon_pair); #endif int nbuttons = 0; BOOL has_direct_menu; @@ -262,7 +293,8 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_BACK); ++nbuttons; } - if ([gamepad respondsToSelector:@selector(buttonHome)] && gamepad.buttonHome) { + /* The Nintendo Switch JoyCon home button doesn't ever show as being held down */ + if ([gamepad respondsToSelector:@selector(buttonHome)] && gamepad.buttonHome && !is_switch_joycon_pair) { device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_GUIDE); ++nbuttons; } @@ -347,6 +379,10 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle vendor = USB_VENDOR_NINTENDO; product = USB_PRODUCT_NINTENDO_SWITCH_PRO; subtype = 0; + } else if (is_switch_joycon_pair) { + vendor = USB_VENDOR_NINTENDO; + product = USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_GRIP; + subtype = 0; } else { vendor = USB_VENDOR_APPLE; product = 1; @@ -367,8 +403,24 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle device->nbuttons = nbuttons; } else if (controller.gamepad) { + BOOL is_switch_joyconL = IsControllerSwitchJoyConL(controller); + BOOL is_switch_joyconR = IsControllerSwitchJoyConR(controller); int nbuttons = 0; + if (is_switch_joyconL) { + vendor = USB_VENDOR_NINTENDO; + product = USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_LEFT; + subtype = 0; + } else if (is_switch_joyconR) { + vendor = USB_VENDOR_NINTENDO; + product = USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT; + subtype = 0; + } else { + vendor = USB_VENDOR_APPLE; + product = 2; + subtype = 2; + } + /* These buttons are part of the original MFi spec */ device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A); device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); @@ -380,9 +432,6 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle nbuttons += 7; device->uses_pause_handler = SDL_TRUE; - vendor = USB_VENDOR_APPLE; - product = 2; - subtype = 2; device->naxes = 0; /* no traditional analog inputs */ device->nhats = 1; /* d-pad */ device->nbuttons = nbuttons; @@ -877,6 +926,23 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) int i; int pause_button_index = 0; +#ifdef DEBUG_CONTROLLER_STATE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (controller.physicalInputProfile) { + for (id key in controller.physicalInputProfile.buttons) { + GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; + if (button.isPressed) + NSLog(@"Button %@ = %s\n", key, button.isPressed ? "pressed" : "released"); + } + for (id key in controller.physicalInputProfile.axes) { + GCControllerAxisInput *axis = controller.physicalInputProfile.axes[key]; + if (axis.value != 0.0f) + NSLog(@"Axis %@ = %.2f\n", key, axis.value); + } + } + } +#endif + if (controller.extendedGamepad) { GCExtendedGamepad *gamepad = controller.extendedGamepad;