sdl2-compat: update after latest SDL3 gamepad changes

From a97a8da1b1bcf08655968eaa0a14186ab5c4817a Mon Sep 17 00:00:00 2001
From: Ozkan Sezer <[EMAIL REDACTED]>
Date: Sun, 16 Jul 2023 18:51:10 +0300
Subject: [PATCH] update after latest SDL3 gamepad changes

---
 src/sdl2_compat.c          | 74 +++++++++++++++++++++++++++++++++++++-
 src/sdl2_compat.h          | 43 ++++++++++++++++++++--
 src/sdl3_include_wrapper.h | 20 +++++------
 src/sdl3_syms.h            |  5 ++-
 4 files changed, 126 insertions(+), 16 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index ab7145c..7868eba 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -5295,11 +5295,59 @@ SDL_GameControllerOpen(int idx)
     return jid ? SDL3_OpenGamepad(jid) : NULL;
 }
 
+static SDL_GameControllerType SDLCALL
+SDL2COMPAT_GetGamepadInstanceType(const SDL_JoystickID jid)
+{
+    const Uint16 vid = SDL3_GetJoystickInstanceVendor(jid);
+    const Uint16 pid = SDL3_GetJoystickInstanceProduct(jid);
+    if (SDL3_IsJoystickVirtual(jid)) {
+        return SDL_CONTROLLER_TYPE_VIRTUAL;
+    }
+    if ((vid == 0x1949 && pid == 0x0419) ||
+        (vid == 0x0171 && pid == 0x0419)) {
+        return SDL_CONTROLLER_TYPE_AMAZON_LUNA;
+    }
+    if (vid == 0x18d1 && pid == 0x9400) {
+        return SDL_CONTROLLER_TYPE_GOOGLE_STADIA;
+    }
+    if (vid == 0x0955 && (pid == 0x7210 || pid == 0x7214)) {
+        return SDL_CONTROLLER_TYPE_NVIDIA_SHIELD;
+    }
+    switch (SDL3_GetGamepadInstanceType(jid)) {
+    case SDL_GAMEPAD_TYPE_XBOX360:
+        return SDL_CONTROLLER_TYPE_XBOX360;
+    case SDL_GAMEPAD_TYPE_XBOXONE:
+        return SDL_CONTROLLER_TYPE_XBOXONE;
+    case SDL_GAMEPAD_TYPE_PS3:
+        return SDL_CONTROLLER_TYPE_PS3;
+    case SDL_GAMEPAD_TYPE_PS4:
+        return SDL_CONTROLLER_TYPE_PS4;
+    case SDL_GAMEPAD_TYPE_PS5:
+        return SDL_CONTROLLER_TYPE_PS5;
+    case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
+        return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
+    case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT:
+        return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT;
+    case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT:
+        return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT;
+    case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR:
+        return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR;
+    default:
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
+    }
+}
+
+DECLSPEC SDL_GameControllerType SDLCALL
+SDL_GameControllerGetType(SDL_GameController *controller)
+{
+    return SDL2COMPAT_GetGamepadInstanceType(SDL3_GetGamepadInstanceID(controller));
+}
+
 DECLSPEC SDL_GameControllerType SDLCALL
 SDL_GameControllerTypeForIndex(int idx)
 {
     const SDL_JoystickID jid = GetJoystickInstanceFromIndex(idx);
-    return jid ? SDL3_GetGamepadInstanceType(jid) : SDL_GAMEPAD_TYPE_UNKNOWN;
+    return jid ? SDL2COMPAT_GetGamepadInstanceType(jid) : SDL_CONTROLLER_TYPE_UNKNOWN;
 }
 
 DECLSPEC const char* SDLCALL
@@ -5309,6 +5357,30 @@ SDL_GameControllerPathForIndex(int idx)
     return jid ? SDL3_GetGamepadInstancePath(jid) : NULL;
 }
 
+DECLSPEC SDL_GameControllerButtonBind SDLCALL
+SDL_GameControllerGetBindForAxis(SDL_GameController *controller,
+                                 SDL_GameControllerAxis axis)
+{
+    SDL_GameControllerButtonBind bind;
+    /* FIXME */
+    (void) controller;
+    (void) axis;
+    SDL3_zero(bind);
+    return bind;
+}
+
+DECLSPEC SDL_GameControllerButtonBind SDLCALL
+SDL_GameControllerGetBindForButton(SDL_GameController *controller,
+                                   SDL_GameControllerButton button)
+{
+    SDL_GameControllerButtonBind bind;
+    /* FIXME */
+    (void) controller;
+    (void) button;
+    SDL3_zero(bind);
+    return bind;
+}
+
 DECLSPEC int SDLCALL
 SDL_JoystickAttachVirtual(SDL_JoystickType type, int naxes, int nbuttons, int nhats)
 {
diff --git a/src/sdl2_compat.h b/src/sdl2_compat.h
index e4abf0e..80f77db 100644
--- a/src/sdl2_compat.h
+++ b/src/sdl2_compat.h
@@ -30,11 +30,50 @@ typedef SDL_Condition SDL_cond;
 typedef SDL_Mutex SDL_mutex;
 typedef SDL_Semaphore SDL_sem;
 
+typedef enum
+{
+    SDL_CONTROLLER_BINDTYPE_NONE = 0,
+    SDL_CONTROLLER_BINDTYPE_BUTTON,
+    SDL_CONTROLLER_BINDTYPE_AXIS,
+    SDL_CONTROLLER_BINDTYPE_HAT
+} SDL_GameControllerBindType;
+
+typedef struct SDL_GameControllerButtonBind
+{
+    SDL_GameControllerBindType bindType;
+    union
+    {
+        int button;
+        int axis;
+        struct {
+            int hat;
+            int hat_mask;
+        } hat;
+    } value;
+
+} SDL_GameControllerButtonBind;
+
+typedef enum
+{
+    SDL_CONTROLLER_TYPE_UNKNOWN = 0,
+    SDL_CONTROLLER_TYPE_XBOX360,
+    SDL_CONTROLLER_TYPE_XBOXONE,
+    SDL_CONTROLLER_TYPE_PS3,
+    SDL_CONTROLLER_TYPE_PS4,
+    SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO,
+    SDL_CONTROLLER_TYPE_VIRTUAL,
+    SDL_CONTROLLER_TYPE_PS5,
+    SDL_CONTROLLER_TYPE_AMAZON_LUNA,
+    SDL_CONTROLLER_TYPE_GOOGLE_STADIA,
+    SDL_CONTROLLER_TYPE_NVIDIA_SHIELD,
+    SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT,
+    SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT,
+    SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR
+} SDL_GameControllerType;
+
 typedef SDL_Gamepad SDL_GameController;  /* since they're opaque types, for simplicity we just typedef it here and use the old types in sdl3_syms.h */
 typedef SDL_GamepadAxis SDL_GameControllerAxis;
-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. */
diff --git a/src/sdl3_include_wrapper.h b/src/sdl3_include_wrapper.h
index b49fcd7..287dfd6 100644
--- a/src/sdl3_include_wrapper.h
+++ b/src/sdl3_include_wrapper.h
@@ -215,8 +215,6 @@
 #define SDL_GetGamepadAppleSFSymbolsNameForButton IGNORE_THIS_VERSION_OF_SDL_GetGamepadAppleSFSymbolsNameForButton
 #define SDL_GetGamepadAxis IGNORE_THIS_VERSION_OF_SDL_GetGamepadAxis
 #define SDL_GetGamepadAxisFromString IGNORE_THIS_VERSION_OF_SDL_GetGamepadAxisFromString
-#define SDL_GetGamepadBindForAxis IGNORE_THIS_VERSION_OF_SDL_GetGamepadBindForAxis
-#define SDL_GetGamepadBindForButton IGNORE_THIS_VERSION_OF_SDL_GetGamepadBindForButton
 #define SDL_GetGamepadButton IGNORE_THIS_VERSION_OF_SDL_GetGamepadButton
 #define SDL_GetGamepadButtonFromString IGNORE_THIS_VERSION_OF_SDL_GetGamepadButtonFromString
 #define SDL_GetGamepadFirmwareVersion IGNORE_THIS_VERSION_OF_SDL_GetGamepadFirmwareVersion
@@ -897,6 +895,8 @@
 #define SDL_ClearClipboardData IGNORE_THIS_VERSION_OF_SDL_ClearClipboardData
 #define SDL_GetGamepadInstanceID IGNORE_THIS_VERSION_OF_SDL_GetGamepadInstanceID
 #define SDL_GetGamepadPowerLevel IGNORE_THIS_VERSION_OF_SDL_GetGamepadPowerLevel
+#define SDL_SetGamepadMapping IGNORE_THIS_VERSION_OF_SDL_SetGamepadMapping
+#define SDL_strndup IGNORE_THIS_VERSION_OF_SDL_strndup
 
 /* *** HACK HACK HACK:
  * *** Avoid including SDL_thread.h: it defines SDL_CreateThread() as a macro
@@ -1703,14 +1703,6 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned);
 #undef SDL_GetGamepadAxisFromString
 #endif
 
-#ifdef SDL_GetGamepadBindForAxis
-#undef SDL_GetGamepadBindForAxis
-#endif
-
-#ifdef SDL_GetGamepadBindForButton
-#undef SDL_GetGamepadBindForButton
-#endif
-
 #ifdef SDL_GetGamepadButton
 #undef SDL_GetGamepadButton
 #endif
@@ -4431,6 +4423,14 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned);
 #undef SDL_GetGamepadPowerLevel
 #endif
 
+#ifdef SDL_SetGamepadMapping
+#undef SDL_SetGamepadMapping
+#endif
+
+#ifdef SDL_strndup
+#undef SDL_strndup
+#endif
+
 /* undefine these macros too: */
 /* redefine as SDL3_xxx, if needed. */
 
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index 0268020..debc6b9 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -154,11 +154,9 @@ SDL3_SYM_RENAMED(SDL_Joystick*,GameControllerGetJoystick,GetGamepadJoystick,(SDL
 SDL3_SYM_RENAMED(void,GameControllerUpdate,UpdateGamepads,(void),(),)
 SDL3_SYM_RENAMED(SDL_GameControllerAxis,GameControllerGetAxisFromString,GetGamepadAxisFromString,(const char *a),(a),return)
 SDL3_SYM_RENAMED(const char*,GameControllerGetStringForAxis,GetGamepadStringForAxis,(SDL_GameControllerAxis a),(a),return)
-SDL3_SYM_RENAMED(SDL_GameControllerButtonBind,GameControllerGetBindForAxis,GetGamepadBindForAxis,(SDL_GameController *a, SDL_GameControllerAxis b),(a,b),return)
 SDL3_SYM_RENAMED(Sint16,GameControllerGetAxis,GetGamepadAxis,(SDL_GameController *a, SDL_GameControllerAxis b),(a,b),return)
 SDL3_SYM_RENAMED(SDL_GameControllerButton,GameControllerGetButtonFromString,GetGamepadButtonFromString,(const char *a),(a),return)
 SDL3_SYM_RENAMED(const char*,GameControllerGetStringForButton,GetGamepadStringForButton,(SDL_GameControllerButton a),(a),return)
-SDL3_SYM_RENAMED(SDL_GameControllerButtonBind,GameControllerGetBindForButton,GetGamepadBindForButton,(SDL_GameController *a, SDL_GameControllerButton b),(a,b),return)
 SDL3_SYM_RENAMED(Uint8,GameControllerGetButton,GetGamepadButton,(SDL_GameController *a, SDL_GameControllerButton b),(a,b),return)
 SDL3_SYM_RENAMED(void,GameControllerClose,CloseGamepad,(SDL_GameController *a),(a),)
 SDL3_SYM_PASSTHROUGH(int,NumHaptics,(void),(),return)
@@ -696,7 +694,7 @@ SDL3_SYM_PASSTHROUGH(SDL_bool,HasARMSIMD,(void),(),return)
 SDL3_SYM_RENAMED(char*,strtokr,strtok_r,(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,GameControllerGetType,GetGamepadType,(SDL_GameController *a),(a),return)
+SDL3_SYM(SDL_GamepadType,GetGamepadType,(SDL_GameController *a),(a),return)
 SDL3_SYM_RENAMED(SDL_GameController*,GameControllerFromPlayerIndex,GetGamepadFromPlayerIndex,(int a),(a),return)
 SDL3_SYM(int,SetGamepadPlayerIndex,(SDL_GameController *a, int b),(a,b),return)
 SDL3_SYM_RENAMED(SDL_Joystick*,JoystickFromPlayerIndex,GetJoystickFromPlayerIndex,(int a),(a),return)
@@ -890,6 +888,7 @@ 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(SDL_JoystickID,GetGamepadInstanceID,(SDL_GameController *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)