23 #ifdef SDL_JOYSTICK_DINPUT
38 #include "SDL_thread.h"
40 #include "SDL_mutex.h"
44 #include "../SDL_sysjoystick.h"
45 #if !SDL_EVENTS_DISABLED
46 #include "../../events/SDL_events_c.h"
52 #ifndef DIDFT_OPTIONAL
53 #define DIDFT_OPTIONAL 0x80000000
57 #define INPUT_QSIZE 32
58 #define AXIS_MIN -32768
59 #define AXIS_MAX 32767
60 #define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100)
63 extern HWND SDL_HelperWindow;
68 static LPDIRECTINPUT8 dinput =
NULL;
83 static HANDLE s_pXInputDLL = 0;
84 static int s_XInputDLLRefCount = 0;
93 s_XInputDLLRefCount++;
97 version = (1 << 16) | 4;
98 s_pXInputDLL = LoadLibrary( L
"XInput1_4.dll" );
100 version = (1 << 16) | 3;
101 s_pXInputDLL = LoadLibrary( L
"XInput1_3.dll" );
104 s_pXInputDLL = LoadLibrary( L
"bin\\XInput1_3.dll" );
112 s_XInputDLLRefCount = 1;
115 SDL_XInputGetState = (XInputGetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, (LPCSTR)100 );
116 SDL_XInputSetState = (XInputSetState_t)GetProcAddress( (HMODULE)s_pXInputDLL,
"XInputSetState" );
129 if ( s_pXInputDLL ) {
131 if (--s_XInputDLLRefCount == 0) {
132 FreeLibrary( s_pXInputDLL );
141 extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst,
DWORD dwVersion,
142 LPDIRECTINPUT * ppDI,
143 LPUNKNOWN punkOuter);
144 struct JoyStick_DeviceData_
147 DIDEVICEINSTANCE dxdevice;
149 Uint8 send_add_event;
153 struct JoyStick_DeviceData_ *pNext;
156 typedef struct JoyStick_DeviceData_ JoyStick_DeviceData;
158 static JoyStick_DeviceData *SYS_Joystick;
161 static int SetDIerror(
const char *
function,
HRESULT code);
162 static BOOL CALLBACK EnumJoysticksCallback(
const DIDEVICEINSTANCE *
164 static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev,
172 static int SDL_PrivateJoystickButton_Int(
SDL_Joystick * joystick,
176 DIOBJECTDATAFORMAT dfDIJoystick2[] = {
177 { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
178 { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
179 { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
180 { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
181 { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
182 { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
183 { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
184 { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
185 { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
186 { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
187 { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
188 { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
189 {
NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
190 {
NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
191 {
NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
192 {
NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
193 {
NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
194 {
NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
195 {
NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
196 {
NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
197 {
NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
198 {
NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
199 {
NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
200 {
NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
201 {
NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
202 {
NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
203 {
NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
204 {
NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
205 {
NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
206 {
NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
207 {
NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
208 {
NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
209 {
NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
210 {
NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
211 {
NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
212 {
NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
213 {
NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
214 {
NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
215 {
NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
216 {
NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
217 {
NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
218 {
NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
219 {
NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
220 {
NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
221 {
NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
222 {
NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
223 {
NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
224 {
NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
225 {
NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
226 {
NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
227 {
NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
228 {
NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
229 {
NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
230 {
NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
231 {
NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
232 {
NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
233 {
NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
234 {
NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
235 {
NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
236 {
NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
237 {
NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
238 {
NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
239 {
NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
240 {
NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
241 {
NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
242 {
NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
243 {
NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
244 {
NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
245 {
NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
246 {
NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
247 {
NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
248 {
NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
249 {
NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
250 {
NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
251 {
NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
252 {
NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
253 {
NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
254 {
NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
255 {
NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
256 {
NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
257 {
NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
258 {
NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
259 {
NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
260 {
NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
261 {
NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
262 {
NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
263 {
NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
264 {
NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
265 {
NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
266 {
NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
267 {
NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
268 {
NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
269 {
NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
270 {
NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
271 {
NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
272 {
NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
273 {
NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
274 {
NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
275 {
NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
276 {
NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
277 {
NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
278 {
NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
279 {
NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
280 {
NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
281 {
NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
282 {
NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
283 {
NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
284 {
NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
285 {
NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
286 {
NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
287 {
NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
288 {
NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
289 {
NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
290 {
NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
291 {
NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
292 {
NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
293 {
NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
294 {
NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
295 {
NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
296 {
NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
297 {
NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
298 {
NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
299 {
NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
300 {
NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
301 {
NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
302 {
NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
303 {
NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
304 {
NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
305 {
NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
306 {
NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
307 {
NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
308 {
NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
309 {
NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
310 {
NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
311 {
NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
312 {
NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
313 {
NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
314 {
NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
315 {
NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
316 {
NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
317 { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
318 { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
319 { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
320 { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
321 { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
322 { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
323 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
324 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
325 { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
326 { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
327 { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
328 { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
329 { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
330 { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
331 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
332 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
333 { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
334 { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
335 { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
336 { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
337 { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
338 { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
339 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
340 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
343 const DIDATAFORMAT c_dfDIJoystick2 = {
344 sizeof(DIDATAFORMAT),
345 sizeof(DIOBJECTDATAFORMAT),
361 return SDL_SetError(
"%s() DirectX error %d",
function, code);
365 #define SAFE_RELEASE(p) \
368 (p)->lpVtbl->Release((p)); \
373 DEFINE_GUID(IID_ValveStreamingGamepad, MAKELONG( 0x28DE, 0x11FF ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
374 DEFINE_GUID(IID_X360WiredGamepad, MAKELONG( 0x045E, 0x02A1 ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
375 DEFINE_GUID(IID_X360WirelessGamepad, MAKELONG( 0x045E, 0x028E ),0x0000,0x0000,0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44);
377 static PRAWINPUTDEVICELIST SDL_RawDevList =
NULL;
378 static UINT SDL_RawDevListCount = 0;
381 SDL_IsXInputDevice(
const GUID* pGuidProductFromDirectInput )
383 static const GUID *s_XInputProductGUID[] = {
384 &IID_ValveStreamingGamepad,
385 &IID_X360WiredGamepad,
386 &IID_X360WirelessGamepad
393 if (!s_bXInputEnabled) {
399 for ( iDevice = 0; iDevice <
SDL_arraysize(s_XInputProductGUID); ++iDevice ) {
400 if (
SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice],
sizeof(GUID)) == 0) {
407 if (SDL_RawDevList ==
NULL) {
408 if ((GetRawInputDeviceList(
NULL, &SDL_RawDevListCount,
sizeof (RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
412 SDL_RawDevList = (PRAWINPUTDEVICELIST)
SDL_malloc(
sizeof (RAWINPUTDEVICELIST) * SDL_RawDevListCount);
413 if (SDL_RawDevList ==
NULL) {
418 if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount,
sizeof (RAWINPUTDEVICELIST)) == -1) {
420 SDL_RawDevList =
NULL;
425 for (i = 0; i < SDL_RawDevListCount; i++) {
428 UINT rdiSize =
sizeof (rdi);
431 rdi.cbSize =
sizeof (rdi);
432 if ( (SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
433 (GetRawInputDeviceInfoA(SDL_RawDevList[i].
hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((
UINT)-1)) &&
434 (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
435 (GetRawInputDeviceInfoA(SDL_RawDevList[i].
hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((
UINT)-1)) &&
449 LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd,
UINT message, WPARAM wParam, LPARAM lParam) {
451 case WM_DEVICECHANGE:
453 case DBT_DEVICEARRIVAL:
454 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
458 case DBT_DEVICEREMOVECOMPLETE:
459 if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
467 return DefWindowProc (hwnd, message, wParam, lParam);
471 DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, \
472 0xC0, 0x4F, 0xB9, 0x51, 0xED);
477 SDL_JoystickThread(
void *_data)
479 HWND messageWindow = 0;
480 HDEVNOTIFY hNotify = 0;
481 DEV_BROADCAST_DEVICEINTERFACE dbh;
490 wincl.hInstance = GetModuleHandle(
NULL );
491 wincl.lpszClassName = L
"Message";
492 wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc;
493 wincl.cbSize =
sizeof (WNDCLASSEX);
495 if (!RegisterClassEx (&wincl))
497 return SDL_SetError(
"Failed to create register class for joystick autodetect.", GetLastError());
500 messageWindow = (HWND)CreateWindowEx( 0, L
"Message",
NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
NULL,
NULL,
NULL );
501 if ( !messageWindow )
503 return SDL_SetError(
"Failed to create message window for joystick autodetect.", GetLastError());
508 dbh.dbcc_size =
sizeof(dbh);
509 dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
510 dbh.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
512 hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE );
515 return SDL_SetError(
"Failed to create notify device for joystick autodetect.", GetLastError());
519 while ( s_bJoystickThreadQuit ==
SDL_FALSE )
526 while ( s_bJoystickThreadQuit ==
SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE) )
528 if ( GetMessage(&messages, messageWindow, 0, 0) != 0 ) {
529 TranslateMessage(&messages);
530 DispatchMessage(&messages);
538 XINPUT_CAPABILITIES capabilities;
540 const SDL_bool available = (result == ERROR_SUCCESS);
541 if (bOpenedXInputDevices[userId] != available) {
543 bOpenedXInputDevices[userId] = available;
548 if (s_bWindowsDeviceChanged || bXInputChanged) {
561 UnregisterDeviceNotification( hNotify );
564 DestroyWindow( messageWindow );
566 UnregisterClass( wincl.lpszClassName, wincl.hInstance );
589 if (FAILED(result)) {
590 return SetDIerror(
"CoInitialize", result);
595 result = CoCreateInstance(&CLSID_DirectInput8,
NULL, CLSCTX_INPROC_SERVER,
596 &IID_IDirectInput8, (
LPVOID)&dinput);
598 if (FAILED(result)) {
600 return SetDIerror(
"CoCreateInstance", result);
604 instance = GetModuleHandle(
NULL);
605 if (instance ==
NULL) {
607 return SDL_SetError(
"GetModuleHandle() failed with error code %d.", GetLastError());
611 if (FAILED(result)) {
613 return SetDIerror(
"IDirectInput::Initialize", result);
626 if ( !s_threadJoystick )
630 #if defined(__WIN32__) && !defined(HAVE_LIBC)
631 #undef SDL_CreateThread
644 JoyStick_DeviceData *device = SYS_Joystick;
648 device = device->pNext;
656 EnumJoysticksCallback(
const DIDEVICEINSTANCE * pdidInstance,
VOID *
pContext)
658 JoyStick_DeviceData *pNewJoystick;
659 JoyStick_DeviceData *pPrevJoystick =
NULL;
661 if (SDL_IsXInputDevice( &pdidInstance->guidProduct )) {
662 return DIENUM_CONTINUE;
665 pNewJoystick = *(JoyStick_DeviceData **)pContext;
666 while ( pNewJoystick )
668 if ( !
SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance,
sizeof(pNewJoystick->dxdevice.guidInstance) ) )
671 if ( pNewJoystick == *(JoyStick_DeviceData **)
pContext )
673 *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
675 else if ( pPrevJoystick )
677 pPrevJoystick->pNext = pNewJoystick->pNext;
680 pNewJoystick->pNext = SYS_Joystick;
681 SYS_Joystick = pNewJoystick;
683 return DIENUM_CONTINUE;
686 pPrevJoystick = pNewJoystick;
687 pNewJoystick = pNewJoystick->pNext;
690 pNewJoystick = (JoyStick_DeviceData *)
SDL_malloc(
sizeof(JoyStick_DeviceData) );
692 return DIENUM_CONTINUE;
696 pNewJoystick->joystickname =
WIN_StringToUTF8(pdidInstance->tszProductName);
697 if (!pNewJoystick->joystickname) {
699 return DIENUM_CONTINUE;
702 SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
703 sizeof(DIDEVICEINSTANCE));
706 pNewJoystick->send_add_event = 1;
707 pNewJoystick->nInstanceID = ++s_nInstanceID;
708 SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct,
sizeof(pNewJoystick->guid) );
709 pNewJoystick->pNext = SYS_Joystick;
710 SYS_Joystick = pNewJoystick;
714 return DIENUM_CONTINUE;
718 AddXInputDevice(
const Uint8 userid, JoyStick_DeviceData **pContext)
721 JoyStick_DeviceData *pPrevJoystick =
NULL;
722 JoyStick_DeviceData *pNewJoystick = *
pContext;
724 while (pNewJoystick) {
725 if ((pNewJoystick->bXInputDevice) && (pNewJoystick->XInputUserId == userid)) {
727 if (pNewJoystick == *pContext) {
728 *pContext = pNewJoystick->pNext;
729 }
else if (pPrevJoystick) {
730 pPrevJoystick->pNext = pNewJoystick->pNext;
733 pNewJoystick->pNext = SYS_Joystick;
734 SYS_Joystick = pNewJoystick;
738 pPrevJoystick = pNewJoystick;
739 pNewJoystick = pNewJoystick->pNext;
742 pNewJoystick = (JoyStick_DeviceData *)
SDL_malloc(
sizeof (JoyStick_DeviceData));
748 SDL_snprintf(name,
sizeof (name),
"XInput Controller #%u", ((
unsigned int) userid) + 1);
749 pNewJoystick->joystickname =
SDL_strdup(name);
750 if (!pNewJoystick->joystickname) {
755 pNewJoystick->bXInputDevice =
SDL_TRUE;
756 pNewJoystick->XInputUserId = userid;
757 pNewJoystick->send_add_event = 1;
758 pNewJoystick->nInstanceID = ++s_nInstanceID;
759 pNewJoystick->pNext = SYS_Joystick;
760 SYS_Joystick = pNewJoystick;
766 EnumXInputDevices(JoyStick_DeviceData **pContext)
768 if (s_bXInputEnabled) {
771 for (iuserid = SDL_XINPUT_MAX_DEVICES-1; iuserid >= 0; iuserid--) {
773 XINPUT_CAPABILITIES capabilities;
777 if (capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD) {
778 AddXInputDevice(userid, pContext);
789 JoyStick_DeviceData *pCurList =
NULL;
791 if ( s_bDeviceAdded || s_bDeviceRemoved )
798 pCurList = SYS_Joystick;
802 IDirectInput8_EnumDevices(dinput,
803 DI8DEVCLASS_GAMECTRL,
804 EnumJoysticksCallback,
805 &pCurList, DIEDFL_ATTACHEDONLY);
808 SDL_RawDevList =
NULL;
809 SDL_RawDevListCount = 0;
812 EnumXInputDevices(&pCurList);
821 JoyStick_DeviceData *pListNext =
NULL;
822 #if !SDL_EVENTS_DISABLED
827 event.jdevice.which = pCurList->nInstanceID;
835 pListNext = pCurList->pNext;
838 pCurList = pListNext;
843 if ( s_bDeviceAdded )
845 JoyStick_DeviceData *pNewJoystick;
846 int device_index = 0;
848 pNewJoystick = SYS_Joystick;
849 while ( pNewJoystick )
851 if ( pNewJoystick->send_add_event )
853 #if !SDL_EVENTS_DISABLED
858 event.jdevice.which = device_index;
865 pNewJoystick->send_add_event = 0;
868 pNewJoystick = pNewJoystick->pNext;
877 if ( s_bDeviceAdded || s_bDeviceRemoved )
887 JoyStick_DeviceData *device = SYS_Joystick;
889 for (; device_index > 0; device_index--)
890 device = device->pNext;
892 return device->joystickname;
898 JoyStick_DeviceData *device = SYS_Joystick;
901 for (index = device_index; index > 0; index--)
902 device = device->pNext;
904 return device->nInstanceID;
916 JoyStick_DeviceData *joystickdevice = SYS_Joystick;
918 for (; device_index > 0; device_index--)
919 joystickdevice = joystickdevice->pNext;
922 joystick->
instance_id = joystickdevice->nInstanceID;
931 if (joystickdevice->bXInputDevice) {
933 const Uint8 userId = joystickdevice->XInputUserId;
934 XINPUT_CAPABILITIES capabilities;
946 return SDL_SetError(
"Failed to obtain XInput device capabilities. Device disconnected?");
949 SDL_assert(capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD);
962 LPDIRECTINPUTDEVICE8 device;
968 joystick->
hwdata->
guid = joystickdevice->guid;
971 dipdw.diph.dwSize =
sizeof(DIPROPDWORD);
972 dipdw.diph.dwHeaderSize =
sizeof(DIPROPHEADER);
975 IDirectInput8_CreateDevice(dinput,
976 &(joystickdevice->dxdevice.guidInstance), &device,
NULL);
977 if (FAILED(result)) {
978 return SetDIerror(
"IDirectInput::CreateDevice", result);
982 result = IDirectInputDevice8_QueryInterface(device,
983 &IID_IDirectInputDevice8,
985 hwdata->InputDevice);
987 IDirectInputDevice8_Release(device);
989 if (FAILED(result)) {
990 return SetDIerror(
"IDirectInputDevice8::QueryInterface", result);
996 IDirectInputDevice8_SetCooperativeLevel(joystick->
hwdata->
997 InputDevice, SDL_HelperWindow,
1000 if (FAILED(result)) {
1001 return SetDIerror(
"IDirectInputDevice8::SetCooperativeLevel", result);
1008 if (FAILED(result)) {
1009 return SetDIerror(
"IDirectInputDevice8::SetDataFormat", result);
1017 if (FAILED(result)) {
1018 return SetDIerror(
"IDirectInputDevice8::GetCapabilities", result);
1026 if (FAILED(result)) {
1027 return SetDIerror(
"IDirectInputDevice8::Acquire", result);
1032 IDirectInputDevice8_SendForceFeedbackCommand(joystick->
hwdata->
1044 if (FAILED(result)) {
1045 return SetDIerror(
"IDirectInputDevice8::Unacquire", result);
1050 dipdw.diph.dwObj = 0;
1051 dipdw.diph.dwHow = DIPH_DEVICE;
1052 dipdw.dwData = DIPROPAUTOCENTER_ON;
1056 DIPROP_AUTOCENTER, &dipdw.diph);
1067 EnumDevObjectsCallback, joystick,
1068 DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
1072 SortDevObjects(joystick);
1074 dipdw.diph.dwObj = 0;
1075 dipdw.diph.dwHow = DIPH_DEVICE;
1076 dipdw.dwData = INPUT_QSIZE;
1081 DIPROP_BUFFERSIZE, &dipdw.diph);
1083 if (result == DI_POLLEDDEVICE) {
1087 }
else if (FAILED(result)) {
1088 return SetDIerror(
"IDirectInputDevice8::SetProperty", result);
1104 SortDevFunc(
const void *
a,
const void *
b)
1109 if (inputA->
ofs < inputB->
ofs)
1111 if (inputA->
ofs > inputB->
ofs)
1130 switch (inputs[n].
type)
1133 inputs[
n].
num = nButtons;
1138 inputs[
n].
num = nHats;
1143 inputs[
n].
num = nAxis;
1150 static BOOL CALLBACK
1151 EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev,
LPVOID pvRef)
1157 if (dev->dwType & DIDFT_BUTTON) {
1160 in->
ofs = DIJOFS_BUTTON( in->
num );
1162 }
else if (dev->dwType & DIDFT_POV) {
1165 in->
ofs = DIJOFS_POV( in->
num );
1167 }
else if (dev->dwType & DIDFT_AXIS) {
1174 if ( !
SDL_memcmp( &dev->guidType, &GUID_XAxis,
sizeof(dev->guidType) ) )
1176 else if ( !
SDL_memcmp( &dev->guidType, &GUID_YAxis,
sizeof(dev->guidType) ) )
1178 else if ( !
SDL_memcmp( &dev->guidType, &GUID_ZAxis,
sizeof(dev->guidType) ) )
1180 else if ( !
SDL_memcmp( &dev->guidType, &GUID_RxAxis,
sizeof(dev->guidType) ) )
1181 in->
ofs = DIJOFS_RX;
1182 else if ( !
SDL_memcmp( &dev->guidType, &GUID_RyAxis,
sizeof(dev->guidType) ) )
1183 in->
ofs = DIJOFS_RY;
1184 else if ( !
SDL_memcmp( &dev->guidType, &GUID_RzAxis,
sizeof(dev->guidType) ) )
1185 in->
ofs = DIJOFS_RZ;
1186 else if ( !
SDL_memcmp( &dev->guidType, &GUID_Slider,
sizeof(dev->guidType) ) )
1193 return DIENUM_CONTINUE;
1196 diprg.diph.dwSize =
sizeof(diprg);
1197 diprg.diph.dwHeaderSize =
sizeof(diprg.diph);
1198 diprg.diph.dwObj = dev->dwType;
1199 diprg.diph.dwHow = DIPH_BYID;
1200 diprg.lMin = AXIS_MIN;
1201 diprg.lMax = AXIS_MAX;
1205 DIPROP_RANGE, &diprg.diph);
1206 if (FAILED(result)) {
1207 return DIENUM_CONTINUE;
1211 dilong.diph.dwSize =
sizeof(dilong);
1212 dilong.diph.dwHeaderSize =
sizeof(dilong.diph);
1213 dilong.diph.dwObj = dev->dwType;
1214 dilong.diph.dwHow = DIPH_BYID;
1218 DIPROP_DEADZONE, &dilong.diph);
1219 if (FAILED(result)) {
1220 return DIENUM_CONTINUE;
1226 return DIENUM_CONTINUE;
1235 return DIENUM_CONTINUE;
1252 sizeof(DIJOYSTATE2), &state);
1253 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
1257 sizeof(DIJOYSTATE2), &state);
1260 if ( result != DI_OK )
1275 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1279 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1283 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1287 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1291 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1295 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1298 case DIJOFS_SLIDER(0):
1299 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1300 (
Sint16) state.rglSlider[0]);
1302 case DIJOFS_SLIDER(1):
1303 SDL_PrivateJoystickAxis_Int(joystick, in->
num,
1304 (
Sint16) state.rglSlider[1]);
1311 SDL_PrivateJoystickButton_Int(joystick, in->
num,
1313 rgbButtons[in->
ofs -
1320 Uint8 pos = TranslatePOV(state.rgdwPOV[in->
ofs -
1322 SDL_PrivateJoystickHat_Int(joystick, in->
num, pos);
1330 SDL_SYS_JoystickUpdate_Buffered(
SDL_Joystick * joystick)
1335 DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
1337 numevents = INPUT_QSIZE;
1340 sizeof(DIDEVICEOBJECTDATA), evtbuf,
1342 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
1346 sizeof(DIDEVICEOBJECTDATA),
1347 evtbuf, &numevents, 0);
1358 for (i = 0; i < (
int) numevents; ++
i) {
1364 if (evtbuf[i].dwOfs != in->
ofs)
1370 (
Sint16) evtbuf[i].dwData);
1380 Uint8 pos = TranslatePOV(evtbuf[i].dwData);
1391 int ButtonChanged(
int ButtonsNow,
int ButtonsPrev,
int ButtonMask )
1393 return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask );
1407 if ( result == ERROR_DEVICE_NOT_CONNECTED )
1468 const int HAT_VALS[] = {
1479 if (LOWORD(value) == 0xFFFF)
1490 return HAT_VALS[
value];
1498 if (joystick->
axes[axis] != value)
1506 if (joystick->
hats[hat] != value)
1515 if (joystick->
buttons[button] != state)
1530 SDL_SYS_JoystickUpdate_XInput(joystick);
1535 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
1541 SDL_SYS_JoystickUpdate_Buffered(joystick);
1543 SDL_SYS_JoystickUpdate_Polled(joystick);
1572 JoyStick_DeviceData *device = SYS_Joystick;
1576 JoyStick_DeviceData *device_next = device->pNext;
1579 device = device_next;
1581 SYS_Joystick =
NULL;
1583 if ( s_threadJoystick )
1593 s_condJoystickThread=
NULL;
1594 s_mutexJoyStickEnum =
NULL;
1595 s_threadJoystick =
NULL;
1598 if (dinput !=
NULL) {
1599 IDirectInput8_Release(dinput);
1603 if (coinitialized) {
1608 if (s_bXInputEnabled) {
1616 JoyStick_DeviceData *device = SYS_Joystick;
1619 for (index = device_index; index > 0; index--)
1620 device = device->pNext;
1622 return device->guid;
1631 SDL_bool SDL_SYS_IsXInputDeviceIndex(
int device_index)
1633 JoyStick_DeviceData *device = SYS_Joystick;
1636 for (index = device_index; index > 0; index--)
1637 device = device->pNext;
1639 return device->bXInputDevice;
input_t Inputs[MAX_INPUTS]
DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond *cond)
XINPUT_GAMEPAD_EX Gamepad
#define DIRECTINPUT_VERSION
DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
#define INVALID_XINPUT_USERID
DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event *event)
Add an event to the event queue.
LPDIRECTINPUTDEVICE8 InputDevice
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
int SDL_SYS_NumJoysticks()
DECLSPEC int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt,...)
typedef HRESULT(WINAPI *LPD3DXIMTSIGNALCALLBACK)(CONST D3DXVECTOR2 *uv
DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex *mutex)
DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void)
DECLSPEC void SDLCALL SDL_free(void *mem)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
GLboolean GLboolean GLboolean GLboolean a
EGLImageKHR EGLint * name
DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len)
DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond *cond)
void SDL_SYS_JoystickQuit(void)
#define XINPUT_CAPS_FFB_SUPPORTED
XInputSetState_t SDL_XInputSetState
typedef UINT(WINAPI *PFNWGLGETCONTEXTGPUIDAMDPROC)(HGLRC hglrc)
#define XINPUTGETCAPABILITIES
#define SDL_XINPUT_MAX_DEVICES
DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex *mutex)
struct joystick_hwdata * hwdata
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
#define SDL_HINT_XINPUT_ENABLED
A variable that lets you disable the detection and use of Xinput gamepad devices. ...
DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread *thread, int *status)
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
#define SDL_GetEventState(type)
void WIN_UnloadXInputDLL(void)
HRESULT WIN_CoInitialize(void)
DECLSPEC char *SDLCALL SDL_strdup(const char *str)
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
SDL_EventFilter SDL_EventOK
DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle)
DECLSPEC void SDLCALL SDL_Delay(Uint32 ms)
Wait a specified number of milliseconds before returning.
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
void SDL_SYS_JoystickDetect()
#define WIN_StringToUTF8(S)
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71)
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index)
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void)
DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data)
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
SDL_bool SDL_SYS_JoystickNeedsPolling()
#define SDL_assert(condition)
int SDL_SYS_JoystickInit(void)
#define SDL_OutOfMemory()
void WIN_CoUninitialize(void)
#define SDL_arraysize(array)
struct SDL_mutex SDL_mutex
int WIN_LoadXInputDLL(void)
EGLSurface EGLint void ** value
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
XInputGetCapabilities_t SDL_XInputGetCapabilities
uint8_t Uint8
An unsigned 8-bit integer type.
DECLSPEC int SDLCALL SDL_atoi(const char *str)
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
int16_t Sint16
A signed 16-bit integer type.
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
GLdouble GLdouble GLdouble b
HVIDEOINPUTDEVICENV hDevice
int SDL_SYS_JoystickOpen(SDL_Joystick *joystick, int device_index)
DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int(*compare)(const void *, const void *))
DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex *mutex)
XInputGetState_t SDL_XInputGetState
XINPUT_STATE_EX XInputState[2]
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
SDL_JoystickID instance_id
typedef VOID(WINAPI *PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)(HGLRC dstCtx
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC