Commit 34634082ff755a0811bfe21822a155e897459108

Sam Lantinga 2015-06-14T19:25:12

Fixed bug 3012 - Android accelerometer joystick axis values overflow when values from Android are larger than gravity Magnus Bjerke Vik This causes issues when for instance using the joystick API to make an Android phone rotate an object by rotating the phone. When the absolute value of an axis reported by android is larger than earth gravity, SDL will overflow the Sint16 value used for joystick axes, causing sporadic movements when close to the gravity. Just holding the phone so that e.g. Y points directly upwards will make it unstable, and even more if you just tap the phone gently from below (increasing the acceleration). More detailed: SDLActivity gets the accelerometer values in onSensorChanged and divides each axis by earth gravity. SDL_SYS_JoystickUpdate takes each of the axis values, multiplies them by 32767.0 (largest Sint16), and the casts them to Sint16. From this you can see that any value from Android that exceeds earth gravity will overflow the joystick axis. A fix is to clamp the values so that they won't overflow the Sint16.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c
index 91480b8..b564f18 100644
--- a/src/joystick/android/SDL_sysjoystick.c
+++ b/src/joystick/android/SDL_sysjoystick.c
@@ -518,6 +518,15 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
             if (item->joystick) {
                 if (Android_JNI_GetAccelerometerValues(values)) {
                     for ( i = 0; i < 3; i++ ) {
+                        if (values[i] > 1.0f)
+                        {
+                            values[i] = 1.0f;
+                        }
+                        else if (values[i] < -1.0f)
+                        {
+                            values[i] = -1.0f;
+                        }
+
                         value = (Sint16)(values[i] * 32767.0f);
                         SDL_PrivateJoystickAxis(item->joystick, i, value);
                     }