SDL  2.0
SDL_gamecontroller.c File Reference
#include "../SDL_internal.h"
#include "SDL_events.h"
#include "SDL_assert.h"
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_hints.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_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_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, SDL_JoystickGUID guid, 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 ()
 
int SDL_GameControllerInitMappings (void)
 
int SDL_GameControllerInit (void)
 
const char * SDL_GameControllerNameForIndex (int device_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)
 
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)
 
void SDL_GameControllerClose (SDL_GameController *gamecontroller)
 
void SDL_GameControllerQuit (void)
 
void SDL_GameControllerQuitMappings (void)
 
int SDL_GameControllerEventState (int state)
 

Variables

static SDL_GameController * SDL_gamecontrollers = NULL
 
static SDL_JoystickGUID s_zeroGUID
 
static ControllerMapping_ts_pSupportedControllers = NULL
 
static ControllerMapping_ts_pXInputMapping = NULL
 
static ControllerMapping_ts_pEmscriptenMapping = 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 36 of file SDL_gamecontroller.c.

Referenced by SDL_GameControllerAddMappingsFromRW().

Enumeration Type Documentation

◆ SDL_ControllerMappingPriority

Enumerator
SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT 
SDL_CONTROLLER_MAPPING_PRIORITY_API 
SDL_CONTROLLER_MAPPING_PRIORITY_USER 

Definition at line 77 of file SDL_gamecontroller.c.

Function Documentation

◆ HandleJoystickAxis()

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

Definition at line 237 of file SDL_gamecontroller.c.

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().

238 {
239  int i;
240  SDL_ExtendedGameControllerBind *last_match = gamecontroller->last_match_axis[axis];
242 
243  for (i = 0; i < gamecontroller->num_bindings; ++i) {
244  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
245  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
246  axis == binding->input.axis.axis) {
247  if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
248  if (value >= binding->input.axis.axis_min &&
249  value <= binding->input.axis.axis_max) {
250  match = binding;
251  break;
252  }
253  } else {
254  if (value >= binding->input.axis.axis_max &&
255  value <= binding->input.axis.axis_min) {
256  match = binding;
257  break;
258  }
259  }
260  }
261  }
262 
263  if (last_match && (!match || !HasSameOutput(last_match, match))) {
264  /* Clear the last input that this axis generated */
265  ResetOutput(gamecontroller, last_match);
266  }
267 
268  if (match) {
270  if (match->input.axis.axis_min != match->output.axis.axis_min || match->input.axis.axis_max != match->output.axis.axis_max) {
271  float normalized_value = (float)(value - match->input.axis.axis_min) / (match->input.axis.axis_max - match->input.axis.axis_min);
272  value = match->output.axis.axis_min + (int)(normalized_value * (match->output.axis.axis_max - match->output.axis.axis_min));
273  }
274  SDL_PrivateGameControllerAxis(gamecontroller, match->output.axis.axis, (Sint16)value);
275  } else {
276  Uint8 state;
277  int threshold = match->input.axis.axis_min + (match->input.axis.axis_max - match->input.axis.axis_min) / 2;
278  if (match->input.axis.axis_max < match->input.axis.axis_min) {
279  state = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
280  } else {
281  state = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
282  }
283  SDL_PrivateGameControllerButton(gamecontroller, match->output.button, state);
284  }
285  }
286  gamecontroller->last_match_axis[axis] = match;
287 }
union SDL_ExtendedGameControllerBind::@24 output
static void ResetOutput(SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind)
struct xkb_state * state
SDL_GameControllerBindType inputType
SDL_Texture * axis
union SDL_ExtendedGameControllerBind::@23 input
GLenum GLenum GLenum input
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:153
SDL_GameControllerBindType outputType
static SDL_bool HasSameOutput(SDL_ExtendedGameControllerBind *a, SDL_ExtendedGameControllerBind *b)
GLsizei const GLfloat * value
static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 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:164
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_RELEASED
Definition: SDL_events.h:49
static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:157

◆ HandleJoystickButton()

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

Definition at line 289 of file SDL_gamecontroller.c.

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

Referenced by SDL_GameControllerEventWatcher().

290 {
291  int i;
292 
293  for (i = 0; i < gamecontroller->num_bindings; ++i) {
294  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
295  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON &&
296  button == binding->input.button) {
297  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
298  int value = state ? binding->output.axis.axis_max : binding->output.axis.axis_min;
299  SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)value);
300  } else {
301  SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, state);
302  }
303  break;
304  }
305  }
306 }
union SDL_ExtendedGameControllerBind::@24 output
SDL_Texture * button
struct xkb_state * state
SDL_GameControllerBindType inputType
union SDL_ExtendedGameControllerBind::@23 input
SDL_GameControllerBindType outputType
GLsizei const GLfloat * value
static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 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
static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:157

◆ HandleJoystickHat()

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

Definition at line 308 of file SDL_gamecontroller.c.

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().

309 {
310  int i;
311  Uint8 last_mask = gamecontroller->last_hat_mask[hat];
312  Uint8 changed_mask = (last_mask ^ value);
313 
314  for (i = 0; i < gamecontroller->num_bindings; ++i) {
315  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
316  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT && hat == binding->input.hat.hat) {
317  if ((changed_mask & binding->input.hat.hat_mask) != 0) {
318  if (value & binding->input.hat.hat_mask) {
319  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
320  SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)binding->output.axis.axis_max);
321  } else {
322  SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, SDL_PRESSED);
323  }
324  } else {
325  ResetOutput(gamecontroller, binding);
326  }
327  }
328  }
329  }
330  gamecontroller->last_hat_mask[hat] = value;
331 }
union SDL_ExtendedGameControllerBind::@24 output
static void ResetOutput(SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind)
SDL_GameControllerBindType inputType
union SDL_ExtendedGameControllerBind::@23 input
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:153
SDL_GameControllerBindType outputType
GLsizei const GLfloat * value
static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 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 SDL_PRESSED
Definition: SDL_events.h:50
static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:157

◆ HasSameOutput()

◆ ResetOutput()

static void ResetOutput ( SDL_GameController *  gamecontroller,
SDL_ExtendedGameControllerBind bind 
)
static

Definition at line 228 of file SDL_gamecontroller.c.

References SDL_ExtendedGameControllerBind::axis, SDL_ExtendedGameControllerBind::button, SDL_ExtendedGameControllerBind::output, SDL_ExtendedGameControllerBind::outputType, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_PrivateGameControllerAxis(), SDL_PrivateGameControllerButton(), and SDL_RELEASED.

Referenced by HandleJoystickAxis(), and HandleJoystickHat().

229 {
231  SDL_PrivateGameControllerAxis(gamecontroller, bind->output.axis.axis, 0);
232  } else {
234  }
235 }
union SDL_ExtendedGameControllerBind::@24 output
SDL_GameControllerBindType outputType
static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state)
#define SDL_RELEASED
Definition: SDL_events.h:49
static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)

◆ 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 1038 of file SDL_gamecontroller.c.

References SDL_CONTROLLER_MAPPING_PRIORITY_API, and SDL_PrivateGameControllerAddMapping().

Referenced by SDL_GameControllerAddMappingsFromRW().

1039 {
1041 }
static int SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority)

◆ 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 919 of file SDL_gamecontroller.c.

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.

920 {
921  const char *platform = SDL_GetPlatform();
922  int controllers = 0;
923  char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
924  size_t db_size, platform_len;
925 
926  if (rw == NULL) {
927  return SDL_SetError("Invalid RWops");
928  }
929  db_size = (size_t)SDL_RWsize(rw);
930 
931  buf = (char *)SDL_malloc(db_size + 1);
932  if (buf == NULL) {
933  if (freerw) {
934  SDL_RWclose(rw);
935  }
936  return SDL_SetError("Could not allocate space to read DB into memory");
937  }
938 
939  if (SDL_RWread(rw, buf, db_size, 1) != 1) {
940  if (freerw) {
941  SDL_RWclose(rw);
942  }
943  SDL_free(buf);
944  return SDL_SetError("Could not read DB");
945  }
946 
947  if (freerw) {
948  SDL_RWclose(rw);
949  }
950 
951  buf[db_size] = '\0';
952  line = buf;
953 
954  while (line < buf + db_size) {
955  line_end = SDL_strchr(line, '\n');
956  if (line_end != NULL) {
957  *line_end = '\0';
958  } else {
959  line_end = buf + db_size;
960  }
961 
962  /* Extract and verify the platform */
964  if (tmp != NULL) {
966  comma = SDL_strchr(tmp, ',');
967  if (comma != NULL) {
968  platform_len = comma - tmp + 1;
969  if (platform_len + 1 < SDL_arraysize(line_platform)) {
970  SDL_strlcpy(line_platform, tmp, platform_len);
971  if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 &&
972  SDL_GameControllerAddMapping(line) > 0) {
973  controllers++;
974  }
975  }
976  }
977  }
978 
979  line = line_end + 1;
980  }
981 
982  SDL_free(buf);
983  return controllers;
984 }
#define SDL_strlcpy
#define SDL_CONTROLLER_PLATFORM_FIELD
#define SDL_RWsize(ctx)
Definition: SDL_rwops.h:184
#define SDL_RWread(ctx, ptr, size, n)
Definition: SDL_rwops.h:187
#define SDL_strncasecmp
#define SDL_strchr
unsigned int size_t
int SDL_GameControllerAddMapping(const char *mappingString)
void SDL_free(void *mem)
#define SDL_GetPlatform
GLenum GLuint GLenum GLsizei const GLchar * buf
#define NULL
Definition: begin_code.h:164
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
#define SDL_SetError
#define SDL_strlen
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
#define SDL_malloc
#define SDL_strstr

◆ SDL_GameControllerClose()

void SDL_GameControllerClose ( SDL_GameController *  gamecontroller)

Close a controller previously opened with SDL_GameControllerOpen().

Definition at line 1637 of file SDL_gamecontroller.c.

References NULL, SDL_free(), SDL_gamecontrollers, SDL_JoystickClose, SDL_LockJoystickList(), and SDL_UnlockJoystickList().

Referenced by SDL_GameControllerQuit().

1638 {
1639  SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
1640 
1641  if (!gamecontroller)
1642  return;
1643 
1645 
1646  /* First decrement ref count */
1647  if (--gamecontroller->ref_count > 0) {
1649  return;
1650  }
1651 
1652  SDL_JoystickClose(gamecontroller->joystick);
1653 
1654  gamecontrollerlist = SDL_gamecontrollers;
1655  gamecontrollerlistprev = NULL;
1656  while (gamecontrollerlist) {
1657  if (gamecontroller == gamecontrollerlist) {
1658  if (gamecontrollerlistprev) {
1659  /* unlink this entry */
1660  gamecontrollerlistprev->next = gamecontrollerlist->next;
1661  } else {
1662  SDL_gamecontrollers = gamecontroller->next;
1663  }
1664  break;
1665  }
1666  gamecontrollerlistprev = gamecontrollerlist;
1667  gamecontrollerlist = gamecontrollerlist->next;
1668  }
1669 
1670  SDL_free(gamecontroller->bindings);
1671  SDL_free(gamecontroller->last_match_axis);
1672  SDL_free(gamecontroller->last_hat_mask);
1673  SDL_free(gamecontroller);
1674 
1676 }
void SDL_UnlockJoystickList(void)
Definition: SDL_joystick.c:51
#define SDL_JoystickClose
void SDL_LockJoystickList(void)
Definition: SDL_joystick.c:43
static SDL_GameController * SDL_gamecontrollers
void SDL_free(void *mem)
#define NULL
Definition: begin_code.h:164

◆ 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 1790 of file SDL_gamecontroller.c.

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

1791 {
1792 #if SDL_EVENTS_DISABLED
1793  return SDL_IGNORE;
1794 #else
1795  const Uint32 event_list[] = {
1798  };
1799  unsigned int i;
1800 
1801  switch (state) {
1802  case SDL_QUERY:
1803  state = SDL_IGNORE;
1804  for (i = 0; i < SDL_arraysize(event_list); ++i) {
1805  state = SDL_EventState(event_list[i], SDL_QUERY);
1806  if (state == SDL_ENABLE) {
1807  break;
1808  }
1809  }
1810  break;
1811  default:
1812  for (i = 0; i < SDL_arraysize(event_list); ++i) {
1813  SDL_EventState(event_list[i], state);
1814  }
1815  break;
1816  }
1817  return (state);
1818 #endif /* SDL_EVENTS_DISABLED */
1819 }
struct xkb_state * state
#define SDL_ENABLE
Definition: SDL_events.h:722
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:169
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define SDL_EventState
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
#define SDL_QUERY
Definition: SDL_events.h:719
#define SDL_IGNORE
Definition: SDL_events.h:720

◆ SDL_GameControllerEventWatcher()

static int SDL_GameControllerEventWatcher ( void userdata,
SDL_Event event 
)
static

Definition at line 336 of file SDL_gamecontroller.c.

References SDL_JoyAxisEvent::axis, SDL_JoyButtonEvent::button, SDL_Event::cdevice, HandleJoystickAxis(), HandleJoystickButton(), HandleJoystickHat(), SDL_JoyHatEvent::hat, SDL_Event::jaxis, SDL_Event::jbutton, SDL_Event::jdevice, SDL_Event::jhat, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_gamecontrollers, SDL_IsGameController(), SDL_JOYAXISMOTION, SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED, SDL_JOYHATMOTION, SDL_PushEvent, SDL_JoyButtonEvent::state, SDL_Event::type, UpdateEventsForDeviceRemoval(), SDL_JoyAxisEvent::value, SDL_JoyHatEvent::value, SDL_JoyAxisEvent::which, SDL_JoyHatEvent::which, SDL_JoyButtonEvent::which, SDL_JoyDeviceEvent::which, and SDL_ControllerDeviceEvent::which.

Referenced by SDL_GameControllerInit(), and SDL_GameControllerQuitMappings().

337 {
338  switch(event->type) {
339  case SDL_JOYAXISMOTION:
340  {
341  SDL_GameController *controllerlist = SDL_gamecontrollers;
342  while (controllerlist) {
343  if (controllerlist->joystick->instance_id == event->jaxis.which) {
344  HandleJoystickAxis(controllerlist, event->jaxis.axis, event->jaxis.value);
345  break;
346  }
347  controllerlist = controllerlist->next;
348  }
349  }
350  break;
351  case SDL_JOYBUTTONDOWN:
352  case SDL_JOYBUTTONUP:
353  {
354  SDL_GameController *controllerlist = SDL_gamecontrollers;
355  while (controllerlist) {
356  if (controllerlist->joystick->instance_id == event->jbutton.which) {
357  HandleJoystickButton(controllerlist, event->jbutton.button, event->jbutton.state);
358  break;
359  }
360  controllerlist = controllerlist->next;
361  }
362  }
363  break;
364  case SDL_JOYHATMOTION:
365  {
366  SDL_GameController *controllerlist = SDL_gamecontrollers;
367  while (controllerlist) {
368  if (controllerlist->joystick->instance_id == event->jhat.which) {
369  HandleJoystickHat(controllerlist, event->jhat.hat, event->jhat.value);
370  break;
371  }
372  controllerlist = controllerlist->next;
373  }
374  }
375  break;
376  case SDL_JOYDEVICEADDED:
377  {
378  if (SDL_IsGameController(event->jdevice.which)) {
379  SDL_Event deviceevent;
380  deviceevent.type = SDL_CONTROLLERDEVICEADDED;
381  deviceevent.cdevice.which = event->jdevice.which;
382  SDL_PushEvent(&deviceevent);
383  }
384  }
385  break;
387  {
388  SDL_GameController *controllerlist = SDL_gamecontrollers;
389  while (controllerlist) {
390  if (controllerlist->joystick->instance_id == event->jdevice.which) {
391  SDL_Event deviceevent;
392 
393  deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
394  deviceevent.cdevice.which = event->jdevice.which;
395  SDL_PushEvent(&deviceevent);
396 
398  break;
399  }
400  controllerlist = controllerlist->next;
401  }
402  }
403  break;
404  default:
405  break;
406  }
407 
408  return 1;
409 }
SDL_JoystickID which
Definition: SDL_events.h:335
SDL_JoyDeviceEvent jdevice
Definition: SDL_events.h:540
static void HandleJoystickHat(SDL_GameController *gamecontroller, int hat, Uint8 value)
SDL_ControllerDeviceEvent cdevice
Definition: SDL_events.h:543
SDL_JoyButtonEvent jbutton
Definition: SDL_events.h:539
static void UpdateEventsForDeviceRemoval()
SDL_JoystickID which
Definition: SDL_events.h:283
static SDL_GameController * SDL_gamecontrollers
SDL_JoyAxisEvent jaxis
Definition: SDL_events.h:536
#define SDL_PushEvent
static void HandleJoystickButton(SDL_GameController *gamecontroller, int button, Uint8 state)
SDL_bool SDL_IsGameController(int device_index)
General event structure.
Definition: SDL_events.h:525
SDL_JoyHatEvent jhat
Definition: SDL_events.h:538
SDL_JoystickID which
Definition: SDL_events.h:315
static void HandleJoystickAxis(SDL_GameController *gamecontroller, int axis, int value)
Uint32 type
Definition: SDL_events.h:527

◆ SDL_GameControllerFromInstanceID()

SDL_GameController* SDL_GameControllerFromInstanceID ( SDL_JoystickID  joyid)

Return the SDL_GameController associated with an instance id.

Definition at line 1555 of file SDL_gamecontroller.c.

References NULL, SDL_gamecontrollers, SDL_LockJoystickList(), and SDL_UnlockJoystickList().

1556 {
1557  SDL_GameController *gamecontroller;
1558 
1560  gamecontroller = SDL_gamecontrollers;
1561  while (gamecontroller) {
1562  if (gamecontroller->joystick->instance_id == joyid) {
1564  return gamecontroller;
1565  }
1566  gamecontroller = gamecontroller->next;
1567  }
1569  return NULL;
1570 }
void SDL_UnlockJoystickList(void)
Definition: SDL_joystick.c:51
void SDL_LockJoystickList(void)
Definition: SDL_joystick.c:43
static SDL_GameController * SDL_gamecontrollers
#define NULL
Definition: begin_code.h:164

◆ 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 1531 of file SDL_gamecontroller.c.

References SDL_FALSE, and SDL_JoystickGetAttached.

1532 {
1533  if (!gamecontroller)
1534  return SDL_FALSE;
1535 
1536  return SDL_JoystickGetAttached(gamecontroller->joystick);
1537 }
#define 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 1405 of file SDL_gamecontroller.c.

References SDL_ExtendedGameControllerBind::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.

1406 {
1407  int i;
1408 
1409  if (!gamecontroller)
1410  return 0;
1411 
1412  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1413  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1414  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
1415  int value = 0;
1416  SDL_bool valid_input_range;
1417  SDL_bool valid_output_range;
1418 
1419  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1420  value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
1421  if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
1422  valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
1423  } else {
1424  valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
1425  }
1426  if (valid_input_range) {
1427  if (binding->input.axis.axis_min != binding->output.axis.axis_min || binding->input.axis.axis_max != binding->output.axis.axis_max) {
1428  float normalized_value = (float)(value - binding->input.axis.axis_min) / (binding->input.axis.axis_max - binding->input.axis.axis_min);
1429  value = binding->output.axis.axis_min + (int)(normalized_value * (binding->output.axis.axis_max - binding->output.axis.axis_min));
1430  }
1431  }
1432  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1433  value = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
1434  if (value == SDL_PRESSED) {
1435  value = binding->output.axis.axis_max;
1436  }
1437  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1438  int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
1439  if (hat_mask & binding->input.hat.hat_mask) {
1440  value = binding->output.axis.axis_max;
1441  }
1442  }
1443 
1444  if (binding->output.axis.axis_min < binding->output.axis.axis_max) {
1445  valid_output_range = (value >= binding->output.axis.axis_min && value <= binding->output.axis.axis_max);
1446  } else {
1447  valid_output_range = (value >= binding->output.axis.axis_max && value <= binding->output.axis.axis_min);
1448  }
1449  /* If the value is zero, there might be another binding that makes it non-zero */
1450  if (value != 0 && valid_output_range) {
1451  return (Sint16)value;
1452  }
1453  }
1454  }
1455  return 0;
1456 }
union SDL_ExtendedGameControllerBind::@24 output
#define SDL_JoystickGetButton
SDL_GameControllerBindType inputType
SDL_Texture * axis
#define SDL_JoystickGetHat
union SDL_ExtendedGameControllerBind::@23 input
SDL_GameControllerBindType outputType
GLsizei const GLfloat * value
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_bool
Definition: SDL_stdinc.h:139
#define SDL_JoystickGetAxis
#define SDL_PRESSED
Definition: SDL_events.h:50
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:157

◆ SDL_GameControllerGetAxisFromString()

SDL_GameControllerAxis SDL_GameControllerGetAxisFromString ( const char *  pchString)

turn this string into a axis mapping

Definition at line 439 of file SDL_gamecontroller.c.

References map_StringForControllerAxis, SDL_CONTROLLER_AXIS_INVALID, and SDL_strcasecmp.

Referenced by SDL_PrivateGameControllerParseElement().

440 {
441  int entry;
442 
443  if (pchString && (*pchString == '+' || *pchString == '-')) {
444  ++pchString;
445  }
446 
447  if (!pchString || !pchString[0]) {
449  }
450 
451  for (entry = 0; map_StringForControllerAxis[entry]; ++entry) {
452  if (!SDL_strcasecmp(pchString, map_StringForControllerAxis[entry]))
453  return (SDL_GameControllerAxis) entry;
454  }
456 }
static const char * map_StringForControllerAxis[]
#define SDL_strcasecmp
SDL_GameControllerAxis

◆ 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 1576 of file SDL_gamecontroller.c.

References SDL_ExtendedGameControllerBind::axis, SDL_GameControllerButtonBind::axis, SDL_GameControllerButtonBind::bindType, SDL_ExtendedGameControllerBind::button, SDL_GameControllerButtonBind::button, SDL_ExtendedGameControllerBind::hat, SDL_GameControllerButtonBind::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.

1577 {
1578  int i;
1580  SDL_zero(bind);
1581 
1582  if (!gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID)
1583  return bind;
1584 
1585  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1586  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1587  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
1588  bind.bindType = binding->inputType;
1589  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1590  /* FIXME: There might be multiple axes bound now that we have axis ranges... */
1591  bind.value.axis = binding->input.axis.axis;
1592  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1593  bind.value.button = binding->input.button;
1594  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1595  bind.value.hat.hat = binding->input.hat.hat;
1596  bind.value.hat.hat_mask = binding->input.hat.hat_mask;
1597  }
1598  break;
1599  }
1600  }
1601  return bind;
1602 }
union SDL_ExtendedGameControllerBind::@24 output
SDL_GameControllerBindType inputType
SDL_Texture * axis
union SDL_ExtendedGameControllerBind::@23 input
SDL_GameControllerBindType bindType
SDL_GameControllerBindType outputType
#define SDL_zero(x)
Definition: SDL_stdinc.h:369
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
union SDL_GameControllerButtonBind::@0 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 1608 of file SDL_gamecontroller.c.

References SDL_ExtendedGameControllerBind::axis, SDL_GameControllerButtonBind::axis, SDL_GameControllerButtonBind::bindType, SDL_ExtendedGameControllerBind::button, SDL_GameControllerButtonBind::button, SDL_ExtendedGameControllerBind::hat, SDL_GameControllerButtonBind::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.

1609 {
1610  int i;
1612  SDL_zero(bind);
1613 
1614  if (!gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID)
1615  return bind;
1616 
1617  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1618  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1619  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
1620  bind.bindType = binding->inputType;
1621  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1622  bind.value.axis = binding->input.axis.axis;
1623  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1624  bind.value.button = binding->input.button;
1625  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1626  bind.value.hat.hat = binding->input.hat.hat;
1627  bind.value.hat.hat_mask = binding->input.hat.hat_mask;
1628  }
1629  break;
1630  }
1631  }
1632  return bind;
1633 }
union SDL_ExtendedGameControllerBind::@24 output
SDL_Texture * button
SDL_GameControllerBindType inputType
union SDL_ExtendedGameControllerBind::@23 input
SDL_GameControllerBindType bindType
SDL_GameControllerBindType outputType
#define SDL_zero(x)
Definition: SDL_stdinc.h:369
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
union SDL_GameControllerButtonBind::@0 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 1462 of file SDL_gamecontroller.c.

References SDL_ExtendedGameControllerBind::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, SDL_PRESSED, and SDL_RELEASED.

1463 {
1464  int i;
1465 
1466  if (!gamecontroller)
1467  return 0;
1468 
1469  for (i = 0; i < gamecontroller->num_bindings; ++i) {
1470  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
1471  if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
1472  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
1473  SDL_bool valid_input_range;
1474 
1475  int value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
1476  int threshold = binding->input.axis.axis_min + (binding->input.axis.axis_max - binding->input.axis.axis_min) / 2;
1477  if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
1478  valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
1479  if (valid_input_range) {
1480  return (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
1481  }
1482  } else {
1483  valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
1484  if (valid_input_range) {
1485  return (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
1486  }
1487  }
1488  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
1489  return SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
1490  } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
1491  int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
1492  return (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED;
1493  }
1494  }
1495  }
1496  return SDL_RELEASED;
1497 }
union SDL_ExtendedGameControllerBind::@24 output
#define SDL_JoystickGetButton
SDL_Texture * button
SDL_GameControllerBindType inputType
#define SDL_JoystickGetHat
union SDL_ExtendedGameControllerBind::@23 input
SDL_GameControllerBindType outputType
GLsizei const GLfloat * value
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_bool
Definition: SDL_stdinc.h:139
#define SDL_JoystickGetAxis
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_RELEASED
Definition: SDL_events.h:49

◆ SDL_GameControllerGetButtonFromString()

SDL_GameControllerButton SDL_GameControllerGetButtonFromString ( const char *  pchString)

turn this string into a button mapping

Definition at line 491 of file SDL_gamecontroller.c.

References map_StringForControllerButton, SDL_CONTROLLER_BUTTON_INVALID, and SDL_strcasecmp.

Referenced by SDL_PrivateGameControllerParseElement().

492 {
493  int entry;
494  if (!pchString || !pchString[0])
496 
497  for (entry = 0; map_StringForControllerButton[entry]; ++entry) {
498  if (SDL_strcasecmp(pchString, map_StringForControllerButton[entry]) == 0)
499  return (SDL_GameControllerButton) entry;
500  }
502 }
SDL_GameControllerButton
#define SDL_strcasecmp
static const char * map_StringForControllerButton[]

◆ SDL_GameControllerGetJoystick()

SDL_Joystick* SDL_GameControllerGetJoystick ( SDL_GameController *  gamecontroller)

Get the underlying joystick object used by a controller

Definition at line 1542 of file SDL_gamecontroller.c.

References NULL.

Referenced by SDL_GameControllerGetProduct(), SDL_GameControllerGetProductVersion(), and SDL_GameControllerGetVendor().

1543 {
1544  if (!gamecontroller)
1545  return NULL;
1546 
1547  return gamecontroller->joystick;
1548 }
#define NULL
Definition: begin_code.h:164

◆ 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 1515 of file SDL_gamecontroller.c.

References SDL_GameControllerGetJoystick(), and SDL_JoystickGetProduct.

1516 {
1517  return SDL_JoystickGetProduct(SDL_GameControllerGetJoystick(gamecontroller));
1518 }
#define SDL_JoystickGetProduct
SDL_Joystick * SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)

◆ 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 1521 of file SDL_gamecontroller.c.

References SDL_GameControllerGetJoystick(), and SDL_JoystickGetProductVersion.

1522 {
1524 }
SDL_Joystick * SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)
#define SDL_JoystickGetProductVersion

◆ SDL_GameControllerGetStringForAxis()

const char* SDL_GameControllerGetStringForAxis ( SDL_GameControllerAxis  axis)

turn this axis enum into a string mapping

Definition at line 461 of file SDL_gamecontroller.c.

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

462 {
465  }
466  return NULL;
467 }
static const char * map_StringForControllerAxis[]
SDL_Texture * axis
#define NULL
Definition: begin_code.h:164

◆ SDL_GameControllerGetStringForButton()

const char* SDL_GameControllerGetStringForButton ( SDL_GameControllerButton  button)

turn this button enum into a string mapping

Definition at line 507 of file SDL_gamecontroller.c.

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

508 {
511  }
512  return NULL;
513 }
SDL_Texture * axis
static const char * map_StringForControllerButton[]
#define NULL
Definition: begin_code.h:164

◆ 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 1509 of file SDL_gamecontroller.c.

References SDL_GameControllerGetJoystick(), and SDL_JoystickGetVendor.

1510 {
1511  return SDL_JoystickGetVendor(SDL_GameControllerGetJoystick(gamecontroller));
1512 }
#define SDL_JoystickGetVendor
SDL_Joystick * SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)

◆ SDL_GameControllerIgnoreDevicesChanged()

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

Definition at line 172 of file SDL_gamecontroller.c.

References SDL_LoadVIDPIDListFromHint(), and SDLCALL.

Referenced by SDL_GameControllerInitMappings(), and SDL_GameControllerQuitMappings().

173 {
175 }
static SDL_vidpid_list SDL_ignored_controllers
static void SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list)

◆ SDL_GameControllerIgnoreDevicesExceptChanged()

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

Definition at line 178 of file SDL_gamecontroller.c.

References axis, button, SDL_LoadVIDPIDListFromHint(), SDL_PrivateGameControllerAxis(), SDL_PrivateGameControllerButton(), and state.

Referenced by SDL_GameControllerInitMappings(), and SDL_GameControllerQuitMappings().

179 {
181 }
static SDL_vidpid_list SDL_allowed_controllers
static void SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list)

◆ SDL_GameControllerInit()

int SDL_GameControllerInit ( void  )

Definition at line 1188 of file SDL_gamecontroller.c.

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().

1189 {
1190  int i;
1191 
1192  /* watch for joy events and fire controller ones if needed */
1194 
1195  /* Send added events for controllers currently attached */
1196  for (i = 0; i < SDL_NumJoysticks(); ++i) {
1197  if (SDL_IsGameController(i)) {
1198  SDL_Event deviceevent;
1199  deviceevent.type = SDL_CONTROLLERDEVICEADDED;
1200  deviceevent.cdevice.which = i;
1201  SDL_PushEvent(&deviceevent);
1202  }
1203  }
1204 
1205  return (0);
1206 }
static int SDL_GameControllerEventWatcher(void *userdata, SDL_Event *event)
SDL_ControllerDeviceEvent cdevice
Definition: SDL_events.h:543
#define SDL_NumJoysticks
#define SDL_PushEvent
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_bool SDL_IsGameController(int device_index)
#define NULL
Definition: begin_code.h:164
#define SDL_AddEventWatch
General event structure.
Definition: SDL_events.h:525
Uint32 type
Definition: SDL_events.h:527

◆ SDL_GameControllerInitMappings()

int SDL_GameControllerInitMappings ( void  )

Definition at line 1164 of file SDL_gamecontroller.c.

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

Referenced by SDL_JoystickInit().

1165 {
1166  int i = 0;
1167  const char *pMappingString = NULL;
1168  pMappingString = s_ControllerMappings[i];
1169  while (pMappingString) {
1171 
1172  i++;
1173  pMappingString = s_ControllerMappings[i];
1174  }
1175 
1176  /* load in any user supplied config */
1178 
1183 
1184  return (0);
1185 }
static void SDL_GameControllerLoadHints()
static int SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority)
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT
Definition: SDL_hints.h:420
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:164
static void SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
static const char * s_ControllerMappings[]
#define SDL_AddHintCallback
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES
Definition: SDL_hints.h:407
static void SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)

◆ SDL_GameControllerLoadHints()

static void SDL_GameControllerLoadHints ( )
static

Definition at line 1132 of file SDL_gamecontroller.c.

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().

1133 {
1134  const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
1135  if (hint && hint[0]) {
1136  size_t nchHints = SDL_strlen(hint);
1137  char *pUserMappings = SDL_malloc(nchHints + 1);
1138  char *pTempMappings = pUserMappings;
1139  SDL_memcpy(pUserMappings, hint, nchHints);
1140  pUserMappings[nchHints] = '\0';
1141  while (pUserMappings) {
1142  char *pchNewLine = NULL;
1143 
1144  pchNewLine = SDL_strchr(pUserMappings, '\n');
1145  if (pchNewLine)
1146  *pchNewLine = '\0';
1147 
1149 
1150  if (pchNewLine) {
1151  pUserMappings = pchNewLine + 1;
1152  } else {
1153  pUserMappings = NULL;
1154  }
1155  }
1156  SDL_free(pTempMappings);
1157  }
1158 }
#define SDL_GetHint
#define SDL_strchr
static int SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority)
#define SDL_memcpy
void SDL_free(void *mem)
#define NULL
Definition: begin_code.h:164
#define SDL_strlen
#define SDL_HINT_GAMECONTROLLERCONFIG
A variable that lets you manually hint extra gamecontroller db entries.
Definition: SDL_hints.h:394
#define SDL_malloc

◆ 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 1122 of file SDL_gamecontroller.c.

References NULL, and SDL_GameControllerMappingForGUID().

1123 {
1124  if (!gamecontroller) {
1125  return NULL;
1126  }
1127 
1128  return SDL_GameControllerMappingForGUID(gamecontroller->guid);
1129 }
#define NULL
Definition: begin_code.h:164
char * SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)

◆ 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 1098 of file SDL_gamecontroller.c.

References ControllerMapping_t::mapping, ControllerMapping_t::name, NULL, SDL_JoystickGetGUIDString, SDL_malloc, SDL_OutOfMemory, SDL_PrivateGetControllerMappingForGUID(), SDL_snprintf, and SDL_strlen.

Referenced by SDL_GameControllerMapping().

1099 {
1100  char *pMappingString = NULL;
1102  if (mapping) {
1103  char pchGUID[33];
1104  size_t needed;
1105  SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
1106  /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1107  needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1108  pMappingString = SDL_malloc(needed);
1109  if (!pMappingString) {
1110  SDL_OutOfMemory();
1111  return NULL;
1112  }
1113  SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1114  }
1115  return pMappingString;
1116 }
#define SDL_JoystickGetGUIDString
static ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_strlen
#define SDL_snprintf
GLenum GLenum GLenum GLenum mapping
#define SDL_malloc

◆ 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 1065 of file SDL_gamecontroller.c.

References ControllerMapping_t::guid, ControllerMapping_t::mapping, ControllerMapping_t::name, ControllerMapping_t::next, NULL, SDL_JoystickGetGUIDString, SDL_malloc, SDL_memcmp, SDL_OutOfMemory, SDL_snprintf, and SDL_strlen.

1066 {
1068 
1069  for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
1070  if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
1071  continue;
1072  }
1073  if (mapping_index == 0) {
1074  char *pMappingString;
1075  char pchGUID[33];
1076  size_t needed;
1077 
1078  SDL_JoystickGetGUIDString(mapping->guid, pchGUID, sizeof(pchGUID));
1079  /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
1080  needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
1081  pMappingString = SDL_malloc(needed);
1082  if (!pMappingString) {
1083  SDL_OutOfMemory();
1084  return NULL;
1085  }
1086  SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
1087  return pMappingString;
1088  }
1089  --mapping_index;
1090  }
1091  return NULL;
1092 }
struct _ControllerMapping_t * next
#define SDL_JoystickGetGUIDString
SDL_JoystickGUID guid
static ControllerMapping_t * s_pSupportedControllers
#define SDL_memcmp
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
static SDL_JoystickGUID s_zeroGUID
#define SDL_strlen
#define SDL_snprintf
GLenum GLenum GLenum GLenum mapping
#define SDL_malloc

◆ SDL_GameControllerName()

const char* SDL_GameControllerName ( SDL_GameController *  gamecontroller)

Return the name for this currently opened controller

Definition at line 1500 of file SDL_gamecontroller.c.

References NULL.

1501 {
1502  if (!gamecontroller)
1503  return NULL;
1504 
1505  return gamecontroller->name;
1506 }
#define NULL
Definition: begin_code.h:164

◆ 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 1213 of file SDL_gamecontroller.c.

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

1214 {
1215  ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1216  if (pSupportedController) {
1217  return pSupportedController->name;
1218  }
1219  return NULL;
1220 }
static ControllerMapping_t * SDL_PrivateGetControllerMapping(int device_index)
#define NULL
Definition: begin_code.h:164

◆ SDL_GameControllerNumMappings()

int SDL_GameControllerNumMappings ( void  )

Get the number of mappings installed

Returns
the number of mappings

Definition at line 1047 of file SDL_gamecontroller.c.

References ControllerMapping_t::guid, ControllerMapping_t::next, and SDL_memcmp.

1048 {
1049  int num_mappings = 0;
1051 
1052  for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
1053  if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
1054  continue;
1055  }
1056  ++num_mappings;
1057  }
1058  return num_mappings;
1059 }
struct _ControllerMapping_t * next
SDL_JoystickGUID guid
static ControllerMapping_t * s_pSupportedControllers
#define SDL_memcmp
static SDL_JoystickGUID s_zeroGUID
GLenum GLenum GLenum GLenum mapping

◆ 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 1308 of file SDL_gamecontroller.c.

References ControllerMapping_t::guid, ControllerMapping_t::mapping, ControllerMapping_t::name, NULL, SDL_calloc(), SDL_free(), SDL_gamecontrollers, SDL_JoystickClose, SDL_JoystickOpen, SDL_LockJoystickList(), SDL_NumJoysticks, SDL_OutOfMemory, SDL_PrivateGetControllerMapping(), SDL_PrivateLoadButtonMapping(), SDL_SetError, SDL_SYS_GetInstanceIdOfDeviceIndex(), and SDL_UnlockJoystickList().

1309 {
1310  SDL_GameController *gamecontroller;
1311  SDL_GameController *gamecontrollerlist;
1312  ControllerMapping_t *pSupportedController = NULL;
1313 
1314  if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
1315  SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
1316  return (NULL);
1317  }
1318 
1320 
1321  gamecontrollerlist = SDL_gamecontrollers;
1322  /* If the controller is already open, return it */
1323  while (gamecontrollerlist) {
1324  if (SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id) {
1325  gamecontroller = gamecontrollerlist;
1326  ++gamecontroller->ref_count;
1328  return (gamecontroller);
1329  }
1330  gamecontrollerlist = gamecontrollerlist->next;
1331  }
1332 
1333  /* Find a controller mapping */
1334  pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1335  if (!pSupportedController) {
1336  SDL_SetError("Couldn't find mapping for device (%d)", device_index);
1338  return NULL;
1339  }
1340 
1341  /* Create and initialize the controller */
1342  gamecontroller = (SDL_GameController *) SDL_calloc(1, sizeof(*gamecontroller));
1343  if (gamecontroller == NULL) {
1344  SDL_OutOfMemory();
1346  return NULL;
1347  }
1348 
1349  gamecontroller->joystick = SDL_JoystickOpen(device_index);
1350  if (!gamecontroller->joystick) {
1351  SDL_free(gamecontroller);
1353  return NULL;
1354  }
1355 
1356  if (gamecontroller->joystick->naxes) {
1357  gamecontroller->last_match_axis = (SDL_ExtendedGameControllerBind **)SDL_calloc(gamecontroller->joystick->naxes, sizeof(*gamecontroller->last_match_axis));
1358  if (!gamecontroller->last_match_axis) {
1359  SDL_OutOfMemory();
1360  SDL_JoystickClose(gamecontroller->joystick);
1361  SDL_free(gamecontroller);
1363  return NULL;
1364  }
1365  }
1366  if (gamecontroller->joystick->nhats) {
1367  gamecontroller->last_hat_mask = (Uint8 *)SDL_calloc(gamecontroller->joystick->nhats, sizeof(*gamecontroller->last_hat_mask));
1368  if (!gamecontroller->last_hat_mask) {
1369  SDL_OutOfMemory();
1370  SDL_JoystickClose(gamecontroller->joystick);
1371  SDL_free(gamecontroller->last_match_axis);
1372  SDL_free(gamecontroller);
1374  return NULL;
1375  }
1376  }
1377 
1378  SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping);
1379 
1380  /* Add the controller to list */
1381  ++gamecontroller->ref_count;
1382  /* Link the controller in the list */
1383  gamecontroller->next = SDL_gamecontrollers;
1384  SDL_gamecontrollers = gamecontroller;
1385 
1387 
1388  return (gamecontroller);
1389 }
void SDL_UnlockJoystickList(void)
Definition: SDL_joystick.c:51
#define SDL_JoystickClose
#define SDL_JoystickOpen
#define SDL_NumJoysticks
void SDL_LockJoystickList(void)
Definition: SDL_joystick.c:43
void * SDL_calloc(size_t nmemb, size_t size)
SDL_JoystickGUID guid
static SDL_GameController * SDL_gamecontrollers
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:153
void SDL_free(void *mem)
static ControllerMapping_t * SDL_PrivateGetControllerMapping(int device_index)
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_SetError
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)

◆ SDL_GameControllerQuit()

void SDL_GameControllerQuit ( void  )

Definition at line 1683 of file SDL_gamecontroller.c.

References SDL_GameControllerClose(), SDL_gamecontrollers, SDL_LockJoystickList(), and SDL_UnlockJoystickList().

Referenced by SDL_QuitSubSystem().

1684 {
1686  while (SDL_gamecontrollers) {
1687  SDL_gamecontrollers->ref_count = 1;
1689  }
1691 }
void SDL_UnlockJoystickList(void)
Definition: SDL_joystick.c:51
void SDL_LockJoystickList(void)
Definition: SDL_joystick.c:43
void SDL_GameControllerClose(SDL_GameController *gamecontroller)
static SDL_GameController * SDL_gamecontrollers

◆ SDL_GameControllerQuitMappings()

void SDL_GameControllerQuitMappings ( void  )

Definition at line 1694 of file SDL_gamecontroller.c.

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

Referenced by SDL_JoystickQuit().

1695 {
1696  ControllerMapping_t *pControllerMap;
1697 
1698  while (s_pSupportedControllers) {
1699  pControllerMap = s_pSupportedControllers;
1701  SDL_free(pControllerMap->name);
1702  SDL_free(pControllerMap->mapping);
1703  SDL_free(pControllerMap);
1704  }
1705 
1707 
1712 
1716  }
1720  }
1721 }
#define SDL_DelEventWatch
static int SDL_GameControllerEventWatcher(void *userdata, SDL_Event *event)
struct _ControllerMapping_t * next
static SDL_vidpid_list SDL_ignored_controllers
static ControllerMapping_t * s_pSupportedControllers
void SDL_free(void *mem)
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT
Definition: SDL_hints.h:420
#define SDL_zero(x)
Definition: SDL_stdinc.h:369
#define NULL
Definition: begin_code.h:164
static void SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
static SDL_vidpid_list SDL_allowed_controllers
#define SDL_DelHintCallback
#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES
Definition: SDL_hints.h:407
static void SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)

◆ 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 1395 of file SDL_gamecontroller.c.

References SDL_JoystickUpdate.

1396 {
1397  /* Just for API completeness; the joystick API does all the work. */
1399 }
#define SDL_JoystickUpdate

◆ SDL_IsGameController()

SDL_bool SDL_IsGameController ( int  joystick_index)

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

Definition at line 1240 of file SDL_gamecontroller.c.

References SDL_FALSE, SDL_PrivateGetControllerMapping(), and SDL_TRUE.

Referenced by SDL_GameControllerEventWatcher(), and SDL_GameControllerInit().

1241 {
1242  ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
1243  if (pSupportedController) {
1244  return SDL_TRUE;
1245  }
1246  return SDL_FALSE;
1247 }
static ControllerMapping_t * SDL_PrivateGetControllerMapping(int device_index)

◆ SDL_IsGameControllerNameAndGUID()

SDL_bool SDL_IsGameControllerNameAndGUID ( const char *  name,
SDL_JoystickGUID  guid 
)

Definition at line 1227 of file SDL_gamecontroller.c.

References SDL_FALSE, SDL_PrivateGetControllerMappingForNameAndGUID(), and SDL_TRUE.

1228 {
1230  if (pSupportedController) {
1231  return SDL_TRUE;
1232  }
1233  return SDL_FALSE;
1234 }
static ControllerMapping_t * SDL_PrivateGetControllerMappingForNameAndGUID(const char *name, SDL_JoystickGUID guid)
GLuint const GLchar * name

◆ SDL_LoadVIDPIDListFromHint()

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

Definition at line 126 of file SDL_gamecontroller.c.

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

Referenced by SDL_GameControllerIgnoreDevicesChanged(), and SDL_GameControllerIgnoreDevicesExceptChanged().

127 {
128  Uint32 entry;
129  char *spot;
130  char *file = NULL;
131 
132  list->num_entries = 0;
133 
134  if (hint && *hint == '@') {
135  spot = file = (char *)SDL_LoadFile(hint+1, NULL);
136  } else {
137  spot = (char *)hint;
138  }
139 
140  if (!spot) {
141  return;
142  }
143 
144  while ((spot = SDL_strstr(spot, "0x")) != NULL) {
145  entry = (Uint16)SDL_strtol(spot, &spot, 0);
146  entry <<= 16;
147  spot = SDL_strstr(spot, "0x");
148  if (!spot) {
149  break;
150  }
151  entry |= (Uint16)SDL_strtol(spot, &spot, 0);
152 
153  if (list->num_entries == list->max_entries) {
154  int max_entries = list->max_entries + 16;
155  Uint32 *entries = (Uint32 *)SDL_realloc(list->entries, max_entries*sizeof(*list->entries));
156  if (entries == NULL) {
157  /* Out of memory, go with what we have already */
158  break;
159  }
160  list->entries = entries;
161  list->max_entries = max_entries;
162  }
163  list->entries[list->num_entries++] = entry;
164  }
165 
166  if (file) {
167  SDL_free(file);
168  }
169 }
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:169
#define SDL_realloc
void SDL_free(void *mem)
#define SDL_strtol
#define NULL
Definition: begin_code.h:164
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:161
#define SDL_LoadFile(file, datasize)
Definition: SDL_rwops.h:214
#define SDL_strstr

◆ SDL_PrivateAddMappingForGUID()

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

Definition at line 799 of file SDL_gamecontroller.c.

References ControllerMapping_t::guid, ControllerMapping_t::mapping, ControllerMapping_t::name, ControllerMapping_t::next, NULL, ControllerMapping_t::priority, 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().

800 {
801  char *pchName;
802  char *pchMapping;
803  ControllerMapping_t *pControllerMapping;
804 
805  pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString);
806  if (!pchName) {
807  SDL_SetError("Couldn't parse name from %s", mappingString);
808  return NULL;
809  }
810 
811  pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString);
812  if (!pchMapping) {
813  SDL_free(pchName);
814  SDL_SetError("Couldn't parse %s", mappingString);
815  return NULL;
816  }
817 
818  pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
819  if (pControllerMapping) {
820  /* Only overwrite the mapping if the priority is the same or higher. */
821  if (pControllerMapping->priority <= priority) {
822  /* Update existing mapping */
823  SDL_free(pControllerMapping->name);
824  pControllerMapping->name = pchName;
825  SDL_free(pControllerMapping->mapping);
826  pControllerMapping->mapping = pchMapping;
827  pControllerMapping->priority = priority;
828  /* refresh open controllers */
829  SDL_PrivateGameControllerRefreshMapping(pControllerMapping);
830  } else {
831  SDL_free(pchName);
832  SDL_free(pchMapping);
833  }
834  *existing = SDL_TRUE;
835  } else {
836  pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
837  if (!pControllerMapping) {
838  SDL_free(pchName);
839  SDL_free(pchMapping);
840  SDL_OutOfMemory();
841  return NULL;
842  }
843  pControllerMapping->guid = jGUID;
844  pControllerMapping->name = pchName;
845  pControllerMapping->mapping = pchMapping;
846  pControllerMapping->next = NULL;
847  pControllerMapping->priority = priority;
848 
850  /* Add the mapping to the end of the list */
851  ControllerMapping_t *pCurrMapping, *pPrevMapping;
852 
853  for ( pPrevMapping = s_pSupportedControllers, pCurrMapping = pPrevMapping->next;
854  pCurrMapping;
855  pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next ) {
856  continue;
857  }
858  pPrevMapping->next = pControllerMapping;
859  } else {
860  s_pSupportedControllers = pControllerMapping;
861  }
862  *existing = SDL_FALSE;
863  }
864  return pControllerMapping;
865 }
SDL_ControllerMappingPriority priority
struct _ControllerMapping_t * next
static ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
SDL_JoystickGUID guid
static ControllerMapping_t * s_pSupportedControllers
void SDL_free(void *mem)
static char * SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
static char * SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
#define SDL_SetError
#define SDL_malloc

◆ SDL_PrivateGameControllerAddMapping()

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

Definition at line 990 of file SDL_gamecontroller.c.

References 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().

991 {
992  char *pchGUID;
993  SDL_JoystickGUID jGUID;
994  SDL_bool is_xinput_mapping = SDL_FALSE;
995  SDL_bool is_emscripten_mapping = SDL_FALSE;
996  SDL_bool existing = SDL_FALSE;
997  ControllerMapping_t *pControllerMapping;
998 
999  if (!mappingString) {
1000  return SDL_InvalidParamError("mappingString");
1001  }
1002 
1003  pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString);
1004  if (!pchGUID) {
1005  return SDL_SetError("Couldn't parse GUID from %s", mappingString);
1006  }
1007  if (!SDL_strcasecmp(pchGUID, "xinput")) {
1008  is_xinput_mapping = SDL_TRUE;
1009  }
1010  if (!SDL_strcasecmp(pchGUID, "emscripten")) {
1011  is_emscripten_mapping = SDL_TRUE;
1012  }
1013  jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
1014  SDL_free(pchGUID);
1015 
1016  pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority);
1017  if (!pControllerMapping) {
1018  return -1;
1019  }
1020 
1021  if (existing) {
1022  return 0;
1023  } else {
1024  if (is_xinput_mapping) {
1025  s_pXInputMapping = pControllerMapping;
1026  }
1027  if (is_emscripten_mapping) {
1028  s_pEmscriptenMapping = pControllerMapping;
1029  }
1030  return 1;
1031  }
1032 }
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
#define SDL_strcasecmp
static ControllerMapping_t * s_pEmscriptenMapping
void SDL_free(void *mem)
static char * SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
SDL_bool
Definition: SDL_stdinc.h:139
#define SDL_SetError
static ControllerMapping_t * s_pXInputMapping
static ControllerMapping_t * SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)
#define SDL_JoystickGetGUIDFromString

◆ SDL_PrivateGameControllerAxis()

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

Definition at line 1727 of file SDL_gamecontroller.c.

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

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

1728 {
1729  int posted;
1730 
1731  /* translate the event, if desired */
1732  posted = 0;
1733 #if !SDL_EVENTS_DISABLED
1735  SDL_Event event;
1736  event.type = SDL_CONTROLLERAXISMOTION;
1737  event.caxis.which = gamecontroller->joystick->instance_id;
1738  event.caxis.axis = axis;
1739  event.caxis.value = value;
1740  posted = SDL_PushEvent(&event) == 1;
1741  }
1742 #endif /* !SDL_EVENTS_DISABLED */
1743  return (posted);
1744 }
#define SDL_ENABLE
Definition: SDL_events.h:722
SDL_Texture * axis
#define SDL_GetEventState(type)
Definition: SDL_events.h:735
struct _cl_event * event
#define SDL_PushEvent
GLsizei const GLfloat * value
General event structure.
Definition: SDL_events.h:525

◆ SDL_PrivateGameControllerButton()

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

Definition at line 1751 of file SDL_gamecontroller.c.

References button, SDL_CONTROLLER_BUTTON_INVALID, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP, SDL_ENABLE, SDL_GetEventState, SDL_PRESSED, SDL_PushEvent, SDL_RELEASED, state, and SDL_Event::type.

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

1752 {
1753  int posted;
1754 #if !SDL_EVENTS_DISABLED
1755  SDL_Event event;
1756 
1758  return (0);
1759 
1760  switch (state) {
1761  case SDL_PRESSED:
1762  event.type = SDL_CONTROLLERBUTTONDOWN;
1763  break;
1764  case SDL_RELEASED:
1765  event.type = SDL_CONTROLLERBUTTONUP;
1766  break;
1767  default:
1768  /* Invalid state -- bail */
1769  return (0);
1770  }
1771 #endif /* !SDL_EVENTS_DISABLED */
1772 
1773  /* translate the event, if desired */
1774  posted = 0;
1775 #if !SDL_EVENTS_DISABLED
1776  if (SDL_GetEventState(event.type) == SDL_ENABLE) {
1777  event.cbutton.which = gamecontroller->joystick->instance_id;
1778  event.cbutton.button = button;
1779  event.cbutton.state = state;
1780  posted = SDL_PushEvent(&event) == 1;
1781  }
1782 #endif /* !SDL_EVENTS_DISABLED */
1783  return (posted);
1784 }
SDL_Texture * button
struct xkb_state * state
#define SDL_ENABLE
Definition: SDL_events.h:722
#define SDL_GetEventState(type)
Definition: SDL_events.h:735
struct _cl_event * event
#define SDL_PushEvent
General event structure.
Definition: SDL_events.h:525
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_RELEASED
Definition: SDL_events.h:49
Uint32 type
Definition: SDL_events.h:527

◆ SDL_PrivateGameControllerParseControllerConfigString()

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

Definition at line 614 of file SDL_gamecontroller.c.

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

Referenced by SDL_PrivateLoadButtonMapping().

615 {
616  char szGameButton[20];
617  char szJoystickButton[20];
618  SDL_bool bGameButton = SDL_TRUE;
619  int i = 0;
620  const char *pchPos = pchString;
621 
622  SDL_zero(szGameButton);
623  SDL_zero(szJoystickButton);
624 
625  while (pchPos && *pchPos) {
626  if (*pchPos == ':') {
627  i = 0;
628  bGameButton = SDL_FALSE;
629  } else if (*pchPos == ' ') {
630 
631  } else if (*pchPos == ',') {
632  i = 0;
633  bGameButton = SDL_TRUE;
634  SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
635  SDL_zero(szGameButton);
636  SDL_zero(szJoystickButton);
637 
638  } else if (bGameButton) {
639  if (i >= sizeof(szGameButton)) {
640  SDL_SetError("Button name too large: %s", szGameButton);
641  return;
642  }
643  szGameButton[i] = *pchPos;
644  i++;
645  } else {
646  if (i >= sizeof(szJoystickButton)) {
647  SDL_SetError("Joystick button name too large: %s", szJoystickButton);
648  return;
649  }
650  szJoystickButton[i] = *pchPos;
651  i++;
652  }
653  pchPos++;
654  }
655 
656  SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
657 
658 }
#define SDL_zero(x)
Definition: SDL_stdinc.h:369
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
static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontroller, const char *szGameButton, const char *szJoystickButton)
SDL_bool
Definition: SDL_stdinc.h:139
#define SDL_SetError

◆ SDL_PrivateGameControllerParseElement()

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

Definition at line 518 of file SDL_gamecontroller.c.

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().

519 {
523  SDL_bool invert_input = SDL_FALSE;
524  char half_axis_input = 0;
525  char half_axis_output = 0;
526 
527  if (*szGameButton == '+' || *szGameButton == '-') {
528  half_axis_output = *szGameButton++;
529  }
530 
531  axis = SDL_GameControllerGetAxisFromString(szGameButton);
532  button = SDL_GameControllerGetButtonFromString(szGameButton);
533  if (axis != SDL_CONTROLLER_AXIS_INVALID) {
535  bind.output.axis.axis = axis;
537  bind.output.axis.axis_min = 0;
538  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
539  } else {
540  if (half_axis_output == '+') {
541  bind.output.axis.axis_min = 0;
542  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
543  } else if (half_axis_output == '-') {
544  bind.output.axis.axis_min = 0;
545  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
546  } else {
547  bind.output.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
548  bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
549  }
550  }
551  } else if (button != SDL_CONTROLLER_BUTTON_INVALID) {
553  bind.output.button = button;
554  } else {
555  SDL_SetError("Unexpected controller element %s", szGameButton);
556  return;
557  }
558 
559  if (*szJoystickButton == '+' || *szJoystickButton == '-') {
560  half_axis_input = *szJoystickButton++;
561  }
562  if (szJoystickButton[SDL_strlen(szJoystickButton) - 1] == '~') {
563  invert_input = SDL_TRUE;
564  }
565 
566  if (szJoystickButton[0] == 'a' && SDL_isdigit(szJoystickButton[1])) {
568  bind.input.axis.axis = SDL_atoi(&szJoystickButton[1]);
569  if (half_axis_input == '+') {
570  bind.input.axis.axis_min = 0;
571  bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
572  } else if (half_axis_input == '-') {
573  bind.input.axis.axis_min = 0;
574  bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
575  } else {
576  bind.input.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
577  bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
578  }
579  if (invert_input) {
580  int tmp = bind.input.axis.axis_min;
581  bind.input.axis.axis_min = bind.input.axis.axis_max;
582  bind.input.axis.axis_max = tmp;
583  }
584  } else if (szJoystickButton[0] == 'b' && SDL_isdigit(szJoystickButton[1])) {
586  bind.input.button = SDL_atoi(&szJoystickButton[1]);
587  } else if (szJoystickButton[0] == 'h' && SDL_isdigit(szJoystickButton[1]) &&
588  szJoystickButton[2] == '.' && SDL_isdigit(szJoystickButton[3])) {
589  int hat = SDL_atoi(&szJoystickButton[1]);
590  int mask = SDL_atoi(&szJoystickButton[3]);
592  bind.input.hat.hat = hat;
593  bind.input.hat.hat_mask = mask;
594  } else {
595  SDL_SetError("Unexpected joystick element: %s", szJoystickButton);
596  return;
597  }
598 
599  ++gamecontroller->num_bindings;
600  gamecontroller->bindings = (SDL_ExtendedGameControllerBind *)SDL_realloc(gamecontroller->bindings, gamecontroller->num_bindings * sizeof(*gamecontroller->bindings));
601  if (!gamecontroller->bindings) {
602  gamecontroller->num_bindings = 0;
603  SDL_OutOfMemory();
604  return;
605  }
606  gamecontroller->bindings[gamecontroller->num_bindings - 1] = bind;
607 }
union SDL_ExtendedGameControllerBind::@24 output
SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *pchString)
SDL_Texture * button
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *pchString)
SDL_GameControllerBindType inputType
SDL_Texture * axis
SDL_GameControllerButton
#define SDL_realloc
#define SDL_JOYSTICK_AXIS_MIN
Definition: SDL_joystick.h:275
union SDL_ExtendedGameControllerBind::@23 input
#define SDL_JOYSTICK_AXIS_MAX
Definition: SDL_joystick.h:274
#define SDL_isdigit
GLenum GLint GLuint mask
SDL_GameControllerBindType outputType
#define SDL_atoi
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_bool
Definition: SDL_stdinc.h:139
#define SDL_SetError
#define SDL_strlen
SDL_GameControllerAxis

◆ SDL_PrivateGameControllerRefreshMapping()

static void SDL_PrivateGameControllerRefreshMapping ( ControllerMapping_t pControllerMapping)
static

Definition at line 777 of file SDL_gamecontroller.c.

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().

778 {
779  SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
780  while (gamecontrollerlist) {
781  if (!SDL_memcmp(&gamecontrollerlist->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
783  event.type = SDL_CONTROLLERDEVICEREMAPPED;
784  event.cdevice.which = gamecontrollerlist->joystick->instance_id;
785  SDL_PushEvent(&event);
786 
787  /* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
788  SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
789  }
790 
791  gamecontrollerlist = gamecontrollerlist->next;
792  }
793 }
SDL_JoystickGUID guid
static SDL_GameController * SDL_gamecontrollers
struct _cl_event * event
#define SDL_PushEvent
#define SDL_memcmp
General event structure.
Definition: SDL_events.h:525
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)

◆ SDL_PrivateGetControllerGUIDFromMappingString()

static char* SDL_PrivateGetControllerGUIDFromMappingString ( const char *  pMapping)
static

Definition at line 693 of file SDL_gamecontroller.c.

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

Referenced by SDL_PrivateGameControllerAddMapping().

694 {
695  const char *pFirstComma = SDL_strchr(pMapping, ',');
696  if (pFirstComma) {
697  char *pchGUID = SDL_malloc(pFirstComma - pMapping + 1);
698  if (!pchGUID) {
699  SDL_OutOfMemory();
700  return NULL;
701  }
702  SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
703  pchGUID[pFirstComma - pMapping] = '\0';
704 
705  /* Convert old style GUIDs to the new style in 2.0.5 */
706 #if __WIN32__
707  if (SDL_strlen(pchGUID) == 32 &&
708  SDL_memcmp(&pchGUID[20], "504944564944", 12) == 0) {
709  SDL_memcpy(&pchGUID[20], "000000000000", 12);
710  SDL_memcpy(&pchGUID[16], &pchGUID[4], 4);
711  SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
712  SDL_memcpy(&pchGUID[0], "03000000", 8);
713  }
714 #elif __MACOSX__
715  if (SDL_strlen(pchGUID) == 32 &&
716  SDL_memcmp(&pchGUID[4], "000000000000", 12) == 0 &&
717  SDL_memcmp(&pchGUID[20], "000000000000", 12) == 0) {
718  SDL_memcpy(&pchGUID[20], "000000000000", 12);
719  SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
720  SDL_memcpy(&pchGUID[0], "03000000", 8);
721  }
722 #endif
723  return pchGUID;
724  }
725  return NULL;
726 }
#define SDL_strchr
#define SDL_memcpy
#define SDL_memcmp
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_strlen
#define SDL_malloc

◆ SDL_PrivateGetControllerMapping()

static ControllerMapping_t* SDL_PrivateGetControllerMapping ( int  device_index)
static

Definition at line 902 of file SDL_gamecontroller.c.

References recDevice::guid, s_pXInputMapping, SDL_JoystickGetDeviceGUID, SDL_JoystickNameForIndex, and SDL_PrivateGetControllerMappingForNameAndGUID().

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

903 {
904  const char *name = SDL_JoystickNameForIndex(device_index);
905  SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
907 #if SDL_JOYSTICK_XINPUT
908  if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
909  mapping = s_pXInputMapping;
910  }
911 #endif
912  return mapping;
913 }
#define SDL_JoystickNameForIndex
static ControllerMapping_t * SDL_PrivateGetControllerMappingForNameAndGUID(const char *name, SDL_JoystickGUID guid)
GLuint const GLchar * name
#define SDL_JoystickGetDeviceGUID
static ControllerMapping_t * s_pXInputMapping
GLenum GLenum GLenum GLenum mapping

◆ SDL_PrivateGetControllerMappingForGUID()

static ControllerMapping_t* SDL_PrivateGetControllerMappingForGUID ( SDL_JoystickGUID guid)
static

Definition at line 414 of file SDL_gamecontroller.c.

References ControllerMapping_t::guid, ControllerMapping_t::next, NULL, s_pSupportedControllers, and SDL_memcmp.

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

415 {
416  ControllerMapping_t *pSupportedController = s_pSupportedControllers;
417  while (pSupportedController) {
418  if (SDL_memcmp(guid, &pSupportedController->guid, sizeof(*guid)) == 0) {
419  return pSupportedController;
420  }
421  pSupportedController = pSupportedController->next;
422  }
423  return NULL;
424 }
struct _ControllerMapping_t * next
SDL_JoystickGUID guid
static ControllerMapping_t * s_pSupportedControllers
#define SDL_memcmp
#define NULL
Definition: begin_code.h:164

◆ SDL_PrivateGetControllerMappingForNameAndGUID()

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

Definition at line 870 of file SDL_gamecontroller.c.

References s_pEmscriptenMapping, s_pXInputMapping, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT, SDL_PrivateAddMappingForGUID(), SDL_PrivateGetControllerMappingForGUID(), SDL_strstr, and void.

Referenced by SDL_IsGameControllerNameAndGUID(), and SDL_PrivateGetControllerMapping().

871 {
873 
875 #if defined(SDL_JOYSTICK_EMSCRIPTEN)
876  if (!mapping && s_pEmscriptenMapping) {
877  mapping = s_pEmscriptenMapping;
878  }
879 #else
880  (void) s_pEmscriptenMapping; /* pacify ARMCC */
881 #endif
882 #ifdef __LINUX__
883  if (!mapping && name) {
884  if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
885  /* The Linux driver xpad.c maps the wireless dpad to buttons */
886  SDL_bool existing;
887  mapping = SDL_PrivateAddMappingForGUID(guid,
888 "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,",
890  }
891  }
892 #endif /* __LINUX__ */
893 
894  if (!mapping && name) {
895  if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {
896  mapping = s_pXInputMapping;
897  }
898  }
899  return mapping;
900 }
static ControllerMapping_t * s_pEmscriptenMapping
GLuint const GLchar * name
static ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
SDL_bool
Definition: SDL_stdinc.h:139
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
static ControllerMapping_t * s_pXInputMapping
GLenum GLenum GLenum GLenum mapping
static ControllerMapping_t * SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority)
#define SDL_strstr

◆ SDL_PrivateGetControllerMappingFromMappingString()

static char* SDL_PrivateGetControllerMappingFromMappingString ( const char *  pMapping)
static

Definition at line 759 of file SDL_gamecontroller.c.

References NULL, SDL_strchr, and SDL_strdup.

Referenced by SDL_PrivateAddMappingForGUID().

760 {
761  const char *pFirstComma, *pSecondComma;
762 
763  pFirstComma = SDL_strchr(pMapping, ',');
764  if (!pFirstComma)
765  return NULL;
766 
767  pSecondComma = SDL_strchr(pFirstComma + 1, ',');
768  if (!pSecondComma)
769  return NULL;
770 
771  return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
772 }
#define SDL_strchr
#define NULL
Definition: begin_code.h:164
#define SDL_strdup

◆ SDL_PrivateGetControllerNameFromMappingString()

static char* SDL_PrivateGetControllerNameFromMappingString ( const char *  pMapping)
static

Definition at line 732 of file SDL_gamecontroller.c.

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

Referenced by SDL_PrivateAddMappingForGUID().

733 {
734  const char *pFirstComma, *pSecondComma;
735  char *pchName;
736 
737  pFirstComma = SDL_strchr(pMapping, ',');
738  if (!pFirstComma)
739  return NULL;
740 
741  pSecondComma = SDL_strchr(pFirstComma + 1, ',');
742  if (!pSecondComma)
743  return NULL;
744 
745  pchName = SDL_malloc(pSecondComma - pFirstComma);
746  if (!pchName) {
747  SDL_OutOfMemory();
748  return NULL;
749  }
750  SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
751  pchName[pSecondComma - pFirstComma - 1] = 0;
752  return pchName;
753 }
#define SDL_strchr
#define SDL_memcpy
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_malloc

◆ SDL_PrivateLoadButtonMapping()

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

Definition at line 663 of file SDL_gamecontroller.c.

References SDL_ExtendedGameControllerBind::axis, recDevice::guid, 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().

664 {
665  int i;
666 
667  gamecontroller->guid = guid;
668  gamecontroller->name = pchName;
669  gamecontroller->num_bindings = 0;
670  SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
671 
672  SDL_PrivateGameControllerParseControllerConfigString(gamecontroller, pchMapping);
673 
674  /* Set the zero point for triggers */
675  for (i = 0; i < gamecontroller->num_bindings; ++i) {
676  SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
677  if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS &&
679  (binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ||
680  binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) {
681  if (binding->input.axis.axis < gamecontroller->joystick->naxes) {
682  gamecontroller->joystick->axes[binding->input.axis.axis].value =
683  gamecontroller->joystick->axes[binding->input.axis.axis].zero = (Sint16)binding->input.axis.axis_min;
684  }
685  }
686  }
687 }
union SDL_ExtendedGameControllerBind::@24 output
SDL_GameControllerBindType inputType
union SDL_ExtendedGameControllerBind::@23 input
static void SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecontroller, const char *pchString)
SDL_GameControllerBindType outputType
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define SDL_memset
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:157

◆ SDL_ShouldIgnoreGameController()

SDL_bool SDL_ShouldIgnoreGameController ( const char *  name,
SDL_JoystickGUID  guid 
)

Definition at line 1252 of file SDL_gamecontroller.c.

References SDL_vidpid_list::entries, i, MAKE_VIDPID, NULL, SDL_vidpid_list::num_entries, recDevice::product, SDL_FALSE, SDL_GetHintBoolean, SDL_GetJoystickGUIDInfo(), SDL_strncmp, and SDL_TRUE.

1253 {
1254  int i;
1255  Uint16 vendor;
1256  Uint16 product;
1257  Uint32 vidpid;
1258 
1261  return SDL_FALSE;
1262  }
1263 
1264  SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
1265  vidpid = MAKE_VIDPID(vendor, product);
1266 
1267  if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
1268  /* 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 */
1269  SDL_bool bSteamVirtualGamepad = SDL_FALSE;
1270 #if defined(__LINUX__)
1271  bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
1272 #elif defined(__MACOSX__)
1273  bSteamVirtualGamepad = (SDL_strncmp(name, "GamePad-", 8) == 0);
1274 #elif defined(__WIN32__)
1275  /* We can't tell on Windows, but Steam will block others in input hooks */
1276  bSteamVirtualGamepad = SDL_TRUE;
1277 #endif
1278  if (bSteamVirtualGamepad) {
1279  return SDL_FALSE;
1280  }
1281  }
1282 
1284  for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) {
1285  if (vidpid == SDL_allowed_controllers.entries[i]) {
1286  return SDL_FALSE;
1287  }
1288  }
1289  return SDL_TRUE;
1290  } else {
1291  for (i = 0; i < SDL_ignored_controllers.num_entries; ++i) {
1292  if (vidpid == SDL_ignored_controllers.entries[i]) {
1293  return SDL_TRUE;
1294  }
1295  }
1296  return SDL_FALSE;
1297  }
1298 }
#define MAKE_VIDPID(VID, PID)
static SDL_vidpid_list SDL_ignored_controllers
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:169
#define SDL_strncmp
GLuint const GLchar * name
#define SDL_GetHintBoolean
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:164
SDL_bool
Definition: SDL_stdinc.h:139
static SDL_vidpid_list SDL_allowed_controllers
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
Definition: SDL_joystick.c:939
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:161

◆ UpdateEventsForDeviceRemoval()

static void UpdateEventsForDeviceRemoval ( )
static

Definition at line 191 of file SDL_gamecontroller.c.

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

Referenced by SDL_GameControllerEventWatcher().

192 {
193  int i, num_events;
194  SDL_Event *events;
195 
197  if (num_events <= 0) {
198  return;
199  }
200 
201  events = SDL_stack_alloc(SDL_Event, num_events);
202  if (!events) {
203  return;
204  }
205 
207  for (i = 0; i < num_events; ++i) {
208  --events[i].cdevice.which;
209  }
210  SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
211 
212  SDL_stack_free(events);
213 }
SDL_ControllerDeviceEvent cdevice
Definition: SDL_events.h:543
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:35
#define SDL_PeepEvents
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:338
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:164
General event structure.
Definition: SDL_events.h:525
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:339

Variable Documentation

◆ map_StringForControllerAxis

const char* map_StringForControllerAxis[]
static
Initial value:
= {
"leftx",
"lefty",
"rightx",
"righty",
"lefttrigger",
"righttrigger",
}
#define NULL
Definition: begin_code.h:164

Definition at line 426 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",
}
#define NULL
Definition: begin_code.h:164

Definition at line 469 of file SDL_gamecontroller.c.

Referenced by SDL_GameControllerGetButtonFromString(), and SDL_GameControllerGetStringForButton().

◆ s_pEmscriptenMapping

ControllerMapping_t* s_pEmscriptenMapping = NULL
static

Definition at line 96 of file SDL_gamecontroller.c.

Referenced by SDL_PrivateGetControllerMappingForNameAndGUID().

◆ s_pSupportedControllers

ControllerMapping_t* s_pSupportedControllers = NULL
static

◆ s_pXInputMapping

◆ s_zeroGUID

SDL_JoystickGUID s_zeroGUID
static

Definition at line 93 of file SDL_gamecontroller.c.

◆ SDL_allowed_controllers

SDL_vidpid_list SDL_allowed_controllers
static

Definition at line 122 of file SDL_gamecontroller.c.

◆ SDL_gamecontrollers

◆ SDL_ignored_controllers

SDL_vidpid_list SDL_ignored_controllers
static

Definition at line 123 of file SDL_gamecontroller.c.