Keep track of whether a controller was a gamepad

Fixes https://github.com/libsdl-org/SDL/issues/9996
This commit is contained in:
Sam Lantinga 2024-06-09 17:42:27 -07:00
parent 20fccdabf4
commit 4fc68a48f2
4 changed files with 30 additions and 16 deletions

View File

@ -170,9 +170,9 @@ typedef enum SDL_EventType
SDL_EVENT_GAMEPAD_AXIS_MOTION = 0x650, /**< Gamepad axis motion */
SDL_EVENT_GAMEPAD_BUTTON_DOWN, /**< Gamepad button pressed */
SDL_EVENT_GAMEPAD_BUTTON_UP, /**< Gamepad button released */
SDL_EVENT_GAMEPAD_ADDED, /**< A new gamepad has been inserted into the system */
SDL_EVENT_GAMEPAD_REMOVED, /**< An opened gamepad has been removed */
SDL_EVENT_GAMEPAD_REMAPPED, /**< The gamepad mapping was updated */
SDL_EVENT_GAMEPAD_ADDED, /**< A new gamepad has been inserted into the system */
SDL_EVENT_GAMEPAD_REMOVED, /**< A gamepad has been removed */
SDL_EVENT_GAMEPAD_REMAPPED, /**< The gamepad mapping was updated */
SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN, /**< Gamepad touchpad was touched */
SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION, /**< Gamepad touchpad finger was moved */
SDL_EVENT_GAMEPAD_TOUCHPAD_UP, /**< Gamepad touchpad finger was lifted */

View File

@ -31,6 +31,7 @@
#include "usb_ids.h"
#include "hidapi/SDL_hidapi_nintendo.h"
#include "../events/SDL_events_c.h"
#include "../SDL_hashtable.h"
#ifdef SDL_PLATFORM_ANDROID
@ -103,6 +104,7 @@ static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_joystick_lock)
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 MappingChangeTracker *s_mappingChangeTracker SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
static SDL_HashTable *s_gamepadInstanceIDs SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
#define _guarded SDL_GUARDED_BY(SDL_joystick_lock)
@ -561,8 +563,11 @@ static void PopMappingChangeTracking(void)
GamepadMapping_t *old_mapping = gamepad ? gamepad->mapping : tracker->joystick_mappings[i];
if (new_mapping && !old_mapping) {
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick, (const void *)SDL_TRUE);
SDL_PrivateGamepadAdded(joystick);
} else if (old_mapping && !new_mapping) {
SDL_RemoveFromHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick);
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)joystick, (const void *)SDL_FALSE);
SDL_PrivateGamepadRemoved(joystick);
} else if (old_mapping != new_mapping || HasMappingChangeTracking(tracker, new_mapping)) {
if (gamepad) {
@ -2560,10 +2565,20 @@ SDL_bool SDL_IsGamepad(SDL_JoystickID instance_id)
SDL_LockJoysticks();
{
if (SDL_PrivateGetGamepadMapping(instance_id, SDL_TRUE) != NULL) {
retval = SDL_TRUE;
const void *value;
if (SDL_FindInHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)instance_id, &value)) {
retval = (SDL_bool)(uintptr_t)value;
} else {
retval = SDL_FALSE;
if (SDL_PrivateGetGamepadMapping(instance_id, SDL_TRUE) != NULL) {
retval = SDL_TRUE;
} else {
retval = SDL_FALSE;
}
if (!s_gamepadInstanceIDs) {
s_gamepadInstanceIDs = SDL_CreateHashTable(NULL, 4, SDL_HashID, SDL_KeyMatchID, NULL, SDL_FALSE);
}
SDL_InsertIntoHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)instance_id, (void *)(uintptr_t)retval);
}
}
SDL_UnlockJoysticks();
@ -3669,6 +3684,11 @@ void SDL_QuitGamepads(void)
SDL_CloseGamepad(SDL_gamepads);
}
if (s_gamepadInstanceIDs) {
SDL_DestroyHashTable(s_gamepadInstanceIDs);
s_gamepadInstanceIDs = NULL;
}
SDL_UnlockJoysticks();
}

View File

@ -898,7 +898,7 @@ static SDL_bool ShouldAttemptSensorFusion(SDL_Joystick *joystick, SDL_bool *inve
*invert_sensors = SDL_FALSE;
/* The SDL controller sensor API is only available for gamepads (at the moment) */
if (!joystick->is_gamepad) {
if (!SDL_IsGamepad(joystick->instance_id)) {
return SDL_FALSE;
}
@ -1150,8 +1150,6 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
}
}
joystick->is_gamepad = SDL_IsGamepad(instance_id);
/* Get the Steam Input API handle */
info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id);
if (info) {
@ -2135,10 +2133,7 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID instance_id)
}
}
/* FIXME: The driver no longer provides the name and GUID at this point, so we
* don't know whether this was a gamepad. For now always send the event.
*/
if (SDL_TRUE /*SDL_IsGamepad(instance_id)*/) {
if (SDL_IsGamepad(instance_id)) {
SDL_PrivateGamepadRemoved(instance_id);
}
@ -2363,7 +2358,7 @@ static void SendSteamHandleUpdateEvents(void)
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
SDL_bool changed = SDL_FALSE;
if (!joystick->is_gamepad) {
if (!SDL_IsGamepad(joystick->instance_id)) {
continue;
}
@ -3449,7 +3444,7 @@ SDL_JoystickType SDL_GetJoystickType(SDL_Joystick *joystick)
{
CHECK_JOYSTICK_MAGIC(joystick, SDL_JOYSTICK_TYPE_UNKNOWN);
if (joystick->is_gamepad) {
if (SDL_IsGamepad(joystick->instance_id)) {
type = SDL_JOYSTICK_TYPE_GAMEPAD;
}
}

View File

@ -118,7 +118,6 @@ struct SDL_Joystick
Uint64 led_expiration _guarded;
SDL_bool attached _guarded;
SDL_bool is_gamepad _guarded;
SDL_JoystickConnectionState connection_state _guarded;
SDL_PowerState battery_state _guarded;
int battery_percent _guarded;