summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Howard2014-04-28 20:22:08 -0400
committerSimon Howard2014-04-28 20:22:08 -0400
commita9be9d879ad141ba6f0153bbf7e823256495065b (patch)
tree3d580e3d7b7071aed680dfe3a66b72d587770d53
parent797a9a563b2e90849bc6eb79169a9381896eeb15 (diff)
downloadchocolate-doom-a9be9d879ad141ba6f0153bbf7e823256495065b.tar.gz
chocolate-doom-a9be9d879ad141ba6f0153bbf7e823256495065b.tar.bz2
chocolate-doom-a9be9d879ad141ba6f0153bbf7e823256495065b.zip
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.
-rw-r--r--src/i_joystick.c57
-rw-r--r--src/i_joystick.h18
2 files changed, 63 insertions, 12 deletions
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);