Added SDL_ReloadGamepadMappings() to reset the SDL gamepad mappings
parent
75e7a6fcfa
commit
9db2cb3513
|
@ -213,6 +213,18 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromRW(SDL_RWops *src, int fre
|
||||||
*/
|
*/
|
||||||
extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromFile(const char *file);
|
extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromFile(const char *file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reinitialize the SDL mapping database to its initial state.
|
||||||
|
*
|
||||||
|
* This will generate gamepad events as needed if device mappings change.
|
||||||
|
*
|
||||||
|
* \returns 0 on success or a negative error code on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*/
|
||||||
|
extern DECLSPEC int SDLCALL SDL_ReloadGamepadMappings(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of mappings installed.
|
* Get the number of mappings installed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -878,6 +878,7 @@ SDL3_0.0.0 {
|
||||||
SDL_wcsnlen;
|
SDL_wcsnlen;
|
||||||
SDL_strnlen;
|
SDL_strnlen;
|
||||||
SDL_AddGamepadMappingsFromFile;
|
SDL_AddGamepadMappingsFromFile;
|
||||||
|
SDL_ReloadGamepadMappings;
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -904,3 +904,4 @@
|
||||||
#define SDL_wcsnlen SDL_wcsnlen_REAL
|
#define SDL_wcsnlen SDL_wcsnlen_REAL
|
||||||
#define SDL_strnlen SDL_strnlen_REAL
|
#define SDL_strnlen SDL_strnlen_REAL
|
||||||
#define SDL_AddGamepadMappingsFromFile SDL_AddGamepadMappingsFromFile_REAL
|
#define SDL_AddGamepadMappingsFromFile SDL_AddGamepadMappingsFromFile_REAL
|
||||||
|
#define SDL_ReloadGamepadMappings SDL_ReloadGamepadMappings_REAL
|
||||||
|
|
|
@ -949,3 +949,4 @@ SDL_DYNAPI_PROC(SDL_GamepadType,SDL_GetRealGamepadType,(SDL_Gamepad *a),(a),retu
|
||||||
SDL_DYNAPI_PROC(size_t,SDL_wcsnlen,(const wchar_t *a, size_t b),(a,b),return)
|
SDL_DYNAPI_PROC(size_t,SDL_wcsnlen,(const wchar_t *a, size_t b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(size_t,SDL_strnlen,(const char *a, size_t b),(a,b),return)
|
SDL_DYNAPI_PROC(size_t,SDL_strnlen,(const char *a, size_t b),(a,b),return)
|
||||||
SDL_DYNAPI_PROC(int,SDL_AddGamepadMappingsFromFile,(const char *a),(a),return)
|
SDL_DYNAPI_PROC(int,SDL_AddGamepadMappingsFromFile,(const char *a),(a),return)
|
||||||
|
SDL_DYNAPI_PROC(int,SDL_ReloadGamepadMappings,(void),(),return)
|
||||||
|
|
|
@ -139,7 +139,7 @@ static SDL_JoystickGUID s_zeroGUID;
|
||||||
static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static GamepadMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static GamepadMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static MappingChangeTracker s_mappingChangeTracker;
|
static MappingChangeTracker *s_mappingChangeTracker SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static char gamepad_magic;
|
static char gamepad_magic;
|
||||||
|
|
||||||
#define _guarded SDL_GUARDED_BY(SDL_joystick_lock)
|
#define _guarded SDL_GUARDED_BY(SDL_joystick_lock)
|
||||||
|
@ -506,52 +506,61 @@ void SDL_GamepadSensorWatcher(Uint64 timestamp, SDL_SensorID sensor, Uint64 sens
|
||||||
|
|
||||||
static void PushMappingChangeTracking(void)
|
static void PushMappingChangeTracking(void)
|
||||||
{
|
{
|
||||||
|
MappingChangeTracker *tracker;
|
||||||
int i, num_joysticks;
|
int i, num_joysticks;
|
||||||
|
|
||||||
SDL_AssertJoysticksLocked();
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
++s_mappingChangeTracker.refcount;
|
if (s_mappingChangeTracker) {
|
||||||
if (s_mappingChangeTracker.refcount > 1) {
|
++s_mappingChangeTracker->refcount;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
s_mappingChangeTracker = (MappingChangeTracker *)SDL_calloc(1, sizeof(*tracker));
|
||||||
|
s_mappingChangeTracker->refcount = 1;
|
||||||
|
|
||||||
/* Save the list of joysticks and associated mappings */
|
/* Save the list of joysticks and associated mappings */
|
||||||
s_mappingChangeTracker.joysticks = SDL_GetJoysticks(&num_joysticks);
|
tracker = s_mappingChangeTracker;
|
||||||
if (!s_mappingChangeTracker.joysticks) {
|
tracker->joysticks = SDL_GetJoysticks(&num_joysticks);
|
||||||
|
if (!tracker->joysticks) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (num_joysticks == 0) {
|
if (num_joysticks == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s_mappingChangeTracker.joystick_mappings = (GamepadMapping_t **)SDL_malloc(num_joysticks * sizeof(*s_mappingChangeTracker.joystick_mappings));
|
tracker->joystick_mappings = (GamepadMapping_t **)SDL_malloc(num_joysticks * sizeof(*tracker->joystick_mappings));
|
||||||
if (!s_mappingChangeTracker.joystick_mappings) {
|
if (!tracker->joystick_mappings) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (i = 0; i < num_joysticks; ++i) {
|
for (i = 0; i < num_joysticks; ++i) {
|
||||||
s_mappingChangeTracker.joystick_mappings[i] = SDL_PrivateGetGamepadMapping(s_mappingChangeTracker.joysticks[i]);
|
tracker->joystick_mappings[i] = SDL_PrivateGetGamepadMapping(tracker->joysticks[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddMappingChangeTracking(GamepadMapping_t *mapping)
|
static void AddMappingChangeTracking(GamepadMapping_t *mapping)
|
||||||
{
|
{
|
||||||
|
MappingChangeTracker *tracker;
|
||||||
int num_mappings;
|
int num_mappings;
|
||||||
GamepadMapping_t **new_mappings;
|
GamepadMapping_t **new_mappings;
|
||||||
|
|
||||||
num_mappings = s_mappingChangeTracker.num_changed_mappings;
|
SDL_AssertJoysticksLocked();
|
||||||
new_mappings = (GamepadMapping_t **)SDL_realloc(s_mappingChangeTracker.changed_mappings, (num_mappings + 1) * sizeof(*new_mappings));
|
|
||||||
|
SDL_assert(s_mappingChangeTracker != NULL);
|
||||||
|
tracker = s_mappingChangeTracker;
|
||||||
|
num_mappings = tracker->num_changed_mappings;
|
||||||
|
new_mappings = (GamepadMapping_t **)SDL_realloc(tracker->changed_mappings, (num_mappings + 1) * sizeof(*new_mappings));
|
||||||
if (new_mappings) {
|
if (new_mappings) {
|
||||||
s_mappingChangeTracker.changed_mappings = new_mappings;
|
tracker->changed_mappings = new_mappings;
|
||||||
s_mappingChangeTracker.changed_mappings[num_mappings] = mapping;
|
tracker->changed_mappings[num_mappings] = mapping;
|
||||||
s_mappingChangeTracker.num_changed_mappings = (num_mappings + 1);
|
tracker->num_changed_mappings = (num_mappings + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool HasMappingChangeTracking(GamepadMapping_t *mapping)
|
static SDL_bool HasMappingChangeTracking(MappingChangeTracker *tracker, GamepadMapping_t *mapping)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < s_mappingChangeTracker.num_changed_mappings; ++i) {
|
for (i = 0; i < tracker->num_changed_mappings; ++i) {
|
||||||
if (s_mappingChangeTracker.changed_mappings[i] == mapping) {
|
if (tracker->changed_mappings[i] == mapping) {
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,26 +570,32 @@ static SDL_bool HasMappingChangeTracking(GamepadMapping_t *mapping)
|
||||||
static void PopMappingChangeTracking(void)
|
static void PopMappingChangeTracking(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
MappingChangeTracker *tracker;
|
||||||
|
|
||||||
SDL_assert(s_mappingChangeTracker.refcount > 0);
|
SDL_AssertJoysticksLocked();
|
||||||
--s_mappingChangeTracker.refcount;
|
|
||||||
if (s_mappingChangeTracker.refcount > 0) {
|
SDL_assert(s_mappingChangeTracker != NULL);
|
||||||
|
tracker = s_mappingChangeTracker;
|
||||||
|
--tracker->refcount;
|
||||||
|
if (tracker->refcount > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
s_mappingChangeTracker = NULL;
|
||||||
|
|
||||||
/* Now check to see what gamepads changed because of the mapping changes */
|
/* Now check to see what gamepads changed because of the mapping changes */
|
||||||
if (s_mappingChangeTracker.joysticks && s_mappingChangeTracker.joystick_mappings) {
|
if (tracker->joysticks && tracker->joystick_mappings) {
|
||||||
for (i = 0; s_mappingChangeTracker.joysticks[i]; ++i) {
|
for (i = 0; tracker->joysticks[i]; ++i) {
|
||||||
SDL_JoystickID joystick = s_mappingChangeTracker.joysticks[i];
|
/* Looking up the new mapping might create one and associate it with the gamepad (and generate events) */
|
||||||
GamepadMapping_t *old_mapping = s_mappingChangeTracker.joystick_mappings[i];
|
SDL_JoystickID joystick = tracker->joysticks[i];
|
||||||
GamepadMapping_t *new_mapping = SDL_PrivateGetGamepadMapping(joystick);
|
|
||||||
SDL_Gamepad *gamepad = SDL_GetGamepadFromInstanceID(joystick);
|
SDL_Gamepad *gamepad = SDL_GetGamepadFromInstanceID(joystick);
|
||||||
|
GamepadMapping_t *new_mapping = SDL_PrivateGetGamepadMapping(joystick);
|
||||||
|
GamepadMapping_t *old_mapping = gamepad ? gamepad->mapping : tracker->joystick_mappings[i];
|
||||||
|
|
||||||
if (new_mapping && !old_mapping) {
|
if (new_mapping && !old_mapping) {
|
||||||
SDL_PrivateGamepadAdded(joystick);
|
SDL_PrivateGamepadAdded(joystick);
|
||||||
} else if (old_mapping && !new_mapping) {
|
} else if (old_mapping && !new_mapping) {
|
||||||
SDL_PrivateGamepadRemoved(joystick);
|
SDL_PrivateGamepadRemoved(joystick);
|
||||||
} else if (old_mapping != new_mapping || HasMappingChangeTracking(new_mapping)) {
|
} else if (old_mapping != new_mapping || HasMappingChangeTracking(tracker, new_mapping)) {
|
||||||
if (gamepad) {
|
if (gamepad) {
|
||||||
SDL_PrivateLoadButtonMapping(gamepad, new_mapping);
|
SDL_PrivateLoadButtonMapping(gamepad, new_mapping);
|
||||||
}
|
}
|
||||||
|
@ -589,19 +604,10 @@ static void PopMappingChangeTracking(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_mappingChangeTracker.joysticks) {
|
SDL_free(tracker->joysticks);
|
||||||
SDL_free(s_mappingChangeTracker.joysticks);
|
SDL_free(tracker->joystick_mappings);
|
||||||
s_mappingChangeTracker.joysticks = NULL;
|
SDL_free(tracker->changed_mappings);
|
||||||
}
|
SDL_free(tracker);
|
||||||
if (s_mappingChangeTracker.joystick_mappings) {
|
|
||||||
SDL_free(s_mappingChangeTracker.joystick_mappings);
|
|
||||||
s_mappingChangeTracker.joystick_mappings = NULL;
|
|
||||||
}
|
|
||||||
if (s_mappingChangeTracker.changed_mappings) {
|
|
||||||
SDL_free(s_mappingChangeTracker.changed_mappings);
|
|
||||||
s_mappingChangeTracker.changed_mappings = NULL;
|
|
||||||
}
|
|
||||||
s_mappingChangeTracker.num_changed_mappings = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
|
@ -1738,6 +1744,28 @@ int SDL_AddGamepadMappingsFromFile(const char *file)
|
||||||
return SDL_AddGamepadMappingsFromRW(SDL_RWFromFile(file, "rb"), 1);
|
return SDL_AddGamepadMappingsFromRW(SDL_RWFromFile(file, "rb"), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SDL_ReloadGamepadMappings(void)
|
||||||
|
{
|
||||||
|
SDL_Gamepad *gamepad;
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
|
||||||
|
PushMappingChangeTracking();
|
||||||
|
|
||||||
|
for (gamepad = SDL_gamepads; gamepad; gamepad = gamepad->next) {
|
||||||
|
AddMappingChangeTracking(gamepad->mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_QuitGamepadMappings();
|
||||||
|
SDL_InitGamepadMappings();
|
||||||
|
|
||||||
|
PopMappingChangeTracking();
|
||||||
|
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add or update an entry into the Mappings Database with a priority
|
* Add or update an entry into the Mappings Database with a priority
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1627,6 +1627,8 @@ static void loop(void *arg)
|
||||||
OpenVirtualGamepad();
|
OpenVirtualGamepad();
|
||||||
} else if (event.key.keysym.sym == SDLK_d) {
|
} else if (event.key.keysym.sym == SDLK_d) {
|
||||||
CloseVirtualGamepad();
|
CloseVirtualGamepad();
|
||||||
|
} else if (event.key.keysym.sym == SDLK_r && (event.key.keysym.mod & SDL_KMOD_CTRL)) {
|
||||||
|
SDL_ReloadGamepadMappings();
|
||||||
} else if (event.key.keysym.sym == SDLK_ESCAPE) {
|
} else if (event.key.keysym.sym == SDLK_ESCAPE) {
|
||||||
done = SDL_TRUE;
|
done = SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue