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