summaryrefslogtreecommitdiff
path: root/Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-01-31 18:38:35 +0800
committerchai <chaifix@163.com>2019-01-31 18:38:35 +0800
commit2ec55fd974a63b705a4777c256d2222c874fa043 (patch)
tree48f1fea59ee9fc713a28a9aac3f05b98dc5ae66f /Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c
parentc581dfbf1e849f393861d15e82aa6446c0c1c310 (diff)
*SDL project
Diffstat (limited to 'Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c')
-rw-r--r--Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c322
1 files changed, 263 insertions, 59 deletions
diff --git a/Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c b/Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c
index b0f833a..eb1ef06 100644
--- a/Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c
+++ b/Source/3rdParty/SDL2/src/joystick/SDL_gamecontroller.c
@@ -25,6 +25,7 @@
#include "SDL_events.h"
#include "SDL_assert.h"
#include "SDL_hints.h"
+#include "SDL_timer.h"
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_gamecontrollerdb.h"
@@ -38,6 +39,9 @@
#endif
+/* Many controllers turn the center button into an instantaneous button press */
+#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS 250
+
#define SDL_CONTROLLER_PLATFORM_FIELD "platform:"
/* a list of currently opened game controllers */
@@ -97,8 +101,9 @@ typedef struct _ControllerMapping_t
static SDL_JoystickGUID s_zeroGUID;
static ControllerMapping_t *s_pSupportedControllers = NULL;
+static ControllerMapping_t *s_pDefaultMapping = NULL;
+static ControllerMapping_t *s_pHIDAPIMapping = NULL;
static ControllerMapping_t *s_pXInputMapping = NULL;
-static ControllerMapping_t *s_pEmscriptenMapping = NULL;
/* The SDL game controller structure */
struct _SDL_GameController
@@ -106,12 +111,12 @@ struct _SDL_GameController
SDL_Joystick *joystick; /* underlying joystick device */
int ref_count;
- SDL_JoystickGUID guid;
const char *name;
int num_bindings;
SDL_ExtendedGameControllerBind *bindings;
SDL_ExtendedGameControllerBind **last_match_axis;
Uint8 *last_hat_mask;
+ Uint32 guide_button_down;
struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
};
@@ -416,7 +421,7 @@ static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event * ev
/*
* Helper function to scan the mappings database for a controller with the specified GUID
*/
-static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
+static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid, SDL_bool exact_match)
{
ControllerMapping_t *pSupportedController = s_pSupportedControllers;
while (pSupportedController) {
@@ -425,6 +430,18 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
}
pSupportedController = pSupportedController->next;
}
+ if (!exact_match) {
+ if (SDL_IsJoystickHIDAPI(*guid)) {
+ /* This is a HIDAPI device */
+ return s_pHIDAPIMapping;
+ }
+#if SDL_JOYSTICK_XINPUT
+ if (SDL_IsJoystickXInput(*guid)) {
+ /* This is an XInput device */
+ return s_pXInputMapping;
+ }
+#endif
+ }
return NULL;
}
@@ -665,11 +682,10 @@ SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecon
/*
* Make a new button mapping struct
*/
-static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)
+static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
{
int i;
- gamecontroller->guid = guid;
gamecontroller->name = pchName;
gamecontroller->num_bindings = 0;
SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
@@ -783,14 +799,16 @@ static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pContro
{
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
while (gamecontrollerlist) {
- if (!SDL_memcmp(&gamecontrollerlist->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
- SDL_Event event;
- event.type = SDL_CONTROLLERDEVICEREMAPPED;
- event.cdevice.which = gamecontrollerlist->joystick->instance_id;
- SDL_PushEvent(&event);
-
+ if (!SDL_memcmp(&gamecontrollerlist->joystick->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
/* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
- SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
+ SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->name, pControllerMapping->mapping);
+
+ {
+ SDL_Event event;
+ event.type = SDL_CONTROLLERDEVICEREMAPPED;
+ event.cdevice.which = gamecontrollerlist->joystick->instance_id;
+ SDL_PushEvent(&event);
+ }
}
gamecontrollerlist = gamecontrollerlist->next;
@@ -820,7 +838,7 @@ SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString,
return NULL;
}
- pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
+ pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID, SDL_TRUE);
if (pControllerMapping) {
/* Only overwrite the mapping if the priority is the same or higher. */
if (pControllerMapping->priority <= priority) {
@@ -869,6 +887,119 @@ SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString,
return pControllerMapping;
}
+#ifdef __ANDROID__
+/*
+ * Helper function to guess at a mapping based on the elements reported for this controller
+ */
+static ControllerMapping_t *SDL_CreateMappingForAndroidController(const char *name, SDL_JoystickGUID guid)
+{
+ SDL_bool existing;
+ char name_string[128];
+ char mapping_string[1024];
+ int button_mask;
+ int axis_mask;
+
+ button_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-4]));
+ axis_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-2]));
+ if (!button_mask && !axis_mask) {
+ /* Accelerometer, shouldn't have a game controller mapping */
+ return NULL;
+ }
+
+ /* Remove any commas in the name */
+ SDL_strlcpy(name_string, name, sizeof(name_string));
+ {
+ char *spot;
+ for (spot = name_string; *spot; ++spot) {
+ if (*spot == ',') {
+ *spot = ' ';
+ }
+ }
+ }
+ SDL_snprintf(mapping_string, sizeof(mapping_string), "none,%s,", name_string);
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_A)) {
+ SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_B)) {
+ SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string));
+ } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
+ /* Use the back button as "B" for easy UI navigation with TV remotes */
+ SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string));
+ button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_BACK);
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_X)) {
+ SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_Y)) {
+ SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
+ SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string));
+ }
+#if 0 /* The guide button generally isn't functional (or acts as a home button) on most Android controllers */
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) {
+ SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string));
+#if 0 /* Actually this will be done in Steam */
+ } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
+ /* The guide button doesn't exist, use the start button instead,
+ so you can do Steam guide button chords and open the Steam overlay.
+ */
+ SDL_strlcat(mapping_string, "guide:b6,", sizeof(mapping_string));
+ button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_START);
+#endif
+ }
+#endif
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
+ SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) {
+ SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) {
+ SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) {
+ SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) {
+ SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP)) {
+ SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN)) {
+ SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT)) {
+ SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string));
+ }
+ if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
+ SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string));
+ }
+ if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX)) {
+ SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string));
+ }
+ if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY)) {
+ SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string));
+ }
+ if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX)) {
+ SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string));
+ }
+ if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY)) {
+ SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string));
+ }
+ if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT)) {
+ SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string));
+ }
+ if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
+ SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string));
+ }
+ return SDL_PrivateAddMappingForGUID(guid, mapping_string,
+ &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
+}
+#endif /* __ANDROID__ */
+
+
/*
* Helper function to determine pre-calculated offset to certain joystick mappings
*/
@@ -876,14 +1007,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const
{
ControllerMapping_t *mapping;
- mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
-#if defined(SDL_JOYSTICK_EMSCRIPTEN)
- if (!mapping && s_pEmscriptenMapping) {
- mapping = s_pEmscriptenMapping;
- }
-#else
- (void) s_pEmscriptenMapping; /* pacify ARMCC */
-#endif
+ mapping = SDL_PrivateGetControllerMappingForGUID(&guid, SDL_FALSE);
#ifdef __LINUX__
if (!mapping && name) {
if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
@@ -901,6 +1025,14 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const
mapping = s_pXInputMapping;
}
}
+#ifdef __ANDROID__
+ if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) {
+ mapping = SDL_CreateMappingForAndroidController(name, guid);
+ }
+#endif
+ if (!mapping) {
+ mapping = s_pDefaultMapping;
+ }
return mapping;
}
@@ -921,20 +1053,6 @@ static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
name = SDL_JoystickNameForIndex(device_index);
guid = SDL_JoystickGetDeviceGUID(device_index);
mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid);
-#if SDL_JOYSTICK_XINPUT
- if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
- mapping = s_pXInputMapping;
- }
-#endif
-#if defined(__ANDROID__)
- if (!mapping && SDL_SYS_IsDPAD_DeviceIndex(device_index)) {
- SDL_bool existing;
- char mapping_string[1024];
- SDL_snprintf(mapping_string, sizeof(mapping_string), "none,%s,a:b0,b:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,", name);
- mapping = SDL_PrivateAddMappingForGUID(guid, mapping_string,
- &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
- }
-#endif /* __ANDROID__ */
SDL_UnlockJoysticks();
return mapping;
}
@@ -1018,8 +1136,9 @@ SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMap
{
char *pchGUID;
SDL_JoystickGUID jGUID;
+ SDL_bool is_default_mapping = SDL_FALSE;
+ SDL_bool is_hidapi_mapping = SDL_FALSE;
SDL_bool is_xinput_mapping = SDL_FALSE;
- SDL_bool is_emscripten_mapping = SDL_FALSE;
SDL_bool existing = SDL_FALSE;
ControllerMapping_t *pControllerMapping;
@@ -1031,12 +1150,13 @@ SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMap
if (!pchGUID) {
return SDL_SetError("Couldn't parse GUID from %s", mappingString);
}
- if (!SDL_strcasecmp(pchGUID, "xinput")) {
+ if (!SDL_strcasecmp(pchGUID, "default")) {
+ is_default_mapping = SDL_TRUE;
+ } else if (!SDL_strcasecmp(pchGUID, "hidapi")) {
+ is_hidapi_mapping = SDL_TRUE;
+ } else if (!SDL_strcasecmp(pchGUID, "xinput")) {
is_xinput_mapping = SDL_TRUE;
}
- if (!SDL_strcasecmp(pchGUID, "emscripten")) {
- is_emscripten_mapping = SDL_TRUE;
- }
jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
SDL_free(pchGUID);
@@ -1048,12 +1168,13 @@ SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMap
if (existing) {
return 0;
} else {
- if (is_xinput_mapping) {
+ if (is_default_mapping) {
+ s_pDefaultMapping = pControllerMapping;
+ } else if (is_hidapi_mapping) {
+ s_pHIDAPIMapping = pControllerMapping;
+ } else if (is_xinput_mapping) {
s_pXInputMapping = pControllerMapping;
}
- if (is_emscripten_mapping) {
- s_pEmscriptenMapping = pControllerMapping;
- }
return 1;
}
}
@@ -1125,7 +1246,7 @@ char *
SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)
{
char *pMappingString = NULL;
- ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
+ ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid, SDL_FALSE);
if (mapping) {
char pchGUID[33];
size_t needed;
@@ -1152,7 +1273,7 @@ SDL_GameControllerMapping(SDL_GameController * gamecontroller)
return NULL;
}
- return SDL_GameControllerMappingForGUID(gamecontroller->guid);
+ return SDL_GameControllerMappingForGUID(gamecontroller->joystick->guid);
}
static void
@@ -1263,12 +1384,50 @@ SDL_GameControllerNameForIndex(int device_index)
{
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (pSupportedController) {
- return pSupportedController->name;
+ if (SDL_strcmp(pSupportedController->name, "*") == 0) {
+ return SDL_JoystickNameForIndex(device_index);
+ } else {
+ return pSupportedController->name;
+ }
}
return NULL;
}
+/**
+ * Get the mapping of a game controller.
+ * This can be called before any controllers are opened.
+ * If no mapping can be found, this function returns NULL.
+ */
+char *
+SDL_GameControllerMappingForDeviceIndex(int joystick_index)
+{
+ char *pMappingString = NULL;
+ ControllerMapping_t *mapping;
+
+ SDL_LockJoysticks();
+ mapping = SDL_PrivateGetControllerMapping(joystick_index);
+ if (mapping) {
+ SDL_JoystickGUID guid;
+ char pchGUID[33];
+ size_t needed;
+ guid = SDL_JoystickGetDeviceGUID(joystick_index);
+ SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
+ /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
+ needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
+ pMappingString = SDL_malloc(needed);
+ if (!pMappingString) {
+ SDL_OutOfMemory();
+ SDL_UnlockJoysticks();
+ return NULL;
+ }
+ SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
+ }
+ SDL_UnlockJoysticks();
+ return pMappingString;
+}
+
+
/*
* Return 1 if the joystick with this name and GUID is a supported controller
*/
@@ -1303,6 +1462,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
int i;
Uint16 vendor;
Uint16 product;
+ Uint16 version;
Uint32 vidpid;
if (SDL_allowed_controllers.num_entries == 0 &&
@@ -1310,8 +1470,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
return SDL_FALSE;
}
- SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
- vidpid = MAKE_VIDPID(vendor, product);
+ SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version);
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
/* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */
@@ -1319,7 +1478,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
#if defined(__LINUX__)
bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
#elif defined(__MACOSX__)
- bSteamVirtualGamepad = (SDL_strncmp(name, "GamePad-", 8) == 0);
+ bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
#elif defined(__WIN32__)
/* We can't tell on Windows, but Steam will block others in input hooks */
bSteamVirtualGamepad = SDL_TRUE;
@@ -1329,6 +1488,8 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
}
}
+ vidpid = MAKE_VIDPID(vendor, product);
+
if (SDL_allowed_controllers.num_entries > 0) {
for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) {
if (vidpid == SDL_allowed_controllers.entries[i]) {
@@ -1356,22 +1517,18 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
SDL_GameController *
SDL_GameControllerOpen(int device_index)
{
+ SDL_JoystickID instance_id;
SDL_GameController *gamecontroller;
SDL_GameController *gamecontrollerlist;
ControllerMapping_t *pSupportedController = NULL;
SDL_LockJoysticks();
- if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
- SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
- SDL_UnlockJoysticks();
- return (NULL);
- }
-
gamecontrollerlist = SDL_gamecontrollers;
/* If the controller is already open, return it */
+ instance_id = SDL_JoystickGetDeviceInstanceID(device_index);
while (gamecontrollerlist) {
- if (SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id) {
+ if (instance_id == gamecontrollerlist->joystick->instance_id) {
gamecontroller = gamecontrollerlist;
++gamecontroller->ref_count;
SDL_UnlockJoysticks();
@@ -1425,7 +1582,7 @@ SDL_GameControllerOpen(int device_index)
}
}
- SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping);
+ SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->name, pSupportedController->mapping);
/* Add the controller to list */
++gamecontroller->ref_count;
@@ -1552,7 +1709,17 @@ SDL_GameControllerName(SDL_GameController * gamecontroller)
if (!gamecontroller)
return NULL;
- return gamecontroller->name;
+ if (SDL_strcmp(gamecontroller->name, "*") == 0) {
+ return SDL_JoystickName(SDL_GameControllerGetJoystick(gamecontroller));
+ } else {
+ return gamecontroller->name;
+ }
+}
+
+int
+SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
+{
+ return SDL_JoystickGetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller));
}
Uint16
@@ -1683,6 +1850,12 @@ SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameControll
}
+int
+SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
+{
+ return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms);
+}
+
void
SDL_GameControllerClose(SDL_GameController * gamecontroller)
{
@@ -1820,6 +1993,24 @@ SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameCon
}
#endif /* !SDL_EVENTS_DISABLED */
+ if (button == SDL_CONTROLLER_BUTTON_GUIDE) {
+ Uint32 now = SDL_GetTicks();
+ if (state == SDL_PRESSED) {
+ gamecontroller->guide_button_down = now;
+
+ if (gamecontroller->joystick->delayed_guide_button) {
+ /* Skip duplicate press */
+ return (0);
+ }
+ } else {
+ if (!SDL_TICKS_PASSED(now, gamecontroller->guide_button_down+SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS) && !gamecontroller->joystick->force_recentering) {
+ gamecontroller->joystick->delayed_guide_button = SDL_TRUE;
+ return (0);
+ }
+ gamecontroller->joystick->delayed_guide_button = SDL_FALSE;
+ }
+ }
+
/* translate the event, if desired */
posted = 0;
#if !SDL_EVENTS_DISABLED
@@ -1868,4 +2059,17 @@ SDL_GameControllerEventState(int state)
#endif /* SDL_EVENTS_DISABLED */
}
+void
+SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
+{
+ SDL_GameController *controllerlist = SDL_gamecontrollers;
+ while (controllerlist) {
+ if (controllerlist->joystick == joystick) {
+ SDL_PrivateGameControllerButton(controllerlist, SDL_CONTROLLER_BUTTON_GUIDE, SDL_RELEASED);
+ break;
+ }
+ controllerlist = controllerlist->next;
+ }
+}
+
/* vi: set ts=4 sw=4 expandtab: */