21 #include "../SDL_internal.h" 31 #if !SDL_EVENTS_DISABLED 32 #include "../events/SDL_events_c.h" 34 #define ABS(_x) ((_x) < 0 ? -(_x) : (_x)) 36 #define SDL_CONTROLLER_PLATFORM_FIELD "platform:" 49 #define k_nMaxReverseEntries 48 55 #define k_nMaxHatEntries 0x3f + 1 83 typedef struct _ControllerMapping_t
88 struct _ControllerMapping_t *
next;
120 if (num_events <= 0) {
130 for (i = 0; i < num_events; ++
i) {
143 switch(event->
type) {
146 SDL_GameController *controllerlist;
150 SDL_SetError(
"SDL_GameControllerEventWatcher: Axis index %d too large, ignoring motion", (
int)event->
jaxis.
axis);
155 while (controllerlist) {
156 if (controllerlist->joystick->instance_id == event->
jaxis.
which) {
157 if (controllerlist->mapping.raxes[event->
jaxis.
axis] >= 0) {
163 value = value / 2 + 16384;
169 }
else if (controllerlist->mapping.raxesasbutton[event->
jaxis.
axis] >= 0) {
174 controllerlist = controllerlist->next;
181 SDL_GameController *controllerlist;
190 while (controllerlist) {
191 if (controllerlist->joystick->instance_id == event->
jbutton.
which) {
192 if (controllerlist->mapping.rbuttons[event->
jbutton.
button] >= 0) {
194 }
else if (controllerlist->mapping.rbuttonasaxis[event->
jbutton.
button] >= 0) {
199 controllerlist = controllerlist->next;
205 SDL_GameController *controllerlist;
207 if (event->
jhat.
hat >= 4)
break;
210 while (controllerlist) {
211 if (controllerlist->joystick->instance_id == event->
jhat.
which) {
212 Uint8 bSame = controllerlist->hatState[
event->jhat.hat] &
event->jhat.value;
214 Uint8 bChanged = controllerlist->hatState[
event->jhat.hat] ^ bSame;
216 int bHighHat =
event->jhat.hat << 4;
228 bChanged =
event->jhat.value ^ bSame;
230 if (bChanged & SDL_HAT_DOWN)
232 if (bChanged & SDL_HAT_UP)
234 if (bChanged & SDL_HAT_LEFT)
236 if (bChanged & SDL_HAT_RIGHT)
240 controllerlist->hatState[
event->jhat.hat] =
event->jhat.value;
244 controllerlist = controllerlist->next;
261 while (controllerlist) {
262 if (controllerlist->joystick->instance_id == event->
jdevice.
which) {
272 controllerlist = controllerlist->next;
289 while (pSupportedController) {
290 if (
SDL_memcmp(guid, &pSupportedController->
guid,
sizeof(*guid)) == 0) {
291 return pSupportedController;
293 pSupportedController = pSupportedController->
next;
314 if (!pchString || !pchString[0])
360 if (!pchString || !pchString[0])
391 iSDLButton =
SDL_atoi(&szJoystickButton[1]);
393 if (szJoystickButton[0] ==
'a') {
399 pMapping->
axes[
axis ] = iSDLButton;
408 }
else if (szJoystickButton[0] ==
'b') {
422 }
else if (szJoystickButton[0] ==
'h') {
433 ridx = (hat << 4) | mask;
450 char szGameButton[20];
451 char szJoystickButton[20];
454 const char *pchPos = pchString;
457 SDL_memset(szJoystickButton, 0
x0,
sizeof(szJoystickButton));
459 while (pchPos && *pchPos) {
460 if (*pchPos ==
':') {
463 }
else if (*pchPos ==
' ') {
465 }
else if (*pchPos ==
',') {
470 SDL_memset(szJoystickButton, 0
x0,
sizeof(szJoystickButton));
472 }
else if (bGameButton) {
473 if (i >=
sizeof(szGameButton)) {
474 SDL_SetError(
"Button name too large: %s", szGameButton);
477 szGameButton[
i] = *pchPos;
480 if (i >=
sizeof(szJoystickButton)) {
481 SDL_SetError(
"Joystick button name too large: %s", szJoystickButton);
484 szJoystickButton[
i] = *pchPos;
501 pMapping->
guid = guid;
502 pMapping->
name = pchName;
506 pMapping->
axes[
j] = -1;
535 const char *pFirstComma =
SDL_strchr(pMapping,
',');
537 char *pchGUID =
SDL_malloc(pFirstComma - pMapping + 1);
542 SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
543 pchGUID[ pFirstComma - pMapping ] = 0;
555 const char *pFirstComma, *pSecondComma;
562 pSecondComma =
SDL_strchr(pFirstComma + 1,
',');
566 pchName =
SDL_malloc(pSecondComma - pFirstComma);
571 SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
572 pchName[ pSecondComma - pFirstComma - 1 ] = 0;
582 const char *pFirstComma, *pSecondComma;
588 pSecondComma =
SDL_strchr(pFirstComma + 1,
',');
601 while (gamecontrollerlist) {
602 if (!
SDL_memcmp(&gamecontrollerlist->mapping.guid, &pControllerMapping->
guid,
sizeof(pControllerMapping->
guid))) {
605 event.cdevice.which = gamecontrollerlist->joystick->instance_id;
612 gamecontrollerlist = gamecontrollerlist->next;
628 SDL_SetError(
"Couldn't parse name from %s", mappingString);
640 if (pControllerMapping) {
643 pControllerMapping->
name = pchName;
645 pControllerMapping->
mapping = pchMapping;
650 pControllerMapping =
SDL_malloc(
sizeof(*pControllerMapping));
651 if (!pControllerMapping) {
657 pControllerMapping->
guid = jGUID;
658 pControllerMapping->
name = pchName;
659 pControllerMapping->
mapping = pchMapping;
661 s_pSupportedControllers = pControllerMapping;
664 return pControllerMapping;
676 #if SDL_JOYSTICK_XINPUT 677 if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
681 #if defined(SDL_JOYSTICK_EMSCRIPTEN) 682 if (!mapping && s_pEmscriptenMapping) {
690 if (
SDL_strstr(name,
"Xbox 360 Wireless Receiver")) {
694 "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,",
720 char *
buf, *line, *line_end, *tmp, *comma, line_platform[64];
721 size_t db_size, platform_len;
733 return SDL_SetError(
"Could not allocate space to read DB into memory");
751 while (line < buf + db_size) {
753 if (line_end !=
NULL) {
756 line_end = buf + db_size;
765 platform_len = comma - tmp + 1;
796 if (!mappingString) {
802 return SDL_SetError(
"Couldn't parse GUID from %s", mappingString);
814 if (!pControllerMapping) {
821 if (is_xinput_mapping) {
822 s_pXInputMapping = pControllerMapping;
824 if (is_emscripten_mapping) {
825 s_pEmscriptenMapping = pControllerMapping;
837 char *pMappingString =
NULL;
846 if (!pMappingString) {
852 return pMappingString;
861 if (!gamecontroller) {
872 if (hint && hint[0]) {
874 char *pUserMappings =
SDL_malloc(nchHints + 1);
875 char *pTempMappings = pUserMappings;
877 pUserMappings[nchHints] =
'\0';
878 while (pUserMappings) {
879 char *pchNewLine =
NULL;
888 pUserMappings = pchNewLine + 1;
890 pUserMappings =
NULL;
904 const char *pMappingString =
NULL;
906 while (pMappingString) {
940 if (pSupportedController) {
941 return pSupportedController->
name;
954 if (pSupportedController) {
971 SDL_GameController *gamecontroller;
972 SDL_GameController *gamecontrollerlist;
982 while (gamecontrollerlist) {
984 gamecontroller = gamecontrollerlist;
985 ++gamecontroller->ref_count;
986 return (gamecontroller);
988 gamecontrollerlist = gamecontrollerlist->next;
993 if (!pSupportedController) {
994 SDL_SetError(
"Couldn't find mapping for device (%d)", device_index);
999 gamecontroller = (SDL_GameController *)
SDL_malloc((
sizeof *gamecontroller));
1000 if (gamecontroller ==
NULL) {
1005 SDL_memset(gamecontroller, 0, (
sizeof *gamecontroller));
1007 if (!gamecontroller->joystick) {
1018 if (leftTriggerMapping >= 0) {
1019 gamecontroller->joystick->axes[leftTriggerMapping] =
1020 gamecontroller->joystick->axes_zero[leftTriggerMapping] = (
Sint16)-32768;
1022 if (rightTriggerMapping >= 0) {
1023 gamecontroller->joystick->axes[rightTriggerMapping] =
1024 gamecontroller->joystick->axes_zero[rightTriggerMapping] = (
Sint16)-32768;
1029 ++gamecontroller->ref_count;
1036 return (gamecontroller);
1056 if (!gamecontroller)
1059 if (gamecontroller->mapping.axes[axis] >= 0) {
1065 value = value / 2 + 16384;
1070 }
else if (gamecontroller->mapping.buttonasaxis[axis] >= 0) {
1072 value =
SDL_JoystickGetButton(gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis]);
1087 if (!gamecontroller)
1090 if (gamecontroller->mapping.buttons[button] >= 0) {
1092 }
else if (gamecontroller->mapping.axesasbutton[button] >= 0) {
1094 value =
SDL_JoystickGetAxis(gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button]);
1095 if (
ABS(value) > 32768/2)
1098 }
else if (gamecontroller->mapping.hatasbutton[button].hat >= 0) {
1100 value =
SDL_JoystickGetHat(gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat);
1102 if (value & gamecontroller->mapping.hatasbutton[button].mask)
1117 if (!gamecontroller)
1127 if (!gamecontroller)
1130 return (gamecontroller->mapping.name);
1139 if (!gamecontroller)
1142 return gamecontroller->joystick;
1149 SDL_GameController *
1153 while (gamecontroller) {
1154 if (gamecontroller->joystick->instance_id == joyid) {
1155 return gamecontroller;
1157 gamecontroller = gamecontroller->next;
1175 if (gamecontroller->mapping.axes[axis] >= 0) {
1178 }
else if (gamecontroller->mapping.buttonasaxis[axis] >= 0) {
1198 if (gamecontroller->mapping.buttons[button] >= 0) {
1201 }
else if (gamecontroller->mapping.axesasbutton[button] >= 0) {
1204 }
else if (gamecontroller->mapping.hatasbutton[button].hat >= 0) {
1206 bind.
value.
hat.hat = gamecontroller->mapping.hatasbutton[
button].hat;
1207 bind.
value.
hat.hat_mask = gamecontroller->mapping.hatasbutton[
button].mask;
1217 SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
1219 if (!gamecontroller)
1223 if (--gamecontroller->ref_count > 0) {
1230 gamecontrollerlistprev =
NULL;
1231 while (gamecontrollerlist) {
1232 if (gamecontroller == gamecontrollerlist) {
1233 if (gamecontrollerlistprev) {
1235 gamecontrollerlistprev->next = gamecontrollerlist->next;
1242 gamecontrollerlistprev = gamecontrollerlist;
1243 gamecontrollerlist = gamecontrollerlist->next;
1262 while (s_pSupportedControllers) {
1264 s_pSupportedControllers = s_pSupportedControllers->
next;
1284 #if !SDL_EVENTS_DISABLED 1288 event.caxis.which = gamecontroller->joystick->instance_id;
1289 event.caxis.axis =
axis;
1290 event.caxis.value =
value;
1305 #if !SDL_EVENTS_DISABLED 1326 #if !SDL_EVENTS_DISABLED 1328 event.cbutton.which = gamecontroller->joystick->instance_id;
1329 event.cbutton.button =
button;
1330 event.cbutton.state =
state;
1343 #if SDL_EVENTS_DISABLED 1346 const Uint32 event_list[] = {
static const char * map_StringForControllerAxis[]
char * SDL_GameControllerMapping(SDL_GameController *gamecontroller)
char * SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
#define SDL_DelEventWatch
static ControllerMapping_t * SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing)
#define SDL_CONTROLLER_PLATFORM_FIELD
struct _SDL_HatMapping hatasbutton[SDL_CONTROLLER_BUTTON_MAX]
int buttons[SDL_CONTROLLER_BUTTON_MAX]
#define SDL_JoystickGetButton
SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *pchString)
SDL_JoyDeviceEvent jdevice
#define SDL_JoystickClose
void SDL_PrivateGameControllerParseButton(const char *szGameButton, const char *szJoystickButton, struct _SDL_ControllerMapping *pMapping)
SDL_ControllerDeviceEvent cdevice
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
SDL_JoyButtonEvent jbutton
struct _ControllerMapping_t * next
static void UpdateEventsForDeviceRemoval()
Sint16 SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
ControllerMapping_t * SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *guid)
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *pchString)
#define SDL_JoystickNameForIndex
static SDL_Event events[EVENT_BUF_SIZE]
SDL_GameControllerAxis raxes[k_nMaxReverseEntries]
SDL_GameControllerButton rbuttons[k_nMaxReverseEntries]
#define SDL_RWread(ctx, ptr, size, n)
int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state)
GLuint const GLchar * name
uint32_t Uint32
An unsigned 32-bit integer type.
#define SDL_InvalidParamError(param)
static void SDL_GameControllerLoadHints()
static ControllerMapping_t * s_pEmscriptenMapping
#define SDL_JoystickGetGUIDString
SDL_GameControllerButton rhatasbutton[k_nMaxHatEntries]
int buttonasaxis[SDL_CONTROLLER_AXIS_MAX]
#define SDL_JoystickGetHat
struct _SDL_GameController * next
#define SDL_JoystickGetDeviceGUID
SDL_GameController * SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value)
void SDL_GameControllerClose(SDL_GameController *gamecontroller)
SDL_GameControllerButton raxesasbutton[k_nMaxReverseEntries]
#define SDL_GetEventState(type)
static SDL_GameController * SDL_gamecontrollers
GLsizei const GLfloat * value
static ControllerMapping_t * s_pSupportedControllers
int SDL_GameControllerEventState(int state)
void SDL_GameControllerQuit(void)
uint8_t Uint8
An unsigned 8-bit integer type.
int SDL_GameControllerAddMapping(const char *mappingString)
#define SDL_stack_alloc(type, count)
const char * SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis)
const char * SDL_GameControllerName(SDL_GameController *gamecontroller)
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)
void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
void SDL_PrivateLoadButtonMapping(struct _SDL_ControllerMapping *pMapping, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping)
ControllerMapping_t * SDL_PrivateGetControllerMapping(int device_index)
#define SDL_JoystickGetAttached
static const char * map_StringForControllerButton[]
void SDL_GameControllerUpdate(void)
SDL_GameControllerAxis rbuttonasaxis[k_nMaxReverseEntries]
GLenum GLuint GLenum GLsizei const GLchar * buf
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
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)
#define SDL_assert(condition)
SDL_GameController * SDL_GameControllerOpen(int device_index)
SDL_bool SDL_IsGameController(int device_index)
#define SDL_OutOfMemory()
static const char * s_ControllerMappings[]
#define SDL_JoystickUpdate
SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis)
#define SDL_JoystickGetAxis
char * SDL_PrivateGetControllerNameFromMappingString(const char *pMapping)
#define SDL_AddEventWatch
SDL_Joystick * SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)
static ControllerMapping_t * s_pXInputMapping
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
#define SDL_arraysize(array)
GLenum GLenum GLenum GLenum mapping
#define SDL_HINT_GAMECONTROLLERCONFIG
A variable that lets you manually hint extra gamecontroller db entries.
int axes[SDL_CONTROLLER_AXIS_MAX]
int axesasbutton[SDL_CONTROLLER_BUTTON_MAX]
#define SDL_stack_free(data)
int SDL_GameControllerAddMappingsFromRW(SDL_RWops *rw, int freerw)
int SDL_GameControllerInit(void)
const char * SDL_GameControllerGetStringForButton(SDL_GameControllerButton axis)
char * SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid)
#define k_nMaxReverseEntries
Uint8 SDL_GameControllerGetButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
int SDL_GameControllerEventWatcher(void *userdata, SDL_Event *event)
static void SDL_PrivateGameControllerParseControllerConfigString(struct _SDL_ControllerMapping *pMapping, const char *pchString)
char * SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping)
SDL_bool SDL_GameControllerGetAttached(SDL_GameController *gamecontroller)
#define SDL_JoystickGetGUIDFromString
int16_t Sint16
A signed 16-bit integer type.
const char * SDL_GameControllerNameForIndex(int device_index)