foxygit / doom Log in
commit 79d38c7d1ef051aad898eb45e965f3660bffc763
Author:     Simon Howard <fraggle@soulsphere.org>
AuthorDate: Sun May 8 15:24:34 2016 -0400
Commit:     Simon Howard <fraggle@soulsphere.org>
CommitDate: Sun May 8 15:24:34 2016 -0400

    setup: Fix use of SDL_JoystickID.

    The event 'which' fields now refer to an SDL_JoystickID in SDL2,
    which does not equate to the index given to SDL_JoystickOpen() (see
    the documentation for that function). This fixes a crash when
    configuring which joystick to use in the setup tool.
---
 src/setup/joystick.c    | 26 +++++++++++++++++++++++---
 src/setup/txt_joyaxis.c |  3 +--
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/setup/joystick.c b/src/setup/joystick.c
index c32ecbf4..f2d63e80 100644
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@ -563,8 +563,7 @@ static int OpenAllJoysticks(void)
     // SDL_JoystickOpen() all joysticks.

     num_joysticks = SDL_NumJoysticks();
-
-    all_joysticks = malloc(sizeof(SDL_Joystick *) * num_joysticks);
+    all_joysticks = calloc(num_joysticks, sizeof(SDL_Joystick *));

     result = 0;

@@ -625,6 +624,22 @@ static void CalibrateXAxis(void)
     TXT_ConfigureJoystickAxis(x_axis_widget, calibrate_button, NULL);
 }

+// TODO: Remove once we no longer use joystick_index in .cfg files.
+static int JoystickIDToIndex(int joy_id)
+{
+    SDL_Joystick *joystick = SDL_JoystickFromInstanceID(joy_id);
+    int i;
+
+    for (i = 0; i < SDL_NumJoysticks(); ++i)
+    {
+        if (joystick == all_joysticks[i])
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+
 static int CalibrationEventCallback(SDL_Event *event, void *user_data)
 {
     if (event->type != SDL_JOYBUTTONDOWN)
@@ -636,9 +651,14 @@ static int CalibrationEventCallback(SDL_Event *event, void *user_data)
     // In the first "center" stage, we're just trying to work out which
     // joystick is being configured and which button the user is pressing.
     usejoystick = 1;
-    joystick_index = event->jbutton.which;
+    joystick_index = JoystickIDToIndex(event->jbutton.which);
     calibrate_button = event->jbutton.button;

+    if (joystick_index < 0)
+    {
+        return 0;
+    }
+
     // If the joystick is a known one, auto-load default
     // config for it. Otherwise, proceed with calibration.
     if (IsKnownJoystick(joystick_index))
diff --git a/src/setup/txt_joyaxis.c b/src/setup/txt_joyaxis.c
index df9deaa0..f2861c28 100644
--- a/src/setup/txt_joyaxis.c
+++ b/src/setup/txt_joyaxis.c
@@ -286,7 +286,6 @@ static int EventCallback(SDL_Event *event, TXT_UNCAST_ARG(joystick_axis))
     // joystick is being configured and which button the user is pressing.
     if (joystick_axis->config_stage == CONFIG_CENTER)
     {
-        joystick_index = event->jbutton.which;
         joystick_axis->config_button = event->jbutton.button;
         IdentifyBadAxes(joystick_axis);

@@ -300,7 +299,7 @@ static int EventCallback(SDL_Event *event, TXT_UNCAST_ARG(joystick_axis))
     // In subsequent stages, the user is asked to push in a specific
     // direction and press the button. They must push the same button
     // as they did before; this is necessary to support button axes.
-    if (event->jbutton.which == joystick_index
+    if (event->jbutton.which == SDL_JoystickInstanceID(joystick_axis->joystick)
      && event->jbutton.button == joystick_axis->config_button)
     {
         switch (joystick_axis->config_stage)