Skip to content

Commit

Permalink
Added an API to iterate over game controller mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Nov 29, 2016
1 parent 1e8f074 commit dd5d85a
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include/SDL_gamecontroller.h
Expand Up @@ -135,6 +135,20 @@ extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw,
*/
extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char* mappingString);

/**
* Get the number of mappings installed
*
* \return the number of mappings
*/
extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings();

/**
* Get the mapping at a particular index.
*
* \return the mapping string. Must be freed with SDL_free(). Returns NULL if the index is out of range.
*/
extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForIndex(int mapping_index);

/**
* Get a mapping string for a GUID
*
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Expand Up @@ -622,3 +622,5 @@
#define SDL_GameControllerGetProduct SDL_GameControllerGetProduct_REAL
#define SDL_GameControllerGetProductVersion SDL_GameControllerGetProductVersion_REAL
#define SDL_HasNEON SDL_HasNEON_REAL
#define SDL_GameControllerNumMappings SDL_GameControllerNumMappings_REAL
#define SDL_GameControllerMappingForIndex SDL_GameControllerMappingForIndex_REAL
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Expand Up @@ -654,3 +654,5 @@ SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetVendor,(SDL_GameController *a),(a),r
SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetProduct,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetProductVersion,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasNEON,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerNumMappings,(void),(),return)
SDL_DYNAPI_PROC(char*,SDL_GameControllerMappingForIndex,(int a),(a),return)
52 changes: 52 additions & 0 deletions src/joystick/SDL_gamecontroller.c
Expand Up @@ -96,6 +96,7 @@ typedef struct _ControllerMapping_t
struct _ControllerMapping_t *next;
} ControllerMapping_t;

static SDL_JoystickGUID s_zeroGUID;
static ControllerMapping_t *s_pSupportedControllers = NULL;
static ControllerMapping_t *s_pXInputMapping = NULL;
static ControllerMapping_t *s_pEmscriptenMapping = NULL;
Expand Down Expand Up @@ -872,6 +873,57 @@ SDL_GameControllerAddMapping(const char *mappingString)
return SDL_PrivateGameControllerAddMapping(mappingString, SDL_CONTROLLER_MAPPING_PRIORITY_API);
}

/**
* Get the number of mappings installed
*/
int
SDL_GameControllerNumMappings()
{
int num_mappings = 0;
ControllerMapping_t *mapping;

for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
continue;
}
++num_mappings;
}
return num_mappings;
}

/**
* Get the mapping at a particular index.
*/
char *
SDL_GameControllerMappingForIndex(int mapping_index)
{
ControllerMapping_t *mapping;

for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
continue;
}
if (mapping_index == 0) {
char *pMappingString;
char pchGUID[33];
size_t needed;

SDL_JoystickGetGUIDString(mapping->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();
return NULL;
}
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
return pMappingString;
}
--mapping_index;
}
return NULL;
}

/*
* Get the mapping string for this GUID
*/
Expand Down
11 changes: 11 additions & 0 deletions test/testgamecontroller.c
Expand Up @@ -259,6 +259,17 @@ main(int argc, char *argv[])

SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");

/* Print information about the mappings */
SDL_Log("Supported mappings:\n");
for (i = 0; i < SDL_GameControllerNumMappings(); ++i) {
char *mapping = SDL_GameControllerMappingForIndex(i);
if (mapping) {
SDL_Log("\t%s\n", mapping);
SDL_free(mapping);
}
}
SDL_Log("\n");

/* Print information about the controller */
for (i = 0; i < SDL_NumJoysticks(); ++i) {
const char *name;
Expand Down

0 comments on commit dd5d85a

Please sign in to comment.