Use a separate sensor watching function for gamepad events to avoid reliance on system sensor events and prevent a potential deadlock
This commit is contained in:
parent
70e43c150e
commit
20ea35138f
3 changed files with 53 additions and 33 deletions
|
@ -318,22 +318,6 @@ static void RecenterGamepad(SDL_Gamepad *gamepad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SDL defines sensor orientation relative to the device natural
|
|
||||||
orientation, so when it's changed orientation to be used as a
|
|
||||||
gamepad, change the sensor orientation to match.
|
|
||||||
*/
|
|
||||||
static void AdjustSensorOrientation(SDL_Joystick *joystick, float *src, float *dst)
|
|
||||||
{
|
|
||||||
unsigned int i, j;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
|
||||||
dst[i] = 0.0f;
|
|
||||||
for (j = 0; j < 3; ++j) {
|
|
||||||
dst[i] += joystick->sensor_transform[i][j] * src[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Event filter to fire gamepad events from joystick ones
|
* Event filter to fire gamepad events from joystick ones
|
||||||
*/
|
*/
|
||||||
|
@ -408,23 +392,6 @@ static int SDLCALL SDL_GamepadEventWatcher(void *userdata, SDL_Event *event)
|
||||||
SDL_PushEvent(&deviceevent);
|
SDL_PushEvent(&deviceevent);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case SDL_EVENT_SENSOR_UPDATE:
|
|
||||||
{
|
|
||||||
SDL_LockJoysticks();
|
|
||||||
for (gamepad = SDL_gamepads; gamepad; gamepad = gamepad->next) {
|
|
||||||
if (gamepad->joystick->accel && gamepad->joystick->accel_sensor == event->sensor.which) {
|
|
||||||
float data[3];
|
|
||||||
AdjustSensorOrientation(gamepad->joystick, event->sensor.data, data);
|
|
||||||
SDL_SendJoystickSensor(event->common.timestamp, gamepad->joystick, SDL_SENSOR_ACCEL, event->sensor.sensor_timestamp, data, SDL_arraysize(data));
|
|
||||||
}
|
|
||||||
if (gamepad->joystick->gyro && gamepad->joystick->gyro_sensor == event->sensor.which) {
|
|
||||||
float data[3];
|
|
||||||
AdjustSensorOrientation(gamepad->joystick, event->sensor.data, data);
|
|
||||||
SDL_SendJoystickSensor(event->common.timestamp, gamepad->joystick, SDL_SENSOR_GYRO, event->sensor.sensor_timestamp, data, SDL_arraysize(data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDL_UnlockJoysticks();
|
|
||||||
} break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -432,6 +399,52 @@ static int SDLCALL SDL_GamepadEventWatcher(void *userdata, SDL_Event *event)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SDL defines sensor orientation relative to the device natural
|
||||||
|
orientation, so when it's changed orientation to be used as a
|
||||||
|
gamepad, change the sensor orientation to match.
|
||||||
|
*/
|
||||||
|
static void AdjustSensorOrientation(SDL_Joystick *joystick, float *src, float *dst)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
dst[i] = 0.0f;
|
||||||
|
for (j = 0; j < 3; ++j) {
|
||||||
|
dst[i] += joystick->sensor_transform[i][j] * src[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Event filter to fire gamepad sensor events from system sensor events
|
||||||
|
*
|
||||||
|
* We don't use SDL_GamepadEventWatcher() for this because we want to
|
||||||
|
* deliver gamepad sensor events when system sensor events are disabled,
|
||||||
|
* and we also need to avoid a potential deadlock where joystick event
|
||||||
|
* delivery locks the joysticks and then the event queue, but sensor
|
||||||
|
* event delivery would lock the event queue and then from within the
|
||||||
|
* event watcher function lock the joysticks.
|
||||||
|
*/
|
||||||
|
void SDL_GamepadSensorWatcher(Uint64 timestamp, SDL_SensorID sensor, Uint64 sensor_timestamp, float *data, int num_values)
|
||||||
|
{
|
||||||
|
SDL_Gamepad *gamepad;
|
||||||
|
|
||||||
|
SDL_LockJoysticks();
|
||||||
|
for (gamepad = SDL_gamepads; gamepad; gamepad = gamepad->next) {
|
||||||
|
if (gamepad->joystick->accel && gamepad->joystick->accel_sensor == sensor) {
|
||||||
|
float gamepad_data[3];
|
||||||
|
AdjustSensorOrientation(gamepad->joystick, data, gamepad_data);
|
||||||
|
SDL_SendJoystickSensor(timestamp, gamepad->joystick, SDL_SENSOR_ACCEL, sensor_timestamp, gamepad_data, SDL_arraysize(gamepad_data));
|
||||||
|
}
|
||||||
|
if (gamepad->joystick->gyro && gamepad->joystick->gyro_sensor == sensor) {
|
||||||
|
float gamepad_data[3];
|
||||||
|
AdjustSensorOrientation(gamepad->joystick, data, gamepad_data);
|
||||||
|
SDL_SendJoystickSensor(timestamp, gamepad->joystick, SDL_SENSOR_GYRO, sensor_timestamp, gamepad_data, SDL_arraysize(gamepad_data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_UnlockJoysticks();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
/*
|
/*
|
||||||
* Helper function to guess at a mapping based on the elements reported for this gamepad
|
* Helper function to guess at a mapping based on the elements reported for this gamepad
|
||||||
|
|
|
@ -42,4 +42,7 @@ extern SDL_bool SDL_ShouldIgnoreGamepad(const char *name, SDL_JoystickGUID guid)
|
||||||
/* Handle delayed guide button on a gamepad */
|
/* Handle delayed guide button on a gamepad */
|
||||||
extern void SDL_GamepadHandleDelayedGuideButton(SDL_Joystick *joystick);
|
extern void SDL_GamepadHandleDelayedGuideButton(SDL_Joystick *joystick);
|
||||||
|
|
||||||
|
/* Handle system sensor data */
|
||||||
|
extern void SDL_GamepadSensorWatcher(Uint64 timestamp, SDL_SensorID sensor, Uint64 sensor_timestamp, float *data, int num_values);
|
||||||
|
|
||||||
#endif /* SDL_gamepad_c_h_ */
|
#endif /* SDL_gamepad_c_h_ */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#ifndef SDL_EVENTS_DISABLED
|
#ifndef SDL_EVENTS_DISABLED
|
||||||
#include "../events/SDL_events_c.h"
|
#include "../events/SDL_events_c.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "../joystick/SDL_gamepad_c.h"
|
||||||
|
|
||||||
static SDL_SensorDriver *SDL_sensor_drivers[] = {
|
static SDL_SensorDriver *SDL_sensor_drivers[] = {
|
||||||
#ifdef SDL_SENSOR_ANDROID
|
#ifdef SDL_SENSOR_ANDROID
|
||||||
|
@ -501,6 +502,9 @@ int SDL_SendSensorUpdate(Uint64 timestamp, SDL_Sensor *sensor, Uint64 sensor_tim
|
||||||
posted = SDL_PushEvent(&event) == 1;
|
posted = SDL_PushEvent(&event) == 1;
|
||||||
}
|
}
|
||||||
#endif /* !SDL_EVENTS_DISABLED */
|
#endif /* !SDL_EVENTS_DISABLED */
|
||||||
|
|
||||||
|
SDL_GamepadSensorWatcher(timestamp, sensor->instance_id, sensor_timestamp, data, num_values);
|
||||||
|
|
||||||
return posted;
|
return posted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue