Added a patchfile against SDL-1.2.7 to let Stella see input devices

by actual name, instead of by driver name.  This is required for
automatic Stelladaptor detection.  Also added a README explaining
how to rebuild the SDL source to include this patch (required by GPL).

Since Linux, Mac, and other SDL variants work out of the box wrt
input device naming, I consider this an SDL/Windows bug, and this
patchfile is a workaround.  Hopefully, future versions of SDL will
incorporate the patch.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@319 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2004-07-15 18:08:55 +00:00
parent e44e59cc13
commit b05178d523
2 changed files with 743 additions and 0 deletions

View File

@ -0,0 +1,47 @@
Please distribute this file with the SDL runtime environment:
The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library
designed to make it easy to write multi-media software, such as games and
emulators.
The Simple DirectMedia Layer library source code is available from:
http://www.libsdl.org/
This library is distributed under the terms of the GNU LGPL license:
http://www.gnu.org/copyleft/lesser.html
---------------------------------------------------------------------------
The SDL.dll library included in this package has been modified to
automatically work with the Stelladaptor device.
As per the GPL, all modifications to SDL must be provided and documented.
The included patchfile 'SDL_mmjoystick_1.2.7.diff' can be used with
SDL-1.2.7.zip (located on the main SDL web page).
To rebuild the SDL.dll file, follow the instructions below:
1) Get the 'SDL-1.2.7.zip' package from the main SDL website and
unzip it.
2) Apply the patchfile 'SDL_mmjoystick_1.2.7.diff' to the SDL-1.2.7
directory (under Linux: patch -p0 < SDL_mmjoystick_1.2.7.diff).
3) Build the SDL.dll library from within Visual C++ (you may need the DX5
development files).
Notes:
1) Credit for the bulk of the patchfile goes to Glenn Maynard.
2) Future versions of SDL will hopefully have this patch integrated.
3) The included SDL.dll file has not been extensively tested. It is
believed to be compatible with the most common input devices,
but support may not be present for buttons on esoteric devices
(hats, sliders, etc). If the included version of SDL.dll doesn't
support your particular input device (and you have no need for
Stelladaptor support), you can use the standard SDL.dll from
the main SDL website.

View File

@ -0,0 +1,696 @@
--- SDL-1.2.7/src/joystick/win32/SDL_mmjoystick.c 2004-02-18 09:22:02.000000000 -0330
+++ SDL-1.2.7/src/joystick/win32/SDL_mmjoystick.c 2004-07-15 14:43:57.623276184 -0230
@@ -22,12 +22,19 @@
#ifdef SAVE_RCSID
static char rcsid =
- "@(#) $Id: SDL_mmjoystick_1.2.7.diff,v 1.1 2004-07-15 18:08:55 stephena Exp $";
+ "@(#) $Id: SDL_mmjoystick_1.2.7.diff,v 1.1 2004-07-15 18:08:55 stephena Exp $";
#endif
-/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */
+/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de
+ * A. Formiga's WINMM driver.
+ *
+ * Hats and sliders are completely untested; the app I'm writing this for mostly
+ * doesn't use them and I don't own any joysticks with them.
+ *
+ * We don't bother to use event notification here. It doesn't seem to work
+ * with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and
+ * let it return 0 events. */
-#include <stdlib.h>
#include <stdio.h> /* For the definition of NULL */
#include "SDL_error.h"
@@ -35,12 +42,28 @@
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
-#include <windows.h>
-#include <mmsystem.h>
+#ifdef _XBOX
+ #include <xtl.h>
+#else
+ #include <windows.h>
+#endif
+
+#define DIRECTINPUT_VERSION 0x0500
+#include <dinput.h>
+
+#include "SDL_active.h"
+
+#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
+
+extern HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter);
+
+static LPDIRECTINPUT dinput = NULL;
+extern HINSTANCE SDL_Instance;
#define MAX_JOYSTICKS 16
#define MAX_AXES 6 /* each joystick can have up to 6 axes */
#define MAX_BUTTONS 32 /* and 32 buttons */
+#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 */
/* limit axis to 256 possible positions to filter out noise */
@@ -48,27 +71,148 @@
#define JOY_BUTTON_FLAG(n) (1<<n)
+typedef enum Type { BUTTON, AXIS, HAT } Type;
+
/* array to hold joystick ID values */
-static UINT SYS_JoystickID[MAX_JOYSTICKS];
-static JOYCAPS SYS_Joystick[MAX_JOYSTICKS];
+static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS];
+static int SYS_NumJoysticks;
+
+extern HWND SDL_Window;
+
+typedef struct input_t
+{
+ /* DirectInput offset for this input type: */
+ DWORD ofs;
+
+ /* Button, axis or hat: */
+ Type type;
+
+ /* SDL input offset: */
+ Uint8 num;
+} input_t;
/* The private structure used to keep track of a joystick */
struct joystick_hwdata
{
- /* joystick ID */
- UINT id;
+ LPDIRECTINPUTDEVICE2 InputDevice;
+ int buffered;
- /* values used to translate device-specific coordinates into
- SDL-standard ranges */
- struct _transaxis {
- int offset;
- float scale;
- } transaxis[6];
+ input_t Inputs[MAX_INPUTS];
+ int NumInputs;
};
-/* Convert a win32 Multimedia API return code to a text message */
-static void SetMMerror(char *function, int code);
+/* 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 )
+{
+ memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance, sizeof(DIDEVICEINSTANCE));
+ SYS_NumJoysticks++;
+
+ if( SYS_NumJoysticks >= MAX_JOYSTICKS )
+ return DIENUM_STOP;
+ return DIENUM_CONTINUE;
+}
+
+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
@@ -77,51 +221,32 @@
*/
int SDL_SYS_JoystickInit(void)
{
- int i;
- int maxdevs;
- int numdevs;
- JOYINFOEX joyinfo;
- JOYCAPS joycaps;
- MMRESULT result;
+ HRESULT result;
- numdevs = 0;
- maxdevs = joyGetNumDevs();
-
- if ( maxdevs > MAX_JOYSTICKS ) {
- maxdevs = MAX_JOYSTICKS;
- }
+ SYS_NumJoysticks = 0;
-
- for ( i = 0; i < MAX_JOYSTICKS; i++ ) {
- SYS_JoystickID[i] = JOYSTICKID1 + i;
+ /* Create the DirectInput object */
+ result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
+ &dinput, NULL);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputCreate", result);
+ return(-1);
}
+ result = IDirectInput_EnumDevices(dinput,
+ DIDEVTYPE_JOYSTICK,
+ EnumJoysticksCallback,
+ NULL,
+ DIEDFL_ATTACHEDONLY );
- for ( i = 0; (i < maxdevs); ++i ) {
-
- /* added 8/31/2001 By Vitaliy Mikitchenko */
- joyinfo.dwSize = sizeof(joyinfo);
- joyinfo.dwFlags = JOY_RETURNALL;
- /* end addition */
-
- result = joyGetPosEx(SYS_JoystickID[i], &joyinfo);
- if ( result == JOYERR_NOERROR ) {
- result = joyGetDevCaps(SYS_JoystickID[i], &joycaps, sizeof(joycaps));
- if ( result == JOYERR_NOERROR ) {
- SYS_JoystickID[numdevs] = SYS_JoystickID[i];
- SYS_Joystick[numdevs] = joycaps;
- numdevs++;
- }
- }
- }
- return(numdevs);
+ return SYS_NumJoysticks;
}
/* Function to get the device-dependent name of a joystick */
const char *SDL_SYS_JoystickName(int index)
{
/***-> test for invalid index ? */
- return(SYS_Joystick[index].szPname);
+ return(SYS_Joystick[index].tszProductName);
}
/* Function to open a joystick for use.
@@ -131,26 +256,8 @@
*/
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
{
- int index, i;
- int caps_flags[MAX_AXES-2] =
- { JOYCAPS_HASZ, JOYCAPS_HASR, JOYCAPS_HASU, JOYCAPS_HASV };
- int axis_min[MAX_AXES], axis_max[MAX_AXES];
-
-
- /* shortcut */
- index = joystick->index;
- axis_min[0] = SYS_Joystick[index].wXmin;
- axis_max[0] = SYS_Joystick[index].wXmax;
- axis_min[1] = SYS_Joystick[index].wYmin;
- axis_max[1] = SYS_Joystick[index].wYmax;
- axis_min[2] = SYS_Joystick[index].wZmin;
- axis_max[2] = SYS_Joystick[index].wZmax;
- axis_min[3] = SYS_Joystick[index].wRmin;
- axis_max[3] = SYS_Joystick[index].wRmax;
- axis_min[4] = SYS_Joystick[index].wUmin;
- axis_max[4] = SYS_Joystick[index].wUmax;
- axis_min[5] = SYS_Joystick[index].wVmin;
- axis_max[5] = SYS_Joystick[index].wVmax;
+ HRESULT result;
+ LPDIRECTINPUTDEVICE device;
/* allocate memory for system specific hardware data */
joystick->hwdata = (struct joystick_hwdata *) malloc(sizeof(*joystick->hwdata));
@@ -160,52 +267,114 @@
return(-1);
}
memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
+ joystick->hwdata->buffered = 1;
+
+ result = IDirectInput_CreateDevice(dinput, &SYS_Joystick[joystick->index].guidInstance,
+ &device, NULL);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInput::CreateDevice", result);
+ return(-1);
+ }
- /* set hardware data */
- joystick->hwdata->id = SYS_JoystickID[index];
- for ( i = 0; i < MAX_AXES; ++i ) {
- if ( (i<2) || (SYS_Joystick[index].wCaps & caps_flags[i-2]) ) {
- joystick->hwdata->transaxis[i].offset =
- AXIS_MIN - axis_min[i];
- joystick->hwdata->transaxis[i].scale =
- (float)(AXIS_MAX - AXIS_MIN) / (axis_max[i] - axis_min[i]);
- } else {
- joystick->hwdata->transaxis[i].offset = 0;
- joystick->hwdata->transaxis[i].scale = 1.0; /* Just in case */
- }
+ result = IDirectInputDevice_QueryInterface(device,
+ &IID_IDirectInputDevice2, (LPVOID *)&joystick->hwdata->InputDevice);
+ IDirectInputDevice_Release(device);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::QueryInterface", result);
+ return(-1);
}
- /* fill nbuttons, naxes, and nhats fields */
- joystick->nbuttons = SYS_Joystick[index].wNumButtons;
- joystick->naxes = SYS_Joystick[index].wNumAxes;
- if ( SYS_Joystick[index].wCaps & JOYCAPS_HASPOV ) {
- joystick->nhats = 1;
- } else {
- joystick->nhats = 0;
+ result = IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata->InputDevice, SDL_Window,
+ DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::SetCooperativeLevel", result);
+ return(-1);
+ }
+
+ result = IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice, &c_dfDIJoystick);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::SetDataFormat", result);
+ return(-1);
+ }
+
+ IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice,
+ DIJoystick_EnumDevObjectsProc,
+ joystick,
+ DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
+
+ {
+ DIPROPDWORD dipdw;
+ memset(&dipdw, 0, sizeof(dipdw));
+ dipdw.diph.dwSize = sizeof(dipdw);
+ dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
+ dipdw.diph.dwObj = 0;
+ dipdw.diph.dwHow = DIPH_DEVICE;
+ dipdw.dwData = INPUT_QSIZE;
+ 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);
+ return(-1);
+ }
}
+
return(0);
}
static Uint8 TranslatePOV(DWORD value)
{
- Uint8 pos;
+ 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];
+}
- pos = SDL_HAT_CENTERED;
- if ( value != JOY_POVCENTERED ) {
- if ( (value > JOY_POVLEFT) || (value < JOY_POVRIGHT) ) {
- pos |= SDL_HAT_UP;
- }
- if ( (value > JOY_POVFORWARD) && (value < JOY_POVBACKWARD) ) {
- pos |= SDL_HAT_RIGHT;
- }
- if ( (value > JOY_POVRIGHT) && (value < JOY_POVLEFT) ) {
- pos |= SDL_HAT_DOWN;
- }
- if ( value > JOY_POVBACKWARD ) {
- pos |= SDL_HAT_LEFT;
- }
- }
- return(pos);
+/* 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;
}
/* Function to update the state of a joystick - called as a device poll.
@@ -213,76 +382,126 @@
* but instead should call SDL_PrivateJoystick*() to deliver events
* and update joystick device state.
*/
-void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
+void SDL_SYS_JoystickUpdate_Polled(SDL_Joystick *joystick)
{
- MMRESULT result;
+ DIJOYSTATE state;
+ HRESULT result;
int i;
- DWORD flags[MAX_AXES] = { JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ,
- JOY_RETURNR, JOY_RETURNU, JOY_RETURNV };
- DWORD pos[MAX_AXES];
- struct _transaxis *transaxis;
- int value, change;
- JOYINFOEX joyinfo;
-
- joyinfo.dwSize = sizeof(joyinfo);
- joyinfo.dwFlags = JOY_RETURNALL|JOY_RETURNPOVCTS;
- if ( ! joystick->hats ) {
- joyinfo.dwFlags &= ~(JOY_RETURNPOV|JOY_RETURNPOVCTS);
- }
- result = joyGetPosEx(joystick->hwdata->id, &joyinfo);
- if ( result != JOYERR_NOERROR ) {
- SetMMerror("joyGetPosEx", result);
- return;
- }
-
- /* joystick motion events */
- pos[0] = joyinfo.dwXpos;
- pos[1] = joyinfo.dwYpos;
- pos[2] = joyinfo.dwZpos;
- pos[3] = joyinfo.dwRpos;
- pos[4] = joyinfo.dwUpos;
- pos[5] = joyinfo.dwVpos;
-
- transaxis = joystick->hwdata->transaxis;
- for (i = 0; i < joystick->naxes; i++) {
- if (joyinfo.dwFlags & flags[i]) {
- value = (int)(((float)pos[i] + transaxis[i].offset) * transaxis[i].scale);
- change = (value - joystick->axes[i]);
- if ( (change < -JOY_AXIS_THRESHOLD) || (change > JOY_AXIS_THRESHOLD) ) {
- SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)value);
+
+ result = IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, sizeof(state), &state);
+ if ( result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED ) {
+ IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
+ result = IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice, sizeof(state), &state);
+ }
+
+ /* Set each known axis, button and POV. */
+ for(i = 0; i < joystick->hwdata->NumInputs; ++i)
+ {
+ const input_t *in = &joystick->hwdata->Inputs[i];
+
+ switch(in->type)
+ {
+ case AXIS:
+ switch(in->ofs)
+ {
+ case DIJOFS_X: SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.lX); break;
+ case DIJOFS_Y: SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.lY); break;
+ case DIJOFS_Z: SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.lZ); break;
+ case DIJOFS_RX: SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.lRx); break;
+ case DIJOFS_RY: SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.lRy); break;
+ case DIJOFS_RZ: SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.lRz); break;
+ case DIJOFS_SLIDER(0): SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.rglSlider[0]); break;
+ case DIJOFS_SLIDER(1): SDL_PrivateJoystickAxis_Int(joystick, in->num, (Sint16)state.rglSlider[0]); break;
}
+
+ break;
+
+ case BUTTON:
+ SDL_PrivateJoystickButton_Int(joystick, in->num, (Uint8) (state.rgbButtons[in->ofs - DIJOFS_BUTTON0]?SDL_PRESSED:SDL_RELEASED));
+ break;
+ case HAT:
+ {
+ Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]);
+ SDL_PrivateJoystickHat_Int(joystick, in->num, pos);
+ break;
+ }
}
}
+}
+
+void SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick *joystick)
+{
+ int i;
+ HRESULT result;
+ DWORD numevents;
+ DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
+
+ numevents = INPUT_QSIZE;
+ result = IDirectInputDevice2_GetDeviceData(
+ joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA),
+ evtbuf, &numevents, 0);
+ if ( result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED ) {
+ IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
+ result = IDirectInputDevice2_GetDeviceData(
+ joystick->hwdata->InputDevice, sizeof(DIDEVICEOBJECTDATA),
+ evtbuf, &numevents, 0);
+ }
+
+ /* Handle the events */
+ if ( result != DI_OK )
+ return;
+
+ for(i = 0; i < (int) numevents; ++i)
+ {
+ int j;
+
+ for(j = 0; j < joystick->hwdata->NumInputs; ++j)
+ {
+ const input_t *in = &joystick->hwdata->Inputs[j];
- /* joystick button events */
- if ( joyinfo.dwFlags & JOY_RETURNBUTTONS ) {
- for ( i = 0; i < joystick->nbuttons; ++i ) {
- if ( joyinfo.dwButtons & JOY_BUTTON_FLAG(i) ) {
- if ( ! joystick->buttons[i] ) {
- SDL_PrivateJoystickButton(joystick, (Uint8)i, SDL_PRESSED);
- }
- } else {
- if ( joystick->buttons[i] ) {
- SDL_PrivateJoystickButton(joystick, (Uint8)i, SDL_RELEASED);
- }
+ if(evtbuf[i].dwOfs != in->ofs)
+ continue;
+
+ switch(in->type)
+ {
+ case AXIS:
+ SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData);
+ break;
+ case BUTTON:
+ SDL_PrivateJoystickButton(joystick, in->num, (Uint8) (evtbuf[i].dwData?SDL_PRESSED:SDL_RELEASED));
+ break;
+ case HAT:
+ {
+ Uint8 pos = TranslatePOV(evtbuf[i].dwData);
+ SDL_PrivateJoystickHat(joystick, in->num, pos);
+ }
}
}
}
+}
- /* joystick hat events */
- if ( joyinfo.dwFlags & JOY_RETURNPOV ) {
- Uint8 pos;
-
- pos = TranslatePOV(joyinfo.dwPOV);
- if ( pos != joystick->hats[0] ) {
- SDL_PrivateJoystickHat(joystick, 0, pos);
- }
+void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
+{
+ HRESULT result;
+
+ result = IDirectInputDevice2_Poll(joystick->hwdata->InputDevice);
+ if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
+ IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
+ IDirectInputDevice2_Poll(joystick->hwdata->InputDevice);
}
+
+ if(joystick->hwdata->buffered)
+ SDL_SYS_JoystickUpdate_Buffered(joystick);
+ else
+ SDL_SYS_JoystickUpdate_Polled(joystick);
}
/* Function to close a joystick after use */
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
{
+ IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice);
+ IDirectInputDevice2_Release(joystick->hwdata->InputDevice);
+
if (joystick->hwdata != NULL) {
/* free system specific hardware data */
free(joystick->hwdata);
@@ -292,48 +511,6 @@
/* Function to perform any system-specific joystick related cleanup */
void SDL_SYS_JoystickQuit(void)
{
- return;
-}
-
-
-/* implementation functions */
-void SetMMerror(char *function, int code)
-{
- static char *error;
- static char errbuf[BUFSIZ];
-
- errbuf[0] = 0;
- switch (code)
- {
- case MMSYSERR_NODRIVER:
- error = "Joystick driver not present";
- break;
-
- case MMSYSERR_INVALPARAM:
- case JOYERR_PARMS:
- error = "Invalid parameter(s)";
- break;
-
- case MMSYSERR_BADDEVICEID:
- error = "Bad device ID";
- break;
-
- case JOYERR_UNPLUGGED:
- error = "Joystick not attached";
- break;
-
- case JOYERR_NOCANDO:
- error = "Can't capture joystick input";
- break;
-
- default:
- sprintf(errbuf, "%s: Unknown Multimedia system error: 0x%x",
- function, code);
- break;
- }
-
- if ( ! errbuf[0] ) {
- sprintf(errbuf, "%s: %s", function, error);
- }
- SDL_SetError("%s", errbuf);
+ IDirectInput_Release(dinput);
+ dinput = NULL;
}