SDL  2.0
SDL_dinputjoystick.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #include "../SDL_sysjoystick.h"
24 
25 #if SDL_JOYSTICK_DINPUT
26 
27 #include "SDL_windowsjoystick_c.h"
28 #include "SDL_dinputjoystick_c.h"
29 #include "SDL_xinputjoystick_c.h"
30 #include "../hidapi/SDL_hidapijoystick_c.h"
31 
32 #ifndef DIDFT_OPTIONAL
33 #define DIDFT_OPTIONAL 0x80000000
34 #endif
35 
36 #define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
37 #define JOY_AXIS_THRESHOLD (((SDL_JOYSTICK_AXIS_MAX)-(SDL_JOYSTICK_AXIS_MIN))/100) /* 1% motion */
38 
39 #define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF)
40 
41 /* external variables referenced. */
42 extern HWND SDL_HelperWindow;
43 
44 /* local variables */
45 static SDL_bool coinitialized = SDL_FALSE;
46 static LPDIRECTINPUT8 dinput = NULL;
47 static PRAWINPUTDEVICELIST SDL_RawDevList = NULL;
48 static UINT SDL_RawDevListCount = 0;
49 
50 /* Taken from Wine - Thanks! */
51 static DIOBJECTDATAFORMAT dfDIJoystick2[] = {
52  { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
53  { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
54  { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
55  { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
56  { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
57  { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
58  { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
59  { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
60  { &GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
61  { &GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
62  { &GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
63  { &GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
64  { NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
65  { NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
66  { NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
67  { NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
68  { NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
69  { NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
70  { NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
71  { NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
72  { NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
73  { NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
74  { NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
75  { NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
76  { NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
77  { NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
78  { NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
79  { NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
80  { NULL, DIJOFS_BUTTON(16), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
81  { NULL, DIJOFS_BUTTON(17), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
82  { NULL, DIJOFS_BUTTON(18), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
83  { NULL, DIJOFS_BUTTON(19), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
84  { NULL, DIJOFS_BUTTON(20), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
85  { NULL, DIJOFS_BUTTON(21), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
86  { NULL, DIJOFS_BUTTON(22), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
87  { NULL, DIJOFS_BUTTON(23), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
88  { NULL, DIJOFS_BUTTON(24), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
89  { NULL, DIJOFS_BUTTON(25), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
90  { NULL, DIJOFS_BUTTON(26), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
91  { NULL, DIJOFS_BUTTON(27), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
92  { NULL, DIJOFS_BUTTON(28), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
93  { NULL, DIJOFS_BUTTON(29), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
94  { NULL, DIJOFS_BUTTON(30), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
95  { NULL, DIJOFS_BUTTON(31), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
96  { NULL, DIJOFS_BUTTON(32), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
97  { NULL, DIJOFS_BUTTON(33), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
98  { NULL, DIJOFS_BUTTON(34), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
99  { NULL, DIJOFS_BUTTON(35), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
100  { NULL, DIJOFS_BUTTON(36), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
101  { NULL, DIJOFS_BUTTON(37), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
102  { NULL, DIJOFS_BUTTON(38), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
103  { NULL, DIJOFS_BUTTON(39), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
104  { NULL, DIJOFS_BUTTON(40), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
105  { NULL, DIJOFS_BUTTON(41), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
106  { NULL, DIJOFS_BUTTON(42), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
107  { NULL, DIJOFS_BUTTON(43), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
108  { NULL, DIJOFS_BUTTON(44), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
109  { NULL, DIJOFS_BUTTON(45), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
110  { NULL, DIJOFS_BUTTON(46), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
111  { NULL, DIJOFS_BUTTON(47), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
112  { NULL, DIJOFS_BUTTON(48), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
113  { NULL, DIJOFS_BUTTON(49), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
114  { NULL, DIJOFS_BUTTON(50), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
115  { NULL, DIJOFS_BUTTON(51), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
116  { NULL, DIJOFS_BUTTON(52), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
117  { NULL, DIJOFS_BUTTON(53), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
118  { NULL, DIJOFS_BUTTON(54), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
119  { NULL, DIJOFS_BUTTON(55), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
120  { NULL, DIJOFS_BUTTON(56), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
121  { NULL, DIJOFS_BUTTON(57), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
122  { NULL, DIJOFS_BUTTON(58), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
123  { NULL, DIJOFS_BUTTON(59), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
124  { NULL, DIJOFS_BUTTON(60), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
125  { NULL, DIJOFS_BUTTON(61), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
126  { NULL, DIJOFS_BUTTON(62), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
127  { NULL, DIJOFS_BUTTON(63), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
128  { NULL, DIJOFS_BUTTON(64), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
129  { NULL, DIJOFS_BUTTON(65), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
130  { NULL, DIJOFS_BUTTON(66), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
131  { NULL, DIJOFS_BUTTON(67), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
132  { NULL, DIJOFS_BUTTON(68), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
133  { NULL, DIJOFS_BUTTON(69), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
134  { NULL, DIJOFS_BUTTON(70), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
135  { NULL, DIJOFS_BUTTON(71), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
136  { NULL, DIJOFS_BUTTON(72), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
137  { NULL, DIJOFS_BUTTON(73), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
138  { NULL, DIJOFS_BUTTON(74), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
139  { NULL, DIJOFS_BUTTON(75), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
140  { NULL, DIJOFS_BUTTON(76), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
141  { NULL, DIJOFS_BUTTON(77), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
142  { NULL, DIJOFS_BUTTON(78), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
143  { NULL, DIJOFS_BUTTON(79), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
144  { NULL, DIJOFS_BUTTON(80), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
145  { NULL, DIJOFS_BUTTON(81), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
146  { NULL, DIJOFS_BUTTON(82), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
147  { NULL, DIJOFS_BUTTON(83), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
148  { NULL, DIJOFS_BUTTON(84), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
149  { NULL, DIJOFS_BUTTON(85), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
150  { NULL, DIJOFS_BUTTON(86), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
151  { NULL, DIJOFS_BUTTON(87), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
152  { NULL, DIJOFS_BUTTON(88), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
153  { NULL, DIJOFS_BUTTON(89), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
154  { NULL, DIJOFS_BUTTON(90), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
155  { NULL, DIJOFS_BUTTON(91), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
156  { NULL, DIJOFS_BUTTON(92), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
157  { NULL, DIJOFS_BUTTON(93), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
158  { NULL, DIJOFS_BUTTON(94), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
159  { NULL, DIJOFS_BUTTON(95), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
160  { NULL, DIJOFS_BUTTON(96), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
161  { NULL, DIJOFS_BUTTON(97), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
162  { NULL, DIJOFS_BUTTON(98), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
163  { NULL, DIJOFS_BUTTON(99), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
164  { NULL, DIJOFS_BUTTON(100), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
165  { NULL, DIJOFS_BUTTON(101), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
166  { NULL, DIJOFS_BUTTON(102), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
167  { NULL, DIJOFS_BUTTON(103), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
168  { NULL, DIJOFS_BUTTON(104), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
169  { NULL, DIJOFS_BUTTON(105), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
170  { NULL, DIJOFS_BUTTON(106), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
171  { NULL, DIJOFS_BUTTON(107), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
172  { NULL, DIJOFS_BUTTON(108), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
173  { NULL, DIJOFS_BUTTON(109), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
174  { NULL, DIJOFS_BUTTON(110), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
175  { NULL, DIJOFS_BUTTON(111), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
176  { NULL, DIJOFS_BUTTON(112), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
177  { NULL, DIJOFS_BUTTON(113), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
178  { NULL, DIJOFS_BUTTON(114), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
179  { NULL, DIJOFS_BUTTON(115), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
180  { NULL, DIJOFS_BUTTON(116), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
181  { NULL, DIJOFS_BUTTON(117), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
182  { NULL, DIJOFS_BUTTON(118), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
183  { NULL, DIJOFS_BUTTON(119), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
184  { NULL, DIJOFS_BUTTON(120), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
185  { NULL, DIJOFS_BUTTON(121), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
186  { NULL, DIJOFS_BUTTON(122), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
187  { NULL, DIJOFS_BUTTON(123), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
188  { NULL, DIJOFS_BUTTON(124), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
189  { NULL, DIJOFS_BUTTON(125), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
190  { NULL, DIJOFS_BUTTON(126), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
191  { NULL, DIJOFS_BUTTON(127), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
192  { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
193  { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
194  { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
195  { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
196  { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
197  { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
198  { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
199  { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
200  { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
201  { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
202  { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
203  { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
204  { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
205  { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
206  { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
207  { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
208  { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
209  { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
210  { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
211  { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
212  { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
213  { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
214  { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
215  { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
216 };
217 
218 const DIDATAFORMAT SDL_c_dfDIJoystick2 = {
219  sizeof(DIDATAFORMAT),
220  sizeof(DIOBJECTDATAFORMAT),
221  DIDF_ABSAXIS,
222  sizeof(DIJOYSTATE2),
223  SDL_arraysize(dfDIJoystick2),
224  dfDIJoystick2
225 };
226 
227 /* Convert a DirectInput return code to a text message */
228 static int
229 SetDIerror(const char *function, HRESULT code)
230 {
231  /*
232  return SDL_SetError("%s() [%s]: %s", function,
233  DXGetErrorString9A(code), DXGetErrorDescription9A(code));
234  */
235  return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code);
236 }
237 
238 static SDL_bool
239 SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
240 {
241  static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
242  static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
243  static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
244  static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
245  static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
246  static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
247  static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
248  static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
249  static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
250 
251  static const GUID *s_XInputProductGUID[] = {
252  &IID_ValveStreamingGamepad,
253  &IID_X360WiredGamepad, /* Microsoft's wired X360 controller for Windows. */
254  &IID_X360WirelessGamepad, /* Microsoft's wireless X360 controller for Windows. */
255  &IID_XOneWiredGamepad, /* Microsoft's wired Xbox One controller for Windows. */
256  &IID_XOneWirelessGamepad, /* Microsoft's wireless Xbox One controller for Windows. */
257  &IID_XOneNewWirelessGamepad, /* Microsoft's updated wireless Xbox One controller (w/ 3.5 mm jack) for Windows. */
258  &IID_XOneSWirelessGamepad, /* Microsoft's wireless Xbox One S controller for Windows. */
259  &IID_XOneSBluetoothGamepad, /* Microsoft's Bluetooth Xbox One S controller for Windows. */
260  &IID_XOneEliteWirelessGamepad /* Microsoft's wireless Xbox One Elite controller for Windows. */
261  };
262 
263  size_t iDevice;
264  UINT i;
265 
266  if (!SDL_XINPUT_Enabled()) {
267  return SDL_FALSE;
268  }
269 
270  /* Check for well known XInput device GUIDs */
271  /* 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. */
272  for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) {
273  if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
274  return SDL_TRUE;
275  }
276  }
277 
278  /* Go through RAWINPUT (WinXP and later) to find HID devices. */
279  /* Cache this if we end up using it. */
280  if (SDL_RawDevList == NULL) {
281  if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
282  return SDL_FALSE; /* oh well. */
283  }
284 
285  SDL_RawDevList = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount);
286  if (SDL_RawDevList == NULL) {
287  SDL_OutOfMemory();
288  return SDL_FALSE;
289  }
290 
291  if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) {
292  SDL_free(SDL_RawDevList);
293  SDL_RawDevList = NULL;
294  return SDL_FALSE; /* oh well. */
295  }
296  }
297 
298  for (i = 0; i < SDL_RawDevListCount; i++) {
299  RID_DEVICE_INFO rdi;
300  char devName[128];
301  UINT rdiSize = sizeof(rdi);
302  UINT nameSize = SDL_arraysize(devName);
303 
304  rdi.cbSize = sizeof(rdi);
305  if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
306  (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
307  (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
308  (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
309  (SDL_strstr(devName, "IG_") != NULL)) {
310  return SDL_TRUE;
311  }
312  }
313 
314  return SDL_FALSE;
315 }
316 
317 void FreeRumbleEffectData(DIEFFECT *effect)
318 {
319  if (!effect) {
320  return;
321  }
322  SDL_free(effect->rgdwAxes);
323  SDL_free(effect->rglDirection);
324  SDL_free(effect->lpvTypeSpecificParams);
325  SDL_free(effect);
326 }
327 
328 DIEFFECT *CreateRumbleEffectData(Sint16 magnitude, Uint32 duration_ms)
329 {
330  DIEFFECT *effect;
331  DIPERIODIC *periodic;
332 
333  /* Create the effect */
334  effect = (DIEFFECT *)SDL_calloc(1, sizeof(*effect));
335  if (!effect) {
336  return NULL;
337  }
338  effect->dwSize = sizeof(*effect);
339  effect->dwGain = 10000;
340  effect->dwFlags = DIEFF_OBJECTOFFSETS;
341  effect->dwDuration = duration_ms * 1000; /* In microseconds. */
342  effect->dwTriggerButton = DIEB_NOTRIGGER;
343 
344  effect->cAxes = 2;
345  effect->rgdwAxes = (DWORD *)SDL_calloc(effect->cAxes, sizeof(DWORD));
346  if (!effect->rgdwAxes) {
347  FreeRumbleEffectData(effect);
348  return NULL;
349  }
350 
351  effect->rglDirection = (LONG *)SDL_calloc(effect->cAxes, sizeof(LONG));
352  if (!effect->rglDirection) {
353  FreeRumbleEffectData(effect);
354  return NULL;
355  }
356  effect->dwFlags |= DIEFF_CARTESIAN;
357 
358  periodic = (DIPERIODIC *)SDL_calloc(1, sizeof(*periodic));
359  if (!periodic) {
360  FreeRumbleEffectData(effect);
361  return NULL;
362  }
363  periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude);
364  periodic->dwPeriod = 1000000;
365 
366  effect->cbTypeSpecificParams = sizeof(*periodic);
367  effect->lpvTypeSpecificParams = periodic;
368 
369  return effect;
370 }
371 
372 int
374 {
375  HRESULT result;
376  HINSTANCE instance;
377 
378  result = WIN_CoInitialize();
379  if (FAILED(result)) {
380  return SetDIerror("CoInitialize", result);
381  }
382 
383  coinitialized = SDL_TRUE;
384 
385  result = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
386  &IID_IDirectInput8, (LPVOID)&dinput);
387 
388  if (FAILED(result)) {
389  return SetDIerror("CoCreateInstance", result);
390  }
391 
392  /* Because we used CoCreateInstance, we need to Initialize it, first. */
393  instance = GetModuleHandle(NULL);
394  if (instance == NULL) {
395  return SDL_SetError("GetModuleHandle() failed with error code %lu.", GetLastError());
396  }
397  result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
398 
399  if (FAILED(result)) {
400  return SetDIerror("IDirectInput::Initialize", result);
401  }
402  return 0;
403 }
404 
405 /* helper function for direct input, gets called for each connected joystick */
406 static BOOL CALLBACK
407 EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
408 {
409  JoyStick_DeviceData *pNewJoystick;
410  JoyStick_DeviceData *pPrevJoystick = NULL;
411  const DWORD devtype = (pdidInstance->dwDevType & 0xFF);
412  Uint16 *guid16;
413  Uint16 vendor = 0;
414  Uint16 product = 0;
415  Uint16 version = 0;
416  WCHAR hidPath[MAX_PATH];
417 
418  if (devtype == DI8DEVTYPE_SUPPLEMENTAL) {
419  /* Add any supplemental devices that should be ignored here */
420 #define MAKE_TABLE_ENTRY(VID, PID) ((((DWORD)PID)<<16)|VID)
421  static DWORD ignored_devices[] = {
422  MAKE_TABLE_ENTRY(0, 0)
423  };
424 #undef MAKE_TABLE_ENTRY
425  unsigned int i;
426 
427  for (i = 0; i < SDL_arraysize(ignored_devices); ++i) {
428  if (pdidInstance->guidProduct.Data1 == ignored_devices[i]) {
429  return DIENUM_CONTINUE;
430  }
431  }
432  }
433 
434  if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) {
435  return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */
436  }
437 
438  {
439  HRESULT result;
440  LPDIRECTINPUTDEVICE8 device;
441  LPDIRECTINPUTDEVICE8 InputDevice;
442  DIPROPGUIDANDPATH dipdw2;
443 
444  result = IDirectInput8_CreateDevice(dinput, &(pdidInstance->guidInstance), &device, NULL);
445  if (FAILED(result)) {
446  return DIENUM_CONTINUE; /* better luck next time? */
447  }
448 
449  /* Now get the IDirectInputDevice8 interface, instead. */
450  result = IDirectInputDevice8_QueryInterface(device, &IID_IDirectInputDevice8, (LPVOID *)&InputDevice);
451  /* We are done with this object. Use the stored one from now on. */
452  IDirectInputDevice8_Release(device);
453  if (FAILED(result)) {
454  return DIENUM_CONTINUE; /* better luck next time? */
455  }
456  dipdw2.diph.dwSize = sizeof(dipdw2);
457  dipdw2.diph.dwHeaderSize = sizeof(dipdw2.diph);
458  dipdw2.diph.dwObj = 0; // device property
459  dipdw2.diph.dwHow = DIPH_DEVICE;
460 
461  result = IDirectInputDevice8_GetProperty(InputDevice, DIPROP_GUIDANDPATH, &dipdw2.diph);
462  IDirectInputDevice8_Release(InputDevice);
463  if (FAILED(result)) {
464  return DIENUM_CONTINUE; /* better luck next time? */
465  }
466 
467  /* Get device path, compare that instead of GUID, additionally update GUIDs of joysticks with matching paths, in case they're not open yet. */
468  SDL_wcslcpy(hidPath, dipdw2.wszPath, SDL_arraysize(hidPath));
469  }
470 
471  pNewJoystick = *(JoyStick_DeviceData **)pContext;
472  while (pNewJoystick) {
473  if (SDL_wcscmp(pNewJoystick->hidPath, hidPath) == 0) {
474  /* if we are replacing the front of the list then update it */
475  if (pNewJoystick == *(JoyStick_DeviceData **)pContext) {
476  *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
477  } else if (pPrevJoystick) {
478  pPrevJoystick->pNext = pNewJoystick->pNext;
479  }
480 
481  // Update with new guid/etc, if it has changed
482  pNewJoystick->dxdevice = *pdidInstance;
483 
484  pNewJoystick->pNext = SYS_Joystick;
485  SYS_Joystick = pNewJoystick;
486 
487  return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
488  }
489 
490  pPrevJoystick = pNewJoystick;
491  pNewJoystick = pNewJoystick->pNext;
492  }
493 
494  pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData));
495  if (!pNewJoystick) {
496  return DIENUM_CONTINUE; /* better luck next time? */
497  }
498 
499  SDL_zerop(pNewJoystick);
500  SDL_wcslcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath));
501  pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
502  if (!pNewJoystick->joystickname) {
503  SDL_free(pNewJoystick);
504  return DIENUM_CONTINUE; /* better luck next time? */
505  }
506 
507  SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
508  sizeof(DIDEVICEINSTANCE));
509 
510  SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
511 
512  guid16 = (Uint16 *)pNewJoystick->guid.data;
513  if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
514  vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1);
515  product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1);
516  version = 0;
517 
518  *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
519  *guid16++ = 0;
520  *guid16++ = SDL_SwapLE16(vendor);
521  *guid16++ = 0;
522  *guid16++ = SDL_SwapLE16(product);
523  *guid16++ = 0;
524  *guid16++ = SDL_SwapLE16(version);
525  *guid16++ = 0;
526  } else {
528  *guid16++ = 0;
529  SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
530  }
531 
532  if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
533  SDL_free(pNewJoystick);
534  return DIENUM_CONTINUE;
535  }
536 
537 #ifdef SDL_JOYSTICK_HIDAPI
538  if (HIDAPI_IsDevicePresent(vendor, product, 0)) {
539  /* The HIDAPI driver is taking care of this device */
540  SDL_free(pNewJoystick);
541  return DIENUM_CONTINUE;
542  }
543 #endif
544 
545  WINDOWS_AddJoystickDevice(pNewJoystick);
546 
547  return DIENUM_CONTINUE; /* get next device, please */
548 }
549 
550 void
552 {
553  IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY);
554 
555  if (SDL_RawDevList) {
556  SDL_free(SDL_RawDevList); /* in case we used this in DirectInput detection */
557  SDL_RawDevList = NULL;
558  }
559  SDL_RawDevListCount = 0;
560 }
561 
562 static BOOL CALLBACK
563 EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
564 {
565  SDL_Joystick *joystick = (SDL_Joystick *)pvRef;
566  HRESULT result;
567  input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
568 
569  if (dev->dwType & DIDFT_BUTTON) {
570  in->type = BUTTON;
571  in->num = joystick->nbuttons;
572  in->ofs = DIJOFS_BUTTON(in->num);
573  joystick->nbuttons++;
574  } else if (dev->dwType & DIDFT_POV) {
575  in->type = HAT;
576  in->num = joystick->nhats;
577  in->ofs = DIJOFS_POV(in->num);
578  joystick->nhats++;
579  } else if (dev->dwType & DIDFT_AXIS) {
580  DIPROPRANGE diprg;
581  DIPROPDWORD dilong;
582 
583  in->type = AXIS;
584  in->num = joystick->naxes;
585  if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType)))
586  in->ofs = DIJOFS_X;
587  else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType)))
588  in->ofs = DIJOFS_Y;
589  else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType)))
590  in->ofs = DIJOFS_Z;
591  else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType)))
592  in->ofs = DIJOFS_RX;
593  else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType)))
594  in->ofs = DIJOFS_RY;
595  else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType)))
596  in->ofs = DIJOFS_RZ;
597  else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) {
598  in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders);
599  ++joystick->hwdata->NumSliders;
600  } else {
601  return DIENUM_CONTINUE; /* not an axis we can grok */
602  }
603 
604  diprg.diph.dwSize = sizeof(diprg);
605  diprg.diph.dwHeaderSize = sizeof(diprg.diph);
606  diprg.diph.dwObj = dev->dwType;
607  diprg.diph.dwHow = DIPH_BYID;
608  diprg.lMin = SDL_JOYSTICK_AXIS_MIN;
609  diprg.lMax = SDL_JOYSTICK_AXIS_MAX;
610 
611  result =
612  IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
613  DIPROP_RANGE, &diprg.diph);
614  if (FAILED(result)) {
615  return DIENUM_CONTINUE; /* don't use this axis */
616  }
617 
618  /* Set dead zone to 0. */
619  dilong.diph.dwSize = sizeof(dilong);
620  dilong.diph.dwHeaderSize = sizeof(dilong.diph);
621  dilong.diph.dwObj = dev->dwType;
622  dilong.diph.dwHow = DIPH_BYID;
623  dilong.dwData = 0;
624  result =
625  IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
626  DIPROP_DEADZONE, &dilong.diph);
627  if (FAILED(result)) {
628  return DIENUM_CONTINUE; /* don't use this axis */
629  }
630 
631  joystick->naxes++;
632  } else {
633  /* not supported at this time */
634  return DIENUM_CONTINUE;
635  }
636 
637  joystick->hwdata->NumInputs++;
638 
639  if (joystick->hwdata->NumInputs == MAX_INPUTS) {
640  return DIENUM_STOP; /* too many */
641  }
642 
643  return DIENUM_CONTINUE;
644 }
645 
646 /* Sort using the data offset into the DInput struct.
647  * This gives a reasonable ordering for the inputs.
648  */
649 static int
650 SortDevFunc(const void *a, const void *b)
651 {
652  const input_t *inputA = (const input_t*)a;
653  const input_t *inputB = (const input_t*)b;
654 
655  if (inputA->ofs < inputB->ofs)
656  return -1;
657  if (inputA->ofs > inputB->ofs)
658  return 1;
659  return 0;
660 }
661 
662 /* Sort the input objects and recalculate the indices for each input. */
663 static void
664 SortDevObjects(SDL_Joystick *joystick)
665 {
666  input_t *inputs = joystick->hwdata->Inputs;
667  int nButtons = 0;
668  int nHats = 0;
669  int nAxis = 0;
670  int n;
671 
672  SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc);
673 
674  for (n = 0; n < joystick->hwdata->NumInputs; n++) {
675  switch (inputs[n].type) {
676  case BUTTON:
677  inputs[n].num = nButtons;
678  nButtons++;
679  break;
680 
681  case HAT:
682  inputs[n].num = nHats;
683  nHats++;
684  break;
685 
686  case AXIS:
687  inputs[n].num = nAxis;
688  nAxis++;
689  break;
690  }
691  }
692 }
693 
694 int
695 SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
696 {
697  HRESULT result;
698  LPDIRECTINPUTDEVICE8 device;
699  DIPROPDWORD dipdw;
700 
701  joystick->hwdata->buffered = SDL_TRUE;
702  joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
703 
704  SDL_zero(dipdw);
705  dipdw.diph.dwSize = sizeof(DIPROPDWORD);
706  dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
707 
708  result =
709  IDirectInput8_CreateDevice(dinput,
710  &(joystickdevice->dxdevice.guidInstance), &device, NULL);
711  if (FAILED(result)) {
712  return SetDIerror("IDirectInput::CreateDevice", result);
713  }
714 
715  /* Now get the IDirectInputDevice8 interface, instead. */
716  result = IDirectInputDevice8_QueryInterface(device,
717  &IID_IDirectInputDevice8,
718  (LPVOID *)& joystick->
719  hwdata->InputDevice);
720  /* We are done with this object. Use the stored one from now on. */
721  IDirectInputDevice8_Release(device);
722 
723  if (FAILED(result)) {
724  return SetDIerror("IDirectInputDevice8::QueryInterface", result);
725  }
726 
727  /* Acquire shared access. Exclusive access is required for forces,
728  * though. */
729  result =
730  IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata->
731  InputDevice, SDL_HelperWindow,
732  DISCL_EXCLUSIVE |
733  DISCL_BACKGROUND);
734  if (FAILED(result)) {
735  return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result);
736  }
737 
738  /* Use the extended data structure: DIJOYSTATE2. */
739  result =
740  IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice,
741  &SDL_c_dfDIJoystick2);
742  if (FAILED(result)) {
743  return SetDIerror("IDirectInputDevice8::SetDataFormat", result);
744  }
745 
746  /* Get device capabilities */
747  result =
748  IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice,
749  &joystick->hwdata->Capabilities);
750  if (FAILED(result)) {
751  return SetDIerror("IDirectInputDevice8::GetCapabilities", result);
752  }
753 
754  /* Force capable? */
755  if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
756  result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
757  if (FAILED(result)) {
758  return SetDIerror("IDirectInputDevice8::Acquire", result);
759  }
760 
761  /* reset all actuators. */
762  result =
763  IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->
764  InputDevice,
765  DISFFC_RESET);
766 
767  /* Not necessarily supported, ignore if not supported.
768  if (FAILED(result)) {
769  return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result);
770  }
771  */
772 
773  result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
774 
775  if (FAILED(result)) {
776  return SetDIerror("IDirectInputDevice8::Unacquire", result);
777  }
778 
779  /* Turn on auto-centering for a ForceFeedback device (until told
780  * otherwise). */
781  dipdw.diph.dwObj = 0;
782  dipdw.diph.dwHow = DIPH_DEVICE;
783  dipdw.dwData = DIPROPAUTOCENTER_ON;
784 
785  result =
786  IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
787  DIPROP_AUTOCENTER, &dipdw.diph);
788 
789  /* Not necessarily supported, ignore if not supported.
790  if (FAILED(result)) {
791  return SetDIerror("IDirectInputDevice8::SetProperty", result);
792  }
793  */
794  }
795 
796  /* What buttons and axes does it have? */
797  IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice,
798  EnumDevObjectsCallback, joystick,
799  DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
800 
801  /* Reorder the input objects. Some devices do not report the X axis as
802  * the first axis, for example. */
803  SortDevObjects(joystick);
804 
805  dipdw.diph.dwObj = 0;
806  dipdw.diph.dwHow = DIPH_DEVICE;
807  dipdw.dwData = INPUT_QSIZE;
808 
809  /* Set the buffer size */
810  result =
811  IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
812  DIPROP_BUFFERSIZE, &dipdw.diph);
813 
814  if (result == DI_POLLEDDEVICE) {
815  /* This device doesn't support buffering, so we're forced
816  * to use less reliable polling. */
817  joystick->hwdata->buffered = SDL_FALSE;
818  } else if (FAILED(result)) {
819  return SetDIerror("IDirectInputDevice8::SetProperty", result);
820  }
821  return 0;
822 }
823 
824 static int
825 SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude, Uint32 duration_ms)
826 {
827  HRESULT result;
828 
829  /* Reset and then enable actuators */
830  result = IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->InputDevice, DISFFC_RESET);
831  if (result == DIERR_INPUTLOST || result == DIERR_NOTEXCLUSIVEACQUIRED) {
832  result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
833  if (SUCCEEDED(result)) {
834  result = IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->InputDevice, DISFFC_RESET);
835  }
836  }
837  if (FAILED(result)) {
838  return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand(DISFFC_RESET)", result);
839  }
840 
841  result = IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->InputDevice, DISFFC_SETACTUATORSON);
842  if (FAILED(result)) {
843  return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand(DISFFC_SETACTUATORSON)", result);
844  }
845 
846  /* Create the effect */
847  joystick->hwdata->ffeffect = CreateRumbleEffectData(magnitude, duration_ms);
848  if (!joystick->hwdata->ffeffect) {
849  return SDL_OutOfMemory();
850  }
851 
852  result = IDirectInputDevice8_CreateEffect(joystick->hwdata->InputDevice, &GUID_Sine,
853  joystick->hwdata->ffeffect, &joystick->hwdata->ffeffect_ref, NULL);
854  if (FAILED(result)) {
855  return SetDIerror("IDirectInputDevice8::CreateEffect", result);
856  }
857  return 0;
858 }
859 
860 int
861 SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
862 {
863  HRESULT result;
864 
865  /* Scale and average the two rumble strengths */
866  Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2);
867 
868  if (!(joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK)) {
869  return SDL_Unsupported();
870  }
871 
872  if (joystick->hwdata->ff_initialized) {
873  DIPERIODIC *periodic = ((DIPERIODIC *)joystick->hwdata->ffeffect->lpvTypeSpecificParams);
874  joystick->hwdata->ffeffect->dwDuration = duration_ms * 1000; /* In microseconds. */
875  periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude);
876 
877  result = IDirectInputEffect_SetParameters(joystick->hwdata->ffeffect_ref, joystick->hwdata->ffeffect, (DIEP_DURATION | DIEP_TYPESPECIFICPARAMS));
878  if (result == DIERR_INPUTLOST) {
879  result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
880  if (SUCCEEDED(result)) {
881  result = IDirectInputEffect_SetParameters(joystick->hwdata->ffeffect_ref, joystick->hwdata->ffeffect, (DIEP_DURATION | DIEP_TYPESPECIFICPARAMS));
882  }
883  }
884  if (FAILED(result)) {
885  return SetDIerror("IDirectInputDevice8::SetParameters", result);
886  }
887  } else {
888  if (SDL_DINPUT_JoystickInitRumble(joystick, magnitude, duration_ms) < 0) {
889  return -1;
890  }
891  joystick->hwdata->ff_initialized = SDL_TRUE;
892  }
893 
894  result = IDirectInputEffect_Start(joystick->hwdata->ffeffect_ref, 1, 0);
895  if (result == DIERR_INPUTLOST || result == DIERR_NOTEXCLUSIVEACQUIRED) {
896  result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
897  if (SUCCEEDED(result)) {
898  result = IDirectInputEffect_Start(joystick->hwdata->ffeffect_ref, 1, 0);
899  }
900  }
901  if (FAILED(result)) {
902  return SetDIerror("IDirectInputDevice8::Start", result);
903  }
904  return 0;
905 }
906 
907 static Uint8
908 TranslatePOV(DWORD value)
909 {
910  const int HAT_VALS[] = {
911  SDL_HAT_UP,
915  SDL_HAT_DOWN,
916  SDL_HAT_DOWN | SDL_HAT_LEFT,
917  SDL_HAT_LEFT,
918  SDL_HAT_UP | SDL_HAT_LEFT
919  };
920 
921  if (LOWORD(value) == 0xFFFF)
922  return SDL_HAT_CENTERED;
923 
924  /* Round the value up: */
925  value += 4500 / 2;
926  value %= 36000;
927  value /= 4500;
928 
929  if (value >= 8)
930  return SDL_HAT_CENTERED; /* shouldn't happen */
931 
932  return HAT_VALS[value];
933 }
934 
935 static void
936 UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick)
937 {
938  int i;
939  HRESULT result;
940  DWORD numevents;
941  DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
942 
943  numevents = INPUT_QSIZE;
944  result =
945  IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
946  sizeof(DIDEVICEOBJECTDATA), evtbuf,
947  &numevents, 0);
948  if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
949  IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
950  result =
951  IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
952  sizeof(DIDEVICEOBJECTDATA),
953  evtbuf, &numevents, 0);
954  }
955 
956  /* Handle the events or punt */
957  if (FAILED(result)) {
958  return;
959  }
960 
961  for (i = 0; i < (int)numevents; ++i) {
962  int j;
963 
964  for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
965  const input_t *in = &joystick->hwdata->Inputs[j];
966 
967  if (evtbuf[i].dwOfs != in->ofs)
968  continue;
969 
970  switch (in->type) {
971  case AXIS:
972  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData);
973  break;
974  case BUTTON:
975  SDL_PrivateJoystickButton(joystick, in->num,
976  (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED));
977  break;
978  case HAT:
979  {
980  Uint8 pos = TranslatePOV(evtbuf[i].dwData);
981  SDL_PrivateJoystickHat(joystick, in->num, pos);
982  }
983  break;
984  }
985  }
986  }
987 }
988 
989 /* Function to update the state of a joystick - called as a device poll.
990  * This function shouldn't update the joystick structure directly,
991  * but instead should call SDL_PrivateJoystick*() to deliver events
992  * and update joystick device state.
993  */
994 static void
995 UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick)
996 {
997  DIJOYSTATE2 state;
998  HRESULT result;
999  int i;
1000 
1001  result =
1002  IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
1003  sizeof(DIJOYSTATE2), &state);
1004  if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
1005  IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
1006  result =
1007  IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
1008  sizeof(DIJOYSTATE2), &state);
1009  }
1010 
1011  if (result != DI_OK) {
1012  return;
1013  }
1014 
1015  /* Set each known axis, button and POV. */
1016  for (i = 0; i < joystick->hwdata->NumInputs; ++i) {
1017  const input_t *in = &joystick->hwdata->Inputs[i];
1018 
1019  switch (in->type) {
1020  case AXIS:
1021  switch (in->ofs) {
1022  case DIJOFS_X:
1023  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lX);
1024  break;
1025  case DIJOFS_Y:
1026  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lY);
1027  break;
1028  case DIJOFS_Z:
1029  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lZ);
1030  break;
1031  case DIJOFS_RX:
1032  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRx);
1033  break;
1034  case DIJOFS_RY:
1035  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRy);
1036  break;
1037  case DIJOFS_RZ:
1038  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.lRz);
1039  break;
1040  case DIJOFS_SLIDER(0):
1041  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[0]);
1042  break;
1043  case DIJOFS_SLIDER(1):
1044  SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)state.rglSlider[1]);
1045  break;
1046  }
1047  break;
1048 
1049  case BUTTON:
1050  SDL_PrivateJoystickButton(joystick, in->num,
1051  (Uint8)(state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED));
1052  break;
1053  case HAT:
1054  {
1055  Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs - DIJOFS_POV(0)]);
1056  SDL_PrivateJoystickHat(joystick, in->num, pos);
1057  break;
1058  }
1059  }
1060  }
1061 }
1062 
1063 void
1064 SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
1065 {
1066  HRESULT result;
1067 
1068  result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
1069  if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
1070  IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
1071  IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
1072  }
1073 
1074  if (joystick->hwdata->buffered) {
1075  UpdateDINPUTJoystickState_Buffered(joystick);
1076  } else {
1077  UpdateDINPUTJoystickState_Polled(joystick);
1078  }
1079 }
1080 
1081 void
1082 SDL_DINPUT_JoystickClose(SDL_Joystick * joystick)
1083 {
1084  if (joystick->hwdata->ffeffect_ref) {
1085  IDirectInputEffect_Unload(joystick->hwdata->ffeffect_ref);
1086  joystick->hwdata->ffeffect_ref = NULL;
1087  }
1088  if (joystick->hwdata->ffeffect) {
1089  FreeRumbleEffectData(joystick->hwdata->ffeffect);
1090  joystick->hwdata->ffeffect = NULL;
1091  }
1092  IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
1093  IDirectInputDevice8_Release(joystick->hwdata->InputDevice);
1094  joystick->hwdata->ff_initialized = SDL_FALSE;
1095 }
1096 
1097 void
1099 {
1100  if (dinput != NULL) {
1101  IDirectInput8_Release(dinput);
1102  dinput = NULL;
1103  }
1104 
1105  if (coinitialized) {
1107  coinitialized = SDL_FALSE;
1108  }
1109 }
1110 
1111 #else /* !SDL_JOYSTICK_DINPUT */
1112 
1114 
1115 int
1117 {
1118  return 0;
1119 }
1120 
1121 void
1123 {
1124 }
1125 
1126 int
1127 SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
1128 {
1129  return SDL_Unsupported();
1130 }
1131 
1132 int
1133 SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
1134 {
1135  return SDL_Unsupported();
1136 }
1137 
1138 void
1139 SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
1140 {
1141 }
1142 
1143 void
1144 SDL_DINPUT_JoystickClose(SDL_Joystick * joystick)
1145 {
1146 }
1147 
1148 void
1150 {
1151 }
1152 
1153 #endif /* SDL_JOYSTICK_DINPUT */
1154 
1155 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_strlcpy
JoyStick_DeviceData * SYS_Joystick
GLuint num
#define SDL_qsort
GLuint64EXT * result
int SDL_DINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:885
#define DIRECTINPUT_VERSION
Definition: SDL_directx.h:95
#define SDL_HARDWARE_BUS_USB
struct JoyStick_DeviceData * pNext
int SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice)
struct xkb_state * state
SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:961
uint16_t Uint16
Definition: SDL_stdinc.h:191
Uint8 data[16]
Definition: SDL_joystick.h:71
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:828
#define SDL_HARDWARE_BUS_BLUETOOTH
static SDL_AudioDeviceID device
Definition: loopwave.c:37
#define SDL_JOYSTICK_AXIS_MIN
Definition: SDL_joystick.h:302
#define FAILED(x)
Definition: SDL_directx.h:54
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:331
#define SDL_memcpy
int SDL_DINPUT_JoystickInit(void)
#define SDL_JOYSTICK_AXIS_MAX
Definition: SDL_joystick.h:301
#define SDL_wcscmp
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:333
HRESULT WIN_CoInitialize(void)
uint8_t Uint8
Definition: SDL_stdinc.h:179
#define SDL_free
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
#define SDL_memcmp
GLsizei const GLfloat * value
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:46
SDL_bool SDL_XINPUT_Enabled(void)
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
#define SDL_wcslcpy
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:161
void WIN_CoUninitialize(void)
#define SUCCEEDED(x)
Definition: SDL_directx.h:51
#define SDL_SetError
#define SDL_calloc
void SDL_DINPUT_JoystickUpdate(SDL_Joystick *joystick)
void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
uint32_t Uint32
Definition: SDL_stdinc.h:203
GLdouble n
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
#define SDL_malloc
void SDL_DINPUT_JoystickClose(SDL_Joystick *joystick)
#define SDL_PRESSED
Definition: SDL_events.h:50
DIDEVICEINSTANCE dxdevice
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:329
GLboolean GLboolean GLboolean GLboolean a
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:232
SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version)
#define SDL_RELEASED
Definition: SDL_events.h:49
GLuint in
#define SDL_HAT_UP
Definition: SDL_joystick.h:330
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:332
GLboolean GLboolean GLboolean b
#define FIELD_OFFSET(type, field)
Definition: SDL_directx.h:87
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define SDL_memset
int16_t Sint16
Definition: SDL_stdinc.h:185
#define SDL_strstr
#define MAX_INPUTS
void SDL_DINPUT_JoystickQuit(void)