testcontroller: memory management cleanup
Also saved the guide button for last in the binding flow, since it may not be present on the controller or available from the OSmain
parent
611b3dd1fd
commit
787786bdbc
|
@ -2179,6 +2179,18 @@ static void FreeMappingParts(MappingParts *parts)
|
|||
SDL_zerop(parts);
|
||||
}
|
||||
|
||||
/* Create a new mapping from the parts and free the old mapping and parts */
|
||||
static char *RecreateMapping(MappingParts *parts, char *mapping)
|
||||
{
|
||||
char *new_mapping = JoinMapping(parts);
|
||||
if (new_mapping) {
|
||||
SDL_free(mapping);
|
||||
mapping = new_mapping;
|
||||
}
|
||||
FreeMappingParts(parts);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
static char *GetMappingValue(const char *mapping, const char *key)
|
||||
{
|
||||
int i;
|
||||
|
@ -2200,7 +2212,6 @@ static char *SetMappingValue(char *mapping, const char *key, const char *value)
|
|||
{
|
||||
MappingParts parts;
|
||||
int i;
|
||||
char *new_mapping;
|
||||
char *new_key = NULL;
|
||||
char *new_value = NULL;
|
||||
char **new_keys = NULL;
|
||||
|
@ -2240,11 +2251,7 @@ static char *SetMappingValue(char *mapping, const char *key, const char *value)
|
|||
}
|
||||
|
||||
if (result) {
|
||||
new_mapping = JoinMapping(&parts);
|
||||
if (new_mapping) {
|
||||
SDL_free(mapping);
|
||||
mapping = new_mapping;
|
||||
}
|
||||
mapping = RecreateMapping(&parts, mapping);
|
||||
} else {
|
||||
SDL_free(new_key);
|
||||
SDL_free(new_value);
|
||||
|
@ -2264,7 +2271,7 @@ static char *RemoveMappingKey(char *mapping, const char *key)
|
|||
if (i >= 0) {
|
||||
RemoveMappingValueAt(&parts, i);
|
||||
}
|
||||
return JoinMapping(&parts);
|
||||
return RecreateMapping(&parts, mapping);
|
||||
}
|
||||
|
||||
SDL_bool MappingHasBindings(const char *mapping)
|
||||
|
@ -2323,20 +2330,48 @@ char *GetMappingName(const char *mapping)
|
|||
char *SetMappingName(char *mapping, const char *name)
|
||||
{
|
||||
MappingParts parts;
|
||||
char *new_name;
|
||||
char *new_mapping;
|
||||
char *new_name, *spot;
|
||||
size_t length;
|
||||
|
||||
if (!name) {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/* Remove any leading whitespace */
|
||||
while (*name && SDL_isspace(*name)) {
|
||||
++name;
|
||||
}
|
||||
|
||||
new_name = SDL_strdup(name);
|
||||
if (!new_name) {
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/* Remove any commas, which are field separators in the mapping */
|
||||
length = SDL_strlen(new_name);
|
||||
while ((spot = SDL_strchr(new_name, ',')) != NULL) {
|
||||
SDL_memmove(spot, spot + 1, length - (spot - new_name) - 1);
|
||||
--length;
|
||||
}
|
||||
|
||||
/* Remove any trailing whitespace */
|
||||
while (length > 0 && SDL_isspace(new_name[length - 1])) {
|
||||
--length;
|
||||
}
|
||||
|
||||
/* See if we have anything left */
|
||||
if (length == 0) {
|
||||
SDL_free(new_name);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/* null terminate to cut off anything we've trimmed */
|
||||
new_name[length] = '\0';
|
||||
|
||||
SplitMapping(mapping, &parts);
|
||||
SDL_free(parts.name);
|
||||
parts.name = new_name;
|
||||
new_mapping = JoinMapping(&parts);
|
||||
FreeMappingParts(&parts);
|
||||
return new_mapping;
|
||||
return RecreateMapping(&parts, mapping);
|
||||
}
|
||||
|
||||
char *GetMappingType(const char *mapping)
|
||||
|
@ -2449,5 +2484,5 @@ char *ClearMappingBinding(char *mapping, const char *binding)
|
|||
RemoveMappingValueAt(&parts, i);
|
||||
}
|
||||
}
|
||||
return JoinMapping(&parts);
|
||||
return RecreateMapping(&parts, mapping);
|
||||
}
|
||||
|
|
|
@ -209,18 +209,10 @@ static int StandardizeAxisValue(int nValue)
|
|||
}
|
||||
}
|
||||
|
||||
static void SetGamepadMapping(char *mapping)
|
||||
static void SetAndFreeGamepadMapping(char *mapping)
|
||||
{
|
||||
/* Make sure the mapping has a valid name */
|
||||
if (!MappingHasName(mapping)) {
|
||||
SetMappingName(mapping, SDL_GetJoystickName(controller->joystick));
|
||||
}
|
||||
|
||||
SDL_free(controller->mapping);
|
||||
controller->mapping = mapping;
|
||||
controller->has_bindings = MappingHasBindings(mapping);
|
||||
|
||||
SDL_SetGamepadMapping(controller->id, mapping);
|
||||
SDL_free(mapping);
|
||||
}
|
||||
|
||||
static void SetCurrentBindingElement(int element)
|
||||
|
@ -264,8 +256,8 @@ static void SetNextBindingElement()
|
|||
SDL_GAMEPAD_BUTTON_DPAD_DOWN,
|
||||
SDL_GAMEPAD_BUTTON_DPAD_LEFT,
|
||||
SDL_GAMEPAD_BUTTON_BACK,
|
||||
SDL_GAMEPAD_BUTTON_GUIDE,
|
||||
SDL_GAMEPAD_BUTTON_START,
|
||||
SDL_GAMEPAD_BUTTON_GUIDE,
|
||||
SDL_GAMEPAD_BUTTON_MISC1,
|
||||
SDL_GAMEPAD_ELEMENT_INVALID,
|
||||
|
||||
|
@ -304,7 +296,11 @@ static void CommitBindingElement(const char *binding, SDL_bool force)
|
|||
return;
|
||||
}
|
||||
|
||||
mapping = controller->mapping;
|
||||
if (controller->mapping) {
|
||||
mapping = SDL_strdup(controller->mapping);
|
||||
} else {
|
||||
mapping = NULL;
|
||||
}
|
||||
|
||||
/* If the controller generates multiple events for a single element, pick the best one */
|
||||
if (!force && binding_advance_time) {
|
||||
|
@ -360,7 +356,7 @@ static void CommitBindingElement(const char *binding, SDL_bool force)
|
|||
|
||||
mapping = ClearMappingBinding(mapping, binding);
|
||||
mapping = SetElementBinding(mapping, binding_element, binding);
|
||||
SetGamepadMapping(mapping);
|
||||
SetAndFreeGamepadMapping(mapping);
|
||||
|
||||
if (force) {
|
||||
SetNextBindingElement();
|
||||
|
@ -411,43 +407,22 @@ static void SetDisplayMode(ControllerDisplayMode mode)
|
|||
|
||||
static void CancelMapping(void)
|
||||
{
|
||||
if (backup_mapping) {
|
||||
SetGamepadMapping(backup_mapping);
|
||||
backup_mapping = NULL;
|
||||
}
|
||||
SetAndFreeGamepadMapping(backup_mapping);
|
||||
backup_mapping = NULL;
|
||||
|
||||
SetDisplayMode(CONTROLLER_MODE_TESTING);
|
||||
}
|
||||
|
||||
static void ClearMapping(void)
|
||||
{
|
||||
SetGamepadMapping(NULL);
|
||||
SetAndFreeGamepadMapping(NULL);
|
||||
SetCurrentBindingElement(SDL_GAMEPAD_ELEMENT_INVALID);
|
||||
}
|
||||
|
||||
static void CopyMapping(void)
|
||||
{
|
||||
if (controller && controller->mapping) {
|
||||
char *mapping = controller->mapping;
|
||||
char *wildcard = SDL_strchr(mapping, '*');
|
||||
const char *name = SDL_GetGamepadName(controller->gamepad);
|
||||
if (wildcard && name && *name) {
|
||||
char *text;
|
||||
size_t size;
|
||||
|
||||
/* Personalize the mapping for this controller */
|
||||
*wildcard++ = '\0';
|
||||
size = SDL_strlen(mapping) + SDL_strlen(name) + SDL_strlen(wildcard) + 1;
|
||||
text = SDL_malloc(size);
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
SDL_snprintf(text, size, "%s%s%s", mapping, name, wildcard);
|
||||
SDL_SetClipboardText(text);
|
||||
SDL_free(text);
|
||||
*wildcard = '*';
|
||||
} else {
|
||||
SDL_SetClipboardText(mapping);
|
||||
}
|
||||
SDL_SetClipboardText(controller->mapping);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,7 +432,7 @@ static void PasteMapping(void)
|
|||
char *mapping = SDL_GetClipboardText();
|
||||
if (MappingHasBindings(mapping)) {
|
||||
CancelBinding();
|
||||
SetGamepadMapping(mapping);
|
||||
SetAndFreeGamepadMapping(mapping);
|
||||
} else {
|
||||
/* Not a valid mapping, ignore it */
|
||||
SDL_free(mapping);
|
||||
|
@ -584,6 +559,32 @@ static void SetController(SDL_JoystickID id)
|
|||
}
|
||||
}
|
||||
|
||||
static void HandleGamepadRemapped(SDL_JoystickID id)
|
||||
{
|
||||
char *mapping;
|
||||
int i = FindController(id);
|
||||
|
||||
if (i < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!controllers[i].gamepad) {
|
||||
controllers[i].gamepad = SDL_OpenGamepad(id);
|
||||
}
|
||||
|
||||
/* Get the current mapping */
|
||||
mapping = SDL_GetGamepadMapping(controllers[i].gamepad);
|
||||
|
||||
/* Make sure the mapping has a valid name */
|
||||
if (mapping && !MappingHasName(mapping)) {
|
||||
mapping = SetMappingName(mapping, SDL_GetJoystickName(controllers[i].joystick));
|
||||
}
|
||||
|
||||
SDL_free(controllers[i].mapping);
|
||||
controllers[i].mapping = mapping;
|
||||
controllers[i].has_bindings = MappingHasBindings(mapping);
|
||||
}
|
||||
|
||||
static void AddController(SDL_JoystickID id, SDL_bool verbose)
|
||||
{
|
||||
Controller *new_controllers;
|
||||
|
@ -620,8 +621,6 @@ static void AddController(SDL_JoystickID id, SDL_bool verbose)
|
|||
new_controller->axis_state = (AxisState *)SDL_calloc(new_controller->num_axes, sizeof(*new_controller->axis_state));
|
||||
|
||||
new_controller->gamepad = SDL_OpenGamepad(id);
|
||||
new_controller->mapping = SDL_GetGamepadMapping(new_controller->gamepad);
|
||||
new_controller->has_bindings = MappingHasBindings(new_controller->mapping);
|
||||
|
||||
if (new_controller->gamepad) {
|
||||
SDL_Gamepad *gamepad = new_controller->gamepad;
|
||||
|
@ -670,6 +669,9 @@ static void AddController(SDL_JoystickID id, SDL_bool verbose)
|
|||
} else {
|
||||
SetController(id);
|
||||
}
|
||||
|
||||
/* Update the binding state */
|
||||
HandleGamepadRemapped(id);
|
||||
}
|
||||
|
||||
static void DelController(SDL_JoystickID id)
|
||||
|
@ -714,23 +716,6 @@ static void DelController(SDL_JoystickID id)
|
|||
}
|
||||
}
|
||||
|
||||
static void HandleGamepadRemapped(SDL_JoystickID id)
|
||||
{
|
||||
int i = FindController(id);
|
||||
|
||||
if (i < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!controllers[i].gamepad) {
|
||||
controllers[i].gamepad = SDL_OpenGamepad(id);
|
||||
}
|
||||
if (controllers[i].mapping) {
|
||||
SDL_free(controllers[i].mapping);
|
||||
}
|
||||
controllers[i].mapping = SDL_GetGamepadMapping(controllers[i].gamepad);
|
||||
}
|
||||
|
||||
static Uint16 ConvertAxisToRumble(Sint16 axisval)
|
||||
{
|
||||
/* Only start rumbling if the axis is past the halfway point */
|
||||
|
|
Loading…
Reference in New Issue