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

Go to the source code of this file.

Data Structures

struct  SDL_ExtendedGameControllerBind
struct  ControllerMapping_t
struct  SDL_GameController
struct  SDL_vidpid_list

Macros

#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS   250
#define SDL_CONTROLLER_PLATFORM_FIELD   "platform:"

Enumerations

enum  SDL_ControllerMappingPriority {
  SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT,
  SDL_CONTROLLER_MAPPING_PRIORITY_API,
  SDL_CONTROLLER_MAPPING_PRIORITY_USER
}

Functions

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

Variables

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

Macro Definition Documentation

#define SDL_CONTROLLER_PLATFORM_FIELD   "platform:"

Definition at line 45 of file SDL_gamecontroller.c.

Referenced by SDL_GameControllerAddMappingsFromRW().

#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS   250

Definition at line 43 of file SDL_gamecontroller.c.

Referenced by SDL_PrivateGameControllerButton().

Enumeration Type Documentation

Enumerator:
SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT 
SDL_CONTROLLER_MAPPING_PRIORITY_API 
SDL_CONTROLLER_MAPPING_PRIORITY_USER 

Definition at line 86 of file SDL_gamecontroller.c.

Function Documentation

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

Definition at line 247 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().

{
int i;
SDL_ExtendedGameControllerBind *last_match = gamecontroller->last_match_axis[axis];
for (i = 0; i < gamecontroller->num_bindings; ++i) {
SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
axis == binding->input.axis.axis) {
if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
if (value >= binding->input.axis.axis_min &&
value <= binding->input.axis.axis_max) {
match = binding;
break;
}
} else {
if (value >= binding->input.axis.axis_max &&
value <= binding->input.axis.axis_min) {
match = binding;
break;
}
}
}
}
if (last_match && (!match || !HasSameOutput(last_match, match))) {
/* Clear the last input that this axis generated */
ResetOutput(gamecontroller, last_match);
}
if (match) {
if (match->input.axis.axis_min != match->output.axis.axis_min || match->input.axis.axis_max != match->output.axis.axis_max) {
float normalized_value = (float)(value - match->input.axis.axis_min) / (match->input.axis.axis_max - match->input.axis.axis_min);
value = match->output.axis.axis_min + (int)(normalized_value * (match->output.axis.axis_max - match->output.axis.axis_min));
}
SDL_PrivateGameControllerAxis(gamecontroller, match->output.axis.axis, (Sint16)value);
} else {
int threshold = match->input.axis.axis_min + (match->input.axis.axis_max - match->input.axis.axis_min) / 2;
if (match->input.axis.axis_max < match->input.axis.axis_min) {
state = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
} else {
state = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
}
SDL_PrivateGameControllerButton(gamecontroller, match->output.button, state);
}
}
gamecontroller->last_match_axis[axis] = match;
}
static void HandleJoystickButton ( SDL_GameController *  gamecontroller,
int  button,
Uint8  state 
)
static
static void HandleJoystickHat ( SDL_GameController *  gamecontroller,
int  hat,
Uint8  value 
)
static

Definition at line 318 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().

{
int i;
Uint8 last_mask = gamecontroller->last_hat_mask[hat];
Uint8 changed_mask = (last_mask ^ value);
for (i = 0; i < gamecontroller->num_bindings; ++i) {
SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT && hat == binding->input.hat.hat) {
if ((changed_mask & binding->input.hat.hat_mask) != 0) {
if (value & binding->input.hat.hat_mask) {
SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)binding->output.axis.axis_max);
} else {
}
} else {
ResetOutput(gamecontroller, binding);
}
}
}
}
gamecontroller->last_hat_mask[hat] = value;
}
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 1186 of file SDL_gamecontroller.c.

References SDL_CONTROLLER_MAPPING_PRIORITY_API, and SDL_PrivateGameControllerAddMapping().

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 1064 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.

{
const char *platform = SDL_GetPlatform();
int controllers = 0;
char *buf, *line, *line_end, *tmp, *comma, line_platform[64];
size_t db_size, platform_len;
if (rw == NULL) {
return SDL_SetError("Invalid RWops");
}
db_size = (size_t)SDL_RWsize(rw);
buf = (char *)SDL_malloc(db_size + 1);
if (buf == NULL) {
if (freerw) {
}
return SDL_SetError("Could not allocate space to read DB into memory");
}
if (SDL_RWread(rw, buf, db_size, 1) != 1) {
if (freerw) {
}
SDL_free(buf);
return SDL_SetError("Could not read DB");
}
if (freerw) {
}
buf[db_size] = '\0';
line = buf;
while (line < buf + db_size) {
line_end = SDL_strchr(line, '\n');
if (line_end != NULL) {
*line_end = '\0';
} else {
line_end = buf + db_size;
}
/* Extract and verify the platform */
if (tmp != NULL) {
comma = SDL_strchr(tmp, ',');
if (comma != NULL) {
platform_len = comma - tmp + 1;
if (platform_len + 1 < SDL_arraysize(line_platform)) {
SDL_strlcpy(line_platform, tmp, platform_len);
if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 &&
controllers++;
}
}
}
}
line = line_end + 1;
}
SDL_free(buf);
return controllers;
}
void SDL_GameControllerClose ( SDL_GameController *  gamecontroller)

Close a controller previously opened with SDL_GameControllerOpen().

Definition at line 1860 of file SDL_gamecontroller.c.

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

{
SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
if (!gamecontroller)
return;
/* First decrement ref count */
if (--gamecontroller->ref_count > 0) {
return;
}
SDL_JoystickClose(gamecontroller->joystick);
gamecontrollerlist = SDL_gamecontrollers;
gamecontrollerlistprev = NULL;
while (gamecontrollerlist) {
if (gamecontroller == gamecontrollerlist) {
if (gamecontrollerlistprev) {
/* unlink this entry */
gamecontrollerlistprev->next = gamecontrollerlist->next;
} else {
SDL_gamecontrollers = gamecontroller->next;
}
break;
}
gamecontrollerlistprev = gamecontrollerlist;
gamecontrollerlist = gamecontrollerlist->next;
}
SDL_free(gamecontroller->bindings);
SDL_free(gamecontroller->last_match_axis);
SDL_free(gamecontroller->last_hat_mask);
SDL_free(gamecontroller);
}
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 2031 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.

{
#if SDL_EVENTS_DISABLED
return SDL_IGNORE;
#else
const Uint32 event_list[] = {
};
unsigned int i;
switch (state) {
case SDL_QUERY:
for (i = 0; i < SDL_arraysize(event_list); ++i) {
state = SDL_EventState(event_list[i], SDL_QUERY);
if (state == SDL_ENABLE) {
break;
}
}
break;
default:
for (i = 0; i < SDL_arraysize(event_list); ++i) {
SDL_EventState(event_list[i], state);
}
break;
}
return (state);
#endif /* SDL_EVENTS_DISABLED */
}
static int SDL_GameControllerEventWatcher ( void userdata,
SDL_Event event 
)
static

Definition at line 346 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().

{
switch(event->type) {
{
SDL_GameController *controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jaxis.which) {
HandleJoystickAxis(controllerlist, event->jaxis.axis, event->jaxis.value);
break;
}
controllerlist = controllerlist->next;
}
}
break;
{
SDL_GameController *controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jbutton.which) {
HandleJoystickButton(controllerlist, event->jbutton.button, event->jbutton.state);
break;
}
controllerlist = controllerlist->next;
}
}
break;
{
SDL_GameController *controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jhat.which) {
HandleJoystickHat(controllerlist, event->jhat.hat, event->jhat.value);
break;
}
controllerlist = controllerlist->next;
}
}
break;
{
SDL_Event deviceevent;
deviceevent.cdevice.which = event->jdevice.which;
SDL_PushEvent(&deviceevent);
}
}
break;
{
SDL_GameController *controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jdevice.which) {
SDL_Event deviceevent;
deviceevent.cdevice.which = event->jdevice.which;
SDL_PushEvent(&deviceevent);
break;
}
controllerlist = controllerlist->next;
}
}
break;
default:
break;
}
return 1;
}
SDL_GameController* SDL_GameControllerFromInstanceID ( SDL_JoystickID  joyid)

Return the SDL_GameController associated with an instance id.

Definition at line 1772 of file SDL_gamecontroller.c.

References NULL, SDL_gamecontrollers, SDL_LockJoysticks, and SDL_UnlockJoysticks.

{
SDL_GameController *gamecontroller;
gamecontroller = SDL_gamecontrollers;
while (gamecontroller) {
if (gamecontroller->joystick->instance_id == joyid) {
return gamecontroller;
}
gamecontroller = gamecontroller->next;
}
return NULL;
}
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 1748 of file SDL_gamecontroller.c.

References SDL_FALSE, and SDL_JoystickGetAttached.

{
if (!gamecontroller)
return SDL_FALSE;
return SDL_JoystickGetAttached(gamecontroller->joystick);
}
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 1612 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.

{
int i;
if (!gamecontroller)
return 0;
for (i = 0; i < gamecontroller->num_bindings; ++i) {
SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
int value = 0;
SDL_bool valid_input_range;
SDL_bool valid_output_range;
value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
} else {
valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
}
if (valid_input_range) {
if (binding->input.axis.axis_min != binding->output.axis.axis_min || binding->input.axis.axis_max != binding->output.axis.axis_max) {
float normalized_value = (float)(value - binding->input.axis.axis_min) / (binding->input.axis.axis_max - binding->input.axis.axis_min);
value = binding->output.axis.axis_min + (int)(normalized_value * (binding->output.axis.axis_max - binding->output.axis.axis_min));
}
}
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
value = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
if (value == SDL_PRESSED) {
value = binding->output.axis.axis_max;
}
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
if (hat_mask & binding->input.hat.hat_mask) {
value = binding->output.axis.axis_max;
}
}
if (binding->output.axis.axis_min < binding->output.axis.axis_max) {
valid_output_range = (value >= binding->output.axis.axis_min && value <= binding->output.axis.axis_max);
} else {
valid_output_range = (value >= binding->output.axis.axis_max && value <= binding->output.axis.axis_min);
}
/* If the value is zero, there might be another binding that makes it non-zero */
if (value != 0 && valid_output_range) {
return (Sint16)value;
}
}
}
return 0;
}
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString ( const char *  pchString)

turn this string into a axis mapping

Definition at line 461 of file SDL_gamecontroller.c.

References map_StringForControllerAxis, SDL_CONTROLLER_AXIS_INVALID, and SDL_strcasecmp.

{
int entry;
if (pchString && (*pchString == '+' || *pchString == '-')) {
++pchString;
}
if (!pchString || !pchString[0]) {
}
for (entry = 0; map_StringForControllerAxis[entry]; ++entry) {
return (SDL_GameControllerAxis) entry;
}
}
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis ( SDL_GameController *  gamecontroller,
SDL_GameControllerAxis  axis 
)

Get the SDL joystick layer binding for this controller button mapping

Definition at line 1793 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.

{
int i;
SDL_zero(bind);
if (!gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID)
return bind;
for (i = 0; i < gamecontroller->num_bindings; ++i) {
SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
bind.bindType = binding->inputType;
/* FIXME: There might be multiple axes bound now that we have axis ranges... */
bind.value.axis = binding->input.axis.axis;
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
bind.value.button = binding->input.button;
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
bind.value.hat.hat = binding->input.hat.hat;
bind.value.hat.hat_mask = binding->input.hat.hat_mask;
}
break;
}
}
return bind;
}
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton ( SDL_GameController *  gamecontroller,
SDL_GameControllerButton  button 
)

Get the SDL joystick layer binding for this controller button mapping

Definition at line 1825 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.

{
int i;
SDL_zero(bind);
if (!gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID)
return bind;
for (i = 0; i < gamecontroller->num_bindings; ++i) {
SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
bind.bindType = binding->inputType;
bind.value.axis = binding->input.axis.axis;
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
bind.value.button = binding->input.button;
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
bind.value.hat.hat = binding->input.hat.hat;
bind.value.hat.hat_mask = binding->input.hat.hat_mask;
}
break;
}
}
return bind;
}
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 1669 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.

{
int i;
if (!gamecontroller)
return 0;
for (i = 0; i < gamecontroller->num_bindings; ++i) {
SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
SDL_bool valid_input_range;
int value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis);
int threshold = binding->input.axis.axis_min + (binding->input.axis.axis_max - binding->input.axis.axis_min) / 2;
if (binding->input.axis.axis_min < binding->input.axis.axis_max) {
valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max);
if (valid_input_range) {
return (value >= threshold) ? SDL_PRESSED : SDL_RELEASED;
}
} else {
valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min);
if (valid_input_range) {
return (value <= threshold) ? SDL_PRESSED : SDL_RELEASED;
}
}
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
return SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button);
} else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat);
return (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED;
}
}
}
return SDL_RELEASED;
}
SDL_GameControllerButton SDL_GameControllerGetButtonFromString ( const char *  pchString)

turn this string into a button mapping

Definition at line 513 of file SDL_gamecontroller.c.

References map_StringForControllerButton, SDL_CONTROLLER_BUTTON_INVALID, and SDL_strcasecmp.

{
int entry;
if (!pchString || !pchString[0])
for (entry = 0; map_StringForControllerButton[entry]; ++entry) {
if (SDL_strcasecmp(pchString, map_StringForControllerButton[entry]) == 0)
return (SDL_GameControllerButton) entry;
}
}
SDL_Joystick* SDL_GameControllerGetJoystick ( SDL_GameController *  gamecontroller)

Get the underlying joystick object used by a controller

Definition at line 1759 of file SDL_gamecontroller.c.

References NULL.

{
if (!gamecontroller)
return NULL;
return gamecontroller->joystick;
}
int SDL_GameControllerGetPlayerIndex ( SDL_GameController *  gamecontroller)

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

For XInput controllers this returns the XInput user index.

Definition at line 1720 of file SDL_gamecontroller.c.

References SDL_GameControllerGetJoystick, and SDL_JoystickGetPlayerIndex.

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

References SDL_GameControllerGetJoystick, and SDL_JoystickGetProduct.

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

References SDL_GameControllerGetJoystick, and SDL_JoystickGetProductVersion.

const char* SDL_GameControllerGetStringForAxis ( SDL_GameControllerAxis  axis)

turn this axis enum into a string mapping

Definition at line 483 of file SDL_gamecontroller.c.

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

const char* SDL_GameControllerGetStringForButton ( SDL_GameControllerButton  button)

turn this button enum into a string mapping

Definition at line 529 of file SDL_gamecontroller.c.

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

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

References SDL_GameControllerGetJoystick, and SDL_JoystickGetVendor.

void SDL_GameControllerHandleDelayedGuideButton ( SDL_Joystick *  joystick)

Definition at line 2063 of file SDL_gamecontroller.c.

References SDL_CONTROLLER_BUTTON_GUIDE, SDL_gamecontrollers, SDL_PrivateGameControllerButton(), and SDL_RELEASED.

Referenced by SDL_JoystickUpdate().

{
SDL_GameController *controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick == joystick) {
break;
}
controllerlist = controllerlist->next;
}
}
static void SDL_GameControllerIgnoreDevicesChanged ( void userdata,
const char *  name,
const char *  oldValue,
const char *  hint 
)
static
static void SDL_GameControllerIgnoreDevicesExceptChanged ( void userdata,
const char *  name,
const char *  oldValue,
const char *  hint 
)
static
int SDL_GameControllerInit ( void  )

Definition at line 1358 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().

{
int i;
/* watch for joy events and fire controller ones if needed */
/* Send added events for controllers currently attached */
for (i = 0; i < SDL_NumJoysticks(); ++i) {
SDL_Event deviceevent;
deviceevent.cdevice.which = i;
SDL_PushEvent(&deviceevent);
}
}
return (0);
}
static void SDL_GameControllerLoadHints ( )
static

Definition at line 1280 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().

{
if (hint && hint[0]) {
size_t nchHints = SDL_strlen(hint);
char *pUserMappings = SDL_malloc(nchHints + 1);
char *pTempMappings = pUserMappings;
SDL_memcpy(pUserMappings, hint, nchHints);
pUserMappings[nchHints] = '\0';
while (pUserMappings) {
char *pchNewLine = NULL;
pchNewLine = SDL_strchr(pUserMappings, '\n');
if (pchNewLine)
*pchNewLine = '\0';
if (pchNewLine) {
pUserMappings = pchNewLine + 1;
} else {
pUserMappings = NULL;
}
}
SDL_free(pTempMappings);
}
}
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 1270 of file SDL_gamecontroller.c.

References NULL, and SDL_GameControllerMappingForGUID.

{
if (!gamecontroller) {
return NULL;
}
return SDL_GameControllerMappingForGUID(gamecontroller->joystick->guid);
}
char* SDL_GameControllerMappingForDeviceIndex ( int  joystick_index)

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

Definition at line 1403 of file SDL_gamecontroller.c.

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

{
char *pMappingString = NULL;
mapping = SDL_PrivateGetControllerMapping(joystick_index);
if (mapping) {
char pchGUID[33];
size_t needed;
guid = SDL_JoystickGetDeviceGUID(joystick_index);
SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
/* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
pMappingString = SDL_malloc(needed);
if (!pMappingString) {
return NULL;
}
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
}
return pMappingString;
}
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 1246 of file SDL_gamecontroller.c.

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

{
char *pMappingString = NULL;
if (mapping) {
char pchGUID[33];
size_t needed;
SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID));
/* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
pMappingString = SDL_malloc(needed);
if (!pMappingString) {
return NULL;
}
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
}
return pMappingString;
}
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 1213 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.

{
for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
continue;
}
if (mapping_index == 0) {
char *pMappingString;
char pchGUID[33];
size_t needed;
SDL_JoystickGetGUIDString(mapping->guid, pchGUID, sizeof(pchGUID));
/* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */
needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1;
pMappingString = SDL_malloc(needed);
if (!pMappingString) {
return NULL;
}
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
return pMappingString;
}
--mapping_index;
}
return NULL;
}
const char* SDL_GameControllerName ( SDL_GameController *  gamecontroller)

Return the name for this currently opened controller

Definition at line 1707 of file SDL_gamecontroller.c.

References NULL, SDL_GameControllerGetJoystick, SDL_JoystickName, and SDL_strcmp.

{
if (!gamecontroller)
return NULL;
if (SDL_strcmp(gamecontroller->name, "*") == 0) {
} else {
return gamecontroller->name;
}
}
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 1383 of file SDL_gamecontroller.c.

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

{
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (pSupportedController) {
if (SDL_strcmp(pSupportedController->name, "*") == 0) {
return SDL_JoystickNameForIndex(device_index);
} else {
return pSupportedController->name;
}
}
return NULL;
}
int SDL_GameControllerNumMappings ( void  )

Get the number of mappings installed

Returns
the number of mappings

Definition at line 1195 of file SDL_gamecontroller.c.

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

{
int num_mappings = 0;
for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) {
if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) {
continue;
}
++num_mappings;
}
return num_mappings;
}
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 1518 of file SDL_gamecontroller.c.

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

{
SDL_JoystickID instance_id;
SDL_GameController *gamecontroller;
SDL_GameController *gamecontrollerlist;
ControllerMapping_t *pSupportedController = NULL;
gamecontrollerlist = SDL_gamecontrollers;
/* If the controller is already open, return it */
instance_id = SDL_JoystickGetDeviceInstanceID(device_index);
while (gamecontrollerlist) {
if (instance_id == gamecontrollerlist->joystick->instance_id) {
gamecontroller = gamecontrollerlist;
++gamecontroller->ref_count;
return (gamecontroller);
}
gamecontrollerlist = gamecontrollerlist->next;
}
/* Find a controller mapping */
pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (!pSupportedController) {
SDL_SetError("Couldn't find mapping for device (%d)", device_index);
return NULL;
}
/* Create and initialize the controller */
gamecontroller = (SDL_GameController *) SDL_calloc(1, sizeof(*gamecontroller));
if (gamecontroller == NULL) {
return NULL;
}
gamecontroller->joystick = SDL_JoystickOpen(device_index);
if (!gamecontroller->joystick) {
SDL_free(gamecontroller);
return NULL;
}
if (gamecontroller->joystick->naxes) {
gamecontroller->last_match_axis = (SDL_ExtendedGameControllerBind **)SDL_calloc(gamecontroller->joystick->naxes, sizeof(*gamecontroller->last_match_axis));
if (!gamecontroller->last_match_axis) {
SDL_JoystickClose(gamecontroller->joystick);
SDL_free(gamecontroller);
return NULL;
}
}
if (gamecontroller->joystick->nhats) {
gamecontroller->last_hat_mask = (Uint8 *)SDL_calloc(gamecontroller->joystick->nhats, sizeof(*gamecontroller->last_hat_mask));
if (!gamecontroller->last_hat_mask) {
SDL_JoystickClose(gamecontroller->joystick);
SDL_free(gamecontroller->last_match_axis);
SDL_free(gamecontroller);
return NULL;
}
}
SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->name, pSupportedController->mapping);
/* Add the controller to list */
++gamecontroller->ref_count;
/* Link the controller in the list */
gamecontroller->next = SDL_gamecontrollers;
SDL_gamecontrollers = gamecontroller;
return (gamecontroller);
}
int SDL_GameControllerRumble ( SDL_GameController *  gamecontroller,
Uint16  low_frequency_rumble,
Uint16  high_frequency_rumble,
Uint32  duration_ms 
)

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

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

Definition at line 1854 of file SDL_gamecontroller.c.

References SDL_GameControllerGetJoystick, and SDL_JoystickRumble.

{
return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms);
}
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 1602 of file SDL_gamecontroller.c.

References SDL_JoystickUpdate.

{
/* Just for API completeness; the joystick API does all the work. */
}
static SDL_bool SDL_GetControllerMappingFilePath ( char *  path,
size_t  size 
)
static

Definition at line 1313 of file SDL_gamecontroller.c.

References SDL_AndroidGetInternalStoragePath, SDL_FALSE, SDL_snprintf, and SDL_strlcpy.

Referenced by SDL_GameControllerInitMappings().

{
#ifdef CONTROLLER_MAPPING_FILE
#define STRING(X) SDL_STRINGIFY_ARG(X)
return SDL_strlcpy(path, STRING(CONTROLLER_MAPPING_FILE), size) < size;
#elif defined(__ANDROID__)
return SDL_snprintf(path, size, "%s/controller_map.txt", SDL_AndroidGetInternalStoragePath()) < size;
#else
return SDL_FALSE;
#endif
}
SDL_bool SDL_IsGameController ( int  joystick_index)

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

Definition at line 1448 of file SDL_gamecontroller.c.

References SDL_FALSE, SDL_PrivateGetControllerMapping(), and SDL_TRUE.

{
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (pSupportedController) {
return SDL_TRUE;
}
return SDL_FALSE;
}
SDL_bool SDL_IsGameControllerNameAndGUID ( const char *  name,
SDL_JoystickGUID  guid 
)

Definition at line 1435 of file SDL_gamecontroller.c.

References SDL_FALSE, SDL_PrivateGetControllerMappingForNameAndGUID(), and SDL_TRUE.

Referenced by SDL_ShouldIgnoreJoystick().

{
if (pSupportedController) {
return SDL_TRUE;
}
return SDL_FALSE;
}
static void SDL_LoadVIDPIDListFromHint ( const char *  hint,
SDL_vidpid_list list 
)
static

Definition at line 136 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, and SDL_strtol.

Referenced by SDL_GameControllerIgnoreDevicesChanged(), and SDL_GameControllerIgnoreDevicesExceptChanged().

{
Uint32 entry;
char *spot;
char *file = NULL;
list->num_entries = 0;
if (hint && *hint == '@') {
spot = file = (char *)SDL_LoadFile(hint+1, NULL);
} else {
spot = (char *)hint;
}
if (!spot) {
return;
}
while ((spot = SDL_strstr(spot, "0x")) != NULL) {
entry = (Uint16)SDL_strtol(spot, &spot, 0);
entry <<= 16;
spot = SDL_strstr(spot, "0x");
if (!spot) {
break;
}
entry |= (Uint16)SDL_strtol(spot, &spot, 0);
if (list->num_entries == list->max_entries) {
int max_entries = list->max_entries + 16;
Uint32 *entries = (Uint32 *)SDL_realloc(list->entries, max_entries*sizeof(*list->entries));
if (entries == NULL) {
/* Out of memory, go with what we have already */
break;
}
list->entries = entries;
list->max_entries = max_entries;
}
list->entries[list->num_entries++] = entry;
}
if (file) {
SDL_free(file);
}
}
static ControllerMapping_t* SDL_PrivateAddMappingForGUID ( SDL_JoystickGUID  jGUID,
const char *  mappingString,
SDL_bool existing,
SDL_ControllerMappingPriority  priority 
)
static

Definition at line 822 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().

{
char *pchName;
char *pchMapping;
ControllerMapping_t *pControllerMapping;
if (!pchName) {
SDL_SetError("Couldn't parse name from %s", mappingString);
return NULL;
}
if (!pchMapping) {
SDL_free(pchName);
SDL_SetError("Couldn't parse %s", mappingString);
return NULL;
}
pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID, SDL_TRUE);
if (pControllerMapping) {
/* Only overwrite the mapping if the priority is the same or higher. */
if (pControllerMapping->priority <= priority) {
/* Update existing mapping */
SDL_free(pControllerMapping->name);
pControllerMapping->name = pchName;
SDL_free(pControllerMapping->mapping);
pControllerMapping->mapping = pchMapping;
pControllerMapping->priority = priority;
/* refresh open controllers */
} else {
SDL_free(pchName);
SDL_free(pchMapping);
}
*existing = SDL_TRUE;
} else {
pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
if (!pControllerMapping) {
SDL_free(pchName);
SDL_free(pchMapping);
return NULL;
}
pControllerMapping->guid = jGUID;
pControllerMapping->name = pchName;
pControllerMapping->mapping = pchMapping;
pControllerMapping->next = NULL;
pControllerMapping->priority = priority;
/* Add the mapping to the end of the list */
ControllerMapping_t *pCurrMapping, *pPrevMapping;
for ( pPrevMapping = s_pSupportedControllers, pCurrMapping = pPrevMapping->next;
pCurrMapping;
pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next ) {
continue;
}
pPrevMapping->next = pControllerMapping;
} else {
s_pSupportedControllers = pControllerMapping;
}
*existing = SDL_FALSE;
}
return pControllerMapping;
}
static int SDL_PrivateGameControllerAddMapping ( const char *  mappingString,
SDL_ControllerMappingPriority  priority 
)
static

Definition at line 1135 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().

{
char *pchGUID;
SDL_bool is_default_mapping = SDL_FALSE;
SDL_bool is_hidapi_mapping = SDL_FALSE;
SDL_bool is_xinput_mapping = SDL_FALSE;
SDL_bool existing = SDL_FALSE;
ControllerMapping_t *pControllerMapping;
if (!mappingString) {
return SDL_InvalidParamError("mappingString");
}
if (!pchGUID) {
return SDL_SetError("Couldn't parse GUID from %s", mappingString);
}
if (!SDL_strcasecmp(pchGUID, "default")) {
is_default_mapping = SDL_TRUE;
} else if (!SDL_strcasecmp(pchGUID, "hidapi")) {
is_hidapi_mapping = SDL_TRUE;
} else if (!SDL_strcasecmp(pchGUID, "xinput")) {
is_xinput_mapping = SDL_TRUE;
}
SDL_free(pchGUID);
pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority);
if (!pControllerMapping) {
return -1;
}
if (existing) {
return 0;
} else {
if (is_default_mapping) {
s_pDefaultMapping = pControllerMapping;
} else if (is_hidapi_mapping) {
s_pHIDAPIMapping = pControllerMapping;
} else if (is_xinput_mapping) {
s_pXInputMapping = pControllerMapping;
}
return 1;
}
}
static int SDL_PrivateGameControllerAxis ( SDL_GameController *  gamecontroller,
SDL_GameControllerAxis  axis,
Sint16  value 
)
static

Definition at line 1950 of file SDL_gamecontroller.c.

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

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

{
int posted;
/* translate the event, if desired */
posted = 0;
#if !SDL_EVENTS_DISABLED
event.caxis.which = gamecontroller->joystick->instance_id;
event.caxis.axis = axis;
event.caxis.value = value;
posted = SDL_PushEvent(&event) == 1;
}
#endif /* !SDL_EVENTS_DISABLED */
return (posted);
}
static int SDL_PrivateGameControllerButton ( SDL_GameController *  gamecontroller,
SDL_GameControllerButton  button,
Uint8  state 
)
static

Definition at line 1974 of file SDL_gamecontroller.c.

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

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

{
int posted;
#if !SDL_EVENTS_DISABLED
return (0);
switch (state) {
break;
event.type = SDL_CONTROLLERBUTTONUP;
break;
default:
/* Invalid state -- bail */
return (0);
}
#endif /* !SDL_EVENTS_DISABLED */
if (state == SDL_PRESSED) {
gamecontroller->guide_button_down = now;
if (gamecontroller->joystick->delayed_guide_button) {
/* Skip duplicate press */
return (0);
}
} else {
if (!SDL_TICKS_PASSED(now, gamecontroller->guide_button_down+SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS) && !gamecontroller->joystick->force_recentering) {
gamecontroller->joystick->delayed_guide_button = SDL_TRUE;
return (0);
}
gamecontroller->joystick->delayed_guide_button = SDL_FALSE;
}
}
/* translate the event, if desired */
posted = 0;
#if !SDL_EVENTS_DISABLED
event.cbutton.which = gamecontroller->joystick->instance_id;
event.cbutton.button = button;
event.cbutton.state = state;
posted = SDL_PushEvent(&event) == 1;
}
#endif /* !SDL_EVENTS_DISABLED */
return (posted);
}
static void SDL_PrivateGameControllerParseControllerConfigString ( SDL_GameController *  gamecontroller,
const char *  pchString 
)
static

Definition at line 636 of file SDL_gamecontroller.c.

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

Referenced by SDL_PrivateLoadButtonMapping().

{
char szGameButton[20];
char szJoystickButton[20];
SDL_bool bGameButton = SDL_TRUE;
int i = 0;
const char *pchPos = pchString;
SDL_zero(szGameButton);
SDL_zero(szJoystickButton);
while (pchPos && *pchPos) {
if (*pchPos == ':') {
i = 0;
bGameButton = SDL_FALSE;
} else if (*pchPos == ' ') {
} else if (*pchPos == ',') {
i = 0;
bGameButton = SDL_TRUE;
SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
SDL_zero(szGameButton);
SDL_zero(szJoystickButton);
} else if (bGameButton) {
if (i >= sizeof(szGameButton)) {
SDL_SetError("Button name too large: %s", szGameButton);
return;
}
szGameButton[i] = *pchPos;
i++;
} else {
if (i >= sizeof(szJoystickButton)) {
SDL_SetError("Joystick button name too large: %s", szJoystickButton);
return;
}
szJoystickButton[i] = *pchPos;
i++;
}
pchPos++;
}
SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton);
}
static void SDL_PrivateGameControllerParseElement ( SDL_GameController *  gamecontroller,
const char *  szGameButton,
const char *  szJoystickButton 
)
static

Definition at line 540 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().

{
SDL_bool invert_input = SDL_FALSE;
char half_axis_input = 0;
char half_axis_output = 0;
if (*szGameButton == '+' || *szGameButton == '-') {
half_axis_output = *szGameButton++;
}
button = SDL_GameControllerGetButtonFromString(szGameButton);
bind.output.axis.axis = axis;
bind.output.axis.axis_min = 0;
} else {
if (half_axis_output == '+') {
bind.output.axis.axis_min = 0;
} else if (half_axis_output == '-') {
bind.output.axis.axis_min = 0;
} else {
}
}
} else if (button != SDL_CONTROLLER_BUTTON_INVALID) {
} else {
SDL_SetError("Unexpected controller element %s", szGameButton);
return;
}
if (*szJoystickButton == '+' || *szJoystickButton == '-') {
half_axis_input = *szJoystickButton++;
}
if (szJoystickButton[SDL_strlen(szJoystickButton) - 1] == '~') {
invert_input = SDL_TRUE;
}
if (szJoystickButton[0] == 'a' && SDL_isdigit(szJoystickButton[1])) {
bind.input.axis.axis = SDL_atoi(&szJoystickButton[1]);
if (half_axis_input == '+') {
bind.input.axis.axis_min = 0;
bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
} else if (half_axis_input == '-') {
bind.input.axis.axis_min = 0;
bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MIN;
} else {
bind.input.axis.axis_min = SDL_JOYSTICK_AXIS_MIN;
bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX;
}
if (invert_input) {
int tmp = bind.input.axis.axis_min;
bind.input.axis.axis_min = bind.input.axis.axis_max;
bind.input.axis.axis_max = tmp;
}
} else if (szJoystickButton[0] == 'b' && SDL_isdigit(szJoystickButton[1])) {
bind.input.button = SDL_atoi(&szJoystickButton[1]);
} else if (szJoystickButton[0] == 'h' && SDL_isdigit(szJoystickButton[1]) &&
szJoystickButton[2] == '.' && SDL_isdigit(szJoystickButton[3])) {
int hat = SDL_atoi(&szJoystickButton[1]);
int mask = SDL_atoi(&szJoystickButton[3]);
bind.input.hat.hat = hat;
bind.input.hat.hat_mask = mask;
} else {
SDL_SetError("Unexpected joystick element: %s", szJoystickButton);
return;
}
++gamecontroller->num_bindings;
gamecontroller->bindings = (SDL_ExtendedGameControllerBind *)SDL_realloc(gamecontroller->bindings, gamecontroller->num_bindings * sizeof(*gamecontroller->bindings));
if (!gamecontroller->bindings) {
gamecontroller->num_bindings = 0;
return;
}
gamecontroller->bindings[gamecontroller->num_bindings - 1] = bind;
}
static void SDL_PrivateGameControllerRefreshMapping ( ControllerMapping_t pControllerMapping)
static

Definition at line 798 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().

{
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
while (gamecontrollerlist) {
if (!SDL_memcmp(&gamecontrollerlist->joystick->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
/* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->name, pControllerMapping->mapping);
{
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
SDL_PushEvent(&event);
}
}
gamecontrollerlist = gamecontrollerlist->next;
}
}
static char* SDL_PrivateGetControllerGUIDFromMappingString ( const char *  pMapping)
static

Definition at line 714 of file SDL_gamecontroller.c.

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

Referenced by SDL_PrivateGameControllerAddMapping().

{
const char *pFirstComma = SDL_strchr(pMapping, ',');
if (pFirstComma) {
char *pchGUID = SDL_malloc(pFirstComma - pMapping + 1);
if (!pchGUID) {
return NULL;
}
SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
pchGUID[pFirstComma - pMapping] = '\0';
/* Convert old style GUIDs to the new style in 2.0.5 */
#if __WIN32__
if (SDL_strlen(pchGUID) == 32 &&
SDL_memcmp(&pchGUID[20], "504944564944", 12) == 0) {
SDL_memcpy(&pchGUID[20], "000000000000", 12);
SDL_memcpy(&pchGUID[16], &pchGUID[4], 4);
SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
SDL_memcpy(&pchGUID[0], "03000000", 8);
}
#elif __MACOSX__
if (SDL_strlen(pchGUID) == 32 &&
SDL_memcmp(&pchGUID[4], "000000000000", 12) == 0 &&
SDL_memcmp(&pchGUID[20], "000000000000", 12) == 0) {
SDL_memcpy(&pchGUID[20], "000000000000", 12);
SDL_memcpy(&pchGUID[8], &pchGUID[0], 4);
SDL_memcpy(&pchGUID[0], "03000000", 8);
}
#endif
return pchGUID;
}
return NULL;
}
static ControllerMapping_t* SDL_PrivateGetControllerMappingForGUID ( SDL_JoystickGUID guid,
SDL_bool  exact_match 
)
static

Definition at line 424 of file SDL_gamecontroller.c.

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

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

{
while (pSupportedController) {
if (SDL_memcmp(guid, &pSupportedController->guid, sizeof(*guid)) == 0) {
return pSupportedController;
}
pSupportedController = pSupportedController->next;
}
if (!exact_match) {
if (SDL_IsJoystickHIDAPI(*guid)) {
/* This is a HIDAPI device */
}
#if SDL_JOYSTICK_XINPUT
if (SDL_IsJoystickXInput(*guid)) {
/* This is an XInput device */
}
#endif
}
return NULL;
}
static ControllerMapping_t* SDL_PrivateGetControllerMappingForNameAndGUID ( const char *  name,
SDL_JoystickGUID  guid 
)
static

Definition at line 1006 of file SDL_gamecontroller.c.

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

Referenced by SDL_IsGameControllerNameAndGUID(), and SDL_PrivateGetControllerMapping().

{
#ifdef __LINUX__
if (!mapping && name) {
if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
/* The Linux driver xpad.c maps the wireless dpad to buttons */
SDL_bool existing;
"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,",
}
}
#endif /* __LINUX__ */
if (!mapping && name) {
if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX")) {
mapping = s_pXInputMapping;
}
}
#ifdef __ANDROID__
if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForAndroidController(name, guid);
}
#endif
if (!mapping) {
mapping = s_pDefaultMapping;
}
return mapping;
}
static char* SDL_PrivateGetControllerMappingFromMappingString ( const char *  pMapping)
static

Definition at line 780 of file SDL_gamecontroller.c.

References NULL, SDL_strchr, and SDL_strdup.

Referenced by SDL_PrivateAddMappingForGUID().

{
const char *pFirstComma, *pSecondComma;
pFirstComma = SDL_strchr(pMapping, ',');
if (!pFirstComma)
return NULL;
pSecondComma = SDL_strchr(pFirstComma + 1, ',');
if (!pSecondComma)
return NULL;
return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
}
static char* SDL_PrivateGetControllerNameFromMappingString ( const char *  pMapping)
static

Definition at line 753 of file SDL_gamecontroller.c.

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

Referenced by SDL_PrivateAddMappingForGUID().

{
const char *pFirstComma, *pSecondComma;
char *pchName;
pFirstComma = SDL_strchr(pMapping, ',');
if (!pFirstComma)
return NULL;
pSecondComma = SDL_strchr(pFirstComma + 1, ',');
if (!pSecondComma)
return NULL;
pchName = SDL_malloc(pSecondComma - pFirstComma);
if (!pchName) {
return NULL;
}
SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
pchName[pSecondComma - pFirstComma - 1] = 0;
return pchName;
}
static void SDL_PrivateLoadButtonMapping ( SDL_GameController *  gamecontroller,
const char *  pchName,
const char *  pchMapping 
)
static

Definition at line 685 of file SDL_gamecontroller.c.

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

Referenced by SDL_GameControllerOpen(), and SDL_PrivateGameControllerRefreshMapping().

{
int i;
gamecontroller->name = pchName;
gamecontroller->num_bindings = 0;
SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
/* Set the zero point for triggers */
for (i = 0; i < gamecontroller->num_bindings; ++i) {
SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i];
if (binding->input.axis.axis < gamecontroller->joystick->naxes) {
gamecontroller->joystick->axes[binding->input.axis.axis].value =
gamecontroller->joystick->axes[binding->input.axis.axis].zero = (Sint16)binding->input.axis.axis_min;
}
}
}
}
SDL_bool SDL_ShouldIgnoreGameController ( const char *  name,
SDL_JoystickGUID  guid 
)

Definition at line 1460 of file SDL_gamecontroller.c.

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

Referenced by SDL_ShouldIgnoreJoystick().

{
int i;
Uint16 vendor;
Uint16 product;
Uint16 version;
Uint32 vidpid;
return SDL_FALSE;
}
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version);
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
/* 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 */
SDL_bool bSteamVirtualGamepad = SDL_FALSE;
#if defined(__LINUX__)
bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
#elif defined(__MACOSX__)
bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
#elif defined(__WIN32__)
/* We can't tell on Windows, but Steam will block others in input hooks */
bSteamVirtualGamepad = SDL_TRUE;
#endif
if (bSteamVirtualGamepad) {
return SDL_FALSE;
}
}
vidpid = MAKE_VIDPID(vendor, product);
for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) {
if (vidpid == SDL_allowed_controllers.entries[i]) {
return SDL_FALSE;
}
}
return SDL_TRUE;
} else {
for (i = 0; i < SDL_ignored_controllers.num_entries; ++i) {
if (vidpid == SDL_ignored_controllers.entries[i]) {
return SDL_TRUE;
}
}
return SDL_FALSE;
}
}
static void UpdateEventsForDeviceRemoval ( )
static

Definition at line 201 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().

{
int i, num_events;
if (num_events <= 0) {
return;
}
events = SDL_stack_alloc(SDL_Event, num_events);
if (!events) {
return;
}
for (i = 0; i < num_events; ++i) {
--events[i].cdevice.which;
}
SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
SDL_stack_free(events);
}

Variable Documentation

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

Definition at line 448 of file SDL_gamecontroller.c.

Referenced by SDL_GameControllerGetAxisFromString(), and SDL_GameControllerGetStringForAxis().

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

Definition at line 491 of file SDL_gamecontroller.c.

Referenced by SDL_GameControllerGetButtonFromString(), and SDL_GameControllerGetStringForButton().

ControllerMapping_t* s_pDefaultMapping = NULL
static

Definition at line 104 of file SDL_gamecontroller.c.

Referenced by SDL_PrivateGetControllerMappingForNameAndGUID().

ControllerMapping_t* s_pHIDAPIMapping = NULL
static

Definition at line 105 of file SDL_gamecontroller.c.

Referenced by SDL_PrivateGetControllerMappingForGUID().

ControllerMapping_t* s_pSupportedControllers = NULL
static
SDL_JoystickGUID s_zeroGUID
static

Definition at line 102 of file SDL_gamecontroller.c.

SDL_vidpid_list SDL_allowed_controllers
static

Definition at line 132 of file SDL_gamecontroller.c.

SDL_vidpid_list SDL_ignored_controllers
static

Definition at line 133 of file SDL_gamecontroller.c.