From 4dda785c697b6c6b32f6d9d2cad31f6147db1959 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 15 Jul 2024 20:41:46 -0400 Subject: [PATCH] gamepad: Several gamepad mapping functions now follow the SDL_GetStringRule. Reference Issue #10229. --- include/SDL3/SDL_gamepad.h | 23 +++++++++++------------ src/dynapi/SDL_dynapi_procs.h | 8 ++++---- src/joystick/SDL_gamepad.c | 15 ++++++++++----- test/gamepadutils.c | 13 +++++-------- test/testcontroller.c | 10 +++++----- 5 files changed, 35 insertions(+), 34 deletions(-) diff --git a/include/SDL3/SDL_gamepad.h b/include/SDL3/SDL_gamepad.h index dea57ca27..48eda3c2e 100644 --- a/include/SDL3/SDL_gamepad.h +++ b/include/SDL3/SDL_gamepad.h @@ -389,22 +389,20 @@ extern SDL_DECLSPEC int SDLCALL SDL_ReloadGamepadMappings(void); /** * Get the current gamepad mappings. * - * You must free the returned pointer with SDL_free() when you are done with - * it, but you do _not_ free each string in the array. + * The returned pointer follows the SDL_GetStringRule. * * \param count a pointer filled in with the number of mappings returned, can * be NULL. - * \returns an array of the mapping strings, NULL-terminated. Must be freed - * with SDL_free(). Returns NULL on error. + * \returns an array of the mapping strings, NULL-terminated. Returns NULL on error. * * \since This function is available since SDL 3.0.0. */ -extern SDL_DECLSPEC char ** SDLCALL SDL_GetGamepadMappings(int *count); +extern SDL_DECLSPEC const char * const * SDLCALL SDL_GetGamepadMappings(int *count); /** * Get the gamepad mapping string for a given GUID. * - * The returned string must be freed with SDL_free(). + * The returned string follows the SDL_GetStringRule. * * \param guid a structure containing the GUID for which a mapping is desired. * \returns a mapping string or NULL on error; call SDL_GetError() for more @@ -415,12 +413,12 @@ extern SDL_DECLSPEC char ** SDLCALL SDL_GetGamepadMappings(int *count); * \sa SDL_GetJoystickGUIDForID * \sa SDL_GetJoystickGUID */ -extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid); +extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid); /** * Get the current mapping of a gamepad. * - * The returned string must be freed with SDL_free(). + * The returned string follows the SDL_GetStringRule. * * Details about mappings are discussed with SDL_AddGamepadMapping(). * @@ -435,7 +433,7 @@ extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMappingForGUID(SDL_JoystickGUID * \sa SDL_GetGamepadMappingForGUID * \sa SDL_SetGamepadMapping */ -extern SDL_DECLSPEC char * SDLCALL SDL_GetGamepadMapping(SDL_Gamepad *gamepad); +extern SDL_DECLSPEC const char * SDLCALL SDL_GetGamepadMapping(SDL_Gamepad *gamepad); /** * Set the current mapping of a joystick or gamepad. @@ -651,16 +649,17 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetRealGamepadTypeForID(SDL_Joys * * This can be called before any gamepads are opened. * + * The returned string follows the SDL_GetStringRule. + * * \param instance_id the joystick instance ID. - * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if - * no mapping is available. + * \returns the mapping string. Returns NULL if no mapping is available. * * \since This function is available since SDL 3.0.0. * * \sa SDL_GetGamepads * \sa SDL_GetGamepadMapping */ -extern SDL_DECLSPEC char *SDLCALL SDL_GetGamepadMappingForID(SDL_JoystickID instance_id); +extern SDL_DECLSPEC const char *SDLCALL SDL_GetGamepadMappingForID(SDL_JoystickID instance_id); /** * Open a gamepad for use. diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index ac14f04df..2e3f15cef 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -286,10 +286,10 @@ SDL_DYNAPI_PROC(SDL_Gamepad*,SDL_GetGamepadFromPlayerIndex,(int a),(a),return) SDL_DYNAPI_PROC(SDL_JoystickGUID,SDL_GetGamepadGUIDForID,(SDL_JoystickID a),(a),return) SDL_DYNAPI_PROC(SDL_JoystickID,SDL_GetGamepadID,(SDL_Gamepad *a),(a),return) SDL_DYNAPI_PROC(SDL_Joystick*,SDL_GetGamepadJoystick,(SDL_Gamepad *a),(a),return) -SDL_DYNAPI_PROC(char*,SDL_GetGamepadMapping,(SDL_Gamepad *a),(a),return) -SDL_DYNAPI_PROC(char*,SDL_GetGamepadMappingForGUID,(SDL_JoystickGUID a),(a),return) -SDL_DYNAPI_PROC(char*,SDL_GetGamepadMappingForID,(SDL_JoystickID a),(a),return) -SDL_DYNAPI_PROC(char**,SDL_GetGamepadMappings,(int *a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_GetGamepadMapping,(SDL_Gamepad *a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_GetGamepadMappingForGUID,(SDL_JoystickGUID a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_GetGamepadMappingForID,(SDL_JoystickID a),(a),return) +SDL_DYNAPI_PROC(const char * const *,SDL_GetGamepadMappings,(int *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetGamepadName,(SDL_Gamepad *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetGamepadNameForID,(SDL_JoystickID a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetGamepadPath,(SDL_Gamepad *a),(a),return) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index ce9e614d1..cc2f3eceb 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -2125,7 +2125,7 @@ static char *CreateMappingString(GamepadMapping_t *mapping, SDL_JoystickGUID gui return pMappingString; } -char **SDL_GetGamepadMappings(int *count) +const char * const *SDL_GetGamepadMappings(int *count) { int num_mappings = 0; char **retval = NULL; @@ -2198,13 +2198,14 @@ char **SDL_GetGamepadMappings(int *count) SDL_free(mappings); } - return retval; + SDL_FreeLater(retval); + return (const char * const *) retval; } /* * Get the mapping string for this GUID */ -char *SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid) +const char *SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid) { char *retval; @@ -2220,13 +2221,14 @@ char *SDL_GetGamepadMappingForGUID(SDL_JoystickGUID guid) } SDL_UnlockJoysticks(); + SDL_FreeLater(retval); return retval; } /* * Get the mapping string for this device */ -char *SDL_GetGamepadMapping(SDL_Gamepad *gamepad) +const char *SDL_GetGamepadMapping(SDL_Gamepad *gamepad) { char *retval; @@ -2238,6 +2240,7 @@ char *SDL_GetGamepadMapping(SDL_Gamepad *gamepad) } SDL_UnlockJoysticks(); + SDL_FreeLater(retval); return retval; } @@ -2519,7 +2522,7 @@ SDL_GamepadType SDL_GetRealGamepadTypeForID(SDL_JoystickID instance_id) return type; } -char *SDL_GetGamepadMappingForID(SDL_JoystickID instance_id) +const char *SDL_GetGamepadMappingForID(SDL_JoystickID instance_id) { char *retval = NULL; @@ -2534,6 +2537,8 @@ char *SDL_GetGamepadMappingForID(SDL_JoystickID instance_id) } } SDL_UnlockJoysticks(); + + SDL_FreeLater(retval); return retval; } diff --git a/test/gamepadutils.c b/test/gamepadutils.c index f94da4012..887c83fc7 100644 --- a/test/gamepadutils.c +++ b/test/gamepadutils.c @@ -416,13 +416,12 @@ void UpdateGamepadImageFromGamepad(GamepadImage *ctx, SDL_Gamepad *gamepad) } ctx->type = SDL_GetGamepadType(gamepad); - char *mapping = SDL_GetGamepadMapping(gamepad); + const char *mapping = SDL_GetGamepadMapping(gamepad); if (mapping) { if (SDL_strstr(mapping, "SDL_GAMECONTROLLER_USE_BUTTON_LABELS")) { /* Just for display purposes */ ctx->type = SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO; } - SDL_free(mapping); } for (i = 0; i < SDL_GAMEPAD_BUTTON_TOUCHPAD; ++i) { @@ -750,7 +749,7 @@ void SetGamepadDisplayArea(GamepadDisplay *ctx, const SDL_FRect *area) SDL_copyp(&ctx->area, area); } -static SDL_bool GetBindingString(const char *label, char *mapping, char *text, size_t size) +static SDL_bool GetBindingString(const char *label, const char *mapping, char *text, size_t size) { char *key; char *value, *end; @@ -791,7 +790,7 @@ static SDL_bool GetBindingString(const char *label, char *mapping, char *text, s return found; } -static SDL_bool GetButtonBindingString(SDL_GamepadButton button, char *mapping, char *text, size_t size) +static SDL_bool GetButtonBindingString(SDL_GamepadButton button, const char *mapping, char *text, size_t size) { char label[32]; SDL_bool baxy_mapping = SDL_FALSE; @@ -839,7 +838,7 @@ static SDL_bool GetButtonBindingString(SDL_GamepadButton button, char *mapping, } } -static SDL_bool GetAxisBindingString(SDL_GamepadAxis axis, int direction, char *mapping, char *text, size_t size) +static SDL_bool GetAxisBindingString(SDL_GamepadAxis axis, int direction, const char *mapping, char *text, size_t size) { char label[32]; @@ -1022,7 +1021,7 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad) const float arrow_extent = 48.0f; SDL_FRect dst, rect, highlight; Uint8 r, g, b, a; - char *mapping = NULL; + const char *mapping = NULL; SDL_bool has_accel; SDL_bool has_gyro; @@ -1286,8 +1285,6 @@ void RenderGamepadDisplay(GamepadDisplay *ctx, SDL_Gamepad *gamepad) } } } - - SDL_free(mapping); } void DestroyGamepadDisplay(GamepadDisplay *ctx) diff --git a/test/testcontroller.c b/test/testcontroller.c index 7f791e09f..e6820ff88 100644 --- a/test/testcontroller.c +++ b/test/testcontroller.c @@ -973,6 +973,7 @@ static void DelController(SDL_JoystickID id) static void HandleGamepadRemapped(SDL_JoystickID id) { + const char *sdlmapping; char *mapping; int i = FindController(id); @@ -987,7 +988,8 @@ static void HandleGamepadRemapped(SDL_JoystickID id) } /* Get the current mapping */ - mapping = SDL_GetGamepadMapping(controllers[i].gamepad); + sdlmapping = SDL_GetGamepadMapping(controllers[i].gamepad); + mapping = sdlmapping ? SDL_strdup(sdlmapping) : NULL; /* Make sure the mapping has a valid name */ if (mapping && !MappingHasName(mapping)) { @@ -1063,10 +1065,9 @@ static void HandleGamepadAdded(SDL_JoystickID id, SDL_bool verbose) } if (verbose) { - char *mapping = SDL_GetGamepadMapping(gamepad); + const char *mapping = SDL_GetGamepadMapping(gamepad); if (mapping) { SDL_Log("Mapping: %s\n", mapping); - SDL_free(mapping); } } } else { @@ -2053,14 +2054,13 @@ int main(int argc, char *argv[]) if (show_mappings) { int count = 0; - char **mappings = SDL_GetGamepadMappings(&count); + const char * const *mappings = SDL_GetGamepadMappings(&count); int map_i; SDL_Log("Supported mappings:\n"); for (map_i = 0; map_i < count; ++map_i) { SDL_Log("\t%s\n", mappings[map_i]); } SDL_Log("\n"); - SDL_free(mappings); } /* Create a window to display gamepad state */