Browse Source

Fixed bug 2155 - automatically remap accelerometer coordinates according to screen orientation on Android

Denis Bernard

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.
Sam Lantinga 12 years ago
parent
commit
7ae171d15e
1 changed files with 23 additions and 2 deletions
  1. 23 2
      android-project/src/org/libsdl/app/SDLActivity.java

+ 23 - 2
android-project/src/org/libsdl/app/SDLActivity.java

@@ -433,6 +433,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
 
 
     // Sensors
     // Sensors
     protected static SensorManager mSensorManager;
     protected static SensorManager mSensorManager;
+    protected static Display mDisplay;
 
 
     // Keep track of the surface size to normalize touch events
     // Keep track of the surface size to normalize touch events
     protected static float mWidth, mHeight;
     protected static float mWidth, mHeight;
@@ -448,6 +449,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
         setOnKeyListener(this); 
         setOnKeyListener(this); 
         setOnTouchListener(this);   
         setOnTouchListener(this);   
 
 
+        mDisplay = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
         mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
         mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
 
 
         // Some arbitrary defaults to avoid a potential division by zero
         // Some arbitrary defaults to avoid a potential division by zero
@@ -621,8 +623,27 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
     @Override
     @Override
     public void onSensorChanged(SensorEvent event) {
     public void onSensorChanged(SensorEvent event) {
         if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
         if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
-            SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
-                                      event.values[1] / SensorManager.GRAVITY_EARTH,
+            float x, y;
+            switch (mDisplay.getRotation()) {
+                case Surface.ROTATION_90:
+                    x = -event.values[1];
+                    y = event.values[0];
+                    break;
+                case Surface.ROTATION_270:
+                    x = event.values[1];
+                    y = -event.values[0];
+                    break;
+                case Surface.ROTATION_180:
+                    x = -event.values[1];
+                    y = -event.values[0];
+                    break;
+                default:
+                    x = event.values[0];
+                    y = event.values[1];
+                    break;
+            }
+            SDLActivity.onNativeAccel(x / SensorManager.GRAVITY_EARTH,
+                                      y / SensorManager.GRAVITY_EARTH,
                                       event.values[2] / SensorManager.GRAVITY_EARTH);
                                       event.values[2] / SensorManager.GRAVITY_EARTH);
         }
         }
     }
     }