From 9dd423a34aed282348f9af73563a0f52d1cfda12 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 15 Jul 2007 01:51:11 +0000 Subject: [PATCH] Split acinclude.m4 into its component parts for easy updating --- src/joystick/win32/SDL_dxjoystick.c | 524 ++++++++++++++++------------ 1 file changed, 298 insertions(+), 226 deletions(-) diff --git a/src/joystick/win32/SDL_dxjoystick.c b/src/joystick/win32/SDL_dxjoystick.c index 7b47c1909..0392eb6c8 100644 --- a/src/joystick/win32/SDL_dxjoystick.c +++ b/src/joystick/win32/SDL_dxjoystick.c @@ -44,33 +44,61 @@ #define DIRECTINPUT_VERSION 0x0500 #include +#ifdef _MSC_VER + /* Used for the c_dfDIJoystick2 symbol (no imports are used) */ +# pragma comment (lib, "dinput.lib") +#endif +#include /* From DirectX SDK 9c */ +#ifdef _MSC_VER +# pragma comment (lib, "dxerr9.lib") +#endif + +/* an ISO hack for VisualC++ */ +#ifdef _MSC_VER +#define snprintf _snprintf +#endif #define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ +#define MAX_JOYSTICKS 8 +#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ +#define AXIS_MIN -32768 /* minimum value for axis coordinate */ +#define AXIS_MAX 32767 /* maximum value for axis coordinate */ +#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */ +/* external variables referenced. */ extern HINSTANCE SDL_Instance; -extern int DX5_Load(); -extern void DX5_Unload(); +extern HWND SDL_Window; + + +/* local variables */ +static LPDIRECTINPUT dinput = NULL; extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT * ppDI, LPUNKNOWN punkOuter); +static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS]; /* array to hold joystick ID values */ +static int SYS_NumJoysticks; +static HINSTANCE DInputDLL = NULL; -static LPDIRECTINPUT dinput = NULL; -#define MAX_JOYSTICKS 8 -#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ -#define AXIS_MIN -32768 /* minimum value for axis coordinate */ -#define AXIS_MAX 32767 /* maximum value for axis coordinate */ -#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */ +/* local prototypes */ +static void SetDIerror(const char *function, HRESULT code); +static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE * + pdidInstance, VOID * pContext); +static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, + LPVOID pvRef); +static Uint8 TranslatePOV(DWORD value); +static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, + Sint16 value); +static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, + Uint8 value); +static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, + Uint8 button, Uint8 state); + +/* local types */ typedef enum Type { BUTTON, AXIS, HAT } Type; -/* array to hold joystick ID values */ -static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS]; -static int SYS_NumJoysticks; - -extern HWND SDL_Window; - typedef struct input_t { /* DirectInput offset for this input type: */ @@ -87,6 +115,7 @@ typedef struct input_t struct joystick_hwdata { LPDIRECTINPUTDEVICE2 InputDevice; + DIDEVCAPS Capabilities; int buffered; input_t Inputs[MAX_INPUTS]; @@ -95,122 +124,12 @@ struct joystick_hwdata /* Convert a DirectInput return code to a text message */ static void -SetDIerror(char *function, int code) -{ - static char *error; - static char errbuf[1024]; - - errbuf[0] = 0; - switch (code) { - case DIERR_GENERIC: - error = "Undefined error!"; - break; - case DIERR_OLDDIRECTINPUTVERSION: - error = "Your version of DirectInput needs upgrading"; - break; - case DIERR_INVALIDPARAM: - error = "Invalid parameters"; - break; - case DIERR_OUTOFMEMORY: - error = "Out of memory"; - break; - case DIERR_DEVICENOTREG: - error = "Device not registered"; - break; - case DIERR_NOINTERFACE: - error = "Interface not supported"; - break; - case DIERR_NOTINITIALIZED: - error = "Device not initialized"; - break; - default: - sprintf(errbuf, "%s: Unknown DirectInput error: 0x%x", - function, code); - break; - } - if (!errbuf[0]) { - sprintf(errbuf, "%s: %s", function, error); - } - SDL_SetError("%s", errbuf); - return; -} - - -BOOL CALLBACK -EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +SetDIerror(const char *function, HRESULT code) { - memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance, - sizeof(DIDEVICEINSTANCE)); - SYS_NumJoysticks++; - - if (SYS_NumJoysticks >= MAX_JOYSTICKS) - return DIENUM_STOP; - - return DIENUM_CONTINUE; + SDL_SetError("%s() [%s]: %s", function, + DXGetErrorString9(code), DXGetErrorDescription9(code)); } -static BOOL CALLBACK -DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) -{ - SDL_Joystick *joystick = (SDL_Joystick *) pvRef; - HRESULT result; - input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs]; - const int SupportedMask = DIDFT_BUTTON | DIDFT_POV | DIDFT_AXIS; - if (!(dev->dwType & SupportedMask)) - return DIENUM_CONTINUE; /* unsupported */ - - in->ofs = dev->dwOfs; - - if (dev->dwType & DIDFT_BUTTON) { - in->type = BUTTON; - in->num = joystick->nbuttons; - joystick->nbuttons++; - } else if (dev->dwType & DIDFT_POV) { - in->type = HAT; - in->num = joystick->nhats; - joystick->nhats++; - } else { /* dev->dwType & DIDFT_AXIS */ - DIPROPRANGE diprg; - DIPROPDWORD dilong; - - in->type = AXIS; - in->num = joystick->naxes; - - diprg.diph.dwSize = sizeof(diprg); - diprg.diph.dwHeaderSize = sizeof(diprg.diph); - diprg.diph.dwObj = dev->dwOfs; - diprg.diph.dwHow = DIPH_BYOFFSET; - diprg.lMin = AXIS_MIN; - diprg.lMax = AXIS_MAX; - - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_RANGE, &diprg.diph); - if (result != DI_OK) - return DIENUM_CONTINUE; /* don't use this axis */ - - /* Set dead zone to 0. */ - dilong.diph.dwSize = sizeof(dilong); - dilong.diph.dwHeaderSize = sizeof(dilong.diph); - dilong.diph.dwObj = dev->dwOfs; - dilong.diph.dwHow = DIPH_BYOFFSET; - dilong.dwData = 0; - result = - IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_DEADZONE, &dilong.diph); - if (result != DI_OK) - return DIENUM_CONTINUE; /* don't use this axis */ - - joystick->naxes++; - } - - joystick->hwdata->NumInputs++; - - if (joystick->hwdata->NumInputs == MAX_INPUTS) - return DIENUM_STOP; /* too many */ - - return DIENUM_CONTINUE; -} /* Function to scan the system for joysticks. * This function should set SDL_numjoysticks to the number of available @@ -224,18 +143,30 @@ SDL_SYS_JoystickInit(void) SYS_NumJoysticks = 0; - /* Create the DirectInput object */ - if (DX5_Load() < 0) { - SDL_SetError("Couldn't load DirectInput"); + result = CoInitialize(NULL); + if (FAILED(result)) { + SetDIerror("CoInitialize", result); return (-1); } - result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION, &dinput, NULL); - if (result != DI_OK) { - DX5_Unload(); - SetDIerror("DirectInputCreate", result); + + result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, + &IID_IDirectInput, &dinput); + + if (FAILED(result)) { + SetDIerror("CoCreateInstance", result); return (-1); } + /* Because we used CoCreateInstance, we need to Initialize it, first. */ + result = + IDirectInput_Initialize(dinput, SDL_Instance, DIRECTINPUT_VERSION); + + if (FAILED(result)) { + SetDIerror("IDirectInput::Initialize", result); + return (-1); + } + + /* Look for joysticks, wheels, head trackers, gamepads, etc.. */ result = IDirectInput_EnumDevices(dinput, DIDEVTYPE_JOYSTICK, EnumJoysticksCallback, @@ -244,6 +175,19 @@ SDL_SYS_JoystickInit(void) return SYS_NumJoysticks; } +static BOOL CALLBACK +EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +{ + memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance, + sizeof(DIDEVICEINSTANCE)); + SYS_NumJoysticks++; + + if (SYS_NumJoysticks >= MAX_JOYSTICKS) + return DIENUM_STOP; + + return DIENUM_CONTINUE; +} + /* Function to get the device-dependent name of a joystick */ const char * SDL_SYS_JoystickName(int index) @@ -262,137 +206,212 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick) { HRESULT result; LPDIRECTINPUTDEVICE device; + DIPROPDWORD dipdw; + + ZeroMemory(&dipdw, sizeof(DIPROPDWORD)); + dipdw.diph.dwSize = sizeof(DIPROPDWORD); + dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); + /* allocate memory for system specific hardware data */ joystick->hwdata = - (struct joystick_hwdata *) malloc(sizeof(*joystick->hwdata)); + (struct joystick_hwdata *) malloc(sizeof(struct joystick_hwdata)); if (joystick->hwdata == NULL) { SDL_OutOfMemory(); return (-1); } - memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + ZeroMemory(joystick->hwdata, sizeof(struct joystick_hwdata)); joystick->hwdata->buffered = 1; + joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS); result = IDirectInput_CreateDevice(dinput, &SYS_Joystick[joystick->index]. guidInstance, &device, NULL); - if (result != DI_OK) { - SetDIerror("DirectInput::CreateDevice", result); + if (FAILED(result)) { + SetDIerror("IDirectInput::CreateDevice", result); return (-1); } + /* Now get the IDirectInputDevice2 interface, instead. */ result = IDirectInputDevice_QueryInterface(device, &IID_IDirectInputDevice2, (LPVOID *) & joystick-> hwdata->InputDevice); + /* We are done with this object. Use the stored one from now on. */ IDirectInputDevice_Release(device); - if (result != DI_OK) { - SetDIerror("DirectInputDevice::QueryInterface", result); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice::QueryInterface", result); return (-1); } + /* Aquire shared access. Exclusive access is required for forces, + * though. */ result = IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata-> InputDevice, SDL_Window, - DISCL_NONEXCLUSIVE | + DISCL_EXCLUSIVE | DISCL_BACKGROUND); - if (result != DI_OK) { - SetDIerror("DirectInputDevice::SetCooperativeLevel", result); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetCooperativeLevel", result); return (-1); } + /* Use the extended data structure: DIJOYSTATE2. */ result = IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice, - &c_dfDIJoystick); - if (result != DI_OK) { - SetDIerror("DirectInputDevice::SetDataFormat", result); + &c_dfDIJoystick2); + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetDataFormat", result); return (-1); } - IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice, - DIJoystick_EnumDevObjectsProc, - joystick, - DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + /* Get device capabilities */ + result = + IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice, + &joystick->hwdata->Capabilities); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::GetCapabilities", result); + return (-1); + } + + /* Force capable? */ + if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { + + result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::Acquire", result); + return (-1); + } + + /* reset all accuators. */ + result = + IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata-> + InputDevice, + DISFFC_RESET); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand", + result); + return (-1); + } - { - DIPROPDWORD dipdw; - memset(&dipdw, 0, sizeof(dipdw)); - dipdw.diph.dwSize = sizeof(dipdw); - dipdw.diph.dwHeaderSize = sizeof(dipdw.diph); + result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::Unacquire", result); + return (-1); + } + + /* Turn on auto-centering for a ForceFeedback device (until told + * otherwise). */ dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = INPUT_QSIZE; + dipdw.dwData = DIPROPAUTOCENTER_ON; + result = IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, - DIPROP_BUFFERSIZE, &dipdw.diph); - - if (result == DI_POLLEDDEVICE) { - /* This device doesn't support buffering, so we're forced - * to use less reliable polling. */ - joystick->hwdata->buffered = 0; - } else if (result != DI_OK) { - SetDIerror("DirectInputDevice::SetProperty", result); + DIPROP_AUTOCENTER, &dipdw.diph); + + if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetProperty", result); return (-1); } } + /* What buttons and axes does it have? */ + IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice, + EnumDevObjectsCallback, joystick, + DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = INPUT_QSIZE; + + /* Set the buffer size */ + result = + IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + DIPROP_BUFFERSIZE, &dipdw.diph); + + if (result == DI_POLLEDDEVICE) { + /* This device doesn't support buffering, so we're forced + * to use less reliable polling. */ + joystick->hwdata->buffered = 0; + } else if (FAILED(result)) { + SetDIerror("IDirectInputDevice2::SetProperty", result); + return (-1); + } + return (0); } -static Uint8 -TranslatePOV(DWORD value) +static BOOL CALLBACK +EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) { - const int HAT_VALS[] = { - SDL_HAT_UP, - SDL_HAT_UP | SDL_HAT_RIGHT, - SDL_HAT_RIGHT, - SDL_HAT_DOWN | SDL_HAT_RIGHT, - SDL_HAT_DOWN, - SDL_HAT_DOWN | SDL_HAT_LEFT, - SDL_HAT_LEFT, - SDL_HAT_UP | SDL_HAT_LEFT - }; + SDL_Joystick *joystick = (SDL_Joystick *) pvRef; + HRESULT result; + input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs]; - if (LOWORD(value) == 0xFFFF) - return SDL_HAT_CENTERED; + in->ofs = dev->dwOfs; - /* Round the value up: */ - value += 4500 / 2; - value %= 36000; - value /= 4500; + if (dev->dwType & DIDFT_BUTTON) { + in->type = BUTTON; + in->num = joystick->nbuttons; + joystick->nbuttons++; + } else if (dev->dwType & DIDFT_POV) { + in->type = HAT; + in->num = joystick->nhats; + joystick->nhats++; + } else if (dev->dwType & DIDFT_AXIS) { + DIPROPRANGE diprg; + DIPROPDWORD dilong; - if (value >= 8) - return SDL_HAT_CENTERED; /* shouldn't happen */ + in->type = AXIS; + in->num = joystick->naxes; - return HAT_VALS[value]; -} + diprg.diph.dwSize = sizeof(diprg); + diprg.diph.dwHeaderSize = sizeof(diprg.diph); + diprg.diph.dwObj = dev->dwOfs; + diprg.diph.dwHow = DIPH_BYOFFSET; + diprg.lMin = AXIS_MIN; + diprg.lMax = AXIS_MAX; -/* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to - * do it. */ -static int -SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value) -{ - if (joystick->axes[axis] != value) - return SDL_PrivateJoystickAxis(joystick, axis, value); - return 0; -} + result = + IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + DIPROP_RANGE, &diprg.diph); + if (FAILED(result)) { + return DIENUM_CONTINUE; /* don't use this axis */ + } -static int -SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, Uint8 value) -{ - if (joystick->hats[hat] != value) - return SDL_PrivateJoystickHat(joystick, hat, value); - return 0; -} + /* Set dead zone to 0. */ + dilong.diph.dwSize = sizeof(dilong); + dilong.diph.dwHeaderSize = sizeof(dilong.diph); + dilong.diph.dwObj = dev->dwOfs; + dilong.diph.dwHow = DIPH_BYOFFSET; + dilong.dwData = 0; + result = + IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice, + DIPROP_DEADZONE, &dilong.diph); + if (FAILED(result)) { + return DIENUM_CONTINUE; /* don't use this axis */ + } -static int -SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, - Uint8 state) -{ - if (joystick->buttons[button] != state) - return SDL_PrivateJoystickButton(joystick, button, state); - return 0; + joystick->naxes++; + } else { + /* not supported at this time */ + return DIENUM_CONTINUE; + } + + joystick->hwdata->NumInputs++; + + if (joystick->hwdata->NumInputs == MAX_INPUTS) { + return DIENUM_STOP; /* too many */ + } + + return DIENUM_CONTINUE; } /* Function to update the state of a joystick - called as a device poll. @@ -403,19 +422,18 @@ SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, void SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick) { - DIJOYSTATE state; + DIJOYSTATE2 state; HRESULT result; int i; result = IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, - sizeof(state), &state); + sizeof(DIJOYSTATE2), &state); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); result = - IDirectInputDevice2_GetDeviceState(joystick->hwdata-> - InputDevice, sizeof(state), - &state); + IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, + sizeof(DIJOYSTATE2), &state); } /* Set each known axis, button and POV. */ @@ -455,7 +473,7 @@ SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick) break; case DIJOFS_SLIDER(1): SDL_PrivateJoystickAxis_Int(joystick, in->num, - (Sint16) state.rglSlider[0]); + (Sint16) state.rglSlider[1]); break; } @@ -471,8 +489,8 @@ SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick) break; case HAT: { - Uint8 pos = - TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]); + Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - + DIJOFS_POV(0)]); SDL_PrivateJoystickHat_Int(joystick, in->num, pos); break; } @@ -491,19 +509,18 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) numevents = INPUT_QSIZE; result = IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, - sizeof(DIDEVICEOBJECTDATA), - evtbuf, &numevents, 0); + sizeof(DIDEVICEOBJECTDATA), evtbuf, + &numevents, 0); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice); result = - IDirectInputDevice2_GetDeviceData(joystick->hwdata-> - InputDevice, + IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA), evtbuf, &numevents, 0); } - /* Handle the events */ - if (result != DI_OK) + /* Handle the events or punt */ + if (FAILED(result)) return; for (i = 0; i < (int) numevents; ++i) { @@ -523,8 +540,8 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) case BUTTON: SDL_PrivateJoystickButton(joystick, in->num, (Uint8) (evtbuf[i]. - dwData ? SDL_PRESSED - : SDL_RELEASED)); + dwData ? SDL_PRESSED : + SDL_RELEASED)); break; case HAT: { @@ -536,6 +553,62 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) } } + +static Uint8 +TranslatePOV(DWORD value) +{ + const int HAT_VALS[] = { + SDL_HAT_UP, + SDL_HAT_UP | SDL_HAT_RIGHT, + SDL_HAT_RIGHT, + SDL_HAT_DOWN | SDL_HAT_RIGHT, + SDL_HAT_DOWN, + SDL_HAT_DOWN | SDL_HAT_LEFT, + SDL_HAT_LEFT, + SDL_HAT_UP | SDL_HAT_LEFT + }; + + if (LOWORD(value) == 0xFFFF) + return SDL_HAT_CENTERED; + + /* Round the value up: */ + value += 4500 / 2; + value %= 36000; + value /= 4500; + + if (value >= 8) + return SDL_HAT_CENTERED; /* shouldn't happen */ + + return HAT_VALS[value]; +} + +/* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to + * do it. */ +static int +SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value) +{ + if (joystick->axes[axis] != value) + return SDL_PrivateJoystickAxis(joystick, axis, value); + return 0; +} + +static int +SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, Uint8 value) +{ + if (joystick->hats[hat] != value) + return SDL_PrivateJoystickHat(joystick, hat, value); + return 0; +} + +static int +SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, + Uint8 state) +{ + if (joystick->buttons[button] != state) + return SDL_PrivateJoystickButton(joystick, button, state); + return 0; +} + void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { @@ -572,7 +645,6 @@ SDL_SYS_JoystickQuit(void) { IDirectInput_Release(dinput); dinput = NULL; - DX5_Unload(); } #endif /* SDL_JOYSTICK_DINPUT */