ref: a9be9d879ad141ba6f0153bbf7e823256495065b
parent: 797a9a563b2e90849bc6eb79169a9381896eeb15
author: Simon Howard <fraggle@gmail.com>
date: Mon Apr 28 16:22:08 EDT 2014
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.
--- a/src/i_joystick.c
+++ b/src/i_joystick.c
@@ -82,10 +82,27 @@
}
}
-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 @@
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 @@
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;
--- 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);