summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/setup/joystick.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/setup/joystick.c b/src/setup/joystick.c
index acabb61f..6fc505f6 100644
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@ -216,7 +216,7 @@ static void SetCalibrationLabel(void)
}
// Search all axes on joystick being configured; find a button that is
-// pressed (other than the calibrate button).
+// pressed (other than the calibrate button). Returns the button number.
static int FindPressedAxisButton(void)
{
@@ -241,6 +241,45 @@ static int FindPressedAxisButton(void)
return -1;
}
+// Look for a hat that isn't centered. Returns the encoded hat axis.
+
+static int FindUncenteredHat(int *axis_invert)
+{
+ SDL_Joystick *joystick;
+ int i, hatval;
+
+ joystick = all_joysticks[joystick_index];
+
+ for (i = 0; i < SDL_JoystickNumHats(joystick); ++i)
+ {
+ hatval = SDL_JoystickGetHat(joystick, i);
+
+ switch (hatval)
+ {
+ case SDL_HAT_LEFT:
+ case SDL_HAT_RIGHT:
+ *axis_invert = hatval != SDL_HAT_LEFT;
+ return CREATE_HAT_AXIS(i, HAT_AXIS_HORIZONTAL);
+
+ case SDL_HAT_UP:
+ case SDL_HAT_DOWN:
+ *axis_invert = hatval != SDL_HAT_UP;
+ return CREATE_HAT_AXIS(i, HAT_AXIS_VERTICAL);
+
+ // If the hat is centered, or is not pointing in a
+ // definite direction, then ignore it. We don't accept
+ // the hat being pointed to the upper-left for example,
+ // because it's ambiguous.
+ case SDL_HAT_CENTERED:
+ default:
+ break;
+ }
+ }
+
+ // None found.
+ return -1;
+}
+
static boolean CalibrateAxis(int *axis_index, int *axis_invert)
{
SDL_Joystick *joystick;
@@ -296,6 +335,18 @@ static boolean CalibrateAxis(int *axis_index, int *axis_invert)
return true;
}
+ // Maybe it's a D-pad that is presented as a hat. This sounds weird
+ // but gamepads like this really do exist; an example is the
+ // Nyko AIRFLO Ex.
+
+ i = FindUncenteredHat(axis_invert);
+
+ if (i >= 0)
+ {
+ *axis_index = i;
+ return true;
+ }
+
// User pressed the button without pushing the joystick anywhere.
return false;
}