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:" 48 #define k_nMaxReverseEntries 20 54 #define k_nMaxHatEntries 0x3f + 1 82 typedef struct _ControllerMapping_t
87 struct _ControllerMapping_t *
next;
113 switch(event->
type) {
116 SDL_GameController *controllerlist;
121 while (controllerlist) {
122 if (controllerlist->joystick->instance_id == event->
jaxis.
which) {
123 if (controllerlist->mapping.raxes[event->
jaxis.
axis] >= 0) {
130 value = value / 2 + 16384;
135 }
else if (controllerlist->mapping.raxesasbutton[event->
jaxis.
axis] >= 0) {
140 controllerlist = controllerlist->next;
147 SDL_GameController *controllerlist;
152 while (controllerlist) {
153 if (controllerlist->joystick->instance_id == event->
jbutton.
which) {
154 if (controllerlist->mapping.rbuttons[event->
jbutton.
button] >= 0) {
156 }
else if (controllerlist->mapping.rbuttonasaxis[event->
jbutton.
button] >= 0) {
161 controllerlist = controllerlist->next;
167 SDL_GameController *controllerlist;
169 if (event->
jhat.
hat >= 4)
break;
172 while (controllerlist) {
173 if (controllerlist->joystick->instance_id == event->
jhat.
which) {
174 Uint8 bSame = controllerlist->hatState[
event->jhat.hat] &
event->jhat.value;
176 Uint8 bChanged = controllerlist->hatState[
event->jhat.hat] ^ bSame;
178 int bHighHat =
event->jhat.hat << 4;
190 bChanged =
event->jhat.value ^ bSame;
192 if (bChanged & SDL_HAT_DOWN)
194 if (bChanged & SDL_HAT_UP)
196 if (bChanged & SDL_HAT_LEFT)
198 if (bChanged & SDL_HAT_RIGHT)
202 controllerlist->hatState[
event->jhat.hat] =
event->jhat.value;
206 controllerlist = controllerlist->next;
223 while (controllerlist) {
224 if (controllerlist->joystick->instance_id == event->
jdevice.
which) {
231 controllerlist = controllerlist->next;
248 while (pSupportedController) {
249 if (
SDL_memcmp(guid, &pSupportedController->
guid,
sizeof(*guid)) == 0) {
250 return pSupportedController;
252 pSupportedController = pSupportedController->
next;
273 if (!pchString || !pchString[0])
319 if (!pchString || !pchString[0])
350 iSDLButton =
SDL_atoi(&szJoystickButton[1]);
352 if (szJoystickButton[0] ==
'a') {
358 pMapping->
axes[
axis ] = iSDLButton;
367 }
else if (szJoystickButton[0] ==
'b') {
381 }
else if (szJoystickButton[0] ==
'h') {
392 ridx = (hat << 4) | mask;
409 char szGameButton[20];
410 char szJoystickButton[20];
413 const char *pchPos = pchString;
416 SDL_memset(szJoystickButton, 0
x0,
sizeof(szJoystickButton));
418 while (pchPos && *pchPos) {
419 if (*pchPos ==
':') {
422 }
else if (*pchPos ==
' ') {
424 }
else if (*pchPos ==
',') {
429 SDL_memset(szJoystickButton, 0
x0,
sizeof(szJoystickButton));
431 }
else if (bGameButton) {
432 if (i >=
sizeof(szGameButton)) {
433 SDL_SetError(
"Button name too large: %s", szGameButton);
436 szGameButton[
i] = *pchPos;
439 if (i >=
sizeof(szJoystickButton)) {
440 SDL_SetError(
"Joystick button name too large: %s", szJoystickButton);
443 szJoystickButton[
i] = *pchPos;
460 pMapping->
guid = guid;
461 pMapping->
name = pchName;
465 pMapping->
axes[
j] = -1;
494 const char *pFirstComma =
SDL_strchr(pMapping,
',');
496 char *pchGUID =
SDL_malloc(pFirstComma - pMapping + 1);
501 SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping);
502 pchGUID[ pFirstComma - pMapping ] = 0;
514 const char *pFirstComma, *pSecondComma;
521 pSecondComma =
SDL_strchr(pFirstComma + 1,
',');
525 pchName =
SDL_malloc(pSecondComma - pFirstComma);
530 SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma);
531 pchName[ pSecondComma - pFirstComma - 1 ] = 0;
541 const char *pFirstComma, *pSecondComma;
547 pSecondComma =
SDL_strchr(pFirstComma + 1,
',');
560 while (gamecontrollerlist) {
561 if (!
SDL_memcmp(&gamecontrollerlist->mapping.guid, &pControllerMapping->
guid,
sizeof(pControllerMapping->
guid))) {
564 event.cdevice.which = gamecontrollerlist->joystick->instance_id;
571 gamecontrollerlist = gamecontrollerlist->next;
587 SDL_SetError(
"Couldn't parse name from %s", mappingString);
599 if (pControllerMapping) {
602 pControllerMapping->
name = pchName;
604 pControllerMapping->
mapping = pchMapping;
609 pControllerMapping =
SDL_malloc(
sizeof(*pControllerMapping));
610 if (!pControllerMapping) {
616 pControllerMapping->
guid = jGUID;
617 pControllerMapping->
name = pchName;
618 pControllerMapping->
mapping = pchMapping;
620 s_pSupportedControllers = pControllerMapping;
623 return pControllerMapping;
635 #if SDL_JOYSTICK_XINPUT 636 if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
640 #if defined(SDL_JOYSTICK_EMSCRIPTEN) 641 if (!mapping && s_pEmscriptenMapping) {
649 if (
SDL_strstr(name,
"Xbox 360 Wireless Receiver")) {
653 "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,",
679 char *
buf, *line, *line_end, *tmp, *comma, line_platform[64];
680 size_t db_size, platform_len;
692 return SDL_SetError(
"Could not allocate space to read DB into memory");
710 while (line < buf + db_size) {
712 if (line_end !=
NULL) {
715 line_end = buf + db_size;
724 platform_len = comma - tmp + 1;
755 if (!mappingString) {
761 return SDL_SetError(
"Couldn't parse GUID from %s", mappingString);
773 if (!pControllerMapping) {
780 if (is_xinput_mapping) {
781 s_pXInputMapping = pControllerMapping;
783 if (is_emscripten_mapping) {
784 s_pEmscriptenMapping = pControllerMapping;
796 char *pMappingString =
NULL;
805 if (!pMappingString) {
811 return pMappingString;
820 if (!gamecontroller) {
831 if (hint && hint[0]) {
833 char *pUserMappings =
SDL_malloc(nchHints + 1);
834 char *pTempMappings = pUserMappings;
836 pUserMappings[nchHints] =
'\0';
837 while (pUserMappings) {
838 char *pchNewLine =
NULL;
847 pUserMappings = pchNewLine + 1;
849 pUserMappings =
NULL;
863 const char *pMappingString =
NULL;
864 s_pSupportedControllers =
NULL;
866 while (pMappingString) {
900 if (pSupportedController) {
901 return pSupportedController->
name;
914 if (pSupportedController) {
931 SDL_GameController *gamecontroller;
932 SDL_GameController *gamecontrollerlist;
942 while (gamecontrollerlist) {
944 gamecontroller = gamecontrollerlist;
945 ++gamecontroller->ref_count;
946 return (gamecontroller);
948 gamecontrollerlist = gamecontrollerlist->next;
953 if (!pSupportedController) {
954 SDL_SetError(
"Couldn't find mapping for device (%d)", device_index);
959 gamecontroller = (SDL_GameController *)
SDL_malloc((
sizeof *gamecontroller));
960 if (gamecontroller ==
NULL) {
965 SDL_memset(gamecontroller, 0, (
sizeof *gamecontroller));
967 if (!gamecontroller->joystick) {
975 ++gamecontroller->ref_count;
982 return (gamecontroller);
1002 if (!gamecontroller)
1005 if (gamecontroller->mapping.axes[axis] >= 0) {
1011 value = value / 2 + 16384;
1016 }
else if (gamecontroller->mapping.buttonasaxis[axis] >= 0) {
1018 value =
SDL_JoystickGetButton(gamecontroller->joystick, gamecontroller->mapping.buttonasaxis[axis]);
1033 if (!gamecontroller)
1036 if (gamecontroller->mapping.buttons[button] >= 0) {
1038 }
else if (gamecontroller->mapping.axesasbutton[button] >= 0) {
1040 value =
SDL_JoystickGetAxis(gamecontroller->joystick, gamecontroller->mapping.axesasbutton[button]);
1041 if (
ABS(value) > 32768/2)
1044 }
else if (gamecontroller->mapping.hatasbutton[button].hat >= 0) {
1046 value =
SDL_JoystickGetHat(gamecontroller->joystick, gamecontroller->mapping.hatasbutton[button].hat);
1048 if (value & gamecontroller->mapping.hatasbutton[button].mask)
1063 if (!gamecontroller)
1073 if (!gamecontroller)
1076 return (gamecontroller->mapping.name);
1085 if (!gamecontroller)
1088 return gamecontroller->joystick;
1095 SDL_GameController *
1099 while (gamecontroller) {
1100 if (gamecontroller->joystick->instance_id == joyid) {
1101 return gamecontroller;
1103 gamecontroller = gamecontroller->next;
1121 if (gamecontroller->mapping.axes[axis] >= 0) {
1124 }
else if (gamecontroller->mapping.buttonasaxis[axis] >= 0) {
1144 if (gamecontroller->mapping.buttons[button] >= 0) {
1147 }
else if (gamecontroller->mapping.axesasbutton[button] >= 0) {
1150 }
else if (gamecontroller->mapping.hatasbutton[button].hat >= 0) {
1152 bind.
value.
hat.hat = gamecontroller->mapping.hatasbutton[
button].hat;
1153 bind.
value.
hat.hat_mask = gamecontroller->mapping.hatasbutton[
button].mask;
1163 SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev;
1165 if (!gamecontroller)
1169 if (--gamecontroller->ref_count > 0) {
1176 gamecontrollerlistprev =
NULL;
1177 while (gamecontrollerlist) {
1178 if (gamecontroller == gamecontrollerlist) {
1179 if (gamecontrollerlistprev) {
1181 gamecontrollerlistprev->next = gamecontrollerlist->next;
1188 gamecontrollerlistprev = gamecontrollerlist;
1189 gamecontrollerlist = gamecontrollerlist->next;
1208 while (s_pSupportedControllers) {
1210 s_pSupportedControllers = s_pSupportedControllers->
next;
1230 #if !SDL_EVENTS_DISABLED 1234 event.caxis.which = gamecontroller->joystick->instance_id;
1235 event.caxis.axis =
axis;
1236 event.caxis.value =
value;
1251 #if !SDL_EVENTS_DISABLED 1272 #if !SDL_EVENTS_DISABLED 1274 event.cbutton.which = gamecontroller->joystick->instance_id;
1275 event.cbutton.button =
button;
1276 event.cbutton.state =
state;
1289 #if SDL_EVENTS_DISABLED 1292 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)
uint32_t Uint32
An unsigned 32-bit integer type.
SDL_ControllerDeviceEvent cdevice
SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button)
SDL_JoyButtonEvent jbutton
struct _ControllerMapping_t * next
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
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
#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)
const char * SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis)
const char * SDL_GameControllerName(SDL_GameController *gamecontroller)
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]
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)
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)