We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2155

Summary: [patch] automatically remap accelerometer coordinates according to screen orientation on Android
Product: SDL Reporter: Denis Bernard <denis>
Component: joystickAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: denis, philipp.wiesemann
Version: HG 2.0   
Hardware: All   
OS: Android (All)   
Attachments: Coordinate remapping of the accelerometer data according to screen orientation
Coordinate remapping of the accelerometer data according to screen orientation
Coordinate remapping of the accelerometer data according to screen orientation

Description Denis Bernard 2013-10-15 17:18:02 UTC
Created attachment 1369 [details]
Coordinate remapping of the accelerometer data according to screen orientation

Background information: http://android-developers.blogspot.fr/2010/09/one-screen-turn-deserves-another.html and http://developer.android.com/reference/android/hardware/SensorEvent.html

Right now, the Android accelerometer event handler feeds raw accelerometer data  to the SDL Joystick driver. The result is that for landscape-only applications, the axis need to be swapped if running on a portrait device (like a phone), and vice-versa: running a portrait only app on a landscape device like a tablet.

The purpose of this patch is to perform coordinate remapping of the accelerometer data before feeding it to the SDL joystick driver so that the X axis of the joystick is always aligned with the X axis of the display, same for the Y axis.

This has been tested on applications that support screen orientation changes as well as applications with fixed screen orientations, both on phones and tablets.
Comment 1 Philipp Wiesemann 2013-10-15 20:58:43 UTC
About the implementation in your patch:

I think cloning of the array object is not needed. You could just use three local float variables. onSensorChanged() is called very often and this would prevent some creation and garbage collection overhead for a tiny performance improvement.

Also I think swapping through a temporary variable is not needed. You could just assign the values from the input array (maybe modified) into three local "output" variables and use these as parameters for the JNI call.

e.g.:

// ...

float x, y, z;

// ...

case Surface.ROTATION_90:
    x = -event.values[1];
    y = event.values[0];
    z = event.values[2];
    break;

// ...

default:
    x = event.values[0];
    y = event.values[1];
    z = event.values[2];
    break;
}

SDLActivity.onNativeAccel(x / SensorManager.GRAVITY_EARTH,
                          y / SensorManager.GRAVITY_EARTH,
                          z / SensorManager.GRAVITY_EARTH);
Comment 2 Denis Bernard 2013-10-16 02:16:14 UTC
Created attachment 1370 [details]
Coordinate remapping of the accelerometer data according to screen orientation

Good point, I was initially using SensorManager.remapCoordinateSystem() (but overkill for our need), hence the clone. Here's a new patch where I kept the new variables to a minimum. No need to get Z out as it won't change (it just needs to be adjusted once, see bug 2156)
Comment 3 Denis Bernard 2013-10-16 02:19:51 UTC
Created attachment 1371 [details]
Coordinate remapping of the accelerometer data according to screen orientation

Had forgotten to remove yet another variable. This time it should be as lean a possible.
Comment 4 Sam Lantinga 2013-10-18 06:44:56 UTC
Good patch, thanks!
http://hg.libsdl.org/SDL/rev/e2188abb7c10