Commit 45a88b6ade1e13e2f0d2e68fec73dd1ddc9ad682

Gabriel Jacobo 2013-11-11T10:15:35

[Android] Fixes bug 2217, better joystick axes handling on Android.

diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java
index 60b6aa0..d0155a5 100755
--- a/android-project/src/org/libsdl/app/SDLActivity.java
+++ b/android-project/src/org/libsdl/app/SDLActivity.java
@@ -433,6 +433,10 @@ public class SDLActivity extends Activity {
         return mJoystickHandler.getJoystickAxes(joy);
     }
     
+    public static boolean handleJoystickMotionEvent(MotionEvent event) {
+        return mJoystickHandler.handleMotionEvent(event);
+    }
+    
     /**
      * @param devId the device id to get opened joystick id for.
      * @return joystick id for device id or -1 if there is none.
@@ -840,73 +844,105 @@ class SDLJoystickHandler {
     public int getJoyId(int devId) {
         return -1;
     }
+    
+    public boolean handleMotionEvent(MotionEvent event) {
+        return false;
+    }
 }
 
 /* Actual joystick functionality available for API >= 12 devices */
 class SDLJoystickHandler_API12 extends SDLJoystickHandler {
-    private ArrayList<Integer> mJoyIdList;
+  
+    class SDLJoystick {
+        public int id;
+        public String name;
+        public ArrayList<InputDevice.MotionRange> axes;
+    }
     
-    // Create a list of valid ID's the first time this function is called
-    private void createJoystickList() {
-        if(mJoyIdList != null) {
-            return;
-        }
+    private ArrayList<SDLJoystick> mJoysticks;
+    
+    public SDLJoystickHandler_API12() {
+        /* FIXME: Move the joystick initialization code to its own function and support hotplugging of devices */
+       
+        mJoysticks = new ArrayList<SDLJoystick>();
         
-        mJoyIdList = new ArrayList<Integer>();
         int[] deviceIds = InputDevice.getDeviceIds();
         for(int i=0; i<deviceIds.length; i++) {
-            if( (InputDevice.getDevice(deviceIds[i]).getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
-                mJoyIdList.add(Integer.valueOf(deviceIds[i]));
+            SDLJoystick joystick = new SDLJoystick();
+            InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
+            
+            if( (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+                joystick.id = deviceIds[i];
+                joystick.name = joystickDevice.getName();
+                joystick.axes = new ArrayList<InputDevice.MotionRange>();
+                
+                for (InputDevice.MotionRange range : joystickDevice.getMotionRanges()) {
+                     if ( (range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
+                        joystick.axes.add(range);
+                     }
+                }
+                
+                mJoysticks.add(joystick);
             }
         }
     }
     
     @Override
     public int getNumJoysticks() {
-        createJoystickList();
-        return mJoyIdList.size();
+        return mJoysticks.size();
     }
     
     @Override
     public String getJoystickName(int joy) {
-        createJoystickList();
-        return InputDevice.getDevice(mJoyIdList.get(joy).intValue()).getName();
+        return mJoysticks.get(joy).name;
     }
     
     @Override
     public int getJoystickAxes(int joy) {
-        createJoystickList();
-        return InputDevice.getDevice(mJoyIdList.get(joy).intValue()).getMotionRanges().size();
+        return mJoysticks.get(joy).axes.size();
     }
     
     @Override
     public int getJoyId(int devId) {
-        createJoystickList();
-        return mJoyIdList.indexOf(Integer.valueOf(devId));
-    }
+        for(int i=0; i < mJoysticks.size(); i++) {
+            if (mJoysticks.get(i).id == devId) {
+                return i;
+            }
+        }
+        return -1;
+    }   
     
-}
-
-class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
-    // Generic Motion (mouse hover, joystick...) events go here
-    // We only have joysticks yet
-    @Override
-    public boolean onGenericMotion(View v, MotionEvent event) {
+    @Override        
+    public boolean handleMotionEvent(MotionEvent event) {
         if ( (event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
             int actionPointerIndex = event.getActionIndex();
             int action = event.getActionMasked();
             switch(action) {
                 case MotionEvent.ACTION_MOVE:
-                    int id = SDLActivity.getJoyId( event.getDeviceId() );
-                    if (id != -1) {
-                        float x = event.getAxisValue(MotionEvent.AXIS_X, actionPointerIndex);
-                        float y = event.getAxisValue(MotionEvent.AXIS_Y, actionPointerIndex);
-                        SDLActivity.onNativeJoy(id, 0, x);
-                        SDLActivity.onNativeJoy(id, 1, y);
+                    int id = getJoyId( event.getDeviceId() );
+                    if ( id != -1 ) {
+                        SDLJoystick joystick = mJoysticks.get(id);
+                        for (int i = 0; i < joystick.axes.size(); i++) {
+                            InputDevice.MotionRange range = joystick.axes.get(i);
+                            /* Normalize the value to -1...1 */
+                            float value = ( event.getAxisValue( range.getAxis(), actionPointerIndex) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
+                            SDLActivity.onNativeJoy(id, i, value );
+                        }                       
                     }
                     break;
+                default:
+                    break;
             }
         }
         return true;
+    }            
+}
+
+class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
+    // Generic Motion (mouse hover, joystick...) events go here
+    // We only have joysticks yet
+    @Override
+    public boolean onGenericMotion(View v, MotionEvent event) {
+        return SDLActivity.handleJoystickMotionEvent(event);
     }
 }
diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c
index e29aced..a98cef5 100644
--- a/src/joystick/android/SDL_sysjoystick.c
+++ b/src/joystick/android/SDL_sysjoystick.c
@@ -308,7 +308,10 @@ SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
 int
 Android_OnPadDown(int padId, int keycode)
 {
-    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_PRESSED);
+    int button = keycode_to_SDL(keycode);
+    if (button >= 0) {
+        SDL_PrivateJoystickButton(SYS_Joysticks[padId], button , SDL_PRESSED);
+    }
     
     return 0;
 }
@@ -316,7 +319,10 @@ Android_OnPadDown(int padId, int keycode)
 int
 Android_OnPadUp(int padId, int keycode)
 {
-    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_RELEASED);
+    int button = keycode_to_SDL(keycode);
+    if (button >= 0) {
+        SDL_PrivateJoystickButton(SYS_Joysticks[padId], button, SDL_RELEASED);
+    }
     
     return 0;
 }