SDL  2.0
SDL_xinputjoystick.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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_XINPUT
26 
27 #include "SDL_hints.h"
28 #include "SDL_timer.h"
29 #include "SDL_windowsjoystick_c.h"
30 #include "SDL_xinputjoystick_c.h"
31 #include "SDL_rawinputjoystick_c.h"
32 #include "../hidapi/SDL_hidapijoystick_c.h"
33 
34 /*
35  * Internal stuff.
36  */
37 static SDL_bool s_bXInputEnabled = SDL_TRUE;
38 static char *s_arrXInputDevicePath[XUSER_MAX_COUNT];
39 
40 
41 static SDL_bool
42 SDL_XInputUseOldJoystickMapping()
43 {
44 #ifdef __WINRT__
45  /* TODO: remove this __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
46  /* FIXME: Why are Win8/10 different here? -flibit */
47  return (NTDDI_VERSION < NTDDI_WIN10);
48 #else
49  static int s_XInputUseOldJoystickMapping = -1;
50  if (s_XInputUseOldJoystickMapping < 0) {
52  }
53  return (s_XInputUseOldJoystickMapping > 0);
54 #endif
55 }
56 
58 {
59  return s_bXInputEnabled;
60 }
61 
62 int
64 {
66 
67 #ifdef SDL_JOYSTICK_RAWINPUT
68  if (RAWINPUT_IsEnabled()) {
69  /* The raw input driver handles more than 4 controllers, so prefer that when available */
70  s_bXInputEnabled = SDL_FALSE;
71  }
72 #endif
73 
74  if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
75  s_bXInputEnabled = SDL_FALSE; /* oh well. */
76  }
77  return 0;
78 }
79 
80 static const char *
81 GetXInputName(const Uint8 userid, BYTE SubType)
82 {
83  static char name[32];
84 
85  if (SDL_XInputUseOldJoystickMapping()) {
86  SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid);
87  } else {
88  switch (SubType) {
89  case XINPUT_DEVSUBTYPE_GAMEPAD:
90  SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid);
91  break;
92  case XINPUT_DEVSUBTYPE_WHEEL:
93  SDL_snprintf(name, sizeof(name), "XInput Wheel #%u", 1 + userid);
94  break;
95  case XINPUT_DEVSUBTYPE_ARCADE_STICK:
96  SDL_snprintf(name, sizeof(name), "XInput ArcadeStick #%u", 1 + userid);
97  break;
98  case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
99  SDL_snprintf(name, sizeof(name), "XInput FlightStick #%u", 1 + userid);
100  break;
101  case XINPUT_DEVSUBTYPE_DANCE_PAD:
102  SDL_snprintf(name, sizeof(name), "XInput DancePad #%u", 1 + userid);
103  break;
104  case XINPUT_DEVSUBTYPE_GUITAR:
105  case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE:
106  case XINPUT_DEVSUBTYPE_GUITAR_BASS:
107  SDL_snprintf(name, sizeof(name), "XInput Guitar #%u", 1 + userid);
108  break;
109  case XINPUT_DEVSUBTYPE_DRUM_KIT:
110  SDL_snprintf(name, sizeof(name), "XInput DrumKit #%u", 1 + userid);
111  break;
112  case XINPUT_DEVSUBTYPE_ARCADE_PAD:
113  SDL_snprintf(name, sizeof(name), "XInput ArcadePad #%u", 1 + userid);
114  break;
115  default:
116  SDL_snprintf(name, sizeof(name), "XInput Device #%u", 1 + userid);
117  break;
118  }
119  }
120  return name;
121 }
122 
123 /* We can't really tell what device is being used for XInput, but we can guess
124  and we'll be correct for the case where only one device is connected.
125  */
126 static void
127 GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
128 {
129 #ifndef __WINRT__ /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */
130 
131  PRAWINPUTDEVICELIST devices = NULL;
132  UINT i, j, device_count = 0;
133 
134  if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!device_count)) {
135  return; /* oh well. */
136  }
137 
138  devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count);
139  if (devices == NULL) {
140  return;
141  }
142 
143  if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) {
144  SDL_free(devices);
145  return; /* oh well. */
146  }
147 
148  /* First see if we have a cached entry for this index */
149  if (s_arrXInputDevicePath[userid]) {
150  for (i = 0; i < device_count; i++) {
151  RID_DEVICE_INFO rdi;
152  char devName[128];
153  UINT rdiSize = sizeof(rdi);
154  UINT nameSize = SDL_arraysize(devName);
155 
156  rdi.cbSize = sizeof(rdi);
157  if (devices[i].dwType == RIM_TYPEHID &&
158  GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
159  GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
160  if (SDL_strcmp(devName, s_arrXInputDevicePath[userid]) == 0) {
161  *pVID = (Uint16)rdi.hid.dwVendorId;
162  *pPID = (Uint16)rdi.hid.dwProductId;
163  *pVersion = (Uint16)rdi.hid.dwVersionNumber;
164  SDL_free(devices);
165  return;
166  }
167  }
168  }
169  }
170 
171  for (i = 0; i < device_count; i++) {
172  RID_DEVICE_INFO rdi;
173  char devName[MAX_PATH];
174  UINT rdiSize = sizeof(rdi);
175  UINT nameSize = SDL_arraysize(devName);
176 
177  rdi.cbSize = sizeof(rdi);
178  if (devices[i].dwType == RIM_TYPEHID &&
179  GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
180  GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
181 #ifdef DEBUG_JOYSTICK
182  SDL_Log("Raw input device: VID = 0x%x, PID = 0x%x, %s\n", rdi.hid.dwVendorId, rdi.hid.dwProductId, devName);
183 #endif
184  if (SDL_strstr(devName, "IG_") != NULL) {
185  SDL_bool found = SDL_FALSE;
186  for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) {
187  if (!s_arrXInputDevicePath[j]) {
188  continue;
189  }
190  if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
191  found = SDL_TRUE;
192  break;
193  }
194  }
195  if (found) {
196  /* We already have this device in our XInput device list */
197  continue;
198  }
199 
200  /* We don't actually know if this is the right device for this
201  * userid, but we'll record it so we'll at least be consistent
202  * when the raw device list changes.
203  */
204  *pVID = (Uint16)rdi.hid.dwVendorId;
205  *pPID = (Uint16)rdi.hid.dwProductId;
206  *pVersion = (Uint16)rdi.hid.dwVersionNumber;
207  if (s_arrXInputDevicePath[userid]) {
208  SDL_free(s_arrXInputDevicePath[userid]);
209  }
210  s_arrXInputDevicePath[userid] = SDL_strdup(devName);
211  SDL_free(devices);
212  return;
213  }
214  }
215  }
216  SDL_free(devices);
217 #endif /* !__WINRT__ */
218 
219  /* The device wasn't in the raw HID device list, it's probably Bluetooth */
220  *pVID = 0x045e; /* Microsoft */
221  *pPID = 0x02fd; /* XBox One S Bluetooth */
222  *pVersion = 0;
223 }
224 
225 static void
226 AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
227 {
228  Uint16 vendor = 0;
229  Uint16 product = 0;
230  Uint16 version = 0;
231  JoyStick_DeviceData *pPrevJoystick = NULL;
232  JoyStick_DeviceData *pNewJoystick = *pContext;
233 
234  if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD)
235  return;
236 
237  if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN)
238  return;
239 
240  while (pNewJoystick) {
241  if (pNewJoystick->bXInputDevice && (pNewJoystick->XInputUserId == userid) && (pNewJoystick->SubType == SubType)) {
242  /* if we are replacing the front of the list then update it */
243  if (pNewJoystick == *pContext) {
244  *pContext = pNewJoystick->pNext;
245  } else if (pPrevJoystick) {
246  pPrevJoystick->pNext = pNewJoystick->pNext;
247  }
248 
249  pNewJoystick->pNext = SYS_Joystick;
250  SYS_Joystick = pNewJoystick;
251  return; /* already in the list. */
252  }
253 
254  pPrevJoystick = pNewJoystick;
255  pNewJoystick = pNewJoystick->pNext;
256  }
257 
258  pNewJoystick = (JoyStick_DeviceData *)SDL_calloc(1, sizeof(JoyStick_DeviceData));
259  if (!pNewJoystick) {
260  return; /* better luck next time? */
261  }
262 
263  pNewJoystick->bXInputDevice = SDL_TRUE;
264  if (!SDL_XInputUseOldJoystickMapping()) {
265  Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data;
266 
267  GuessXInputDevice(userid, &vendor, &product, &version);
268 
269  *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
270  *guid16++ = 0;
271  *guid16++ = SDL_SwapLE16(vendor);
272  *guid16++ = 0;
273  *guid16++ = SDL_SwapLE16(product);
274  *guid16++ = 0;
275  *guid16++ = SDL_SwapLE16(version);
276  *guid16++ = 0;
277 
278  /* Note that this is an XInput device and what subtype it is */
279  pNewJoystick->guid.data[14] = 'x';
280  pNewJoystick->guid.data[15] = SubType;
281  }
282  pNewJoystick->SubType = SubType;
283  pNewJoystick->XInputUserId = userid;
284  pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, GetXInputName(userid, SubType));
285  if (!pNewJoystick->joystickname) {
286  SDL_free(pNewJoystick);
287  return; /* better luck next time? */
288  }
289 
290  if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
291  SDL_free(pNewJoystick);
292  return;
293  }
294 
295 #ifdef SDL_JOYSTICK_HIDAPI
296  /* Since we're guessing about the VID/PID, use a hard-coded VID/PID to represent XInput */
298  /* The HIDAPI driver is taking care of this device */
299  SDL_free(pNewJoystick);
300  return;
301  }
302 #endif
303 
304 #ifdef SDL_JOYSTICK_RAWINPUT
305  if (RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) {
306  /* The RAWINPUT driver is taking care of this device */
307  SDL_free(pNewJoystick);
308  return;
309  }
310 #endif
311 
312  WINDOWS_AddJoystickDevice(pNewJoystick);
313 }
314 
315 static void
316 DelXInputDevice(Uint8 userid)
317 {
318  if (s_arrXInputDevicePath[userid]) {
319  SDL_free(s_arrXInputDevicePath[userid]);
320  s_arrXInputDevicePath[userid] = NULL;
321  }
322 }
323 
324 void
326 {
327  int iuserid;
328 
329  if (!s_bXInputEnabled) {
330  return;
331  }
332 
333  /* iterate in reverse, so these are in the final list in ascending numeric order. */
334  for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
335  const Uint8 userid = (Uint8)iuserid;
336  XINPUT_CAPABILITIES capabilities;
337  if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) {
338  /* Adding a new device, must handle all removes first, or GuessXInputDevice goes terribly wrong (returns
339  a product/vendor ID that is not even attached to the system) when we get a remove and add on the same tick
340  (e.g. when disconnecting a device and the OS reassigns which userid an already-attached controller is)
341  */
342  int iuserid2;
343  for (iuserid2 = iuserid - 1; iuserid2 >= 0; iuserid2--) {
344  const Uint8 userid2 = (Uint8)iuserid2;
345  XINPUT_CAPABILITIES capabilities2;
346  if (XINPUTGETCAPABILITIES(userid2, XINPUT_FLAG_GAMEPAD, &capabilities2) != ERROR_SUCCESS) {
347  DelXInputDevice(userid2);
348  }
349  }
350  AddXInputDevice(userid, capabilities.SubType, pContext);
351  } else {
352  DelXInputDevice(userid);
353  }
354  }
355 }
356 
357 int
358 SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
359 {
360  const Uint8 userId = joystickdevice->XInputUserId;
361  XINPUT_CAPABILITIES capabilities;
362  XINPUT_VIBRATION state;
363 
364  SDL_assert(s_bXInputEnabled);
365  SDL_assert(XINPUTGETCAPABILITIES);
366  SDL_assert(XINPUTSETSTATE);
367  SDL_assert(userId < XUSER_MAX_COUNT);
368 
369  joystick->hwdata->bXInputDevice = SDL_TRUE;
370 
371  if (XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities) != ERROR_SUCCESS) {
372  SDL_free(joystick->hwdata);
373  joystick->hwdata = NULL;
374  return SDL_SetError("Failed to obtain XInput device capabilities. Device disconnected?");
375  }
376  SDL_zero(state);
377  joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS);
378  joystick->hwdata->userid = userId;
379 
380  /* The XInput API has a hard coded button/axis mapping, so we just match it */
381  if (SDL_XInputUseOldJoystickMapping()) {
382  joystick->naxes = 6;
383  joystick->nbuttons = 15;
384  } else {
385  joystick->naxes = 6;
386  joystick->nbuttons = 11;
387  joystick->nhats = 1;
388  }
389  return 0;
390 }
391 
392 static void
393 UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
394 {
395  if (pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN) {
397  if (pBatteryInformation->BatteryType == BATTERY_TYPE_WIRED) {
398  ePowerLevel = SDL_JOYSTICK_POWER_WIRED;
399  } else {
400  switch (pBatteryInformation->BatteryLevel) {
401  case BATTERY_LEVEL_EMPTY:
402  ePowerLevel = SDL_JOYSTICK_POWER_EMPTY;
403  break;
404  case BATTERY_LEVEL_LOW:
405  ePowerLevel = SDL_JOYSTICK_POWER_LOW;
406  break;
407  case BATTERY_LEVEL_MEDIUM:
408  ePowerLevel = SDL_JOYSTICK_POWER_MEDIUM;
409  break;
410  default:
411  case BATTERY_LEVEL_FULL:
412  ePowerLevel = SDL_JOYSTICK_POWER_FULL;
413  break;
414  }
415  }
416 
418  }
419 }
420 
421 static void
422 UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
423 {
424  static WORD s_XInputButtons[] = {
425  XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT,
426  XINPUT_GAMEPAD_START, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
427  XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER,
428  XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
429  XINPUT_GAMEPAD_GUIDE
430  };
431  WORD wButtons = pXInputState->Gamepad.wButtons;
432  Uint8 button;
433 
434  SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX);
435  SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbLY)));
436  SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX);
437  SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-SDL_max(-32767, pXInputState->Gamepad.sThumbRY)));
438  SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger * 65535 / 255) - 32768));
439  SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger * 65535 / 255) - 32768));
440 
441  for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) {
442  SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED);
443  }
444 
445  UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
446 }
447 
448 static void
449 UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation)
450 {
451  static WORD s_XInputButtons[] = {
452  XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y,
453  XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_START,
454  XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB,
455  XINPUT_GAMEPAD_GUIDE
456  };
457  WORD wButtons = pXInputState->Gamepad.wButtons;
458  Uint8 button;
459  Uint8 hat = SDL_HAT_CENTERED;
460 
461  SDL_PrivateJoystickAxis(joystick, 0, pXInputState->Gamepad.sThumbLX);
462  SDL_PrivateJoystickAxis(joystick, 1, ~pXInputState->Gamepad.sThumbLY);
463  SDL_PrivateJoystickAxis(joystick, 2, ((int)pXInputState->Gamepad.bLeftTrigger * 257) - 32768);
464  SDL_PrivateJoystickAxis(joystick, 3, pXInputState->Gamepad.sThumbRX);
465  SDL_PrivateJoystickAxis(joystick, 4, ~pXInputState->Gamepad.sThumbRY);
466  SDL_PrivateJoystickAxis(joystick, 5, ((int)pXInputState->Gamepad.bRightTrigger * 257) - 32768);
467 
468  for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) {
469  SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED);
470  }
471 
472  if (wButtons & XINPUT_GAMEPAD_DPAD_UP) {
473  hat |= SDL_HAT_UP;
474  }
475  if (wButtons & XINPUT_GAMEPAD_DPAD_DOWN) {
476  hat |= SDL_HAT_DOWN;
477  }
478  if (wButtons & XINPUT_GAMEPAD_DPAD_LEFT) {
479  hat |= SDL_HAT_LEFT;
480  }
481  if (wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) {
482  hat |= SDL_HAT_RIGHT;
483  }
485 
486  UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation);
487 }
488 
489 int
490 SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
491 {
492  XINPUT_VIBRATION XVibration;
493 
494  if (!XINPUTSETSTATE) {
495  return SDL_Unsupported();
496  }
497 
498  XVibration.wLeftMotorSpeed = low_frequency_rumble;
499  XVibration.wRightMotorSpeed = high_frequency_rumble;
500  if (XINPUTSETSTATE(joystick->hwdata->userid, &XVibration) != ERROR_SUCCESS) {
501  return SDL_SetError("XInputSetState() failed");
502  }
503  return 0;
504 }
505 
506 void
507 SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick)
508 {
509  HRESULT result;
510  XINPUT_STATE_EX XInputState;
511  XINPUT_BATTERY_INFORMATION_EX XBatteryInformation;
512 
513  if (!XINPUTGETSTATE)
514  return;
515 
516  result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState);
517  if (result == ERROR_DEVICE_NOT_CONNECTED) {
518  return;
519  }
520 
521  SDL_zero(XBatteryInformation);
522  if (XINPUTGETBATTERYINFORMATION) {
523  result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation);
524  }
525 
526  /* only fire events if the data changed from last time */
527  if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) {
528  if (SDL_XInputUseOldJoystickMapping()) {
529  UpdateXInputJoystickState_OLD(joystick, &XInputState, &XBatteryInformation);
530  } else {
531  UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation);
532  }
533  joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber;
534  }
535 }
536 
537 void
538 SDL_XINPUT_JoystickClose(SDL_Joystick * joystick)
539 {
540 }
541 
542 void
544 {
545  if (s_bXInputEnabled) {
546  WIN_UnloadXInputDLL();
547  }
548 }
549 
550 #else /* !SDL_JOYSTICK_XINPUT */
551 
553 
555 {
556  return SDL_FALSE;
557 }
558 
559 int
561 {
562  return 0;
563 }
564 
565 void
567 {
568 }
569 
570 int
571 SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice)
572 {
573  return SDL_Unsupported();
574 }
575 
576 int
577 SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
578 {
579  return SDL_Unsupported();
580 }
581 
582 void
584 {
585 }
586 
587 void
589 {
590 }
591 
592 void
594 {
595 }
596 
597 #endif /* SDL_JOYSTICK_XINPUT */
598 
599 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_assert(condition)
Definition: SDL_assert.h:171
#define NTDDI_WIN10
#define SDL_SetError
#define SDL_malloc
#define SDL_free
#define SDL_strdup
#define SDL_strcmp
#define SDL_strstr
#define SDL_GetHintBoolean
#define SDL_Log
#define SDL_snprintf
#define SDL_calloc
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:235
#define SDL_Unsupported()
Definition: SDL_error.h:89
#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, const char *name)
#define SDL_HINT_XINPUT_ENABLED
A variable that lets you disable the detection and use of Xinput gamepad devices.
Definition: SDL_hints.h:473
#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING
A variable that causes SDL to use the old axis and button mapping for XInput devices.
Definition: SDL_hints.h:482
void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel)
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
char * SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
SDL_JoystickPowerLevel
Definition: SDL_joystick.h:98
@ SDL_JOYSTICK_POWER_FULL
Definition: SDL_joystick.h:103
@ SDL_JOYSTICK_POWER_MEDIUM
Definition: SDL_joystick.h:102
@ SDL_JOYSTICK_POWER_EMPTY
Definition: SDL_joystick.h:100
@ SDL_JOYSTICK_POWER_UNKNOWN
Definition: SDL_joystick.h:99
@ SDL_JOYSTICK_POWER_WIRED
Definition: SDL_joystick.h:104
@ SDL_JOYSTICK_POWER_LOW
Definition: SDL_joystick.h:101
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:390
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:388
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:389
#define SDL_HAT_UP
Definition: SDL_joystick.h:387
#define SDL_HAT_CENTERED
Definition: SDL_joystick.h:386
GLuint64EXT * result
GLuint const GLchar * name
SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
SDL_bool RAWINPUT_IsEnabled()
uint16_t Uint16
Definition: SDL_stdinc.h:197
int16_t Sint16
Definition: SDL_stdinc.h:191
#define SDL_zero(x)
Definition: SDL_stdinc.h:426
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:121
uint8_t Uint8
Definition: SDL_stdinc.h:185
#define SDL_max(x, y)
Definition: SDL_stdinc.h:413
#define SDL_HARDWARE_BUS_USB
struct xkb_state * state
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
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 in i)
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 int in j)
Definition: SDL_x11sym.h:50
int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice)
int SDL_XINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
void SDL_XINPUT_JoystickQuit(void)
void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
void SDL_XINPUT_JoystickClose(SDL_Joystick *joystick)
SDL_bool SDL_XINPUT_Enabled(void)
void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick)
int SDL_XINPUT_JoystickInit(void)
#define NULL
Definition: begin_code.h:163
EGLDeviceEXT * devices
Definition: eglext.h:621
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
struct JoyStick_DeviceData * pNext
Uint8 data[16]
Definition: SDL_joystick.h:71
SDL_Texture * button
static SDL_Joystick * joystick
Definition: testjoystick.c:37
#define USB_VENDOR_MICROSOFT
Definition: usb_ids.h:29
#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER
Definition: usb_ids.h:56