SDL  2.0
SDL_gamecontroller.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 /* This is the game controller API for Simple DirectMedia Layer */
24 
25 #include "SDL_events.h"
26 #include "SDL_assert.h"
27 #include "SDL_hints.h"
28 #include "SDL_timer.h"
29 #include "SDL_sysjoystick.h"
30 #include "SDL_joystick_c.h"
31 #include "SDL_gamecontrollerdb.h"
32 
33 #if !SDL_EVENTS_DISABLED
34 #include "../events/SDL_events_c.h"
35 #endif
36 
37 #if defined(__ANDROID__)
38 #include "SDL_system.h"
39 #endif
40 
41 
42 /* Many controllers turn the center button into an instantaneous button press */
43 #define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS 250
44 
45 #define SDL_CONTROLLER_PLATFORM_FIELD "platform:"
46 
47 /* a list of currently opened game controllers */
48 static SDL_GameController *SDL_gamecontrollers = NULL;
49 
50 typedef struct
51 {
53  union
54  {
55  int button;
56 
57  struct {
58  int axis;
59  int axis_min;
60  int axis_max;
61  } axis;
62 
63  struct {
64  int hat;
65  int hat_mask;
66  } hat;
67 
68  } input;
69 
71  union
72  {
74 
75  struct {
77  int axis_min;
78  int axis_max;
79  } axis;
80 
81  } output;
82 
84 
85 /* our hard coded list of mapping support */
86 typedef enum
87 {
92 
93 typedef struct _ControllerMapping_t
94 {
96  char *name;
97  char *mapping;
99  struct _ControllerMapping_t *next;
101 
107 
108 /* The SDL game controller structure */
110 {
111  SDL_Joystick *joystick; /* underlying joystick device */
113 
114  const char *name;
120 
121  struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
122 };
123 
124 
125 typedef struct
126 {
131 
134 
135 static void
137 {
138  Uint32 entry;
139  char *spot;
140  char *file = NULL;
141 
142  list->num_entries = 0;
143 
144  if (hint && *hint == '@') {
145  spot = file = (char *)SDL_LoadFile(hint+1, NULL);
146  } else {
147  spot = (char *)hint;
148  }
149 
150  if (!spot) {
151  return;
152  }
153 
154  while ((spot = SDL_strstr(spot, "0x")) != NULL) {
155  entry = (Uint16)SDL_strtol(spot, &spot, 0);
156  entry <<= 16;
157  spot = SDL_strstr(spot, "0x");
158  if (!spot) {
159  break;
160  }
161  entry |= (Uint16)SDL_strtol(spot, &spot, 0);
162 
163  if (list->num_entries == list->max_entries) {
164  int max_entries = list->max_entries + 16;
165  Uint32 *entries = (Uint32 *)SDL_realloc(list->entries, max_entries*sizeof(*list->entries));
166  if (entries == NULL) {
167  /* Out of memory, go with what we have already */
168  break;
169  }
170  list->entries = entries;
171  list->max_entries = max_entries;
172  }
173  list->entries[list->num_entries++] = entry;
174  }
175 
176  if (file) {
177  SDL_free(file);
178  }
179 }
180 
181 static void SDLCALL
182 SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
183 {
185 }
186 
187 static void SDLCALL
188 SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
189 {
191 }
192 
193 static int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
194 static int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
195 
196 /*
197  * If there is an existing add event in the queue, it needs to be modified
198  * to have the right value for which, because the number of controllers in
199  * the system is now one less.
200  */
202 {
203  int i, num_events;
204  SDL_Event *events;
205 
207  if (num_events <= 0) {
208  return;
209  }
210 
211  events = SDL_stack_alloc(SDL_Event, num_events);
212  if (!events) {
213  return;
214  }
215 
217  for (i = 0; i < num_events; ++i) {
218  --events[i].cdevice.which;
219  }
220  SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
221 
223 }
224 
226 {
227  if (a->outputType != b->outputType) {
228  return SDL_FALSE;
229  }
230 
231  if (a->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
232  return (a->output.axis.axis == b->output.axis.axis);
233  } else {
234  return (a->output.button == b->output.button);
235  }
236 }
237 
238 static void ResetOutput(SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind)
239 {
241  SDL_PrivateGameControllerAxis(gamecontroller, bind->output.axis.axis, 0);
242  } else {
244  }
245 }
246 
247 static void HandleJoystickAxis(SDL_GameController *gamecontroller, int axis, int value)
248 {
249  int i;
250  SDL_ExtendedGameControllerBind *last_match = gamecontroller->last_match_axis[axis];
252 
253  for (i = 0; i < gamecontroller->num_bindings; ++i) {
254  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
255  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
256  axis == binding->input.axis.axis) {
257  if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
258  if (value >= binding->input.axis.axis_min &&
259  value <= binding->input.axis.axis_max) {
260  match = binding;
261  break;
262  }
263  } else {
264  if (value >= binding->input.axis.axis_max &&
265  value <= binding->input.axis.axis_min) {
266  match = binding;
267  break;
268  }
269  }
270  }
271  }
272 
273  if (last_match && (!match || !HasSameOutput(last_match, match))) {
274  /* Clear the last input that this axis generated */
275  ResetOutput(gamecontroller, last_match);
276  }
277 
278  if (match) {
280  if (match->input.axis.axis_min != match->output.axis.axis_min || match->input.axis.axis_max != match->output.axis.axis_max) {
281  float normalized_value = (float)(value - match->input.axis.axis_min) / (match->input.axis.axis_max - match->input.axis.axis_min);
282  value = match->output.axis.axis_min + (int)(normalized_value * (match->output.axis.axis_max - match->output.axis.axis_min));
283  }
284  SDL_PrivateGameControllerAxis(gamecontroller, match->output.axis.axis, (Sint16)value);
285  } else {
286  Uint8 state;
287  int threshold = match->input.axis.axis_min + (match->input.axis.axis_max - match->input.axis.axis_min) / 2;
288  if (match->input.axis.axis_max < match->input.axis.axis_min) {
289  state = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
290  } else {
291  state = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
292  }
293  SDL_PrivateGameControllerButton(gamecontroller, match->output.button, state);
294  }
295  }
296  gamecontroller->last_match_axis[axis] = match;
297 }
298 
299 static void HandleJoystickButton(SDL_GameController *gamecontroller, int button, Uint8 state)
300 {
301  int i;
302 
303  for (i = 0; i < gamecontroller->num_bindings; ++i) {
304  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
305  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON &&
306  button == binding->input.button) {
307  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
308  int value = state ? binding->output.axis.axis_max : binding->output.axis.axis_min;
309  SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)value);
310  } else {
311  SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, state);
312  }
313  break;
314  }
315  }
316 }
317 
318 static void HandleJoystickHat(SDL_GameController *gamecontroller, int hat, Uint8 value)
319 {
320  int i;
321  Uint8 last_mask = gamecontroller->last_hat_mask[hat];
322  Uint8 changed_mask = (last_mask ^ value);
323 
324  for (i = 0; i < gamecontroller->num_bindings; ++i) {
325  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
326  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT && hat == binding->input.hat.hat) {
327  if ((changed_mask & binding->input.hat.hat_mask) != 0) {
328  if (value & binding->input.hat.hat_mask) {
329  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
330  SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)binding->output.axis.axis_max);
331  } else {
332  SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, SDL_PRESSED);
333  }
334  } else {
335  ResetOutput(gamecontroller, binding);
336  }
337  }
338  }
339  }
340  gamecontroller->last_hat_mask[hat] = value;
341 }
342 
343 /*
344  * Event filter to fire controller events from joystick ones
345  */
347 {
348  switch(event->type) {
349  case SDL_JOYAXISMOTION:
350  {
351  SDL_GameController *controllerlist = SDL_gamecontrollers;
352  while (controllerlist) {
353  if (controllerlist->joystick->instance_id == event->jaxis.which) {
354  HandleJoystickAxis(controllerlist, event->jaxis.axis, event->jaxis.value);
355  break;
356  }
357  controllerlist = controllerlist->next;
358  }
359  }
360  break;
361  case SDL_JOYBUTTONDOWN:
362  case SDL_JOYBUTTONUP:
363  {
364  SDL_GameController *controllerlist = SDL_gamecontrollers;
365  while (controllerlist) {
366  if (controllerlist->joystick->instance_id == event->jbutton.which) {
367  HandleJoystickButton(controllerlist, event->jbutton.button, event->jbutton.state);
368  break;
369  }
370  controllerlist = controllerlist->next;
371  }
372  }
373  break;
374  case SDL_JOYHATMOTION:
375  {
376  SDL_GameController *controllerlist = SDL_gamecontrollers;
377  while (controllerlist) {
378  if (controllerlist->joystick->instance_id == event->jhat.which) {
379  HandleJoystickHat(controllerlist, event->jhat.hat, event->jhat.value);
380  break;
381  }
382  controllerlist = controllerlist->next;
383  }
384  }
385  break;
386  case SDL_JOYDEVICEADDED:
387  {
388  if (SDL_IsGameController(event->jdevice.which)) {
389  SDL_Event deviceevent;
390  deviceevent.type = SDL_CONTROLLERDEVICEADDED;
391  deviceevent.cdevice.which = event->jdevice.which;
392  SDL_PushEvent(&deviceevent);
393  }
394  }
395  break;
397  {
398  SDL_GameController *controllerlist = SDL_gamecontrollers;
399  while (controllerlist) {
400  if (controllerlist->joystick->instance_id == event->jdevice.which) {
401  SDL_Event deviceevent;
402 
403  deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
404  deviceevent.cdevice.which = event->jdevice.which;
405  SDL_PushEvent(&deviceevent);
406 
408  break;
409  }
410  controllerlist = controllerlist->next;
411  }
412  }
413  break;
414  default:
415  break;
416  }
417 
418  return 1;
419 }
420 
421 /*
422  * Helper function to scan the mappings database for a controller with the specified GUID
423  */
425 {
426  ControllerMapping_t *pSupportedController = s_pSupportedControllers;
427  while (pSupportedController) {
428  if (SDL_memcmp(guid, &pSupportedController->guid, sizeof(*guid)) == 0) {
429  return pSupportedController;
430  }
431  pSupportedController = pSupportedController->next;
432  }
433  if (!exact_match) {
434  if (SDL_IsJoystickHIDAPI(*guid)) {
435  /* This is a HIDAPI device */
436  return s_pHIDAPIMapping;
437  }
438 #if SDL_JOYSTICK_XINPUT
439  if (SDL_IsJoystickXInput(*guid)) {
440  /* This is an XInput device */
441  return s_pXInputMapping;
442  }
443 #endif
444  }
445  return NULL;
446 }
447 
448 static const char* map_StringForControllerAxis[] = {
449  "leftx",
450  "lefty",
451  "rightx",
452  "righty",
453  "lefttrigger",
454  "righttrigger",
455  NULL
456 };
457 
458 /*
459  * convert a string to its enum equivalent
460  */
462 {
463  int entry;
464 
465  if (pchString && (*pchString == '+' || *pchString == '-')) {
466  ++pchString;
467  }
468 
469  if (!pchString || !pchString[0]) {
471  }
472 
473  for (entry = 0; map_StringForControllerAxis[entry]; ++entry) {
474  if (!SDL_strcasecmp(pchString, map_StringForControllerAxis[entry]))
475  return (SDL_GameControllerAxis) entry;
476  }
478 }
479 
480 /*
481  * convert an enum to its string equivalent
482  */
484 {
487  }
488  return NULL;
489 }
490 
491 static const char* map_StringForControllerButton[] = {
492  "a",
493  "b",
494  "x",
495  "y",
496  "back",
497  "guide",
498  "start",
499  "leftstick",
500  "rightstick",
501  "leftshoulder",
502  "rightshoulder",
503  "dpup",
504  "dpdown",
505  "dpleft",
506  "dpright",
507  NULL
508 };
509 
510 /*
511  * convert a string to its enum equivalent
512  */
514 {
515  int entry;
516  if (!pchString || !pchString[0])
518 
519  for (entry = 0; map_StringForControllerButton[entry]; ++entry) {
520  if (SDL_strcasecmp(pchString, map_StringForControllerButton[entry]) == 0)
521  return (SDL_GameControllerButton) entry;
522  }
524 }
525 
526 /*
527  * convert an enum to its string equivalent
528  */
530 {
533  }
534  return NULL;
535 }
536 
537 /*
538  * given a controller button name and a joystick name update our mapping structure with it
539  */
540 static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontroller, const char *szGameButton, const char *szJoystickButton)
541 {
545  SDL_bool invert_input = SDL_FALSE;
546  char half_axis_input = 0;
547  char half_axis_output = 0;
548 
549  if (*szGameButton == '+' || *szGameButton == '-') {
550  half_axis_output = *szGameButton++;
551  }
552 
557  bind.output.axis.axis = axis;
559  bind.output.axis.axis_min = 0;
560  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
561  } else {
562  if (half_axis_output == '+') {
563  bind.output.axis.axis_min = 0;
564  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
565  } else if (half_axis_output == '-') {
566  bind.output.axis.axis_min = 0;
567  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
568  } else {
569  bind.output.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
570  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
571  }
572  }
573  } else if (button != SDL_CONTROLLER_BUTTON_INVALID) {
575  bind.output.button = button;
576  } else {
577  SDL_SetError("Unexpected controller element %s", szGameButton);
578  return;
579  }
580 
581  if (*szJoystickButton == '+' || *szJoystickButton == '-') {
582  half_axis_input = *szJoystickButton++;
583  }
584  if (szJoystickButton[SDL_strlen(szJoystickButton) - 1] == '~') {
585  invert_input = SDL_TRUE;
586  }
587 
588  if (szJoystickButton[0] == 'a' && SDL_isdigit(szJoystickButton[1])) {
590  bind.input.axis.axis = SDL_atoi(&szJoystickButton[1]);
591  if (half_axis_input == '+') {
592  bind.input.axis.axis_min = 0;
593  bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
594  } else if (half_axis_input == '-') {
595  bind.input.axis.axis_min = 0;
596  bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
597  } else {
598  bind.input.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
599  bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
600  }
601  if (invert_input) {
602  int tmp = bind.input.axis.axis_min;
603  bind.input.axis.axis_min = bind.input.axis.axis_max;
604  bind.input.axis.axis_max = tmp;
605  }
606  } else if (szJoystickButton[0] == 'b' && SDL_isdigit(szJoystickButton[1])) {
608  bind.input.button = SDL_atoi(&szJoystickButton[1]);
609  } else if (szJoystickButton[0] == 'h' && SDL_isdigit(szJoystickButton[1]) &&
610  szJoystickButton[2] == '.' && SDL_isdigit(szJoystickButton[3])) {
611  int hat = SDL_atoi(&szJoystickButton[1]);
612  int mask = SDL_atoi(&szJoystickButton[3]);
614  bind.input.hat.hat = hat;
615  bind.input.hat.hat_mask = mask;
616  } else {
617  SDL_SetError("Unexpected joystick element: %s", szJoystickButton);
618  return;
619  }
620 
621  ++gamecontroller->num_bindings;
622  gamecontroller->bindings = (SDL_ExtendedGameControllerBind *)SDL_realloc(gamecontroller->bindings, gamecontroller->num_bindings * sizeof(*gamecontroller->bindings));
623  if (!gamecontroller->bindings) {
624  gamecontroller->num_bindings = 0;
625  SDL_OutOfMemory();
626  return;
627  }
628  gamecontroller->bindings[gamecontroller->num_bindings - 1] = bind;
629 }
630 
631 
632 /*
633  * given a controller mapping string update our mapping object
634  */
635 static void
636 SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecontroller, const char *pchString)
637 {
638  char szGameButton[20];
639  char szJoystickButton[20];
640  SDL_bool bGameButton = SDL_TRUE;
641  int i = 0;
642  const char *pchPos = pchString;
643 
644  SDL_zero(szGameButton);
645  SDL_zero(szJoystickButton);
646 
647  while (pchPos && *pchPos) {
648  if (*pchPos == ':') {
649  i = 0;
650  bGameButton = SDL_FALSE;
651  } else if (*pchPos == ' ') {
652 
653  } else if (*pchPos == ',') {
654  i = 0;
655  bGameButton = SDL_TRUE;
656  SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
657  SDL_zero(szGameButton);
658  SDL_zero(szJoystickButton);
659 
660  } else if (bGameButton) {
661  if (i >= sizeof(szGameButton)) {
662  SDL_SetError("Button name too large: %s", szGameButton);
663  return;
664  }
665  szGameButton[i] = *pchPos;
666  i++;
667  } else {
668  if (i >= sizeof(szJoystickButton)) {
669  SDL_SetError("Joystick button name too large: %s", szJoystickButton);
670  return;
671  }
672  szJoystickButton[i] = *pchPos;
673  i++;
674  }
675  pchPos++;
676  }
677 
678  SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
679 
680 }
681 
682 /*
683  * Make a new button mapping struct
684  */
685 static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
686 {
687  int i;
688 
689  gamecontroller->name = pchName;
690  gamecontroller->num_bindings = 0;
691  SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
692 
693  SDL_PrivateGameControllerParseControllerConfigString(gamecontroller, pchMapping);
694 
695  /* Set the zero point for triggers */
696  for (i = 0; i < gamecontroller->num_bindings; ++i) {
697  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
698  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
700  (binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ||
701  binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
702  if (binding->input.axis.axis < gamecontroller->joystick->naxes) {
703  gamecontroller->joystick->axes[binding->input.axis.axis].value =
704  gamecontroller->joystick->axes[binding->input.axis.axis].zero = (Sint16)binding->input.axis.axis_min;
705  }
706  }
707  }
708 }
709 
710 
711 /*
712  * grab the guid string from a mapping string
713  */
714 static char *SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
715 {
716  const char *pFirstComma = SDL_strchr(pMapping, ',');
717  if (pFirstComma) {
718  char *pchGUID = SDL_malloc(pFirstComma - pMapping + 1);
719  if (!pchGUID) {
720  SDL_OutOfMemory();
721  return NULL;
722  }
723  SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
724  pchGUID[pFirstComma - pMapping] = '\0';
725 
726  /* Convert old style GUIDs to the new style in 2.0.5 */
727 #if __WIN32__
728  if (SDL_strlen(pchGUID) == 32 &&
729  SDL_memcmp(&pchGUID[20], "504944564944", 12) == 0) {
730  SDL_memcpy(&pchGUID[20], "000000000000", 12);
731  SDL_memcpy(&pchGUID[16], &pchGUID[4], 4);
732  SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
733  SDL_memcpy(&pchGUID[0], "03000000", 8);
734  }
735 #elif __MACOSX__
736  if (SDL_strlen(pchGUID) == 32 &&
737  SDL_memcmp(&pchGUID[4], "000000000000", 12) == 0 &&
738  SDL_memcmp(&pchGUID[20], "000000000000", 12) == 0) {
739  SDL_memcpy(&pchGUID[20], "000000000000", 12);
740  SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
741  SDL_memcpy(&pchGUID[0], "03000000", 8);
742  }
743 #endif
744  return pchGUID;
745  }
746  return NULL;
747 }
748 
749 
750 /*
751  * grab the name string from a mapping string
752  */
753 static char *SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
754 {
755  const char *pFirstComma, *pSecondComma;
756  char *pchName;
757 
758  pFirstComma = SDL_strchr(pMapping, ',');
759  if (!pFirstComma)
760  return NULL;
761 
762  pSecondComma = SDL_strchr(pFirstComma + 1, ',');
763  if (!pSecondComma)
764  return NULL;
765 
766  pchName = SDL_malloc(pSecondComma - pFirstComma);
767  if (!pchName) {
768  SDL_OutOfMemory();
769  return NULL;
770  }
771  SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
772  pchName[pSecondComma - pFirstComma - 1] = 0;
773  return pchName;
774 }
775 
776 
777 /*
778  * grab the button mapping string from a mapping string
779  */
780 static char *SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
781 {
782  const char *pFirstComma, *pSecondComma;
783 
784  pFirstComma = SDL_strchr(pMapping, ',');
785  if (!pFirstComma)
786  return NULL;
787 
788  pSecondComma = SDL_strchr(pFirstComma + 1, ',');
789  if (!pSecondComma)
790  return NULL;
791 
792  return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
793 }
794 
795 /*
796  * Helper function to refresh a mapping
797  */
799 {
800  SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
801  while (gamecontrollerlist) {
802  if (!SDL_memcmp(&gamecontrollerlist->joystick->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
803  /* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
804  SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->name, pControllerMapping->mapping);
805 
806  {
808  event.type = SDL_CONTROLLERDEVICEREMAPPED;
809  event.cdevice.which = gamecontrollerlist->joystick->instance_id;
811  }
812  }
813 
814  gamecontrollerlist = gamecontrollerlist->next;
815  }
816 }
817 
818 /*
819  * Helper function to add a mapping for a guid
820  */
821 static ControllerMapping_t *
822 SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)
823 {
824  char *pchName;
825  char *pchMapping;
826  ControllerMapping_t *pControllerMapping;
827 
828  pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString);
829  if (!pchName) {
830  SDL_SetError("Couldn't parse name from %s", mappingString);
831  return NULL;
832  }
833 
834  pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString);
835  if (!pchMapping) {
836  SDL_free(pchName);
837  SDL_SetError("Couldn't parse %s", mappingString);
838  return NULL;
839  }
840 
841  pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID, SDL_TRUE);
842  if (pControllerMapping) {
843  /* Only overwrite the mapping if the priority is the same or higher. */
844  if (pControllerMapping->priority <= priority) {
845  /* Update existing mapping */
846  SDL_free(pControllerMapping->name);
847  pControllerMapping->name = pchName;
848  SDL_free(pControllerMapping->mapping);
849  pControllerMapping->mapping = pchMapping;
850  pControllerMapping->priority = priority;
851  /* refresh open controllers */
852  SDL_PrivateGameControllerRefreshMapping(pControllerMapping);
853  } else {
854  SDL_free(pchName);
855  SDL_free(pchMapping);
856  }
857  *existing = SDL_TRUE;
858  } else {
859  pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
860  if (!pControllerMapping) {
861  SDL_free(pchName);
862  SDL_free(pchMapping);
863  SDL_OutOfMemory();
864  return NULL;
865  }
866  pControllerMapping->guid = jGUID;
867  pControllerMapping->name = pchName;
868  pControllerMapping->mapping = pchMapping;
869  pControllerMapping->next = NULL;
870  pControllerMapping->priority = priority;
871 
873  /* Add the mapping to the end of the list */
874  ControllerMapping_t *pCurrMapping, *pPrevMapping;
875 
876  for ( pPrevMapping = s_pSupportedControllers, pCurrMapping = pPrevMapping->next;
877  pCurrMapping;
878  pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next ) {
879  continue;
880  }
881  pPrevMapping->next = pControllerMapping;
882  } else {
883  s_pSupportedControllers = pControllerMapping;
884  }
885  *existing = SDL_FALSE;
886  }
887  return pControllerMapping;
888 }
889 
890 #ifdef __ANDROID__
891 /*
892  * Helper function to guess at a mapping based on the elements reported for this controller
893  */
894 static ControllerMapping_t *SDL_CreateMappingForAndroidController(const char *name, SDL_JoystickGUID guid)
895 {
896  SDL_bool existing;
897  char name_string[128];
898  char mapping_string[1024];
899  int button_mask;
900  int axis_mask;
901 
902  button_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-4]));
903  axis_mask = SDL_SwapLE16(*(Uint16*)(&guid.data[sizeof(guid.data)-2]));
904  if (!button_mask && !axis_mask) {
905  /* Accelerometer, shouldn't have a game controller mapping */
906  return NULL;
907  }
908 
909  /* Remove any commas in the name */
910  SDL_strlcpy(name_string, name, sizeof(name_string));
911  {
912  char *spot;
913  for (spot = name_string; *spot; ++spot) {
914  if (*spot == ',') {
915  *spot = ' ';
916  }
917  }
918  }
919  SDL_snprintf(mapping_string, sizeof(mapping_string), "none,%s,", name_string);
920  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_A)) {
921  SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string));
922  }
923  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_B)) {
924  SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string));
925  } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
926  /* Use the back button as "B" for easy UI navigation with TV remotes */
927  SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string));
928  button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_BACK);
929  }
930  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_X)) {
931  SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string));
932  }
933  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_Y)) {
934  SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string));
935  }
936  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) {
937  SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string));
938  }
939 #if 0 /* The guide button generally isn't functional (or acts as a home button) on most Android controllers */
940  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) {
941  SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string));
942 #if 0 /* Actually this will be done in Steam */
943  } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
944  /* The guide button doesn't exist, use the start button instead,
945  so you can do Steam guide button chords and open the Steam overlay.
946  */
947  SDL_strlcat(mapping_string, "guide:b6,", sizeof(mapping_string));
948  button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_START);
949 #endif
950  }
951 #endif
952  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) {
953  SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string));
954  }
955  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) {
956  SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string));
957  }
958  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) {
959  SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string));
960  }
961  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) {
962  SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string));
963  }
964  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) {
965  SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string));
966  }
967  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP)) {
968  SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string));
969  }
970  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN)) {
971  SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string));
972  }
973  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT)) {
974  SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string));
975  }
976  if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
977  SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string));
978  }
979  if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX)) {
980  SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string));
981  }
982  if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY)) {
983  SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string));
984  }
985  if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX)) {
986  SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string));
987  }
988  if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY)) {
989  SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string));
990  }
991  if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT)) {
992  SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string));
993  }
994  if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
995  SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string));
996  }
997  return SDL_PrivateAddMappingForGUID(guid, mapping_string,
999 }
1000 #endif /* __ANDROID__ */
1001 
1002 
1003 /*
1004  * Helper function to determine pre-calculated offset to certain joystick mappings
1005  */
1007 {
1009 
1011 #ifdef __LINUX__
1012  if (!mapping && name) {
1013  if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
1014  /* The Linux driver xpad.c maps the wireless dpad to buttons */
1015  SDL_bool existing;
1017 "none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
1019  }
1020  }
1021 #endif /* __LINUX__ */
1022 
1023  if (!mapping && name) {
1024  if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {
1026  }
1027  }
1028 #ifdef __ANDROID__
1029  if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) {
1030  mapping = SDL_CreateMappingForAndroidController(name, guid);
1031  }
1032 #endif
1033  if (!mapping) {
1035  }
1036  return mapping;
1037 }
1038 
1040 {
1041  const char *name;
1042  SDL_JoystickGUID guid;
1044 
1046 
1047  if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
1048  SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
1050  return (NULL);
1051  }
1052 
1053  name = SDL_JoystickNameForIndex(device_index);
1054  guid = SDL_JoystickGetDeviceGUID(device_index);
1057  return mapping;
1058 }
1059 
1060 /*
1061  * Add or update an entry into the Mappings Database
1062  */
1063 int
1065 {
1066  const char *platform = SDL_GetPlatform();
1067  int controllers = 0;
1068  char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
1069  size_t db_size, platform_len;
1070 
1071  if (rw == NULL) {
1072  return SDL_SetError("Invalid RWops");
1073  }
1074  db_size = (size_t)SDL_RWsize(rw);
1075 
1076  buf = (char *)SDL_malloc(db_size + 1);
1077  if (buf == NULL) {
1078  if (freerw) {
1079  SDL_RWclose(rw);
1080  }
1081  return SDL_SetError("Could not allocate space to read DB into memory");
1082  }
1083 
1084  if (SDL_RWread(rw, buf, db_size, 1) != 1) {
1085  if (freerw) {
1086  SDL_RWclose(rw);
1087  }
1088  SDL_free(buf);
1089  return SDL_SetError("Could not read DB");
1090  }
1091 
1092  if (freerw) {
1093  SDL_RWclose(rw);
1094  }
1095 
1096  buf[db_size] = '\0';
1097  line = buf;
1098 
1099  while (line < buf + db_size) {
1100  line_end = SDL_strchr(line, '\n');
1101  if (line_end != NULL) {
1102  *line_end = '\0';
1103  } else {
1104  line_end = buf + db_size;
1105  }
1106 
1107  /* Extract and verify the platform */
1109  if (tmp != NULL) {
1111  comma = SDL_strchr(tmp, ',');
1112  if (comma != NULL) {
1113  platform_len = comma - tmp + 1;
1114  if (platform_len + 1 < SDL_arraysize(line_platform)) {
1115  SDL_strlcpy(line_platform, tmp, platform_len);
1116  if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 &&
1117  SDL_GameControllerAddMapping(line) > 0) {
1118  controllers++;
1119  }
1120  }
1121  }
1122  }
1123 
1124  line = line_end + 1;
1125  }
1126 
1127  SDL_free(buf);
1128  return controllers;
1129 }
1130 
1131 /*
1132  * Add or update an entry into the Mappings Database with a priority
1133  */
1134 static int
1136 {
1137  char *pchGUID;
1138  SDL_JoystickGUID jGUID;
1139  SDL_bool is_default_mapping = SDL_FALSE;
1140  SDL_bool is_hidapi_mapping = SDL_FALSE;
1141  SDL_bool is_xinput_mapping = SDL_FALSE;
1142  SDL_bool existing = SDL_FALSE;
1143  ControllerMapping_t *pControllerMapping;
1144 
1145  if (!mappingString) {
1146  return SDL_InvalidParamError("mappingString");
1147  }
1148 
1149  pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString);
1150  if (!pchGUID) {
1151  return SDL_SetError("Couldn't parse GUID from %s", mappingString);
1152  }
1153  if (!SDL_strcasecmp(pchGUID, "default")) {
1154  is_default_mapping = SDL_TRUE;
1155  } else if (!SDL_strcasecmp(pchGUID, "hidapi")) {
1156  is_hidapi_mapping = SDL_TRUE;
1157  } else if (!SDL_strcasecmp(pchGUID, "xinput")) {
1158  is_xinput_mapping = SDL_TRUE;
1159  }
1160  jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
1161  SDL_free(pchGUID);
1162 
1163  pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority);
1164  if (!pControllerMapping) {
1165  return -1;
1166  }
1167 
1168  if (existing) {
1169  return 0;
1170  } else {
1171  if (is_default_mapping) {
1172  s_pDefaultMapping = pControllerMapping;
1173  } else if (is_hidapi_mapping) {
1174  s_pHIDAPIMapping = pControllerMapping;
1175  } else if (is_xinput_mapping) {
1176  s_pXInputMapping = pControllerMapping;
1177  }
1178  return 1;
1179  }
1180 }
1181 
1182 /*
1183  * Add or update an entry into the Mappings Database
1184  */
1185 int
1186 SDL_GameControllerAddMapping(const char *mappingString)
1187 {
1189 }
1190 
1191 /*
1192  * Get the number of mappings installed
1193  */
1194 int
1196 {
1197  int num_mappings = 0;
1199 
1201  if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
1202  continue;
1203  }
1204  ++num_mappings;
1205  }
1206  return num_mappings;
1207 }
1208 
1209 /*
1210  * Get the mapping at a particular index.
1211  */
1212 char *
1214 {
1216 
1218  if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
1219  continue;
1220  }
1221  if (mapping_index == 0) {
1222  char *pMappingString;
1223  char pchGUID[33];
1224  size_t needed;
1225 
1226  SDL_JoystickGetGUIDString(mapping->guid, pchGUID, sizeof(pchGUID));
1227  /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1228  needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1229  pMappingString = SDL_malloc(needed);
1230  if (!pMappingString) {
1231  SDL_OutOfMemory();
1232  return NULL;
1233  }
1234  SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1235  return pMappingString;
1236  }
1237  --mapping_index;
1238  }
1239  return NULL;
1240 }
1241 
1242 /*
1243  * Get the mapping string for this GUID
1244  */
1245 char *
1247 {
1248  char *pMappingString = NULL;
1250  if (mapping) {
1251  char pchGUID[33];
1252  size_t needed;
1253  SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
1254  /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1255  needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1256  pMappingString = SDL_malloc(needed);
1257  if (!pMappingString) {
1258  SDL_OutOfMemory();
1259  return NULL;
1260  }
1261  SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1262  }
1263  return pMappingString;
1264 }
1265 
1266 /*
1267  * Get the mapping string for this device
1268  */
1269 char *
1270 SDL_GameControllerMapping(SDL_GameController * gamecontroller)
1271 {
1272  if (!gamecontroller) {
1273  return NULL;
1274  }
1275 
1276  return SDL_GameControllerMappingForGUID(gamecontroller->joystick->guid);
1277 }
1278 
1279 static void
1281 {
1282  const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
1283  if (hint && hint[0]) {
1284  size_t nchHints = SDL_strlen(hint);
1285  char *pUserMappings = SDL_malloc(nchHints + 1);
1286  char *pTempMappings = pUserMappings;
1287  SDL_memcpy(pUserMappings, hint, nchHints);
1288  pUserMappings[nchHints] = '\0';
1289  while (pUserMappings) {
1290  char *pchNewLine = NULL;
1291 
1292  pchNewLine = SDL_strchr(pUserMappings, '\n');
1293  if (pchNewLine)
1294  *pchNewLine = '\0';
1295 
1297 
1298  if (pchNewLine) {
1299  pUserMappings = pchNewLine + 1;
1300  } else {
1301  pUserMappings = NULL;
1302  }
1303  }
1304  SDL_free(pTempMappings);
1305  }
1306 }
1307 
1308 /*
1309  * Fill the given buffer with the expected controller mapping filepath.
1310  * Usually this will just be CONTROLLER_MAPPING_FILE, but for Android,
1311  * we want to get the internal storage path.
1312  */
1314 {
1315 #ifdef CONTROLLER_MAPPING_FILE
1316 #define STRING(X) SDL_STRINGIFY_ARG(X)
1317  return SDL_strlcpy(path, STRING(CONTROLLER_MAPPING_FILE), size) < size;
1318 #elif defined(__ANDROID__)
1319  return SDL_snprintf(path, size, "%s/controller_map.txt", SDL_AndroidGetInternalStoragePath()) < size;
1320 #else
1321  return SDL_FALSE;
1322 #endif
1323 }
1324 
1325 /*
1326  * Initialize the game controller system, mostly load our DB of controller config mappings
1327  */
1328 int
1330 {
1331  char szControllerMapPath[1024];
1332  int i = 0;
1333  const char *pMappingString = NULL;
1334  pMappingString = s_ControllerMappings[i];
1335  while (pMappingString) {
1337 
1338  i++;
1339  pMappingString = s_ControllerMappings[i];
1340  }
1341 
1342  if (SDL_GetControllerMappingFilePath(szControllerMapPath, sizeof(szControllerMapPath))) {
1343  SDL_GameControllerAddMappingsFromFile(szControllerMapPath);
1344  }
1345 
1346  /* load in any user supplied config */
1348 
1353 
1354  return (0);
1355 }
1356 
1357 int
1359 {
1360  int i;
1361 
1362  /* watch for joy events and fire controller ones if needed */
1364 
1365  /* Send added events for controllers currently attached */
1366  for (i = 0; i < SDL_NumJoysticks(); ++i) {
1367  if (SDL_IsGameController(i)) {
1368  SDL_Event deviceevent;
1369  deviceevent.type = SDL_CONTROLLERDEVICEADDED;
1370  deviceevent.cdevice.which = i;
1371  SDL_PushEvent(&deviceevent);
1372  }
1373  }
1374 
1375  return (0);
1376 }
1377 
1378 
1379 /*
1380  * Get the implementation dependent name of a controller
1381  */
1382 const char *
1384 {
1385  ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1386  if (pSupportedController) {
1387  if (SDL_strcmp(pSupportedController->name, "*") == 0) {
1388  return SDL_JoystickNameForIndex(device_index);
1389  } else {
1390  return pSupportedController->name;
1391  }
1392  }
1393  return NULL;
1394 }
1395 
1396 
1397 /**
1398  * Get the mapping of a game controller.
1399  * This can be called before any controllers are opened.
1400  * If no mapping can be found, this function returns NULL.
1401  */
1402 char *
1404 {
1405  char *pMappingString = NULL;
1407 
1409  mapping = SDL_PrivateGetControllerMapping(joystick_index);
1410  if (mapping) {
1411  SDL_JoystickGUID guid;
1412  char pchGUID[33];
1413  size_t needed;
1414  guid = SDL_JoystickGetDeviceGUID(joystick_index);
1415  SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
1416  /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1417  needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1418  pMappingString = SDL_malloc(needed);
1419  if (!pMappingString) {
1420  SDL_OutOfMemory();
1422  return NULL;
1423  }
1424  SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1425  }
1427  return pMappingString;
1428 }
1429 
1430 
1431 /*
1432  * Return 1 if the joystick with this name and GUID is a supported controller
1433  */
1434 SDL_bool
1436 {
1438  if (pSupportedController) {
1439  return SDL_TRUE;
1440  }
1441  return SDL_FALSE;
1442 }
1443 
1444 /*
1445  * Return 1 if the joystick at this device index is a supported controller
1446  */
1447 SDL_bool
1448 SDL_IsGameController(int device_index)
1449 {
1450  ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1451  if (pSupportedController) {
1452  return SDL_TRUE;
1453  }
1454  return SDL_FALSE;
1455 }
1456 
1457 /*
1458  * Return 1 if the game controller should be ignored by SDL
1459  */
1461 {
1462  int i;
1463  Uint16 vendor;
1464  Uint16 product;
1465  Uint16 version;
1466  Uint32 vidpid;
1467 
1470  return SDL_FALSE;
1471  }
1472 
1473  SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version);
1474 
1475  if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
1476  /* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */
1477  SDL_bool bSteamVirtualGamepad = SDL_FALSE;
1478 #if defined(__LINUX__)
1479  bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
1480 #elif defined(__MACOSX__)
1481  bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
1482 #elif defined(__WIN32__)
1483  /* We can't tell on Windows, but Steam will block others in input hooks */
1484  bSteamVirtualGamepad = SDL_TRUE;
1485 #endif
1486  if (bSteamVirtualGamepad) {
1487  return SDL_FALSE;
1488  }
1489  }
1490 
1491  vidpid = MAKE_VIDPID(vendor, product);
1492 
1494  for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) {
1495  if (vidpid == SDL_allowed_controllers.entries[i]) {
1496  return SDL_FALSE;
1497  }
1498  }
1499  return SDL_TRUE;
1500  } else {
1501  for (i = 0; i < SDL_ignored_controllers.num_entries; ++i) {
1502  if (vidpid == SDL_ignored_controllers.entries[i]) {
1503  return SDL_TRUE;
1504  }
1505  }
1506  return SDL_FALSE;
1507  }
1508 }
1509 
1510 /*
1511  * Open a controller for use - the index passed as an argument refers to
1512  * the N'th controller on the system. This index is the value which will
1513  * identify this controller in future controller events.
1514  *
1515  * This function returns a controller identifier, or NULL if an error occurred.
1516  */
1517 SDL_GameController *
1518 SDL_GameControllerOpen(int device_index)
1519 {
1520  SDL_JoystickID instance_id;
1521  SDL_GameController *gamecontroller;
1522  SDL_GameController *gamecontrollerlist;
1523  ControllerMapping_t *pSupportedController = NULL;
1524 
1526 
1527  gamecontrollerlist = SDL_gamecontrollers;
1528  /* If the controller is already open, return it */
1529  instance_id = SDL_JoystickGetDeviceInstanceID(device_index);
1530  while (gamecontrollerlist) {
1531  if (instance_id == gamecontrollerlist->joystick->instance_id) {
1532  gamecontroller = gamecontrollerlist;
1533  ++gamecontroller->ref_count;
1535  return (gamecontroller);
1536  }
1537  gamecontrollerlist = gamecontrollerlist->next;
1538  }
1539 
1540  /* Find a controller mapping */
1541  pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1542  if (!pSupportedController) {
1543  SDL_SetError("Couldn't find mapping for device (%d)", device_index);
1545  return NULL;
1546  }
1547 
1548  /* Create and initialize the controller */
1549  gamecontroller = (SDL_GameController *) SDL_calloc(1, sizeof(*gamecontroller));
1550  if (gamecontroller == NULL) {
1551  SDL_OutOfMemory();
1553  return NULL;
1554  }
1555 
1556  gamecontroller->joystick = SDL_JoystickOpen(device_index);
1557  if (!gamecontroller->joystick) {
1558  SDL_free(gamecontroller);
1560  return NULL;
1561  }
1562 
1563  if (gamecontroller->joystick->naxes) {
1564  gamecontroller->last_match_axis = (SDL_ExtendedGameControllerBind **)SDL_calloc(gamecontroller->joystick->naxes, sizeof(*gamecontroller->last_match_axis));
1565  if (!gamecontroller->last_match_axis) {
1566  SDL_OutOfMemory();
1567  SDL_JoystickClose(gamecontroller->joystick);
1568  SDL_free(gamecontroller);
1570  return NULL;
1571  }
1572  }
1573  if (gamecontroller->joystick->nhats) {
1574  gamecontroller->last_hat_mask = (Uint8 *)SDL_calloc(gamecontroller->joystick->nhats, sizeof(*gamecontroller->last_hat_mask));
1575  if (!gamecontroller->last_hat_mask) {
1576  SDL_OutOfMemory();
1577  SDL_JoystickClose(gamecontroller->joystick);
1578  SDL_free(gamecontroller->last_match_axis);
1579  SDL_free(gamecontroller);
1581  return NULL;
1582  }
1583  }
1584 
1585  SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->name, pSupportedController->mapping);
1586 
1587  /* Add the controller to list */
1588  ++gamecontroller->ref_count;
1589  /* Link the controller in the list */
1590  gamecontroller->next = SDL_gamecontrollers;
1591  SDL_gamecontrollers = gamecontroller;
1592 
1594 
1595  return (gamecontroller);
1596 }
1597 
1598 /*
1599  * Manually pump for controller updates.
1600  */
1601 void
1603 {
1604  /* Just for API completeness; the joystick API does all the work. */
1606 }
1607 
1608 /*
1609  * Get the current state of an axis control on a controller
1610  */
1611 Sint16
1612 SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
1613 {
1614  int i;
1615 
1616  if (!gamecontroller)
1617  return 0;
1618 
1619  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1620  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1621  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
1622  int value = 0;
1623  SDL_bool valid_input_range;
1624  SDL_bool valid_output_range;
1625 
1626  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1627  value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
1628  if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
1629  valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
1630  } else {
1631  valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
1632  }
1633  if (valid_input_range) {
1634  if (binding->input.axis.axis_min != binding->output.axis.axis_min || binding->input.axis.axis_max != binding->output.axis.axis_max) {
1635  float normalized_value = (float)(value - binding->input.axis.axis_min) / (binding->input.axis.axis_max - binding->input.axis.axis_min);
1636  value = binding->output.axis.axis_min + (int)(normalized_value * (binding->output.axis.axis_max - binding->output.axis.axis_min));
1637  }
1638  }
1639  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1640  value = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
1641  if (value == SDL_PRESSED) {
1642  value = binding->output.axis.axis_max;
1643  }
1644  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1645  int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
1646  if (hat_mask & binding->input.hat.hat_mask) {
1647  value = binding->output.axis.axis_max;
1648  }
1649  }
1650 
1651  if (binding->output.axis.axis_min < binding->output.axis.axis_max) {
1652  valid_output_range = (value >= binding->output.axis.axis_min && value <= binding->output.axis.axis_max);
1653  } else {
1654  valid_output_range = (value >= binding->output.axis.axis_max && value <= binding->output.axis.axis_min);
1655  }
1656  /* If the value is zero, there might be another binding that makes it non-zero */
1657  if (value != 0 && valid_output_range) {
1658  return (Sint16)value;
1659  }
1660  }
1661  }
1662  return 0;
1663 }
1664 
1665 /*
1666  * Get the current state of a button on a controller
1667  */
1668 Uint8
1669 SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
1670 {
1671  int i;
1672 
1673  if (!gamecontroller)
1674  return 0;
1675 
1676  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1677  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1678  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
1679  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1680  SDL_bool valid_input_range;
1681 
1682  int value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
1683  int threshold = binding->input.axis.axis_min + (binding->input.axis.axis_max - binding->input.axis.axis_min) / 2;
1684  if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
1685  valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
1686  if (valid_input_range) {
1687  return (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
1688  }
1689  } else {
1690  valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
1691  if (valid_input_range) {
1692  return (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
1693  }
1694  }
1695  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1696  return SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
1697  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1698  int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
1699  return (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED;
1700  }
1701  }
1702  }
1703  return SDL_RELEASED;
1704 }
1705 
1706 const char *
1707 SDL_GameControllerName(SDL_GameController * gamecontroller)
1708 {
1709  if (!gamecontroller)
1710  return NULL;
1711 
1712  if (SDL_strcmp(gamecontroller->name, "*") == 0) {
1713  return SDL_JoystickName(SDL_GameControllerGetJoystick(gamecontroller));
1714  } else {
1715  return gamecontroller->name;
1716  }
1717 }
1718 
1719 int
1720 SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
1721 {
1723 }
1724 
1725 Uint16
1726 SDL_GameControllerGetVendor(SDL_GameController * gamecontroller)
1727 {
1728  return SDL_JoystickGetVendor(SDL_GameControllerGetJoystick(gamecontroller));
1729 }
1730 
1731 Uint16
1732 SDL_GameControllerGetProduct(SDL_GameController * gamecontroller)
1733 {
1734  return SDL_JoystickGetProduct(SDL_GameControllerGetJoystick(gamecontroller));
1735 }
1736 
1737 Uint16
1738 SDL_GameControllerGetProductVersion(SDL_GameController * gamecontroller)
1739 {
1741 }
1742 
1743 /*
1744  * Return if the controller in question is currently attached to the system,
1745  * \return 0 if not plugged in, 1 if still present.
1746  */
1747 SDL_bool
1748 SDL_GameControllerGetAttached(SDL_GameController * gamecontroller)
1749 {
1750  if (!gamecontroller)
1751  return SDL_FALSE;
1752 
1753  return SDL_JoystickGetAttached(gamecontroller->joystick);
1754 }
1755 
1756 /*
1757  * Get the joystick for this controller
1758  */
1759 SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
1760 {
1761  if (!gamecontroller)
1762  return NULL;
1763 
1764  return gamecontroller->joystick;
1765 }
1766 
1767 
1768 /*
1769  * Find the SDL_GameController that owns this instance id
1770  */
1771 SDL_GameController *
1773 {
1774  SDL_GameController *gamecontroller;
1775 
1777  gamecontroller = SDL_gamecontrollers;
1778  while (gamecontroller) {
1779  if (gamecontroller->joystick->instance_id == joyid) {
1781  return gamecontroller;
1782  }
1783  gamecontroller = gamecontroller->next;
1784  }
1786  return NULL;
1787 }
1788 
1789 
1790 /*
1791  * Get the SDL joystick layer binding for this controller axis mapping
1792  */
1794 {
1795  int i;
1797  SDL_zero(bind);
1798 
1799  if (!gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID)
1800  return bind;
1801 
1802  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1803  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1804  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
1805  bind.bindType = binding->inputType;
1806  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1807  /* FIXME: There might be multiple axes bound now that we have axis ranges... */
1808  bind.value.axis = binding->input.axis.axis;
1809  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1810  bind.value.button = binding->input.button;
1811  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1812  bind.value.hat.hat = binding->input.hat.hat;
1813  bind.value.hat.hat_mask = binding->input.hat.hat_mask;
1814  }
1815  break;
1816  }
1817  }
1818  return bind;
1819 }
1820 
1821 
1822 /*
1823  * Get the SDL joystick layer binding for this controller button mapping
1824  */
1826 {
1827  int i;
1829  SDL_zero(bind);
1830 
1831  if (!gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID)
1832  return bind;
1833 
1834  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1835  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1836  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
1837  bind.bindType = binding->inputType;
1838  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1839  bind.value.axis = binding->input.axis.axis;
1840  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1841  bind.value.button = binding->input.button;
1842  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1843  bind.value.hat.hat = binding->input.hat.hat;
1844  bind.value.hat.hat_mask = binding->input.hat.hat_mask;
1845  }
1846  break;
1847  }
1848  }
1849  return bind;
1850 }
1851 
1852 
1853 int
1854 SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
1855 {
1856  return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms);
1857 }
1858 
1859 void
1860 SDL_GameControllerClose(SDL_GameController * gamecontroller)
1861 {
1862  SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
1863 
1864  if (!gamecontroller)
1865  return;
1866 
1868 
1869  /* First decrement ref count */
1870  if (--gamecontroller->ref_count > 0) {
1872  return;
1873  }
1874 
1875  SDL_JoystickClose(gamecontroller->joystick);
1876 
1877  gamecontrollerlist = SDL_gamecontrollers;
1878  gamecontrollerlistprev = NULL;
1879  while (gamecontrollerlist) {
1880  if (gamecontroller == gamecontrollerlist) {
1881  if (gamecontrollerlistprev) {
1882  /* unlink this entry */
1883  gamecontrollerlistprev->next = gamecontrollerlist->next;
1884  } else {
1885  SDL_gamecontrollers = gamecontroller->next;
1886  }
1887  break;
1888  }
1889  gamecontrollerlistprev = gamecontrollerlist;
1890  gamecontrollerlist = gamecontrollerlist->next;
1891  }
1892 
1893  SDL_free(gamecontroller->bindings);
1894  SDL_free(gamecontroller->last_match_axis);
1895  SDL_free(gamecontroller->last_hat_mask);
1896  SDL_free(gamecontroller);
1897 
1899 }
1900 
1901 
1902 /*
1903  * Quit the controller subsystem
1904  */
1905 void
1907 {
1909  while (SDL_gamecontrollers) {
1910  SDL_gamecontrollers->ref_count = 1;
1912  }
1914 }
1915 
1916 void
1918 {
1919  ControllerMapping_t *pControllerMap;
1920 
1921  while (s_pSupportedControllers) {
1922  pControllerMap = s_pSupportedControllers;
1924  SDL_free(pControllerMap->name);
1925  SDL_free(pControllerMap->mapping);
1926  SDL_free(pControllerMap);
1927  }
1928 
1930 
1935 
1939  }
1943  }
1944 }
1945 
1946 /*
1947  * Event filter to transform joystick events into appropriate game controller ones
1948  */
1949 static int
1951 {
1952  int posted;
1953 
1954  /* translate the event, if desired */
1955  posted = 0;
1956 #if !SDL_EVENTS_DISABLED
1958  SDL_Event event;
1959  event.type = SDL_CONTROLLERAXISMOTION;
1960  event.caxis.which = gamecontroller->joystick->instance_id;
1961  event.caxis.axis = axis;
1962  event.caxis.value = value;
1963  posted = SDL_PushEvent(&event) == 1;
1964  }
1965 #endif /* !SDL_EVENTS_DISABLED */
1966  return (posted);
1967 }
1968 
1969 
1970 /*
1971  * Event filter to transform joystick events into appropriate game controller ones
1972  */
1973 static int
1975 {
1976  int posted;
1977 #if !SDL_EVENTS_DISABLED
1978  SDL_Event event;
1979 
1981  return (0);
1982 
1983  switch (state) {
1984  case SDL_PRESSED:
1985  event.type = SDL_CONTROLLERBUTTONDOWN;
1986  break;
1987  case SDL_RELEASED:
1988  event.type = SDL_CONTROLLERBUTTONUP;
1989  break;
1990  default:
1991  /* Invalid state -- bail */
1992  return (0);
1993  }
1994 #endif /* !SDL_EVENTS_DISABLED */
1995 
1997  Uint32 now = SDL_GetTicks();
1998  if (state == SDL_PRESSED) {
1999  gamecontroller->guide_button_down = now;
2000 
2001  if (gamecontroller->joystick->delayed_guide_button) {
2002  /* Skip duplicate press */
2003  return (0);
2004  }
2005  } else {
2006  if (!SDL_TICKS_PASSED(now, gamecontroller->guide_button_down+SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS) && !gamecontroller->joystick->force_recentering) {
2007  gamecontroller->joystick->delayed_guide_button = SDL_TRUE;
2008  return (0);
2009  }
2010  gamecontroller->joystick->delayed_guide_button = SDL_FALSE;
2011  }
2012  }
2013 
2014  /* translate the event, if desired */
2015  posted = 0;
2016 #if !SDL_EVENTS_DISABLED
2017  if (SDL_GetEventState(event.type) == SDL_ENABLE) {
2018  event.cbutton.which = gamecontroller->joystick->instance_id;
2019  event.cbutton.button = button;
2020  event.cbutton.state = state;
2021  posted = SDL_PushEvent(&event) == 1;
2022  }
2023 #endif /* !SDL_EVENTS_DISABLED */
2024  return (posted);
2025 }
2026 
2027 /*
2028  * Turn off controller events
2029  */
2030 int
2032 {
2033 #if SDL_EVENTS_DISABLED
2034  return SDL_IGNORE;
2035 #else
2036  const Uint32 event_list[] = {
2039  };
2040  unsigned int i;
2041 
2042  switch (state) {
2043  case SDL_QUERY:
2044  state = SDL_IGNORE;
2045  for (i = 0; i < SDL_arraysize(event_list); ++i) {
2046  state = SDL_EventState(event_list[i], SDL_QUERY);
2047  if (state == SDL_ENABLE) {
2048  break;
2049  }
2050  }
2051  break;
2052  default:
2053  for (i = 0; i < SDL_arraysize(event_list); ++i) {
2054  SDL_EventState(event_list[i], state);
2055  }
2056  break;
2057  }
2058  return (state);
2059 #endif /* SDL_EVENTS_DISABLED */
2060 }
2061 
2062 void
2064 {
2065  SDL_GameController *controllerlist = SDL_gamecontrollers;
2066  while (controllerlist) {
2067  if (controllerlist->joystick == joystick) {
2069  break;
2070  }
2071  controllerlist = controllerlist->next;
2072  }
2073 }
2074 
2075 /* vi: set ts=4 sw=4 expandtab: */
SDL_LoadVIDPIDListFromHint
static void SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list)
Definition: SDL_gamecontroller.c:136
SDL_PrivateGetControllerMappingForGUID
static ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid, SDL_bool exact_match)
Definition: SDL_gamecontroller.c:424
SDL_ExtendedGameControllerBind::outputType
SDL_GameControllerBindType outputType
Definition: SDL_gamecontroller.c:70
SDL_CONTROLLER_MAPPING_PRIORITY_API
@ SDL_CONTROLLER_MAPPING_PRIORITY_API
Definition: SDL_gamecontroller.c:89
SDL_GameControllerGetButton
Uint8 SDL_GameControllerGetButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
Definition: SDL_gamecontroller.c:1669
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
SDL_Event::type
Uint32 type
Definition: SDL_events.h:559
SDL_CONTROLLER_BUTTON_DPAD_LEFT
@ SDL_CONTROLLER_BUTTON_DPAD_LEFT
Definition: SDL_gamecontroller.h:332
SDL_CONTROLLERDEVICEREMOVED
@ SDL_CONTROLLERDEVICEREMOVED
Definition: SDL_events.h:124
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_IsJoystickHIDAPI
SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
Definition: SDL_joystick.c:1192
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_GameControllerUpdate
void SDL_GameControllerUpdate(void)
Definition: SDL_gamecontroller.c:1602
s_zeroGUID
static SDL_JoystickGUID s_zeroGUID
Definition: SDL_gamecontroller.c:102
_SDL_GameController::last_match_axis
SDL_ExtendedGameControllerBind ** last_match_axis
Definition: SDL_gamecontroller.c:117
SDL_CONTROLLER_AXIS_RIGHTX
@ SDL_CONTROLLER_AXIS_RIGHTX
Definition: SDL_gamecontroller.h:277
SDL_strlcat
#define SDL_strlcat
Definition: SDL_dynapi_overrides.h:396
SDL_events.h
SDL_GameControllerButtonBind::button
int button
Definition: SDL_gamecontroller.h:77
HasSameOutput
static SDL_bool HasSameOutput(SDL_ExtendedGameControllerBind *a, SDL_ExtendedGameControllerBind *b)
Definition: SDL_gamecontroller.c:225
SDL_PrivateGameControllerAxis
static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
Definition: SDL_gamecontroller.c:1950
SDL_PrivateGetControllerGUIDFromMappingString
static char * SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
Definition: SDL_gamecontroller.c:714
SDL_strlcpy
#define SDL_strlcpy
Definition: SDL_dynapi_overrides.h:394
SDL_JoystickGetVendor
#define SDL_JoystickGetVendor
Definition: SDL_dynapi_overrides.h:612
SDL_RWsize
#define SDL_RWsize(ctx)
Definition: SDL_rwops.h:184
SDL_IsGameController
SDL_bool SDL_IsGameController(int device_index)
Definition: SDL_gamecontroller.c:1448
SDL_GameControllerEventWatcher
static int SDL_GameControllerEventWatcher(void *userdata, SDL_Event *event)
Definition: SDL_gamecontroller.c:346
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:657
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_GameControllerButtonBind::hat
int hat
Definition: SDL_gamecontroller.h:80
ControllerMapping_t::priority
SDL_ControllerMappingPriority priority
Definition: SDL_gamecontroller.c:98
SDL_sysjoystick.h
SDL_gamecontrollers
static SDL_GameController * SDL_gamecontrollers
Definition: SDL_gamecontroller.c:48
SDL_UnlockJoysticks
#define SDL_UnlockJoysticks
Definition: SDL_dynapi_overrides.h:639
_SDL_GameController::guide_button_down
Uint32 guide_button_down
Definition: SDL_gamecontroller.c:119
SDL_ExtendedGameControllerBind::button
SDL_GameControllerButton button
Definition: SDL_gamecontroller.c:73
SDL_JoystickClose
#define SDL_JoystickClose
Definition: SDL_dynapi_overrides.h:215
SDL_joystick_c.h
SDL_ExtendedGameControllerBind::button
int button
Definition: SDL_gamecontroller.c:55
SDL_ADDEVENT
@ SDL_ADDEVENT
Definition: SDL_events.h:612
NULL
#define NULL
Definition: begin_code.h:164
SDL_CONTROLLER_BUTTON_INVALID
@ SDL_CONTROLLER_BUTTON_INVALID
Definition: SDL_gamecontroller.h:318
SDL_timer.h
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
SDL_JoystickGetButton
#define SDL_JoystickGetButton
Definition: SDL_dynapi_overrides.h:214
UpdateEventsForDeviceRemoval
static void UpdateEventsForDeviceRemoval()
Definition: SDL_gamecontroller.c:201
SDL_PrivateGameControllerParseElement
static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontroller, const char *szGameButton, const char *szJoystickButton)
Definition: SDL_gamecontroller.c:540
SDL_JoystickID
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81
SDL_GameControllerGetStringForButton
const char * SDL_GameControllerGetStringForButton(SDL_GameControllerButton axis)
Definition: SDL_gamecontroller.c:529
SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS
#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS
Definition: SDL_gamecontroller.c:43
SDL_CONTROLLERBUTTONDOWN
@ SDL_CONTROLLERBUTTONDOWN
Definition: SDL_events.h:121
SDL_GameControllerButtonBind::bindType
SDL_GameControllerBindType bindType
Definition: SDL_gamecontroller.h:74
SDL_ExtendedGameControllerBind
Definition: SDL_gamecontroller.c:51
HandleJoystickAxis
static void HandleJoystickAxis(SDL_GameController *gamecontroller, int axis, int value)
Definition: SDL_gamecontroller.c:247
SDLCALL
#define SDLCALL
Definition: SDL_internal.h:45
SDL_GameControllerIgnoreDevicesChanged
static void SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
Definition: SDL_gamecontroller.c:182
SDL_NumJoysticks
#define SDL_NumJoysticks
Definition: SDL_dynapi_overrides.h:195
ControllerMapping_t
Definition: SDL_gamecontroller.c:94
SDL_realloc
#define SDL_realloc
Definition: SDL_dynapi_overrides.h:376
SDL_InvalidParamError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
SDL_CONTROLLER_PLATFORM_FIELD
#define SDL_CONTROLLER_PLATFORM_FIELD
Definition: SDL_gamecontroller.c:45
SDL_CONTROLLER_BUTTON_RIGHTSTICK
@ SDL_CONTROLLER_BUTTON_RIGHTSTICK
Definition: SDL_gamecontroller.h:327
SDL_ExtendedGameControllerBind::axis_min
int axis_min
Definition: SDL_gamecontroller.c:59
SDL_vidpid_list::entries
Uint32 * entries
Definition: SDL_gamecontroller.c:129
SDL_ExtendedGameControllerBind::inputType
SDL_GameControllerBindType inputType
Definition: SDL_gamecontroller.c:52
SDL_PrivateGetControllerMapping
static ControllerMapping_t * SDL_PrivateGetControllerMapping(int device_index)
Definition: SDL_gamecontroller.c:1039
SDL_ControllerDeviceEvent::which
Sint32 which
Definition: SDL_events.h:413
SDL_JoystickGetGUIDString
#define SDL_JoystickGetGUIDString
Definition: SDL_dynapi_overrides.h:201
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:756
SDL_JoystickNameForIndex
#define SDL_JoystickNameForIndex
Definition: SDL_dynapi_overrides.h:196
SDL_GameControllerOpen
SDL_GameController * SDL_GameControllerOpen(int device_index)
Definition: SDL_gamecontroller.c:1518
SDL_GameControllerButtonBind
Definition: SDL_gamecontroller.h:73
SDL_CONTROLLER_AXIS_LEFTX
@ SDL_CONTROLLER_AXIS_LEFTX
Definition: SDL_gamecontroller.h:275
SDL_ControllerMappingPriority
SDL_ControllerMappingPriority
Definition: SDL_gamecontroller.c:87
SDL_JoystickGUID::data
Uint8 data[16]
Definition: SDL_joystick.h:71
input
GLenum GLenum GLenum input
Definition: SDL_opengl_glext.h:9374
path
GLsizei const GLchar *const * path
Definition: SDL_opengl_glext.h:3730
SDL_JOYDEVICEREMOVED
@ SDL_JOYDEVICEREMOVED
Definition: SDL_events.h:117
SDL_GameControllerGetAxis
Sint16 SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
Definition: SDL_gamecontroller.c:1612
SDL_JoystickGetHat
#define SDL_JoystickGetHat
Definition: SDL_dynapi_overrides.h:212
SDL_JoystickGetProduct
#define SDL_JoystickGetProduct
Definition: SDL_dynapi_overrides.h:613
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:191
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
ControllerMapping_t::next
struct _ControllerMapping_t * next
Definition: SDL_gamecontroller.c:99
SDL_JoystickOpen
#define SDL_JoystickOpen
Definition: SDL_dynapi_overrides.h:197
SDL_ExtendedGameControllerBind::output
union SDL_ExtendedGameControllerBind::@23 output
SDL_RWread
#define SDL_RWread(ctx, ptr, size, n)
Definition: SDL_rwops.h:187
SDL_vidpid_list::max_entries
int max_entries
Definition: SDL_gamecontroller.c:128
s_pSupportedControllers
static ControllerMapping_t * s_pSupportedControllers
Definition: SDL_gamecontroller.c:103
SDL_CONTROLLERDEVICEADDED
@ SDL_CONTROLLERDEVICEADDED
Definition: SDL_events.h:123
SDL_JoystickName
#define SDL_JoystickName
Definition: SDL_dynapi_overrides.h:198
SDL_SwapLE16
#define SDL_SwapLE16(X)
Definition: SDL_endian.h:232
_SDL_GameController::bindings
SDL_ExtendedGameControllerBind * bindings
Definition: SDL_gamecontroller.c:116
SDL_CONTROLLERAXISMOTION
@ SDL_CONTROLLERAXISMOTION
Definition: SDL_events.h:120
SDL_GameControllerGetJoystick
SDL_Joystick * SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1759
SDL_CONTROLLER_BUTTON_B
@ SDL_CONTROLLER_BUTTON_B
Definition: SDL_gamecontroller.h:320
SDL_ShouldIgnoreGameController
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
Definition: SDL_gamecontroller.c:1460
SDL_GameControllerName
const char * SDL_GameControllerName(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1707
_SDL_GameController::ref_count
int ref_count
Definition: SDL_gamecontroller.c:112
SDL_CONTROLLER_BUTTON_MAX
@ SDL_CONTROLLER_BUTTON_MAX
Definition: SDL_gamecontroller.h:334
SDL_stack_alloc
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:354
SDL_JoystickGetPlayerIndex
#define SDL_JoystickGetPlayerIndex
Definition: SDL_dynapi_overrides.h:702
SDL_strcasecmp
#define SDL_strcasecmp
Definition: SDL_dynapi_overrides.h:419
SDL_vidpid_list::num_entries
int num_entries
Definition: SDL_gamecontroller.c:127
SDL_CONTROLLER_BUTTON_BACK
@ SDL_CONTROLLER_BUTTON_BACK
Definition: SDL_gamecontroller.h:323
SDL_strncasecmp
#define SDL_strncasecmp
Definition: SDL_dynapi_overrides.h:420
SDL_CONTROLLER_BINDTYPE_BUTTON
@ SDL_CONTROLLER_BINDTYPE_BUTTON
Definition: SDL_gamecontroller.h:64
SDL_CONTROLLER_BUTTON_LEFTSHOULDER
@ SDL_CONTROLLER_BUTTON_LEFTSHOULDER
Definition: SDL_gamecontroller.h:328
SDL_GameControllerInit
int SDL_GameControllerInit(void)
Definition: SDL_gamecontroller.c:1358
SDL_GameControllerGetAxisFromString
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *pchString)
Definition: SDL_gamecontroller.c:461
map_StringForControllerButton
static const char * map_StringForControllerButton[]
Definition: SDL_gamecontroller.c:491
SDL_QUERY
#define SDL_QUERY
Definition: SDL_events.h:753
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
Sint16
int16_t Sint16
Definition: SDL_stdinc.h:185
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: SDL_opengl_glext.h:2480
SDL_GameControllerGetButtonFromString
SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *pchString)
Definition: SDL_gamecontroller.c:513
SDL_PrivateGameControllerRefreshMapping
static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
Definition: SDL_gamecontroller.c:798
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_JoystickGetDeviceGUID
#define SDL_JoystickGetDeviceGUID
Definition: SDL_dynapi_overrides.h:199
SDL_CONTROLLER_MAPPING_PRIORITY_USER
@ SDL_CONTROLLER_MAPPING_PRIORITY_USER
Definition: SDL_gamecontroller.c:90
SDL_GameControllerHandleDelayedGuideButton
void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick)
Definition: SDL_gamecontroller.c:2063
SDL_PrivateGetControllerNameFromMappingString
static char * SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
Definition: SDL_gamecontroller.c:753
SDL_strchr
#define SDL_strchr
Definition: SDL_dynapi_overrides.h:401
SDL_GameControllerBindType
SDL_GameControllerBindType
Definition: SDL_gamecontroller.h:62
SDL_GameControllerMappingForDeviceIndex
char * SDL_GameControllerMappingForDeviceIndex(int joystick_index)
Definition: SDL_gamecontroller.c:1403
SDL_GameControllerGetBindForButton
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
Definition: SDL_gamecontroller.c:1825
SDL_IsJoystickXInput
SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid)
Definition: SDL_joystick.c:1186
SDL_JOYSTICK_AXIS_MIN
#define SDL_JOYSTICK_AXIS_MIN
Definition: SDL_joystick.h:302
SDL_CONTROLLERBUTTONUP
@ SDL_CONTROLLERBUTTONUP
Definition: SDL_events.h:122
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:769
SDL_CONTROLLER_AXIS_TRIGGERLEFT
@ SDL_CONTROLLER_AXIS_TRIGGERLEFT
Definition: SDL_gamecontroller.h:279
mapping
GLenum GLenum GLenum GLenum mapping
Definition: SDL_opengl_glext.h:9374
SDL_GameControllerButtonBind::value
union SDL_GameControllerButtonBind::@0 value
SDL_GetJoystickGUIDInfo
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
Definition: SDL_joystick.c:1113
SDL_GameControllerGetAttached
SDL_bool SDL_GameControllerGetAttached(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1748
SDL_memcmp
#define SDL_memcmp
Definition: SDL_dynapi_overrides.h:389
SDL_ExtendedGameControllerBind::hat_mask
int hat_mask
Definition: SDL_gamecontroller.c:65
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
HandleJoystickButton
static void HandleJoystickButton(SDL_GameController *gamecontroller, int button, Uint8 state)
Definition: SDL_gamecontroller.c:299
SDL_PushEvent
#define SDL_PushEvent
Definition: SDL_dynapi_overrides.h:125
SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT
Definition: SDL_hints.h:463
SDL_GameControllerNumMappings
int SDL_GameControllerNumMappings(void)
Definition: SDL_gamecontroller.c:1195
HandleJoystickHat
static void HandleJoystickHat(SDL_GameController *gamecontroller, int hat, Uint8 value)
Definition: SDL_gamecontroller.c:318
SDL_CONTROLLER_AXIS_INVALID
@ SDL_CONTROLLER_AXIS_INVALID
Definition: SDL_gamecontroller.h:274
SDL_ignored_controllers
static SDL_vidpid_list SDL_ignored_controllers
Definition: SDL_gamecontroller.c:133
s_pXInputMapping
static ControllerMapping_t * s_pXInputMapping
Definition: SDL_gamecontroller.c:106
ControllerMapping_t::name
char * name
Definition: SDL_gamecontroller.c:96
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
s_ControllerMappings
static const char * s_ControllerMappings[]
Definition: SDL_gamecontrollerdb.h:32
SDL_GameControllerMapping
char * SDL_GameControllerMapping(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1270
SDL_strtol
#define SDL_strtol
Definition: SDL_dynapi_overrides.h:412
SDL_CONTROLLER_AXIS_MAX
@ SDL_CONTROLLER_AXIS_MAX
Definition: SDL_gamecontroller.h:281
SDL_GetPlatform
#define SDL_GetPlatform
Definition: SDL_dynapi_overrides.h:291
SDL_JoystickGetAttached
#define SDL_JoystickGetAttached
Definition: SDL_dynapi_overrides.h:203
SDL_JoystickGetDeviceInstanceID
#define SDL_JoystickGetDeviceInstanceID
Definition: SDL_dynapi_overrides.h:626
SDL_isdigit
#define SDL_isdigit
Definition: SDL_dynapi_overrides.h:382
SDL_GameControllerInitMappings
int SDL_GameControllerInitMappings(void)
Definition: SDL_gamecontroller.c:1329
SDL_PeepEvents
#define SDL_PeepEvents
Definition: SDL_dynapi_overrides.h:117
SDL_PrivateLoadButtonMapping
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
Definition: SDL_gamecontroller.c:685
SDL_assert.h
SDL_GetTicks
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
SDL_GameControllerAxis
SDL_GameControllerAxis
Definition: SDL_gamecontroller.h:273
s_pDefaultMapping
static ControllerMapping_t * s_pDefaultMapping
Definition: SDL_gamecontroller.c:104
MAKE_VIDPID
#define MAKE_VIDPID(VID, PID)
Definition: SDL_sysjoystick.h:90
SDL_JOYAXISMOTION
@ SDL_JOYAXISMOTION
Definition: SDL_events.h:111
SDL_GameControllerButtonBind::axis
int axis
Definition: SDL_gamecontroller.h:78
SDL_ExtendedGameControllerBind::axis
int axis
Definition: SDL_gamecontroller.c:58
SDL_CONTROLLER_BUTTON_START
@ SDL_CONTROLLER_BUTTON_START
Definition: SDL_gamecontroller.h:325
SDL_GameControllerNameForIndex
const char * SDL_GameControllerNameForIndex(int device_index)
Definition: SDL_gamecontroller.c:1383
SDL_GameControllerLoadHints
static void SDL_GameControllerLoadHints()
Definition: SDL_gamecontroller.c:1280
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_GameControllerGetPlayerIndex
int SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1720
map_StringForControllerAxis
static const char * map_StringForControllerAxis[]
Definition: SDL_gamecontroller.c:448
SDL_JOYSTICK_AXIS_MAX
#define SDL_JOYSTICK_AXIS_MAX
Definition: SDL_joystick.h:301
size_t
unsigned int size_t
Definition: SDL_config_windows.h:68
axis
SDL_Texture * axis
Definition: testgamecontroller.c:67
ControllerMapping_t::guid
SDL_JoystickGUID guid
Definition: SDL_gamecontroller.c:95
_SDL_GameController::joystick
SDL_Joystick * joystick
Definition: SDL_gamecontroller.c:111
SDL_GameControllerMappingForIndex
char * SDL_GameControllerMappingForIndex(int mapping_index)
Definition: SDL_gamecontroller.c:1213
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_ExtendedGameControllerBind::input
union SDL_ExtendedGameControllerBind::@22 input
_SDL_GameController::last_hat_mask
Uint8 * last_hat_mask
Definition: SDL_gamecontroller.c:118
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
SDL_JoystickUpdate
#define SDL_JoystickUpdate
Definition: SDL_dynapi_overrides.h:209
SDL_JoystickRumble
#define SDL_JoystickRumble
Definition: SDL_dynapi_overrides.h:682
SDL_RWclose
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_atoi
#define SDL_atoi
Definition: SDL_dynapi_overrides.h:410
SDL_PrivateGameControllerAddMapping
static int SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority)
Definition: SDL_gamecontroller.c:1135
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
@ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER
Definition: SDL_gamecontroller.h:329
SDL_CONTROLLER_BINDTYPE_HAT
@ SDL_CONTROLLER_BINDTYPE_HAT
Definition: SDL_gamecontroller.h:66
SDL_GameControllerQuitMappings
void SDL_GameControllerQuitMappings(void)
Definition: SDL_gamecontroller.c:1917
SDL_CONTROLLER_BUTTON_Y
@ SDL_CONTROLLER_BUTTON_Y
Definition: SDL_gamecontroller.h:322
_SDL_GameController::num_bindings
int num_bindings
Definition: SDL_gamecontroller.c:115
sort_controllers.controllers
list controllers
Definition: sort_controllers.py:12
_SDL_GameController
Definition: SDL_gamecontroller.c:110
events
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:35
SDL_vidpid_list
Definition: SDL_gamecontroller.c:126
SDL_gamecontrollerdb.h
SDL_CONTROLLER_BINDTYPE_AXIS
@ SDL_CONTROLLER_BINDTYPE_AXIS
Definition: SDL_gamecontroller.h:65
SDL_GameControllerGetStringForAxis
const char * SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis)
Definition: SDL_gamecontroller.c:483
SDL_AddHintCallback
#define SDL_AddHintCallback
Definition: SDL_dynapi_overrides.h:192
SDL_stack_free
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:355
ControllerMapping_t::mapping
char * mapping
Definition: SDL_gamecontroller.c:97
sort_controllers.output
output
Definition: sort_controllers.py:10
SDL_allowed_controllers
static SDL_vidpid_list SDL_allowed_controllers
Definition: SDL_gamecontroller.c:132
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
SDL_PrivateGetControllerMappingForNameAndGUID
static ControllerMapping_t * SDL_PrivateGetControllerMappingForNameAndGUID(const char *name, SDL_JoystickGUID guid)
Definition: SDL_gamecontroller.c:1006
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_GameControllerClose
void SDL_GameControllerClose(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1860
SDL_JoystickGetAxis
#define SDL_JoystickGetAxis
Definition: SDL_dynapi_overrides.h:211
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:40
SDL_IsGameControllerNameAndGUID
SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
Definition: SDL_gamecontroller.c:1435
SDL_JOYBUTTONUP
@ SDL_JOYBUTTONUP
Definition: SDL_events.h:115
SDL_system.h
SDL_hints.h
SDL_CONTROLLER_AXIS_LEFTY
@ SDL_CONTROLLER_AXIS_LEFTY
Definition: SDL_gamecontroller.h:276
SDL_GameControllerGetVendor
Uint16 SDL_GameControllerGetVendor(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1726
SDL_IGNORE
#define SDL_IGNORE
Definition: SDL_events.h:754
SDL_GameControllerMappingForGUID
char * SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)
Definition: SDL_gamecontroller.c:1246
SDL_HINT_GAMECONTROLLERCONFIG
#define SDL_HINT_GAMECONTROLLERCONFIG
A variable that lets you manually hint extra gamecontroller db entries.
Definition: SDL_hints.h:437
SDL_CONTROLLER_BUTTON_LEFTSTICK
@ SDL_CONTROLLER_BUTTON_LEFTSTICK
Definition: SDL_gamecontroller.h:326
SDL_GameControllerAddMappingsFromRW
int SDL_GameControllerAddMappingsFromRW(SDL_RWops *rw, int freerw)
Definition: SDL_gamecontroller.c:1064
SDL_GETEVENT
@ SDL_GETEVENT
Definition: SDL_events.h:614
SDL_EventState
#define SDL_EventState
Definition: SDL_dynapi_overrides.h:131
SDL_AddEventWatch
#define SDL_AddEventWatch
Definition: SDL_dynapi_overrides.h:128
SDL_GameControllerRumble
int SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
Definition: SDL_gamecontroller.c:1854
SDL_GameControllerQuit
void SDL_GameControllerQuit(void)
Definition: SDL_gamecontroller.c:1906
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
SDL_GameControllerGetProduct
Uint16 SDL_GameControllerGetProduct(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1732
SDL_strlen
#define SDL_strlen
Definition: SDL_dynapi_overrides.h:393
SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT
@ SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT
Definition: SDL_gamecontroller.c:88
SDL_JOYDEVICEADDED
@ SDL_JOYDEVICEADDED
Definition: SDL_events.h:116
SDL_ExtendedGameControllerBind::hat
int hat
Definition: SDL_gamecontroller.c:64
SDL_GameControllerFromInstanceID
SDL_GameController * SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
Definition: SDL_gamecontroller.c:1772
SDL_TICKS_PASSED
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_PrivateGameControllerParseControllerConfigString
static void SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecontroller, const char *pchString)
Definition: SDL_gamecontroller.c:636
SDL_GameControllerGetProductVersion
Uint16 SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1738
SDL_Event
General event structure.
Definition: SDL_events.h:558
SDL_PrivateGameControllerButton
static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state)
Definition: SDL_gamecontroller.c:1974
SDL_CONTROLLER_BUTTON_DPAD_DOWN
@ SDL_CONTROLLER_BUTTON_DPAD_DOWN
Definition: SDL_gamecontroller.h:331
SDL_DelHintCallback
#define SDL_DelHintCallback
Definition: SDL_dynapi_overrides.h:193
SDL_ExtendedGameControllerBind::axis
SDL_GameControllerAxis axis
Definition: SDL_gamecontroller.c:76
SDL_PrivateGetControllerMappingFromMappingString
static char * SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
Definition: SDL_gamecontroller.c:780
s_pHIDAPIMapping
static ControllerMapping_t * s_pHIDAPIMapping
Definition: SDL_gamecontroller.c:105
SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES
Definition: SDL_hints.h:450
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_CONTROLLER_BUTTON_DPAD_UP
@ SDL_CONTROLLER_BUTTON_DPAD_UP
Definition: SDL_gamecontroller.h:330
_SDL_GameController::next
struct _SDL_GameController * next
Definition: SDL_gamecontroller.c:121
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_JOYBUTTONDOWN
@ SDL_JOYBUTTONDOWN
Definition: SDL_events.h:114
SDL_CONTROLLER_AXIS_TRIGGERRIGHT
@ SDL_CONTROLLER_AXIS_TRIGGERRIGHT
Definition: SDL_gamecontroller.h:280
SDL_LoadFile
#define SDL_LoadFile(file, datasize)
Definition: SDL_rwops.h:214
SDL_strcmp
#define SDL_strcmp
Definition: SDL_dynapi_overrides.h:417
SDL_strstr
#define SDL_strstr
Definition: SDL_dynapi_overrides.h:403
SDL_CONTROLLERDEVICEREMAPPED
@ SDL_CONTROLLERDEVICEREMAPPED
Definition: SDL_events.h:125
SDL_CONTROLLER_AXIS_RIGHTY
@ SDL_CONTROLLER_AXIS_RIGHTY
Definition: SDL_gamecontroller.h:278
SDL_CONTROLLER_BUTTON_X
@ SDL_CONTROLLER_BUTTON_X
Definition: SDL_gamecontroller.h:321
SDL_ExtendedGameControllerBind::axis_max
int axis_max
Definition: SDL_gamecontroller.c:60
SDL_JoystickGUID
Definition: SDL_joystick.h:70
SDL_RWops
Definition: SDL_rwops.h:53
SDL_GameControllerEventState
int SDL_GameControllerEventState(int state)
Definition: SDL_gamecontroller.c:2031
SDL_Event::cdevice
SDL_ControllerDeviceEvent cdevice
Definition: SDL_events.h:576
SDL_CONTROLLER_BUTTON_A
@ SDL_CONTROLLER_BUTTON_A
Definition: SDL_gamecontroller.h:319
state
struct xkb_state * state
Definition: SDL_waylandsym.h:113
SDL_GameControllerAddMappingsFromFile
#define SDL_GameControllerAddMappingsFromFile(file)
Definition: SDL_gamecontroller.h:129
SDL_GameControllerGetBindForAxis
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
Definition: SDL_gamecontroller.c:1793
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_JoystickGetProductVersion
#define SDL_JoystickGetProductVersion
Definition: SDL_dynapi_overrides.h:614
_SDL_GameController::name
const char * name
Definition: SDL_gamecontroller.c:114
SDL_JOYHATMOTION
@ SDL_JOYHATMOTION
Definition: SDL_events.h:113
ResetOutput
static void ResetOutput(SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind)
Definition: SDL_gamecontroller.c:238
SDL_LockJoysticks
#define SDL_LockJoysticks
Definition: SDL_dynapi_overrides.h:638
button
SDL_Texture * button
Definition: testgamecontroller.c:67
SDL_CONTROLLER_BUTTON_DPAD_RIGHT
@ SDL_CONTROLLER_BUTTON_DPAD_RIGHT
Definition: SDL_gamecontroller.h:333
SDL_AndroidGetInternalStoragePath
#define SDL_AndroidGetInternalStoragePath
Definition: SDL_dynapi_overrides.h:51
SDL_GetControllerMappingFilePath
static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size)
Definition: SDL_gamecontroller.c:1313
SDL_PEEKEVENT
@ SDL_PEEKEVENT
Definition: SDL_events.h:613
SDL_DelEventWatch
#define SDL_DelEventWatch
Definition: SDL_dynapi_overrides.h:129
SDL_GameControllerIgnoreDevicesExceptChanged
static void SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
Definition: SDL_gamecontroller.c:188
SDL_CONTROLLER_BUTTON_GUIDE
@ SDL_CONTROLLER_BUTTON_GUIDE
Definition: SDL_gamecontroller.h:324
SDL_GameControllerAddMapping
int SDL_GameControllerAddMapping(const char *mappingString)
Definition: SDL_gamecontroller.c:1186
SDL_JoystickGetGUIDFromString
#define SDL_JoystickGetGUIDFromString
Definition: SDL_dynapi_overrides.h:202
SDL_PrivateAddMappingForGUID
static ControllerMapping_t * SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)
Definition: SDL_gamecontroller.c:822
SDL_GameControllerButton
SDL_GameControllerButton
Definition: SDL_gamecontroller.h:317