mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-26 12:27:44 +00:00
The names of joysticks and gamepads are valid after they've been removed
This commit is contained in:
@@ -74,6 +74,7 @@
|
|||||||
|
|
||||||
static bool SDL_gamepads_initialized;
|
static bool SDL_gamepads_initialized;
|
||||||
static SDL_Gamepad *SDL_gamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static SDL_Gamepad *SDL_gamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
|
static SDL_HashTable *SDL_gamepad_names SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
|
|
||||||
// The face button style of a gamepad
|
// The face button style of a gamepad
|
||||||
typedef enum
|
typedef enum
|
||||||
@@ -372,6 +373,45 @@ static void RecenterGamepad(SDL_Gamepad *gamepad)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *SDL_UpdateGamepadNameForID(SDL_JoystickID instance_id)
|
||||||
|
{
|
||||||
|
const char *current_name = NULL;
|
||||||
|
|
||||||
|
GamepadMapping_t *mapping = SDL_PrivateGetGamepadMapping(instance_id, true);
|
||||||
|
if (mapping) {
|
||||||
|
if (SDL_strcmp(mapping->name, "*") == 0) {
|
||||||
|
current_name = SDL_GetJoystickNameForID(instance_id);
|
||||||
|
} else {
|
||||||
|
current_name = mapping->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_gamepad_names) {
|
||||||
|
return SDL_GetPersistentString(current_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *name = NULL;
|
||||||
|
bool found = SDL_FindInHashTable(SDL_gamepad_names, (const void *)(uintptr_t)instance_id, (const void **)&name);
|
||||||
|
if (!current_name) {
|
||||||
|
if (!found) {
|
||||||
|
SDL_SetError("Gamepad %" SDL_PRIu32 " not found", instance_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!name) {
|
||||||
|
// SDL_strdup() failed during insert
|
||||||
|
SDL_OutOfMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name || SDL_strcmp(name, current_name) != 0) {
|
||||||
|
name = SDL_strdup(current_name);
|
||||||
|
SDL_InsertIntoHashTable(SDL_gamepad_names, (const void *)(uintptr_t)instance_id, name, true);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
void SDL_PrivateGamepadAdded(SDL_JoystickID instance_id)
|
void SDL_PrivateGamepadAdded(SDL_JoystickID instance_id)
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
@@ -380,6 +420,8 @@ void SDL_PrivateGamepadAdded(SDL_JoystickID instance_id)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_UpdateGamepadNameForID(instance_id);
|
||||||
|
|
||||||
event.type = SDL_EVENT_GAMEPAD_ADDED;
|
event.type = SDL_EVENT_GAMEPAD_ADDED;
|
||||||
event.common.timestamp = 0;
|
event.common.timestamp = 0;
|
||||||
event.gdevice.which = instance_id;
|
event.gdevice.which = instance_id;
|
||||||
@@ -2969,6 +3011,10 @@ bool SDL_InitGamepads(void)
|
|||||||
|
|
||||||
SDL_gamepads_initialized = true;
|
SDL_gamepads_initialized = true;
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
|
||||||
|
SDL_gamepad_names = SDL_CreateHashTable(0, false, SDL_HashID, SDL_KeyMatchID, SDL_DestroyHashValue, NULL);
|
||||||
|
|
||||||
// Watch for joystick events and fire gamepad ones if needed
|
// Watch for joystick events and fire gamepad ones if needed
|
||||||
SDL_AddEventWatch(SDL_GamepadEventWatcher, NULL);
|
SDL_AddEventWatch(SDL_GamepadEventWatcher, NULL);
|
||||||
|
|
||||||
@@ -2983,6 +3029,8 @@ bool SDL_InitGamepads(void)
|
|||||||
SDL_free(joysticks);
|
SDL_free(joysticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3029,19 +3077,10 @@ SDL_JoystickID *SDL_GetGamepads(int *count)
|
|||||||
|
|
||||||
const char *SDL_GetGamepadNameForID(SDL_JoystickID instance_id)
|
const char *SDL_GetGamepadNameForID(SDL_JoystickID instance_id)
|
||||||
{
|
{
|
||||||
const char *result = NULL;
|
const char *result;
|
||||||
|
|
||||||
SDL_LockJoysticks();
|
SDL_LockJoysticks();
|
||||||
{
|
result = SDL_UpdateGamepadNameForID(instance_id);
|
||||||
GamepadMapping_t *mapping = SDL_PrivateGetGamepadMapping(instance_id, true);
|
|
||||||
if (mapping) {
|
|
||||||
if (SDL_strcmp(mapping->name, "*") == 0) {
|
|
||||||
result = SDL_GetJoystickNameForID(instance_id);
|
|
||||||
} else {
|
|
||||||
result = SDL_GetPersistentString(mapping->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -3212,7 +3251,7 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GAMEPAD_BLACKLIST_END:
|
case GAMEPAD_BLACKLIST_END:
|
||||||
if (SDL_endswith(name, blacklist_word->str)) {
|
if (SDL_endswith(name, blacklist_word->str)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -4298,6 +4337,11 @@ void SDL_QuitGamepads(void)
|
|||||||
SDL_CloseGamepad(SDL_gamepads);
|
SDL_CloseGamepad(SDL_gamepads);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDL_gamepad_names) {
|
||||||
|
SDL_DestroyHashTable(SDL_gamepad_names);
|
||||||
|
SDL_gamepad_names = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ static bool SDL_joystick_being_added;
|
|||||||
static SDL_Joystick *SDL_joysticks SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static SDL_Joystick *SDL_joysticks SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_joystick_lock) = 0;
|
static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_joystick_lock) = 0;
|
||||||
static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
|
static SDL_HashTable *SDL_joystick_names SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static bool SDL_joystick_allows_background_events = false;
|
static bool SDL_joystick_allows_background_events = false;
|
||||||
|
|
||||||
static Uint32 initial_old_xboxone_controllers[] = {
|
static Uint32 initial_old_xboxone_controllers[] = {
|
||||||
@@ -833,6 +834,8 @@ bool SDL_InitJoysticks(void)
|
|||||||
|
|
||||||
SDL_joysticks_initialized = true;
|
SDL_joysticks_initialized = true;
|
||||||
|
|
||||||
|
SDL_joystick_names = SDL_CreateHashTable(0, false, SDL_HashID, SDL_KeyMatchID, SDL_DestroyHashValue, NULL);
|
||||||
|
|
||||||
SDL_LoadVIDPIDList(&old_xboxone_controllers);
|
SDL_LoadVIDPIDList(&old_xboxone_controllers);
|
||||||
SDL_LoadVIDPIDList(&arcadestick_devices);
|
SDL_LoadVIDPIDList(&arcadestick_devices);
|
||||||
SDL_LoadVIDPIDList(&blacklist_devices);
|
SDL_LoadVIDPIDList(&blacklist_devices);
|
||||||
@@ -980,20 +983,52 @@ const SDL_SteamVirtualGamepadInfo *SDL_GetJoystickVirtualGamepadInfoForID(SDL_Jo
|
|||||||
/*
|
/*
|
||||||
* Get the implementation dependent name of a joystick
|
* Get the implementation dependent name of a joystick
|
||||||
*/
|
*/
|
||||||
const char *SDL_GetJoystickNameForID(SDL_JoystickID instance_id)
|
static const char *SDL_UpdateJoystickNameForID(SDL_JoystickID instance_id)
|
||||||
{
|
{
|
||||||
SDL_JoystickDriver *driver;
|
SDL_JoystickDriver *driver;
|
||||||
int device_index;
|
int device_index;
|
||||||
const char *name = NULL;
|
const char *current_name = NULL;
|
||||||
const SDL_SteamVirtualGamepadInfo *info;
|
const SDL_SteamVirtualGamepadInfo *info;
|
||||||
|
|
||||||
SDL_LockJoysticks();
|
|
||||||
info = SDL_GetJoystickVirtualGamepadInfoForID(instance_id);
|
info = SDL_GetJoystickVirtualGamepadInfoForID(instance_id);
|
||||||
if (info) {
|
if (info) {
|
||||||
name = SDL_GetPersistentString(info->name);
|
current_name = info->name;
|
||||||
} else if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
|
} else if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
|
||||||
name = SDL_GetPersistentString(driver->GetDeviceName(device_index));
|
current_name = driver->GetDeviceName(device_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SDL_joystick_names) {
|
||||||
|
return SDL_GetPersistentString(current_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *name = NULL;
|
||||||
|
bool found = SDL_FindInHashTable(SDL_joystick_names, (const void *)(uintptr_t)instance_id, (const void **)&name);
|
||||||
|
if (!current_name) {
|
||||||
|
if (!found) {
|
||||||
|
SDL_SetError("Joystick %" SDL_PRIu32 " not found", instance_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!name) {
|
||||||
|
// SDL_strdup() failed during insert
|
||||||
|
SDL_OutOfMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name || SDL_strcmp(name, current_name) != 0) {
|
||||||
|
name = SDL_strdup(current_name);
|
||||||
|
SDL_InsertIntoHashTable(SDL_joystick_names, (const void *)(uintptr_t)instance_id, name, true);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SDL_GetJoystickNameForID(SDL_JoystickID instance_id)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
name = SDL_UpdateJoystickNameForID(instance_id);
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
@@ -2234,6 +2269,11 @@ void SDL_QuitJoysticks(void)
|
|||||||
|
|
||||||
SDL_QuitGamepadMappings();
|
SDL_QuitGamepadMappings();
|
||||||
|
|
||||||
|
if (SDL_joystick_names) {
|
||||||
|
SDL_DestroyHashTable(SDL_joystick_names);
|
||||||
|
SDL_joystick_names = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_joysticks_quitting = false;
|
SDL_joysticks_quitting = false;
|
||||||
SDL_joysticks_initialized = false;
|
SDL_joysticks_initialized = false;
|
||||||
|
|
||||||
@@ -2343,6 +2383,8 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
|
|||||||
SDL_SetJoystickIDForPlayerIndex(player_index, instance_id);
|
SDL_SetJoystickIDForPlayerIndex(player_index, instance_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_UpdateJoystickNameForID(instance_id);
|
||||||
|
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
|
|||||||
@@ -1811,12 +1811,12 @@ void SDLTest_PrintEvent(const SDL_Event *event)
|
|||||||
event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
|
event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_JOYSTICK_ADDED:
|
case SDL_EVENT_JOYSTICK_ADDED:
|
||||||
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " attached",
|
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " (%s) attached",
|
||||||
event->jdevice.which);
|
event->jdevice.which, SDL_GetJoystickNameForID(event->jdevice.which));
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_JOYSTICK_REMOVED:
|
case SDL_EVENT_JOYSTICK_REMOVED:
|
||||||
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " removed",
|
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " (%s) removed",
|
||||||
event->jdevice.which);
|
event->jdevice.which, SDL_GetJoystickNameForID(event->jdevice.which));
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
||||||
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " axis %d value: %d",
|
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " axis %d value: %d",
|
||||||
@@ -1877,12 +1877,12 @@ void SDLTest_PrintEvent(const SDL_Event *event)
|
|||||||
event->jbattery.which, event->jbattery.percent);
|
event->jbattery.which, event->jbattery.percent);
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_GAMEPAD_ADDED:
|
case SDL_EVENT_GAMEPAD_ADDED:
|
||||||
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " attached",
|
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " (%s) attached",
|
||||||
event->gdevice.which);
|
event->gdevice.which, SDL_GetGamepadNameForID(event->gdevice.which));
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||||
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " removed",
|
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " (%s) removed",
|
||||||
event->gdevice.which);
|
event->gdevice.which, SDL_GetGamepadNameForID(event->gdevice.which));
|
||||||
break;
|
break;
|
||||||
case SDL_EVENT_GAMEPAD_REMAPPED:
|
case SDL_EVENT_GAMEPAD_REMAPPED:
|
||||||
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " mapping changed",
|
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " mapping changed",
|
||||||
|
|||||||
Reference in New Issue
Block a user