summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Lantinga <slouken@libsdl.org>2012-01-15 15:48:27 -0500
committerSam Lantinga <slouken@libsdl.org>2012-01-15 15:48:27 -0500
commit8037d9a006c91e3d8be4a990eb66e52f9649b4b7 (patch)
treef9e7e62dcf664a2929c6badd6331c4e091626512 /src
parentdc5869550e33f6154820d81806cc5cc750e285e5 (diff)
Fixed bug 1371 - DX joystick axis ordering fix
Alex Nankervis 2012-01-15 11:19:45 PST DirectX joysticks can enumerate their axis out of order. This results in some joysticks having vertical/horizontal swapped, for example (vertical axis gets assigned to axis0). Joysticks that I've tested with this problem: XBOX 360 controller, Logitech Extreme 3D Pro. Attached is a diff that fixes this by sorting the DX joystick objects by their data offsets into the DX data structs. This puts the joystick objects into a standard ordering (X axis -> axis0, Y axis -> axis1, and so on).
Diffstat (limited to 'src')
-rwxr-xr-xsrc/joystick/windows/SDL_dxjoystick.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/joystick/windows/SDL_dxjoystick.c b/src/joystick/windows/SDL_dxjoystick.c
index a59af75f..d73f6641 100755
--- a/src/joystick/windows/SDL_dxjoystick.c
+++ b/src/joystick/windows/SDL_dxjoystick.c
@@ -74,6 +74,7 @@ static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE *
pdidInstance, VOID * pContext);
static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev,
LPVOID pvRef);
+static void SortDevObjects(SDL_Joystick *joystick);
static Uint8 TranslatePOV(DWORD value);
static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis,
Sint16 value);
@@ -483,6 +484,10 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
EnumDevObjectsCallback, joystick,
DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
+ /* Reorder the input objects. Some devices do not report the X axis as
+ * the first axis, for example. */
+ SortDevObjects(joystick);
+
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = INPUT_QSIZE;
@@ -504,6 +509,55 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
return (0);
}
+/* Sort using the data offset into the DInput struct.
+ * This gives a reasonable ordering for the inputs. */
+static int
+SortDevFunc(const void *a, const void *b)
+{
+ const input_t *inputA = (const input_t*)a;
+ const input_t *inputB = (const input_t*)b;
+
+ if (inputA->ofs < inputB->ofs)
+ return -1;
+ if (inputA->ofs > inputB->ofs)
+ return 1;
+ return 0;
+}
+
+/* Sort the input objects and recalculate the indices for each input. */
+static void
+SortDevObjects(SDL_Joystick *joystick)
+{
+ input_t *inputs = joystick->hwdata->Inputs;
+ int nButtons = 0;
+ int nHats = 0;
+ int nAxis = 0;
+ int n;
+
+ SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc);
+
+ for (n = 0; n < joystick->hwdata->NumInputs; n++)
+ {
+ switch (inputs[n].type)
+ {
+ case BUTTON:
+ inputs[n].num = nButtons;
+ nButtons++;
+ break;
+
+ case HAT:
+ inputs[n].num = nHats;
+ nHats++;
+ break;
+
+ case AXIS:
+ inputs[n].num = nAxis;
+ nAxis++;
+ break;
+ }
+ }
+}
+
static BOOL CALLBACK
EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
{