SDL 2.0
SDL_gamecontroller.c File Reference
#include "../SDL_internal.h"
#include "SDL_events.h"
#include "SDL_assert.h"
#include "SDL_hints.h"
#include "SDL_timer.h"
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_gamecontrollerdb.h"
#include "../events/SDL_events_c.h"
+ Include dependency graph for SDL_gamecontroller.c:

Go to the source code of this file.

Data Structures

struct  SDL_ExtendedGameControllerBind
 
struct  ControllerMapping_t
 
struct  SDL_GameController
 
struct  SDL_vidpid_list
 

Macros

#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS   250
 
#define SDL_CONTROLLER_PLATFORM_FIELD   "platform:"
 

Enumerations

enum  SDL_ControllerMappingPriority {
  SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT ,
  SDL_CONTROLLER_MAPPING_PRIORITY_API ,
  SDL_CONTROLLER_MAPPING_PRIORITY_USER
}
 

Functions

static void SDL_LoadVIDPIDListFromHint (const char *hint, SDL_vidpid_list *list)
 
static void SDL_GameControllerIgnoreDevicesChanged (void *userdata, const char *name, const char *oldValue, const char *hint)
 
static void SDL_GameControllerIgnoreDevicesExceptChanged (void *userdata, const char *name, const char *oldValue, const char *hint)
 
static int SDL_PrivateGameControllerAxis (SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
 
static int SDL_PrivateGameControllerButton (SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state)
 
static void UpdateEventsForDeviceRemoval ()
 
static SDL_bool HasSameOutput (SDL_ExtendedGameControllerBind *a, SDL_ExtendedGameControllerBind *b)
 
static void ResetOutput (SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind)
 
static void HandleJoystickAxis (SDL_GameController *gamecontroller, int axis, int value)
 
static void HandleJoystickButton (SDL_GameController *gamecontroller, int button, Uint8 state)
 
static void HandleJoystickHat (SDL_GameController *gamecontroller, int hat, Uint8 value)
 
static int SDL_GameControllerEventWatcher (void *userdata, SDL_Event *event)
 
static ControllerMapping_tSDL_PrivateGetControllerMappingForGUID (SDL_JoystickGUID *guid, SDL_bool exact_match)
 
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString (const char *pchString)
 
const char * SDL_GameControllerGetStringForAxis (SDL_GameControllerAxis axis)
 
SDL_GameControllerButton SDL_GameControllerGetButtonFromString (const char *pchString)
 
const char * SDL_GameControllerGetStringForButton (SDL_GameControllerButton axis)
 
static void SDL_PrivateGameControllerParseElement (SDL_GameController *gamecontroller, const char *szGameButton, const char *szJoystickButton)
 
static void SDL_PrivateGameControllerParseControllerConfigString (SDL_GameController *gamecontroller, const char *pchString)
 
static void SDL_PrivateLoadButtonMapping (SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
 
static char * SDL_PrivateGetControllerGUIDFromMappingString (const char *pMapping)
 
static char * SDL_PrivateGetControllerNameFromMappingString (const char *pMapping)
 
static char * SDL_PrivateGetControllerMappingFromMappingString (const char *pMapping)
 
static void SDL_PrivateGameControllerRefreshMapping (ControllerMapping_t *pControllerMapping)
 
static ControllerMapping_tSDL_PrivateAddMappingForGUID (SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)
 
static ControllerMapping_tSDL_PrivateGetControllerMappingForNameAndGUID (const char *name, SDL_JoystickGUID guid)
 
static ControllerMapping_tSDL_PrivateGetControllerMapping (int device_index)
 
int SDL_GameControllerAddMappingsFromRW (SDL_RWops *rw, int freerw)
 
static int SDL_PrivateGameControllerAddMapping (const char *mappingString, SDL_ControllerMappingPriority priority)
 
int SDL_GameControllerAddMapping (const char *mappingString)
 
int SDL_GameControllerNumMappings (void)
 
char * SDL_GameControllerMappingForIndex (int mapping_index)
 
char * SDL_GameControllerMappingForGUID (SDL_JoystickGUID guid)
 
char * SDL_GameControllerMapping (SDL_GameController *gamecontroller)
 
static void SDL_GameControllerLoadHints ()
 
static SDL_bool SDL_GetControllerMappingFilePath (char *path, size_t size)
 
int SDL_GameControllerInitMappings (void)
 
int SDL_GameControllerInit (void)
 
const char * SDL_GameControllerNameForIndex (int device_index)
 
char * SDL_GameControllerMappingForDeviceIndex (int joystick_index)
 
SDL_bool SDL_IsGameControllerNameAndGUID (const char *name, SDL_JoystickGUID guid)
 
SDL_bool SDL_IsGameController (int device_index)
 
SDL_bool SDL_ShouldIgnoreGameController (const char *name, SDL_JoystickGUID guid)
 
SDL_GameController * SDL_GameControllerOpen (int device_index)
 
void SDL_GameControllerUpdate (void)
 
Sint16 SDL_GameControllerGetAxis (SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
 
Uint8 SDL_GameControllerGetButton (SDL_GameController *gamecontroller, SDL_GameControllerButton button)
 
const char * SDL_GameControllerName (SDL_GameController *gamecontroller)
 
int SDL_GameControllerGetPlayerIndex (SDL_GameController *gamecontroller)
 
Uint16 SDL_GameControllerGetVendor (SDL_GameController *gamecontroller)
 
Uint16 SDL_GameControllerGetProduct (SDL_GameController *gamecontroller)
 
Uint16 SDL_GameControllerGetProductVersion (SDL_GameController *gamecontroller)
 
SDL_bool SDL_GameControllerGetAttached (SDL_GameController *gamecontroller)
 
SDL_Joystick * SDL_GameControllerGetJoystick (SDL_GameController *gamecontroller)
 
SDL_GameController * SDL_GameControllerFromInstanceID (SDL_JoystickID joyid)
 
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis (SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
 
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton (SDL_GameController *gamecontroller, SDL_GameControllerButton button)
 
int SDL_GameControllerRumble (SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
 
void SDL_GameControllerClose (SDL_GameController *gamecontroller)
 
void SDL_GameControllerQuit (void)
 
void SDL_GameControllerQuitMappings (void)
 
int SDL_GameControllerEventState (int state)
 
void SDL_GameControllerHandleDelayedGuideButton (SDL_Joystick *joystick)
 

Variables

static SDL_GameController * SDL_gamecontrollers = NULL
 
static SDL_JoystickGUID s_zeroGUID
 
static ControllerMapping_ts_pSupportedControllers = NULL
 
static ControllerMapping_ts_pDefaultMapping = NULL
 
static ControllerMapping_ts_pHIDAPIMapping = NULL
 
static ControllerMapping_ts_pXInputMapping = NULL
 
static SDL_vidpid_list SDL_allowed_controllers
 
static SDL_vidpid_list SDL_ignored_controllers
 
static const char * map_StringForControllerAxis []
 
static const char * map_StringForControllerButton []
 

Macro Definition Documentation

◆ SDL_CONTROLLER_PLATFORM_FIELD

#define SDL_CONTROLLER_PLATFORM_FIELD   "platform:"

Definition at line 45 of file SDL_gamecontroller.c.

◆ SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS

#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS   250

Definition at line 43 of file SDL_gamecontroller.c.

Enumeration Type Documentation

◆ SDL_ControllerMappingPriority

Enumerator
SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT 
SDL_CONTROLLER_MAPPING_PRIORITY_API 
SDL_CONTROLLER_MAPPING_PRIORITY_USER 

Definition at line 86 of file SDL_gamecontroller.c.

Function Documentation

◆ HandleJoystickAxis()

static void HandleJoystickAxis ( SDL_GameController *  gamecontroller,
int  axis,
int  value 
)
static

Definition at line 248 of file SDL_gamecontroller.c.

249{
250 int i;
251 SDL_ExtendedGameControllerBind *last_match = gamecontroller->last_match_axis[axis];
253
254 for (i = 0; i < gamecontroller->num_bindings; ++i) {
255 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
256 if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
257 axis == binding->input.axis.axis) {
258 if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
259 if (value >= binding->input.axis.axis_min &&
260 value <= binding->input.axis.axis_max) {
261 match = binding;
262 break;
263 }
264 } else {
265 if (value >= binding->input.axis.axis_max &&
266 value <= binding->input.axis.axis_min) {
267 match = binding;
268 break;
269 }
270 }
271 }
272 }
273
274 if (last_match && (!match || !HasSameOutput(last_match, match))) {
275 /* Clear the last input that this axis generated */
276 ResetOutput(gamecontroller, last_match);
277 }
278
279 if (match) {
281 if (match->input.axis.axis_min != match->output.axis.axis_min || match->input.axis.axis_max != match->output.axis.axis_max) {
282 float normalized_value = (float)(value - match->input.axis.axis_min) / (match->input.axis.axis_max - match->input.axis.axis_min);
283 value = match->output.axis.axis_min + (int)(normalized_value * (match->output.axis.axis_max - match->output.axis.axis_min));
284 }
285 SDL_PrivateGameControllerAxis(gamecontroller, match->output.axis.axis, (Sint16)value);
286 } else {
287 Uint8 state;
288 int threshold = match->input.axis.axis_min + (match->input.axis.axis_max - match->input.axis.axis_min) / 2;
289 if (match->input.axis.axis_max < match->input.axis.axis_min) {
290 state = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
291 } else {
292 state = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
293 }
294 SDL_PrivateGameControllerButton(gamecontroller, match->output.button, state);
295 }
296 }
297 gamecontroller->last_match_axis[axis] = match;
298}
#define SDL_RELEASED
Definition: SDL_events.h:49
#define SDL_PRESSED
Definition: SDL_events.h:50
static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state)
static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
static SDL_bool HasSameOutput(SDL_ExtendedGameControllerBind *a, SDL_ExtendedGameControllerBind *b)
static void ResetOutput(SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind)
@ SDL_CONTROLLER_BINDTYPE_AXIS
GLsizei const GLfloat * value
GLenum GLenum GLenum input
int16_t Sint16
Definition: SDL_stdinc.h:185
uint8_t Uint8
Definition: SDL_stdinc.h:179
struct xkb_state * state
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 NULL
Definition: begin_code.h:167
SDL_GameControllerBindType outputType
union SDL_ExtendedGameControllerBind::@24 input
union SDL_ExtendedGameControllerBind::@25 output
SDL_GameControllerBindType inputType
SDL_Texture * axis

References SDL_ExtendedGameControllerBind::axis, axis, SDL_ExtendedGameControllerBind::button, HasSameOutput(), i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, NULL, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, ResetOutput(), SDL_CONTROLLER_BINDTYPE_AXIS, SDL_PRESSED, SDL_PrivateGameControllerAxis(), SDL_PrivateGameControllerButton(), SDL_RELEASED, and state.

Referenced by SDL_GameControllerEventWatcher().

◆ HandleJoystickButton()

static void HandleJoystickButton ( SDL_GameController *  gamecontroller,
int  button,
Uint8  state 
)
static

Definition at line 300 of file SDL_gamecontroller.c.

301{
302 int i;
303
304 for (i = 0; i < gamecontroller->num_bindings; ++i) {
305 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
307 button == binding->input.button) {
309 int value = state ? binding->output.axis.axis_max : binding->output.axis.axis_min;
310 SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)value);
311 } else {
312 SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, state);
313 }
314 break;
315 }
316 }
317}
@ SDL_CONTROLLER_BINDTYPE_BUTTON
SDL_Texture * button

References SDL_ExtendedGameControllerBind::axis, SDL_ExtendedGameControllerBind::button, button, i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_PrivateGameControllerAxis(), SDL_PrivateGameControllerButton(), and state.

Referenced by SDL_GameControllerEventWatcher().

◆ HandleJoystickHat()

static void HandleJoystickHat ( SDL_GameController *  gamecontroller,
int  hat,
Uint8  value 
)
static

Definition at line 319 of file SDL_gamecontroller.c.

320{
321 int i;
322 Uint8 last_mask = gamecontroller->last_hat_mask[hat];
323 Uint8 changed_mask = (last_mask ^ value);
324
325 for (i = 0; i < gamecontroller->num_bindings; ++i) {
326 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
327 if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT && hat == binding->input.hat.hat) {
328 if ((changed_mask & binding->input.hat.hat_mask) != 0) {
329 if (value & binding->input.hat.hat_mask) {
331 SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)binding->output.axis.axis_max);
332 } else {
333 SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, SDL_PRESSED);
334 }
335 } else {
336 ResetOutput(gamecontroller, binding);
337 }
338 }
339 }
340 }
341 gamecontroller->last_hat_mask[hat] = value;
342}
@ SDL_CONTROLLER_BINDTYPE_HAT

References SDL_ExtendedGameControllerBind::axis, SDL_ExtendedGameControllerBind::button, SDL_ExtendedGameControllerBind::hat, i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, ResetOutput(), SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_HAT, SDL_PRESSED, SDL_PrivateGameControllerAxis(), and SDL_PrivateGameControllerButton().

Referenced by SDL_GameControllerEventWatcher().

◆ HasSameOutput()

static SDL_bool HasSameOutput ( SDL_ExtendedGameControllerBind a,
SDL_ExtendedGameControllerBind b 
)
static

Definition at line 226 of file SDL_gamecontroller.c.

227{
228 if (a->outputType != b->outputType) {
229 return SDL_FALSE;
230 }
231
232 if (a->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
233 return (a->output.axis.axis == b->output.axis.axis);
234 } else {
235 return (a->output.button == b->output.button);
236 }
237}
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
@ SDL_FALSE
Definition: SDL_stdinc.h:163

References SDL_CONTROLLER_BINDTYPE_AXIS, and SDL_FALSE.

Referenced by HandleJoystickAxis().

◆ ResetOutput()

◆ SDL_GameControllerAddMapping()

int SDL_GameControllerAddMapping ( const char *  mappingString)

Add or update an existing mapping configuration

Returns
1 if mapping is added, 0 if updated, -1 on error

Definition at line 1200 of file SDL_gamecontroller.c.

1201{
1203}
static int SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority)

References SDL_CONTROLLER_MAPPING_PRIORITY_API, and SDL_PrivateGameControllerAddMapping().

Referenced by SDL_GameControllerAddMappingsFromRW().

◆ SDL_GameControllerAddMappingsFromRW()

int SDL_GameControllerAddMappingsFromRW ( SDL_RWops rw,
int  freerw 
)

To count the number of game controllers in the system for the following: int nJoysticks = SDL_NumJoysticks(); int nGameControllers = 0; for (int i = 0; i < nJoysticks; i++) { if (SDL_IsGameController(i)) { nGameControllers++; } }

Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: guid,name,mappings

Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. The mapping format for joystick is: bX - a joystick button, index X hX.Y - hat X with value Y aX - axis X of the joystick Buttons can be used as a controller axis and vice versa.

This string shows an example of a valid mapping for a controller "03000000341a00003608000000000000,PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", Load a set of mappings from a seekable SDL data stream (memory or file), filtered by the current SDL_GetPlatform() A community sourced database of controllers is available at https://raw.github.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt

If freerw is non-zero, the stream will be closed after being read.

Returns
number of mappings added, -1 on error

Definition at line 1078 of file SDL_gamecontroller.c.

1079{
1080 const char *platform = SDL_GetPlatform();
1081 int controllers = 0;
1082 char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
1083 size_t db_size, platform_len;
1084
1085 if (rw == NULL) {
1086 return SDL_SetError("Invalid RWops");
1087 }
1088 db_size = (size_t)SDL_RWsize(rw);
1089
1090 buf = (char *)SDL_malloc(db_size + 1);
1091 if (buf == NULL) {
1092 if (freerw) {
1093 SDL_RWclose(rw);
1094 }
1095 return SDL_SetError("Could not allocate space to read DB into memory");
1096 }
1097
1098 if (SDL_RWread(rw, buf, db_size, 1) != 1) {
1099 if (freerw) {
1100 SDL_RWclose(rw);
1101 }
1102 SDL_free(buf);
1103 return SDL_SetError("Could not read DB");
1104 }
1105
1106 if (freerw) {
1107 SDL_RWclose(rw);
1108 }
1109
1110 buf[db_size] = '\0';
1111 line = buf;
1112
1113 while (line < buf + db_size) {
1114 line_end = SDL_strchr(line, '\n');
1115 if (line_end != NULL) {
1116 *line_end = '\0';
1117 } else {
1118 line_end = buf + db_size;
1119 }
1120
1121 /* Extract and verify the platform */
1123 if (tmp != NULL) {
1125 comma = SDL_strchr(tmp, ',');
1126 if (comma != NULL) {
1127 platform_len = comma - tmp + 1;
1128 if (platform_len + 1 < SDL_arraysize(line_platform)) {
1129 SDL_strlcpy(line_platform, tmp, platform_len);
1130 if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 &&
1131 SDL_GameControllerAddMapping(line) > 0) {
1132 controllers++;
1133 }
1134 }
1135 }
1136 }
1137
1138 line = line_end + 1;
1139 }
1140
1141 SDL_free(buf);
1142 return controllers;
1143}
unsigned int size_t
#define SDL_SetError
#define SDL_strchr
#define SDL_RWread
#define SDL_malloc
#define SDL_strlen
#define SDL_strlcpy
#define SDL_GetPlatform
#define SDL_free
#define SDL_strstr
#define SDL_RWsize
#define SDL_RWclose
#define SDL_strncasecmp
int SDL_GameControllerAddMapping(const char *mappingString)
#define SDL_CONTROLLER_PLATFORM_FIELD
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115

References sort_controllers::controllers, NULL, SDL_arraysize, SDL_CONTROLLER_PLATFORM_FIELD, SDL_free, SDL_GameControllerAddMapping(), SDL_GetPlatform, SDL_malloc, SDL_RWclose, SDL_RWread, SDL_RWsize, SDL_SetError, SDL_strchr, SDL_strlcpy, SDL_strlen, SDL_strncasecmp, and SDL_strstr.

◆ SDL_GameControllerClose()

void SDL_GameControllerClose ( SDL_GameController *  gamecontroller)

Close a controller previously opened with SDL_GameControllerOpen().

Definition at line 1885 of file SDL_gamecontroller.c.

1886{
1887 SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
1888
1889 if (!gamecontroller)
1890 return;
1891
1893
1894 /* First decrement ref count */
1895 if (--gamecontroller->ref_count > 0) {
1897 return;
1898 }
1899
1900 SDL_JoystickClose(gamecontroller->joystick);
1901
1902 gamecontrollerlist = SDL_gamecontrollers;
1903 gamecontrollerlistprev = NULL;
1904 while (gamecontrollerlist) {
1905 if (gamecontroller == gamecontrollerlist) {
1906 if (gamecontrollerlistprev) {
1907 /* unlink this entry */
1908 gamecontrollerlistprev->next = gamecontrollerlist->next;
1909 } else {
1910 SDL_gamecontrollers = gamecontroller->next;
1911 }
1912 break;
1913 }
1914 gamecontrollerlistprev = gamecontrollerlist;
1915 gamecontrollerlist = gamecontrollerlist->next;
1916 }
1917
1918 SDL_free(gamecontroller->bindings);
1919 SDL_free(gamecontroller->last_match_axis);
1920 SDL_free(gamecontroller->last_hat_mask);
1921 SDL_free(gamecontroller);
1922
1924}
#define SDL_LockJoysticks
#define SDL_JoystickClose
#define SDL_UnlockJoysticks
static SDL_GameController * SDL_gamecontrollers

References NULL, SDL_free, SDL_gamecontrollers, SDL_JoystickClose, SDL_LockJoysticks, and SDL_UnlockJoysticks.

Referenced by SDL_GameControllerQuit().

◆ SDL_GameControllerEventState()

int SDL_GameControllerEventState ( int  state)

Enable/disable controller event polling.

If controller events are disabled, you must call SDL_GameControllerUpdate() yourself and check the state of the controller when you want controller information.

The state can be one of SDL_QUERY, SDL_ENABLE or SDL_IGNORE.

Definition at line 2056 of file SDL_gamecontroller.c.

2057{
2058#if SDL_EVENTS_DISABLED
2059 return SDL_IGNORE;
2060#else
2061 const Uint32 event_list[] = {
2064 };
2065 unsigned int i;
2066
2067 switch (state) {
2068 case SDL_QUERY:
2069 state = SDL_IGNORE;
2070 for (i = 0; i < SDL_arraysize(event_list); ++i) {
2071 state = SDL_EventState(event_list[i], SDL_QUERY);
2072 if (state == SDL_ENABLE) {
2073 break;
2074 }
2075 }
2076 break;
2077 default:
2078 for (i = 0; i < SDL_arraysize(event_list); ++i) {
2079 SDL_EventState(event_list[i], state);
2080 }
2081 break;
2082 }
2083 return (state);
2084#endif /* SDL_EVENTS_DISABLED */
2085}
#define SDL_EventState
@ SDL_CONTROLLERBUTTONUP
Definition: SDL_events.h:122
@ SDL_CONTROLLERDEVICEADDED
Definition: SDL_events.h:123
@ SDL_CONTROLLERBUTTONDOWN
Definition: SDL_events.h:121
@ SDL_CONTROLLERAXISMOTION
Definition: SDL_events.h:120
@ SDL_CONTROLLERDEVICEREMOVED
Definition: SDL_events.h:124
@ SDL_CONTROLLERDEVICEREMAPPED
Definition: SDL_events.h:125
#define SDL_QUERY
Definition: SDL_events.h:756
#define SDL_ENABLE
Definition: SDL_events.h:759
#define SDL_IGNORE
Definition: SDL_events.h:757
uint32_t Uint32
Definition: SDL_stdinc.h:203

References i, SDL_arraysize, SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMAPPED, SDL_CONTROLLERDEVICEREMOVED, SDL_ENABLE, SDL_EventState, SDL_IGNORE, SDL_QUERY, and state.

◆ SDL_GameControllerEventWatcher()

static int SDL_GameControllerEventWatcher ( void userdata,
SDL_Event event 
)
static

Definition at line 347 of file SDL_gamecontroller.c.

348{
349 switch(event->type) {
351 {
352 SDL_GameController *controllerlist = SDL_gamecontrollers;
353 while (controllerlist) {
354 if (controllerlist->joystick->instance_id == event->jaxis.which) {
355 HandleJoystickAxis(controllerlist, event->jaxis.axis, event->jaxis.value);
356 break;
357 }
358 controllerlist = controllerlist->next;
359 }
360 }
361 break;
363 case SDL_JOYBUTTONUP:
364 {
365 SDL_GameController *controllerlist = SDL_gamecontrollers;
366 while (controllerlist) {
367 if (controllerlist->joystick->instance_id == event->jbutton.which) {
368 HandleJoystickButton(controllerlist, event->jbutton.button, event->jbutton.state);
369 break;
370 }
371 controllerlist = controllerlist->next;
372 }
373 }
374 break;
375 case SDL_JOYHATMOTION:
376 {
377 SDL_GameController *controllerlist = SDL_gamecontrollers;
378 while (controllerlist) {
379 if (controllerlist->joystick->instance_id == event->jhat.which) {
380 HandleJoystickHat(controllerlist, event->jhat.hat, event->jhat.value);
381 break;
382 }
383 controllerlist = controllerlist->next;
384 }
385 }
386 break;
388 {
389 if (SDL_IsGameController(event->jdevice.which)) {
390 SDL_Event deviceevent;
391 deviceevent.type = SDL_CONTROLLERDEVICEADDED;
392 deviceevent.cdevice.which = event->jdevice.which;
393 SDL_PushEvent(&deviceevent);
394 }
395 }
396 break;
398 {
399 SDL_GameController *controllerlist = SDL_gamecontrollers;
400 while (controllerlist) {
401 if (controllerlist->joystick->instance_id == event->jdevice.which) {
402 SDL_Event deviceevent;
403
404 deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
405 deviceevent.cdevice.which = event->jdevice.which;
406 SDL_PushEvent(&deviceevent);
407
409 break;
410 }
411 controllerlist = controllerlist->next;
412 }
413 }
414 break;
415 default:
416 break;
417 }
418
419 return 1;
420}
#define SDL_PushEvent
@ SDL_JOYDEVICEADDED
Definition: SDL_events.h:116
@ SDL_JOYBUTTONDOWN
Definition: SDL_events.h:114
@ SDL_JOYDEVICEREMOVED
Definition: SDL_events.h:117
@ SDL_JOYBUTTONUP
Definition: SDL_events.h:115
@ SDL_JOYAXISMOTION
Definition: SDL_events.h:111
@ SDL_JOYHATMOTION
Definition: SDL_events.h:113
SDL_bool SDL_IsGameController(int device_index)
static void HandleJoystickButton(SDL_GameController *gamecontroller, int button, Uint8 state)
static void UpdateEventsForDeviceRemoval()
static void HandleJoystickHat(SDL_GameController *gamecontroller, int hat, Uint8 value)
static void HandleJoystickAxis(SDL_GameController *gamecontroller, int axis, int value)
struct _cl_event * event
General event structure.
Definition: SDL_events.h:558
Uint32 type
Definition: SDL_events.h:559
SDL_ControllerDeviceEvent cdevice
Definition: SDL_events.h:576

References SDL_Event::cdevice, HandleJoystickAxis(), HandleJoystickButton(), HandleJoystickHat(), SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_gamecontrollers, SDL_IsGameController(), SDL_JOYAXISMOTION, SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED, SDL_JOYHATMOTION, SDL_PushEvent, SDL_Event::type, UpdateEventsForDeviceRemoval(), and SDL_ControllerDeviceEvent::which.

Referenced by SDL_GameControllerInit(), and SDL_GameControllerQuitMappings().

◆ SDL_GameControllerFromInstanceID()

SDL_GameController * SDL_GameControllerFromInstanceID ( SDL_JoystickID  joyid)

Return the SDL_GameController associated with an instance id.

Definition at line 1797 of file SDL_gamecontroller.c.

1798{
1799 SDL_GameController *gamecontroller;
1800
1802 gamecontroller = SDL_gamecontrollers;
1803 while (gamecontroller) {
1804 if (gamecontroller->joystick->instance_id == joyid) {
1806 return gamecontroller;
1807 }
1808 gamecontroller = gamecontroller->next;
1809 }
1811 return NULL;
1812}

References NULL, SDL_gamecontrollers, SDL_LockJoysticks, and SDL_UnlockJoysticks.

◆ SDL_GameControllerGetAttached()

SDL_bool SDL_GameControllerGetAttached ( SDL_GameController *  gamecontroller)

Returns SDL_TRUE if the controller has been opened and currently connected, or SDL_FALSE if it has not.

Definition at line 1773 of file SDL_gamecontroller.c.

1774{
1775 if (!gamecontroller)
1776 return SDL_FALSE;
1777
1778 return SDL_JoystickGetAttached(gamecontroller->joystick);
1779}
#define SDL_JoystickGetAttached

References SDL_FALSE, and SDL_JoystickGetAttached.

◆ SDL_GameControllerGetAxis()

Sint16 SDL_GameControllerGetAxis ( SDL_GameController *  gamecontroller,
SDL_GameControllerAxis  axis 
)

Get the current state of an axis control on a game controller.

The state is a value ranging from -32768 to 32767 (except for the triggers, which range from 0 to 32767).

The axis indices start at index 0.

Definition at line 1635 of file SDL_gamecontroller.c.

1636{
1637 int i;
1638
1639 if (!gamecontroller)
1640 return 0;
1641
1642 for (i = 0; i < gamecontroller->num_bindings; ++i) {
1643 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1644 if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
1645 int value = 0;
1646 SDL_bool valid_input_range;
1647 SDL_bool valid_output_range;
1648
1649 if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1650 value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
1651 if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
1652 valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
1653 } else {
1654 valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
1655 }
1656 if (valid_input_range) {
1657 if (binding->input.axis.axis_min != binding->output.axis.axis_min || binding->input.axis.axis_max != binding->output.axis.axis_max) {
1658 float normalized_value = (float)(value - binding->input.axis.axis_min) / (binding->input.axis.axis_max - binding->input.axis.axis_min);
1659 value = binding->output.axis.axis_min + (int)(normalized_value * (binding->output.axis.axis_max - binding->output.axis.axis_min));
1660 }
1661 } else {
1662 value = 0;
1663 }
1664 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1665 value = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
1666 if (value == SDL_PRESSED) {
1667 value = binding->output.axis.axis_max;
1668 }
1669 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1670 int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
1671 if (hat_mask & binding->input.hat.hat_mask) {
1672 value = binding->output.axis.axis_max;
1673 }
1674 }
1675
1676 if (binding->output.axis.axis_min < binding->output.axis.axis_max) {
1677 valid_output_range = (value >= binding->output.axis.axis_min && value <= binding->output.axis.axis_max);
1678 } else {
1679 valid_output_range = (value >= binding->output.axis.axis_max && value <= binding->output.axis.axis_min);
1680 }
1681 /* If the value is zero, there might be another binding that makes it non-zero */
1682 if (value != 0 && valid_output_range) {
1683 return (Sint16)value;
1684 }
1685 }
1686 }
1687 return 0;
1688}
#define SDL_JoystickGetAxis
#define SDL_JoystickGetHat
#define SDL_JoystickGetButton
SDL_bool
Definition: SDL_stdinc.h:162

References SDL_ExtendedGameControllerBind::axis, axis, SDL_ExtendedGameControllerBind::button, SDL_ExtendedGameControllerBind::hat, i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_HAT, SDL_JoystickGetAxis, SDL_JoystickGetButton, SDL_JoystickGetHat, and SDL_PRESSED.

◆ SDL_GameControllerGetAxisFromString()

SDL_GameControllerAxis SDL_GameControllerGetAxisFromString ( const char *  pchString)

turn this string into a axis mapping

Definition at line 462 of file SDL_gamecontroller.c.

463{
464 int entry;
465
466 if (pchString && (*pchString == '+' || *pchString == '-')) {
467 ++pchString;
468 }
469
470 if (!pchString || !pchString[0]) {
472 }
473
474 for (entry = 0; map_StringForControllerAxis[entry]; ++entry) {
475 if (!SDL_strcasecmp(pchString, map_StringForControllerAxis[entry]))
476 return (SDL_GameControllerAxis) entry;
477 }
479}
#define SDL_strcasecmp
static const char * map_StringForControllerAxis[]
SDL_GameControllerAxis
@ SDL_CONTROLLER_AXIS_INVALID

References map_StringForControllerAxis, SDL_CONTROLLER_AXIS_INVALID, and SDL_strcasecmp.

Referenced by SDL_PrivateGameControllerParseElement().

◆ SDL_GameControllerGetBindForAxis()

SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis ( SDL_GameController *  gamecontroller,
SDL_GameControllerAxis  axis 
)

Get the SDL joystick layer binding for this controller button mapping

Definition at line 1818 of file SDL_gamecontroller.c.

1819{
1820 int i;
1822 SDL_zero(bind);
1823
1824 if (!gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID)
1825 return bind;
1826
1827 for (i = 0; i < gamecontroller->num_bindings; ++i) {
1828 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1829 if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
1830 bind.bindType = binding->inputType;
1831 if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1832 /* FIXME: There might be multiple axes bound now that we have axis ranges... */
1833 bind.value.axis = binding->input.axis.axis;
1834 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1835 bind.value.button = binding->input.button;
1836 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1837 bind.value.hat.hat = binding->input.hat.hat;
1838 bind.value.hat.hat_mask = binding->input.hat.hat_mask;
1839 }
1840 break;
1841 }
1842 }
1843 return bind;
1844}
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
SDL_GameControllerBindType bindType
union SDL_GameControllerButtonBind::@0 value

References SDL_GameControllerButtonBind::axis, SDL_ExtendedGameControllerBind::axis, axis, SDL_GameControllerButtonBind::bindType, SDL_GameControllerButtonBind::button, SDL_ExtendedGameControllerBind::button, SDL_GameControllerButtonBind::hat, SDL_ExtendedGameControllerBind::hat, i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_CONTROLLER_AXIS_INVALID, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_HAT, SDL_zero, and SDL_GameControllerButtonBind::value.

◆ SDL_GameControllerGetBindForButton()

SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton ( SDL_GameController *  gamecontroller,
SDL_GameControllerButton  button 
)

Get the SDL joystick layer binding for this controller button mapping

Definition at line 1850 of file SDL_gamecontroller.c.

1851{
1852 int i;
1854 SDL_zero(bind);
1855
1856 if (!gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID)
1857 return bind;
1858
1859 for (i = 0; i < gamecontroller->num_bindings; ++i) {
1860 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1861 if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
1862 bind.bindType = binding->inputType;
1863 if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1864 bind.value.axis = binding->input.axis.axis;
1865 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1866 bind.value.button = binding->input.button;
1867 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1868 bind.value.hat.hat = binding->input.hat.hat;
1869 bind.value.hat.hat_mask = binding->input.hat.hat_mask;
1870 }
1871 break;
1872 }
1873 }
1874 return bind;
1875}
@ SDL_CONTROLLER_BUTTON_INVALID

References SDL_GameControllerButtonBind::axis, SDL_ExtendedGameControllerBind::axis, SDL_GameControllerButtonBind::bindType, SDL_GameControllerButtonBind::button, SDL_ExtendedGameControllerBind::button, button, SDL_GameControllerButtonBind::hat, SDL_ExtendedGameControllerBind::hat, i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_HAT, SDL_CONTROLLER_BUTTON_INVALID, SDL_zero, and SDL_GameControllerButtonBind::value.

◆ SDL_GameControllerGetButton()

Uint8 SDL_GameControllerGetButton ( SDL_GameController *  gamecontroller,
SDL_GameControllerButton  button 
)

Get the current state of a button on a game controller.

The button indices start at index 0.

Definition at line 1694 of file SDL_gamecontroller.c.

1695{
1696 int i;
1697
1698 if (!gamecontroller)
1699 return 0;
1700
1701 for (i = 0; i < gamecontroller->num_bindings; ++i) {
1702 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1703 if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
1704 if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1705 SDL_bool valid_input_range;
1706
1707 int value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
1708 int threshold = binding->input.axis.axis_min + (binding->input.axis.axis_max - binding->input.axis.axis_min) / 2;
1709 if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
1710 valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
1711 if (valid_input_range) {
1712 return (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
1713 }
1714 } else {
1715 valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
1716 if (valid_input_range) {
1717 return (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
1718 }
1719 }
1720 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1721 return SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
1722 } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1723 int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
1724 return (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED;
1725 }
1726 }
1727 }
1728 return SDL_RELEASED;
1729}

References SDL_ExtendedGameControllerBind::axis, SDL_ExtendedGameControllerBind::button, button, SDL_ExtendedGameControllerBind::hat, i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_HAT, SDL_JoystickGetAxis, SDL_JoystickGetButton, SDL_JoystickGetHat, SDL_PRESSED, and SDL_RELEASED.

◆ SDL_GameControllerGetButtonFromString()

SDL_GameControllerButton SDL_GameControllerGetButtonFromString ( const char *  pchString)

turn this string into a button mapping

Definition at line 514 of file SDL_gamecontroller.c.

515{
516 int entry;
517 if (!pchString || !pchString[0])
519
520 for (entry = 0; map_StringForControllerButton[entry]; ++entry) {
521 if (SDL_strcasecmp(pchString, map_StringForControllerButton[entry]) == 0)
522 return (SDL_GameControllerButton) entry;
523 }
525}
static const char * map_StringForControllerButton[]
SDL_GameControllerButton

References map_StringForControllerButton, SDL_CONTROLLER_BUTTON_INVALID, and SDL_strcasecmp.

Referenced by SDL_PrivateGameControllerParseElement().

◆ SDL_GameControllerGetJoystick()

SDL_Joystick * SDL_GameControllerGetJoystick ( SDL_GameController *  gamecontroller)

Get the underlying joystick object used by a controller

Definition at line 1784 of file SDL_gamecontroller.c.

1785{
1786 if (!gamecontroller)
1787 return NULL;
1788
1789 return gamecontroller->joystick;
1790}

References NULL.

Referenced by SDL_GameControllerGetPlayerIndex(), SDL_GameControllerGetProduct(), SDL_GameControllerGetProductVersion(), SDL_GameControllerGetVendor(), SDL_GameControllerName(), and SDL_GameControllerRumble().

◆ SDL_GameControllerGetPlayerIndex()

int SDL_GameControllerGetPlayerIndex ( SDL_GameController *  gamecontroller)

Get the player index of an opened game controller, or -1 if it's not available

For XInput controllers this returns the XInput user index.

Definition at line 1745 of file SDL_gamecontroller.c.

1746{
1748}
#define SDL_JoystickGetPlayerIndex
SDL_Joystick * SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)

References SDL_GameControllerGetJoystick(), and SDL_JoystickGetPlayerIndex.

◆ SDL_GameControllerGetProduct()

Uint16 SDL_GameControllerGetProduct ( SDL_GameController *  gamecontroller)

Get the USB product ID of an opened controller, if available. If the product ID isn't available this function returns 0.

Definition at line 1757 of file SDL_gamecontroller.c.

1758{
1760}
#define SDL_JoystickGetProduct

References SDL_GameControllerGetJoystick(), and SDL_JoystickGetProduct.

◆ SDL_GameControllerGetProductVersion()

Uint16 SDL_GameControllerGetProductVersion ( SDL_GameController *  gamecontroller)

Get the product version of an opened controller, if available. If the product version isn't available this function returns 0.

Definition at line 1763 of file SDL_gamecontroller.c.

1764{
1766}
#define SDL_JoystickGetProductVersion

References SDL_GameControllerGetJoystick(), and SDL_JoystickGetProductVersion.

◆ SDL_GameControllerGetStringForAxis()

const char * SDL_GameControllerGetStringForAxis ( SDL_GameControllerAxis  axis)

turn this axis enum into a string mapping

Definition at line 484 of file SDL_gamecontroller.c.

485{
488 }
489 return NULL;
490}
@ SDL_CONTROLLER_AXIS_MAX

References axis, map_StringForControllerAxis, NULL, SDL_CONTROLLER_AXIS_INVALID, and SDL_CONTROLLER_AXIS_MAX.

◆ SDL_GameControllerGetStringForButton()

const char * SDL_GameControllerGetStringForButton ( SDL_GameControllerButton  button)

turn this button enum into a string mapping

Definition at line 530 of file SDL_gamecontroller.c.

531{
534 }
535 return NULL;
536}
@ SDL_CONTROLLER_BUTTON_MAX

References axis, map_StringForControllerButton, NULL, SDL_CONTROLLER_BUTTON_INVALID, and SDL_CONTROLLER_BUTTON_MAX.

◆ SDL_GameControllerGetVendor()

Uint16 SDL_GameControllerGetVendor ( SDL_GameController *  gamecontroller)

Get the USB vendor ID of an opened controller, if available. If the vendor ID isn't available this function returns 0.

Definition at line 1751 of file SDL_gamecontroller.c.

1752{
1754}
#define SDL_JoystickGetVendor

References SDL_GameControllerGetJoystick(), and SDL_JoystickGetVendor.

◆ SDL_GameControllerHandleDelayedGuideButton()

void SDL_GameControllerHandleDelayedGuideButton ( SDL_Joystick *  joystick)

Definition at line 2088 of file SDL_gamecontroller.c.

2089{
2090 SDL_GameController *controllerlist = SDL_gamecontrollers;
2091 while (controllerlist) {
2092 if (controllerlist->joystick == joystick) {
2094 break;
2095 }
2096 controllerlist = controllerlist->next;
2097 }
2098}
@ SDL_CONTROLLER_BUTTON_GUIDE

References SDL_GameController::joystick, SDL_CONTROLLER_BUTTON_GUIDE, SDL_gamecontrollers, SDL_PrivateGameControllerButton(), and SDL_RELEASED.

Referenced by SDL_JoystickUpdate().

◆ SDL_GameControllerIgnoreDevicesChanged()

static void SDL_GameControllerIgnoreDevicesChanged ( void userdata,
const char *  name,
const char *  oldValue,
const char *  hint 
)
static

Definition at line 182 of file SDL_gamecontroller.c.

183{
185}
static void SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list)
static SDL_vidpid_list SDL_ignored_controllers

References SDL_ignored_controllers, and SDL_LoadVIDPIDListFromHint().

Referenced by SDL_GameControllerInitMappings(), and SDL_GameControllerQuitMappings().

◆ SDL_GameControllerIgnoreDevicesExceptChanged()

static void SDL_GameControllerIgnoreDevicesExceptChanged ( void userdata,
const char *  name,
const char *  oldValue,
const char *  hint 
)
static

Definition at line 188 of file SDL_gamecontroller.c.

189{
191}
static SDL_vidpid_list SDL_allowed_controllers

References SDL_allowed_controllers, and SDL_LoadVIDPIDListFromHint().

Referenced by SDL_GameControllerInitMappings(), and SDL_GameControllerQuitMappings().

◆ SDL_GameControllerInit()

int SDL_GameControllerInit ( void  )

Definition at line 1374 of file SDL_gamecontroller.c.

1375{
1376 int i;
1377
1378 /* watch for joy events and fire controller ones if needed */
1380
1381 /* Send added events for controllers currently attached */
1382 for (i = 0; i < SDL_NumJoysticks(); ++i) {
1383 if (SDL_IsGameController(i)) {
1384 SDL_Event deviceevent;
1385 deviceevent.type = SDL_CONTROLLERDEVICEADDED;
1386 deviceevent.cdevice.which = i;
1387 SDL_PushEvent(&deviceevent);
1388 }
1389 }
1390
1391 return (0);
1392}
#define SDL_NumJoysticks
#define SDL_AddEventWatch
static int SDL_GameControllerEventWatcher(void *userdata, SDL_Event *event)

References SDL_Event::cdevice, i, NULL, SDL_AddEventWatch, SDL_CONTROLLERDEVICEADDED, SDL_GameControllerEventWatcher(), SDL_IsGameController(), SDL_NumJoysticks, SDL_PushEvent, SDL_Event::type, and SDL_ControllerDeviceEvent::which.

Referenced by SDL_InitSubSystem().

◆ SDL_GameControllerInitMappings()

int SDL_GameControllerInitMappings ( void  )

Definition at line 1345 of file SDL_gamecontroller.c.

1346{
1347 char szControllerMapPath[1024];
1348 int i = 0;
1349 const char *pMappingString = NULL;
1350 pMappingString = s_ControllerMappings[i];
1351 while (pMappingString) {
1353
1354 i++;
1355 pMappingString = s_ControllerMappings[i];
1356 }
1357
1358 if (SDL_GetControllerMappingFilePath(szControllerMapPath, sizeof(szControllerMapPath))) {
1359 SDL_GameControllerAddMappingsFromFile(szControllerMapPath);
1360 }
1361
1362 /* load in any user supplied config */
1364
1369
1370 return (0);
1371}
#define SDL_AddHintCallback
static void SDL_GameControllerLoadHints()
static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size)
static void SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
static void SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
#define SDL_GameControllerAddMappingsFromFile(file)
static const char * s_ControllerMappings[]
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT
Definition: SDL_hints.h:483
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES
Definition: SDL_hints.h:470

References i, NULL, s_ControllerMappings, SDL_AddHintCallback, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT, SDL_GameControllerAddMappingsFromFile, SDL_GameControllerIgnoreDevicesChanged(), SDL_GameControllerIgnoreDevicesExceptChanged(), SDL_GameControllerLoadHints(), SDL_GetControllerMappingFilePath(), SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES, SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, and SDL_PrivateGameControllerAddMapping().

Referenced by SDL_JoystickInit().

◆ SDL_GameControllerLoadHints()

static void SDL_GameControllerLoadHints ( )
static

Definition at line 1294 of file SDL_gamecontroller.c.

1295{
1296 const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
1297 if (hint && hint[0]) {
1298 size_t nchHints = SDL_strlen(hint);
1299 char *pUserMappings = SDL_malloc(nchHints + 1);
1300 char *pTempMappings = pUserMappings;
1301 SDL_memcpy(pUserMappings, hint, nchHints);
1302 pUserMappings[nchHints] = '\0';
1303 while (pUserMappings) {
1304 char *pchNewLine = NULL;
1305
1306 pchNewLine = SDL_strchr(pUserMappings, '\n');
1307 if (pchNewLine)
1308 *pchNewLine = '\0';
1309
1311
1312 if (pchNewLine) {
1313 pUserMappings = pchNewLine + 1;
1314 } else {
1315 pUserMappings = NULL;
1316 }
1317 }
1318 SDL_free(pTempMappings);
1319 }
1320}
#define SDL_memcpy
#define SDL_GetHint
#define SDL_HINT_GAMECONTROLLERCONFIG
A variable that lets you manually hint extra gamecontroller db entries.
Definition: SDL_hints.h:447

References NULL, SDL_CONTROLLER_MAPPING_PRIORITY_USER, SDL_free, SDL_GetHint, SDL_HINT_GAMECONTROLLERCONFIG, SDL_malloc, SDL_memcpy, SDL_PrivateGameControllerAddMapping(), SDL_strchr, and SDL_strlen.

Referenced by SDL_GameControllerInitMappings().

◆ SDL_GameControllerMapping()

char * SDL_GameControllerMapping ( SDL_GameController *  gamecontroller)

Get a mapping string for an open GameController

Returns
the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available

Definition at line 1284 of file SDL_gamecontroller.c.

1285{
1286 if (!gamecontroller) {
1287 return NULL;
1288 }
1289
1290 return SDL_GameControllerMappingForGUID(gamecontroller->joystick->guid);
1291}
char * SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)

References NULL, and SDL_GameControllerMappingForGUID().

◆ SDL_GameControllerMappingForDeviceIndex()

char * SDL_GameControllerMappingForDeviceIndex ( int  joystick_index)

Get the mapping of a game controller. This can be called before any controllers are opened. If no mapping can be found, this function returns NULL.

Definition at line 1419 of file SDL_gamecontroller.c.

1420{
1421 char *pMappingString = NULL;
1423
1425 mapping = SDL_PrivateGetControllerMapping(joystick_index);
1426 if (mapping) {
1427 SDL_JoystickGUID guid;
1428 char pchGUID[33];
1429 size_t needed;
1430 guid = SDL_JoystickGetDeviceGUID(joystick_index);
1431 SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
1432 /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1433 needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1434 pMappingString = SDL_malloc(needed);
1435 if (!pMappingString) {
1438 return NULL;
1439 }
1440 SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1441 }
1443 return pMappingString;
1444}
#define SDL_JoystickGetGUIDString
#define SDL_JoystickGetDeviceGUID
#define SDL_snprintf
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
static ControllerMapping_t * SDL_PrivateGetControllerMapping(int device_index)
GLenum GLenum GLenum GLenum mapping

References NULL, SDL_JoystickGetDeviceGUID, SDL_JoystickGetGUIDString, SDL_LockJoysticks, SDL_malloc, SDL_OutOfMemory, SDL_PrivateGetControllerMapping(), SDL_snprintf, SDL_strlen, and SDL_UnlockJoysticks.

◆ SDL_GameControllerMappingForGUID()

char * SDL_GameControllerMappingForGUID ( SDL_JoystickGUID  guid)

Get a mapping string for a GUID

Returns
the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available

Definition at line 1260 of file SDL_gamecontroller.c.

1261{
1262 char *pMappingString = NULL;
1264 if (mapping) {
1265 char pchGUID[33];
1266 size_t needed;
1267 SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
1268 /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1269 needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1270 pMappingString = SDL_malloc(needed);
1271 if (!pMappingString) {
1273 return NULL;
1274 }
1275 SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1276 }
1277 return pMappingString;
1278}
static ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid, SDL_bool exact_match)

References NULL, SDL_FALSE, SDL_JoystickGetGUIDString, SDL_malloc, SDL_OutOfMemory, SDL_PrivateGetControllerMappingForGUID(), SDL_snprintf, and SDL_strlen.

Referenced by SDL_GameControllerMapping().

◆ SDL_GameControllerMappingForIndex()

char * SDL_GameControllerMappingForIndex ( int  mapping_index)

Get the mapping at a particular index.

Returns
the mapping string. Must be freed with SDL_free(). Returns NULL if the index is out of range.

Definition at line 1227 of file SDL_gamecontroller.c.

1228{
1230
1232 if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
1233 continue;
1234 }
1235 if (mapping_index == 0) {
1236 char *pMappingString;
1237 char pchGUID[33];
1238 size_t needed;
1239
1240 SDL_JoystickGetGUIDString(mapping->guid, pchGUID, sizeof(pchGUID));
1241 /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1242 needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1243 pMappingString = SDL_malloc(needed);
1244 if (!pMappingString) {
1246 return NULL;
1247 }
1248 SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1249 return pMappingString;
1250 }
1251 --mapping_index;
1252 }
1253 return NULL;
1254}
#define SDL_memcmp
static ControllerMapping_t * s_pSupportedControllers
static SDL_JoystickGUID s_zeroGUID

References NULL, s_pSupportedControllers, s_zeroGUID, SDL_JoystickGetGUIDString, SDL_malloc, SDL_memcmp, SDL_OutOfMemory, SDL_snprintf, and SDL_strlen.

◆ SDL_GameControllerName()

const char * SDL_GameControllerName ( SDL_GameController *  gamecontroller)

Return the name for this currently opened controller

Definition at line 1732 of file SDL_gamecontroller.c.

1733{
1734 if (!gamecontroller)
1735 return NULL;
1736
1737 if (SDL_strcmp(gamecontroller->name, "*") == 0) {
1738 return SDL_JoystickName(SDL_GameControllerGetJoystick(gamecontroller));
1739 } else {
1740 return gamecontroller->name;
1741 }
1742}
#define SDL_JoystickName
#define SDL_strcmp

References NULL, SDL_GameControllerGetJoystick(), SDL_JoystickName, and SDL_strcmp.

◆ SDL_GameControllerNameForIndex()

const char * SDL_GameControllerNameForIndex ( int  joystick_index)

Get the implementation dependent name of a game controller. This can be called before any controllers are opened. If no name can be found, this function returns NULL.

Definition at line 1399 of file SDL_gamecontroller.c.

1400{
1401 ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1402 if (pSupportedController) {
1403 if (SDL_strcmp(pSupportedController->name, "*") == 0) {
1404 return SDL_JoystickNameForIndex(device_index);
1405 } else {
1406 return pSupportedController->name;
1407 }
1408 }
1409 return NULL;
1410}
#define SDL_JoystickNameForIndex

References ControllerMapping_t::name, NULL, SDL_JoystickNameForIndex, SDL_PrivateGetControllerMapping(), and SDL_strcmp.

◆ SDL_GameControllerNumMappings()

int SDL_GameControllerNumMappings ( void  )

Get the number of mappings installed

Returns
the number of mappings

Definition at line 1209 of file SDL_gamecontroller.c.

1210{
1211 int num_mappings = 0;
1213
1215 if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
1216 continue;
1217 }
1218 ++num_mappings;
1219 }
1220 return num_mappings;
1221}

References s_pSupportedControllers, s_zeroGUID, and SDL_memcmp.

◆ SDL_GameControllerOpen()

SDL_GameController * SDL_GameControllerOpen ( int  joystick_index)

Open a game controller for use. The index passed as an argument refers to the N'th game controller on the system. This index is not the value which will identify this controller in future controller events. The joystick's instance id (SDL_JoystickID) will be used there instead.

Returns
A controller identifier, or NULL if an error occurred.

Definition at line 1541 of file SDL_gamecontroller.c.

1542{
1543 SDL_JoystickID instance_id;
1544 SDL_GameController *gamecontroller;
1545 SDL_GameController *gamecontrollerlist;
1546 ControllerMapping_t *pSupportedController = NULL;
1547
1549
1550 gamecontrollerlist = SDL_gamecontrollers;
1551 /* If the controller is already open, return it */
1552 instance_id = SDL_JoystickGetDeviceInstanceID(device_index);
1553 while (gamecontrollerlist) {
1554 if (instance_id == gamecontrollerlist->joystick->instance_id) {
1555 gamecontroller = gamecontrollerlist;
1556 ++gamecontroller->ref_count;
1558 return (gamecontroller);
1559 }
1560 gamecontrollerlist = gamecontrollerlist->next;
1561 }
1562
1563 /* Find a controller mapping */
1564 pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1565 if (!pSupportedController) {
1566 SDL_SetError("Couldn't find mapping for device (%d)", device_index);
1568 return NULL;
1569 }
1570
1571 /* Create and initialize the controller */
1572 gamecontroller = (SDL_GameController *) SDL_calloc(1, sizeof(*gamecontroller));
1573 if (gamecontroller == NULL) {
1576 return NULL;
1577 }
1578
1579 gamecontroller->joystick = SDL_JoystickOpen(device_index);
1580 if (!gamecontroller->joystick) {
1581 SDL_free(gamecontroller);
1583 return NULL;
1584 }
1585
1586 if (gamecontroller->joystick->naxes) {
1587 gamecontroller->last_match_axis = (SDL_ExtendedGameControllerBind **)SDL_calloc(gamecontroller->joystick->naxes, sizeof(*gamecontroller->last_match_axis));
1588 if (!gamecontroller->last_match_axis) {
1590 SDL_JoystickClose(gamecontroller->joystick);
1591 SDL_free(gamecontroller);
1593 return NULL;
1594 }
1595 }
1596 if (gamecontroller->joystick->nhats) {
1597 gamecontroller->last_hat_mask = (Uint8 *)SDL_calloc(gamecontroller->joystick->nhats, sizeof(*gamecontroller->last_hat_mask));
1598 if (!gamecontroller->last_hat_mask) {
1600 SDL_JoystickClose(gamecontroller->joystick);
1601 SDL_free(gamecontroller->last_match_axis);
1602 SDL_free(gamecontroller);
1604 return NULL;
1605 }
1606 }
1607
1608 SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->name, pSupportedController->mapping);
1609
1610 /* Add the controller to list */
1611 ++gamecontroller->ref_count;
1612 /* Link the controller in the list */
1613 gamecontroller->next = SDL_gamecontrollers;
1614 SDL_gamecontrollers = gamecontroller;
1615
1617
1618 return (gamecontroller);
1619}
#define SDL_JoystickGetDeviceInstanceID
#define SDL_JoystickOpen
#define SDL_calloc
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:81

References ControllerMapping_t::mapping, ControllerMapping_t::name, NULL, SDL_calloc, SDL_free, SDL_gamecontrollers, SDL_JoystickClose, SDL_JoystickGetDeviceInstanceID, SDL_JoystickOpen, SDL_LockJoysticks, SDL_OutOfMemory, SDL_PrivateGetControllerMapping(), SDL_PrivateLoadButtonMapping(), SDL_SetError, and SDL_UnlockJoysticks.

◆ SDL_GameControllerQuit()

void SDL_GameControllerQuit ( void  )

Definition at line 1931 of file SDL_gamecontroller.c.

1932{
1934 while (SDL_gamecontrollers) {
1935 SDL_gamecontrollers->ref_count = 1;
1937 }
1939}
void SDL_GameControllerClose(SDL_GameController *gamecontroller)

References SDL_GameControllerClose(), SDL_gamecontrollers, SDL_LockJoysticks, and SDL_UnlockJoysticks.

Referenced by SDL_QuitSubSystem().

◆ SDL_GameControllerQuitMappings()

void SDL_GameControllerQuitMappings ( void  )

Definition at line 1942 of file SDL_gamecontroller.c.

References SDL_vidpid_list::entries, ControllerMapping_t::mapping, ControllerMapping_t::name, ControllerMapping_t::next, NULL, s_pSupportedControllers, SDL_allowed_controllers, SDL_DelEventWatch, SDL_DelHintCallback, SDL_free, SDL_GameControllerEventWatcher(), SDL_GameControllerIgnoreDevicesChanged(), SDL_GameControllerIgnoreDevicesExceptChanged(), SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES, SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, SDL_ignored_controllers, and SDL_zero.

Referenced by SDL_JoystickQuit().

◆ SDL_GameControllerRumble()

int SDL_GameControllerRumble ( SDL_GameController *  gamecontroller,
Uint16  low_frequency_rumble,
Uint16  high_frequency_rumble,
Uint32  duration_ms 
)

Trigger a rumble effect Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.

Parameters
gamecontrollerThe controller to vibrate
low_frequency_rumbleThe intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
high_frequency_rumbleThe intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
duration_msThe duration of the rumble effect, in milliseconds
Returns
0, or -1 if rumble isn't supported on this joystick

Definition at line 1879 of file SDL_gamecontroller.c.

1880{
1881 return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms);
1882}
#define SDL_JoystickRumble

References SDL_GameControllerGetJoystick(), and SDL_JoystickRumble.

◆ SDL_GameControllerUpdate()

void SDL_GameControllerUpdate ( void  )

Update the current state of the open game controllers.

This is called automatically by the event loop if any game controller events are enabled.

Definition at line 1625 of file SDL_gamecontroller.c.

1626{
1627 /* Just for API completeness; the joystick API does all the work. */
1629}
#define SDL_JoystickUpdate

References SDL_JoystickUpdate.

◆ SDL_GetControllerMappingFilePath()

static SDL_bool SDL_GetControllerMappingFilePath ( char *  path,
size_t  size 
)
static

Definition at line 1327 of file SDL_gamecontroller.c.

1328{
1330 if (hint && *hint) {
1331 return SDL_strlcpy(path, hint, size) < size;
1332 }
1333
1334#if defined(__ANDROID__)
1335 return SDL_snprintf(path, size, "%s/controller_map.txt", SDL_AndroidGetInternalStoragePath()) < size;
1336#else
1337 return SDL_FALSE;
1338#endif
1339}
#define SDL_AndroidGetInternalStoragePath
#define SDL_HINT_GAMECONTROLLERCONFIG_FILE
A variable that lets you provide a file with extra gamecontroller db entries.
Definition: SDL_hints.h:457
GLsizeiptr size
GLsizei const GLchar *const * path

References SDL_AndroidGetInternalStoragePath, SDL_FALSE, SDL_GetHint, SDL_HINT_GAMECONTROLLERCONFIG_FILE, SDL_snprintf, and SDL_strlcpy.

Referenced by SDL_GameControllerInitMappings().

◆ SDL_IsGameController()

SDL_bool SDL_IsGameController ( int  joystick_index)

Is the joystick on this index supported by the game controller interface?

Definition at line 1464 of file SDL_gamecontroller.c.

1465{
1466 ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1467 if (pSupportedController) {
1468 return SDL_TRUE;
1469 }
1470 return SDL_FALSE;
1471}
@ SDL_TRUE
Definition: SDL_stdinc.h:164

References SDL_FALSE, SDL_PrivateGetControllerMapping(), and SDL_TRUE.

Referenced by SDL_GameControllerEventWatcher(), and SDL_GameControllerInit().

◆ SDL_IsGameControllerNameAndGUID()

SDL_bool SDL_IsGameControllerNameAndGUID ( const char *  name,
SDL_JoystickGUID  guid 
)

Definition at line 1451 of file SDL_gamecontroller.c.

1452{
1454 if (pSupportedController) {
1455 return SDL_TRUE;
1456 }
1457 return SDL_FALSE;
1458}
static ControllerMapping_t * SDL_PrivateGetControllerMappingForNameAndGUID(const char *name, SDL_JoystickGUID guid)
GLuint const GLchar * name

References SDL_FALSE, SDL_PrivateGetControllerMappingForNameAndGUID(), and SDL_TRUE.

Referenced by SDL_ShouldIgnoreJoystick().

◆ SDL_LoadVIDPIDListFromHint()

static void SDL_LoadVIDPIDListFromHint ( const char *  hint,
SDL_vidpid_list list 
)
static

Definition at line 136 of file SDL_gamecontroller.c.

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}
#define SDL_realloc
#define SDL_strtol
#define SDL_LoadFile
uint16_t Uint16
Definition: SDL_stdinc.h:191

References SDL_vidpid_list::entries, SDL_vidpid_list::max_entries, NULL, SDL_vidpid_list::num_entries, SDL_free, SDL_LoadFile, SDL_realloc, SDL_strstr, and SDL_strtol.

Referenced by SDL_GameControllerIgnoreDevicesChanged(), and SDL_GameControllerIgnoreDevicesExceptChanged().

◆ SDL_PrivateAddMappingForGUID()

static ControllerMapping_t * SDL_PrivateAddMappingForGUID ( SDL_JoystickGUID  jGUID,
const char *  mappingString,
SDL_bool existing,
SDL_ControllerMappingPriority  priority 
)
static

Definition at line 825 of file SDL_gamecontroller.c.

826{
827 char *pchName;
828 char *pchMapping;
829 ControllerMapping_t *pControllerMapping;
830
831 pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString);
832 if (!pchName) {
833 SDL_SetError("Couldn't parse name from %s", mappingString);
834 return NULL;
835 }
836
837 pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString);
838 if (!pchMapping) {
839 SDL_free(pchName);
840 SDL_SetError("Couldn't parse %s", mappingString);
841 return NULL;
842 }
843
844 pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID, SDL_TRUE);
845 if (pControllerMapping) {
846 /* Only overwrite the mapping if the priority is the same or higher. */
847 if (pControllerMapping->priority <= priority) {
848 /* Update existing mapping */
849 SDL_free(pControllerMapping->name);
850 pControllerMapping->name = pchName;
851 SDL_free(pControllerMapping->mapping);
852 pControllerMapping->mapping = pchMapping;
853 pControllerMapping->priority = priority;
854 /* refresh open controllers */
855 SDL_PrivateGameControllerRefreshMapping(pControllerMapping);
856 } else {
857 SDL_free(pchName);
858 SDL_free(pchMapping);
859 }
860 *existing = SDL_TRUE;
861 } else {
862 pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
863 if (!pControllerMapping) {
864 SDL_free(pchName);
865 SDL_free(pchMapping);
867 return NULL;
868 }
869 pControllerMapping->guid = jGUID;
870 pControllerMapping->name = pchName;
871 pControllerMapping->mapping = pchMapping;
872 pControllerMapping->next = NULL;
873 pControllerMapping->priority = priority;
874
876 /* Add the mapping to the end of the list */
877 ControllerMapping_t *pCurrMapping, *pPrevMapping;
878
879 for ( pPrevMapping = s_pSupportedControllers, pCurrMapping = pPrevMapping->next;
880 pCurrMapping;
881 pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next ) {
882 continue;
883 }
884 pPrevMapping->next = pControllerMapping;
885 } else {
886 s_pSupportedControllers = pControllerMapping;
887 }
888 *existing = SDL_FALSE;
889 }
890 return pControllerMapping;
891}
static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
static char * SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
static char * SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
SDL_ControllerMappingPriority priority
SDL_JoystickGUID guid

References ControllerMapping_t::guid, ControllerMapping_t::mapping, ControllerMapping_t::name, ControllerMapping_t::next, NULL, ControllerMapping_t::priority, s_pSupportedControllers, SDL_FALSE, SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_PrivateGameControllerRefreshMapping(), SDL_PrivateGetControllerMappingForGUID(), SDL_PrivateGetControllerMappingFromMappingString(), SDL_PrivateGetControllerNameFromMappingString(), SDL_SetError, and SDL_TRUE.

Referenced by SDL_PrivateGameControllerAddMapping(), and SDL_PrivateGetControllerMappingForNameAndGUID().

◆ SDL_PrivateGameControllerAddMapping()

static int SDL_PrivateGameControllerAddMapping ( const char *  mappingString,
SDL_ControllerMappingPriority  priority 
)
static

Definition at line 1149 of file SDL_gamecontroller.c.

1150{
1151 char *pchGUID;
1152 SDL_JoystickGUID jGUID;
1153 SDL_bool is_default_mapping = SDL_FALSE;
1154 SDL_bool is_hidapi_mapping = SDL_FALSE;
1155 SDL_bool is_xinput_mapping = SDL_FALSE;
1156 SDL_bool existing = SDL_FALSE;
1157 ControllerMapping_t *pControllerMapping;
1158
1159 if (!mappingString) {
1160 return SDL_InvalidParamError("mappingString");
1161 }
1162
1163 pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString);
1164 if (!pchGUID) {
1165 return SDL_SetError("Couldn't parse GUID from %s", mappingString);
1166 }
1167 if (!SDL_strcasecmp(pchGUID, "default")) {
1168 is_default_mapping = SDL_TRUE;
1169 } else if (!SDL_strcasecmp(pchGUID, "hidapi")) {
1170 is_hidapi_mapping = SDL_TRUE;
1171 } else if (!SDL_strcasecmp(pchGUID, "xinput")) {
1172 is_xinput_mapping = SDL_TRUE;
1173 }
1174 jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
1175 SDL_free(pchGUID);
1176
1177 pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority);
1178 if (!pControllerMapping) {
1179 return -1;
1180 }
1181
1182 if (existing) {
1183 return 0;
1184 } else {
1185 if (is_default_mapping) {
1186 s_pDefaultMapping = pControllerMapping;
1187 } else if (is_hidapi_mapping) {
1188 s_pHIDAPIMapping = pControllerMapping;
1189 } else if (is_xinput_mapping) {
1190 s_pXInputMapping = pControllerMapping;
1191 }
1192 return 1;
1193 }
1194}
#define SDL_JoystickGetGUIDFromString
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
static char * SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
static ControllerMapping_t * s_pDefaultMapping
static ControllerMapping_t * s_pHIDAPIMapping
static ControllerMapping_t * s_pXInputMapping
static ControllerMapping_t * SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)

References s_pDefaultMapping, s_pHIDAPIMapping, s_pXInputMapping, SDL_FALSE, SDL_free, SDL_InvalidParamError, SDL_JoystickGetGUIDFromString, SDL_PrivateAddMappingForGUID(), SDL_PrivateGetControllerGUIDFromMappingString(), SDL_SetError, SDL_strcasecmp, and SDL_TRUE.

Referenced by SDL_GameControllerAddMapping(), SDL_GameControllerInitMappings(), and SDL_GameControllerLoadHints().

◆ SDL_PrivateGameControllerAxis()

static int SDL_PrivateGameControllerAxis ( SDL_GameController *  gamecontroller,
SDL_GameControllerAxis  axis,
Sint16  value 
)
static

Definition at line 1975 of file SDL_gamecontroller.c.

1976{
1977 int posted;
1978
1979 /* translate the event, if desired */
1980 posted = 0;
1981#if !SDL_EVENTS_DISABLED
1984 event.type = SDL_CONTROLLERAXISMOTION;
1985 event.caxis.which = gamecontroller->joystick->instance_id;
1986 event.caxis.axis = axis;
1987 event.caxis.value = value;
1988 posted = SDL_PushEvent(&event) == 1;
1989 }
1990#endif /* !SDL_EVENTS_DISABLED */
1991 return (posted);
1992}
#define SDL_GetEventState(type)
Definition: SDL_events.h:772

References axis, SDL_CONTROLLERAXISMOTION, SDL_ENABLE, SDL_GetEventState, and SDL_PushEvent.

Referenced by HandleJoystickAxis(), HandleJoystickButton(), HandleJoystickHat(), and ResetOutput().

◆ SDL_PrivateGameControllerButton()

static int SDL_PrivateGameControllerButton ( SDL_GameController *  gamecontroller,
SDL_GameControllerButton  button,
Uint8  state 
)
static

Definition at line 1999 of file SDL_gamecontroller.c.

2000{
2001 int posted;
2002#if !SDL_EVENTS_DISABLED
2004
2006 return (0);
2007
2008 switch (state) {
2009 case SDL_PRESSED:
2010 event.type = SDL_CONTROLLERBUTTONDOWN;
2011 break;
2012 case SDL_RELEASED:
2013 event.type = SDL_CONTROLLERBUTTONUP;
2014 break;
2015 default:
2016 /* Invalid state -- bail */
2017 return (0);
2018 }
2019#endif /* !SDL_EVENTS_DISABLED */
2020
2022 Uint32 now = SDL_GetTicks();
2023 if (state == SDL_PRESSED) {
2024 gamecontroller->guide_button_down = now;
2025
2026 if (gamecontroller->joystick->delayed_guide_button) {
2027 /* Skip duplicate press */
2028 return (0);
2029 }
2030 } else {
2031 if (!SDL_TICKS_PASSED(now, gamecontroller->guide_button_down+SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS) && !gamecontroller->joystick->force_recentering) {
2032 gamecontroller->joystick->delayed_guide_button = SDL_TRUE;
2033 return (0);
2034 }
2035 gamecontroller->joystick->delayed_guide_button = SDL_FALSE;
2036 }
2037 }
2038
2039 /* translate the event, if desired */
2040 posted = 0;
2041#if !SDL_EVENTS_DISABLED
2042 if (SDL_GetEventState(event.type) == SDL_ENABLE) {
2043 event.cbutton.which = gamecontroller->joystick->instance_id;
2044 event.cbutton.button = button;
2045 event.cbutton.state = state;
2046 posted = SDL_PushEvent(&event) == 1;
2047 }
2048#endif /* !SDL_EVENTS_DISABLED */
2049 return (posted);
2050}
#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56

References button, SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP, SDL_ENABLE, SDL_FALSE, SDL_GetEventState, SDL_GetTicks(), SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS, SDL_PRESSED, SDL_PushEvent, SDL_RELEASED, SDL_TICKS_PASSED, SDL_TRUE, and state.

Referenced by HandleJoystickAxis(), HandleJoystickButton(), HandleJoystickHat(), ResetOutput(), and SDL_GameControllerHandleDelayedGuideButton().

◆ SDL_PrivateGameControllerParseControllerConfigString()

static void SDL_PrivateGameControllerParseControllerConfigString ( SDL_GameController *  gamecontroller,
const char *  pchString 
)
static

Definition at line 637 of file SDL_gamecontroller.c.

638{
639 char szGameButton[20];
640 char szJoystickButton[20];
641 SDL_bool bGameButton = SDL_TRUE;
642 int i = 0;
643 const char *pchPos = pchString;
644
645 SDL_zero(szGameButton);
646 SDL_zero(szJoystickButton);
647
648 while (pchPos && *pchPos) {
649 if (*pchPos == ':') {
650 i = 0;
651 bGameButton = SDL_FALSE;
652 } else if (*pchPos == ' ') {
653
654 } else if (*pchPos == ',') {
655 i = 0;
656 bGameButton = SDL_TRUE;
657 SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
658 SDL_zero(szGameButton);
659 SDL_zero(szJoystickButton);
660
661 } else if (bGameButton) {
662 if (i >= sizeof(szGameButton)) {
663 SDL_SetError("Button name too large: %s", szGameButton);
664 return;
665 }
666 szGameButton[i] = *pchPos;
667 i++;
668 } else {
669 if (i >= sizeof(szJoystickButton)) {
670 SDL_SetError("Joystick button name too large: %s", szJoystickButton);
671 return;
672 }
673 szJoystickButton[i] = *pchPos;
674 i++;
675 }
676 pchPos++;
677 }
678
679 /* No more values if the string was terminated by a comma. Don't report an error. */
680 if (szGameButton[0] != '\0' || szJoystickButton[0] != '\0') {
681 SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
682 }
683}
static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontroller, const char *szGameButton, const char *szJoystickButton)

References i, SDL_FALSE, SDL_PrivateGameControllerParseElement(), SDL_SetError, SDL_TRUE, and SDL_zero.

Referenced by SDL_PrivateLoadButtonMapping().

◆ SDL_PrivateGameControllerParseElement()

static void SDL_PrivateGameControllerParseElement ( SDL_GameController *  gamecontroller,
const char *  szGameButton,
const char *  szJoystickButton 
)
static

Definition at line 541 of file SDL_gamecontroller.c.

542{
546 SDL_bool invert_input = SDL_FALSE;
547 char half_axis_input = 0;
548 char half_axis_output = 0;
549
550 if (*szGameButton == '+' || *szGameButton == '-') {
551 half_axis_output = *szGameButton++;
552 }
553
558 bind.output.axis.axis = axis;
560 bind.output.axis.axis_min = 0;
561 bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
562 } else {
563 if (half_axis_output == '+') {
564 bind.output.axis.axis_min = 0;
565 bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
566 } else if (half_axis_output == '-') {
567 bind.output.axis.axis_min = 0;
568 bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
569 } else {
570 bind.output.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
571 bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
572 }
573 }
576 bind.output.button = button;
577 } else {
578 SDL_SetError("Unexpected controller element %s", szGameButton);
579 return;
580 }
581
582 if (*szJoystickButton == '+' || *szJoystickButton == '-') {
583 half_axis_input = *szJoystickButton++;
584 }
585 if (szJoystickButton[SDL_strlen(szJoystickButton) - 1] == '~') {
586 invert_input = SDL_TRUE;
587 }
588
589 if (szJoystickButton[0] == 'a' && SDL_isdigit(szJoystickButton[1])) {
591 bind.input.axis.axis = SDL_atoi(&szJoystickButton[1]);
592 if (half_axis_input == '+') {
593 bind.input.axis.axis_min = 0;
594 bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
595 } else if (half_axis_input == '-') {
596 bind.input.axis.axis_min = 0;
597 bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
598 } else {
599 bind.input.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
600 bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
601 }
602 if (invert_input) {
603 int tmp = bind.input.axis.axis_min;
604 bind.input.axis.axis_min = bind.input.axis.axis_max;
605 bind.input.axis.axis_max = tmp;
606 }
607 } else if (szJoystickButton[0] == 'b' && SDL_isdigit(szJoystickButton[1])) {
609 bind.input.button = SDL_atoi(&szJoystickButton[1]);
610 } else if (szJoystickButton[0] == 'h' && SDL_isdigit(szJoystickButton[1]) &&
611 szJoystickButton[2] == '.' && SDL_isdigit(szJoystickButton[3])) {
612 int hat = SDL_atoi(&szJoystickButton[1]);
613 int mask = SDL_atoi(&szJoystickButton[3]);
615 bind.input.hat.hat = hat;
616 bind.input.hat.hat_mask = mask;
617 } else {
618 SDL_SetError("Unexpected joystick element: %s", szJoystickButton);
619 return;
620 }
621
622 ++gamecontroller->num_bindings;
623 gamecontroller->bindings = (SDL_ExtendedGameControllerBind *)SDL_realloc(gamecontroller->bindings, gamecontroller->num_bindings * sizeof(*gamecontroller->bindings));
624 if (!gamecontroller->bindings) {
625 gamecontroller->num_bindings = 0;
627 return;
628 }
629 gamecontroller->bindings[gamecontroller->num_bindings - 1] = bind;
630}
#define SDL_isdigit
#define SDL_atoi
SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *pchString)
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *pchString)
@ SDL_CONTROLLER_AXIS_TRIGGERRIGHT
@ SDL_CONTROLLER_AXIS_TRIGGERLEFT
#define SDL_JOYSTICK_AXIS_MIN
Definition: SDL_joystick.h:302
#define SDL_JOYSTICK_AXIS_MAX
Definition: SDL_joystick.h:301
GLenum GLint GLuint mask

References SDL_ExtendedGameControllerBind::axis, axis, SDL_ExtendedGameControllerBind::button, button, SDL_ExtendedGameControllerBind::hat, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_atoi, SDL_CONTROLLER_AXIS_INVALID, SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_HAT, SDL_CONTROLLER_BUTTON_INVALID, SDL_FALSE, SDL_GameControllerGetAxisFromString(), SDL_GameControllerGetButtonFromString(), SDL_isdigit, SDL_JOYSTICK_AXIS_MAX, SDL_JOYSTICK_AXIS_MIN, SDL_OutOfMemory, SDL_realloc, SDL_SetError, SDL_strlen, and SDL_TRUE.

Referenced by SDL_PrivateGameControllerParseControllerConfigString().

◆ SDL_PrivateGameControllerRefreshMapping()

static void SDL_PrivateGameControllerRefreshMapping ( ControllerMapping_t pControllerMapping)
static

Definition at line 801 of file SDL_gamecontroller.c.

802{
803 SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
804 while (gamecontrollerlist) {
805 if (!SDL_memcmp(&gamecontrollerlist->joystick->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
806 /* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
807 SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->name, pControllerMapping->mapping);
808
809 {
811 event.type = SDL_CONTROLLERDEVICEREMAPPED;
812 event.cdevice.which = gamecontrollerlist->joystick->instance_id;
814 }
815 }
816
817 gamecontrollerlist = gamecontrollerlist->next;
818 }
819}

References ControllerMapping_t::guid, ControllerMapping_t::mapping, ControllerMapping_t::name, SDL_CONTROLLERDEVICEREMAPPED, SDL_gamecontrollers, SDL_memcmp, SDL_PrivateLoadButtonMapping(), and SDL_PushEvent.

Referenced by SDL_PrivateAddMappingForGUID().

◆ SDL_PrivateGetControllerGUIDFromMappingString()

static char * SDL_PrivateGetControllerGUIDFromMappingString ( const char *  pMapping)
static

Definition at line 717 of file SDL_gamecontroller.c.

718{
719 const char *pFirstComma = SDL_strchr(pMapping, ',');
720 if (pFirstComma) {
721 char *pchGUID = SDL_malloc(pFirstComma - pMapping + 1);
722 if (!pchGUID) {
724 return NULL;
725 }
726 SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
727 pchGUID[pFirstComma - pMapping] = '\0';
728
729 /* Convert old style GUIDs to the new style in 2.0.5 */
730#if __WIN32__
731 if (SDL_strlen(pchGUID) == 32 &&
732 SDL_memcmp(&pchGUID[20], "504944564944", 12) == 0) {
733 SDL_memcpy(&pchGUID[20], "000000000000", 12);
734 SDL_memcpy(&pchGUID[16], &pchGUID[4], 4);
735 SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
736 SDL_memcpy(&pchGUID[0], "03000000", 8);
737 }
738#elif __MACOSX__
739 if (SDL_strlen(pchGUID) == 32 &&
740 SDL_memcmp(&pchGUID[4], "000000000000", 12) == 0 &&
741 SDL_memcmp(&pchGUID[20], "000000000000", 12) == 0) {
742 SDL_memcpy(&pchGUID[20], "000000000000", 12);
743 SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
744 SDL_memcpy(&pchGUID[0], "03000000", 8);
745 }
746#endif
747 return pchGUID;
748 }
749 return NULL;
750}

References NULL, SDL_malloc, SDL_memcmp, SDL_memcpy, SDL_OutOfMemory, SDL_strchr, and SDL_strlen.

Referenced by SDL_PrivateGameControllerAddMapping().

◆ SDL_PrivateGetControllerMapping()

static ControllerMapping_t * SDL_PrivateGetControllerMapping ( int  device_index)
static

Definition at line 1053 of file SDL_gamecontroller.c.

1054{
1055 const char *name;
1056 SDL_JoystickGUID guid;
1058
1060
1061 if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
1062 SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
1064 return (NULL);
1065 }
1066
1067 name = SDL_JoystickNameForIndex(device_index);
1068 guid = SDL_JoystickGetDeviceGUID(device_index);
1071 return mapping;
1072}

References NULL, SDL_JoystickGetDeviceGUID, SDL_JoystickNameForIndex, SDL_LockJoysticks, SDL_NumJoysticks, SDL_PrivateGetControllerMappingForNameAndGUID(), SDL_SetError, and SDL_UnlockJoysticks.

Referenced by SDL_GameControllerMappingForDeviceIndex(), SDL_GameControllerNameForIndex(), SDL_GameControllerOpen(), and SDL_IsGameController().

◆ SDL_PrivateGetControllerMappingForGUID()

static ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID ( SDL_JoystickGUID guid,
SDL_bool  exact_match 
)
static

Definition at line 425 of file SDL_gamecontroller.c.

426{
427 ControllerMapping_t *pSupportedController = s_pSupportedControllers;
428 while (pSupportedController) {
429 if (SDL_memcmp(guid, &pSupportedController->guid, sizeof(*guid)) == 0) {
430 return pSupportedController;
431 }
432 pSupportedController = pSupportedController->next;
433 }
434 if (!exact_match) {
435 if (SDL_IsJoystickHIDAPI(*guid)) {
436 /* This is a HIDAPI device */
437 return s_pHIDAPIMapping;
438 }
439#if SDL_JOYSTICK_XINPUT
440 if (SDL_IsJoystickXInput(*guid)) {
441 /* This is an XInput device */
442 return s_pXInputMapping;
443 }
444#endif
445 }
446 return NULL;
447}
SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid)

References ControllerMapping_t::guid, ControllerMapping_t::next, NULL, s_pHIDAPIMapping, s_pSupportedControllers, s_pXInputMapping, SDL_IsJoystickHIDAPI(), SDL_IsJoystickXInput(), and SDL_memcmp.

Referenced by SDL_GameControllerMappingForGUID(), SDL_PrivateAddMappingForGUID(), and SDL_PrivateGetControllerMappingForNameAndGUID().

◆ SDL_PrivateGetControllerMappingForNameAndGUID()

static ControllerMapping_t * SDL_PrivateGetControllerMappingForNameAndGUID ( const char *  name,
SDL_JoystickGUID  guid 
)
static

Definition at line 1020 of file SDL_gamecontroller.c.

1021{
1023
1025#ifdef __LINUX__
1026 if (!mapping && name) {
1027 if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
1028 /* The Linux driver xpad.c maps the wireless dpad to buttons */
1029 SDL_bool existing;
1031"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",
1033 }
1034 }
1035#endif /* __LINUX__ */
1036
1037 if (!mapping && name) {
1038 if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {
1040 }
1041 }
1042#ifdef __ANDROID__
1043 if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) {
1044 mapping = SDL_CreateMappingForAndroidController(name, guid);
1045 }
1046#endif
1047 if (!mapping) {
1049 }
1050 return mapping;
1051}

References s_pDefaultMapping, s_pXInputMapping, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT, SDL_FALSE, SDL_IsJoystickHIDAPI(), SDL_PrivateAddMappingForGUID(), SDL_PrivateGetControllerMappingForGUID(), and SDL_strstr.

Referenced by SDL_IsGameControllerNameAndGUID(), and SDL_PrivateGetControllerMapping().

◆ SDL_PrivateGetControllerMappingFromMappingString()

static char * SDL_PrivateGetControllerMappingFromMappingString ( const char *  pMapping)
static

Definition at line 783 of file SDL_gamecontroller.c.

784{
785 const char *pFirstComma, *pSecondComma;
786
787 pFirstComma = SDL_strchr(pMapping, ',');
788 if (!pFirstComma)
789 return NULL;
790
791 pSecondComma = SDL_strchr(pFirstComma + 1, ',');
792 if (!pSecondComma)
793 return NULL;
794
795 return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
796}
#define SDL_strdup

References NULL, SDL_strchr, and SDL_strdup.

Referenced by SDL_PrivateAddMappingForGUID().

◆ SDL_PrivateGetControllerNameFromMappingString()

static char * SDL_PrivateGetControllerNameFromMappingString ( const char *  pMapping)
static

Definition at line 756 of file SDL_gamecontroller.c.

757{
758 const char *pFirstComma, *pSecondComma;
759 char *pchName;
760
761 pFirstComma = SDL_strchr(pMapping, ',');
762 if (!pFirstComma)
763 return NULL;
764
765 pSecondComma = SDL_strchr(pFirstComma + 1, ',');
766 if (!pSecondComma)
767 return NULL;
768
769 pchName = SDL_malloc(pSecondComma - pFirstComma);
770 if (!pchName) {
772 return NULL;
773 }
774 SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
775 pchName[pSecondComma - pFirstComma - 1] = 0;
776 return pchName;
777}

References NULL, SDL_malloc, SDL_memcpy, SDL_OutOfMemory, and SDL_strchr.

Referenced by SDL_PrivateAddMappingForGUID().

◆ SDL_PrivateLoadButtonMapping()

static void SDL_PrivateLoadButtonMapping ( SDL_GameController *  gamecontroller,
const char *  pchName,
const char *  pchMapping 
)
static

Definition at line 688 of file SDL_gamecontroller.c.

689{
690 int i;
691
692 gamecontroller->name = pchName;
693 gamecontroller->num_bindings = 0;
694 SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
695
697
698 /* Set the zero point for triggers */
699 for (i = 0; i < gamecontroller->num_bindings; ++i) {
700 SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
701 if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
703 (binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ||
704 binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
705 if (binding->input.axis.axis < gamecontroller->joystick->naxes) {
706 gamecontroller->joystick->axes[binding->input.axis.axis].value =
707 gamecontroller->joystick->axes[binding->input.axis.axis].zero = (Sint16)binding->input.axis.axis_min;
708 }
709 }
710 }
711}
#define SDL_memset
static void SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecontroller, const char *pchString)

References SDL_ExtendedGameControllerBind::axis, i, SDL_ExtendedGameControllerBind::input, SDL_ExtendedGameControllerBind::inputType, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_memset, and SDL_PrivateGameControllerParseControllerConfigString().

Referenced by SDL_GameControllerOpen(), and SDL_PrivateGameControllerRefreshMapping().

◆ SDL_ShouldIgnoreGameController()

SDL_bool SDL_ShouldIgnoreGameController ( const char *  name,
SDL_JoystickGUID  guid 
)

Definition at line 1476 of file SDL_gamecontroller.c.

1477{
1478 int i;
1479 Uint16 vendor;
1480 Uint16 product;
1481 Uint16 version;
1482 Uint32 vidpid;
1483
1484#if defined(__LINUX__)
1485 if (name && SDL_strstr(name, "Wireless Controller Motion Sensors")) {
1486 /* Don't treat the PS4 motion controls as a separate game controller */
1487 return SDL_TRUE;
1488 }
1489#endif
1490
1493 return SDL_FALSE;
1494 }
1495
1496 SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version);
1497
1498 if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
1499 /* 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 */
1500 SDL_bool bSteamVirtualGamepad = SDL_FALSE;
1501#if defined(__LINUX__)
1502 bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
1503#elif defined(__MACOSX__)
1504 bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
1505#elif defined(__WIN32__)
1506 /* We can't tell on Windows, but Steam will block others in input hooks */
1507 bSteamVirtualGamepad = SDL_TRUE;
1508#endif
1509 if (bSteamVirtualGamepad) {
1510 return SDL_FALSE;
1511 }
1512 }
1513
1514 vidpid = MAKE_VIDPID(vendor, product);
1515
1517 for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) {
1518 if (vidpid == SDL_allowed_controllers.entries[i]) {
1519 return SDL_FALSE;
1520 }
1521 }
1522 return SDL_TRUE;
1523 } else {
1524 for (i = 0; i < SDL_ignored_controllers.num_entries; ++i) {
1525 if (vidpid == SDL_ignored_controllers.entries[i]) {
1526 return SDL_TRUE;
1527 }
1528 }
1529 return SDL_FALSE;
1530 }
1531}
#define SDL_GetHintBoolean
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
#define MAKE_VIDPID(VID, PID)

References SDL_vidpid_list::entries, i, MAKE_VIDPID, SDL_vidpid_list::num_entries, SDL_allowed_controllers, SDL_FALSE, SDL_GetHintBoolean, SDL_GetJoystickGUIDInfo(), SDL_ignored_controllers, SDL_strstr, and SDL_TRUE.

Referenced by SDL_ShouldIgnoreJoystick().

◆ UpdateEventsForDeviceRemoval()

static void UpdateEventsForDeviceRemoval ( )
static

Definition at line 201 of file SDL_gamecontroller.c.

202{
203 int i, num_events;
205 SDL_bool isstack;
206
208 if (num_events <= 0) {
209 return;
210 }
211
212 events = SDL_small_alloc(SDL_Event, num_events, &isstack);
213 if (!events) {
214 return;
215 }
216
218 for (i = 0; i < num_events; ++i) {
220 }
221 SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
222
223 SDL_small_free(events, isstack);
224}
#define SDL_PeepEvents
@ SDL_ADDEVENT
Definition: SDL_events.h:615
@ SDL_PEEKEVENT
Definition: SDL_events.h:616
@ SDL_GETEVENT
Definition: SDL_events.h:617
#define SDL_small_alloc(type, count, pisstack)
Definition: SDL_internal.h:39
#define SDL_small_free(ptr, isstack)
Definition: SDL_internal.h:40
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:39

References SDL_Event::cdevice, events, i, NULL, SDL_ADDEVENT, SDL_CONTROLLERDEVICEADDED, SDL_GETEVENT, SDL_PEEKEVENT, SDL_PeepEvents, SDL_small_alloc, SDL_small_free, and SDL_ControllerDeviceEvent::which.

Referenced by SDL_GameControllerEventWatcher().

Variable Documentation

◆ map_StringForControllerAxis

const char* map_StringForControllerAxis[]
static
Initial value:
= {
"leftx",
"lefty",
"rightx",
"righty",
"lefttrigger",
"righttrigger",
}

Definition at line 449 of file SDL_gamecontroller.c.

Referenced by SDL_GameControllerGetAxisFromString(), and SDL_GameControllerGetStringForAxis().

◆ map_StringForControllerButton

const char* map_StringForControllerButton[]
static
Initial value:
= {
"a",
"b",
"x",
"y",
"back",
"guide",
"start",
"leftstick",
"rightstick",
"leftshoulder",
"rightshoulder",
"dpup",
"dpdown",
"dpleft",
"dpright",
}

Definition at line 492 of file SDL_gamecontroller.c.

Referenced by SDL_GameControllerGetButtonFromString(), and SDL_GameControllerGetStringForButton().

◆ s_pDefaultMapping

◆ s_pHIDAPIMapping

ControllerMapping_t* s_pHIDAPIMapping = NULL
static

◆ s_pSupportedControllers

◆ s_pXInputMapping

◆ s_zeroGUID

SDL_JoystickGUID s_zeroGUID
static

◆ SDL_allowed_controllers

◆ SDL_gamecontrollers

◆ SDL_ignored_controllers