Kaynağa Gözat

Adds SDL_GameControllerAddMappingsFromFile

Gabriel Jacobo 11 yıl önce
ebeveyn
işleme
45ae148aef

+ 8 - 0
include/SDL_gamecontroller.h

@@ -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
  *

+ 68 - 0
src/joystick/SDL_gamecontroller.c

@@ -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;
@@ -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
  */