summaryrefslogtreecommitdiff
path: root/src/setup/joystick.c
diff options
context:
space:
mode:
authorSimon Howard2014-04-28 22:03:54 -0400
committerSimon Howard2014-04-28 22:03:54 -0400
commit6d48ceda65af5e3118a43dbbfeb5b699c308cd4c (patch)
treefaac6dab668043d15b3ccd8907386f2ee89651e4 /src/setup/joystick.c
parent15c0779ec829d8a0d83ecf33ce19e681e34f1b89 (diff)
downloadchocolate-doom-6d48ceda65af5e3118a43dbbfeb5b699c308cd4c.tar.gz
chocolate-doom-6d48ceda65af5e3118a43dbbfeb5b699c308cd4c.tar.bz2
chocolate-doom-6d48ceda65af5e3118a43dbbfeb5b699c308cd4c.zip
setup: Detect and configure hat-based D-pads.
As a second fallback, if all joysticks are centered and no buttons are pressed, look at the hats on the joystick to see if one of those is uncentered. Bizarre as it seems, some gamepads actually present the D-pad as a hat.
Diffstat (limited to 'src/setup/joystick.c')
-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;
}