ref: 8659cfd6409dcf093fc6d89e89bd38da391ba009
parent: 242fa1ee46f90f451c625e90f16927e13030c0a0
author: Simon Howard <fraggle@gmail.com>
date: Tue Apr 29 19:45:29 EDT 2014
setup: Detect and ignore bad joystick axes. In some cases a joystick axis can be "stuck" and have a large uncentered value. These must be detected and ignored, otherwise the axis can be chosen during calibration instead of the user's actual desired axis.
--- a/src/setup/joystick.c
+++ b/src/setup/joystick.c
@@ -62,6 +62,15 @@
static int calibrate_button = -1;
+// "Bad" joystick axes. Sometimes an axis can be stuck or "bad". An
+// example I found is that if you unplug the nunchuck extension from
+// a Wii remote, the axes from the nunchuck can be stuck at one of
+// the maximum values. These have to be ignored, so when we ask the
+// user to center the joystick, we look for bad axes that are not
+// close to zero.
+
+static boolean *bad_axis = NULL;
+
// Which joystick axis to use for horizontal movement, and whether to
// invert the direction:
@@ -301,6 +310,11 @@
for (i=0; i<SDL_JoystickNumAxes(joystick); ++i)
{
+ if (bad_axis[i])
+ {
+ continue;
+ }
+
axis_value = SDL_JoystickGetAxis(joystick, i);
if (abs(axis_value) > best_value)
@@ -406,6 +420,31 @@
}
}
+static void IdentifyBadAxes(void)
+{
+ SDL_Joystick *joystick;
+ int i, val;
+
+ free(bad_axis);
+
+ joystick = all_joysticks[joystick_index];
+ bad_axis = calloc(SDL_JoystickNumAxes(joystick), sizeof(boolean));
+
+ // Look for uncentered axes.
+
+ for (i = 0; i < SDL_JoystickNumAxes(joystick); ++i)
+ {
+ val = SDL_JoystickGetAxis(joystick, i);
+
+ bad_axis[i] = abs(val) > (32768 / 5);
+
+ if (bad_axis[i])
+ {
+ printf("Ignoring uncentered joystick axis #%i: %i\n", i, val);
+ }
+ }
+}
+
static int CalibrationEventCallback(SDL_Event *event, void *user_data)
{
boolean advance;
@@ -422,6 +461,7 @@
{
joystick_index = event->jbutton.which;
calibrate_button = event->jbutton.button;
+ IdentifyBadAxes();
// Advance to next stage.
calibrate_stage = CALIBRATE_LEFT;