sdl2-compat: Reimplemented SDL_GameControllerGetBindForAxis() and SDL_GameControllerGetBindForButton() using SDL_GetGamepadBindings()

From 3aad3ec92486aac8360f4d2e37586b3fa5f1dc7c Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 14 Sep 2023 07:05:50 -0700
Subject: [PATCH] Reimplemented SDL_GameControllerGetBindForAxis() and
 SDL_GameControllerGetBindForButton() using SDL_GetGamepadBindings()

---
 src/sdl2_compat.c | 57 ++++++++++++++++++++++++++++++++++++++++++-----
 src/sdl3_syms.h   |  1 +
 2 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 95a66ad..40cd2a0 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -6021,10 +6021,33 @@ SDL_GameControllerGetBindForAxis(SDL_GameController *controller,
                                  SDL_GameControllerAxis axis)
 {
     SDL_GameControllerButtonBind bind;
-    /* FIXME */
-    (void) controller;
-    (void) axis;
+
     SDL3_zero(bind);
+
+    if (axis != SDL_GAMEPAD_AXIS_INVALID) {
+        SDL_GamepadBinding **bindings = SDL3_GetGamepadBindings(controller, NULL);
+        if (bindings) {
+            int i;
+            for (i = 0; bindings[i]; ++i) {
+                SDL_GamepadBinding *binding = bindings[i];
+                if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) {
+                    bind.bindType = binding->inputType;
+                    if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
+                        /* FIXME: There might be multiple axes bound now that we have axis ranges... */
+                        bind.value.axis = binding->input.axis.axis;
+                    } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
+                        bind.value.button = binding->input.button;
+                    } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
+                        bind.value.hat.hat = binding->input.hat.hat;
+                        bind.value.hat.hat_mask = binding->input.hat.hat_mask;
+                    }
+                    break;
+                }
+            }
+            SDL_free(bindings);
+        }
+    }
+
     return bind;
 }
 
@@ -6033,10 +6056,32 @@ SDL_GameControllerGetBindForButton(SDL_GameController *controller,
                                    SDL_GameControllerButton button)
 {
     SDL_GameControllerButtonBind bind;
-    /* FIXME */
-    (void) controller;
-    (void) button;
+
     SDL3_zero(bind);
+
+    if (button != SDL_GAMEPAD_BUTTON_INVALID) {
+        SDL_GamepadBinding **bindings = SDL3_GetGamepadBindings(controller, NULL);
+        if (bindings) {
+            int i;
+            for (i = 0; bindings[i]; ++i) {
+                SDL_GamepadBinding *binding = bindings[i];
+                if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) {
+                    bind.bindType = binding->inputType;
+                    if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) {
+                        bind.value.axis = binding->input.axis.axis;
+                    } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) {
+                        bind.value.button = binding->input.button;
+                    } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) {
+                        bind.value.hat.hat = binding->input.hat.hat;
+                        bind.value.hat.hat_mask = binding->input.hat.hat_mask;
+                    }
+                    break;
+                }
+            }
+            SDL_free(bindings);
+        }
+    }
+
     return bind;
 }
 
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index bf6aadb..7052e9f 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -900,6 +900,7 @@ SDL3_SYM(int,PauseAudioDevice,(SDL_AudioDeviceID a),(a),return)
 SDL3_SYM(int,ResumeAudioDevice,(SDL_AudioDeviceID a),(a),return)
 SDL3_SYM(SDL_bool,AudioDevicePaused,(SDL_AudioDeviceID a),(a),return)
 SDL3_SYM(SDL_AudioDeviceID,GetAudioStreamDevice,(SDL_AudioStream *a),(a),return)
+SDL3_SYM(SDL_GamepadBinding **,GetGamepadBindings,(SDL_Gamepad *a, int *b),(a,b),return)
 #ifdef __GDK__
 SDL3_SYM_PASSTHROUGH(int,GDKGetDefaultUser,(XUserHandle *a),(a),return)
 #endif