Skip to content

Commit

Permalink
Added additional game controller button support on iOS/tvOS
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Nov 7, 2020
1 parent cf8d3be commit faeac6e
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 13 deletions.
6 changes: 4 additions & 2 deletions src/joystick/SDL_gamecontrollerdb.h
Expand Up @@ -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
Expand Down
94 changes: 84 additions & 10 deletions src/joystick/iphoneos/SDL_sysjoystick.m
Expand Up @@ -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
Expand Down Expand Up @@ -77,6 +78,7 @@ @interface GCMicroGamepad (SDL)
#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
Expand Down Expand Up @@ -116,9 +118,6 @@ @interface GCMicroGamepad (SDL)
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;
Expand Down Expand Up @@ -188,16 +187,60 @@ @interface GCMicroGamepad (SDL)
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 */
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 {
/* 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) {
vendor = VENDOR_SONY;
product = 0x09CC; /* Assume DS4 Slim unless/until GCController flows VID/PID */
/* 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 = VENDOR_APPLE;
vendor = USB_VENDOR_APPLE;
product = 1;
subtype = 1;
}
Expand All @@ -220,7 +263,7 @@ @interface GCMicroGamepad (SDL)
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 */
Expand All @@ -239,7 +282,7 @@ @interface GCMicroGamepad (SDL)
++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 */
Expand Down Expand Up @@ -700,6 +743,37 @@ @interface GCMicroGamepad (SDL)
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);
Expand Down
4 changes: 3 additions & 1 deletion src/joystick/iphoneos/SDL_sysjoystick_c.h
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/joystick/usb_ids.h
Expand Up @@ -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
Expand Down

0 comments on commit faeac6e

Please sign in to comment.