fixed and added some range checks for joysticks
[rocksndiamonds.git] / src / libgame / sdl.c
index d6cf2b1779082a6a5b9d418273fe95c91add3ca7..04fa05e8c5151be5721ad9c07bcce1e1f06173ca 100644 (file)
@@ -2603,7 +2603,7 @@ static boolean sdl_is_controller[MAX_PLAYERS];
 
 static boolean SDLOpenJoystick(int nr)
 {
-  if (nr < 0 || nr > MAX_PLAYERS)
+  if (nr < 0 || nr >= MAX_PLAYERS)
     return FALSE;
 
 #if defined(TARGET_SDL2)
@@ -2631,7 +2631,7 @@ static boolean SDLOpenJoystick(int nr)
 
 static void SDLCloseJoystick(int nr)
 {
-  if (nr < 0 || nr > MAX_PLAYERS)
+  if (nr < 0 || nr >= MAX_PLAYERS)
     return;
 
 #if 1
@@ -2659,7 +2659,7 @@ static void SDLCloseJoystick(int nr)
 
 boolean SDLCheckJoystickOpened(int nr)
 {
-  if (nr < 0 || nr > MAX_PLAYERS)
+  if (nr < 0 || nr >= MAX_PLAYERS)
     return FALSE;
 
 #if defined(TARGET_SDL2)
@@ -2680,6 +2680,9 @@ static void setJoystickAxis(int nr, int axis_id_raw, int axis_value)
   int axis_id = axis_id_raw % 2;
 #endif
 
+  if (nr < 0 || nr >= MAX_PLAYERS)
+    return;
+
   if (axis_id == -1)
     return;
 
@@ -2723,6 +2726,9 @@ static void setJoystickButton(int nr, int button_id_raw, int button_state)
   int button_id = button_id_raw % 2;
 #endif
 
+  if (nr < 0 || nr >= MAX_PLAYERS)
+    return;
+
   if (button_id == -1)
     return;
 
@@ -2833,7 +2839,10 @@ void SDLInitJoysticks()
   static boolean sdl_joystick_subsystem_initialized = FALSE;
   boolean print_warning = !sdl_joystick_subsystem_initialized;
 #if defined(TARGET_SDL2)
-  char *mappings_file = "gamecontrollerdb.txt";
+  char *mappings_file_base = getPath2(options.ro_base_directory,
+                                     GAMECONTROLLER_BASENAME);
+  char *mappings_file_user = getPath2(getUserGameDataDir(),
+                                     GAMECONTROLLER_BASENAME);
   int num_mappings;
 #endif
   int i;
@@ -2855,15 +2864,25 @@ void SDLInitJoysticks()
     }
 
 #if defined(TARGET_SDL2)
-    num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file);
+    num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_base);
 
     if (num_mappings != -1)
-      Error(ERR_INFO, "%d game controller mapping(s) added", num_mappings);
+      Error(ERR_INFO, "%d game controller base mapping(s) added", num_mappings);
     else
-      Error(ERR_WARN, "no game controller mappings found");
+      Error(ERR_WARN, "no game controller base mappings found");
+
+    num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_user);
+
+    if (num_mappings != -1)
+      Error(ERR_INFO, "%d game controller user mapping(s) added", num_mappings);
+    else
+      Error(ERR_WARN, "no game controller user mappings found");
 
     Error(ERR_INFO, "%d joystick(s) found:", SDL_NumJoysticks());
 
+    checked_free(mappings_file_base);
+    checked_free(mappings_file_user);
+
     for (i = 0; i < SDL_NumJoysticks(); i++)
     {
       const char *name, *type;
@@ -2900,8 +2919,8 @@ void SDLInitJoysticks()
       joystick_nr = -1;
     }
 
-    /* misuse joystick file descriptor variable to store joystick number */
-    joystick.fd[i] = joystick_nr;
+    /* store configured joystick number for each player */
+    joystick.nr[i] = joystick_nr;
   }
 
   /* now open all connected joysticks (regardless if configured or not) */