From a2c1d83c0232b3ae7a3449cfbf6fc97237489cfa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 7 Mar 2018 18:09:58 -0800 Subject: [PATCH] Include a USB VID/PID for Apple MFI controllers This is just placeholder VID/PID, but allows code that works with VID/PID to identify the MFI controllers easily. --- src/joystick/SDL_gamecontrollerdb.h | 6 +-- src/joystick/iphoneos/SDL_sysjoystick.m | 55 ++++++++++++++----------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 9552e7d458fdc..652cf4eb1dae4 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -215,9 +215,9 @@ static const char *s_ControllerMappings [] = "050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", /* The DPAD doesn't seem to work on this controller on Android TV? */ #endif #if defined(SDL_JOYSTICK_MFI) - "4d466947616d65706164010000000000,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", - "4d466947616d65706164020000000000,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,", - "4d466947616d65706164030000000000,Remote,a:b0,b:b2,leftx:a0,lefty:a1,", + "05000000ac0500000100000000006d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,guide:b6,x:b2,y:b3,", + "05000000ac0500000200000000006d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,guide:b6,x:b2,y:b3,", + "05000000ac0500000300000000006d03,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,", #endif #if defined(SDL_JOYSTICK_EMSCRIPTEN) diff --git a/src/joystick/iphoneos/SDL_sysjoystick.m b/src/joystick/iphoneos/SDL_sysjoystick.m index d6014980c689c..9140e574bb3c0 100644 --- a/src/joystick/iphoneos/SDL_sysjoystick.m +++ b/src/joystick/iphoneos/SDL_sysjoystick.m @@ -83,6 +83,14 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller) { #ifdef SDL_JOYSTICK_MFI + const Uint16 BUS_BLUETOOTH = 0x05; + const Uint16 VENDOR_APPLE = 0x05AC; + Uint16 *guid16 = (Uint16 *)device->guid.data; + Uint16 vendor = 0; + Uint16 product = 0; + Uint16 version = 0; + Uint8 subtype = 0; + const char *name = NULL; /* Explicitly retain the controller because SDL_JoystickDeviceItem is a * struct, and ARC doesn't work with structs. */ @@ -98,40 +106,26 @@ device->name = SDL_strdup(name); - device->guid.data[0] = 'M'; - device->guid.data[1] = 'F'; - device->guid.data[2] = 'i'; - device->guid.data[3] = 'G'; - device->guid.data[4] = 'a'; - device->guid.data[5] = 'm'; - device->guid.data[6] = 'e'; - device->guid.data[7] = 'p'; - device->guid.data[8] = 'a'; - device->guid.data[9] = 'd'; - - if (controller.extendedGamepad) { - device->guid.data[10] = 1; - } else if (controller.gamepad) { - device->guid.data[10] = 2; - } -#if TARGET_OS_TV - else if (controller.microGamepad) { - device->guid.data[10] = 3; - device->remote = SDL_TRUE; - } -#endif /* TARGET_OS_TV */ - if (controller.extendedGamepad) { + vendor = VENDOR_APPLE; + product = 1; + subtype = 1; device->naxes = 6; /* 2 thumbsticks and 2 triggers */ device->nhats = 1; /* d-pad */ device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */ } else if (controller.gamepad) { + vendor = VENDOR_APPLE; + product = 2; + subtype = 2; device->naxes = 0; /* no traditional analog inputs */ device->nhats = 1; /* d-pad */ device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */ } #if TARGET_OS_TV else if (controller.microGamepad) { + vendor = VENDOR_APPLE; + product = 3; + subtype = 3; device->naxes = 2; /* treat the touch surface as two axes */ device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */ device->nbuttons = 3; /* AX, pause button */ @@ -140,6 +134,21 @@ } #endif /* TARGET_OS_TV */ + /* We only need 16 bits for each of these; space them out to fill 128. */ + /* Byteswap so devices get same GUID on little/big endian platforms. */ + *guid16++ = SDL_SwapLE16(BUS_BLUETOOTH); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(vendor); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(product); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(version); + *guid16++ = 0; + + /* Note that this is an MFI controller and what subtype it is */ + device->guid.data[14] = 'm'; + device->guid.data[15] = subtype; + /* This will be set when the first button press of the controller is * detected. */ controller.playerIndex = -1;