Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
slouken committed Jan 15, 2012
1 parent f511a56 commit 3dd95db
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions src/joystick/windows/SDL_dxjoystick.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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)
{
Expand Down

0 comments on commit 3dd95db

Please sign in to comment.