Closed bug #74
Added DirectInput joystick code, contributed by Glenn Maynard.
This fixes a problem with the Windows Multimedia joystick driver
not showing all 6 axes on a GameCube controller converter, which
was donated by Jacob Kolding.
Binary file VisualC.zip has changed
--- a/configure.in Sun May 21 02:50:05 2006 +0000
+++ b/configure.in Sun May 21 16:47:41 2006 +0000
@@ -2270,8 +2270,13 @@
fi
# Set up files for the joystick library
if test x$enable_joystick = xyes; then
- AC_DEFINE(SDL_JOYSTICK_WINMM)
- SOURCES="$SOURCES $srcdir/src/joystick/win32/*.c"
+ if test x$have_directx = xyes; then
+ AC_DEFINE(SDL_JOYSTICK_DINPUT)
+ SOURCES="$SOURCES $srcdir/src/joystick/win32/SDL_dxjoystick.c"
+ else
+ AC_DEFINE(SDL_JOYSTICK_WINMM)
+ SOURCES="$SOURCES $srcdir/src/joystick/win32/SDL_mmjoystick.c"
+ fi
have_joystick=yes
fi
# Set up files for the cdrom library
--- a/include/SDL_config.h.in Sun May 21 02:50:05 2006 +0000
+++ b/include/SDL_config.h.in Sun May 21 16:47:41 2006 +0000
@@ -198,6 +198,7 @@
#undef SDL_JOYSTICK_AMIGA
#undef SDL_JOYSTICK_BEOS
#undef SDL_JOYSTICK_DC
+#undef SDL_JOYSTICK_DINPUT
#undef SDL_JOYSTICK_DUMMY
#undef SDL_JOYSTICK_IOKIT
#undef SDL_JOYSTICK_LINUX
--- a/include/SDL_config_win32.h Sun May 21 02:50:05 2006 +0000
+++ b/include/SDL_config_win32.h Sun May 21 16:47:41 2006 +0000
@@ -131,7 +131,7 @@
#ifdef _WIN32_WCE
#define SDL_JOYSTICK_DISABLED 1
#else
-#define SDL_JOYSTICK_WINMM 1
+#define SDL_JOYSTICK_DINPUT 1
#endif
/* Enable various shared object loading systems */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/joystick/win32/SDL_dxjoystick.c Sun May 21 16:47:41 2006 +0000
@@ -0,0 +1,513 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2006 Sam Lantinga
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#ifdef SDL_JOYSTICK_DINPUT
+
+/* 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 "SDL_error.h"
+#include "SDL_events.h"
+#include "SDL_joystick.h"
+#include "../SDL_sysjoystick.h"
+#include "../SDL_joystick_c.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#define DIRECTINPUT_VERSION 0x0500
+#include <dinput.h>
+
+#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
+
+extern HINSTANCE SDL_Instance;
+extern int DX5_Load();
+extern void DX5_Unload();
+extern HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter);
+
+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 */
+
+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: */
+ 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
+{
+ LPDIRECTINPUTDEVICE2 InputDevice;
+ int buffered;
+
+ input_t Inputs[MAX_INPUTS];
+ int NumInputs;
+};
+
+/* 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
+ * joysticks. Joystick 0 should be the system default joystick.
+ * It should return 0, or -1 on an unrecoverable fatal error.
+ */
+int SDL_SYS_JoystickInit(void)
+{
+ HRESULT result;
+
+ SYS_NumJoysticks = 0;
+
+ /* Create the DirectInput object */
+ if ( DX5_Load() < 0 ) {
+ SDL_SetError("Couldn't load DirectInput");
+ return(-1);
+ }
+ result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION,
+ &dinput, NULL);
+ if ( result != DI_OK ) {
+ DX5_Unload();
+ SetDIerror("DirectInputCreate", result);
+ return(-1);
+ }
+
+ result = IDirectInput_EnumDevices(dinput,
+ DIDEVTYPE_JOYSTICK,
+ EnumJoysticksCallback,
+ NULL,
+ DIEDFL_ATTACHEDONLY );
+
+ 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].tszProductName);
+}
+
+/* Function to open a joystick for use.
+ The joystick to open is specified by the index field of the joystick.
+ This should fill the nbuttons and naxes fields of the joystick structure.
+ It returns 0, or -1 if there is an error.
+ */
+int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
+{
+ HRESULT result;
+ LPDIRECTINPUTDEVICE device;
+
+ /* allocate memory for system specific hardware data */
+ joystick->hwdata = (struct joystick_hwdata *) malloc(sizeof(*joystick->hwdata));
+ if (joystick->hwdata == NULL)
+ {
+ SDL_OutOfMemory();
+ 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);
+ }
+
+ result = IDirectInputDevice_QueryInterface(device,
+ &IID_IDirectInputDevice2, (LPVOID *)&joystick->hwdata->InputDevice);
+ IDirectInputDevice_Release(device);
+ if ( result != DI_OK ) {
+ SetDIerror("DirectInputDevice::QueryInterface", result);
+ return(-1);
+ }
+
+ 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)
+{
+ 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;
+}
+
+/* Function to update the state of a joystick - called as a device poll.
+ * This function shouldn't update the joystick structure directly,
+ * but instead should call SDL_PrivateJoystick*() to deliver events
+ * and update joystick device state.
+ */
+void SDL_SYS_JoystickUpdate_Polled(SDL_Joystick *joystick)
+{
+ DIJOYSTATE state;
+ HRESULT result;
+ int i;
+
+ 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];
+
+ 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);
+ }
+ }
+ }
+ }
+}
+
+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);
+ }
+}
+
+/* Function to perform any system-specific joystick related cleanup */
+void SDL_SYS_JoystickQuit(void)
+{
+ IDirectInput_Release(dinput);
+ dinput = NULL;
+ DX5_Unload();
+}
+
+#endif /* SDL_JOYSTICK_DINPUT */
--- a/src/video/windx5/SDL_dx5video.c Sun May 21 02:50:05 2006 +0000
+++ b/src/video/windx5/SDL_dx5video.c Sun May 21 16:47:41 2006 +0000
@@ -436,102 +436,98 @@
extern int DIB_GetGammaRamp(_THIS, Uint16 *ramp);
extern void DIB_QuitGamma(_THIS);
+/* Functions for loading the DirectX functions dynamically */
+static int DX5_loaded = 0;
+static HINSTANCE DDrawDLL = NULL;
+static HINSTANCE DInputDLL = NULL;
+
+void DX5_Unload(void)
+{
+ if ( --DX5_loaded == 0 ) {
+ if ( DDrawDLL != NULL ) {
+ FreeLibrary(DDrawDLL);
+ DDrawCreate = NULL;
+ DDrawDLL = NULL;
+ }
+ if ( DInputDLL != NULL ) {
+ FreeLibrary(DInputDLL);
+ DInputCreate = NULL;
+ DInputDLL = NULL;
+ }
+ }
+}
+int DX5_Load(void)
+{
+ int status = 0;
+
+ if ( ++DX5_loaded == 1 ) {
+ DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
+ if ( DDrawDLL != NULL ) {
+ DDrawCreate = (void *)GetProcAddress(DDrawDLL,
+ TEXT("DirectDrawCreate"));
+ }
+ DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
+ if ( DInputDLL != NULL ) {
+ DInputCreate = (void *)GetProcAddress(DInputDLL,
+ TEXT("DirectInputCreateA"));
+ }
+ if ( DDrawDLL && DDrawCreate && DInputDLL && DInputCreate ) {
+ status = 0;
+ } else {
+ DX5_Unload();
+ status = -1;
+ }
+ }
+ return status;
+}
+
/* DX5 driver bootstrap functions */
static int DX5_Available(void)
{
- HINSTANCE DInputDLL;
- HINSTANCE DDrawDLL;
- int dinput_ok;
- int ddraw_ok;
+ int ddraw_ok = 0;
+ HRESULT (WINAPI *DDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
+ LPDIRECTDRAW DDraw;
/* Version check DINPUT.DLL and DDRAW.DLL (Is DirectX okay?) */
- dinput_ok = 0;
- DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
- if ( DInputDLL != NULL ) {
- dinput_ok = 1;
- FreeLibrary(DInputDLL);
+ if ( DX5_Load() < 0 ) {
+ return -1;
}
- ddraw_ok = 0;
- DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
- if ( DDrawDLL != NULL ) {
- HRESULT (WINAPI *DDrawCreate)(GUID *,LPDIRECTDRAW *,IUnknown *);
- LPDIRECTDRAW DDraw;
- /* Try to create a valid DirectDraw object */
- DDrawCreate = (void *)GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate"));
- if ( (DDrawCreate != NULL)
+ /* Try to create a valid DirectDraw object */
+ DDrawCreate = (void *)GetProcAddress(DDrawDLL, TEXT("DirectDrawCreate"));
+ if ( (DDrawCreate != NULL)
&& !FAILED(DDrawCreate(NULL, &DDraw, NULL)) ) {
- if ( !FAILED(IDirectDraw_SetCooperativeLevel(DDraw,
+ if ( !FAILED(IDirectDraw_SetCooperativeLevel(DDraw,
NULL, DDSCL_NORMAL)) ) {
- DDSURFACEDESC desc;
- LPDIRECTDRAWSURFACE DDrawSurf;
- LPDIRECTDRAWSURFACE3 DDrawSurf3;
-
- /* Try to create a DirectDrawSurface3 object */
- SDL_memset(&desc, 0, sizeof(desc));
- desc.dwSize = sizeof(desc);
- desc.dwFlags = DDSD_CAPS;
- desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY;
- if ( !FAILED(IDirectDraw_CreateSurface(DDraw, &desc,
- &DDrawSurf, NULL)) ) {
- if ( !FAILED(IDirectDrawSurface_QueryInterface(DDrawSurf,
- &IID_IDirectDrawSurface3, (LPVOID *)&DDrawSurf3)) ) {
- /* Yay! */
- ddraw_ok = 1;
+ DDSURFACEDESC desc;
+ LPDIRECTDRAWSURFACE DDrawSurf;
+ LPDIRECTDRAWSURFACE3 DDrawSurf3;
- /* Clean up.. */
- IDirectDrawSurface3_Release(DDrawSurf3);
- }
- IDirectDrawSurface_Release(DDrawSurf);
- }
- }
- IDirectDraw_Release(DDraw);
- }
- FreeLibrary(DDrawDLL);
- }
- return(dinput_ok && ddraw_ok);
-}
-
-/* Functions for loading the DirectX functions dynamically */
-static HINSTANCE DDrawDLL = NULL;
-static HINSTANCE DInputDLL = NULL;
+ /* Try to create a DirectDrawSurface3 object */
+ SDL_memset(&desc, 0, sizeof(desc));
+ desc.dwSize = sizeof(desc);
+ desc.dwFlags = DDSD_CAPS;
+ desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_VIDEOMEMORY;
+ if ( !FAILED(IDirectDraw_CreateSurface(DDraw, &desc,
+ &DDrawSurf, NULL)) ) {
+ if ( !FAILED(IDirectDrawSurface_QueryInterface(DDrawSurf,
+ &IID_IDirectDrawSurface3, (LPVOID *)&DDrawSurf3)) ) {
+ /* Yay! */
+ ddraw_ok = 1;
-static void DX5_Unload(void)
-{
- if ( DDrawDLL != NULL ) {
- FreeLibrary(DDrawDLL);
- DDrawCreate = NULL;
- DDrawDLL = NULL;
+ /* Clean up.. */
+ IDirectDrawSurface3_Release(DDrawSurf3);
+ }
+ IDirectDrawSurface_Release(DDrawSurf);
+ }
+ }
+ IDirectDraw_Release(DDraw);
}
- if ( DInputDLL != NULL ) {
- FreeLibrary(DInputDLL);
- DInputCreate = NULL;
- DInputDLL = NULL;
- }
-}
-static int DX5_Load(void)
-{
- int status;
DX5_Unload();
- DDrawDLL = LoadLibrary(TEXT("DDRAW.DLL"));
- if ( DDrawDLL != NULL ) {
- DDrawCreate = (void *)GetProcAddress(DDrawDLL,
- TEXT("DirectDrawCreate"));
- }
- DInputDLL = LoadLibrary(TEXT("DINPUT.DLL"));
- if ( DInputDLL != NULL ) {
- DInputCreate = (void *)GetProcAddress(DInputDLL,
- TEXT("DirectInputCreateA"));
- }
- if ( DDrawDLL && DDrawCreate && DInputDLL && DInputCreate ) {
- status = 0;
- } else {
- DX5_Unload();
- status = -1;
- }
- return status;
+
+ return ddraw_ok;
}
static void DX5_DeleteDevice(SDL_VideoDevice *this)
@@ -541,6 +537,7 @@
IDirectDraw2_Release(ddraw2);
}
DX5_Unload();
+
if ( this ) {
if ( this->hidden ) {
SDL_free(this->hidden);
--- a/test/testjoystick.c Sun May 21 02:50:05 2006 +0000
+++ b/test/testjoystick.c Sun May 21 16:47:41 2006 +0000
@@ -17,7 +17,7 @@
int i, done;
SDL_Event event;
int x, y, draw;
- SDL_Rect axis_area[2];
+ SDL_Rect axis_area[6][2];
/* Set a video mode to display joystick axis position */
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0);
@@ -110,36 +110,38 @@
SDL_UpdateRects(screen, 1, &area);
}
- /* Erase previous axes */
- SDL_FillRect(screen, &axis_area[draw], 0x0000);
+ for ( i=0; i<SDL_JoystickNumAxes(joystick)/2 && i < SDL_arraysize(axis_area); ++i ) {
+ /* Erase previous axes */
+ SDL_FillRect(screen, &axis_area[i][draw], 0x0000);
- /* Draw the X/Y axis */
- draw = !draw;
- x = (((int)SDL_JoystickGetAxis(joystick, 0))+32768);
- x *= SCREEN_WIDTH;
- x /= 65535;
- if ( x < 0 ) {
- x = 0;
- } else
- if ( x > (SCREEN_WIDTH-16) ) {
- x = SCREEN_WIDTH-16;
+ /* Draw the X/Y axis */
+ draw = !draw;
+ x = (((int)SDL_JoystickGetAxis(joystick, i*2+0))+32768);
+ x *= SCREEN_WIDTH;
+ x /= 65535;
+ if ( x < 0 ) {
+ x = 0;
+ } else
+ if ( x > (SCREEN_WIDTH-16) ) {
+ x = SCREEN_WIDTH-16;
+ }
+ y = (((int)SDL_JoystickGetAxis(joystick, i*2+1))+32768);
+ y *= SCREEN_HEIGHT;
+ y /= 65535;
+ if ( y < 0 ) {
+ y = 0;
+ } else
+ if ( y > (SCREEN_HEIGHT-16) ) {
+ y = SCREEN_HEIGHT-16;
+ }
+ axis_area[i][draw].x = (Sint16)x;
+ axis_area[i][draw].y = (Sint16)y;
+ axis_area[i][draw].w = 16;
+ axis_area[i][draw].h = 16;
+ SDL_FillRect(screen, &axis_area[i][draw], 0xFFFF);
+
+ SDL_UpdateRects(screen, 2, axis_area[i]);
}
- y = (((int)SDL_JoystickGetAxis(joystick, 1))+32768);
- y *= SCREEN_HEIGHT;
- y /= 65535;
- if ( y < 0 ) {
- y = 0;
- } else
- if ( y > (SCREEN_HEIGHT-16) ) {
- y = SCREEN_HEIGHT-16;
- }
- axis_area[draw].x = (Sint16)x;
- axis_area[draw].y = (Sint16)y;
- axis_area[draw].w = 16;
- axis_area[draw].h = 16;
- SDL_FillRect(screen, &axis_area[draw], 0xFFFF);
-
- SDL_UpdateRects(screen, 2, axis_area);
}
}