SDL_gamecontroller.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
/* This is the game controller API for Simple DirectMedia Layer */
#include "SDL_events.h"
#include "SDL_assert.h"
#include "SDL_sysjoystick.h"
#include "SDL_hints.h"
#include "SDL_gamecontrollerdb.h"
#if !SDL_EVENTS_DISABLED
#include "../events/SDL_events_c.h"
#endif
#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))
#define SDL_CONTROLLER_PLATFORM_FIELD "platform:"
/* a list of currently opened game controllers */
static SDL_GameController *SDL_gamecontrollers = NULL;
/* keep track of the hat and mask value that transforms this hat movement into a button/axis press */
struct _SDL_HatMapping
{
int hat;
Uint8 mask;
};
#define k_nMaxReverseEntries 20
/**
* We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
* MAX 4 hats supported
*/
#define k_nMaxHatEntries 0x3f + 1
/* our in memory mapping db between joystick objects and controller mappings */
struct _SDL_ControllerMapping
{
SDL_JoystickGUID guid;
const char *name;
/* mapping of axis/button id to controller version */
int axes[SDL_CONTROLLER_AXIS_MAX];
int buttonasaxis[SDL_CONTROLLER_AXIS_MAX];
int buttons[SDL_CONTROLLER_BUTTON_MAX];
int axesasbutton[SDL_CONTROLLER_BUTTON_MAX];
struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX];
/* reverse mapping, joystick indices to buttons */
SDL_GameControllerAxis raxes[k_nMaxReverseEntries];
SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries];
SDL_GameControllerButton rbuttons[k_nMaxReverseEntries];
SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries];
SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries];
};
/* our hard coded list of mapping support */
typedef struct _ControllerMapping_t
{
SDL_JoystickGUID guid;
char *name;
char *mapping;
struct _ControllerMapping_t *next;
} ControllerMapping_t;
static ControllerMapping_t *s_pSupportedControllers = NULL;
static ControllerMapping_t *s_pXInputMapping = NULL;
static ControllerMapping_t *s_pEmscriptenMapping = NULL;
/* The SDL game controller structure */
struct _SDL_GameController
{
SDL_Joystick *joystick; /* underlying joystick device */
int ref_count;
Uint8 hatState[4]; /* the current hat state for this controller */
struct _SDL_ControllerMapping mapping; /* the mapping object for this controller */
struct _SDL_GameController *next; /* pointer to next game controller we have allocated */
};
int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
/*
* Event filter to fire controller events from joystick ones
*/
int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
{
switch(event->type) {
case SDL_JOYAXISMOTION:
{
SDL_GameController *controllerlist;
if (event->jaxis.axis >= k_nMaxReverseEntries) break;
controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jaxis.which) {
if (controllerlist->mapping.raxes[event->jaxis.axis] >= 0) /* simple axis to axis, send it through */ {
SDL_GameControllerAxis axis = controllerlist->mapping.raxes[event->jaxis.axis];
Sint16 value = event->jaxis.value;
switch (axis) {
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
/* Shift it to be 0 - 32767. */
value = value / 2 + 16384;
default:
break;
}
SDL_PrivateGameControllerAxis(controllerlist, axis, value);
} else if (controllerlist->mapping.raxesasbutton[event->jaxis.axis] >= 0) { /* simulate an axis as a button */
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.raxesasbutton[event->jaxis.axis], ABS(event->jaxis.value) > 32768/2 ? SDL_PRESSED : SDL_RELEASED);
}
break;
}
controllerlist = controllerlist->next;
}
}
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
{
SDL_GameController *controllerlist;
if (event->jbutton.button >= k_nMaxReverseEntries) break;
controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jbutton.which) {
if (controllerlist->mapping.rbuttons[event->jbutton.button] >= 0) { /* simple button as button */
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rbuttons[event->jbutton.button], event->jbutton.state);
} else if (controllerlist->mapping.rbuttonasaxis[event->jbutton.button] >= 0) { /* an button pretending to be an axis */
SDL_PrivateGameControllerAxis(controllerlist, controllerlist->mapping.rbuttonasaxis[event->jbutton.button], event->jbutton.state > 0 ? 32767 : 0);
}
break;
}
controllerlist = controllerlist->next;
}
}
break;
case SDL_JOYHATMOTION:
{
SDL_GameController *controllerlist;
if (event->jhat.hat >= 4) break;
controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jhat.which) {
Uint8 bSame = controllerlist->hatState[event->jhat.hat] & event->jhat.value;
/* Get list of removed bits (button release) */
Uint8 bChanged = controllerlist->hatState[event->jhat.hat] ^ bSame;
/* the hat idx in the high nibble */
int bHighHat = event->jhat.hat << 4;
if (bChanged & SDL_HAT_DOWN)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_RELEASED);
if (bChanged & SDL_HAT_UP)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_RELEASED);
if (bChanged & SDL_HAT_LEFT)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_RELEASED);
if (bChanged & SDL_HAT_RIGHT)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_RELEASED);
/* Get list of added bits (button press) */
bChanged = event->jhat.value ^ bSame;
if (bChanged & SDL_HAT_DOWN)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_DOWN], SDL_PRESSED);
if (bChanged & SDL_HAT_UP)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_UP], SDL_PRESSED);
if (bChanged & SDL_HAT_LEFT)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_LEFT], SDL_PRESSED);
if (bChanged & SDL_HAT_RIGHT)
SDL_PrivateGameControllerButton(controllerlist, controllerlist->mapping.rhatasbutton[bHighHat | SDL_HAT_RIGHT], SDL_PRESSED);
/* update our state cache */
controllerlist->hatState[event->jhat.hat] = event->jhat.value;
break;
}
controllerlist = controllerlist->next;
}
}
break;
case SDL_JOYDEVICEADDED:
{
if (SDL_IsGameController(event->jdevice.which)) {
SDL_Event deviceevent;
deviceevent.type = SDL_CONTROLLERDEVICEADDED;
deviceevent.cdevice.which = event->jdevice.which;
SDL_PushEvent(&deviceevent);
}
}
break;
case SDL_JOYDEVICEREMOVED:
{
SDL_GameController *controllerlist = SDL_gamecontrollers;
while (controllerlist) {
if (controllerlist->joystick->instance_id == event->jdevice.which) {
SDL_Event deviceevent;
deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
deviceevent.cdevice.which = event->jdevice.which;
SDL_PushEvent(&deviceevent);
break;
}
controllerlist = controllerlist->next;
}
}
break;
default:
break;
}
return 1;
}
/*
* Helper function to scan the mappings database for a controller with the specified GUID
*/
ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
{
ControllerMapping_t *pSupportedController = s_pSupportedControllers;
while (pSupportedController) {
if (SDL_memcmp(guid, &pSupportedController->guid, sizeof(*guid)) == 0) {
return pSupportedController;
}
pSupportedController = pSupportedController->next;
}
return NULL;
}
static const char* map_StringForControllerAxis[] = {
"leftx",
"lefty",
"rightx",
"righty",
"lefttrigger",
"righttrigger",
NULL
};
/*
* convert a string to its enum equivalent
*/
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *pchString)
{
int entry;
if (!pchString || !pchString[0])
return SDL_CONTROLLER_AXIS_INVALID;
for (entry = 0; map_StringForControllerAxis[entry]; ++entry) {
if (!SDL_strcasecmp(pchString, map_StringForControllerAxis[entry]))
return entry;
}
return SDL_CONTROLLER_AXIS_INVALID;
}
/*
* convert an enum to its string equivalent
*/
const char* SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis)
{
if (axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX) {
return map_StringForControllerAxis[axis];
}
return NULL;
}
static const char* map_StringForControllerButton[] = {
"a",
"b",
"x",
"y",
"back",
"guide",
"start",
"leftstick",
"rightstick",
"leftshoulder",
"rightshoulder",
"dpup",
"dpdown",
"dpleft",
"dpright",
NULL
};
/*
* convert a string to its enum equivalent
*/
SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *pchString)
{
int entry;
if (!pchString || !pchString[0])
return SDL_CONTROLLER_BUTTON_INVALID;
for (entry = 0; map_StringForControllerButton[entry]; ++entry) {
if (SDL_strcasecmp(pchString, map_StringForControllerButton[entry]) == 0)
return entry;
}
return SDL_CONTROLLER_BUTTON_INVALID;
}
/*
* convert an enum to its string equivalent
*/
const char* SDL_GameControllerGetStringForButton(SDL_GameControllerButton axis)
{
if (axis > SDL_CONTROLLER_BUTTON_INVALID && axis < SDL_CONTROLLER_BUTTON_MAX) {
return map_StringForControllerButton[axis];
}
return NULL;
}
/*
* given a controller button name and a joystick name update our mapping structure with it
*/
void SDL_PrivateGameControllerParseButton(const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping)
{
int iSDLButton = 0;
SDL_GameControllerButton button;
SDL_GameControllerAxis axis;
button = SDL_GameControllerGetButtonFromString(szGameButton);
axis = SDL_GameControllerGetAxisFromString(szGameButton);
iSDLButton = SDL_atoi(&szJoystickButton[1]);
if (szJoystickButton[0] == 'a') {
if (iSDLButton >= k_nMaxReverseEntries) {
SDL_SetError("Axis index too large: %d", iSDLButton);
return;
}
if (axis != SDL_CONTROLLER_AXIS_INVALID) {
pMapping->axes[ axis ] = iSDLButton;
pMapping->raxes[ iSDLButton ] = axis;
} else if (button != SDL_CONTROLLER_BUTTON_INVALID) {
pMapping->axesasbutton[ button ] = iSDLButton;
pMapping->raxesasbutton[ iSDLButton ] = button;
} else {
SDL_assert(!"How did we get here?");
}
} else if (szJoystickButton[0] == 'b') {
if (iSDLButton >= k_nMaxReverseEntries) {
SDL_SetError("Button index too large: %d", iSDLButton);
return;
}
if (button != SDL_CONTROLLER_BUTTON_INVALID) {
pMapping->buttons[ button ] = iSDLButton;
pMapping->rbuttons[ iSDLButton ] = button;
} else if (axis != SDL_CONTROLLER_AXIS_INVALID) {
pMapping->buttonasaxis[ axis ] = iSDLButton;
pMapping->rbuttonasaxis[ iSDLButton ] = axis;
} else {
SDL_assert(!"How did we get here?");
}
} else if (szJoystickButton[0] == 'h') {
int hat = SDL_atoi(&szJoystickButton[1]);
int mask = SDL_atoi(&szJoystickButton[3]);
if (hat >= 4) {
SDL_SetError("Hat index too large: %d", iSDLButton);
}
if (button != SDL_CONTROLLER_BUTTON_INVALID) {
int ridx;
pMapping->hatasbutton[ button ].hat = hat;
pMapping->hatasbutton[ button ].mask = mask;
ridx = (hat << 4) | mask;
pMapping->rhatasbutton[ ridx ] = button;
} else if (axis != SDL_CONTROLLER_AXIS_INVALID) {
SDL_assert(!"Support hat as axis");
} else {
SDL_assert(!"How did we get here?");
}
}
}
/*
* given a controller mapping string update our mapping object
*/
static void
SDL_PrivateGameControllerParseControllerConfigString(struct _SDL_ControllerMapping *pMapping, const char *pchString)
{
char szGameButton[20];
char szJoystickButton[20];
SDL_bool bGameButton = SDL_TRUE;
int i = 0;
const char *pchPos = pchString;
SDL_memset(szGameButton, 0x0, sizeof(szGameButton));
SDL_memset(szJoystickButton, 0x0, sizeof(szJoystickButton));
while (pchPos && *pchPos) {
if (*pchPos == ':') {
i = 0;
bGameButton = SDL_FALSE;
} else if (*pchPos == ' ') {
} else if (*pchPos == ',') {
i = 0;
bGameButton = SDL_TRUE;
SDL_PrivateGameControllerParseButton(szGameButton, szJoystickButton, pMapping);
SDL_memset(szGameButton, 0x0, sizeof(szGameButton));
SDL_memset(szJoystickButton, 0x0, sizeof(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_PrivateGameControllerParseButton(szGameButton, szJoystickButton, pMapping);
}
/*
* Make a new button mapping struct
*/
void SDL_PrivateLoadButtonMapping(struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)
{
int j;
pMapping->guid = guid;
pMapping->name = pchName;
/* set all the button mappings to non defaults */
for (j = 0; j < SDL_CONTROLLER_AXIS_MAX; j++) {
pMapping->axes[j] = -1;
pMapping->buttonasaxis[j] = -1;
}
for (j = 0; j < SDL_CONTROLLER_BUTTON_MAX; j++) {
pMapping->buttons[j] = -1;
pMapping->axesasbutton[j] = -1;
pMapping->hatasbutton[j].hat = -1;
}
for (j = 0; j < k_nMaxReverseEntries; j++) {
pMapping->raxes[j] = SDL_CONTROLLER_AXIS_INVALID;
pMapping->rbuttonasaxis[j] = SDL_CONTROLLER_AXIS_INVALID;
pMapping->rbuttons[j] = SDL_CONTROLLER_BUTTON_INVALID;
pMapping->raxesasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
}
for (j = 0; j < k_nMaxHatEntries; j++) {
pMapping->rhatasbutton[j] = SDL_CONTROLLER_BUTTON_INVALID;
}
SDL_PrivateGameControllerParseControllerConfigString(pMapping, pchMapping);
}
/*
* grab the guid string from a mapping string
*/
char *SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
{
const char *pFirstComma = SDL_strchr(pMapping, ',');
if (pFirstComma) {
char *pchGUID = SDL_malloc(pFirstComma - pMapping + 1);
if (!pchGUID) {
SDL_OutOfMemory();
return NULL;
}
SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
pchGUID[ pFirstComma - pMapping ] = 0;
return pchGUID;
}
return NULL;
}
/*
* grab the name string from a mapping string
*/
char *SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
{
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) {
SDL_OutOfMemory();
return NULL;
}
SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
pchName[ pSecondComma - pFirstComma - 1 ] = 0;
return pchName;
}
/*
* grab the button mapping string from a mapping string
*/
char *SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
{
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 */
}
/*
* Helper function to refresh a mapping
*/
void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
{
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
while (gamecontrollerlist) {
if (!SDL_memcmp(&gamecontrollerlist->mapping.guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
SDL_Event event;
event.type = SDL_CONTROLLERDEVICEREMAPPED;
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
SDL_PushEvent(&event);
/* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
SDL_PrivateLoadButtonMapping(&gamecontrollerlist->mapping, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping);
}
gamecontrollerlist = gamecontrollerlist->next;
}
}
/*
* Helper function to add a mapping for a guid
*/
static ControllerMapping_t *
SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing)
{
char *pchName;
char *pchMapping;
ControllerMapping_t *pControllerMapping;
pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString);
if (!pchName) {
SDL_SetError("Couldn't parse name from %s", mappingString);
return NULL;
}
pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString);
if (!pchMapping) {
SDL_free(pchName);
SDL_SetError("Couldn't parse %s", mappingString);
return NULL;
}
pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
if (pControllerMapping) {
/* Update existing mapping */
SDL_free(pControllerMapping->name);
pControllerMapping->name = pchName;
SDL_free(pControllerMapping->mapping);
pControllerMapping->mapping = pchMapping;
/* refresh open controllers */
SDL_PrivateGameControllerRefreshMapping(pControllerMapping);
*existing = SDL_TRUE;
} else {
pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
if (!pControllerMapping) {
SDL_free(pchName);
SDL_free(pchMapping);
SDL_OutOfMemory();
return NULL;
}
pControllerMapping->guid = jGUID;
pControllerMapping->name = pchName;
pControllerMapping->mapping = pchMapping;
pControllerMapping->next = s_pSupportedControllers;
s_pSupportedControllers = pControllerMapping;
*existing = SDL_FALSE;
}
return pControllerMapping;
}
/*
* Helper function to determine pre-calculated offset to certain joystick mappings
*/
ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
{
SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID(device_index);
ControllerMapping_t *mapping;
mapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
#if SDL_JOYSTICK_XINPUT
if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
mapping = s_pXInputMapping;
}
#endif
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
if (!mapping && s_pEmscriptenMapping) {
mapping = s_pEmscriptenMapping;
}
#endif
#ifdef __LINUX__
if (!mapping) {
const char *name = SDL_JoystickNameForIndex(device_index);
if (name) {
if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
/* The Linux driver xpad.c maps the wireless dpad to buttons */
SDL_bool existing;
mapping = SDL_PrivateAddMappingForGUID(jGUID,
"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,",
&existing);
}
}
}
#endif /* __LINUX__ */
if (!mapping) {
const char *name = SDL_JoystickNameForIndex(device_index);
if (name) {
if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box")) {
mapping = s_pXInputMapping;
}
}
}
return mapping;
}
/*
* Add or update an entry into the Mappings Database
*/
int
SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw)
{
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) {
SDL_RWclose(rw);
}
return SDL_SetError("Could not allocate space to read DB into memory");
}
if (SDL_RWread(rw, buf, db_size, 1) != 1) {
if (freerw) {
SDL_RWclose(rw);
}
SDL_free(buf);
return SDL_SetError("Could not read DB");
}
if (freerw) {
SDL_RWclose(rw);
}
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 */
tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD);
if (tmp != NULL) {
tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD);
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 &&
SDL_GameControllerAddMapping(line) > 0) {
controllers++;
}
}
}
}
line = line_end + 1;
}
SDL_free(buf);
return controllers;
}
/*
* Add or update an entry into the Mappings Database
*/
int
SDL_GameControllerAddMapping(const char *mappingString)
{
char *pchGUID;
SDL_JoystickGUID jGUID;
SDL_bool is_xinput_mapping = SDL_FALSE;
SDL_bool is_emscripten_mapping = SDL_FALSE;
SDL_bool existing = SDL_FALSE;
ControllerMapping_t *pControllerMapping;
if (!mappingString) {
return SDL_InvalidParamError("mappingString");
}
pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString);
if (!pchGUID) {
return SDL_SetError("Couldn't parse GUID from %s", mappingString);
}
if (!SDL_strcasecmp(pchGUID, "xinput")) {
is_xinput_mapping = SDL_TRUE;
}
if (!SDL_strcasecmp(pchGUID, "emscripten")) {
is_emscripten_mapping = SDL_TRUE;
}
jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
SDL_free(pchGUID);
pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing);
if (!pControllerMapping) {
return -1;
}
if (existing) {
return 0;
} else {
if (is_xinput_mapping) {
s_pXInputMapping = pControllerMapping;
}
if (is_emscripten_mapping) {
s_pEmscriptenMapping = pControllerMapping;
}
return 1;
}
}
/*
* Get the mapping string for this GUID
*/
char *
SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)
{
char *pMappingString = NULL;
ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
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) {
SDL_OutOfMemory();
return NULL;
}
SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping);
}
return pMappingString;
}
/*
* Get the mapping string for this device
*/
char *
SDL_GameControllerMapping(SDL_GameController * gamecontroller)
{
if (!gamecontroller) {
return NULL;
}
return SDL_GameControllerMappingForGUID(gamecontroller->mapping.guid);
}
static void
SDL_GameControllerLoadHints()
{
const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG);
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';
SDL_GameControllerAddMapping(pUserMappings);
if (pchNewLine) {
pUserMappings = pchNewLine + 1;
} else {
pUserMappings = NULL;
}
}
SDL_free(pTempMappings);
}
}
/*
* Initialize the game controller system, mostly load our DB of controller config mappings
*/
int
SDL_GameControllerInit(void)
{
int i = 0;
const char *pMappingString = NULL;
s_pSupportedControllers = NULL;
pMappingString = s_ControllerMappings[i];
while (pMappingString) {
SDL_GameControllerAddMapping(pMappingString);
i++;
pMappingString = s_ControllerMappings[i];
}
/* load in any user supplied config */
SDL_GameControllerLoadHints();
/* watch for joy events and fire controller ones if needed */
SDL_AddEventWatch(SDL_GameControllerEventWatcher, NULL);
/* Send added events for controllers currently attached */
for (i = 0; i < SDL_NumJoysticks(); ++i) {
if (SDL_IsGameController(i)) {
SDL_Event deviceevent;
deviceevent.type = SDL_CONTROLLERDEVICEADDED;
deviceevent.cdevice.which = i;
SDL_PushEvent(&deviceevent);
}
}
return (0);
}
/*
* Get the implementation dependent name of a controller
*/
const char *
SDL_GameControllerNameForIndex(int device_index)
{
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (pSupportedController) {
return pSupportedController->name;
}
return NULL;
}
/*
* Return 1 if the joystick at this device index is a supported controller
*/
SDL_bool
SDL_IsGameController(int device_index)
{
ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMapping(device_index);
if (pSupportedController) {
return SDL_TRUE;
}
return SDL_FALSE;
}
/*
* Open a controller for use - the index passed as an argument refers to
* the N'th controller on the system. This index is the value which will
* identify this controller in future controller events.
*
* This function returns a controller identifier, or NULL if an error occurred.
*/
SDL_GameController *
SDL_GameControllerOpen(int device_index)
{
SDL_GameController *gamecontroller;
SDL_GameController *gamecontrollerlist;
ControllerMapping_t *pSupportedController = NULL;
if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) {
SDL_SetError("There are %d joysticks available", SDL_NumJoysticks());
return (NULL);
}
gamecontrollerlist = SDL_gamecontrollers;
/* If the controller is already open, return it */
while (gamecontrollerlist) {
if (SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == 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 joystick */
gamecontroller = (SDL_GameController *) SDL_malloc((sizeof *gamecontroller));
if (gamecontroller == NULL) {
SDL_OutOfMemory();
return NULL;
}
SDL_memset(gamecontroller, 0, (sizeof *gamecontroller));
gamecontroller->joystick = SDL_JoystickOpen(device_index);
if (!gamecontroller->joystick) {
SDL_free(gamecontroller);
return NULL;
}
SDL_PrivateLoadButtonMapping(&gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping);
/* Add joystick to list */
++gamecontroller->ref_count;
/* Link the joystick in the list */
gamecontroller->next = SDL_gamecontrollers;
SDL_gamecontrollers = gamecontroller;
SDL_SYS_JoystickUpdate(gamecontroller->joystick);
return (gamecontroller);
}
/*
* Manually pump for controller updates.
*/
void
SDL_GameControllerUpdate(void)
{
/* Just for API completeness; the joystick API does all the work. */
SDL_JoystickUpdate();
}
/*
* Get the current state of an axis control on a controller
*/
Sint16
SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
{
if (!gamecontroller)
return 0;
if (gamecontroller->mapping.axes[axis] >= 0) {
Sint16 value = (SDL_JoystickGetAxis(gamecontroller->joystick, gamecontroller->mapping.axes[axis]));
switch (axis) {
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
/* Shift it to be 0 - 32767. */
value = value / 2 + 16384;
default:
break;
}
return value;
} else if (gamecontroller->mapping.buttonasaxis[axis] >= 0) {
Uint8 value;
value = SDL_JoystickGetButton(gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis]);
if (value > 0)
return 32767;
return 0;
}
return 0;
}
/*
* Get the current state of a button on a controller
*/
Uint8
SDL_GameControllerGetButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
{
if (!gamecontroller)
return 0;
if (gamecontroller->mapping.buttons[button] >= 0) {
return (SDL_JoystickGetButton(gamecontroller->joystick, gamecontroller->mapping.buttons[button]));
} else if (gamecontroller->mapping.axesasbutton[button] >= 0) {
Sint16 value;
value = SDL_JoystickGetAxis(gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button]);
if (ABS(value) > 32768/2)
return 1;
return 0;
} else if (gamecontroller->mapping.hatasbutton[button].hat >= 0) {
Uint8 value;
value = SDL_JoystickGetHat(gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat);
if (value & gamecontroller->mapping.hatasbutton[button].mask)
return 1;
return 0;
}
return 0;
}
/*
* Return if the joystick in question is currently attached to the system,
* \return 0 if not plugged in, 1 if still present.
*/
SDL_bool
SDL_GameControllerGetAttached(SDL_GameController * gamecontroller)
{
if (!gamecontroller)
return SDL_FALSE;
return SDL_JoystickGetAttached(gamecontroller->joystick);
}
const char *
SDL_GameControllerName(SDL_GameController * gamecontroller)
{
if (!gamecontroller)
return NULL;
return (gamecontroller->mapping.name);
}
/*
* Get the joystick for this controller
*/
SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
{
if (!gamecontroller)
return NULL;
return gamecontroller->joystick;
}
/*
* Find the SDL_GameController that owns this instance id
*/
SDL_GameController *
SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
{
SDL_GameController *gamecontroller = SDL_gamecontrollers;
while (gamecontroller) {
if (gamecontroller->joystick->instance_id == joyid) {
return gamecontroller;
}
gamecontroller = gamecontroller->next;
}
return NULL;
}
/**
* Get the SDL joystick layer binding for this controller axis mapping
*/
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis)
{
SDL_GameControllerButtonBind bind;
SDL_memset(&bind, 0x0, sizeof(bind));
if (!gamecontroller || axis == SDL_CONTROLLER_AXIS_INVALID)
return bind;
if (gamecontroller->mapping.axes[axis] >= 0) {
bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
bind.value.button = gamecontroller->mapping.axes[axis];
} else if (gamecontroller->mapping.buttonasaxis[axis] >= 0) {
bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
bind.value.button = gamecontroller->mapping.buttonasaxis[axis];
}
return bind;
}
/**
* Get the SDL joystick layer binding for this controller button mapping
*/
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button)
{
SDL_GameControllerButtonBind bind;
SDL_memset(&bind, 0x0, sizeof(bind));
if (!gamecontroller || button == SDL_CONTROLLER_BUTTON_INVALID)
return bind;
if (gamecontroller->mapping.buttons[button] >= 0) {
bind.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON;
bind.value.button = gamecontroller->mapping.buttons[button];
} else if (gamecontroller->mapping.axesasbutton[button] >= 0) {
bind.bindType = SDL_CONTROLLER_BINDTYPE_AXIS;
bind.value.axis = gamecontroller->mapping.axesasbutton[button];
} else if (gamecontroller->mapping.hatasbutton[button].hat >= 0) {
bind.bindType = SDL_CONTROLLER_BINDTYPE_HAT;
bind.value.hat.hat = gamecontroller->mapping.hatasbutton[button].hat;
bind.value.hat.hat_mask = gamecontroller->mapping.hatasbutton[button].mask;
}
return bind;
}
void
SDL_GameControllerClose(SDL_GameController * gamecontroller)
{
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);
}
/*
* Quit the controller subsystem
*/
void
SDL_GameControllerQuit(void)
{
ControllerMapping_t *pControllerMap;
while (SDL_gamecontrollers) {
SDL_gamecontrollers->ref_count = 1;
SDL_GameControllerClose(SDL_gamecontrollers);
}
while (s_pSupportedControllers) {
pControllerMap = s_pSupportedControllers;
s_pSupportedControllers = s_pSupportedControllers->next;
SDL_free(pControllerMap->name);
SDL_free(pControllerMap->mapping);
SDL_free(pControllerMap);
}
SDL_DelEventWatch(SDL_GameControllerEventWatcher, NULL);
}
/*
* Event filter to transform joystick events into appropriate game controller ones
*/
int
SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
{
int posted;
/* translate the event, if desired */
posted = 0;
#if !SDL_EVENTS_DISABLED
if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) {
SDL_Event event;
event.type = SDL_CONTROLLERAXISMOTION;
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);
}
/*
* Event filter to transform joystick events into appropriate game controller ones
*/
int
SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state)
{
int posted;
#if !SDL_EVENTS_DISABLED
SDL_Event event;
if (button == SDL_CONTROLLER_BUTTON_INVALID)
return (0);
switch (state) {
case SDL_PRESSED:
event.type = SDL_CONTROLLERBUTTONDOWN;
break;
case SDL_RELEASED:
event.type = SDL_CONTROLLERBUTTONUP;
break;
default:
/* Invalid state -- bail */
return (0);
}
#endif /* !SDL_EVENTS_DISABLED */
/* translate the event, if desired */
posted = 0;
#if !SDL_EVENTS_DISABLED
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
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);
}
/*
* Turn off controller events
*/
int
SDL_GameControllerEventState(int state)
{
#if SDL_EVENTS_DISABLED
return SDL_IGNORE;
#else
const Uint32 event_list[] = {
SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP,
SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_CONTROLLERDEVICEREMAPPED,
};
unsigned int i;
switch (state) {
case SDL_QUERY:
state = SDL_IGNORE;
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 */
}
/* vi: set ts=4 sw=4 expandtab: */
SDL_JOYBUTTONUP
Definition: SDL_events.h:112
map_StringForControllerAxis
static const char * map_StringForControllerAxis[]
Definition: SDL_gamecontroller.c:257
SDL_CONTROLLER_BUTTON_INVALID
Definition: SDL_gamecontroller.h:264
SDL_JoyAxisEvent::value
Sint16 value
Definition: SDL_events.h:285
SDL_strlcpy
#define SDL_strlcpy
Definition: SDL_dynapi_overrides.h:400
SDL_GameControllerMapping
char * SDL_GameControllerMapping(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:818
SDL_JoyButtonEvent::which
SDL_JoystickID which
Definition: SDL_events.h:332
SDL_PrivateGetControllerMappingFromMappingString
char * SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
Definition: SDL_gamecontroller.c:539
SDL_DelEventWatch
#define SDL_DelEventWatch
Definition: SDL_dynapi_overrides.h:135
SDL_JOYHATMOTION
Definition: SDL_events.h:110
SDL_GameControllerButtonBind::button
int button
Definition: SDL_gamecontroller.h:75
SDL_PrivateAddMappingForGUID
static ControllerMapping_t * SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing)
Definition: SDL_gamecontroller.c:579
SDL_CONTROLLER_PLATFORM_FIELD
#define SDL_CONTROLLER_PLATFORM_FIELD
Definition: SDL_gamecontroller.c:36
_SDL_ControllerMapping::hatasbutton
struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX]
Definition: SDL_gamecontroller.c:68
_SDL_ControllerMapping::buttons
int buttons[SDL_CONTROLLER_BUTTON_MAX]
Definition: SDL_gamecontroller.c:66
SDL_JoystickGetButton
#define SDL_JoystickGetButton
Definition: SDL_dynapi_overrides.h:220
SDL_GameControllerGetButtonFromString
SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *pchString)
Definition: SDL_gamecontroller.c:316
SDL_Event::jdevice
SDL_JoyDeviceEvent jdevice
Definition: SDL_events.h:536
SDL_JoystickClose
#define SDL_JoystickClose
Definition: SDL_dynapi_overrides.h:221
SDL_JoyAxisEvent::axis
Uint8 axis
Definition: SDL_events.h:281
SDL_PrivateGameControllerParseButton
void SDL_PrivateGameControllerParseButton(const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping)
Definition: SDL_gamecontroller.c:343
button
SDL_Texture * button
Definition: testgamecontroller.c:67
_SDL_HatMapping::hat
int hat
Definition: SDL_gamecontroller.c:44
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:157
SDL_CONTROLLERDEVICEREMOVED
Definition: SDL_events.h:121
SDL_Event::cdevice
SDL_ControllerDeviceEvent cdevice
Definition: SDL_events.h:539
SDL_GameControllerGetBindForButton
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
Definition: SDL_gamecontroller.c:1136
SDL_RWsize
#define SDL_RWsize(ctx)
Definition: SDL_rwops.h:184
SDL_Event::jbutton
SDL_JoyButtonEvent jbutton
Definition: SDL_events.h:535
ControllerMapping_t::next
struct _ControllerMapping_t * next
Definition: SDL_gamecontroller.c:87
SDL_RWops
Definition: SDL_rwops.h:52
SDL_JOYDEVICEADDED
Definition: SDL_events.h:113
SDL_GameControllerGetAxis
Sint16 SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
Definition: SDL_gamecontroller.c:1000
SDL_PrivateGetControllerMappingForGUID
ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
Definition: SDL_gamecontroller.c:245
SDL_GameControllerGetAxisFromString
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *pchString)
Definition: SDL_gamecontroller.c:270
SDL_JoystickNameForIndex
#define SDL_JoystickNameForIndex
Definition: SDL_dynapi_overrides.h:202
state
struct xkb_state * state
Definition: SDL_waylandsym.h:97
_SDL_ControllerMapping::guid
SDL_JoystickGUID guid
Definition: SDL_gamecontroller.c:59
SDL_events.h
SDL_JoyAxisEvent::which
SDL_JoystickID which
Definition: SDL_events.h:280
_SDL_ControllerMapping::raxes
SDL_GameControllerAxis raxes[k_nMaxReverseEntries]
Definition: SDL_gamecontroller.c:71
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:197
_SDL_ControllerMapping::rbuttons
SDL_GameControllerButton rbuttons[k_nMaxReverseEntries]
Definition: SDL_gamecontroller.c:74
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:718
SDL_JoystickOpen
#define SDL_JoystickOpen
Definition: SDL_dynapi_overrides.h:203
k_nMaxHatEntries
#define k_nMaxHatEntries
Definition: SDL_gamecontroller.c:54
SDL_RWread
#define SDL_RWread(ctx, ptr, size, n)
Definition: SDL_rwops.h:187
SDL_GameControllerButtonBind
Definition: SDL_gamecontroller.h:70
SDL_CONTROLLER_BINDTYPE_BUTTON
Definition: SDL_gamecontroller.h:62
SDL_NumJoysticks
#define SDL_NumJoysticks
Definition: SDL_dynapi_overrides.h:201
SDL_PrivateGameControllerButton
int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state)
Definition: SDL_gamecontroller.c:1248
SDL_JoyButtonEvent::state
Uint8 state
Definition: SDL_events.h:334
ABS
#define ABS(_x)
Definition: SDL_gamecontroller.c:34
SDL_CONTROLLER_AXIS_MAX
Definition: SDL_gamecontroller.h:227
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
axis
SDL_Texture * axis
Definition: testgamecontroller.c:67
SDL_InvalidParamError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
SDL_GameControllerButton
SDL_GameControllerButton
Definition: SDL_gamecontroller.h:262
SDL_strcasecmp
#define SDL_strcasecmp
Definition: SDL_dynapi_overrides.h:425
SDL_JOYAXISMOTION
Definition: SDL_events.h:108
SDL_GameControllerLoadHints
static void SDL_GameControllerLoadHints()
Definition: SDL_gamecontroller.c:828
s_pEmscriptenMapping
static ControllerMapping_t * s_pEmscriptenMapping
Definition: SDL_gamecontroller.c:92
SDL_CONTROLLERDEVICEADDED
Definition: SDL_events.h:120
SDL_strncasecmp
#define SDL_strncasecmp
Definition: SDL_dynapi_overrides.h:426
SDL_JoystickGetGUIDString
#define SDL_JoystickGetGUIDString
Definition: SDL_dynapi_overrides.h:207
_SDL_ControllerMapping::rhatasbutton
SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries]
Definition: SDL_gamecontroller.c:76
SDL_ControllerDeviceEvent::which
Sint32 which
Definition: SDL_events.h:389
_SDL_ControllerMapping::buttonasaxis
int buttonasaxis[SDL_CONTROLLER_AXIS_MAX]
Definition: SDL_gamecontroller.c:64
SDL_JoystickGetHat
#define SDL_JoystickGetHat
Definition: SDL_dynapi_overrides.h:218
_SDL_GameController::next
struct _SDL_GameController * next
Definition: SDL_gamecontroller.c:101
SDL_CONTROLLERBUTTONUP
Definition: SDL_events.h:119
SDL_JoystickGetDeviceGUID
#define SDL_JoystickGetDeviceGUID
Definition: SDL_dynapi_overrides.h:205
SDL_GameControllerFromInstanceID
SDL_GameController * SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
Definition: SDL_gamecontroller.c:1096
SDL_strchr
#define SDL_strchr
Definition: SDL_dynapi_overrides.h:407
SDL_JOYDEVICEREMOVED
Definition: SDL_events.h:114
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
SDL_PrivateGameControllerAxis
int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
Definition: SDL_gamecontroller.c:1224
size_t
unsigned int size_t
Definition: SDL_config_windows.h:67
_SDL_GameController::ref_count
int ref_count
Definition: SDL_gamecontroller.c:98
SDL_HAT_RIGHT
#define SDL_HAT_RIGHT
Definition: SDL_joystick.h:209
_SDL_ControllerMapping
Definition: SDL_gamecontroller.c:57
SDL_GameControllerClose
void SDL_GameControllerClose(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1161
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:393
_SDL_ControllerMapping::raxesasbutton
SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries]
Definition: SDL_gamecontroller.c:75
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:731
SDL_JoystickID
Sint32 SDL_JoystickID
Definition: SDL_joystick.h:72
ControllerMapping_t::guid
SDL_JoystickGUID guid
Definition: SDL_gamecontroller.c:84
SDL_JOYBUTTONDOWN
Definition: SDL_events.h:111
SDL_HAT_LEFT
#define SDL_HAT_LEFT
Definition: SDL_joystick.h:211
SDL_gamecontrollers
static SDL_GameController * SDL_gamecontrollers
Definition: SDL_gamecontroller.c:39
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
s_pSupportedControllers
static ControllerMapping_t * s_pSupportedControllers
Definition: SDL_gamecontroller.c:90
SDL_GameControllerEventState
int SDL_GameControllerEventState(int state)
Definition: SDL_gamecontroller.c:1287
SDL_Event::jaxis
SDL_JoyAxisEvent jaxis
Definition: SDL_events.h:532
SDL_GameControllerQuit
void SDL_GameControllerQuit(void)
Definition: SDL_gamecontroller.c:1200
sort_controllers.controllers
list controllers
Definition: sort_controllers.py:12
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_GameControllerAddMapping
int SDL_GameControllerAddMapping(const char *mappingString)
Definition: SDL_gamecontroller.c:746
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_GameControllerGetStringForAxis
const char * SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis)
Definition: SDL_gamecontroller.c:286
SDL_free
void SDL_free(void *mem)
SDL_GameControllerButtonBind::bindType
SDL_GameControllerBindType bindType
Definition: SDL_gamecontroller.h:72
SDL_GameControllerName
const char * SDL_GameControllerName(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1071
_SDL_GameController
Definition: SDL_gamecontroller.c:95
SDL_PushEvent
#define SDL_PushEvent
Definition: SDL_dynapi_overrides.h:131
_SDL_ControllerMapping::name
const char * name
Definition: SDL_gamecontroller.c:60
SDL_PrivateGameControllerRefreshMapping
void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
Definition: SDL_gamecontroller.c:557
SDL_memcmp
#define SDL_memcmp
Definition: SDL_dynapi_overrides.h:395
SDL_PrivateLoadButtonMapping
void SDL_PrivateLoadButtonMapping(struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)
Definition: SDL_gamecontroller.c:456
SDL_hints.h
SDL_PrivateGetControllerMapping
ControllerMapping_t * SDL_PrivateGetControllerMapping(int device_index)
Definition: SDL_gamecontroller.c:629
SDL_JoystickGetAttached
#define SDL_JoystickGetAttached
Definition: SDL_dynapi_overrides.h:209
SDL_CONTROLLER_BUTTON_MAX
Definition: SDL_gamecontroller.h:280
SDL_CONTROLLERBUTTONDOWN
Definition: SDL_events.h:118
SDL_GetPlatform
#define SDL_GetPlatform
Definition: SDL_dynapi_overrides.h:297
SDL_CONTROLLER_AXIS_INVALID
Definition: SDL_gamecontroller.h:220
map_StringForControllerButton
static const char * map_StringForControllerButton[]
Definition: SDL_gamecontroller.c:294
SDL_TRUE
Definition: SDL_stdinc.h:129
SDL_GameControllerUpdate
void SDL_GameControllerUpdate(void)
Definition: SDL_gamecontroller.c:989
_SDL_ControllerMapping::rbuttonasaxis
SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries]
Definition: SDL_gamecontroller.c:72
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: SDL_opengl_glext.h:2480
SDL_CONTROLLERDEVICEREMAPPED
Definition: SDL_events.h:122
SDL_SYS_JoystickUpdate
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
Definition: SDL_sysjoystick.m:569
SDL_atoi
#define SDL_atoi
Definition: SDL_dynapi_overrides.h:416
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:657
ControllerMapping_t::name
char * name
Definition: SDL_gamecontroller.c:85
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:167
SDL_CONTROLLER_AXIS_TRIGGERRIGHT
Definition: SDL_gamecontroller.h:226
SDL_GameControllerOpen
SDL_GameController * SDL_GameControllerOpen(int device_index)
Definition: SDL_gamecontroller.c:929
ControllerMapping_t::mapping
char * mapping
Definition: SDL_gamecontroller.c:86
SDL_CONTROLLER_AXIS_TRIGGERLEFT
Definition: SDL_gamecontroller.h:225
SDL_IsGameController
SDL_bool SDL_IsGameController(int device_index)
Definition: SDL_gamecontroller.c:911
NULL
#define NULL
Definition: begin_code.h:143
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
s_ControllerMappings
static const char * s_ControllerMappings[]
Definition: SDL_gamecontrollerdb.h:32
SDL_GameControllerButtonBind::axis
int axis
Definition: SDL_gamecontroller.h:76
SDL_RWclose
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
SDL_JoystickUpdate
#define SDL_JoystickUpdate
Definition: SDL_dynapi_overrides.h:215
SDL_gamecontrollerdb.h
_SDL_GameController::joystick
SDL_Joystick * joystick
Definition: SDL_gamecontroller.c:97
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:36
ControllerMapping_t
Definition: SDL_gamecontroller.c:82
SDL_GameControllerGetBindForAxis
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
Definition: SDL_gamecontroller.c:1113
SDL_JoystickGetAxis
#define SDL_JoystickGetAxis
Definition: SDL_dynapi_overrides.h:217
_SDL_HatMapping
Definition: SDL_gamecontroller.c:42
SDL_JoyHatEvent::hat
Uint8 hat
Definition: SDL_events.h:313
_SDL_HatMapping::mask
Uint8 mask
Definition: SDL_gamecontroller.c:45
SDL_PrivateGetControllerNameFromMappingString
char * SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
Definition: SDL_gamecontroller.c:512
SDL_JoyDeviceEvent::which
Sint32 which
Definition: SDL_events.h:346
SDL_GameControllerButtonBind::value
union SDL_GameControllerButtonBind::@0 value
SDL_AddEventWatch
#define SDL_AddEventWatch
Definition: SDL_dynapi_overrides.h:134
SDL_strlen
#define SDL_strlen
Definition: SDL_dynapi_overrides.h:399
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:403
SDL_GameControllerGetJoystick
SDL_Joystick * SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1083
SDL_EventState
#define SDL_EventState
Definition: SDL_dynapi_overrides.h:137
SDL_JoystickGUID
Definition: SDL_joystick.h:68
s_pXInputMapping
static ControllerMapping_t * s_pXInputMapping
Definition: SDL_gamecontroller.c:91
SDL_FALSE
Definition: SDL_stdinc.h:128
SDL_SYS_GetInstanceIdOfDeviceIndex
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
Definition: SDL_sysjoystick.m:327
x0
GLuint GLfloat x0
Definition: SDL_opengl_glext.h:8583
SDL_CONTROLLER_BINDTYPE_HAT
Definition: SDL_gamecontroller.h:64
SDL_snprintf
#define SDL_snprintf
Definition: SDL_dynapi_overrides.h:46
SDL_CONTROLLER_BINDTYPE_AXIS
Definition: SDL_gamecontroller.h:63
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
mapping
GLenum GLenum GLenum GLenum mapping
Definition: SDL_opengl_glext.h:9374
SDL_HINT_GAMECONTROLLERCONFIG
#define SDL_HINT_GAMECONTROLLERCONFIG
A variable that lets you manually hint extra gamecontroller db entries.
Definition: SDL_hints.h:320
SDL_Event
General event structure.
Definition: SDL_events.h:521
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:380
_SDL_ControllerMapping::axes
int axes[SDL_CONTROLLER_AXIS_MAX]
Definition: SDL_gamecontroller.c:63
_SDL_ControllerMapping::axesasbutton
int axesasbutton[SDL_CONTROLLER_BUTTON_MAX]
Definition: SDL_gamecontroller.c:67
SDL_PRESSED
#define SDL_PRESSED
Definition: SDL_events.h:50
SDL_QUERY
#define SDL_QUERY
Definition: SDL_events.h:715
SDL_Event::jhat
SDL_JoyHatEvent jhat
Definition: SDL_events.h:534
SDL_JoyButtonEvent::button
Uint8 button
Definition: SDL_events.h:333
SDL_GameControllerAddMappingsFromRW
int SDL_GameControllerAddMappingsFromRW(SDL_RWops *rw, int freerw)
Definition: SDL_gamecontroller.c:675
SDL_GameControllerInit
int SDL_GameControllerInit(void)
Definition: SDL_gamecontroller.c:860
SDL_RELEASED
#define SDL_RELEASED
Definition: SDL_events.h:49
SDL_GameControllerGetStringForButton
const char * SDL_GameControllerGetStringForButton(SDL_GameControllerButton axis)
Definition: SDL_gamecontroller.c:332
SDL_GameControllerMappingForGUID
char * SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)
Definition: SDL_gamecontroller.c:794
SDL_CONTROLLERAXISMOTION
Definition: SDL_events.h:117
SDL_GameControllerButtonBind::hat
int hat
Definition: SDL_gamecontroller.h:78
SDL_HAT_UP
#define SDL_HAT_UP
Definition: SDL_joystick.h:208
k_nMaxReverseEntries
#define k_nMaxReverseEntries
Definition: SDL_gamecontroller.c:48
SDL_GameControllerGetButton
Uint8 SDL_GameControllerGetButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
Definition: SDL_gamecontroller.c:1031
SDL_HAT_DOWN
#define SDL_HAT_DOWN
Definition: SDL_joystick.h:210
SDL_JoyHatEvent::which
SDL_JoystickID which
Definition: SDL_events.h:312
SDL_GameControllerAxis
SDL_GameControllerAxis
Definition: SDL_gamecontroller.h:218
SDL_GameControllerEventWatcher
int SDL_GameControllerEventWatcher(void *userdata, SDL_Event *event)
Definition: SDL_gamecontroller.c:111
SDL_PrivateGameControllerParseControllerConfigString
static void SDL_PrivateGameControllerParseControllerConfigString(struct _SDL_ControllerMapping *pMapping, const char *pchString)
Definition: SDL_gamecontroller.c:407
SDL_PrivateGetControllerGUIDFromMappingString
char * SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
Definition: SDL_gamecontroller.c:492
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:392
SDL_GameControllerGetAttached
SDL_bool SDL_GameControllerGetAttached(SDL_GameController *gamecontroller)
Definition: SDL_gamecontroller.c:1061
SDL_JoystickGetGUIDFromString
#define SDL_JoystickGetGUIDFromString
Definition: SDL_dynapi_overrides.h:208
SDL_strstr
#define SDL_strstr
Definition: SDL_dynapi_overrides.h:409
Sint16
int16_t Sint16
A signed 16-bit integer type.
Definition: SDL_stdinc.h:143
SDL_Event::type
Uint32 type
Definition: SDL_events.h:523
SDL_IGNORE
#define SDL_IGNORE
Definition: SDL_events.h:716
SDL_assert.h
SDL_GameControllerNameForIndex
const char * SDL_GameControllerNameForIndex(int device_index)
Definition: SDL_gamecontroller.c:897
j
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:42
SDL_sysjoystick.h