Added additional game controller button support on iOS/tvOS

This commit is contained in:
Sam Lantinga 2020-11-06 16:42:46 -08:00
parent cf8d3befe6
commit faeac6e86c
4 changed files with 92 additions and 13 deletions

View file

@ -827,11 +827,13 @@ 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,",
"050000004c050000cc090000df070000,DUALSHOCK 4 Wireless 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,",
"050000004c050000cc090000ff070000,DUALSHOCK 4 Wireless 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,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"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,",
"050000004c050000cc090000ff070000,PS4 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,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
"050000004c050000cc090000ff876d01,PS4 Controller,a:b0,aux1:b11,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,",
"05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"050000005e040000050b0000ff876d01,Xbox Elite Wireless Controller,a:b0,aux1:b11,aux2:b12,aux3:b13,aux4:b13,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,",
"050000005e040000e0020000df070000,Xbox Wireless 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,",
"050000005e040000e0020000ff070000,Xbox Wireless 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,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,",
#endif

View file

@ -33,6 +33,7 @@
#include "SDL_stdinc.h"
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"
#include "../usb_ids.h"
#if !SDL_EVENTS_DISABLED
@ -77,6 +78,7 @@ static id disconnectObserver = nil;
#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 140000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140000) || (__MAC_OS_VERSION_MAX_ALLOWED > 1500000)
#define ENABLE_MFI_BATTERY
#define ENABLE_MFI_RUMBLE
#define ENABLE_PHYSICAL_INPUT_PROFILE
#endif
#ifdef ENABLE_MFI_RUMBLE
@ -116,9 +118,6 @@ static void
IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
{
#ifdef SDL_JOYSTICK_MFI
const Uint16 VENDOR_APPLE = 0x05AC;
const Uint16 VENDOR_MICROSOFT = 0x045e;
const Uint16 VENDOR_SONY = 0x054C;
Uint16 *guid16 = (Uint16 *)device->guid.data;
Uint16 vendor = 0;
Uint16 product = 0;
@ -188,16 +187,60 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
if (!has_direct_menu) {
device->uses_pause_handler = SDL_TRUE;
}
#ifdef ENABLE_PHYSICAL_INPUT_PROFILE
if ([controller respondsToSelector:@selector(physicalInputProfile)]) {
if (controller.physicalInputProfile.buttons[GCInputDualShockTouchpadButton] != nil) {
device->has_dualshock_touchpad = SDL_TRUE;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_AUX1);
++nbuttons;
}
if (controller.physicalInputProfile.buttons[GCInputXboxPaddleOne] != nil) {
device->has_xbox_paddles = SDL_TRUE;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_AUX1);
++nbuttons;
}
if (controller.physicalInputProfile.buttons[GCInputXboxPaddleTwo] != nil) {
device->has_xbox_paddles = SDL_TRUE;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_AUX2);
++nbuttons;
}
if (controller.physicalInputProfile.buttons[GCInputXboxPaddleThree] != nil) {
device->has_xbox_paddles = SDL_TRUE;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_AUX3);
++nbuttons;
}
if (controller.physicalInputProfile.buttons[GCInputXboxPaddleFour] != nil) {
device->has_xbox_paddles = SDL_TRUE;
device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_AUX4);
++nbuttons;
}
}
#endif
#pragma clang diagnostic pop
if (is_xbox) {
vendor = VENDOR_MICROSOFT;
product = 0x02E0; /* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */
} else if (is_ps4) {
vendor = VENDOR_SONY;
product = 0x09CC; /* Assume DS4 Slim unless/until GCController flows VID/PID */
vendor = USB_VENDOR_MICROSOFT;
if (device->has_xbox_paddles) {
/* Assume Xbox One Elite Series 2 Controller unless/until GCController flows VID/PID */
product = USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH;
subtype = 1;
} else {
vendor = VENDOR_APPLE;
/* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */
product = USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH;
subtype = 0;
}
} else if (is_ps4) {
/* Assume DS4 Slim unless/until GCController flows VID/PID */
vendor = USB_VENDOR_SONY;
product = USB_PRODUCT_SONY_DS4_SLIM;
if ( device->has_dualshock_touchpad ) {
subtype = 1;
} else {
subtype = 0;
}
} else {
vendor = USB_VENDOR_APPLE;
product = 1;
subtype = 1;
}
@ -220,7 +263,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
nbuttons += 7;
device->uses_pause_handler = SDL_TRUE;
vendor = VENDOR_APPLE;
vendor = USB_VENDOR_APPLE;
product = 2;
subtype = 2;
device->naxes = 0; /* no traditional analog inputs */
@ -239,7 +282,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
++nbuttons;
device->uses_pause_handler = SDL_TRUE;
vendor = VENDOR_APPLE;
vendor = USB_VENDOR_APPLE;
product = 3;
subtype = 3;
device->naxes = 2; /* treat the touch surface as two axes */
@ -700,6 +743,37 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
buttons[button_count++] = gamepad.buttonMenu.isPressed;
}
}
#ifdef ENABLE_PHYSICAL_INPUT_PROFILE
if (joystick->hwdata->has_dualshock_touchpad) {
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_AUX1)) {
buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputDualShockTouchpadButton].isPressed;
}
}
if (joystick->hwdata->has_xbox_paddles) {
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_AUX1)) {
buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleOne].isPressed;
}
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_AUX2)) {
buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleTwo].isPressed;
}
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_AUX3)) {
buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleThree].isPressed;
}
if (joystick->hwdata->button_mask & (1 << SDL_CONTROLLER_BUTTON_AUX4)) {
buttons[button_count++] = controller.physicalInputProfile.buttons[GCInputXboxPaddleFour].isPressed;
}
/*
SDL_Log("Paddles: [%d,%d,%d,%d]",
controller.physicalInputProfile.buttons[GCInputXboxPaddleOne].isPressed,
controller.physicalInputProfile.buttons[GCInputXboxPaddleTwo].isPressed,
controller.physicalInputProfile.buttons[GCInputXboxPaddleThree].isPressed,
controller.physicalInputProfile.buttons[GCInputXboxPaddleFour].isPressed);
*/
}
#endif
#pragma clang diagnostic pop
hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad);

View file

@ -47,7 +47,9 @@ typedef struct joystick_hwdata
int naxes;
int nbuttons;
int nhats;
Uint16 button_mask;
Uint32 button_mask;
SDL_bool has_dualshock_touchpad;
SDL_bool has_xbox_paddles;
struct joystick_hwdata *next;
} joystick_hwdata;

View file

@ -24,6 +24,7 @@
/* Definitions of useful USB VID/PID values */
#define USB_VENDOR_APPLE 0x05ac
#define USB_VENDOR_HYPERKIN 0x2e24
#define USB_VENDOR_MICROSOFT 0x045e
#define USB_VENDOR_NINTENDO 0x057e