mirror of https://github.com/encounter/SDL.git
Added broad support for wireless XBox 360 controllers on Linux
This commit is contained in:
parent
11c13916dd
commit
d1e6a2ebe6
|
@ -254,36 +254,6 @@ ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID *gu
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* map_StringForControllerAxis[] = {
|
static const char* map_StringForControllerAxis[] = {
|
||||||
"leftx",
|
"leftx",
|
||||||
"lefty",
|
"lefty",
|
||||||
|
@ -581,6 +551,9 @@ char *SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping)
|
||||||
return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
|
return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function to refresh a mapping
|
||||||
|
*/
|
||||||
void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
|
void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping)
|
||||||
{
|
{
|
||||||
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
|
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
|
||||||
|
@ -599,6 +572,102 @@ void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* Add or update an entry into the Mappings Database
|
||||||
*/
|
*/
|
||||||
|
@ -677,12 +746,11 @@ int
|
||||||
SDL_GameControllerAddMapping(const char *mappingString)
|
SDL_GameControllerAddMapping(const char *mappingString)
|
||||||
{
|
{
|
||||||
char *pchGUID;
|
char *pchGUID;
|
||||||
char *pchName;
|
|
||||||
char *pchMapping;
|
|
||||||
SDL_JoystickGUID jGUID;
|
SDL_JoystickGUID jGUID;
|
||||||
ControllerMapping_t *pControllerMapping;
|
|
||||||
SDL_bool is_xinput_mapping = SDL_FALSE;
|
SDL_bool is_xinput_mapping = SDL_FALSE;
|
||||||
SDL_bool is_emscripten_mapping = SDL_FALSE;
|
SDL_bool is_emscripten_mapping = SDL_FALSE;
|
||||||
|
SDL_bool existing = SDL_FALSE;
|
||||||
|
ControllerMapping_t *pControllerMapping;
|
||||||
|
|
||||||
if (!mappingString) {
|
if (!mappingString) {
|
||||||
return SDL_InvalidParamError("mappingString");
|
return SDL_InvalidParamError("mappingString");
|
||||||
|
@ -701,46 +769,20 @@ SDL_GameControllerAddMapping(const char *mappingString)
|
||||||
jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
|
jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
|
||||||
SDL_free(pchGUID);
|
SDL_free(pchGUID);
|
||||||
|
|
||||||
pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString);
|
pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing);
|
||||||
if (!pchName) {
|
if (!pControllerMapping) {
|
||||||
return SDL_SetError("Couldn't parse name from %s", mappingString);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString);
|
if (existing) {
|
||||||
if (!pchMapping) {
|
|
||||||
SDL_free(pchName);
|
|
||||||
return SDL_SetError("Couldn't parse %s", mappingString);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
pControllerMapping = SDL_malloc(sizeof(*pControllerMapping));
|
|
||||||
if (!pControllerMapping) {
|
|
||||||
SDL_free(pchName);
|
|
||||||
SDL_free(pchMapping);
|
|
||||||
return SDL_OutOfMemory();
|
|
||||||
}
|
|
||||||
if (is_xinput_mapping) {
|
if (is_xinput_mapping) {
|
||||||
s_pXInputMapping = pControllerMapping;
|
s_pXInputMapping = pControllerMapping;
|
||||||
}
|
}
|
||||||
if (is_emscripten_mapping) {
|
if (is_emscripten_mapping) {
|
||||||
s_pEmscriptenMapping = pControllerMapping;
|
s_pEmscriptenMapping = pControllerMapping;
|
||||||
}
|
}
|
||||||
pControllerMapping->guid = jGUID;
|
|
||||||
pControllerMapping->name = pchName;
|
|
||||||
pControllerMapping->mapping = pchMapping;
|
|
||||||
pControllerMapping->next = s_pSupportedControllers;
|
|
||||||
s_pSupportedControllers = pControllerMapping;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,6 @@ static const char *s_ControllerMappings [] =
|
||||||
"050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
"050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
|
||||||
"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
|
"03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
|
||||||
"03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
|
"03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
|
||||||
"030000005e0400001907000000010000,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,",
|
|
||||||
"030000005e0400009102000007010000,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,",
|
|
||||||
"xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
|
"xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
|
||||||
"030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
|
"030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue