[Android] Fixes bug 2217, better joystick axes handling on Android.
authorGabriel Jacobo <gabomdq@gmail.com>
Mon, 11 Nov 2013 10:15:35 -0300
changeset 7956965b7e09c5a8
parent 7955 9446f2fbe4f0
child 7957 5d9563c4f4b6
[Android] Fixes bug 2217, better joystick axes handling on Android.
android-project/src/org/libsdl/app/SDLActivity.java
src/joystick/android/SDL_sysjoystick.c
     1.1 --- a/android-project/src/org/libsdl/app/SDLActivity.java	Mon Nov 11 03:29:11 2013 -0800
     1.2 +++ b/android-project/src/org/libsdl/app/SDLActivity.java	Mon Nov 11 10:15:35 2013 -0300
     1.3 @@ -433,6 +433,10 @@
     1.4          return mJoystickHandler.getJoystickAxes(joy);
     1.5      }
     1.6      
     1.7 +    public static boolean handleJoystickMotionEvent(MotionEvent event) {
     1.8 +        return mJoystickHandler.handleMotionEvent(event);
     1.9 +    }
    1.10 +    
    1.11      /**
    1.12       * @param devId the device id to get opened joystick id for.
    1.13       * @return joystick id for device id or -1 if there is none.
    1.14 @@ -840,51 +844,98 @@
    1.15      public int getJoyId(int devId) {
    1.16          return -1;
    1.17      }
    1.18 +    
    1.19 +    public boolean handleMotionEvent(MotionEvent event) {
    1.20 +        return false;
    1.21 +    }
    1.22  }
    1.23  
    1.24  /* Actual joystick functionality available for API >= 12 devices */
    1.25  class SDLJoystickHandler_API12 extends SDLJoystickHandler {
    1.26 -    private ArrayList<Integer> mJoyIdList;
    1.27 +  
    1.28 +    class SDLJoystick {
    1.29 +        public int id;
    1.30 +        public String name;
    1.31 +        public ArrayList<InputDevice.MotionRange> axes;
    1.32 +    }
    1.33      
    1.34 -    // Create a list of valid ID's the first time this function is called
    1.35 -    private void createJoystickList() {
    1.36 -        if(mJoyIdList != null) {
    1.37 -            return;
    1.38 -        }
    1.39 +    private ArrayList<SDLJoystick> mJoysticks;
    1.40 +    
    1.41 +    public SDLJoystickHandler_API12() {
    1.42 +        /* FIXME: Move the joystick initialization code to its own function and support hotplugging of devices */
    1.43 +       
    1.44 +        mJoysticks = new ArrayList<SDLJoystick>();
    1.45          
    1.46 -        mJoyIdList = new ArrayList<Integer>();
    1.47          int[] deviceIds = InputDevice.getDeviceIds();
    1.48          for(int i=0; i<deviceIds.length; i++) {
    1.49 -            if( (InputDevice.getDevice(deviceIds[i]).getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
    1.50 -                mJoyIdList.add(Integer.valueOf(deviceIds[i]));
    1.51 +            SDLJoystick joystick = new SDLJoystick();
    1.52 +            InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
    1.53 +            
    1.54 +            if( (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
    1.55 +                joystick.id = deviceIds[i];
    1.56 +                joystick.name = joystickDevice.getName();
    1.57 +                joystick.axes = new ArrayList<InputDevice.MotionRange>();
    1.58 +                
    1.59 +                for (InputDevice.MotionRange range : joystickDevice.getMotionRanges()) {
    1.60 +                     if ( (range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
    1.61 +                        joystick.axes.add(range);
    1.62 +                     }
    1.63 +                }
    1.64 +                
    1.65 +                mJoysticks.add(joystick);
    1.66              }
    1.67          }
    1.68      }
    1.69      
    1.70      @Override
    1.71      public int getNumJoysticks() {
    1.72 -        createJoystickList();
    1.73 -        return mJoyIdList.size();
    1.74 +        return mJoysticks.size();
    1.75      }
    1.76      
    1.77      @Override
    1.78      public String getJoystickName(int joy) {
    1.79 -        createJoystickList();
    1.80 -        return InputDevice.getDevice(mJoyIdList.get(joy).intValue()).getName();
    1.81 +        return mJoysticks.get(joy).name;
    1.82      }
    1.83      
    1.84      @Override
    1.85      public int getJoystickAxes(int joy) {
    1.86 -        createJoystickList();
    1.87 -        return InputDevice.getDevice(mJoyIdList.get(joy).intValue()).getMotionRanges().size();
    1.88 +        return mJoysticks.get(joy).axes.size();
    1.89      }
    1.90      
    1.91      @Override
    1.92      public int getJoyId(int devId) {
    1.93 -        createJoystickList();
    1.94 -        return mJoyIdList.indexOf(Integer.valueOf(devId));
    1.95 -    }
    1.96 +        for(int i=0; i < mJoysticks.size(); i++) {
    1.97 +            if (mJoysticks.get(i).id == devId) {
    1.98 +                return i;
    1.99 +            }
   1.100 +        }
   1.101 +        return -1;
   1.102 +    }   
   1.103      
   1.104 +    @Override        
   1.105 +    public boolean handleMotionEvent(MotionEvent event) {
   1.106 +        if ( (event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
   1.107 +            int actionPointerIndex = event.getActionIndex();
   1.108 +            int action = event.getActionMasked();
   1.109 +            switch(action) {
   1.110 +                case MotionEvent.ACTION_MOVE:
   1.111 +                    int id = getJoyId( event.getDeviceId() );
   1.112 +                    if ( id != -1 ) {
   1.113 +                        SDLJoystick joystick = mJoysticks.get(id);
   1.114 +                        for (int i = 0; i < joystick.axes.size(); i++) {
   1.115 +                            InputDevice.MotionRange range = joystick.axes.get(i);
   1.116 +                            /* Normalize the value to -1...1 */
   1.117 +                            float value = ( event.getAxisValue( range.getAxis(), actionPointerIndex) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
   1.118 +                            SDLActivity.onNativeJoy(id, i, value );
   1.119 +                        }                       
   1.120 +                    }
   1.121 +                    break;
   1.122 +                default:
   1.123 +                    break;
   1.124 +            }
   1.125 +        }
   1.126 +        return true;
   1.127 +    }            
   1.128  }
   1.129  
   1.130  class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
   1.131 @@ -892,21 +943,6 @@
   1.132      // We only have joysticks yet
   1.133      @Override
   1.134      public boolean onGenericMotion(View v, MotionEvent event) {
   1.135 -        if ( (event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
   1.136 -            int actionPointerIndex = event.getActionIndex();
   1.137 -            int action = event.getActionMasked();
   1.138 -            switch(action) {
   1.139 -                case MotionEvent.ACTION_MOVE:
   1.140 -                    int id = SDLActivity.getJoyId( event.getDeviceId() );
   1.141 -                    if (id != -1) {
   1.142 -                        float x = event.getAxisValue(MotionEvent.AXIS_X, actionPointerIndex);
   1.143 -                        float y = event.getAxisValue(MotionEvent.AXIS_Y, actionPointerIndex);
   1.144 -                        SDLActivity.onNativeJoy(id, 0, x);
   1.145 -                        SDLActivity.onNativeJoy(id, 1, y);
   1.146 -                    }
   1.147 -                    break;
   1.148 -            }
   1.149 -        }
   1.150 -        return true;
   1.151 +        return SDLActivity.handleJoystickMotionEvent(event);
   1.152      }
   1.153  }
     2.1 --- a/src/joystick/android/SDL_sysjoystick.c	Mon Nov 11 03:29:11 2013 -0800
     2.2 +++ b/src/joystick/android/SDL_sysjoystick.c	Mon Nov 11 10:15:35 2013 -0300
     2.3 @@ -308,7 +308,10 @@
     2.4  int
     2.5  Android_OnPadDown(int padId, int keycode)
     2.6  {
     2.7 -    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_PRESSED);
     2.8 +    int button = keycode_to_SDL(keycode);
     2.9 +    if (button >= 0) {
    2.10 +        SDL_PrivateJoystickButton(SYS_Joysticks[padId], button , SDL_PRESSED);
    2.11 +    }
    2.12      
    2.13      return 0;
    2.14  }
    2.15 @@ -316,7 +319,10 @@
    2.16  int
    2.17  Android_OnPadUp(int padId, int keycode)
    2.18  {
    2.19 -    SDL_PrivateJoystickButton(SYS_Joysticks[padId], keycode_to_SDL(keycode), SDL_RELEASED);
    2.20 +    int button = keycode_to_SDL(keycode);
    2.21 +    if (button >= 0) {
    2.22 +        SDL_PrivateJoystickButton(SYS_Joysticks[padId], button, SDL_RELEASED);
    2.23 +    }
    2.24      
    2.25      return 0;
    2.26  }