diff --git a/stella/src/win32/README-SDL.txt b/stella/src/win32/README-SDL.txt index 5036e6bad..953cb38b5 100644 --- a/stella/src/win32/README-SDL.txt +++ b/stella/src/win32/README-SDL.txt @@ -25,10 +25,12 @@ 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 +2) Unzip 'SDL_mmjoystick_1.2.7.zip' to obtain 'SDL_mmjoystick_1.2.7.diff'. + +3) 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 +4) Build the SDL.dll library from within Visual C++ (you may need the DX5 development files). diff --git a/stella/src/win32/SDL_mmjoystick_1.2.7.diff b/stella/src/win32/SDL_mmjoystick_1.2.7.diff deleted file mode 100644 index 083d02a09..000000000 --- a/stella/src/win32/SDL_mmjoystick_1.2.7.diff +++ /dev/null @@ -1,696 +0,0 @@ ---- 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 - #include /* For the definition of NULL */ - - #include "SDL_error.h" -@@ -35,12 +42,28 @@ - #include "SDL_sysjoystick.h" - #include "SDL_joystick_c.h" - --#include --#include -+#ifdef _XBOX -+ #include -+#else -+ #include -+#endif -+ -+#define DIRECTINPUT_VERSION 0x0500 -+#include -+ -+#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<= 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; - } diff --git a/stella/src/win32/SDL_mmjoystick_1.2.7.zip b/stella/src/win32/SDL_mmjoystick_1.2.7.zip new file mode 100644 index 000000000..a5fdb41a8 Binary files /dev/null and b/stella/src/win32/SDL_mmjoystick_1.2.7.zip differ