From 129431b4f486ab35d76c7e5a254a6e0a9d633645 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 8 Mar 2018 16:32:22 -0800 Subject: [PATCH] Delay delivery of the pause button release on MFI controllers so it doesn't happen in the same frame as the button press --- src/joystick/iphoneos/SDL_sysjoystick.m | 65 +++++++++++++---------- src/joystick/iphoneos/SDL_sysjoystick_c.h | 1 + 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/joystick/iphoneos/SDL_sysjoystick.m b/src/joystick/iphoneos/SDL_sysjoystick.m index 9140e574b..71b81d3cf 100644 --- a/src/joystick/iphoneos/SDL_sysjoystick.m +++ b/src/joystick/iphoneos/SDL_sysjoystick.m @@ -31,6 +31,7 @@ #include "SDL_joystick.h" #include "SDL_hints.h" #include "SDL_stdinc.h" +#include "SDL_timer.h" #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" #include "../steam/SDL_steamcontroller.h" @@ -84,12 +85,12 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr { #ifdef SDL_JOYSTICK_MFI const Uint16 BUS_BLUETOOTH = 0x05; - const Uint16 VENDOR_APPLE = 0x05AC; + const Uint16 VENDOR_APPLE = 0x05AC; Uint16 *guid16 = (Uint16 *)device->guid.data; - Uint16 vendor = 0; - Uint16 product = 0; - Uint16 version = 0; - Uint8 subtype = 0; + 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 @@ -107,25 +108,25 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr device->name = SDL_strdup(name); if (controller.extendedGamepad) { - vendor = VENDOR_APPLE; - product = 1; - subtype = 1; + 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; + 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; + 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 */ @@ -138,16 +139,16 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr /* 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; + *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; + /* 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. */ @@ -559,6 +560,8 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick) Uint8 hatstate = SDL_HAT_CENTERED; int i; int updateplayerindex = 0; + const Uint8 pausebutton = joystick->nbuttons - 1; /* The pause button is always last. */ + const Uint32 PAUSE_RELEASE_DELAY_MS = 100; if (controller.extendedGamepad) { GCExtendedGamepad *gamepad = controller.extendedGamepad; @@ -647,17 +650,21 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick) } for (i = 0; i < joystick->hwdata->num_pause_presses; i++) { - /* The pause button is always last. */ - Uint8 pausebutton = joystick->nbuttons - 1; - SDL_PrivateJoystickButton(joystick, pausebutton, SDL_PRESSED); - SDL_PrivateJoystickButton(joystick, pausebutton, SDL_RELEASED); - + joystick->hwdata->pause_button_down_time = SDL_GetTicks(); + if (!joystick->hwdata->pause_button_down_time) { + joystick->hwdata->pause_button_down_time = 1; + } updateplayerindex = YES; } - joystick->hwdata->num_pause_presses = 0; + if (joystick->hwdata->pause_button_down_time && + SDL_TICKS_PASSED(SDL_GetTicks(), joystick->hwdata->pause_button_down_time + PAUSE_RELEASE_DELAY_MS)) { + SDL_PrivateJoystickButton(joystick, pausebutton, SDL_RELEASED); + joystick->hwdata->pause_button_down_time = 0; + } + if (updateplayerindex && controller.playerIndex == -1) { BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO}; diff --git a/src/joystick/iphoneos/SDL_sysjoystick_c.h b/src/joystick/iphoneos/SDL_sysjoystick_c.h index 7be5b04a5..54bc549aa 100644 --- a/src/joystick/iphoneos/SDL_sysjoystick_c.h +++ b/src/joystick/iphoneos/SDL_sysjoystick_c.h @@ -35,6 +35,7 @@ typedef struct joystick_hwdata GCController __unsafe_unretained *controller; int num_pause_presses; + Uint32 pause_button_down_time; char *name; SDL_Joystick *joystick;