Skip to content

Commit

Permalink
Fixed bug 3079 - Allow non destructive SDL_GameControllerAddMappingsF…
Browse files Browse the repository at this point in the history
…romFile

x414e54

It is a bit of a pain to update the library or rely on whatever version the user has on their computer for default mappings.

So providing an easily updatable text file via SDL_GameControllerAddMappingsFromFile is still currently the most viable way. However using this replaces all mappings provided by the SDL_HINT_GAMECONTROLLERCONFIG environment variable which may have come from the user's custom Steam mapping.

There should be an easy way for games to supply extra game controller mappings to fill in the differences between SDL versions without it clobbering the SDL_HINT_GAMECONTROLLERCONFIG environment variable.

Internally the mappings could use a priority system and if the priority is lower then it will not overwrite the mappings.

For now it just assumes SDL_HINT_GAMECONTROLLERCONFIG is the highest priority, the default hardcoded are the lowest and anything set via the API is medium.
  • Loading branch information
slouken committed Nov 11, 2016
1 parent 74e1dd4 commit 23c01c1
Showing 1 changed file with 37 additions and 15 deletions.
52 changes: 37 additions & 15 deletions src/joystick/SDL_gamecontroller.c
Expand Up @@ -80,11 +80,19 @@ struct _SDL_ControllerMapping


/* our hard coded list of mapping support */
typedef enum
{
SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT,
SDL_CONTROLLER_MAPPING_PRIORITY_API,
SDL_CONTROLLER_MAPPING_PRIORITY_USER,
} SDL_ControllerMappingPriority;

typedef struct _ControllerMapping_t
{
SDL_JoystickGUID guid;
char *name;
char *mapping;
SDL_ControllerMappingPriority priority;
struct _ControllerMapping_t *next;
} ControllerMapping_t;

Expand Down Expand Up @@ -636,7 +644,7 @@ void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMap
* Helper function to add a mapping for a guid
*/
static ControllerMapping_t *
SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing)
SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)
{
char *pchName;
char *pchMapping;
Expand All @@ -657,13 +665,17 @@ SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString,

pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
if (pControllerMapping) {
/* Update existing mapping */
SDL_free(pControllerMapping->name);
pControllerMapping->name = pchName;
SDL_free(pControllerMapping->mapping);
pControllerMapping->mapping = pchMapping;
/* refresh open controllers */
SDL_PrivateGameControllerRefreshMapping(pControllerMapping);
/* Only overwrite the mapping if the priority is the same or higher. */
if (pControllerMapping->priority <= priority) {
/* Update existing mapping */
SDL_free(pControllerMapping->name);
pControllerMapping->name = pchName;
SDL_free(pControllerMapping->mapping);
pControllerMapping->mapping = pchMapping;
pControllerMapping->priority = priority;
/* refresh open controllers */
SDL_PrivateGameControllerRefreshMapping(pControllerMapping);
}
*existing = SDL_TRUE;
} else {
pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
Expand All @@ -677,6 +689,7 @@ SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString,
pControllerMapping->name = pchName;
pControllerMapping->mapping = pchMapping;
pControllerMapping->next = s_pSupportedControllers;
pControllerMapping->priority = priority;
s_pSupportedControllers = pControllerMapping;
*existing = SDL_FALSE;
}
Expand Down Expand Up @@ -711,7 +724,7 @@ ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
SDL_bool existing;
mapping = SDL_PrivateAddMappingForGUID(jGUID,
"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);
&existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
}
}
}
Expand Down Expand Up @@ -800,10 +813,10 @@ SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw)
}

/*
* Add or update an entry into the Mappings Database
* Add or update an entry into the Mappings Database with a priority
*/
int
SDL_GameControllerAddMapping(const char *mappingString)
static int
SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority)
{
char *pchGUID;
SDL_JoystickGUID jGUID;
Expand All @@ -829,7 +842,7 @@ SDL_GameControllerAddMapping(const char *mappingString)
jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
SDL_free(pchGUID);

pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing);
pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority);
if (!pControllerMapping) {
return -1;
}
Expand All @@ -847,6 +860,15 @@ SDL_GameControllerAddMapping(const char *mappingString)
}
}

/*
* Add or update an entry into the Mappings Database
*/
int
SDL_GameControllerAddMapping(const char *mappingString)
{
return SDL_PrivateGameControllerAddMapping(mappingString, SDL_CONTROLLER_MAPPING_PRIORITY_API);
}

/*
* Get the mapping string for this GUID
*/
Expand Down Expand Up @@ -901,7 +923,7 @@ SDL_GameControllerLoadHints()
if (pchNewLine)
*pchNewLine = '\0';

SDL_GameControllerAddMapping(pUserMappings);
SDL_PrivateGameControllerAddMapping(pUserMappings, SDL_CONTROLLER_MAPPING_PRIORITY_USER);

if (pchNewLine) {
pUserMappings = pchNewLine + 1;
Expand All @@ -923,7 +945,7 @@ SDL_GameControllerInit(void)
const char *pMappingString = NULL;
pMappingString = s_ControllerMappings[i];
while (pMappingString) {
SDL_GameControllerAddMapping(pMappingString);
SDL_PrivateGameControllerAddMapping(pMappingString, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);

i++;
pMappingString = s_ControllerMappings[i];
Expand Down

0 comments on commit 23c01c1

Please sign in to comment.