diff options
author | Sam Lantinga <slouken@libsdl.org> | 2012-01-15 15:48:27 -0500 |
---|---|---|
committer | Sam Lantinga <slouken@libsdl.org> | 2012-01-15 15:48:27 -0500 |
commit | 8037d9a006c91e3d8be4a990eb66e52f9649b4b7 (patch) | |
tree | f9e7e62dcf664a2929c6badd6331c4e091626512 /src | |
parent | dc5869550e33f6154820d81806cc5cc750e285e5 (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-x | src/joystick/windows/SDL_dxjoystick.c | 54 |
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) { |