SDL: Added infrastructure for reporting GameInput sensors

From 419aebebda930f5da247e1d314a3663f39f0b41a Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 17 Feb 2024 19:40:42 -0800
Subject: [PATCH] Added infrastructure for reporting GameInput sensors

IGameInputReading::GetMotionState() isn't implemented yet, so we'll need to figure out how to interpret the motion data once it's available.
---
 src/joystick/gdk/SDL_gameinputjoystick.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/joystick/gdk/SDL_gameinputjoystick.c b/src/joystick/gdk/SDL_gameinputjoystick.c
index b0591d069324..5f744c1ec9d6 100644
--- a/src/joystick/gdk/SDL_gameinputjoystick.c
+++ b/src/joystick/gdk/SDL_gameinputjoystick.c
@@ -40,6 +40,7 @@ typedef struct GAMEINPUT_InternalDevice
     SDL_JoystickGUID guid;          /* generated by SDL */
     SDL_JoystickID device_instance; /* generated by SDL */
     SDL_bool wireless;
+    SDL_bool sensors_supported;
     GameInputRumbleMotors supportedRumbleMotors;
     SDL_bool isAdded;
     SDL_bool isDeleteRequested;
@@ -54,6 +55,7 @@ typedef struct GAMEINPUT_InternalList
 typedef struct joystick_hwdata
 {
     GAMEINPUT_InternalDevice *devref;
+    SDL_bool report_sensors;
     GameInputRumbleParams rumbleParams;
 } GAMEINPUT_InternalJoystickHwdata;
 
@@ -123,6 +125,7 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice)
     elem->guid = SDL_CreateJoystickGUID(bus, vendor, product, version, "GameInput", "Gamepad", 'g', 0);
     elem->device_instance = SDL_GetNextObjectID();
     elem->wireless = (devinfo->capabilities & GameInputDeviceCapabilityWireless);
+    elem->sensors_supported = (devinfo->supportedInput & GameInputKindMotion);
     elem->supportedRumbleMotors = devinfo->supportedRumbleMotors;
 
     g_GameInputList.devices = devicelist;
@@ -373,6 +376,12 @@ static int GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
         SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, SDL_TRUE);
     }
 
+    if (elem->sensors_supported) {
+        /* FIXME: What's the sensor update rate? */
+        SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f);
+        SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f);
+    }
+
     if (elem->wireless) {
         joystick->epowerlevel = GAMEINPUT_InternalGetPowerLevel(elem->device);
     } else {
@@ -415,7 +424,7 @@ static int GAMEINPUT_JoystickSendEffect(SDL_Joystick *joystick, const void *data
 
 static int GAMEINPUT_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
 {
-    /* I am not sure what is this even supposed to do in case of GameInput... */
+    joystick->hwdata->report_sensors = enabled;
     return 0;
 }
 
@@ -483,6 +492,14 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
 #undef CONVERT_TRIGGER
     }
 
+    if (hwdata->report_sensors) {
+        GameInputMotionState motion_state;
+
+        if (IGameInputReading_GetMotionState(reading, &motion_state)) {
+            /* FIXME: How do we interpret the motion data? */
+        }
+    }
+
     IGameInputReading_Release(reading);
 
     if (joystick->epowerlevel != SDL_JOYSTICK_POWER_WIRED) {