add new gamecontroller APIs
- add mappings after init (or even before w/o using the hint) - get string for axis - get string for button - get mapping string for controller or for GUID - new event to notify when a controller is remapped. (e.g. mapping was changed via the AddMapping method)
This commit is contained in:
parent
979239e130
commit
5fd98b3297
3 changed files with 247 additions and 132 deletions
|
@ -100,6 +100,7 @@ typedef enum
|
||||||
SDL_CONTROLLERBUTTONUP, /**< Game controller button released */
|
SDL_CONTROLLERBUTTONUP, /**< Game controller button released */
|
||||||
SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */
|
SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */
|
||||||
SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */
|
SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */
|
||||||
|
SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */
|
||||||
|
|
||||||
/* Touch events */
|
/* Touch events */
|
||||||
SDL_FINGERDOWN = 0x700,
|
SDL_FINGERDOWN = 0x700,
|
||||||
|
@ -358,9 +359,9 @@ typedef struct SDL_ControllerButtonEvent
|
||||||
*/
|
*/
|
||||||
typedef struct SDL_ControllerDeviceEvent
|
typedef struct SDL_ControllerDeviceEvent
|
||||||
{
|
{
|
||||||
Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED or ::SDL_CONTROLLERDEVICEREMOVED */
|
Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */
|
||||||
Uint32 timestamp;
|
Uint32 timestamp;
|
||||||
Uint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */
|
Uint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
|
||||||
} SDL_ControllerDeviceEvent;
|
} SDL_ControllerDeviceEvent;
|
||||||
|
|
||||||
|
|
||||||
|
@ -484,7 +485,7 @@ typedef union SDL_Event
|
||||||
SDL_JoyHatEvent jhat; /**< Joystick hat event data */
|
SDL_JoyHatEvent jhat; /**< Joystick hat event data */
|
||||||
SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
|
SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
|
||||||
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
|
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
|
||||||
SDL_ControllerAxisEvent caxis; /**< Game Controller button event data */
|
SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
|
||||||
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
|
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
|
||||||
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
|
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
|
||||||
SDL_QuitEvent quit; /**< Quit request event data */
|
SDL_QuitEvent quit; /**< Quit request event data */
|
||||||
|
|
|
@ -90,7 +90,7 @@ typedef struct SDL_GameControllerButtonBind
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* Using the SDL_HINT_GAMECONTROLLERCONFIG hint you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is:
|
* Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is:
|
||||||
* guid,name,mappings
|
* guid,name,mappings
|
||||||
*
|
*
|
||||||
* Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones.
|
* Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones.
|
||||||
|
@ -106,6 +106,26 @@ typedef struct SDL_GameControllerButtonBind
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add or update an existing mapping configuration
|
||||||
|
*
|
||||||
|
* \return 1 if mapping is added, 0 if updated, -1 on error
|
||||||
|
*/
|
||||||
|
extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping( const char* mappingSring );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a mapping string for a GUID
|
||||||
|
*
|
||||||
|
* \return the mapping string. Must be freed with SDL_free. Returns NULL if no mapping is available
|
||||||
|
*/
|
||||||
|
extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a mapping string for an open GameController
|
||||||
|
*
|
||||||
|
* \return the mapping string. Must be freed with SDL_free. Returns NULL if no mapping is available
|
||||||
|
*/
|
||||||
|
extern DECLSPEC char * SDLCALL SDL_GameControllerMapping( SDL_GameController * gamecontroller );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is the joystick on this index supported by the game controller interface?
|
* Is the joystick on this index supported by the game controller interface?
|
||||||
|
@ -186,6 +206,11 @@ typedef enum
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *pchString);
|
extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *pchString);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* turn this axis enum into a string mapping
|
||||||
|
*/
|
||||||
|
extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the SDL joystick layer binding for this controller button mapping
|
* Get the SDL joystick layer binding for this controller button mapping
|
||||||
*/
|
*/
|
||||||
|
@ -233,6 +258,10 @@ typedef enum
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *pchString);
|
extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *pchString);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* turn this button enum into a string mapping
|
||||||
|
*/
|
||||||
|
extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the SDL joystick layer binding for this controller button mapping
|
* Get the SDL joystick layer binding for this controller button mapping
|
||||||
|
|
|
@ -45,8 +45,10 @@ struct _SDL_HatMapping
|
||||||
|
|
||||||
#define k_nMaxReverseEntries 20
|
#define k_nMaxReverseEntries 20
|
||||||
|
|
||||||
// We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
|
/**
|
||||||
// MAX 4 hats supported
|
* We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
|
||||||
|
* MAX 4 hats supported
|
||||||
|
*/
|
||||||
#define k_nMaxHatEntries 0x3f + 1
|
#define k_nMaxHatEntries 0x3f + 1
|
||||||
|
|
||||||
/* our in memory mapping db between joystick objects and controller mappings*/
|
/* our in memory mapping db between joystick objects and controller mappings*/
|
||||||
|
@ -79,7 +81,7 @@ typedef struct _ControllerMapping_t
|
||||||
{
|
{
|
||||||
SDL_JoystickGUID guid;
|
SDL_JoystickGUID guid;
|
||||||
char *name;
|
char *name;
|
||||||
const char *mapping;
|
char *mapping;
|
||||||
struct _ControllerMapping_t *next;
|
struct _ControllerMapping_t *next;
|
||||||
} ControllerMapping_t;
|
} ControllerMapping_t;
|
||||||
|
|
||||||
|
@ -261,15 +263,28 @@ int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
|
||||||
return 1;
|
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) ) )
|
||||||
|
{
|
||||||
|
return pSupportedController;
|
||||||
|
}
|
||||||
|
pSupportedController = pSupportedController->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function to determine pre-caclulated offset to certain joystick mappings
|
* Helper function to determine pre-caclulated offset to certain joystick mappings
|
||||||
*/
|
*/
|
||||||
ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
|
ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
|
||||||
{
|
{
|
||||||
if ( (device_index < 0) || (device_index >= SDL_NumJoysticks()) ) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SDL_JOYSTICK_DINPUT
|
#ifdef SDL_JOYSTICK_DINPUT
|
||||||
if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
|
if ( SDL_SYS_IsXInputDeviceIndex(device_index) && s_pXInputMapping )
|
||||||
{
|
{
|
||||||
|
@ -279,87 +294,98 @@ ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
|
SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID( device_index );
|
||||||
ControllerMapping_t *pSupportedController = s_pSupportedControllers;
|
return SDL_PrivateGetControllerMappingForGUID(&jGUID);
|
||||||
while ( pSupportedController )
|
|
||||||
{
|
|
||||||
if ( !SDL_memcmp( &jGUID, &pSupportedController->guid, sizeof(jGUID) ) )
|
|
||||||
{
|
|
||||||
return pSupportedController;
|
|
||||||
}
|
|
||||||
pSupportedController = pSupportedController->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* map_StringForControllerAxis[] = {
|
||||||
|
"leftx",
|
||||||
|
"lefty",
|
||||||
|
"rightx",
|
||||||
|
"righty",
|
||||||
|
"lefttrigger",
|
||||||
|
"righttrigger",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* convert a string to its enum equivalent
|
* convert a string to its enum equivalent
|
||||||
*/
|
*/
|
||||||
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
|
SDL_GameControllerAxis SDL_GameControllerGetAxisFromString( const char *pchString )
|
||||||
{
|
{
|
||||||
|
int entry;
|
||||||
if ( !pchString || !pchString[0] )
|
if ( !pchString || !pchString[0] )
|
||||||
return SDL_CONTROLLER_AXIS_INVALID;
|
return SDL_CONTROLLER_AXIS_INVALID;
|
||||||
|
|
||||||
if ( !SDL_strcasecmp( pchString, "leftx" ) )
|
for ( entry = 0; map_StringForControllerAxis[entry]; ++entry)
|
||||||
return SDL_CONTROLLER_AXIS_LEFTX;
|
{
|
||||||
else if ( !SDL_strcasecmp( pchString, "lefty" ) )
|
if ( !SDL_strcasecmp( pchString, map_StringForControllerAxis[entry] ) )
|
||||||
return SDL_CONTROLLER_AXIS_LEFTY;
|
return entry;
|
||||||
else if ( !SDL_strcasecmp( pchString, "rightx" ) )
|
}
|
||||||
return SDL_CONTROLLER_AXIS_RIGHTX;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "righty" ) )
|
|
||||||
return SDL_CONTROLLER_AXIS_RIGHTY;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "lefttrigger" ) )
|
|
||||||
return SDL_CONTROLLER_AXIS_TRIGGERLEFT;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "righttrigger" ) )
|
|
||||||
return SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
|
|
||||||
else
|
|
||||||
return SDL_CONTROLLER_AXIS_INVALID;
|
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
|
* convert a string to its enum equivalent
|
||||||
*/
|
*/
|
||||||
SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
|
SDL_GameControllerButton SDL_GameControllerGetButtonFromString( const char *pchString )
|
||||||
{
|
{
|
||||||
|
int entry;
|
||||||
if ( !pchString || !pchString[0] )
|
if ( !pchString || !pchString[0] )
|
||||||
return SDL_CONTROLLER_BUTTON_INVALID;
|
return SDL_CONTROLLER_BUTTON_INVALID;
|
||||||
|
|
||||||
if ( !SDL_strcasecmp( pchString, "a" ) )
|
for ( entry = 0; map_StringForControllerButton[entry]; ++entry)
|
||||||
return SDL_CONTROLLER_BUTTON_A;
|
{
|
||||||
else if ( !SDL_strcasecmp( pchString, "b" ) )
|
if ( !SDL_strcasecmp( pchString, map_StringForControllerButton[entry] ) )
|
||||||
return SDL_CONTROLLER_BUTTON_B;
|
return entry;
|
||||||
else if ( !SDL_strcasecmp( pchString, "x" ) )
|
}
|
||||||
return SDL_CONTROLLER_BUTTON_X;
|
return SDL_CONTROLLER_BUTTON_INVALID;
|
||||||
else if ( !SDL_strcasecmp( pchString, "y" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_Y;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "start" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_START;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "guide" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_GUIDE;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "back" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_BACK;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "dpup" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_DPAD_UP;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "dpdown" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_DPAD_DOWN;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "dpleft" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_DPAD_LEFT;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "dpright" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "leftshoulder" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "rightshoulder" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "leftstick" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_LEFTSTICK;
|
|
||||||
else if ( !SDL_strcasecmp( pchString, "rightstick" ) )
|
|
||||||
return SDL_CONTROLLER_BUTTON_RIGHTSTICK;
|
|
||||||
else
|
|
||||||
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
|
* given a controller button name and a joystick name update our mapping structure with it
|
||||||
|
@ -602,7 +628,7 @@ char *SDL_PrivateGetControllerNameFromMappingString( const char *pMapping )
|
||||||
/*
|
/*
|
||||||
* grab the button mapping string from a mapping string
|
* grab the button mapping string from a mapping string
|
||||||
*/
|
*/
|
||||||
const char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
|
char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMapping )
|
||||||
{
|
{
|
||||||
const char *pFirstComma, *pSecondComma;
|
const char *pFirstComma, *pSecondComma;
|
||||||
|
|
||||||
|
@ -614,9 +640,126 @@ const char *SDL_PrivateGetControllerMappingFromMappingString( const char *pMappi
|
||||||
if ( !pSecondComma )
|
if ( !pSecondComma )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return pSecondComma + 1; /* mapping is everything after the 3rd comma, no need to malloc it */
|
return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add or update an entry into the Mappings Database
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
SDL_GameControllerAddMapping( const char *mappingString )
|
||||||
|
{
|
||||||
|
char *pchGUID;
|
||||||
|
char *pchName;
|
||||||
|
char *pchMapping;
|
||||||
|
SDL_JoystickGUID jGUID;
|
||||||
|
ControllerMapping_t *pControllerMapping;
|
||||||
|
#ifdef SDL_JOYSTICK_DINPUT
|
||||||
|
SDL_bool is_xinput_mapping = SDL_FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( mappingString );
|
||||||
|
if (!pchGUID) return -1;
|
||||||
|
#ifdef SDL_JOYSTICK_DINPUT
|
||||||
|
if ( !SDL_strcasecmp( pchGUID, "xinput" ) ) {
|
||||||
|
is_xinput_mapping = SDL_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
SDL_free(pchGUID);
|
||||||
|
|
||||||
|
jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
|
||||||
|
|
||||||
|
pControllerMapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
|
||||||
|
|
||||||
|
pchName = SDL_PrivateGetControllerNameFromMappingString( mappingString );
|
||||||
|
if (!pchName) return -1;
|
||||||
|
|
||||||
|
pchMapping = SDL_PrivateGetControllerMappingFromMappingString( mappingString );
|
||||||
|
if (!pchMapping) {
|
||||||
|
SDL_free( pchName );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else {
|
||||||
|
pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
|
||||||
|
if (!pControllerMapping) {
|
||||||
|
SDL_OutOfMemory();
|
||||||
|
SDL_free( pchName );
|
||||||
|
SDL_free( pchMapping );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#ifdef SDL_JOYSTICK_DINPUT
|
||||||
|
if ( is_xinput_mapping )
|
||||||
|
{
|
||||||
|
s_pXInputMapping = pControllerMapping;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
pControllerMapping->guid = jGUID;
|
||||||
|
pControllerMapping->name = pchName;
|
||||||
|
pControllerMapping->mapping = pchMapping;
|
||||||
|
pControllerMapping->next = s_pSupportedControllers;
|
||||||
|
s_pSupportedControllers = 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 );
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
return SDL_GameControllerMappingForGUID( gamecontroller->mapping.guid );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the game controller system, mostly load our DB of controller config mappings
|
* Initialize the game controller system, mostly load our DB of controller config mappings
|
||||||
|
@ -630,36 +773,7 @@ SDL_GameControllerInit(void)
|
||||||
pMappingString = s_ControllerMappings[i];
|
pMappingString = s_ControllerMappings[i];
|
||||||
while ( pMappingString )
|
while ( pMappingString )
|
||||||
{
|
{
|
||||||
ControllerMapping_t *pControllerMapping;
|
SDL_GameControllerAddMapping( pMappingString );
|
||||||
char *pchGUID;
|
|
||||||
char *pchName;
|
|
||||||
const char *pchMapping;
|
|
||||||
pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
|
|
||||||
if ( !pControllerMapping )
|
|
||||||
{
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( pMappingString );
|
|
||||||
pchName = SDL_PrivateGetControllerNameFromMappingString( pMappingString );
|
|
||||||
pchMapping = SDL_PrivateGetControllerMappingFromMappingString( pMappingString );
|
|
||||||
if ( pchGUID && pchName )
|
|
||||||
{
|
|
||||||
#ifdef SDL_JOYSTICK_DINPUT
|
|
||||||
if ( !SDL_strcasecmp( pchGUID, "xinput" ) )
|
|
||||||
{
|
|
||||||
s_pXInputMapping = pControllerMapping;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
pControllerMapping->guid = SDL_JoystickGetGUIDFromString( pchGUID );
|
|
||||||
pControllerMapping->name = pchName;
|
|
||||||
pControllerMapping->mapping = pchMapping;
|
|
||||||
pControllerMapping->next = s_pSupportedControllers;
|
|
||||||
s_pSupportedControllers = pControllerMapping;
|
|
||||||
|
|
||||||
SDL_free( pchGUID );
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
pMappingString = s_ControllerMappings[i];
|
pMappingString = s_ControllerMappings[i];
|
||||||
|
@ -671,54 +785,25 @@ SDL_GameControllerInit(void)
|
||||||
if ( hint && hint[0] )
|
if ( hint && hint[0] )
|
||||||
{
|
{
|
||||||
int nchHints = SDL_strlen( hint );
|
int nchHints = SDL_strlen( hint );
|
||||||
char *pUserMappings = SDL_malloc( nchHints + 1 ); /* FIXME: memory leak, but we can't free it in this function because pchMapping below points into this memory */
|
char *pUserMappings = SDL_malloc( nchHints + 1 );
|
||||||
SDL_memcpy( pUserMappings, hint, nchHints + 1 );
|
char *pTempMappings = pUserMappings;
|
||||||
|
SDL_memcpy( pUserMappings, hint, nchHints );
|
||||||
while ( pUserMappings )
|
while ( pUserMappings )
|
||||||
{
|
{
|
||||||
char *pchGUID;
|
|
||||||
char *pchName;
|
|
||||||
const char *pchMapping;
|
|
||||||
char *pchNewLine = NULL;
|
char *pchNewLine = NULL;
|
||||||
ControllerMapping_t *pControllerMapping;
|
|
||||||
|
|
||||||
pchNewLine = SDL_strchr( pUserMappings, '\n' );
|
pchNewLine = SDL_strchr( pUserMappings, '\n' );
|
||||||
if ( pchNewLine )
|
if ( pchNewLine )
|
||||||
*pchNewLine = '\0';
|
*pchNewLine = '\0';
|
||||||
|
|
||||||
pControllerMapping = SDL_malloc( sizeof(*pControllerMapping) );
|
SDL_GameControllerAddMapping( pUserMappings );
|
||||||
if ( !pControllerMapping )
|
|
||||||
{
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pchGUID = SDL_PrivateGetControllerGUIDFromMappingString( pUserMappings );
|
|
||||||
pchName = SDL_PrivateGetControllerNameFromMappingString( pUserMappings );
|
|
||||||
pchMapping = SDL_PrivateGetControllerMappingFromMappingString( pUserMappings );
|
|
||||||
|
|
||||||
if ( pchGUID && pchName )
|
|
||||||
{
|
|
||||||
#ifdef SDL_JOYSTICK_DINPUT
|
|
||||||
if ( !SDL_strcasecmp( pchGUID, "xinput" ) )
|
|
||||||
{
|
|
||||||
s_pXInputMapping = pControllerMapping;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pControllerMapping->guid = SDL_JoystickGetGUIDFromString( pchGUID );
|
|
||||||
pControllerMapping->name = pchName;
|
|
||||||
pControllerMapping->mapping = pchMapping;
|
|
||||||
pControllerMapping->next = s_pSupportedControllers;
|
|
||||||
s_pSupportedControllers = pControllerMapping;
|
|
||||||
|
|
||||||
SDL_free( pchGUID );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( pchNewLine )
|
if ( pchNewLine )
|
||||||
pUserMappings = pchNewLine + 1;
|
pUserMappings = pchNewLine + 1;
|
||||||
else
|
else
|
||||||
pUserMappings = NULL;
|
pUserMappings = NULL;
|
||||||
}
|
}
|
||||||
|
SDL_free(pTempMappings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1133,7 +1218,7 @@ SDL_GameControllerEventState(int state)
|
||||||
#else
|
#else
|
||||||
const Uint32 event_list[] = {
|
const Uint32 event_list[] = {
|
||||||
SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP,
|
SDL_CONTROLLERAXISMOTION, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP,
|
||||||
SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED,
|
SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_CONTROLLERDEVICEREMAPPED,
|
||||||
};
|
};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue