src/joystick/win32/SDL_dxjoystick.c
changeset 2198 fe19afb86473
parent 1895 c121d94672cb
child 2576 034440120c38
child 2698 e1da92da346c
child 2713 0906692aa6a4
     1.1 --- a/src/joystick/win32/SDL_dxjoystick.c	Sat Jul 14 07:28:45 2007 +0000
     1.2 +++ b/src/joystick/win32/SDL_dxjoystick.c	Sun Jul 15 01:51:11 2007 +0000
     1.3 @@ -44,33 +44,61 @@
     1.4  
     1.5  #define DIRECTINPUT_VERSION 0x0500
     1.6  #include <dinput.h>
     1.7 +#ifdef _MSC_VER
     1.8 +    /* Used for the c_dfDIJoystick2 symbol (no imports are used) */
     1.9 +#   pragma comment (lib, "dinput.lib")
    1.10 +#endif
    1.11 +#include <dxerr9.h>             /* From DirectX SDK 9c */
    1.12 +#ifdef _MSC_VER
    1.13 +#   pragma comment (lib, "dxerr9.lib")
    1.14 +#endif
    1.15 +
    1.16 +/* an ISO hack for VisualC++ */
    1.17 +#ifdef _MSC_VER
    1.18 +#define   snprintf	_snprintf
    1.19 +#endif
    1.20  
    1.21  #define INPUT_QSIZE	32      /* Buffer up to 32 input messages */
    1.22 -
    1.23 -extern HINSTANCE SDL_Instance;
    1.24 -extern int DX5_Load();
    1.25 -extern void DX5_Unload();
    1.26 -extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
    1.27 -                                       LPDIRECTINPUT * ppDI,
    1.28 -                                       LPUNKNOWN punkOuter);
    1.29 -
    1.30 -static LPDIRECTINPUT dinput = NULL;
    1.31 -
    1.32  #define MAX_JOYSTICKS	8
    1.33  #define MAX_INPUTS	256     /* each joystick can have up to 256 inputs */
    1.34  #define AXIS_MIN	-32768  /* minimum value for axis coordinate */
    1.35  #define AXIS_MAX	32767   /* maximum value for axis coordinate */
    1.36  #define JOY_AXIS_THRESHOLD	(((AXIS_MAX)-(AXIS_MIN))/100)   /* 1% motion */
    1.37  
    1.38 +/* external variables referenced. */
    1.39 +extern HINSTANCE SDL_Instance;
    1.40 +extern HWND SDL_Window;
    1.41 +
    1.42 +
    1.43 +/* local variables */
    1.44 +static LPDIRECTINPUT dinput = NULL;
    1.45 +extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
    1.46 +                                       LPDIRECTINPUT * ppDI,
    1.47 +                                       LPUNKNOWN punkOuter);
    1.48 +static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS];    /* array to hold joystick ID values */
    1.49 +static int SYS_NumJoysticks;
    1.50 +static HINSTANCE DInputDLL = NULL;
    1.51 +
    1.52 +
    1.53 +/* local prototypes */
    1.54 +static void SetDIerror(const char *function, HRESULT code);
    1.55 +static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE *
    1.56 +                                           pdidInstance, VOID * pContext);
    1.57 +static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev,
    1.58 +                                            LPVOID pvRef);
    1.59 +static Uint8 TranslatePOV(DWORD value);
    1.60 +static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis,
    1.61 +                                       Sint16 value);
    1.62 +static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat,
    1.63 +                                      Uint8 value);
    1.64 +static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick,
    1.65 +                                         Uint8 button, Uint8 state);
    1.66 +
    1.67 +
    1.68 +/* local types */
    1.69  typedef enum Type
    1.70  { BUTTON, AXIS, HAT } Type;
    1.71  
    1.72 -/* array to hold joystick ID values */
    1.73 -static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS];
    1.74 -static int SYS_NumJoysticks;
    1.75 -
    1.76 -extern HWND SDL_Window;
    1.77 -
    1.78  typedef struct input_t
    1.79  {
    1.80      /* DirectInput offset for this input type: */
    1.81 @@ -87,6 +115,7 @@
    1.82  struct joystick_hwdata
    1.83  {
    1.84      LPDIRECTINPUTDEVICE2 InputDevice;
    1.85 +    DIDEVCAPS Capabilities;
    1.86      int buffered;
    1.87  
    1.88      input_t Inputs[MAX_INPUTS];
    1.89 @@ -95,123 +124,13 @@
    1.90  
    1.91  /* Convert a DirectInput return code to a text message */
    1.92  static void
    1.93 -SetDIerror(char *function, int code)
    1.94 +SetDIerror(const char *function, HRESULT code)
    1.95  {
    1.96 -    static char *error;
    1.97 -    static char errbuf[1024];
    1.98 -
    1.99 -    errbuf[0] = 0;
   1.100 -    switch (code) {
   1.101 -    case DIERR_GENERIC:
   1.102 -        error = "Undefined error!";
   1.103 -        break;
   1.104 -    case DIERR_OLDDIRECTINPUTVERSION:
   1.105 -        error = "Your version of DirectInput needs upgrading";
   1.106 -        break;
   1.107 -    case DIERR_INVALIDPARAM:
   1.108 -        error = "Invalid parameters";
   1.109 -        break;
   1.110 -    case DIERR_OUTOFMEMORY:
   1.111 -        error = "Out of memory";
   1.112 -        break;
   1.113 -    case DIERR_DEVICENOTREG:
   1.114 -        error = "Device not registered";
   1.115 -        break;
   1.116 -    case DIERR_NOINTERFACE:
   1.117 -        error = "Interface not supported";
   1.118 -        break;
   1.119 -    case DIERR_NOTINITIALIZED:
   1.120 -        error = "Device not initialized";
   1.121 -        break;
   1.122 -    default:
   1.123 -        sprintf(errbuf, "%s: Unknown DirectInput error: 0x%x",
   1.124 -                function, code);
   1.125 -        break;
   1.126 -    }
   1.127 -    if (!errbuf[0]) {
   1.128 -        sprintf(errbuf, "%s: %s", function, error);
   1.129 -    }
   1.130 -    SDL_SetError("%s", errbuf);
   1.131 -    return;
   1.132 +    SDL_SetError("%s() [%s]: %s", function,
   1.133 +                 DXGetErrorString9(code), DXGetErrorDescription9(code));
   1.134  }
   1.135  
   1.136  
   1.137 -BOOL CALLBACK
   1.138 -EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
   1.139 -{
   1.140 -    memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance,
   1.141 -           sizeof(DIDEVICEINSTANCE));
   1.142 -    SYS_NumJoysticks++;
   1.143 -
   1.144 -    if (SYS_NumJoysticks >= MAX_JOYSTICKS)
   1.145 -        return DIENUM_STOP;
   1.146 -
   1.147 -    return DIENUM_CONTINUE;
   1.148 -}
   1.149 -
   1.150 -static BOOL CALLBACK
   1.151 -DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
   1.152 -{
   1.153 -    SDL_Joystick *joystick = (SDL_Joystick *) pvRef;
   1.154 -    HRESULT result;
   1.155 -    input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
   1.156 -    const int SupportedMask = DIDFT_BUTTON | DIDFT_POV | DIDFT_AXIS;
   1.157 -    if (!(dev->dwType & SupportedMask))
   1.158 -        return DIENUM_CONTINUE; /* unsupported */
   1.159 -
   1.160 -    in->ofs = dev->dwOfs;
   1.161 -
   1.162 -    if (dev->dwType & DIDFT_BUTTON) {
   1.163 -        in->type = BUTTON;
   1.164 -        in->num = joystick->nbuttons;
   1.165 -        joystick->nbuttons++;
   1.166 -    } else if (dev->dwType & DIDFT_POV) {
   1.167 -        in->type = HAT;
   1.168 -        in->num = joystick->nhats;
   1.169 -        joystick->nhats++;
   1.170 -    } else {                    /* dev->dwType & DIDFT_AXIS */
   1.171 -        DIPROPRANGE diprg;
   1.172 -        DIPROPDWORD dilong;
   1.173 -
   1.174 -        in->type = AXIS;
   1.175 -        in->num = joystick->naxes;
   1.176 -
   1.177 -        diprg.diph.dwSize = sizeof(diprg);
   1.178 -        diprg.diph.dwHeaderSize = sizeof(diprg.diph);
   1.179 -        diprg.diph.dwObj = dev->dwOfs;
   1.180 -        diprg.diph.dwHow = DIPH_BYOFFSET;
   1.181 -        diprg.lMin = AXIS_MIN;
   1.182 -        diprg.lMax = AXIS_MAX;
   1.183 -
   1.184 -        result =
   1.185 -            IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
   1.186 -                                            DIPROP_RANGE, &diprg.diph);
   1.187 -        if (result != DI_OK)
   1.188 -            return DIENUM_CONTINUE;     /* don't use this axis */
   1.189 -
   1.190 -        /* Set dead zone to 0. */
   1.191 -        dilong.diph.dwSize = sizeof(dilong);
   1.192 -        dilong.diph.dwHeaderSize = sizeof(dilong.diph);
   1.193 -        dilong.diph.dwObj = dev->dwOfs;
   1.194 -        dilong.diph.dwHow = DIPH_BYOFFSET;
   1.195 -        dilong.dwData = 0;
   1.196 -        result =
   1.197 -            IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
   1.198 -                                            DIPROP_DEADZONE, &dilong.diph);
   1.199 -        if (result != DI_OK)
   1.200 -            return DIENUM_CONTINUE;     /* don't use this axis */
   1.201 -
   1.202 -        joystick->naxes++;
   1.203 -    }
   1.204 -
   1.205 -    joystick->hwdata->NumInputs++;
   1.206 -
   1.207 -    if (joystick->hwdata->NumInputs == MAX_INPUTS)
   1.208 -        return DIENUM_STOP;     /* too many */
   1.209 -
   1.210 -    return DIENUM_CONTINUE;
   1.211 -}
   1.212 -
   1.213  /* Function to scan the system for joysticks.
   1.214   * This function should set SDL_numjoysticks to the number of available
   1.215   * joysticks.  Joystick 0 should be the system default joystick.
   1.216 @@ -224,18 +143,30 @@
   1.217  
   1.218      SYS_NumJoysticks = 0;
   1.219  
   1.220 -    /* Create the DirectInput object */
   1.221 -    if (DX5_Load() < 0) {
   1.222 -        SDL_SetError("Couldn't load DirectInput");
   1.223 -        return (-1);
   1.224 -    }
   1.225 -    result = DInputCreate(SDL_Instance, DIRECTINPUT_VERSION, &dinput, NULL);
   1.226 -    if (result != DI_OK) {
   1.227 -        DX5_Unload();
   1.228 -        SetDIerror("DirectInputCreate", result);
   1.229 +    result = CoInitialize(NULL);
   1.230 +    if (FAILED(result)) {
   1.231 +        SetDIerror("CoInitialize", result);
   1.232          return (-1);
   1.233      }
   1.234  
   1.235 +    result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
   1.236 +                              &IID_IDirectInput, &dinput);
   1.237 +
   1.238 +    if (FAILED(result)) {
   1.239 +        SetDIerror("CoCreateInstance", result);
   1.240 +        return (-1);
   1.241 +    }
   1.242 +
   1.243 +    /* Because we used CoCreateInstance, we need to Initialize it, first. */
   1.244 +    result =
   1.245 +        IDirectInput_Initialize(dinput, SDL_Instance, DIRECTINPUT_VERSION);
   1.246 +
   1.247 +    if (FAILED(result)) {
   1.248 +        SetDIerror("IDirectInput::Initialize", result);
   1.249 +        return (-1);
   1.250 +    }
   1.251 +
   1.252 +    /* Look for joysticks, wheels, head trackers, gamepads, etc.. */
   1.253      result = IDirectInput_EnumDevices(dinput,
   1.254                                        DIDEVTYPE_JOYSTICK,
   1.255                                        EnumJoysticksCallback,
   1.256 @@ -244,6 +175,19 @@
   1.257      return SYS_NumJoysticks;
   1.258  }
   1.259  
   1.260 +static BOOL CALLBACK
   1.261 +EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
   1.262 +{
   1.263 +    memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance,
   1.264 +           sizeof(DIDEVICEINSTANCE));
   1.265 +    SYS_NumJoysticks++;
   1.266 +
   1.267 +    if (SYS_NumJoysticks >= MAX_JOYSTICKS)
   1.268 +        return DIENUM_STOP;
   1.269 +
   1.270 +    return DIENUM_CONTINUE;
   1.271 +}
   1.272 +
   1.273  /* Function to get the device-dependent name of a joystick */
   1.274  const char *
   1.275  SDL_SYS_JoystickName(int index)
   1.276 @@ -262,84 +206,354 @@
   1.277  {
   1.278      HRESULT result;
   1.279      LPDIRECTINPUTDEVICE device;
   1.280 +    DIPROPDWORD dipdw;
   1.281 +
   1.282 +    ZeroMemory(&dipdw, sizeof(DIPROPDWORD));
   1.283 +    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
   1.284 +    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
   1.285 +
   1.286  
   1.287      /* allocate memory for system specific hardware data */
   1.288      joystick->hwdata =
   1.289 -        (struct joystick_hwdata *) malloc(sizeof(*joystick->hwdata));
   1.290 +        (struct joystick_hwdata *) malloc(sizeof(struct joystick_hwdata));
   1.291      if (joystick->hwdata == NULL) {
   1.292          SDL_OutOfMemory();
   1.293          return (-1);
   1.294      }
   1.295 -    memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
   1.296 +    ZeroMemory(joystick->hwdata, sizeof(struct joystick_hwdata));
   1.297      joystick->hwdata->buffered = 1;
   1.298 +    joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
   1.299  
   1.300      result =
   1.301          IDirectInput_CreateDevice(dinput,
   1.302                                    &SYS_Joystick[joystick->index].
   1.303                                    guidInstance, &device, NULL);
   1.304 -    if (result != DI_OK) {
   1.305 -        SetDIerror("DirectInput::CreateDevice", result);
   1.306 +    if (FAILED(result)) {
   1.307 +        SetDIerror("IDirectInput::CreateDevice", result);
   1.308          return (-1);
   1.309      }
   1.310  
   1.311 +    /* Now get the IDirectInputDevice2 interface, instead. */
   1.312      result = IDirectInputDevice_QueryInterface(device,
   1.313                                                 &IID_IDirectInputDevice2,
   1.314                                                 (LPVOID *) & joystick->
   1.315                                                 hwdata->InputDevice);
   1.316 +    /* We are done with this object.  Use the stored one from now on. */
   1.317      IDirectInputDevice_Release(device);
   1.318 -    if (result != DI_OK) {
   1.319 -        SetDIerror("DirectInputDevice::QueryInterface", result);
   1.320 +
   1.321 +    if (FAILED(result)) {
   1.322 +        SetDIerror("IDirectInputDevice::QueryInterface", result);
   1.323          return (-1);
   1.324      }
   1.325  
   1.326 +    /* Aquire shared access. Exclusive access is required for forces,
   1.327 +     * though. */
   1.328      result =
   1.329          IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata->
   1.330                                                  InputDevice, SDL_Window,
   1.331 -                                                DISCL_NONEXCLUSIVE |
   1.332 +                                                DISCL_EXCLUSIVE |
   1.333                                                  DISCL_BACKGROUND);
   1.334 -    if (result != DI_OK) {
   1.335 -        SetDIerror("DirectInputDevice::SetCooperativeLevel", result);
   1.336 +    if (FAILED(result)) {
   1.337 +        SetDIerror("IDirectInputDevice2::SetCooperativeLevel", result);
   1.338          return (-1);
   1.339      }
   1.340  
   1.341 +    /* Use the extended data structure: DIJOYSTATE2. */
   1.342      result =
   1.343          IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice,
   1.344 -                                          &c_dfDIJoystick);
   1.345 -    if (result != DI_OK) {
   1.346 -        SetDIerror("DirectInputDevice::SetDataFormat", result);
   1.347 +                                          &c_dfDIJoystick2);
   1.348 +    if (FAILED(result)) {
   1.349 +        SetDIerror("IDirectInputDevice2::SetDataFormat", result);
   1.350          return (-1);
   1.351      }
   1.352  
   1.353 -    IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice,
   1.354 -                                    DIJoystick_EnumDevObjectsProc,
   1.355 -                                    joystick,
   1.356 -                                    DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
   1.357 +    /* Get device capabilities */
   1.358 +    result =
   1.359 +        IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice,
   1.360 +                                            &joystick->hwdata->Capabilities);
   1.361  
   1.362 -    {
   1.363 -        DIPROPDWORD dipdw;
   1.364 -        memset(&dipdw, 0, sizeof(dipdw));
   1.365 -        dipdw.diph.dwSize = sizeof(dipdw);
   1.366 -        dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
   1.367 +    if (FAILED(result)) {
   1.368 +        SetDIerror("IDirectInputDevice2::GetCapabilities", result);
   1.369 +        return (-1);
   1.370 +    }
   1.371 +
   1.372 +    /* Force capable? */
   1.373 +    if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
   1.374 +
   1.375 +        result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
   1.376 +
   1.377 +        if (FAILED(result)) {
   1.378 +            SetDIerror("IDirectInputDevice2::Acquire", result);
   1.379 +            return (-1);
   1.380 +        }
   1.381 +
   1.382 +        /* reset all accuators. */
   1.383 +        result =
   1.384 +            IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata->
   1.385 +                                                         InputDevice,
   1.386 +                                                         DISFFC_RESET);
   1.387 +
   1.388 +        if (FAILED(result)) {
   1.389 +            SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand",
   1.390 +                       result);
   1.391 +            return (-1);
   1.392 +        }
   1.393 +
   1.394 +        result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice);
   1.395 +
   1.396 +        if (FAILED(result)) {
   1.397 +            SetDIerror("IDirectInputDevice2::Unacquire", result);
   1.398 +            return (-1);
   1.399 +        }
   1.400 +
   1.401 +        /* Turn on auto-centering for a ForceFeedback device (until told
   1.402 +         * otherwise). */
   1.403          dipdw.diph.dwObj = 0;
   1.404          dipdw.diph.dwHow = DIPH_DEVICE;
   1.405 -        dipdw.dwData = INPUT_QSIZE;
   1.406 +        dipdw.dwData = DIPROPAUTOCENTER_ON;
   1.407 +
   1.408          result =
   1.409              IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
   1.410 -                                            DIPROP_BUFFERSIZE, &dipdw.diph);
   1.411 +                                            DIPROP_AUTOCENTER, &dipdw.diph);
   1.412  
   1.413 -        if (result == DI_POLLEDDEVICE) {
   1.414 -            /* This device doesn't support buffering, so we're forced
   1.415 -             * to use less reliable polling. */
   1.416 -            joystick->hwdata->buffered = 0;
   1.417 -        } else if (result != DI_OK) {
   1.418 -            SetDIerror("DirectInputDevice::SetProperty", result);
   1.419 +        if (FAILED(result)) {
   1.420 +            SetDIerror("IDirectInputDevice2::SetProperty", result);
   1.421              return (-1);
   1.422          }
   1.423      }
   1.424  
   1.425 +    /* What buttons and axes does it have? */
   1.426 +    IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice,
   1.427 +                                    EnumDevObjectsCallback, joystick,
   1.428 +                                    DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
   1.429 +
   1.430 +    dipdw.diph.dwObj = 0;
   1.431 +    dipdw.diph.dwHow = DIPH_DEVICE;
   1.432 +    dipdw.dwData = INPUT_QSIZE;
   1.433 +
   1.434 +    /* Set the buffer size */
   1.435 +    result =
   1.436 +        IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
   1.437 +                                        DIPROP_BUFFERSIZE, &dipdw.diph);
   1.438 +
   1.439 +    if (result == DI_POLLEDDEVICE) {
   1.440 +        /* This device doesn't support buffering, so we're forced
   1.441 +         * to use less reliable polling. */
   1.442 +        joystick->hwdata->buffered = 0;
   1.443 +    } else if (FAILED(result)) {
   1.444 +        SetDIerror("IDirectInputDevice2::SetProperty", result);
   1.445 +        return (-1);
   1.446 +    }
   1.447 +
   1.448      return (0);
   1.449  }
   1.450  
   1.451 +static BOOL CALLBACK
   1.452 +EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
   1.453 +{
   1.454 +    SDL_Joystick *joystick = (SDL_Joystick *) pvRef;
   1.455 +    HRESULT result;
   1.456 +    input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
   1.457 +
   1.458 +    in->ofs = dev->dwOfs;
   1.459 +
   1.460 +    if (dev->dwType & DIDFT_BUTTON) {
   1.461 +        in->type = BUTTON;
   1.462 +        in->num = joystick->nbuttons;
   1.463 +        joystick->nbuttons++;
   1.464 +    } else if (dev->dwType & DIDFT_POV) {
   1.465 +        in->type = HAT;
   1.466 +        in->num = joystick->nhats;
   1.467 +        joystick->nhats++;
   1.468 +    } else if (dev->dwType & DIDFT_AXIS) {
   1.469 +        DIPROPRANGE diprg;
   1.470 +        DIPROPDWORD dilong;
   1.471 +
   1.472 +        in->type = AXIS;
   1.473 +        in->num = joystick->naxes;
   1.474 +
   1.475 +        diprg.diph.dwSize = sizeof(diprg);
   1.476 +        diprg.diph.dwHeaderSize = sizeof(diprg.diph);
   1.477 +        diprg.diph.dwObj = dev->dwOfs;
   1.478 +        diprg.diph.dwHow = DIPH_BYOFFSET;
   1.479 +        diprg.lMin = AXIS_MIN;
   1.480 +        diprg.lMax = AXIS_MAX;
   1.481 +
   1.482 +        result =
   1.483 +            IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
   1.484 +                                            DIPROP_RANGE, &diprg.diph);
   1.485 +        if (FAILED(result)) {
   1.486 +            return DIENUM_CONTINUE;     /* don't use this axis */
   1.487 +        }
   1.488 +
   1.489 +        /* Set dead zone to 0. */
   1.490 +        dilong.diph.dwSize = sizeof(dilong);
   1.491 +        dilong.diph.dwHeaderSize = sizeof(dilong.diph);
   1.492 +        dilong.diph.dwObj = dev->dwOfs;
   1.493 +        dilong.diph.dwHow = DIPH_BYOFFSET;
   1.494 +        dilong.dwData = 0;
   1.495 +        result =
   1.496 +            IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
   1.497 +                                            DIPROP_DEADZONE, &dilong.diph);
   1.498 +        if (FAILED(result)) {
   1.499 +            return DIENUM_CONTINUE;     /* don't use this axis */
   1.500 +        }
   1.501 +
   1.502 +        joystick->naxes++;
   1.503 +    } else {
   1.504 +        /* not supported at this time */
   1.505 +        return DIENUM_CONTINUE;
   1.506 +    }
   1.507 +
   1.508 +    joystick->hwdata->NumInputs++;
   1.509 +
   1.510 +    if (joystick->hwdata->NumInputs == MAX_INPUTS) {
   1.511 +        return DIENUM_STOP;     /* too many */
   1.512 +    }
   1.513 +
   1.514 +    return DIENUM_CONTINUE;
   1.515 +}
   1.516 +
   1.517 +/* Function to update the state of a joystick - called as a device poll.
   1.518 + * This function shouldn't update the joystick structure directly,
   1.519 + * but instead should call SDL_PrivateJoystick*() to deliver events
   1.520 + * and update joystick device state.
   1.521 + */
   1.522 +void
   1.523 +SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick)
   1.524 +{
   1.525 +    DIJOYSTATE2 state;
   1.526 +    HRESULT result;
   1.527 +    int i;
   1.528 +
   1.529 +    result =
   1.530 +        IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice,
   1.531 +                                           sizeof(DIJOYSTATE2), &state);
   1.532 +    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
   1.533 +        IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
   1.534 +        result =
   1.535 +            IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice,
   1.536 +                                               sizeof(DIJOYSTATE2), &state);
   1.537 +    }
   1.538 +
   1.539 +    /* Set each known axis, button and POV. */
   1.540 +    for (i = 0; i < joystick->hwdata->NumInputs; ++i) {
   1.541 +        const input_t *in = &joystick->hwdata->Inputs[i];
   1.542 +
   1.543 +        switch (in->type) {
   1.544 +        case AXIS:
   1.545 +            switch (in->ofs) {
   1.546 +            case DIJOFS_X:
   1.547 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.548 +                                            (Sint16) state.lX);
   1.549 +                break;
   1.550 +            case DIJOFS_Y:
   1.551 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.552 +                                            (Sint16) state.lY);
   1.553 +                break;
   1.554 +            case DIJOFS_Z:
   1.555 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.556 +                                            (Sint16) state.lZ);
   1.557 +                break;
   1.558 +            case DIJOFS_RX:
   1.559 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.560 +                                            (Sint16) state.lRx);
   1.561 +                break;
   1.562 +            case DIJOFS_RY:
   1.563 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.564 +                                            (Sint16) state.lRy);
   1.565 +                break;
   1.566 +            case DIJOFS_RZ:
   1.567 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.568 +                                            (Sint16) state.lRz);
   1.569 +                break;
   1.570 +            case DIJOFS_SLIDER(0):
   1.571 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.572 +                                            (Sint16) state.rglSlider[0]);
   1.573 +                break;
   1.574 +            case DIJOFS_SLIDER(1):
   1.575 +                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.576 +                                            (Sint16) state.rglSlider[1]);
   1.577 +                break;
   1.578 +            }
   1.579 +
   1.580 +            break;
   1.581 +
   1.582 +        case BUTTON:
   1.583 +            SDL_PrivateJoystickButton_Int(joystick, in->num,
   1.584 +                                          (Uint8) (state.
   1.585 +                                                   rgbButtons[in->ofs -
   1.586 +                                                              DIJOFS_BUTTON0]
   1.587 +                                                   ? SDL_PRESSED :
   1.588 +                                                   SDL_RELEASED));
   1.589 +            break;
   1.590 +        case HAT:
   1.591 +            {
   1.592 +                Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs -
   1.593 +                                                       DIJOFS_POV(0)]);
   1.594 +                SDL_PrivateJoystickHat_Int(joystick, in->num, pos);
   1.595 +                break;
   1.596 +            }
   1.597 +        }
   1.598 +    }
   1.599 +}
   1.600 +
   1.601 +void
   1.602 +SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick)
   1.603 +{
   1.604 +    int i;
   1.605 +    HRESULT result;
   1.606 +    DWORD numevents;
   1.607 +    DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
   1.608 +
   1.609 +    numevents = INPUT_QSIZE;
   1.610 +    result =
   1.611 +        IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice,
   1.612 +                                          sizeof(DIDEVICEOBJECTDATA), evtbuf,
   1.613 +                                          &numevents, 0);
   1.614 +    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
   1.615 +        IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
   1.616 +        result =
   1.617 +            IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice,
   1.618 +                                              sizeof(DIDEVICEOBJECTDATA),
   1.619 +                                              evtbuf, &numevents, 0);
   1.620 +    }
   1.621 +
   1.622 +    /* Handle the events or punt */
   1.623 +    if (FAILED(result))
   1.624 +        return;
   1.625 +
   1.626 +    for (i = 0; i < (int) numevents; ++i) {
   1.627 +        int j;
   1.628 +
   1.629 +        for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
   1.630 +            const input_t *in = &joystick->hwdata->Inputs[j];
   1.631 +
   1.632 +            if (evtbuf[i].dwOfs != in->ofs)
   1.633 +                continue;
   1.634 +
   1.635 +            switch (in->type) {
   1.636 +            case AXIS:
   1.637 +                SDL_PrivateJoystickAxis(joystick, in->num,
   1.638 +                                        (Sint16) evtbuf[i].dwData);
   1.639 +                break;
   1.640 +            case BUTTON:
   1.641 +                SDL_PrivateJoystickButton(joystick, in->num,
   1.642 +                                          (Uint8) (evtbuf[i].
   1.643 +                                                   dwData ? SDL_PRESSED :
   1.644 +                                                   SDL_RELEASED));
   1.645 +                break;
   1.646 +            case HAT:
   1.647 +                {
   1.648 +                    Uint8 pos = TranslatePOV(evtbuf[i].dwData);
   1.649 +                    SDL_PrivateJoystickHat(joystick, in->num, pos);
   1.650 +                }
   1.651 +            }
   1.652 +        }
   1.653 +    }
   1.654 +}
   1.655 +
   1.656 +
   1.657  static Uint8
   1.658  TranslatePOV(DWORD value)
   1.659  {
   1.660 @@ -395,147 +609,6 @@
   1.661      return 0;
   1.662  }
   1.663  
   1.664 -/* Function to update the state of a joystick - called as a device poll.
   1.665 - * This function shouldn't update the joystick structure directly,
   1.666 - * but instead should call SDL_PrivateJoystick*() to deliver events
   1.667 - * and update joystick device state.
   1.668 - */
   1.669 -void
   1.670 -SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick)
   1.671 -{
   1.672 -    DIJOYSTATE state;
   1.673 -    HRESULT result;
   1.674 -    int i;
   1.675 -
   1.676 -    result =
   1.677 -        IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice,
   1.678 -                                           sizeof(state), &state);
   1.679 -    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
   1.680 -        IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
   1.681 -        result =
   1.682 -            IDirectInputDevice2_GetDeviceState(joystick->hwdata->
   1.683 -                                               InputDevice, sizeof(state),
   1.684 -                                               &state);
   1.685 -    }
   1.686 -
   1.687 -    /* Set each known axis, button and POV. */
   1.688 -    for (i = 0; i < joystick->hwdata->NumInputs; ++i) {
   1.689 -        const input_t *in = &joystick->hwdata->Inputs[i];
   1.690 -
   1.691 -        switch (in->type) {
   1.692 -        case AXIS:
   1.693 -            switch (in->ofs) {
   1.694 -            case DIJOFS_X:
   1.695 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.696 -                                            (Sint16) state.lX);
   1.697 -                break;
   1.698 -            case DIJOFS_Y:
   1.699 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.700 -                                            (Sint16) state.lY);
   1.701 -                break;
   1.702 -            case DIJOFS_Z:
   1.703 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.704 -                                            (Sint16) state.lZ);
   1.705 -                break;
   1.706 -            case DIJOFS_RX:
   1.707 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.708 -                                            (Sint16) state.lRx);
   1.709 -                break;
   1.710 -            case DIJOFS_RY:
   1.711 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.712 -                                            (Sint16) state.lRy);
   1.713 -                break;
   1.714 -            case DIJOFS_RZ:
   1.715 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.716 -                                            (Sint16) state.lRz);
   1.717 -                break;
   1.718 -            case DIJOFS_SLIDER(0):
   1.719 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.720 -                                            (Sint16) state.rglSlider[0]);
   1.721 -                break;
   1.722 -            case DIJOFS_SLIDER(1):
   1.723 -                SDL_PrivateJoystickAxis_Int(joystick, in->num,
   1.724 -                                            (Sint16) state.rglSlider[0]);
   1.725 -                break;
   1.726 -            }
   1.727 -
   1.728 -            break;
   1.729 -
   1.730 -        case BUTTON:
   1.731 -            SDL_PrivateJoystickButton_Int(joystick, in->num,
   1.732 -                                          (Uint8) (state.
   1.733 -                                                   rgbButtons[in->ofs -
   1.734 -                                                              DIJOFS_BUTTON0]
   1.735 -                                                   ? SDL_PRESSED :
   1.736 -                                                   SDL_RELEASED));
   1.737 -            break;
   1.738 -        case HAT:
   1.739 -            {
   1.740 -                Uint8 pos =
   1.741 -                    TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]);
   1.742 -                SDL_PrivateJoystickHat_Int(joystick, in->num, pos);
   1.743 -                break;
   1.744 -            }
   1.745 -        }
   1.746 -    }
   1.747 -}
   1.748 -
   1.749 -void
   1.750 -SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick)
   1.751 -{
   1.752 -    int i;
   1.753 -    HRESULT result;
   1.754 -    DWORD numevents;
   1.755 -    DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
   1.756 -
   1.757 -    numevents = INPUT_QSIZE;
   1.758 -    result =
   1.759 -        IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice,
   1.760 -                                          sizeof(DIDEVICEOBJECTDATA),
   1.761 -                                          evtbuf, &numevents, 0);
   1.762 -    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
   1.763 -        IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
   1.764 -        result =
   1.765 -            IDirectInputDevice2_GetDeviceData(joystick->hwdata->
   1.766 -                                              InputDevice,
   1.767 -                                              sizeof(DIDEVICEOBJECTDATA),
   1.768 -                                              evtbuf, &numevents, 0);
   1.769 -    }
   1.770 -
   1.771 -    /* Handle the events */
   1.772 -    if (result != DI_OK)
   1.773 -        return;
   1.774 -
   1.775 -    for (i = 0; i < (int) numevents; ++i) {
   1.776 -        int j;
   1.777 -
   1.778 -        for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
   1.779 -            const input_t *in = &joystick->hwdata->Inputs[j];
   1.780 -
   1.781 -            if (evtbuf[i].dwOfs != in->ofs)
   1.782 -                continue;
   1.783 -
   1.784 -            switch (in->type) {
   1.785 -            case AXIS:
   1.786 -                SDL_PrivateJoystickAxis(joystick, in->num,
   1.787 -                                        (Sint16) evtbuf[i].dwData);
   1.788 -                break;
   1.789 -            case BUTTON:
   1.790 -                SDL_PrivateJoystickButton(joystick, in->num,
   1.791 -                                          (Uint8) (evtbuf[i].
   1.792 -                                                   dwData ? SDL_PRESSED
   1.793 -                                                   : SDL_RELEASED));
   1.794 -                break;
   1.795 -            case HAT:
   1.796 -                {
   1.797 -                    Uint8 pos = TranslatePOV(evtbuf[i].dwData);
   1.798 -                    SDL_PrivateJoystickHat(joystick, in->num, pos);
   1.799 -                }
   1.800 -            }
   1.801 -        }
   1.802 -    }
   1.803 -}
   1.804 -
   1.805  void
   1.806  SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
   1.807  {
   1.808 @@ -572,7 +645,6 @@
   1.809  {
   1.810      IDirectInput_Release(dinput);
   1.811      dinput = NULL;
   1.812 -    DX5_Unload();
   1.813  }
   1.814  
   1.815  #endif /* SDL_JOYSTICK_DINPUT */