From 03f8528315fa46c95991a34f3325d7b33ae5538c Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Sat, 02 May 2020 21:48:36 +0000
Subject: [PATCH] Update source to SDL2 2.0.12
---
source/src/joystick/SDL_gamecontroller.c | 130 ++++++++++++++++++++++++++++++++++++-------
1 files changed, 109 insertions(+), 21 deletions(-)
diff --git a/source/src/joystick/SDL_gamecontroller.c b/source/src/joystick/SDL_gamecontroller.c
index eb1ef06..6ebdf66 100644
--- a/source/src/joystick/SDL_gamecontroller.c
+++ b/source/src/joystick/SDL_gamecontroller.c
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
- Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+ Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -42,7 +42,9 @@
/* 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:"
+#define SDL_CONTROLLER_PLATFORM_FIELD "platform:"
+#define SDL_CONTROLLER_SDKGE_FIELD "sdk>=:"
+#define SDL_CONTROLLER_SDKLE_FIELD "sdk<=:"
/* a list of currently opened game controllers */
static SDL_GameController *SDL_gamecontrollers = NULL;
@@ -202,13 +204,14 @@
{
int i, num_events;
SDL_Event *events;
+ SDL_bool isstack;
num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
if (num_events <= 0) {
return;
}
- events = SDL_stack_alloc(SDL_Event, num_events);
+ events = SDL_small_alloc(SDL_Event, num_events, &isstack);
if (!events) {
return;
}
@@ -219,7 +222,7 @@
}
SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
- SDL_stack_free(events);
+ SDL_small_free(events, isstack);
}
static SDL_bool HasSameOutput(SDL_ExtendedGameControllerBind *a, SDL_ExtendedGameControllerBind *b)
@@ -641,8 +644,8 @@
int i = 0;
const char *pchPos = pchString;
- SDL_zero(szGameButton);
- SDL_zero(szJoystickButton);
+ SDL_zeroa(szGameButton);
+ SDL_zeroa(szJoystickButton);
while (pchPos && *pchPos) {
if (*pchPos == ':') {
@@ -654,8 +657,8 @@
i = 0;
bGameButton = SDL_TRUE;
SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
- SDL_zero(szGameButton);
- SDL_zero(szJoystickButton);
+ SDL_zeroa(szGameButton);
+ SDL_zeroa(szJoystickButton);
} else if (bGameButton) {
if (i >= sizeof(szGameButton)) {
@@ -675,8 +678,10 @@
pchPos++;
}
- SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
-
+ /* No more values if the string was terminated by a comma. Don't report an error. */
+ if (szGameButton[0] != '\0' || szJoystickButton[0] != '\0') {
+ SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
+ }
}
/*
@@ -688,7 +693,9 @@
gamecontroller->name = pchName;
gamecontroller->num_bindings = 0;
- SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
+ if (gamecontroller->joystick->naxes) {
+ SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
+ }
SDL_PrivateGameControllerParseControllerConfigString(gamecontroller, pchMapping);
@@ -876,7 +883,7 @@
for ( pPrevMapping = s_pSupportedControllers, pCurrMapping = pPrevMapping->next;
pCurrMapping;
pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next ) {
- continue;
+ /* continue; */
}
pPrevMapping->next = pControllerMapping;
} else {
@@ -994,6 +1001,17 @@
if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string));
}
+
+ /* Remove trailing comma */
+ {
+ int pos = (int)SDL_strlen(mapping_string) - 1;
+ if (pos >= 0) {
+ if (mapping_string[pos] == ',') {
+ mapping_string[pos] = '\0';
+ }
+ }
+ }
+
return SDL_PrivateAddMappingForGUID(guid, mapping_string,
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
@@ -1014,7 +1032,7 @@
/* The Linux driver xpad.c maps the wireless dpad to buttons */
SDL_bool existing;
mapping = SDL_PrivateAddMappingForGUID(guid,
-"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
+"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3",
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
}
@@ -1120,7 +1138,7 @@
}
}
}
-
+
line = line_end + 1;
}
@@ -1145,6 +1163,27 @@
if (!mappingString) {
return SDL_InvalidParamError("mappingString");
}
+
+#ifdef ANDROID
+ { /* Extract and verify the SDK version */
+ const char *tmp;
+
+ tmp = SDL_strstr(mappingString, SDL_CONTROLLER_SDKGE_FIELD);
+ if (tmp != NULL) {
+ tmp += SDL_strlen(SDL_CONTROLLER_SDKGE_FIELD);
+ if (!(SDL_GetAndroidSDKVersion() >= SDL_atoi(tmp))) {
+ return SDL_SetError("SDK version %d < minimum version %d", SDL_GetAndroidSDKVersion(), SDL_atoi(tmp));
+ }
+ }
+ tmp = SDL_strstr(mappingString, SDL_CONTROLLER_SDKLE_FIELD);
+ if (tmp != NULL) {
+ tmp += SDL_strlen(SDL_CONTROLLER_SDKLE_FIELD);
+ if (!(SDL_GetAndroidSDKVersion() <= SDL_atoi(tmp))) {
+ return SDL_SetError("SDK version %d > maximum version %d", SDL_GetAndroidSDKVersion(), SDL_atoi(tmp));
+ }
+ }
+ }
+#endif
pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString);
if (!pchGUID) {
@@ -1307,15 +1346,17 @@
/*
* Fill the given buffer with the expected controller mapping filepath.
- * Usually this will just be CONTROLLER_MAPPING_FILE, but for Android,
- * we want to get the internal storage path.
+ * Usually this will just be SDL_HINT_GAMECONTROLLERCONFIG_FILE, but for
+ * Android, we want to get the internal storage path.
*/
static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size)
{
-#ifdef CONTROLLER_MAPPING_FILE
-#define STRING(X) SDL_STRINGIFY_ARG(X)
- return SDL_strlcpy(path, STRING(CONTROLLER_MAPPING_FILE), size) < size;
-#elif defined(__ANDROID__)
+ const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG_FILE);
+ if (hint && *hint) {
+ return SDL_strlcpy(path, hint, size) < size;
+ }
+
+#if defined(__ANDROID__)
return SDL_snprintf(path, size, "%s/controller_map.txt", SDL_AndroidGetInternalStoragePath()) < size;
#else
return SDL_FALSE;
@@ -1395,6 +1436,16 @@
/**
+ * Get the type of a game controller.
+ */
+SDL_GameControllerType
+SDL_GameControllerTypeForIndex(int joystick_index)
+{
+ return SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGetDeviceGUID(joystick_index), SDL_JoystickNameForIndex(joystick_index));
+}
+
+
+/**
* 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.
@@ -1464,6 +1515,13 @@
Uint16 product;
Uint16 version;
Uint32 vidpid;
+
+#if defined(__LINUX__)
+ if (name && SDL_strstr(name, "Controller Motion Sensors")) {
+ /* Don't treat the PS3 and PS4 motion controls as a separate game controller */
+ return SDL_TRUE;
+ }
+#endif
if (SDL_allowed_controllers.num_entries == 0 &&
SDL_ignored_controllers.num_entries == 0) {
@@ -1635,6 +1693,8 @@
float normalized_value = (float)(value - binding->input.axis.axis_min) / (binding->input.axis.axis_max - binding->input.axis.axis_min);
value = binding->output.axis.axis_min + (int)(normalized_value * (binding->output.axis.axis_max - binding->output.axis.axis_min));
}
+ } else {
+ value = 0;
}
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
value = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
@@ -1716,10 +1776,25 @@
}
}
+SDL_GameControllerType
+SDL_GameControllerGetType(SDL_GameController *gamecontroller)
+{
+ return SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(gamecontroller)), SDL_JoystickName(SDL_GameControllerGetJoystick(gamecontroller)));
+}
+
int
SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
{
return SDL_JoystickGetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller));
+}
+
+/**
+ * Set the player index of an opened game controller
+ */
+void
+SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index)
+{
+ SDL_JoystickSetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller), player_index);
}
Uint16
@@ -1766,7 +1841,7 @@
/*
- * Find the SDL_GameController that owns this instance id
+ * Return the SDL_GameController associated with an instance id.
*/
SDL_GameController *
SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
@@ -1787,6 +1862,19 @@
}
+/**
+ * Return the SDL_GameController associated with a player index.
+ */
+SDL_GameController *SDL_GameControllerFromPlayerIndex(int player_index)
+{
+ SDL_Joystick *joystick = SDL_JoystickFromPlayerIndex(player_index);
+ if (joystick) {
+ return SDL_GameControllerFromInstanceID(joystick->instance_id);
+ }
+ return NULL;
+}
+
+
/*
* Get the SDL joystick layer binding for this controller axis mapping
*/
--
Gitblit v1.9.3