Skip to content

Latest commit

 

History

History
592 lines (507 loc) · 19.4 KB

SDL_xinputjoystick.c

File metadata and controls

592 lines (507 loc) · 19.4 KB
 
1
2
/*
Simple DirectMedia Layer
Jan 5, 2019
Jan 5, 2019
3
Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#include "../SDL_sysjoystick.h"
#if SDL_JOYSTICK_XINPUT
#include "SDL_assert.h"
#include "SDL_hints.h"
Nov 21, 2019
Nov 21, 2019
29
#include "SDL_log.h"
Aug 9, 2018
Aug 9, 2018
30
#include "SDL_timer.h"
31
32
#include "SDL_windowsjoystick_c.h"
#include "SDL_xinputjoystick_c.h"
Aug 9, 2018
Aug 9, 2018
33
#include "../hidapi/SDL_hidapijoystick_c.h"
34
35
36
37
38
/*
* Internal stuff.
*/
static SDL_bool s_bXInputEnabled = SDL_TRUE;
Feb 3, 2017
Feb 3, 2017
39
static char *s_arrXInputDevicePath[XUSER_MAX_COUNT];
40
41
42
43
44
static SDL_bool
SDL_XInputUseOldJoystickMapping()
{
Dec 10, 2016
Dec 10, 2016
45
46
#ifdef __WINRT__
/* TODO: remove this __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
Feb 21, 2018
Feb 21, 2018
47
48
/* FIXME: Why are Win8/10 different here? -flibit */
return (NTDDI_VERSION < NTDDI_WIN10);
Dec 10, 2016
Dec 10, 2016
49
#else
50
51
static int s_XInputUseOldJoystickMapping = -1;
if (s_XInputUseOldJoystickMapping < 0) {
Oct 8, 2016
Oct 8, 2016
52
s_XInputUseOldJoystickMapping = SDL_GetHintBoolean(SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING, SDL_FALSE);
53
54
}
return (s_XInputUseOldJoystickMapping > 0);
Dec 10, 2016
Dec 10, 2016
55
#endif
56
57
58
59
60
61
62
63
64
65
}
SDL_bool SDL_XINPUT_Enabled(void)
{
return s_bXInputEnabled;
}
int
SDL_XINPUT_JoystickInit(void)
{
Oct 8, 2016
Oct 8, 2016
66
s_bXInputEnabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE);
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
s_bXInputEnabled = SDL_FALSE; /* oh well. */
}
return 0;
}
static char *
GetXInputName(const Uint8 userid, BYTE SubType)
{
char name[32];
if (SDL_XInputUseOldJoystickMapping()) {
SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid);
} else {
switch (SubType) {
case XINPUT_DEVSUBTYPE_GAMEPAD:
SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid);
break;
case XINPUT_DEVSUBTYPE_WHEEL:
SDL_snprintf(name, sizeof(name), "XInput Wheel #%u", 1 + userid);
break;
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
SDL_snprintf(name, sizeof(name), "XInput ArcadeStick #%u", 1 + userid);
break;
case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
SDL_snprintf(name, sizeof(name), "XInput FlightStick #%u", 1 + userid);
break;
case XINPUT_DEVSUBTYPE_DANCE_PAD:
SDL_snprintf(name, sizeof(name), "XInput DancePad #%u", 1 + userid);
break;
case XINPUT_DEVSUBTYPE_GUITAR:
case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
case XINPUT_DEVSUBTYPE_GUITAR_BASS:
SDL_snprintf(name, sizeof(name), "XInput Guitar #%u", 1 + userid);
break;
case XINPUT_DEVSUBTYPE_DRUM_KIT:
SDL_snprintf(name, sizeof(name), "XInput DrumKit #%u", 1 + userid);
break;
case XINPUT_DEVSUBTYPE_ARCADE_PAD:
SDL_snprintf(name, sizeof(name), "XInput ArcadePad #%u", 1 + userid);
break;
default:
SDL_snprintf(name, sizeof(name), "XInput Device #%u", 1 + userid);
break;
}
}
return SDL_strdup(name);
}
Nov 24, 2016
Nov 24, 2016
117
118
119
120
/* We can't really tell what device is being used for XInput, but we can guess
and we'll be correct for the case where only one device is connected.
*/
static void
Feb 3, 2017
Feb 3, 2017
121
GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
Nov 24, 2016
Nov 24, 2016
122
{
Dec 10, 2016
Dec 10, 2016
123
124
#ifndef __WINRT__ /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
Nov 24, 2016
Nov 24, 2016
125
PRAWINPUTDEVICELIST devices = NULL;
Feb 3, 2017
Feb 3, 2017
126
UINT i, j, device_count = 0;
Nov 24, 2016
Nov 24, 2016
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!device_count)) {
return; /* oh well. */
}
devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count);
if (devices == NULL) {
return;
}
if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) {
SDL_free(devices);
return; /* oh well. */
}
Nov 21, 2019
Nov 21, 2019
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* First see if we have a cached entry for this index */
if (s_arrXInputDevicePath[userid]) {
for (i = 0; i < device_count; i++) {
RID_DEVICE_INFO rdi;
char devName[128];
UINT rdiSize = sizeof(rdi);
UINT nameSize = SDL_arraysize(devName);
rdi.cbSize = sizeof(rdi);
if (devices[i].dwType == RIM_TYPEHID &&
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
if (SDL_strcmp(devName, s_arrXInputDevicePath[userid]) == 0) {
*pVID = (Uint16)rdi.hid.dwVendorId;
*pPID = (Uint16)rdi.hid.dwProductId;
*pVersion = (Uint16)rdi.hid.dwVersionNumber;
return;
}
}
}
}
Nov 24, 2016
Nov 24, 2016
164
165
166
167
168
169
170
for (i = 0; i < device_count; i++) {
RID_DEVICE_INFO rdi;
char devName[128];
UINT rdiSize = sizeof(rdi);
UINT nameSize = SDL_arraysize(devName);
rdi.cbSize = sizeof(rdi);
Nov 21, 2019
Nov 21, 2019
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
if (devices[i].dwType == RIM_TYPEHID &&
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
#ifdef DEBUG_JOYSTICK
SDL_Log("Raw input device: VID = 0x%x, PID = 0x%x, %s\n", rdi.hid.dwVendorId, rdi.hid.dwProductId, devName);
#endif
if (SDL_strstr(devName, "IG_") != NULL) {
SDL_bool found = SDL_FALSE;
for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) {
if (!s_arrXInputDevicePath[j]) {
continue;
}
if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
found = SDL_TRUE;
break;
}
Feb 3, 2017
Feb 3, 2017
187
}
Nov 21, 2019
Nov 21, 2019
188
189
if (found) {
/* We already have this device in our XInput device list */
Feb 3, 2017
Feb 3, 2017
190
191
192
continue;
}
Nov 21, 2019
Nov 21, 2019
193
194
195
196
197
198
199
200
201
202
203
204
/* We don't actually know if this is the right device for this
* userid, but we'll record it so we'll at least be consistent
* when the raw device list changes.
*/
*pVID = (Uint16)rdi.hid.dwVendorId;
*pPID = (Uint16)rdi.hid.dwProductId;
*pVersion = (Uint16)rdi.hid.dwVersionNumber;
if (s_arrXInputDevicePath[userid]) {
SDL_free(s_arrXInputDevicePath[userid]);
}
s_arrXInputDevicePath[userid] = SDL_strdup(devName);
return;
Nov 24, 2016
Nov 24, 2016
205
206
207
208
}
}
}
SDL_free(devices);
Dec 10, 2016
Dec 10, 2016
209
#endif /* ifndef __WINRT__ */
Nov 21, 2019
Nov 21, 2019
210
211
212
213
214
/* The device wasn't in the raw HID device list, it's probably Bluetooth */
*pVID = 0x045e; /* Microsoft */
*pPID = 0x02fd; /* XBox One S Bluetooth */
*pVersion = 0;
Nov 24, 2016
Nov 24, 2016
215
216
}
Nov 24, 2016
Nov 24, 2016
218
AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
Aug 9, 2018
Aug 9, 2018
220
221
222
Uint16 vendor = 0;
Uint16 product = 0;
Uint16 version = 0;
Dec 12, 2019
Dec 12, 2019
223
const char *name;
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
JoyStick_DeviceData *pPrevJoystick = NULL;
JoyStick_DeviceData *pNewJoystick = *pContext;
if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
return;
if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN)
return;
while (pNewJoystick) {
if (pNewJoystick->bXInputDevice && (pNewJoystick->XInputUserId == userid) && (pNewJoystick->SubType == SubType)) {
/* if we are replacing the front of the list then update it */
if (pNewJoystick == *pContext) {
*pContext = pNewJoystick->pNext;
} else if (pPrevJoystick) {
pPrevJoystick->pNext = pNewJoystick->pNext;
}
pNewJoystick->pNext = SYS_Joystick;
SYS_Joystick = pNewJoystick;
return; /* already in the list. */
}
pPrevJoystick = pNewJoystick;
pNewJoystick = pNewJoystick->pNext;
}
Dec 12, 2019
Dec 12, 2019
251
pNewJoystick = (JoyStick_DeviceData *)SDL_calloc(1, sizeof(JoyStick_DeviceData));
252
253
254
255
256
if (!pNewJoystick) {
return; /* better luck next time? */
}
pNewJoystick->bXInputDevice = SDL_TRUE;
Dec 12, 2019
Dec 12, 2019
257
if (!SDL_XInputUseOldJoystickMapping()) {
Nov 24, 2016
Nov 24, 2016
258
259
260
261
Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data;
GuessXInputDevice(userid, &vendor, &product, &version);
Aug 9, 2018
Aug 9, 2018
262
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
Nov 24, 2016
Nov 24, 2016
263
264
265
266
267
268
269
270
271
272
273
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
/* Note that this is an XInput device and what subtype it is */
pNewJoystick->guid.data[14] = 'x';
pNewJoystick->guid.data[15] = SubType;
274
275
276
}
pNewJoystick->SubType = SubType;
pNewJoystick->XInputUserId = userid;
Aug 9, 2017
Aug 9, 2017
277
Dec 12, 2019
Dec 12, 2019
278
279
280
281
282
283
284
285
286
287
288
name = SDL_GetCustomJoystickName(vendor, product);
if (name) {
pNewJoystick->joystickname = SDL_strdup(name);
} else {
pNewJoystick->joystickname = GetXInputName(userid, SubType);
}
if (!pNewJoystick->joystickname) {
SDL_free(pNewJoystick);
return; /* better luck next time? */
}
Aug 9, 2018
Aug 9, 2018
289
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
Aug 9, 2017
Aug 9, 2017
290
291
292
293
SDL_free(pNewJoystick);
return;
}
Aug 9, 2018
Aug 9, 2018
294
#ifdef SDL_JOYSTICK_HIDAPI
Oct 22, 2019
Oct 22, 2019
295
if (HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) {
Aug 9, 2018
Aug 9, 2018
296
297
298
299
300
301
302
/* The HIDAPI driver is taking care of this device */
SDL_free(pNewJoystick);
return;
}
#endif
WINDOWS_AddJoystickDevice(pNewJoystick);
Aug 9, 2018
Aug 9, 2018
305
306
307
308
309
310
311
312
313
static void
DelXInputDevice(Uint8 userid)
{
if (s_arrXInputDevicePath[userid]) {
SDL_free(s_arrXInputDevicePath[userid]);
s_arrXInputDevicePath[userid] = NULL;
}
}
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
void
SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
{
int iuserid;
if (!s_bXInputEnabled) {
return;
}
/* iterate in reverse, so these are in the final list in ascending numeric order. */
for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
const Uint8 userid = (Uint8)iuserid;
XINPUT_CAPABILITIES capabilities;
if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
AddXInputDevice(userid, capabilities.SubType, pContext);
Aug 9, 2018
Aug 9, 2018
329
330
} else {
DelXInputDevice(userid);
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
}
}
}
int
SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
{
const Uint8 userId = joystickdevice->XInputUserId;
XINPUT_CAPABILITIES capabilities;
XINPUT_VIBRATION state;
SDL_assert(s_bXInputEnabled);
SDL_assert(XINPUTGETCAPABILITIES);
SDL_assert(XINPUTSETSTATE);
SDL_assert(userId < XUSER_MAX_COUNT);
Oct 25, 2018
Oct 25, 2018
347
348
joystick->player_index = userId;
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
joystick->hwdata->bXInputDevice = SDL_TRUE;
if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
SDL_free(joystick->hwdata);
joystick->hwdata = NULL;
return SDL_SetError("Failed to obtain XInput device capabilities. Device disconnected?");
}
SDL_zero(state);
joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS);
joystick->hwdata->userid = userId;
/* The XInput API has a hard coded button/axis mapping, so we just match it */
if (SDL_XInputUseOldJoystickMapping()) {
joystick->naxes = 6;
joystick->nbuttons = 15;
} else {
joystick->naxes = 6;
joystick->nbuttons = 11;
joystick->nhats = 1;
}
return 0;
}
Sep 30, 2015
Sep 30, 2015
372
static void
Nov 15, 2015
Nov 15, 2015
373
UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
Sep 30, 2015
Sep 30, 2015
374
{
Feb 3, 2017
Feb 3, 2017
375
if (pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN) {
Sep 30, 2015
Sep 30, 2015
376
377
378
379
SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN;
if (pBatteryInformation->BatteryType == BATTERY_TYPE_WIRED) {
ePowerLevel = SDL_JOYSTICK_POWER_WIRED;
} else {
Feb 3, 2017
Feb 3, 2017
380
switch (pBatteryInformation->BatteryLevel) {
Sep 30, 2015
Sep 30, 2015
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
case BATTERY_LEVEL_EMPTY:
ePowerLevel = SDL_JOYSTICK_POWER_EMPTY;
break;
case BATTERY_LEVEL_LOW:
ePowerLevel = SDL_JOYSTICK_POWER_LOW;
break;
case BATTERY_LEVEL_MEDIUM:
ePowerLevel = SDL_JOYSTICK_POWER_MEDIUM;
break;
default:
case BATTERY_LEVEL_FULL:
ePowerLevel = SDL_JOYSTICK_POWER_FULL;
break;
}
}
Feb 3, 2017
Feb 3, 2017
397
SDL_PrivateJoystickBatteryLevel(joystick, ePowerLevel);
Sep 30, 2015
Sep 30, 2015
398
399
400
}
}
Nov 15, 2015
Nov 15, 2015
402
UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
{
static WORD s_XInputButtons[] = {
XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT,
XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_GUIDE
};
WORD wButtons = pXInputState->Gamepad.wButtons;
Uint8 button;
SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX);
SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbLY)));
SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX);
SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbRY)));
SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger * 65535 / 255) - 32768));
SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger * 65535 / 255) - 32768));
for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) {
SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED);
}
Sep 30, 2015
Sep 30, 2015
424
Feb 3, 2017
Feb 3, 2017
425
UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
Nov 15, 2015
Nov 15, 2015
429
UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
430
431
432
433
434
435
436
437
438
439
440
{
static WORD s_XInputButtons[] = {
XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
XINPUT_GAMEPAD_GUIDE
};
WORD wButtons = pXInputState->Gamepad.wButtons;
Uint8 button;
Uint8 hat = SDL_HAT_CENTERED;
Aug 9, 2018
Aug 9, 2018
441
442
443
444
445
446
SDL_PrivateJoystickAxis(joystick, 0, pXInputState->Gamepad.sThumbLX);
SDL_PrivateJoystickAxis(joystick, 1, ~pXInputState->Gamepad.sThumbLY);
SDL_PrivateJoystickAxis(joystick, 2, ((int)pXInputState->Gamepad.bLeftTrigger * 257) - 32768);
SDL_PrivateJoystickAxis(joystick, 3, pXInputState->Gamepad.sThumbRX);
SDL_PrivateJoystickAxis(joystick, 4, ~pXInputState->Gamepad.sThumbRY);
SDL_PrivateJoystickAxis(joystick, 5, ((int)pXInputState->Gamepad.bRightTrigger * 257) - 32768);
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) {
SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED);
}
if (wButtons & XINPUT_GAMEPAD_DPAD_UP) {
hat |= SDL_HAT_UP;
}
if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
hat |= SDL_HAT_DOWN;
}
if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
hat |= SDL_HAT_LEFT;
}
if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
hat |= SDL_HAT_RIGHT;
}
SDL_PrivateJoystickHat(joystick, 0, hat);
Sep 30, 2015
Sep 30, 2015
465
Feb 3, 2017
Feb 3, 2017
466
UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
Aug 9, 2018
Aug 9, 2018
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
int
SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
XINPUT_VIBRATION XVibration;
if (!XINPUTSETSTATE) {
return SDL_Unsupported();
}
XVibration.wLeftMotorSpeed = low_frequency_rumble;
XVibration.wRightMotorSpeed = high_frequency_rumble;
if (XINPUTSETSTATE(joystick->hwdata->userid, &XVibration) != ERROR_SUCCESS) {
return SDL_SetError("XInputSetState() failed");
}
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
joystick->hwdata->rumble_expiration = SDL_GetTicks() + duration_ms;
} else {
joystick->hwdata->rumble_expiration = 0;
}
return 0;
}
492
493
494
495
496
void
SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
{
HRESULT result;
XINPUT_STATE_EX XInputState;
Nov 15, 2015
Nov 15, 2015
497
XINPUT_BATTERY_INFORMATION_EX XBatteryInformation;
498
499
500
501
502
503
504
505
506
if (!XINPUTGETSTATE)
return;
result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
if (result == ERROR_DEVICE_NOT_CONNECTED) {
return;
}
Feb 3, 2017
Feb 3, 2017
507
508
509
SDL_zero(XBatteryInformation);
if (XINPUTGETBATTERYINFORMATION) {
result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation);
Sep 30, 2015
Sep 30, 2015
510
511
}
512
513
514
/* only fire events if the data changed from last time */
if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
if (SDL_XInputUseOldJoystickMapping()) {
Sep 30, 2015
Sep 30, 2015
515
UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation);
Sep 30, 2015
Sep 30, 2015
517
UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
518
519
520
}
joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
}
Aug 9, 2018
Aug 9, 2018
521
522
523
524
525
526
527
if (joystick->hwdata->rumble_expiration) {
Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, joystick->hwdata->rumble_expiration)) {
SDL_XINPUT_JoystickRumble(joystick, 0, 0, 0);
}
}
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
}
void
SDL_XINPUT_JoystickClose(SDL_Joystick * joystick)
{
}
void
SDL_XINPUT_JoystickQuit(void)
{
if (s_bXInputEnabled) {
WIN_UnloadXInputDLL();
}
}
#else /* !SDL_JOYSTICK_XINPUT */
typedef struct JoyStick_DeviceData JoyStick_DeviceData;
SDL_bool SDL_XINPUT_Enabled(void)
{
return SDL_FALSE;
}
int
SDL_XINPUT_JoystickInit(void)
{
return 0;
}
void
SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
{
}
int
SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
{
return SDL_Unsupported();
}
Aug 9, 2018
Aug 9, 2018
569
570
571
572
573
574
int
SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{
return SDL_Unsupported();
}
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
void
SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
{
}
void
SDL_XINPUT_JoystickClose(SDL_Joystick * joystick)
{
}
void
SDL_XINPUT_JoystickQuit(void)
{
}
#endif /* SDL_JOYSTICK_XINPUT */
/* vi: set ts=4 sw=4 expandtab: */