From aa25a522ddeb6026506e1af333767e2ed59a536c Mon Sep 17 00:00:00 2001
From: Cameron Gutman <[EMAIL REDACTED]>
Date: Tue, 25 Feb 2025 19:30:08 -0600
Subject: [PATCH] sensors: Implement GetSensorDataWithTimestamp functions
---
src/sdl2_compat.c | 65 ++++++++++++++++++++++++++++++++++++++++++-----
src/sdl3_syms.h | 1 +
2 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index a56ee86..9b383d1 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -2085,6 +2085,39 @@ RemoveSupercededWindowEvents(void *userdata, SDL2_Event *event)
return 1;
}
+#define SDL_PROP_SENSOR_TIMESTAMP "sdl2-compat.sensor.timestamp"
+
+#define SDL_PROP_GAMEPAD_UNKNOWN_TIMESTAMP "sdl2-compat.gamepad.timestamp.unknown"
+#define SDL_PROP_GAMEPAD_ACCEL_TIMESTAMP "sdl2-compat.gamepad.timestamp.accel"
+#define SDL_PROP_GAMEPAD_GYRO_TIMESTAMP "sdl2-compat.gamepad.timestamp.gyro"
+#define SDL_PROP_GAMEPAD_ACCEL_L_TIMESTAMP "sdl2-compat.gamepad.timestamp.accel_l"
+#define SDL_PROP_GAMEPAD_GYRO_L_TIMESTAMP "sdl2-compat.gamepad.timestamp.gyro_l"
+#define SDL_PROP_GAMEPAD_ACCEL_R_TIMESTAMP "sdl2-compat.gamepad.timestamp.accel_r"
+#define SDL_PROP_GAMEPAD_GYRO_R_TIMESTAMP "sdl2-compat.gamepad.timestamp.gyro_r"
+
+static const char *GetGamepadSensorTimestampPropertyName(SDL_SensorType type)
+{
+ switch (type)
+ {
+ case SDL_SENSOR_UNKNOWN:
+ return SDL_PROP_GAMEPAD_UNKNOWN_TIMESTAMP;
+ case SDL_SENSOR_ACCEL:
+ return SDL_PROP_GAMEPAD_ACCEL_TIMESTAMP;
+ case SDL_SENSOR_GYRO:
+ return SDL_PROP_GAMEPAD_GYRO_TIMESTAMP;
+ case SDL_SENSOR_ACCEL_L:
+ return SDL_PROP_GAMEPAD_ACCEL_L_TIMESTAMP;
+ case SDL_SENSOR_GYRO_L:
+ return SDL_PROP_GAMEPAD_GYRO_L_TIMESTAMP;
+ case SDL_SENSOR_ACCEL_R:
+ return SDL_PROP_GAMEPAD_ACCEL_R_TIMESTAMP;
+ case SDL_SENSOR_GYRO_R:
+ return SDL_PROP_GAMEPAD_GYRO_R_TIMESTAMP;
+ default:
+ return NULL;
+ }
+}
+
static bool SDLCALL
EventFilter3to2(void *userdata, SDL_Event *event3)
{
@@ -2100,8 +2133,8 @@ EventFilter3to2(void *userdata, SDL_Event *event3)
GestureProcessEvent(event3); /* this might need to generate new gesture events from touch input. */
- /* Ensure joystick and haptic IDs are updated before calling Event3to2() */
switch (event3->type) {
+ /* Ensure joystick and haptic IDs are updated before calling Event3to2() */
case SDL_EVENT_JOYSTICK_ADDED:
case SDL_EVENT_GAMEPAD_ADDED:
case SDL_EVENT_GAMEPAD_REMOVED:
@@ -2114,6 +2147,18 @@ EventFilter3to2(void *userdata, SDL_Event *event3)
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
SDL_GetNumAudioDevices(event3->adevice.recording ? SDL2_TRUE : SDL2_FALSE); /* Refresh */
break;
+
+ /* Save the timestamp for the most recent sensor values */
+ case SDL_EVENT_SENSOR_UPDATE:
+ SDL3_SetNumberProperty(SDL3_GetSensorProperties(SDL3_GetSensorFromID(event3->sensor.which)),
+ SDL_PROP_SENSOR_TIMESTAMP,
+ SDL_NS_TO_US(event3->sensor.sensor_timestamp));
+ break;
+ case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
+ SDL3_SetNumberProperty(SDL3_GetGamepadProperties(SDL3_GetGamepadFromID(event3->gsensor.which)),
+ GetGamepadSensorTimestampPropertyName((SDL_SensorType)event3->gsensor.sensor),
+ SDL_NS_TO_US(event3->gsensor.sensor_timestamp));
+ break;
}
if (EventFilter2) {
@@ -4030,20 +4075,26 @@ SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_Senso
return SDL3_SetGamepadSensorEnabled(gamecontroller, type, enabled) ? 0 : -1;
}
-/* this API was removed in SDL3; use sensor event timestamps instead! */
SDL_DECLSPEC int SDLCALL
SDL_GameControllerGetSensorDataWithTimestamp(SDL_GameController *gamecontroller, SDL_SensorType type, Uint64 *timestamp, float *data, int num_values)
{
- SDL3_Unsupported(); /* !!! FIXME: maybe try to track this from SDL3 events if something needs this? I can't imagine this was widely used. */
- return -1;
+ if (!SDL3_GetGamepadSensorData(gamecontroller, type, data, num_values)) {
+ return -1;
+ }
+
+ *timestamp = SDL3_GetNumberProperty(SDL3_GetGamepadProperties(gamecontroller), GetGamepadSensorTimestampPropertyName(type), 0);
+ return 0;
}
-/* this API was removed in SDL3; use sensor event timestamps instead! */
SDL_DECLSPEC int SDLCALL
SDL_SensorGetDataWithTimestamp(SDL_Sensor *sensor, Uint64 *timestamp, float *data, int num_values)
{
- SDL3_Unsupported(); /* !!! FIXME: maybe try to track this from SDL3 events if something needs this? I can't imagine this was widely used. */
- return -1;
+ if (!SDL3_GetSensorData(sensor, data, num_values)) {
+ return -1;
+ }
+
+ *timestamp = SDL3_GetNumberProperty(SDL3_GetSensorProperties(sensor), SDL_PROP_SENSOR_TIMESTAMP, 0);
+ return 0;
}
SDL_DECLSPEC int SDLCALL
diff --git a/src/sdl3_syms.h b/src/sdl3_syms.h
index 8ef0ca1..973ceeb 100644
--- a/src/sdl3_syms.h
+++ b/src/sdl3_syms.h
@@ -377,6 +377,7 @@ SDL3_SYM(SDL_Sensor*,GetSensorFromID,(SDL_SensorID a),(a),return)
SDL3_SYM(SDL_SensorID,GetSensorID,(SDL_Sensor *a),(a),return)
SDL3_SYM(const char *,GetSensorNameForID,(SDL_SensorID a),(a),return)
SDL3_SYM(int,GetSensorNonPortableTypeForID,(SDL_SensorID a),(a),return)
+SDL3_SYM(SDL_PropertiesID,GetSensorProperties,(SDL_Sensor *a),(a),return)
SDL3_SYM(SDL_SensorType,GetSensorTypeForID,(SDL_SensorID a),(a),return)
SDL3_SYM(SDL_SensorID *,GetSensors,(int *a),(a),return)
SDL3_SYM(int,GetSilenceValueForFormat,(SDL_AudioFormat a),(a),return)