Skip to content

Commit

Permalink
Adds SDL_GameControllerAddMappingsFromFile
Browse files Browse the repository at this point in the history
  • Loading branch information
gabomdq committed Dec 2, 2013
1 parent 7d9e42f commit 45ae148
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/SDL_gamecontroller.h
Expand Up @@ -108,6 +108,14 @@ typedef struct SDL_GameControllerButtonBind
*
*/

/**
* Load a set of mappings from a file, filtered by the current SDL_GetPlatform()
* A community sourced database of controllers is available at https://raw.github.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
*
* \return number of mappings added, -1 on error
*/
extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromFile( const char* mapDB );

/**
* Add or update an existing mapping configuration
*
Expand Down
68 changes: 68 additions & 0 deletions src/joystick/SDL_gamecontroller.c
Expand Up @@ -33,6 +33,7 @@
#endif
#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))

#define SDL_CONTROLLER_PLATFORM_FIELD "platform:"

/* a list of currently opened game controllers */
static SDL_GameController *SDL_gamecontrollers = NULL;
Expand Down Expand Up @@ -653,6 +654,73 @@ void SDL_PrivateGameControllerRefreshMapping( ControllerMapping_t *pControllerMa
}
}

/*
* Add or update an entry into the Mappings Database
*/
int
SDL_GameControllerAddMappingsFromFile( const char* mapDB )
{
const char *platform = SDL_GetPlatform();
SDL_RWops *rw;
int controllers = 0;
char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
size_t db_size, platform_len;

rw = SDL_RWFromFile(mapDB, "rb");
if (rw == NULL) {
return SDL_SetError("Could not open %s", mapDB);
}
db_size = SDL_RWsize(rw);

buf = (char *) SDL_malloc(db_size + 1);
if (buf == NULL) {
SDL_RWclose(rw);
return SDL_SetError("Could allocate space to not read DB into memory");
}

if (SDL_RWread(rw, buf, db_size, 1) != 1) {
SDL_RWclose(rw);
SDL_free(buf);
return SDL_SetError("Could not read DB");
}
SDL_RWclose(rw);

buf[db_size] = '\0';
line = buf;

while (line < buf + db_size) {
line_end = SDL_strchr( line, '\n' );
if (line_end != NULL) {
*line_end = '\0';
}
else {
line_end = buf + db_size;
}

/* Extract and verify the platform */
tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD);
if ( tmp != NULL ) {
tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD);
comma = SDL_strchr(tmp, ',');
if (comma != NULL) {
platform_len = comma - tmp + 1;
if (platform_len + 1 < SDL_arraysize(line_platform)) {
SDL_strlcpy(line_platform, tmp, platform_len);
if(SDL_strncasecmp(line_platform, platform, platform_len) == 0
&& SDL_GameControllerAddMapping(line) > 0) {
controllers++;
}
}
}
}

line = line_end + 1;
}

SDL_free(buf);
return controllers;
}

/*
* Add or update an entry into the Mappings Database
*/
Expand Down

0 comments on commit 45ae148

Please sign in to comment.