diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci index 50e17402d..fb27a66f6 100644 --- a/build-scripts/SDL_migration.cocci +++ b/build-scripts/SDL_migration.cocci @@ -1240,21 +1240,11 @@ typedef SDL_GameControllerButton, SDL_GamepadButton; (...) @@ @@ -- SDL_GameControllerMappingForIndex -+ SDL_GetGamepadMappingForIndex - (...) -@@ -@@ - SDL_GameControllerName + SDL_GetGamepadName (...) @@ @@ -- SDL_GameControllerNumMappings -+ SDL_GetNumGamepadMappings - (...) -@@ -@@ - SDL_GameControllerOpen + SDL_OpenGamepad (...) diff --git a/docs/README-migration.md b/docs/README-migration.md index 60de306e7..14d172f76 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -468,9 +468,7 @@ The following functions have been renamed: * SDL_GameControllerIsSensorEnabled() => SDL_GamepadSensorEnabled() * SDL_GameControllerMapping() => SDL_GetGamepadMapping() * SDL_GameControllerMappingForGUID() => SDL_GetGamepadMappingForGUID() -* SDL_GameControllerMappingForIndex() => SDL_GetGamepadMappingForIndex() * SDL_GameControllerName() => SDL_GetGamepadName() -* SDL_GameControllerNumMappings() => SDL_GetNumGamepadMappings() * SDL_GameControllerOpen() => SDL_OpenGamepad() * SDL_GameControllerPath() => SDL_GetGamepadPath() * SDL_GameControllerRumble() => SDL_RumbleGamepad() @@ -490,6 +488,8 @@ The following functions have been removed: * SDL_GameControllerNameForIndex() - replaced with SDL_GetGamepadInstanceName() * SDL_GameControllerPathForIndex() - replaced with SDL_GetGamepadInstancePath() * SDL_GameControllerTypeForIndex() - replaced with SDL_GetGamepadInstanceType() +* SDL_GameControllerNumMappings() - replaced with SDL_GetGamepadMappings() +* SDL_GameControllerMappingForIndex() replaced with SDL_GetGamepadMappings() The following symbols have been renamed: * SDL_CONTROLLER_AXIS_INVALID => SDL_GAMEPAD_AXIS_INVALID diff --git a/include/SDL3/SDL_gamepad.h b/include/SDL3/SDL_gamepad.h index f0bf60e16..6baeaf305 100644 --- a/include/SDL3/SDL_gamepad.h +++ b/include/SDL3/SDL_gamepad.h @@ -311,25 +311,16 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromFile(const char *file); */ extern DECLSPEC int SDLCALL SDL_ReloadGamepadMappings(void); -/** - * Get the number of mappings installed. - * - * \returns the number of mappings. - * - * \since This function is available since SDL 3.0.0. - */ -extern DECLSPEC int SDLCALL SDL_GetNumGamepadMappings(void); - /** * Get the mapping at a particular index. * - * \param mapping_index mapping index - * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if - * the index is out of range. + * \param count On return, set to 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. * * \since This function is available since SDL 3.0.0. */ -extern DECLSPEC char * SDLCALL SDL_GetGamepadMappingForIndex(int mapping_index); +extern DECLSPEC char ** SDLCALL SDL_GetGamepadMappings(int *count); /** * Get the gamepad mapping string for a given GUID. diff --git a/include/SDL3/SDL_oldnames.h b/include/SDL3/SDL_oldnames.h index bfe64d4f5..5e5042d9e 100644 --- a/include/SDL3/SDL_oldnames.h +++ b/include/SDL3/SDL_oldnames.h @@ -235,9 +235,7 @@ #define SDL_GameControllerIsSensorEnabled SDL_GamepadSensorEnabled #define SDL_GameControllerMapping SDL_GetGamepadMapping #define SDL_GameControllerMappingForGUID SDL_GetGamepadMappingForGUID -#define SDL_GameControllerMappingForIndex SDL_GetGamepadMappingForIndex #define SDL_GameControllerName SDL_GetGamepadName -#define SDL_GameControllerNumMappings SDL_GetNumGamepadMappings #define SDL_GameControllerOpen SDL_OpenGamepad #define SDL_GameControllerPath SDL_GetGamepadPath #define SDL_GameControllerRumble SDL_RumbleGamepad @@ -680,9 +678,7 @@ #define SDL_GameControllerMapping SDL_GameControllerMapping_renamed_SDL_GetGamepadMapping #define SDL_GameControllerMappingForDeviceIndex SDL_GameControllerMappingForDeviceIndex_renamed_SDL_GetGamepadMappingForDeviceIndex #define SDL_GameControllerMappingForGUID SDL_GameControllerMappingForGUID_renamed_SDL_GetGamepadMappingForGUID -#define SDL_GameControllerMappingForIndex SDL_GameControllerMappingForIndex_renamed_SDL_GetGamepadMappingForIndex #define SDL_GameControllerName SDL_GameControllerName_renamed_SDL_GetGamepadName -#define SDL_GameControllerNumMappings SDL_GameControllerNumMappings_renamed_SDL_GetNumGamepadMappings #define SDL_GameControllerOpen SDL_GameControllerOpen_renamed_SDL_OpenGamepad #define SDL_GameControllerPath SDL_GameControllerPath_renamed_SDL_GetGamepadPath #define SDL_GameControllerRumble SDL_GameControllerRumble_renamed_SDL_RumbleGamepad diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 519495499..4e8c1cf87 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -189,7 +189,6 @@ SDL3_0.0.0 { SDL_GetGamepadJoystick; SDL_GetGamepadMapping; SDL_GetGamepadMappingForGUID; - SDL_GetGamepadMappingForIndex; SDL_GetGamepadName; SDL_GetGamepadPath; SDL_GetGamepadPlayerIndex; @@ -250,7 +249,6 @@ SDL3_0.0.0 { SDL_GetMouseState; SDL_GetNaturalDisplayOrientation; SDL_GetNumAllocations; - SDL_GetNumGamepadMappings; SDL_GetNumGamepadTouchpadFingers; SDL_GetNumGamepadTouchpads; SDL_GetNumJoystickAxes; @@ -963,6 +961,7 @@ SDL3_0.0.0 { SDL_GetBooleanProperty; SDL_CreateTextureWithProperties; SDL_CreateRendererWithProperties; + SDL_GetGamepadMappings; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 478005db8..8676e4413 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -213,7 +213,6 @@ #define SDL_GetGamepadJoystick SDL_GetGamepadJoystick_REAL #define SDL_GetGamepadMapping SDL_GetGamepadMapping_REAL #define SDL_GetGamepadMappingForGUID SDL_GetGamepadMappingForGUID_REAL -#define SDL_GetGamepadMappingForIndex SDL_GetGamepadMappingForIndex_REAL #define SDL_GetGamepadName SDL_GetGamepadName_REAL #define SDL_GetGamepadPath SDL_GetGamepadPath_REAL #define SDL_GetGamepadPlayerIndex SDL_GetGamepadPlayerIndex_REAL @@ -274,7 +273,6 @@ #define SDL_GetMouseState SDL_GetMouseState_REAL #define SDL_GetNaturalDisplayOrientation SDL_GetNaturalDisplayOrientation_REAL #define SDL_GetNumAllocations SDL_GetNumAllocations_REAL -#define SDL_GetNumGamepadMappings SDL_GetNumGamepadMappings_REAL #define SDL_GetNumGamepadTouchpadFingers SDL_GetNumGamepadTouchpadFingers_REAL #define SDL_GetNumGamepadTouchpads SDL_GetNumGamepadTouchpads_REAL #define SDL_GetNumJoystickAxes SDL_GetNumJoystickAxes_REAL @@ -988,3 +986,4 @@ #define SDL_GetBooleanProperty SDL_GetBooleanProperty_REAL #define SDL_CreateTextureWithProperties SDL_CreateTextureWithProperties_REAL #define SDL_CreateRendererWithProperties SDL_CreateRendererWithProperties_REAL +#define SDL_GetGamepadMappings SDL_GetGamepadMappings_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 17567ae67..5cce83c8a 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -272,7 +272,6 @@ SDL_DYNAPI_PROC(Uint16,SDL_GetGamepadInstanceVendor,(SDL_JoystickID a),(a),retur 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_GetGamepadMappingForIndex,(int a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetGamepadName,(SDL_Gamepad *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetGamepadPath,(SDL_Gamepad *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetGamepadPlayerIndex,(SDL_Gamepad *a),(a),return) @@ -333,7 +332,6 @@ SDL_DYNAPI_PROC(SDL_Window*,SDL_GetMouseFocus,(void),(),return) SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(float *a, float *b),(a,b),return) SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetNaturalDisplayOrientation,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return) -SDL_DYNAPI_PROC(int,SDL_GetNumGamepadMappings,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetNumGamepadTouchpadFingers,(SDL_Gamepad *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetNumGamepadTouchpads,(SDL_Gamepad *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumJoystickAxes,(SDL_Joystick *a),(a),return) @@ -1013,3 +1011,4 @@ SDL_DYNAPI_PROC(int,SDL_SetBooleanProperty,(SDL_PropertiesID a, const char *b, S SDL_DYNAPI_PROC(SDL_bool,SDL_GetBooleanProperty,(SDL_PropertiesID a, const char *b, SDL_bool c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_Texture*,SDL_CreateTextureWithProperties,(SDL_Renderer *a, SDL_PropertiesID b),(a,b),return) SDL_DYNAPI_PROC(SDL_Renderer*,SDL_CreateRendererWithProperties,(SDL_PropertiesID a),(a),return) +SDL_DYNAPI_PROC(char**,SDL_GetGamepadMappings,(int *a),(a),return) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index ec1120db7..8347857e2 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -2002,29 +2002,6 @@ int SDL_AddGamepadMapping(const char *mapping) return retval; } -/* - * Get the number of mappings installed - */ -int SDL_GetNumGamepadMappings(void) -{ - int num_mappings = 0; - - SDL_LockJoysticks(); - { - GamepadMapping_t *mapping; - - for (mapping = s_pSupportedGamepads; mapping; mapping = mapping->next) { - if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) { - continue; - } - ++num_mappings; - } - } - SDL_UnlockJoysticks(); - - return num_mappings; -} - /* * Create a mapping string for a mapping */ @@ -2081,33 +2058,82 @@ static char *CreateMappingString(GamepadMapping_t *mapping, SDL_JoystickGUID gui return pMappingString; } -/* - * Get the mapping at a particular index. - */ -char *SDL_GetGamepadMappingForIndex(int mapping_index) +char **SDL_GetGamepadMappings(int *count) { - char *retval = NULL; + int num_mappings = 0; + char **retval = NULL; + char **mappings = NULL; + + if (count) { + *count = 0; + } SDL_LockJoysticks(); - { - GamepadMapping_t *mapping; - for (mapping = s_pSupportedGamepads; mapping; mapping = mapping->next) { + for (GamepadMapping_t *mapping = s_pSupportedGamepads; mapping; mapping = mapping->next) { + if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) { + continue; + } + num_mappings++; + } + + size_t final_allocation = sizeof (char *); // for the NULL terminator element. + SDL_bool failed = SDL_FALSE; + mappings = (char **) SDL_calloc(num_mappings + 1, sizeof (char *)); + if (!mappings) { + failed = SDL_TRUE; + SDL_OutOfMemory(); + } else { + size_t i = 0; + for (GamepadMapping_t *mapping = s_pSupportedGamepads; mapping; mapping = mapping->next) { if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) { continue; } - if (mapping_index == 0) { - retval = CreateMappingString(mapping, mapping->guid); - break; + + char *mappingstr = CreateMappingString(mapping, mapping->guid); + if (!mappingstr) { + failed = SDL_TRUE; + break; // error string is already set. } - --mapping_index; + + SDL_assert(i < num_mappings); + mappings[i++] = mappingstr; + + final_allocation += SDL_strlen(mappingstr) + 1 + sizeof (char *); } } + SDL_UnlockJoysticks(); - if (!retval) { - SDL_SetError("Mapping not available"); + if (!failed) { + retval = (char **) SDL_malloc(final_allocation); + if (!retval) { + SDL_OutOfMemory(); + } else { + final_allocation -= (sizeof (char *) * num_mappings + 1); + char *strptr = (char *) (retval + (num_mappings + 1)); + for (int i = 0; i < num_mappings; i++) { + retval[i] = strptr; + const size_t slen = SDL_strlcpy(strptr, mappings[i], final_allocation) + 1; + SDL_assert(final_allocation >= slen); + final_allocation -= slen; + strptr += slen; + } + retval[num_mappings] = NULL; + + if (count) { + *count = num_mappings; + } + } } + + if (mappings) { + for (int i = 0; i < num_mappings; i++) { + SDL_free(mappings[i]); + } + SDL_free(mappings); + } + return retval; } diff --git a/test/testcontroller.c b/test/testcontroller.c index e7d7260bc..f6d406e01 100644 --- a/test/testcontroller.c +++ b/test/testcontroller.c @@ -1871,12 +1871,12 @@ static void loop(void *arg) int main(int argc, char *argv[]) { + SDL_bool show_mappings = SDL_FALSE; int i; float content_scale; int screen_width, screen_height; SDL_Rect area; int gamepad_index = -1; - SDL_bool show_mappings = SDL_FALSE; SDLTest_CommonState *state; /* Initialize test framework */ @@ -1937,16 +1937,15 @@ int main(int argc, char *argv[]) SDL_AddGamepadMappingsFromFile("gamecontrollerdb.txt"); if (show_mappings) { + int count = 0; + char **mappings = SDL_GetGamepadMappings(&count); int map_i; SDL_Log("Supported mappings:\n"); - for (map_i = 0; map_i < SDL_GetNumGamepadMappings(); ++map_i) { - char *mapping = SDL_GetGamepadMappingForIndex(map_i); - if (mapping) { - SDL_Log("\t%s\n", mapping); - SDL_free(mapping); - } + 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 */