Skip to content

Commit

Permalink
Rotate the sensor axes to match gamepad orientation when using the de…
Browse files Browse the repository at this point in the history
…vice sensors for game controllers
  • Loading branch information
slouken committed Jun 17, 2023
1 parent a9c86e5 commit 8de6ce7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
10 changes: 4 additions & 6 deletions include/SDL3/SDL_sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,12 @@ typedef enum
* values[1]: Acceleration on the y axis
* values[2]: Acceleration on the z axis
*
* For phones held in portrait mode and game controllers held in front of you,
* the axes are defined as follows:
* For phones and tablets held in natural orientation and game controllers held in front of you, the axes are defined as follows:
* -X ... +X : left ... right
* -Y ... +Y : bottom ... top
* -Z ... +Z : farther ... closer
*
* The axis data is not changed when the phone is rotated.
* The axis data is not changed when the device is rotated.
*
* \sa SDL_GetDisplayOrientation()
*/
Expand All @@ -114,13 +113,12 @@ typedef enum
* values[1]: Angular speed around the y axis (yaw)
* values[2]: Angular speed around the z axis (roll)
*
* For phones held in portrait mode and game controllers held in front of you,
* the axes are defined as follows:
* For phones and tablets held in natural orientation and game controllers held in front of you, the axes are defined as follows:
* -X ... +X : left ... right
* -Y ... +Y : bottom ... top
* -Z ... +Z : farther ... closer
*
* The axis data is not changed when the phone or controller is rotated.
* The axis data is not changed when the device is rotated.
*
* \sa SDL_GetDisplayOrientation()
*/
Expand Down
26 changes: 24 additions & 2 deletions src/joystick/SDL_gamepad.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,24 @@ static void RecenterGamepad(SDL_Gamepad *gamepad)
}
}

/* SDL defines sensor orientation for phones relative to the natural
orientation, and for gamepads relative to being held in front of you.
When a phone is being used as a gamepad, its orientation changes,
so adjust sensor axes to match.
*/
static void AdjustSensorOrientation(float *src, float *dst)
{
/* When a phone is rotated left and laid flat, the axes change
orientation as follows:
-X to +X becomes +Z to -Z
-Y to +Y becomes +X to -X
-Z to +Z becomes -Y to +Y
*/
dst[0] = -src[1];
dst[1] = src[2];
dst[2] = -src[0];
}

/*
* Event filter to fire gamepad events from joystick ones
*/
Expand Down Expand Up @@ -449,10 +467,14 @@ static int SDLCALL SDL_GamepadEventWatcher(void *userdata, SDL_Event *event)
SDL_LockJoysticks();
for (gamepad = SDL_gamepads; gamepad; gamepad = gamepad->next) {
if (gamepad->joystick->accel && gamepad->joystick->accel_sensor == event->sensor.which) {
SDL_SendJoystickSensor(event->common.timestamp, gamepad->joystick, SDL_SENSOR_ACCEL, event->sensor.sensor_timestamp, event->sensor.data, SDL_arraysize(event->sensor.data));
float data[3];
AdjustSensorOrientation(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) {
SDL_SendJoystickSensor(event->common.timestamp, gamepad->joystick, SDL_SENSOR_GYRO, event->sensor.sensor_timestamp, event->sensor.data, SDL_arraysize(event->sensor.data));
float data[3];
AdjustSensorOrientation(event->sensor.data, data);
SDL_SendJoystickSensor(event->common.timestamp, gamepad->joystick, SDL_SENSOR_GYRO, event->sensor.sensor_timestamp, data, SDL_arraysize(data));
}
}
SDL_UnlockJoysticks();
Expand Down

0 comments on commit 8de6ce7

Please sign in to comment.