From a9be9d879ad141ba6f0153bbf7e823256495065b Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 28 Apr 2014 20:22:08 -0400 Subject: joystick: Add support for "button axes". Some gamepads, notably the PS3 SIXAXIS controller, provide the D-pad not as a pair of axes, but rather as four separate buttons. Define a special axis numbering scheme that packs two button numbers into a single number, and allow an axis to be defined this way. --- src/i_joystick.c | 57 ++++++++++++++++++++++++++++++++++++++++++++------------ src/i_joystick.h | 18 ++++++++++++++++++ 2 files changed, 63 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/i_joystick.c b/src/i_joystick.c index 8d77c9d6..d61d6260 100644 --- a/src/i_joystick.c +++ b/src/i_joystick.c @@ -82,10 +82,27 @@ void I_ShutdownJoystick(void) } } -void I_InitJoystick(void) +static boolean IsValidAxis(int axis) { int num_axes; + if (axis < 0) + { + return true; + } + + if (IS_BUTTON_AXIS(axis)) + { + return true; + } + + num_axes = SDL_JoystickNumAxes(joystick); + + return axis < num_axes; +} + +void I_InitJoystick(void) +{ if (!usejoystick) { return; @@ -115,11 +132,9 @@ void I_InitJoystick(void) return; } - num_axes = SDL_JoystickNumAxes(joystick); - - if (joystick_x_axis >= num_axes - || joystick_y_axis >= num_axes - || joystick_strafe_axis >= num_axes) + if (!IsValidAxis(joystick_x_axis) + || !IsValidAxis(joystick_y_axis) + || !IsValidAxis(joystick_strafe_axis)) { printf("I_InitJoystick: Invalid joystick axis for joystick #%i " "(run joystick setup again)\n", @@ -172,16 +187,34 @@ static int GetAxisState(int axis, int invert) return 0; } - result = SDL_JoystickGetAxis(joystick, axis); + // Is this a button axis? If so, we need to handle it specially. - if (invert) + if (IS_BUTTON_AXIS(axis)) { - result = -result; - } + result = 0; - if (result < DEAD_ZONE && result > -DEAD_ZONE) + if (SDL_JoystickGetButton(joystick, BUTTON_AXIS_NEG(axis))) + { + result -= 32767; + } + if (SDL_JoystickGetButton(joystick, BUTTON_AXIS_POS(axis))) + { + result += 32767; + } + } + else { - result = 0; + result = SDL_JoystickGetAxis(joystick, axis); + + if (invert) + { + result = -result; + } + + if (result < DEAD_ZONE && result > -DEAD_ZONE) + { + result = 0; + } } return result; diff --git a/src/i_joystick.h b/src/i_joystick.h index 98cd218b..93895de7 100644 --- a/src/i_joystick.h +++ b/src/i_joystick.h @@ -27,6 +27,24 @@ #ifndef __I_JOYSTICK__ #define __I_JOYSTICK__ +// If this bit is set in a configuration file axis value, the axis is +// not actually a joystick axis, but instead is a "button axis". This +// means that instead of reading an SDL joystick axis, we read the +// state of two buttons to get the axis value. This is needed for eg. +// the PS3 SIXAXIS controller, where the D-pad buttons register as +// buttons, not as two axes. +#define BUTTON_AXIS 0x10000 + +// Query whether a given axis value describes a button axis. +#define IS_BUTTON_AXIS(axis) ((axis) >= 0 && ((axis) & BUTTON_AXIS) != 0) + +// Get the individual buttons from a button axis value. +#define BUTTON_AXIS_NEG(axis) ((axis) & 0xff) +#define BUTTON_AXIS_POS(axis) (((axis) >> 8) & 0xff) + +// Create a button axis value from two button values. +#define CREATE_BUTTON_AXIS(neg, pos) (BUTTON_AXIS | (neg) | ((pos) << 8)) + void I_InitJoystick(void); void I_ShutdownJoystick(void); void I_UpdateJoystick(void); -- cgit v1.2.3