SDL 2.0
SDL_dinputjoystick.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 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
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. */
42extern HWND SDL_HelperWindow;
43
44/* local variables */
45static SDL_bool coinitialized = SDL_FALSE;
46static LPDIRECTINPUT8 dinput = NULL;
47static PRAWINPUTDEVICELIST SDL_RawDevList = NULL;
48static UINT SDL_RawDevListCount = 0;
49
50/* Taken from Wine - Thanks! */
51static 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
218const 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 */
228static int
229SetDIerror(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
238static SDL_bool
239SDL_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) {
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
317void 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
328DIEFFECT *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
372int
374{
375 HRESULT result;
376 HINSTANCE instance;
377
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 */
406static BOOL CALLBACK
407EnumJoysticksCallback(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
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
550void
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
562static BOOL CALLBACK
563EnumDevObjectsCallback(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 */
649static int
650SortDevFunc(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. */
663static void
664SortDevObjects(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
694int
695SDL_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
824static int
825SDL_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
860int
861SDL_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
907static Uint8
908TranslatePOV(DWORD value)
909{
910 const int HAT_VALS[] = {
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
935static void
936UpdateDINPUTJoystickState_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 */
994static void
995UpdateDINPUTJoystickState_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
1063void
1064SDL_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
1081void
1082SDL_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
1097void
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
1115int
1117{
1118 return 0;
1119}
1120
1121void
1123{
1124}
1125
1126int
1127SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
1128{
1129 return SDL_Unsupported();
1130}
1131
1132int
1133SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
1134{
1135 return SDL_Unsupported();
1136}
1137
1138void
1139SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick)
1140{
1141}
1142
1143void
1144SDL_DINPUT_JoystickClose(SDL_Joystick * joystick)
1145{
1146}
1147
1148void
1150{
1151}
1152
1153#endif /* SDL_JOYSTICK_DINPUT */
1154
1155/* vi: set ts=4 sw=4 expandtab: */
int SDL_DINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
void SDL_DINPUT_JoystickQuit(void)
int SDL_DINPUT_JoystickInit(void)
void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
void SDL_DINPUT_JoystickClose(SDL_Joystick *joystick)
int SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice)
void SDL_DINPUT_JoystickUpdate(SDL_Joystick *joystick)
#define SUCCEEDED(x)
Definition: SDL_directx.h:51
#define DIRECTINPUT_VERSION
Definition: SDL_directx.h:95
#define FIELD_OFFSET(type, field)
Definition: SDL_directx.h:87
#define FAILED(x)
Definition: SDL_directx.h:54
#define SDL_SetError
#define SDL_memset
#define SDL_wcslcpy
#define SDL_qsort
#define SDL_malloc
#define SDL_strlcpy
#define SDL_free
#define SDL_memcmp
#define SDL_strstr
#define SDL_memcpy
#define SDL_wcscmp
#define SDL_calloc
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:232
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define SDL_RELEASED
Definition: SDL_events.h:49
#define SDL_PRESSED
Definition: SDL_events.h:50
SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
Definition: SDL_joystick.c:890
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
Definition: SDL_joystick.c:833
SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
Definition: SDL_joystick.c:966
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:333
#define SDL_JOYSTICK_AXIS_MIN
Definition: SDL_joystick.h:302
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:331
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:332
#define SDL_HAT_UP
Definition: SDL_joystick.h:330
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:329
#define SDL_JOYSTICK_AXIS_MAX
Definition: SDL_joystick.h:301
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
GLboolean GLboolean GLboolean b
GLuint64EXT * result
GLboolean GLboolean GLboolean GLboolean a
GLuint in
GLuint num
GLdouble n
GLsizei const GLfloat * value
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
uint32_t Uint32
Definition: SDL_stdinc.h:203
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
int16_t Sint16
Definition: SDL_stdinc.h:185
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
#define SDL_HARDWARE_BUS_USB
#define SDL_HARDWARE_BUS_BLUETOOTH
struct xkb_state * state
HRESULT WIN_CoInitialize(void)
void WIN_CoUninitialize(void)
#define WIN_StringToUTF8(S)
Definition: SDL_windows.h:46
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
#define MAX_INPUTS
JoyStick_DeviceData * SYS_Joystick
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
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
SDL_bool SDL_XINPUT_Enabled(void)
#define NULL
Definition: begin_code.h:167
static SDL_AudioDeviceID device
Definition: loopwave.c:37
DIDEVICEINSTANCE dxdevice
struct JoyStick_DeviceData * pNext
Uint8 data[16]
Definition: SDL_joystick.h:71