From 6d48ceda65af5e3118a43dbbfeb5b699c308cd4c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 28 Apr 2014 22:03:54 -0400 Subject: 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. --- src/setup/joystick.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'src/setup/joystick.c') 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; } -- cgit v1.2.3