Delay delivery of the pause button release on MFI controllers so it doesn't happen in the same frame as the button press

This commit is contained in:
Sam Lantinga 2018-03-08 16:32:22 -08:00
parent 92847022f5
commit 129431b4f4
2 changed files with 37 additions and 29 deletions

View File

@ -31,6 +31,7 @@
#include "SDL_joystick.h" #include "SDL_joystick.h"
#include "SDL_hints.h" #include "SDL_hints.h"
#include "SDL_stdinc.h" #include "SDL_stdinc.h"
#include "SDL_timer.h"
#include "../SDL_sysjoystick.h" #include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h" #include "../SDL_joystick_c.h"
#include "../steam/SDL_steamcontroller.h" #include "../steam/SDL_steamcontroller.h"
@ -84,12 +85,12 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr
{ {
#ifdef SDL_JOYSTICK_MFI #ifdef SDL_JOYSTICK_MFI
const Uint16 BUS_BLUETOOTH = 0x05; const Uint16 BUS_BLUETOOTH = 0x05;
const Uint16 VENDOR_APPLE = 0x05AC; const Uint16 VENDOR_APPLE = 0x05AC;
Uint16 *guid16 = (Uint16 *)device->guid.data; Uint16 *guid16 = (Uint16 *)device->guid.data;
Uint16 vendor = 0; Uint16 vendor = 0;
Uint16 product = 0; Uint16 product = 0;
Uint16 version = 0; Uint16 version = 0;
Uint8 subtype = 0; Uint8 subtype = 0;
const char *name = NULL; const char *name = NULL;
/* Explicitly retain the controller because SDL_JoystickDeviceItem is a /* 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); device->name = SDL_strdup(name);
if (controller.extendedGamepad) { if (controller.extendedGamepad) {
vendor = VENDOR_APPLE; vendor = VENDOR_APPLE;
product = 1; product = 1;
subtype = 1; subtype = 1;
device->naxes = 6; /* 2 thumbsticks and 2 triggers */ device->naxes = 6; /* 2 thumbsticks and 2 triggers */
device->nhats = 1; /* d-pad */ device->nhats = 1; /* d-pad */
device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */ device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
} else if (controller.gamepad) { } else if (controller.gamepad) {
vendor = VENDOR_APPLE; vendor = VENDOR_APPLE;
product = 2; product = 2;
subtype = 2; subtype = 2;
device->naxes = 0; /* no traditional analog inputs */ device->naxes = 0; /* no traditional analog inputs */
device->nhats = 1; /* d-pad */ device->nhats = 1; /* d-pad */
device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */ device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */
} }
#if TARGET_OS_TV #if TARGET_OS_TV
else if (controller.microGamepad) { else if (controller.microGamepad) {
vendor = VENDOR_APPLE; vendor = VENDOR_APPLE;
product = 3; product = 3;
subtype = 3; subtype = 3;
device->naxes = 2; /* treat the touch surface as two axes */ device->naxes = 2; /* treat the touch surface as two axes */
device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */ device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */
device->nbuttons = 3; /* AX, pause button */ 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. */ /* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(BUS_BLUETOOTH); *guid16++ = SDL_SwapLE16(BUS_BLUETOOTH);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(vendor); *guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(product); *guid16++ = SDL_SwapLE16(product);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(version); *guid16++ = SDL_SwapLE16(version);
*guid16++ = 0; *guid16++ = 0;
/* Note that this is an MFI controller and what subtype it is */ /* Note that this is an MFI controller and what subtype it is */
device->guid.data[14] = 'm'; device->guid.data[14] = 'm';
device->guid.data[15] = subtype; device->guid.data[15] = subtype;
/* This will be set when the first button press of the controller is /* This will be set when the first button press of the controller is
* detected. */ * detected. */
@ -559,6 +560,8 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick)
Uint8 hatstate = SDL_HAT_CENTERED; Uint8 hatstate = SDL_HAT_CENTERED;
int i; int i;
int updateplayerindex = 0; 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) { if (controller.extendedGamepad) {
GCExtendedGamepad *gamepad = 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++) { 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_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; updateplayerindex = YES;
} }
joystick->hwdata->num_pause_presses = 0; 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) { if (updateplayerindex && controller.playerIndex == -1) {
BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO}; BOOL usedPlayerIndexSlots[4] = {NO, NO, NO, NO};

View File

@ -35,6 +35,7 @@ typedef struct joystick_hwdata
GCController __unsafe_unretained *controller; GCController __unsafe_unretained *controller;
int num_pause_presses; int num_pause_presses;
Uint32 pause_button_down_time;
char *name; char *name;
SDL_Joystick *joystick; SDL_Joystick *joystick;