src/joystick/windows/SDL_dinputjoystick.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 07 Jul 2014 10:26:28 -0700
changeset 8976 1a5d959d7b32
parent 8972 dfc759d7486f
child 9475 d5adc0c06a03
permissions -rw-r--r--
Fixed mingw64 build and warnings
slouken@1895
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@8149
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@1895
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@1895
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@1895
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@1895
    20
*/
icculus@8093
    21
#include "../../SDL_internal.h"
slouken@1895
    22
slouken@8972
    23
#include "../SDL_sysjoystick.h"
slouken@8972
    24
#include "SDL_windowsjoystick_c.h"
slouken@8972
    25
#include "SDL_dinputjoystick_c.h"
slouken@8972
    26
#include "SDL_xinputjoystick_c.h"
slouken@1895
    27
slouken@1895
    28
slouken@8972
    29
#if SDL_JOYSTICK_DINPUT
icculus@8179
    30
slouken@2761
    31
#ifndef DIDFT_OPTIONAL
slouken@7191
    32
#define DIDFT_OPTIONAL      0x80000000
slouken@2761
    33
#endif
slouken@2761
    34
slouken@7191
    35
#define INPUT_QSIZE 32      /* Buffer up to 32 input messages */
slouken@7191
    36
#define AXIS_MIN    -32768  /* minimum value for axis coordinate */
slouken@7191
    37
#define AXIS_MAX    32767   /* maximum value for axis coordinate */
slouken@7191
    38
#define JOY_AXIS_THRESHOLD  (((AXIS_MAX)-(AXIS_MIN))/100)   /* 1% motion */
slouken@1895
    39
slouken@2198
    40
/* external variables referenced. */
slouken@2713
    41
extern HWND SDL_HelperWindow;
slouken@2198
    42
slouken@2198
    43
/* local variables */
icculus@5591
    44
static SDL_bool coinitialized = SDL_FALSE;
icculus@6716
    45
static LPDIRECTINPUT8 dinput = NULL;
slouken@8972
    46
static PRAWINPUTDEVICELIST SDL_RawDevList = NULL;
slouken@8972
    47
static UINT SDL_RawDevListCount = 0;
slouken@2198
    48
slouken@7191
    49
/* Taken from Wine - Thanks! */
slouken@8972
    50
static DIOBJECTDATAFORMAT dfDIJoystick2[] = {
slouken@8972
    51
        { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    52
        { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    53
        { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    54
        { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    55
        { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    56
        { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    57
        { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    58
        { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    59
        { &GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    60
        { &GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    61
        { &GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    62
        { &GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    63
        { NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    64
        { NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    65
        { NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    66
        { NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    67
        { NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    68
        { NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    69
        { NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    70
        { NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    71
        { NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    72
        { NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    73
        { NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    74
        { NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    75
        { NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    76
        { NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    77
        { NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    78
        { NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    79
        { NULL, DIJOFS_BUTTON(16), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    80
        { NULL, DIJOFS_BUTTON(17), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    81
        { NULL, DIJOFS_BUTTON(18), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    82
        { NULL, DIJOFS_BUTTON(19), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    83
        { NULL, DIJOFS_BUTTON(20), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    84
        { NULL, DIJOFS_BUTTON(21), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    85
        { NULL, DIJOFS_BUTTON(22), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    86
        { NULL, DIJOFS_BUTTON(23), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    87
        { NULL, DIJOFS_BUTTON(24), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    88
        { NULL, DIJOFS_BUTTON(25), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    89
        { NULL, DIJOFS_BUTTON(26), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    90
        { NULL, DIJOFS_BUTTON(27), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    91
        { NULL, DIJOFS_BUTTON(28), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    92
        { NULL, DIJOFS_BUTTON(29), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    93
        { NULL, DIJOFS_BUTTON(30), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    94
        { NULL, DIJOFS_BUTTON(31), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    95
        { NULL, DIJOFS_BUTTON(32), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    96
        { NULL, DIJOFS_BUTTON(33), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    97
        { NULL, DIJOFS_BUTTON(34), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    98
        { NULL, DIJOFS_BUTTON(35), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
    99
        { NULL, DIJOFS_BUTTON(36), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   100
        { NULL, DIJOFS_BUTTON(37), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   101
        { NULL, DIJOFS_BUTTON(38), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   102
        { NULL, DIJOFS_BUTTON(39), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   103
        { NULL, DIJOFS_BUTTON(40), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   104
        { NULL, DIJOFS_BUTTON(41), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   105
        { NULL, DIJOFS_BUTTON(42), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   106
        { NULL, DIJOFS_BUTTON(43), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   107
        { NULL, DIJOFS_BUTTON(44), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   108
        { NULL, DIJOFS_BUTTON(45), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   109
        { NULL, DIJOFS_BUTTON(46), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   110
        { NULL, DIJOFS_BUTTON(47), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   111
        { NULL, DIJOFS_BUTTON(48), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   112
        { NULL, DIJOFS_BUTTON(49), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   113
        { NULL, DIJOFS_BUTTON(50), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   114
        { NULL, DIJOFS_BUTTON(51), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   115
        { NULL, DIJOFS_BUTTON(52), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   116
        { NULL, DIJOFS_BUTTON(53), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   117
        { NULL, DIJOFS_BUTTON(54), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   118
        { NULL, DIJOFS_BUTTON(55), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   119
        { NULL, DIJOFS_BUTTON(56), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   120
        { NULL, DIJOFS_BUTTON(57), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   121
        { NULL, DIJOFS_BUTTON(58), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   122
        { NULL, DIJOFS_BUTTON(59), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   123
        { NULL, DIJOFS_BUTTON(60), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   124
        { NULL, DIJOFS_BUTTON(61), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   125
        { NULL, DIJOFS_BUTTON(62), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   126
        { NULL, DIJOFS_BUTTON(63), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   127
        { NULL, DIJOFS_BUTTON(64), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   128
        { NULL, DIJOFS_BUTTON(65), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   129
        { NULL, DIJOFS_BUTTON(66), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   130
        { NULL, DIJOFS_BUTTON(67), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   131
        { NULL, DIJOFS_BUTTON(68), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   132
        { NULL, DIJOFS_BUTTON(69), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   133
        { NULL, DIJOFS_BUTTON(70), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   134
        { NULL, DIJOFS_BUTTON(71), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   135
        { NULL, DIJOFS_BUTTON(72), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   136
        { NULL, DIJOFS_BUTTON(73), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   137
        { NULL, DIJOFS_BUTTON(74), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   138
        { NULL, DIJOFS_BUTTON(75), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   139
        { NULL, DIJOFS_BUTTON(76), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   140
        { NULL, DIJOFS_BUTTON(77), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   141
        { NULL, DIJOFS_BUTTON(78), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   142
        { NULL, DIJOFS_BUTTON(79), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   143
        { NULL, DIJOFS_BUTTON(80), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   144
        { NULL, DIJOFS_BUTTON(81), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   145
        { NULL, DIJOFS_BUTTON(82), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   146
        { NULL, DIJOFS_BUTTON(83), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   147
        { NULL, DIJOFS_BUTTON(84), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   148
        { NULL, DIJOFS_BUTTON(85), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   149
        { NULL, DIJOFS_BUTTON(86), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   150
        { NULL, DIJOFS_BUTTON(87), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   151
        { NULL, DIJOFS_BUTTON(88), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   152
        { NULL, DIJOFS_BUTTON(89), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   153
        { NULL, DIJOFS_BUTTON(90), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   154
        { NULL, DIJOFS_BUTTON(91), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   155
        { NULL, DIJOFS_BUTTON(92), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   156
        { NULL, DIJOFS_BUTTON(93), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   157
        { NULL, DIJOFS_BUTTON(94), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   158
        { NULL, DIJOFS_BUTTON(95), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   159
        { NULL, DIJOFS_BUTTON(96), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   160
        { NULL, DIJOFS_BUTTON(97), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   161
        { NULL, DIJOFS_BUTTON(98), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   162
        { NULL, DIJOFS_BUTTON(99), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   163
        { NULL, DIJOFS_BUTTON(100), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   164
        { NULL, DIJOFS_BUTTON(101), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   165
        { NULL, DIJOFS_BUTTON(102), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   166
        { NULL, DIJOFS_BUTTON(103), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   167
        { NULL, DIJOFS_BUTTON(104), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   168
        { NULL, DIJOFS_BUTTON(105), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   169
        { NULL, DIJOFS_BUTTON(106), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   170
        { NULL, DIJOFS_BUTTON(107), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   171
        { NULL, DIJOFS_BUTTON(108), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   172
        { NULL, DIJOFS_BUTTON(109), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   173
        { NULL, DIJOFS_BUTTON(110), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   174
        { NULL, DIJOFS_BUTTON(111), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   175
        { NULL, DIJOFS_BUTTON(112), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   176
        { NULL, DIJOFS_BUTTON(113), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   177
        { NULL, DIJOFS_BUTTON(114), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   178
        { NULL, DIJOFS_BUTTON(115), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   179
        { NULL, DIJOFS_BUTTON(116), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   180
        { NULL, DIJOFS_BUTTON(117), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   181
        { NULL, DIJOFS_BUTTON(118), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   182
        { NULL, DIJOFS_BUTTON(119), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   183
        { NULL, DIJOFS_BUTTON(120), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   184
        { NULL, DIJOFS_BUTTON(121), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   185
        { NULL, DIJOFS_BUTTON(122), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   186
        { NULL, DIJOFS_BUTTON(123), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   187
        { NULL, DIJOFS_BUTTON(124), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   188
        { NULL, DIJOFS_BUTTON(125), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   189
        { NULL, DIJOFS_BUTTON(126), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   190
        { NULL, DIJOFS_BUTTON(127), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   191
        { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   192
        { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   193
        { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   194
        { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   195
        { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   196
        { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   197
        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   198
        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   199
        { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   200
        { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   201
        { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   202
        { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   203
        { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   204
        { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   205
        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   206
        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   207
        { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   208
        { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   209
        { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   210
        { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   211
        { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   212
        { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   213
        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@8972
   214
        { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
slouken@2760
   215
};
slouken@2760
   216
slouken@2760
   217
const DIDATAFORMAT c_dfDIJoystick2 = {
slouken@2760
   218
    sizeof(DIDATAFORMAT),
slouken@2760
   219
    sizeof(DIOBJECTDATAFORMAT),
slouken@2760
   220
    DIDF_ABSAXIS,
slouken@2760
   221
    sizeof(DIJOYSTATE2),
slouken@2760
   222
    SDL_arraysize(dfDIJoystick2),
slouken@2760
   223
    dfDIJoystick2
slouken@2760
   224
};
slouken@2760
   225
slouken@1895
   226
/* Convert a DirectInput return code to a text message */
icculus@7037
   227
static int
slouken@2198
   228
SetDIerror(const char *function, HRESULT code)
slouken@1895
   229
{
slouken@2760
   230
    /*
icculus@7037
   231
    return SDL_SetError("%s() [%s]: %s", function,
slouken@8972
   232
    DXGetErrorString9A(code), DXGetErrorDescription9A(code));
slouken@8972
   233
    */
slouken@8976
   234
    return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code);
slouken@1895
   235
}
slouken@1895
   236
slouken@8920
   237
static SDL_bool
slouken@8920
   238
SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
slouken@6690
   239
{
slouken@8972
   240
    static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
slouken@8972
   241
    static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
slouken@8972
   242
    static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
slouken@8972
   243
slouken@7299
   244
    static const GUID *s_XInputProductGUID[] = {
icculus@7706
   245
        &IID_ValveStreamingGamepad,
icculus@7706
   246
        &IID_X360WiredGamepad,   /* Microsoft's wired X360 controller for Windows. */
icculus@7706
   247
        &IID_X360WirelessGamepad /* Microsoft's wireless X360 controller for Windows. */
slouken@7299
   248
    };
slouken@6690
   249
icculus@7706
   250
    size_t iDevice;
icculus@7706
   251
    UINT i;
icculus@7706
   252
slouken@8972
   253
    if (!SDL_XINPUT_Enabled()) {
urkle@6965
   254
        return SDL_FALSE;
urkle@6965
   255
    }
urkle@6965
   256
gabomdq@7663
   257
    /* Check for well known XInput device GUIDs */
icculus@7706
   258
    /* This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list. */
slouken@8920
   259
    for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) {
slouken@7299
   260
        if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
slouken@7299
   261
            return SDL_TRUE;
slouken@7299
   262
        }
slouken@7299
   263
    }
slouken@7299
   264
icculus@7706
   265
    /* Go through RAWINPUT (WinXP and later) to find HID devices. */
icculus@7706
   266
    /* Cache this if we end up using it. */
icculus@7706
   267
    if (SDL_RawDevList == NULL) {
slouken@8972
   268
        if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
icculus@7706
   269
            return SDL_FALSE;  /* oh well. */
icculus@7706
   270
        }
slouken@6690
   271
slouken@8972
   272
        SDL_RawDevList = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount);
icculus@7706
   273
        if (SDL_RawDevList == NULL) {
icculus@7706
   274
            SDL_OutOfMemory();
icculus@7706
   275
            return SDL_FALSE;
icculus@7706
   276
        }
slouken@6690
   277
slouken@8972
   278
        if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) {
slouken@8972
   279
            SDL_free(SDL_RawDevList);
slouken@8972
   280
            SDL_RawDevList = NULL;
slouken@8972
   281
            return SDL_FALSE;  /* oh well. */
slouken@7191
   282
        }
slouken@7191
   283
    }
slouken@7191
   284
icculus@7706
   285
    for (i = 0; i < SDL_RawDevListCount; i++) {
icculus@7706
   286
        RID_DEVICE_INFO rdi;
icculus@7706
   287
        char devName[128];
slouken@8972
   288
        UINT rdiSize = sizeof(rdi);
icculus@7706
   289
        UINT nameSize = SDL_arraysize(devName);
slouken@6690
   290
slouken@8972
   291
        rdi.cbSize = sizeof(rdi);
slouken@8920
   292
        if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
slouken@8972
   293
            (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
slouken@8972
   294
            (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
slouken@8972
   295
            (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
slouken@8972
   296
            (SDL_strstr(devName, "IG_") != NULL)) {
slouken@8972
   297
            return SDL_TRUE;
icculus@7706
   298
        }
icculus@7706
   299
    }
slouken@6690
   300
icculus@7706
   301
    return SDL_FALSE;
slouken@6690
   302
}
slouken@6690
   303
slouken@1895
   304
int
slouken@8972
   305
SDL_DINPUT_JoystickInit(void)
slouken@1895
   306
{
slouken@1895
   307
    HRESULT result;
slouken@2713
   308
    HINSTANCE instance;
slouken@1895
   309
icculus@5591
   310
    result = WIN_CoInitialize();
slouken@2198
   311
    if (FAILED(result)) {
icculus@7037
   312
        return SetDIerror("CoInitialize", result);
slouken@1895
   313
    }
slouken@1895
   314
icculus@5591
   315
    coinitialized = SDL_TRUE;
icculus@5591
   316
slouken@6690
   317
    result = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
slouken@8972
   318
        &IID_IDirectInput8, (LPVOID)&dinput);
slouken@2198
   319
slouken@2198
   320
    if (FAILED(result)) {
icculus@7037
   321
        return SetDIerror("CoCreateInstance", result);
slouken@2198
   322
    }
slouken@2198
   323
slouken@2198
   324
    /* Because we used CoCreateInstance, we need to Initialize it, first. */
slouken@2713
   325
    instance = GetModuleHandle(NULL);
slouken@2713
   326
    if (instance == NULL) {
slouken@8976
   327
        return SDL_SetError("GetModuleHandle() failed with error code %lu.", GetLastError());
slouken@2713
   328
    }
slouken@6690
   329
    result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
slouken@2198
   330
slouken@2198
   331
    if (FAILED(result)) {
icculus@7037
   332
        return SetDIerror("IDirectInput::Initialize", result);
slouken@2198
   333
    }
slouken@8972
   334
    return 0;
slouken@6707
   335
}
slouken@6707
   336
slouken@6707
   337
/* helper function for direct input, gets called for each connected joystick */
slouken@6707
   338
static BOOL CALLBACK
slouken@8920
   339
EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
slouken@6707
   340
{
slouken@7191
   341
    JoyStick_DeviceData *pNewJoystick;
slouken@7191
   342
    JoyStick_DeviceData *pPrevJoystick = NULL;
icculus@7707
   343
slouken@8920
   344
    if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) {
icculus@7707
   345
        return DIENUM_CONTINUE;  /* ignore XInput devices here, keep going. */
icculus@7707
   346
    }
icculus@7707
   347
slouken@7191
   348
    pNewJoystick = *(JoyStick_DeviceData **)pContext;
slouken@8920
   349
    while (pNewJoystick) {
slouken@8920
   350
        if (!SDL_memcmp(&pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance))) {
slouken@7191
   351
            /* if we are replacing the front of the list then update it */
slouken@8920
   352
            if (pNewJoystick == *(JoyStick_DeviceData **)pContext) {
slouken@7191
   353
                *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
slouken@8920
   354
            } else if (pPrevJoystick) {
slouken@7191
   355
                pPrevJoystick->pNext = pNewJoystick->pNext;
slouken@7191
   356
            }
slouken@6712
   357
slouken@7191
   358
            pNewJoystick->pNext = SYS_Joystick;
slouken@7191
   359
            SYS_Joystick = pNewJoystick;
slouken@6707
   360
icculus@7707
   361
            return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
slouken@7191
   362
        }
slouken@6707
   363
slouken@7191
   364
        pPrevJoystick = pNewJoystick;
slouken@7191
   365
        pNewJoystick = pNewJoystick->pNext;
slouken@7191
   366
    }
slouken@6707
   367
slouken@8920
   368
    pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData));
icculus@7707
   369
    if (!pNewJoystick) {
icculus@7707
   370
        return DIENUM_CONTINUE; /* better luck next time? */
icculus@7707
   371
    }
slouken@6707
   372
icculus@7707
   373
    SDL_zerop(pNewJoystick);
icculus@7707
   374
    pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
icculus@7707
   375
    if (!pNewJoystick->joystickname) {
icculus@7707
   376
        SDL_free(pNewJoystick);
icculus@7707
   377
        return DIENUM_CONTINUE; /* better luck next time? */
slouken@7191
   378
    }
slouken@6712
   379
slouken@7191
   380
    SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
slouken@7191
   381
        sizeof(DIDEVICEINSTANCE));
slouken@6707
   382
slouken@8920
   383
    SDL_memcpy(&pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid));
slouken@8972
   384
    SDL_SYS_AddJoystickDevice(pNewJoystick);
slouken@7191
   385
icculus@7707
   386
    return DIENUM_CONTINUE; /* get next device, please */
slouken@6707
   387
}
slouken@6707
   388
slouken@8972
   389
void
slouken@8972
   390
SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
icculus@7707
   391
{
slouken@8972
   392
    IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY);
slouken@8920
   393
slouken@8972
   394
    if (SDL_RawDevList) {
slouken@8972
   395
        SDL_free(SDL_RawDevList);  /* in case we used this in DirectInput detection */
slouken@8972
   396
        SDL_RawDevList = NULL;
slouken@8972
   397
    }
slouken@8972
   398
    SDL_RawDevListCount = 0;
slouken@8920
   399
}
slouken@8920
   400
slouken@8972
   401
static BOOL CALLBACK
slouken@8972
   402
EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
slouken@8920
   403
{
slouken@8972
   404
    SDL_Joystick *joystick = (SDL_Joystick *)pvRef;
slouken@8972
   405
    HRESULT result;
slouken@8972
   406
    input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
slouken@8920
   407
slouken@8972
   408
    if (dev->dwType & DIDFT_BUTTON) {
slouken@8972
   409
        in->type = BUTTON;
slouken@8972
   410
        in->num = joystick->nbuttons;
slouken@8972
   411
        in->ofs = DIJOFS_BUTTON(in->num);
slouken@8972
   412
        joystick->nbuttons++;
slouken@8972
   413
    } else if (dev->dwType & DIDFT_POV) {
slouken@8972
   414
        in->type = HAT;
slouken@8972
   415
        in->num = joystick->nhats;
slouken@8972
   416
        in->ofs = DIJOFS_POV(in->num);
slouken@8972
   417
        joystick->nhats++;
slouken@8972
   418
    } else if (dev->dwType & DIDFT_AXIS) {
slouken@8972
   419
        DIPROPRANGE diprg;
slouken@8972
   420
        DIPROPDWORD dilong;
slouken@8920
   421
slouken@8972
   422
        in->type = AXIS;
slouken@8972
   423
        in->num = joystick->naxes;
slouken@8972
   424
        if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType)))
slouken@8972
   425
            in->ofs = DIJOFS_X;
slouken@8972
   426
        else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType)))
slouken@8972
   427
            in->ofs = DIJOFS_Y;
slouken@8972
   428
        else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType)))
slouken@8972
   429
            in->ofs = DIJOFS_Z;
slouken@8972
   430
        else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType)))
slouken@8972
   431
            in->ofs = DIJOFS_RX;
slouken@8972
   432
        else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType)))
slouken@8972
   433
            in->ofs = DIJOFS_RY;
slouken@8972
   434
        else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType)))
slouken@8972
   435
            in->ofs = DIJOFS_RZ;
slouken@8972
   436
        else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) {
slouken@8972
   437
            in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders);
slouken@8972
   438
            ++joystick->hwdata->NumSliders;
slouken@8972
   439
        } else {
slouken@8972
   440
            return DIENUM_CONTINUE; /* not an axis we can grok */
icculus@7707
   441
        }
icculus@7707
   442
slouken@8972
   443
        diprg.diph.dwSize = sizeof(diprg);
slouken@8972
   444
        diprg.diph.dwHeaderSize = sizeof(diprg.diph);
slouken@8972
   445
        diprg.diph.dwObj = dev->dwType;
slouken@8972
   446
        diprg.diph.dwHow = DIPH_BYID;
slouken@8972
   447
        diprg.lMin = AXIS_MIN;
slouken@8972
   448
        diprg.lMax = AXIS_MAX;
slouken@8972
   449
slouken@8972
   450
        result =
slouken@8972
   451
            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
slouken@8972
   452
            DIPROP_RANGE, &diprg.diph);
slouken@8972
   453
        if (FAILED(result)) {
slouken@8972
   454
            return DIENUM_CONTINUE;     /* don't use this axis */
slouken@8972
   455
        }
slouken@8972
   456
slouken@8972
   457
        /* Set dead zone to 0. */
slouken@8972
   458
        dilong.diph.dwSize = sizeof(dilong);
slouken@8972
   459
        dilong.diph.dwHeaderSize = sizeof(dilong.diph);
slouken@8972
   460
        dilong.diph.dwObj = dev->dwType;
slouken@8972
   461
        dilong.diph.dwHow = DIPH_BYID;
slouken@8972
   462
        dilong.dwData = 0;
slouken@8972
   463
        result =
slouken@8972
   464
            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
slouken@8972
   465
            DIPROP_DEADZONE, &dilong.diph);
slouken@8972
   466
        if (FAILED(result)) {
slouken@8972
   467
            return DIENUM_CONTINUE;     /* don't use this axis */
slouken@8972
   468
        }
slouken@8972
   469
slouken@8972
   470
        joystick->naxes++;
slouken@8972
   471
    } else {
slouken@8972
   472
        /* not supported at this time */
slouken@8972
   473
        return DIENUM_CONTINUE;
icculus@7707
   474
    }
icculus@7707
   475
slouken@8972
   476
    joystick->hwdata->NumInputs++;
icculus@7707
   477
slouken@8972
   478
    if (joystick->hwdata->NumInputs == MAX_INPUTS) {
slouken@8972
   479
        return DIENUM_STOP;     /* too many */
icculus@7707
   480
    }
icculus@7707
   481
slouken@8972
   482
    return DIENUM_CONTINUE;
icculus@7707
   483
}
icculus@7707
   484
slouken@8972
   485
/* Sort using the data offset into the DInput struct.
slouken@8972
   486
 * This gives a reasonable ordering for the inputs.
slouken@1895
   487
 */
slouken@6220
   488
static int
slouken@6220
   489
SortDevFunc(const void *a, const void *b)
slouken@6220
   490
{
slouken@7191
   491
    const input_t *inputA = (const input_t*)a;
slouken@7191
   492
    const input_t *inputB = (const input_t*)b;
slouken@6220
   493
slouken@7191
   494
    if (inputA->ofs < inputB->ofs)
slouken@7191
   495
        return -1;
slouken@7191
   496
    if (inputA->ofs > inputB->ofs)
slouken@7191
   497
        return 1;
slouken@7191
   498
    return 0;
slouken@6220
   499
}
slouken@6220
   500
slouken@6220
   501
/* Sort the input objects and recalculate the indices for each input. */
slouken@6220
   502
static void
slouken@6220
   503
SortDevObjects(SDL_Joystick *joystick)
slouken@6220
   504
{
slouken@7191
   505
    input_t *inputs = joystick->hwdata->Inputs;
slouken@7191
   506
    int nButtons = 0;
slouken@7191
   507
    int nHats = 0;
slouken@7191
   508
    int nAxis = 0;
slouken@7191
   509
    int n;
slouken@6220
   510
slouken@7191
   511
    SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc);
slouken@6220
   512
slouken@8920
   513
    for (n = 0; n < joystick->hwdata->NumInputs; n++) {
slouken@8920
   514
        switch (inputs[n].type) {
slouken@7191
   515
        case BUTTON:
slouken@7191
   516
            inputs[n].num = nButtons;
slouken@7191
   517
            nButtons++;
slouken@7191
   518
            break;
slouken@6220
   519
slouken@7191
   520
        case HAT:
slouken@7191
   521
            inputs[n].num = nHats;
slouken@7191
   522
            nHats++;
slouken@7191
   523
            break;
slouken@6220
   524
slouken@7191
   525
        case AXIS:
slouken@7191
   526
            inputs[n].num = nAxis;
slouken@7191
   527
            nAxis++;
slouken@7191
   528
            break;
slouken@7191
   529
        }
slouken@7191
   530
    }
slouken@6220
   531
}
slouken@6220
   532
slouken@8972
   533
int
slouken@8972
   534
SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
slouken@2198
   535
{
slouken@2198
   536
    HRESULT result;
slouken@8972
   537
    LPDIRECTINPUTDEVICE8 device;
slouken@8972
   538
    DIPROPDWORD dipdw;
slouken@2198
   539
slouken@8972
   540
    joystick->hwdata->buffered = SDL_TRUE;
slouken@8972
   541
    joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
slouken@2198
   542
slouken@8972
   543
    SDL_zero(dipdw);
slouken@8972
   544
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
slouken@8972
   545
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
slouken@8972
   546
slouken@8972
   547
    result =
slouken@8972
   548
        IDirectInput8_CreateDevice(dinput,
slouken@8972
   549
        &(joystickdevice->dxdevice.guidInstance), &device, NULL);
slouken@8972
   550
    if (FAILED(result)) {
slouken@8972
   551
        return SetDIerror("IDirectInput::CreateDevice", result);
slouken@8972
   552
    }
slouken@8972
   553
slouken@8972
   554
    /* Now get the IDirectInputDevice8 interface, instead. */
slouken@8972
   555
    result = IDirectInputDevice8_QueryInterface(device,
slouken@8972
   556
        &IID_IDirectInputDevice8,
slouken@8972
   557
        (LPVOID *)& joystick->
slouken@8972
   558
        hwdata->InputDevice);
slouken@8972
   559
    /* We are done with this object.  Use the stored one from now on. */
slouken@8972
   560
    IDirectInputDevice8_Release(device);
slouken@8972
   561
slouken@8972
   562
    if (FAILED(result)) {
slouken@8972
   563
        return SetDIerror("IDirectInputDevice8::QueryInterface", result);
slouken@8972
   564
    }
slouken@8972
   565
slouken@8972
   566
    /* Acquire shared access. Exclusive access is required for forces,
slouken@8972
   567
    * though. */
slouken@8972
   568
    result =
slouken@8972
   569
        IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata->
slouken@8972
   570
        InputDevice, SDL_HelperWindow,
slouken@8972
   571
        DISCL_EXCLUSIVE |
slouken@8972
   572
        DISCL_BACKGROUND);
slouken@8972
   573
    if (FAILED(result)) {
slouken@8972
   574
        return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result);
slouken@8972
   575
    }
slouken@8972
   576
slouken@8972
   577
    /* Use the extended data structure: DIJOYSTATE2. */
slouken@8972
   578
    result =
slouken@8972
   579
        IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice,
slouken@8972
   580
        &c_dfDIJoystick2);
slouken@8972
   581
    if (FAILED(result)) {
slouken@8972
   582
        return SetDIerror("IDirectInputDevice8::SetDataFormat", result);
slouken@8972
   583
    }
slouken@8972
   584
slouken@8972
   585
    /* Get device capabilities */
slouken@8972
   586
    result =
slouken@8972
   587
        IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice,
slouken@8972
   588
        &joystick->hwdata->Capabilities);
slouken@8972
   589
    if (FAILED(result)) {
slouken@8972
   590
        return SetDIerror("IDirectInputDevice8::GetCapabilities", result);
slouken@8972
   591
    }
slouken@8972
   592
slouken@8972
   593
    /* Force capable? */
slouken@8972
   594
    if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
slouken@8972
   595
slouken@8972
   596
        result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
slouken@8972
   597
        if (FAILED(result)) {
slouken@8972
   598
            return SetDIerror("IDirectInputDevice8::Acquire", result);
slouken@7191
   599
        }
slouken@2198
   600
slouken@8972
   601
        /* reset all actuators. */
slouken@8972
   602
        result =
slouken@8972
   603
            IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->
slouken@8972
   604
            InputDevice,
slouken@8972
   605
            DISFFC_RESET);
slouken@8972
   606
slouken@8972
   607
        /* Not necessarily supported, ignore if not supported.
slouken@8972
   608
        if (FAILED(result)) {
slouken@8972
   609
        return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result);
slouken@8972
   610
        }
slouken@8972
   611
        */
slouken@8972
   612
slouken@8972
   613
        result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
slouken@8972
   614
slouken@8972
   615
        if (FAILED(result)) {
slouken@8972
   616
            return SetDIerror("IDirectInputDevice8::Unacquire", result);
slouken@8972
   617
        }
slouken@8972
   618
slouken@8972
   619
        /* Turn on auto-centering for a ForceFeedback device (until told
slouken@8972
   620
        * otherwise). */
slouken@8972
   621
        dipdw.diph.dwObj = 0;
slouken@8972
   622
        dipdw.diph.dwHow = DIPH_DEVICE;
slouken@8972
   623
        dipdw.dwData = DIPROPAUTOCENTER_ON;
slouken@2198
   624
slouken@2198
   625
        result =
slouken@6690
   626
            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
slouken@8972
   627
            DIPROP_AUTOCENTER, &dipdw.diph);
slouken@8972
   628
slouken@8972
   629
        /* Not necessarily supported, ignore if not supported.
slouken@2198
   630
        if (FAILED(result)) {
slouken@8972
   631
        return SetDIerror("IDirectInputDevice8::SetProperty", result);
slouken@2198
   632
        }
slouken@8972
   633
        */
slouken@2198
   634
    }
slouken@2198
   635
slouken@8972
   636
    /* What buttons and axes does it have? */
slouken@8972
   637
    IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice,
slouken@8972
   638
        EnumDevObjectsCallback, joystick,
slouken@8972
   639
        DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
slouken@2198
   640
slouken@8972
   641
    /* Reorder the input objects. Some devices do not report the X axis as
slouken@8972
   642
    * the first axis, for example. */
slouken@8972
   643
    SortDevObjects(joystick);
slouken@8972
   644
slouken@8972
   645
    dipdw.diph.dwObj = 0;
slouken@8972
   646
    dipdw.diph.dwHow = DIPH_DEVICE;
slouken@8972
   647
    dipdw.dwData = INPUT_QSIZE;
slouken@8972
   648
slouken@8972
   649
    /* Set the buffer size */
slouken@8972
   650
    result =
slouken@8972
   651
        IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
slouken@8972
   652
        DIPROP_BUFFERSIZE, &dipdw.diph);
slouken@8972
   653
slouken@8972
   654
    if (result == DI_POLLEDDEVICE) {
slouken@8972
   655
        /* This device doesn't support buffering, so we're forced
slouken@8972
   656
         * to use less reliable polling. */
slouken@8972
   657
        joystick->hwdata->buffered = SDL_FALSE;
slouken@8972
   658
    } else if (FAILED(result)) {
slouken@8972
   659
        return SetDIerror("IDirectInputDevice8::SetProperty", result);
slouken@2198
   660
    }
slouken@8972
   661
    return 0;
slouken@6690
   662
}
slouken@6690
   663
slouken@1895
   664
static Uint8
slouken@1895
   665
TranslatePOV(DWORD value)
slouken@1895
   666
{
slouken@1895
   667
    const int HAT_VALS[] = {
slouken@1895
   668
        SDL_HAT_UP,
slouken@1895
   669
        SDL_HAT_UP | SDL_HAT_RIGHT,
slouken@1895
   670
        SDL_HAT_RIGHT,
slouken@1895
   671
        SDL_HAT_DOWN | SDL_HAT_RIGHT,
slouken@1895
   672
        SDL_HAT_DOWN,
slouken@1895
   673
        SDL_HAT_DOWN | SDL_HAT_LEFT,
slouken@1895
   674
        SDL_HAT_LEFT,
slouken@1895
   675
        SDL_HAT_UP | SDL_HAT_LEFT
slouken@1895
   676
    };
slouken@1895
   677
slouken@1895
   678
    if (LOWORD(value) == 0xFFFF)
slouken@1895
   679
        return SDL_HAT_CENTERED;
slouken@1895
   680
slouken@1895
   681
    /* Round the value up: */
slouken@1895
   682
    value += 4500 / 2;
slouken@1895
   683
    value %= 36000;
slouken@1895
   684
    value /= 4500;
slouken@1895
   685
slouken@1895
   686
    if (value >= 8)
slouken@1895
   687
        return SDL_HAT_CENTERED;        /* shouldn't happen */
slouken@1895
   688
slouken@1895
   689
    return HAT_VALS[value];
slouken@1895
   690
}
slouken@1895
   691
slouken@8972
   692
static void
slouken@8972
   693
UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick)
slouken@8972
   694
{
slouken@8972
   695
    int i;
slouken@8972
   696
    HRESULT result;
slouken@8972
   697
    DWORD numevents;
slouken@8972
   698
    DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
slouken@8972
   699
slouken@8972
   700
    numevents = INPUT_QSIZE;
slouken@8972
   701
    result =
slouken@8972
   702
        IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
slouken@8972
   703
        sizeof(DIDEVICEOBJECTDATA), evtbuf,
slouken@8972
   704
        &numevents, 0);
slouken@8972
   705
    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
slouken@8972
   706
        IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
slouken@8972
   707
        result =
slouken@8972
   708
            IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
slouken@8972
   709
            sizeof(DIDEVICEOBJECTDATA),
slouken@8972
   710
            evtbuf, &numevents, 0);
slouken@8972
   711
    }
slouken@8972
   712
slouken@8972
   713
    /* Handle the events or punt */
slouken@8972
   714
    if (FAILED(result)) {
slouken@8972
   715
        joystick->hwdata->send_remove_event = SDL_TRUE;
slouken@8972
   716
        joystick->hwdata->removed = SDL_TRUE;
slouken@8972
   717
        return;
slouken@8972
   718
    }
slouken@8972
   719
slouken@8972
   720
    for (i = 0; i < (int)numevents; ++i) {
slouken@8972
   721
        int j;
slouken@8972
   722
slouken@8972
   723
        for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
slouken@8972
   724
            const input_t *in = &joystick->hwdata->Inputs[j];
slouken@8972
   725
slouken@8972
   726
            if (evtbuf[i].dwOfs != in->ofs)
slouken@8972
   727
                continue;
slouken@8972
   728
slouken@8972
   729
            switch (in->type) {
slouken@8972
   730
            case AXIS:
slouken@8972
   731
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData);
slouken@8972
   732
                break;
slouken@8972
   733
            case BUTTON:
slouken@8972
   734
                SDL_PrivateJoystickButton(joystick, in->num,
slouken@8972
   735
                    (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED));
slouken@8972
   736
                break;
slouken@8972
   737
            case HAT:
slouken@8972
   738
                {
slouken@8972
   739
                    Uint8 pos = TranslatePOV(evtbuf[i].dwData);
slouken@8972
   740
                    SDL_PrivateJoystickHat(joystick, in->num, pos);
slouken@8972
   741
                }
slouken@8972
   742
                break;
slouken@8972
   743
            }
slouken@8972
   744
        }
slouken@8972
   745
    }
slouken@8972
   746
}
slouken@8972
   747
slouken@8972
   748
/* Function to update the state of a joystick - called as a device poll.
slouken@8972
   749
 * This function shouldn't update the joystick structure directly,
slouken@8972
   750
 * but instead should call SDL_PrivateJoystick*() to deliver events
slouken@8972
   751
 * and update joystick device state.
slouken@8972
   752
 */
slouken@8972
   753
static void
slouken@8972
   754
UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick)
slouken@8972
   755
{
slouken@8972
   756
    DIJOYSTATE2 state;
slouken@8972
   757
    HRESULT result;
slouken@8972
   758
    int i;
slouken@8972
   759
slouken@8972
   760
    result =
slouken@8972
   761
        IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
slouken@8972
   762
        sizeof(DIJOYSTATE2), &state);
slouken@8972
   763
    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
slouken@8972
   764
        IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
slouken@8972
   765
        result =
slouken@8972
   766
            IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
slouken@8972
   767
            sizeof(DIJOYSTATE2), &state);
slouken@8972
   768
    }
slouken@8972
   769
slouken@8972
   770
    if (result != DI_OK) {
slouken@8972
   771
        joystick->hwdata->send_remove_event = SDL_TRUE;
slouken@8972
   772
        joystick->hwdata->removed = SDL_TRUE;
slouken@8972
   773
        return;
slouken@8972
   774
    }
slouken@8972
   775
slouken@8972
   776
    /* Set each known axis, button and POV. */
slouken@8972
   777
    for (i = 0; i < joystick->hwdata->NumInputs; ++i) {
slouken@8972
   778
        const input_t *in = &joystick->hwdata->Inputs[i];
slouken@8972
   779
slouken@8972
   780
        switch (in->type) {
slouken@8972
   781
        case AXIS:
slouken@8972
   782
            switch (in->ofs) {
slouken@8972
   783
            case DIJOFS_X:
slouken@8972
   784
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lX);
slouken@8972
   785
                break;
slouken@8972
   786
            case DIJOFS_Y:
slouken@8972
   787
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lY);
slouken@8972
   788
                break;
slouken@8972
   789
            case DIJOFS_Z:
slouken@8972
   790
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lZ);
slouken@8972
   791
                break;
slouken@8972
   792
            case DIJOFS_RX:
slouken@8972
   793
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRx);
slouken@8972
   794
                break;
slouken@8972
   795
            case DIJOFS_RY:
slouken@8972
   796
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRy);
slouken@8972
   797
                break;
slouken@8972
   798
            case DIJOFS_RZ:
slouken@8972
   799
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRz);
slouken@8972
   800
                break;
slouken@8972
   801
            case DIJOFS_SLIDER(0):
slouken@8972
   802
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[0]);
slouken@8972
   803
                break;
slouken@8972
   804
            case DIJOFS_SLIDER(1):
slouken@8972
   805
                SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[1]);
slouken@8972
   806
                break;
slouken@8972
   807
            }
slouken@8972
   808
            break;
slouken@8972
   809
slouken@8972
   810
        case BUTTON:
slouken@8972
   811
            SDL_PrivateJoystickButton(joystick, in->num,
slouken@8972
   812
                (Uint8)(state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED));
slouken@8972
   813
            break;
slouken@8972
   814
        case HAT:
slouken@8972
   815
        {
slouken@8972
   816
            Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]);
slouken@8972
   817
            SDL_PrivateJoystickHat(joystick, in->num, pos);
slouken@8972
   818
            break;
slouken@8972
   819
        }
slouken@8972
   820
        }
slouken@8972
   821
    }
slouken@8972
   822
}
slouken@8972
   823
slouken@1895
   824
void
slouken@8972
   825
SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
slouken@1895
   826
{
slouken@1895
   827
    HRESULT result;
slouken@1895
   828
slouken@8972
   829
    result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
slouken@8972
   830
    if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
slouken@8972
   831
        IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
slouken@8972
   832
        IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
slouken@7191
   833
    }
slouken@6690
   834
slouken@8972
   835
    if (joystick->hwdata->buffered) {
slouken@8972
   836
        UpdateDINPUTJoystickState_Buffered(joystick);
slouken@8972
   837
    } else {
slouken@8972
   838
        UpdateDINPUTJoystickState_Polled(joystick);
slouken@7191
   839
    }
slouken@1895
   840
}
slouken@1895
   841
slouken@1895
   842
void
slouken@8972
   843
SDL_DINPUT_JoystickClose(SDL_Joystick * joystick)
slouken@1895
   844
{
slouken@8972
   845
    IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
slouken@8972
   846
    IDirectInputDevice8_Release(joystick->hwdata->InputDevice);
slouken@1895
   847
}
slouken@1895
   848
slouken@1895
   849
void
slouken@8972
   850
SDL_DINPUT_JoystickQuit(void)
slouken@1895
   851
{
icculus@5591
   852
    if (dinput != NULL) {
slouken@6690
   853
        IDirectInput8_Release(dinput);
icculus@5591
   854
        dinput = NULL;
icculus@5591
   855
    }
icculus@5591
   856
icculus@5591
   857
    if (coinitialized) {
icculus@5591
   858
        WIN_CoUninitialize();
icculus@5591
   859
        coinitialized = SDL_FALSE;
icculus@5591
   860
    }
slouken@6690
   861
}
slouken@6690
   862
slouken@8972
   863
#else /* !SDL_JOYSTICK_DINPUT */
slouken@8972
   864
slouken@8972
   865
slouken@8972
   866
int
slouken@8972
   867
SDL_DINPUT_JoystickInit(void)
slouken@6690
   868
{
slouken@8972
   869
    return 0;
slouken@6690
   870
}
slouken@6690
   871
slouken@8972
   872
void
slouken@8972
   873
SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
slouken@6707
   874
{
slouken@6707
   875
}
slouken@6707
   876
slouken@8972
   877
int
slouken@8972
   878
SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
slouken@6690
   879
{
slouken@8972
   880
    return SDL_Unsupported();
slouken@8972
   881
}
slouken@6690
   882
slouken@8972
   883
void
slouken@8972
   884
SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
slouken@8972
   885
{
slouken@8972
   886
}
slouken@6690
   887
slouken@8972
   888
void
slouken@8972
   889
SDL_DINPUT_JoystickClose(SDL_Joystick * joystick)
slouken@8972
   890
{
slouken@8972
   891
}
slouken@8972
   892
slouken@8972
   893
void
slouken@8972
   894
SDL_DINPUT_JoystickQuit(void)
slouken@8972
   895
{
slouken@7685
   896
}
slouken@7685
   897
slouken@1895
   898
#endif /* SDL_JOYSTICK_DINPUT */
slouken@3575
   899
slouken@1895
   900
/* vi: set ts=4 sw=4 expandtab: */