sdl2-compat: First shot at device indexes for sensors, joysticks and game controllers.

From 0d09049493e7063bda77e1f7f656c2de8cfe151b Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Fri, 30 Dec 2022 23:16:42 -0500
Subject: [PATCH] First shot at device indexes for sensors, joysticks and game
 controllers.

---
 src/sdl2_compat.c | 244 ++++++++++++++++++++++++++++++++++++++++++++--
 src/sdl3_syms.h   |  47 +++++----
 2 files changed, 257 insertions(+), 34 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 9620e19..931f18e 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -105,6 +105,8 @@ typedef SDL_GamepadBinding SDL_GameControllerButtonBind;
 typedef SDL_GamepadButton SDL_GameControllerButton;
 typedef SDL_GamepadType SDL_GameControllerType;
 
+typedef Sint32 SDL2_JoystickID;  /* this became unsigned in SDL3, but we'll just hope we don't overflow. */
+typedef Sint32 SDL2_SensorID;  /* this became unsigned in SDL3, but we'll just hope we don't overflow. */
 
 typedef Sint64 SDL2_GestureID;
 
@@ -775,7 +777,7 @@ typedef struct SDL2_JoyAxisEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Uint8 axis;
     Uint8 padding1;
     Uint8 padding2;
@@ -788,7 +790,7 @@ typedef struct SDL2_JoyBallEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Uint8 ball;
     Uint8 padding1;
     Uint8 padding2;
@@ -801,7 +803,7 @@ typedef struct SDL2_JoyHatEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Uint8 hat;
     Uint8 value;
     Uint8 padding1;
@@ -812,7 +814,7 @@ typedef struct SDL2_JoyButtonEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Uint8 button;
     Uint8 state;
     Uint8 padding1;
@@ -830,7 +832,7 @@ typedef struct SDL2_JoyBatteryEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     SDL_JoystickPowerLevel level;
 } SDL2_JoyBatteryEvent;
 
@@ -838,7 +840,7 @@ typedef struct SDL2_ControllerAxisEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Uint8 axis;
     Uint8 padding1;
     Uint8 padding2;
@@ -851,7 +853,7 @@ typedef struct SDL2_ControllerButtonEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Uint8 button;
     Uint8 state;
     Uint8 padding1;
@@ -869,7 +871,7 @@ typedef struct SDL2_ControllerTouchpadEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Sint32 touchpad;
     Sint32 finger;
     float x;
@@ -881,7 +883,7 @@ typedef struct SDL2_ControllerSensorEvent
 {
     Uint32 type;
     Uint32 timestamp;
-    SDL_JoystickID which;
+    SDL2_JoystickID which;
     Sint32 sensor;
     float data[3];
     Uint64 timestamp_us;
@@ -1045,7 +1047,10 @@ static SDL2_EventFilter EventFilter2 = NULL;
 static void *EventFilterUserData2 = NULL;
 static SDL_mutex *EventWatchListMutex = NULL;
 static EventFilterWrapperData *EventWatchers2 = NULL;
-
+static SDL_JoystickID *joystick_list = NULL;
+static int num_joysticks = 0;
+static SDL_SensorID *sensor_list = NULL;
+static int num_sensors = 0;
 
 /* Functions! */
 
@@ -1348,6 +1353,9 @@ EventFilter3to2(void *userdata, SDL_Event *event3)
         default: break;
     }
 
+    /* !!! FIXME: Deal with device add events using instance ids instead of indices in SDL3. */
+    /* !!! FIXME: Deal with mouse coords becoming floats in SDL3. */
+
     return 1;
 }
 
@@ -2973,6 +2981,222 @@ SDL_JoystickEventState(int state)
     return retval;
 }
 
+
+/* SDL3 dumped the index/instance difference for various devices. */
+
+static SDL_JoystickID GetJoystickInstanceFromIndex(int idx)
+{
+    if ((idx < 0) || (idx >= num_joysticks)) {
+        SDL3_SetError("There are %d joysticks available", num_joysticks);
+        return 0;
+    }
+    return joystick_list[idx];
+}
+
+
+/* !!! FIXME: when we override SDL_Quit(), we need to free/reset joystick_list and friends*/
+/* !!! FIXME: put a mutex on the joystick and sensor lists. Strictly speaking, this will break if you multithread it, but it doesn't have to crash. */
+/* !!! FIXME: we need to override the virtual joystick stuff, since it returns a device index */
+
+DECLSPEC int SDLCALL
+SDL_NumJoysticks(void)
+{
+    SDL3_free(joystick_list);
+    joystick_list = SDL3_GetJoysticks(&num_joysticks);
+    if (joystick_list == NULL) {
+        num_joysticks = 0;
+        return -1;
+    }
+    return num_joysticks;
+}
+
+
+DECLSPEC SDL_JoystickGUID SDLCALL
+SDL_JoystickGetDeviceGUID(int idx)
+{
+    SDL_JoystickGUID guid;
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    if (!jid) {
+        SDL_zero(guid);
+    } else {
+        guid = SDL3_GetJoystickInstanceGUID(jid);
+    }
+    return guid;
+}
+
+DECLSPEC const char* SDLCALL
+SDL_JoystickNameForIndex(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetJoystickInstanceName(jid) : NULL;
+}
+
+DECLSPEC SDL_Joystick* SDLCALL
+SDL_JoystickOpen(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_OpenJoystick(jid) : NULL;
+}
+
+DECLSPEC Uint16 SDLCALL
+SDL_JoystickGetDeviceVendor(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetJoystickInstanceVendor(jid) : 0;
+}
+
+DECLSPEC Uint16 SDLCALL
+SDL_JoystickGetDeviceProduct(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetJoystickInstanceProduct(jid) : 0;
+}
+
+DECLSPEC Uint16 SDLCALL
+SDL_JoystickGetDeviceProductVersion(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetJoystickInstanceProductVersion(jid) : 0;
+}
+
+DECLSPEC SDL_JoystickType SDLCALL
+SDL_JoystickGetDeviceType(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetJoystickInstanceType(jid) : SDL_JOYSTICK_TYPE_UNKNOWN;
+}
+
+DECLSPEC SDL2_JoystickID SDLCALL
+SDL_JoystickGetDeviceInstanceID(int idx)
+{
+    /* this counts on a Uint32 not overflowing an Sint32. */
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return (SDL2_JoystickID) (jid ? jid : -1);
+}
+
+DECLSPEC int SDLCALL
+SDL_JoystickGetDevicePlayerIndex(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetJoystickInstancePlayerIndex(jid) : -1;
+}
+
+DECLSPEC SDL_bool SDLCALL
+SDL_JoystickIsVirtual(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_IsJoystickVirtual(jid) : SDL_FALSE;
+}
+
+DECLSPEC const char* SDLCALL
+SDL_JoystickPathForIndex(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetJoystickInstancePath(jid) : NULL;
+}
+
+DECLSPEC char* SDLCALL
+SDL_GameControllerMappingForDeviceIndex(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetGamepadInstanceMapping(jid) : NULL;
+}
+
+DECLSPEC SDL_bool SDLCALL
+SDL_IsGameController(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_IsGamepad(jid) : SDL_FALSE;
+}
+
+DECLSPEC const char* SDLCALL
+SDL_GameControllerNameForIndex(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetGamepadInstanceName(jid) : NULL;
+}
+
+DECLSPEC SDL_GameController* SDLCALL
+SDL_GameControllerOpen(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_OpenGamepad(jid) : NULL;
+}
+
+DECLSPEC SDL_GameControllerType SDLCALL
+SDL_GameControllerTypeForIndex(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetGamepadInstanceType(jid) : SDL_GAMEPAD_TYPE_UNKNOWN;
+}
+
+DECLSPEC const char* SDLCALL
+SDL_GameControllerPathForIndex(int idx)
+{
+    const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
+    return jid ? SDL3_GetGamepadInstancePath(jid) : NULL;
+}
+
+
+/* !!! FIXME: when we override SDL_Quit(), we need to free/reset sensor_list */
+
+static SDL_SensorID GetSensorInstanceFromIndex(int idx)
+{
+    if ((idx < 0) || (idx >= num_sensors)) {
+        SDL3_SetError("There are %d sensors available", num_sensors);
+        return 0;
+    }
+    return sensor_list[idx];
+}
+
+DECLSPEC int SDLCALL
+SDL_NumSensors(void)
+{
+    SDL3_free(sensor_list);
+    sensor_list = SDL3_GetSensors(&num_sensors);
+    if (sensor_list == NULL) {
+        num_sensors = 0;
+        return -1;
+    }
+    return num_sensors;
+}
+
+DECLSPEC const char* SDLCALL
+SDL_SensorGetDeviceName(int idx)
+{
+    const SDL_SensorID sid = GetSensorInstanceFromIndex(idx);
+    return sid ? SDL3_GetSensorInstanceName(sid) : NULL;
+}
+
+DECLSPEC SDL_SensorType SDLCALL
+SDL_SensorGetDeviceType(int idx)
+{
+    const SDL_SensorID sid = GetSensorInstanceFromIndex(idx);
+    return sid ? SDL3_GetSensorInstanceType(sid) : SDL_SENSOR_INVALID;
+}
+
+DECLSPEC int SDLCALL
+SDL_SensorGetDeviceNonPortableType(int idx)
+{
+    const SDL_SensorID sid = GetSensorInstanceFromIndex(idx);
+    return sid ? SDL3_GetSensorInstanceNonPortableType(sid) : -1;
+}
+
+DECLSPEC SDL2_SensorID SDLCALL
+SDL_SensorGetDeviceInstanceID(int idx)
+{
+    /* this counts on a Uint32 not overflowing an Sint32. */
+    const SDL_SensorID sid = GetSensorInstanceFromIndex(idx);
+    return (SDL2_SensorID) (sid ? sid : -1);
+}
+
+DECLSPEC SDL_Sensor* SDLCALL
+SDL_SensorOpen(int idx)
+{
+    const SDL_SensorID sid = GetSensorInstanceFromIndex(idx);
+    return sid ? SDL3_OpenSensor(sid) : NULL;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index a05720d..e256515 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -157,9 +157,6 @@ SDL3_SYM_PASSTHROUGH(char*,GetPrefPath,(const char *a, const char *b),(a,b),retu
 SDL3_SYM_RENAMED(int,GameControllerAddMapping,AddGamepadMapping,(const char *a),(a),return)
 SDL3_SYM_RENAMED(char*,GameControllerMappingForGUID,GetGamepadMappingForGUID,(SDL_JoystickGUID a),(a),return)
 SDL3_SYM_RENAMED(char*,GameControllerMapping,GetGamepadMapping,(SDL_GameController *a),(a),return)
-SDL3_SYM_RENAMED(SDL_bool,IsGameController,IsGamepad,(int a),(a),return)
-SDL3_SYM_RENAMED(const char*,GameControllerNameForIndex,GetGamepadNameForIndex,(int a),(a),return)
-SDL3_SYM_RENAMED(SDL_GameController*,GameControllerOpen,OpenGamepad,(int a),(a),return)
 SDL3_SYM_RENAMED(const char*,GameControllerName,GetGamepadName,(SDL_GameController *a),(a),return)
 SDL3_SYM_RENAMED(SDL_bool,GameControllerGetAttached,GamepadConnected,(SDL_GameController *a),(a),return)
 SDL3_SYM_RENAMED(SDL_Joystick*,GameControllerGetJoystick,GetGamepadJoystick,(SDL_GameController *a),(a),return)
@@ -209,11 +206,7 @@ SDL3_SYM(const char*,GetHint,(const char *a),(a),return)
 SDL3_SYM(void,AddHintCallback,(const char *a, SDL_HintCallback b, void *c),(a,b,c),)
 SDL3_SYM(void,DelHintCallback,(const char *a, SDL_HintCallback b, void *c),(a,b,c),)
 SDL3_SYM_PASSTHROUGH(void,ClearHints,(void),(),)
-SDL3_SYM_RENAMED(int,NumJoysticks,GetNumJoysticks,(void),(),return)
-SDL3_SYM_RENAMED(const char*,JoystickNameForIndex,GetJoystickNameForIndex,(int a),(a),return)
-SDL3_SYM_RENAMED(SDL_Joystick*,JoystickOpen,OpenJoystick,(int a),(a),return)
 SDL3_SYM_RENAMED(const char*,JoystickName,GetJoystickName,(SDL_Joystick *a),(a),return)
-SDL3_SYM_RENAMED(SDL_JoystickGUID,JoystickGetDeviceGUID,GetJoystickDeviceGUID,(int a),(a),return)
 SDL3_SYM_RENAMED(SDL_JoystickGUID,JoystickGetGUID,GetJoystickGUID,(SDL_Joystick *a),(a),return)
 SDL3_SYM_RENAMED(void,JoystickGetGUIDString,GetJoystickGUIDString,(SDL_JoystickGUID a, char *b, int c),(a,b,c),)
 SDL3_SYM_RENAMED(SDL_JoystickGUID,JoystickGetGUIDFromString,GetJoystickGUIDFromString,(const char *a),(a),return)
@@ -612,9 +605,6 @@ SDL3_SYM_RENAMED(SDL_bool,RenderGetIntegerScale,GetRenderIntegerScale,(SDL_Rende
 SDL3_SYM_PASSTHROUGH(Uint32,DequeueAudio,(SDL_AudioDeviceID a, void *b, Uint32 c),(a,b,c),return)
 SDL3_SYM_PASSTHROUGH(void,SetWindowResizable,(SDL_Window *a, SDL_bool b),(a,b),)
 SDL3_SYM(SDL_bool,GetHintBoolean,(const char *a, SDL_bool b),(a,b),return)
-SDL3_SYM_RENAMED(Uint16,JoystickGetDeviceVendor,GetJoystickDeviceVendor,(int a),(a),return)
-SDL3_SYM_RENAMED(Uint16,JoystickGetDeviceProduct,GetJoystickDeviceProduct,(int a),(a),return)
-SDL3_SYM_RENAMED(Uint16,JoystickGetDeviceProductVersion,GetJoystickDeviceProductVersion,(int a),(a),return)
 SDL3_SYM_RENAMED(Uint16,JoystickGetVendor,GetJoystickVendor,(SDL_Joystick *a),(a),return)
 SDL3_SYM_RENAMED(Uint16,JoystickGetProduct,GetJoystickProduct,(SDL_Joystick *a),(a),return)
 SDL3_SYM_RENAMED(Uint16,JoystickGetProductVersion,GetJoystickProductVersion,(SDL_Joystick *a),(a),return)
@@ -625,11 +615,9 @@ SDL3_SYM_PASSTHROUGH(SDL_bool,HasNEON,(void),(),return)
 SDL3_SYM_RENAMED(int,GameControllerNumMappings,GetNumGamepadMappings,(void),(),return)
 SDL3_SYM_RENAMED(char*,GameControllerMappingForIndex,GetGamepadMappingForIndex,(int a),(a),return)
 SDL3_SYM_RENAMED(SDL_bool,JoystickGetAxisInitialState,GetJoystickAxisInitialState,(SDL_Joystick *a, int b, Sint16 *c),(a,b,c),return)
-SDL3_SYM_RENAMED(SDL_JoystickType,JoystickGetDeviceType,GetJoystickDeviceType,(int a),(a),return)
 SDL3_SYM_RENAMED(SDL_JoystickType,JoystickGetType,GetJoystickType,(SDL_Joystick *a),(a),return)
 SDL3_SYM_PASSTHROUGH(void,MemoryBarrierReleaseFunction,(void),(),)
 SDL3_SYM_PASSTHROUGH(void,MemoryBarrierAcquireFunction,(void),(),)
-SDL3_SYM_RENAMED(SDL_JoystickID,JoystickGetDeviceInstanceID,GetJoystickDeviceInstanceID,(int a),(a),return)
 SDL3_SYM_PASSTHROUGH(size_t,utf8strlen,(const char *a),(a),return)
 SDL3_SYM(void*,LoadFile_RW,(SDL_RWops *a, size_t *b, int c),(a,b,c),return)
 SDL3_SYM_PASSTHROUGH(int,wcscmp,(const wchar_t *a, const wchar_t *b),(a,b),return)
@@ -679,7 +667,6 @@ SDL3_SYM_PASSTHROUGH(SDL_bool,IsAndroidTV,(void),(),return)
 #endif
 SDL3_SYM_PASSTHROUGH(double,log10,(double a),(a),return)
 SDL3_SYM_PASSTHROUGH(float,log10f,(float a),(a),return)
-SDL3_SYM_RENAMED(char*,GameControllerMappingForDeviceIndex,GetGamepadMappingForDeviceIndex,(int a),(a),return)
 #ifdef __LINUX__
 SDL3_SYM_PASSTHROUGH(int,LinuxSetThreadPriority,(Sint64 a, int b),(a,b),return)
 #endif
@@ -694,12 +681,6 @@ SDL3_SYM_PASSTHROUGH(float,expf,(float a),(a),return)
 SDL3_SYM_PASSTHROUGH(wchar_t*,wcsdup,(const wchar_t *a),(a),return)
 SDL3_SYM_RENAMED(int,GameControllerRumble,RumbleGamepad,(SDL_GameController *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return)
 SDL3_SYM_RENAMED(int,JoystickRumble,RumbleJoystick,(SDL_Joystick *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return)
-SDL3_SYM_RENAMED(int,NumSensors,GetNumSensors,(void),(),return)
-SDL3_SYM_RENAMED(const char*,SensorGetDeviceName,GetSensorDeviceName,(int a),(a),return)
-SDL3_SYM_RENAMED(SDL_SensorType,SensorGetDeviceType,GetSensorDeviceType,(int a),(a),return)
-SDL3_SYM_RENAMED(int,SensorGetDeviceNonPortableType,GetSensorDeviceNonPortableType,(int a),(a),return)
-SDL3_SYM_RENAMED(SDL_SensorID,SensorGetDeviceInstanceID,GetSensorDeviceInstanceID,(int a),(a),return)
-SDL3_SYM_RENAMED(SDL_Sensor*,SensorOpen,OpenSensor,(int a),(a),return)
 SDL3_SYM_RENAMED(SDL_Sensor*,SensorFromInstanceID,GetSensorFromInstanceID,(SDL_SensorID a),(a),return)
 SDL3_SYM_RENAMED(const char*,SensorGetName,GetSensorName,(SDL_Sensor *a),(a),return)
 SDL3_SYM_RENAMED(SDL_SensorType,SensorGetType,GetSensorType,(SDL_Sensor *a),(a),return)
@@ -718,7 +699,6 @@ SDL3_SYM_PASSTHROUGH(SDL_Thread*,CreateThreadWithStackSize,(SDL_ThreadFunction a
 SDL3_SYM_PASSTHROUGH(SDL_Thread*,CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d),(a,b,c,d),return)
 #endif
 
-SDL3_SYM_RENAMED(int,JoystickGetDevicePlayerIndex,GetJoystickDevicePlayerIndex,(int a),(a),return)
 SDL3_SYM_RENAMED(int,JoystickGetPlayerIndex,GetJoystickPlayerIndex,(SDL_Joystick *a),(a),return)
 SDL3_SYM_RENAMED(int,GameControllerGetPlayerIndex,GetGamepadPlayerIndex,(SDL_GameController *a),(a),return)
 SDL3_SYM_PASSTHROUGH(int,RenderFlush,(SDL_Renderer *a),(a),return)
@@ -753,7 +733,6 @@ SDL3_SYM_PASSTHROUGH(SDL_bool,HasARMSIMD,(void),(),return)
 SDL3_SYM_PASSTHROUGH(char*,strtokr,(char *a, const char *b, char **c),(a,b,c),return)
 SDL3_SYM_PASSTHROUGH(wchar_t*,wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),return)
 SDL3_SYM_PASSTHROUGH(int,wcsncmp,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
-SDL3_SYM_RENAMED(SDL_GameControllerType,GameControllerTypeForIndex,GetGamepadTypeForIndex,(int a),(a),return)
 SDL3_SYM_RENAMED(SDL_GameControllerType,GameControllerGetType,GetGamepadType,(SDL_GameController *a),(a),return)
 SDL3_SYM_RENAMED(SDL_GameController*,GameControllerFromPlayerIndex,GetGamepadFromPlayerIndex,(int a),(a),return)
 SDL3_SYM_RENAMED(void,GameControllerSetPlayerIndex,SetGamepadPlayerIndex,(SDL_GameController *a, int b),(a,b),)
@@ -777,7 +756,6 @@ SDL3_SYM_PASSTHROUGH(int,isupper,(int a),(a),return)
 SDL3_SYM_PASSTHROUGH(int,islower,(int a),(a),return)
 SDL3_SYM_RENAMED(int,JoystickAttachVirtual,AttachVirtualJoystick,(SDL_JoystickType a, int b, int c, int d),(a,b,c,d),return)
 SDL3_SYM_RENAMED(int,JoystickDetachVirtual,DetachVirtualJoystick,(int a),(a),return)
-SDL3_SYM_RENAMED(SDL_bool,JoystickIsVirtual,JoystickVirtual,(int a),(a),return)
 SDL3_SYM_RENAMED(int,JoystickSetVirtualAxis,SetJoystickVirtualAxis,(SDL_Joystick *a, int b, Sint16 c),(a,b,c),return)
 SDL3_SYM_RENAMED(int,JoystickSetVirtualButton,SetJoystickVirtualButton,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
 SDL3_SYM_RENAMED(int,JoystickSetVirtualHat,SetJoystickVirtualHat,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
@@ -900,9 +878,7 @@ SDL3_SYM_RENAMED(SDL_bool,EncloseFPoints,GetRectEnclosingPointsF,(const SDL_FPoi
 SDL3_SYM_RENAMED(SDL_bool,IntersectFRectAndLine,GetRectAndLineIntersectionF,(const SDL_FRect *a, float *b, float *c, float *d, float *e),(a,b,c,d,e),return)
 SDL3_SYM_RENAMED(SDL_Window*,RenderGetWindow,GetRenderWindow,(SDL_Renderer *a),(a),return)
 SDL3_SYM_PASSTHROUGH(void*,bsearch,(const void *a, const void *b, size_t c, size_t d, int (SDLCALL *e)(const void *, const void *)),(a,b,c,d,e),return)
-SDL3_SYM_RENAMED(const char*,GameControllerPathForIndex,GetGamepadPathForIndex,(int a),(a),return)
 SDL3_SYM_RENAMED(const char*,GameControllerPath,GetGamepadPath,(SDL_GameController *a),(a),return)
-SDL3_SYM_RENAMED(const char*,JoystickPathForIndex,GetJoystickPathForIndex,(int a),(a),return)
 SDL3_SYM_RENAMED(const char*,JoystickPath,GetJoystickPath,(SDL_Joystick *a),(a),return)
 SDL3_SYM_RENAMED(int,JoystickAttachVirtualEx,AttachVirtualJoystickEx,(const SDL_VirtualJoystickDesc *a),(a),return)
 SDL3_SYM_RENAMED(Uint16,GameControllerGetFirmwareVersion,GetGamepadFirmwareVersion,(SDL_GameController *a),(a),return)
@@ -943,6 +919,29 @@ SDL3_SYM(SDL_bool,JoystickEventsEnabled,(void),(),return)
 SDL3_SYM(int,ShowCursor,(void),(),return)
 SDL3_SYM(int,HideCursor,(void),(),return)
 SDL3_SYM(SDL_bool,CursorVisible,(void),(),return)
+SDL3_SYM(SDL_JoystickID*,GetJoysticks,(int *a),(a),return)
+SDL3_SYM(SDL_JoystickGUID,GetJoystickInstanceGUID,(SDL_JoystickID a),(a),return)
+SDL3_SYM(const char *,GetJoystickInstanceName,(SDL_JoystickID a),(a),return)
+SDL3_SYM(const char *,GetJoystickInstancePath,(SDL_JoystickID a),(a),return)
+SDL3_SYM(Uint16,GetJoystickInstanceVendor,(SDL_JoystickID a),(a),return)
+SDL3_SYM(Uint16,GetJoystickInstanceProduct,(SDL_JoystickID a),(a),return)
+SDL3_SYM(Uint16,GetJoystickInstanceProductVersion,(SDL_JoystickID a),(a),return)
+SDL3_SYM(SDL_JoystickType,GetJoystickInstanceType,(SDL_JoystickID a),(a),return)
+SDL3_SYM(SDL_bool,IsJoystickVirtual,(SDL_JoystickID a),(a),return)
+SDL3_SYM(int,GetJoystickInstancePlayerIndex,(SDL_JoystickID a),(a),return)
+SDL3_SYM(SDL_JoystickID*,GetGamepads,(int *a),(a),return)
+SDL3_SYM(SDL_Gamepad *,OpenGamepad,(SDL_JoystickID a),(a),return)
+SDL3_SYM(SDL_Joystick *,OpenJoystick,(SDL_JoystickID a),(a),return)
+SDL3_SYM(char *,GetGamepadInstanceMapping,(SDL_JoystickID a),(a),return)
+SDL3_SYM(const char *,GetGamepadInstanceName,(SDL_JoystickID a),(a),return)
+SDL3_SYM(const char *,GetGamepadInstancePath,(SDL_JoystickID a),(a),return)
+SDL3_SYM(SDL_bool,IsGamepad,(SDL_JoystickID a),(a),return)
+SDL3_SYM(SDL_GamepadType,GetGamepadInstanceType,(SDL_JoystickID a),(a),return)
+SDL3_SYM(SDL_SensorID *,GetSensors,(int *a),(a),return)
+SDL3_SYM(const char *,GetSensorInstanceName,(SDL_SensorID a),(a),return)
+SDL3_SYM(SDL_SensorType,GetSensorInstanceType,(SDL_SensorID a),(a),return)
+SDL3_SYM(int,GetSensorInstanceNonPortableType,(SDL_SensorID a),(a),return)
+SDL3_SYM(SDL_Sensor *,OpenSensor,(SDL_SensorID a),(a),return)
 
 #undef SDL3_SYM
 #undef SDL3_SYM_PASSTHROUGH