| | |
| | | import java.util.List; |
| | | |
| | | import android.content.Context; |
| | | import android.os.*; |
| | | import android.view.*; |
| | | import android.os.Build; |
| | | import android.os.VibrationEffect; |
| | | import android.os.Vibrator; |
| | | import android.util.Log; |
| | | import android.view.InputDevice; |
| | | import android.view.KeyEvent; |
| | | import android.view.MotionEvent; |
| | | import android.view.View; |
| | | |
| | | |
| | | public class SDLControllerManager |
| | |
| | | int sources = device.getSources(); |
| | | |
| | | /* This is called for every button press, so let's not spam the logs */ |
| | | /** |
| | | /* |
| | | if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { |
| | | Log.v(TAG, "Input device " + device.getName() + " has class joystick."); |
| | | } |
| | |
| | | if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { |
| | | Log.v(TAG, "Input device " + device.getName() + " is a gamepad."); |
| | | } |
| | | **/ |
| | | */ |
| | | |
| | | return ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 || |
| | | ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || |
| | |
| | | } |
| | | } |
| | | |
| | | private ArrayList<SDLJoystick> mJoysticks; |
| | | private final ArrayList<SDLJoystick> mJoysticks; |
| | | |
| | | public SDLJoystickHandler_API16() { |
| | | |
| | |
| | | @Override |
| | | public void pollInputDevices() { |
| | | int[] deviceIds = InputDevice.getDeviceIds(); |
| | | for(int i=0; i < deviceIds.length; ++i) { |
| | | SDLJoystick joystick = getJoystick(deviceIds[i]); |
| | | if (joystick == null) { |
| | | joystick = new SDLJoystick(); |
| | | InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]); |
| | | if (SDLControllerManager.isDeviceSDLJoystick(deviceIds[i])) { |
| | | joystick.device_id = deviceIds[i]; |
| | | |
| | | for (int device_id : deviceIds) { |
| | | if (SDLControllerManager.isDeviceSDLJoystick(device_id)) { |
| | | SDLJoystick joystick = getJoystick(device_id); |
| | | if (joystick == null) { |
| | | InputDevice joystickDevice = InputDevice.getDevice(device_id); |
| | | joystick = new SDLJoystick(); |
| | | joystick.device_id = device_id; |
| | | joystick.name = joystickDevice.getName(); |
| | | joystick.desc = getJoystickDescriptor(joystickDevice); |
| | | joystick.axes = new ArrayList<InputDevice.MotionRange>(); |
| | |
| | | |
| | | List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges(); |
| | | Collections.sort(ranges, new RangeComparator()); |
| | | for (InputDevice.MotionRange range : ranges ) { |
| | | for (InputDevice.MotionRange range : ranges) { |
| | | if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { |
| | | if (range.getAxis() == MotionEvent.AXIS_HAT_X || |
| | | range.getAxis() == MotionEvent.AXIS_HAT_Y) { |
| | | if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) { |
| | | joystick.hats.add(range); |
| | | } |
| | | else { |
| | | } else { |
| | | joystick.axes.add(range); |
| | | } |
| | | } |
| | | } |
| | | |
| | | mJoysticks.add(joystick); |
| | | SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, getVendorId(joystickDevice), getProductId(joystickDevice), false, getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0); |
| | | SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, |
| | | getVendorId(joystickDevice), getProductId(joystickDevice), false, |
| | | getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* Check removed devices */ |
| | | ArrayList<Integer> removedDevices = new ArrayList<Integer>(); |
| | | for(int i=0; i < mJoysticks.size(); i++) { |
| | | int device_id = mJoysticks.get(i).device_id; |
| | | int j; |
| | | for (j=0; j < deviceIds.length; j++) { |
| | | if (device_id == deviceIds[j]) break; |
| | | ArrayList<Integer> removedDevices = null; |
| | | for (SDLJoystick joystick : mJoysticks) { |
| | | int device_id = joystick.device_id; |
| | | int i; |
| | | for (i = 0; i < deviceIds.length; i++) { |
| | | if (device_id == deviceIds[i]) break; |
| | | } |
| | | if (j == deviceIds.length) { |
| | | removedDevices.add(Integer.valueOf(device_id)); |
| | | if (i == deviceIds.length) { |
| | | if (removedDevices == null) { |
| | | removedDevices = new ArrayList<Integer>(); |
| | | } |
| | | removedDevices.add(device_id); |
| | | } |
| | | } |
| | | |
| | | for(int i=0; i < removedDevices.size(); i++) { |
| | | int device_id = removedDevices.get(i).intValue(); |
| | | SDLControllerManager.nativeRemoveJoystick(device_id); |
| | | for (int j=0; j < mJoysticks.size(); j++) { |
| | | if (mJoysticks.get(j).device_id == device_id) { |
| | | mJoysticks.remove(j); |
| | | break; |
| | | if (removedDevices != null) { |
| | | for (int device_id : removedDevices) { |
| | | SDLControllerManager.nativeRemoveJoystick(device_id); |
| | | for (int i = 0; i < mJoysticks.size(); i++) { |
| | | if (mJoysticks.get(i).device_id == device_id) { |
| | | mJoysticks.remove(i); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | protected SDLJoystick getJoystick(int device_id) { |
| | | for(int i=0; i < mJoysticks.size(); i++) { |
| | | if (mJoysticks.get(i).device_id == device_id) { |
| | | return mJoysticks.get(i); |
| | | for (SDLJoystick joystick : mJoysticks) { |
| | | if (joystick.device_id == device_id) { |
| | | return joystick; |
| | | } |
| | | } |
| | | return null; |
| | |
| | | if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) { |
| | | int actionPointerIndex = event.getActionIndex(); |
| | | int action = event.getActionMasked(); |
| | | switch(action) { |
| | | case MotionEvent.ACTION_MOVE: |
| | | SDLJoystick joystick = getJoystick(event.getDeviceId()); |
| | | if ( joystick != null ) { |
| | | 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; |
| | | SDLControllerManager.onNativeJoy(joystick.device_id, i, value ); |
| | | } |
| | | for (int i = 0; i < joystick.hats.size(); i+=2) { |
| | | int hatX = Math.round(event.getAxisValue( joystick.hats.get(i).getAxis(), actionPointerIndex ) ); |
| | | int hatY = Math.round(event.getAxisValue( joystick.hats.get(i+1).getAxis(), actionPointerIndex ) ); |
| | | SDLControllerManager.onNativeHat(joystick.device_id, i/2, hatX, hatY ); |
| | | } |
| | | if (action == MotionEvent.ACTION_MOVE) { |
| | | SDLJoystick joystick = getJoystick(event.getDeviceId()); |
| | | if (joystick != null) { |
| | | 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; |
| | | SDLControllerManager.onNativeJoy(joystick.device_id, i, value); |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | for (int i = 0; i < joystick.hats.size() / 2; i++) { |
| | | int hatX = Math.round(event.getAxisValue(joystick.hats.get(2 * i).getAxis(), actionPointerIndex)); |
| | | int hatY = Math.round(event.getAxisValue(joystick.hats.get(2 * i + 1).getAxis(), actionPointerIndex)); |
| | | SDLControllerManager.onNativeHat(joystick.device_id, i, hatX, hatY); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return true; |
| | |
| | | |
| | | class SDLHapticHandler { |
| | | |
| | | class SDLHaptic { |
| | | static class SDLHaptic { |
| | | public int device_id; |
| | | public String name; |
| | | public Vibrator vib; |
| | | } |
| | | |
| | | private ArrayList<SDLHaptic> mHaptics; |
| | | private final ArrayList<SDLHaptic> mHaptics; |
| | | |
| | | public SDLHapticHandler() { |
| | | mHaptics = new ArrayList<SDLHaptic>(); |
| | |
| | | } |
| | | |
| | | /* Check removed devices */ |
| | | ArrayList<Integer> removedDevices = new ArrayList<Integer>(); |
| | | for(int i=0; i < mHaptics.size(); i++) { |
| | | int device_id = mHaptics.get(i).device_id; |
| | | int j; |
| | | for (j=0; j < deviceIds.length; j++) { |
| | | if (device_id == deviceIds[j]) break; |
| | | ArrayList<Integer> removedDevices = null; |
| | | for (SDLHaptic haptic : mHaptics) { |
| | | int device_id = haptic.device_id; |
| | | int i; |
| | | for (i = 0; i < deviceIds.length; i++) { |
| | | if (device_id == deviceIds[i]) break; |
| | | } |
| | | |
| | | if (device_id == deviceId_VIBRATOR_SERVICE && hasVibratorService) { |
| | | // don't remove the vibrator if it is still present |
| | | } else if (j == deviceIds.length) { |
| | | removedDevices.add(device_id); |
| | | } |
| | | if (device_id != deviceId_VIBRATOR_SERVICE || !hasVibratorService) { |
| | | if (i == deviceIds.length) { |
| | | if (removedDevices == null) { |
| | | removedDevices = new ArrayList<Integer>(); |
| | | } |
| | | removedDevices.add(device_id); |
| | | } |
| | | } // else: don't remove the vibrator if it is still present |
| | | } |
| | | |
| | | for(int i=0; i < removedDevices.size(); i++) { |
| | | int device_id = removedDevices.get(i); |
| | | SDLControllerManager.nativeRemoveHaptic(device_id); |
| | | for (int j=0; j < mHaptics.size(); j++) { |
| | | if (mHaptics.get(j).device_id == device_id) { |
| | | mHaptics.remove(j); |
| | | break; |
| | | if (removedDevices != null) { |
| | | for (int device_id : removedDevices) { |
| | | SDLControllerManager.nativeRemoveHaptic(device_id); |
| | | for (int i = 0; i < mHaptics.size(); i++) { |
| | | if (mHaptics.get(i).device_id == device_id) { |
| | | mHaptics.remove(i); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | protected SDLHaptic getHaptic(int device_id) { |
| | | for(int i=0; i < mHaptics.size(); i++) { |
| | | if (mHaptics.get(i).device_id == device_id) { |
| | | return mHaptics.get(i); |
| | | for (SDLHaptic haptic : mHaptics) { |
| | | if (haptic.device_id == device_id) { |
| | | return haptic; |
| | | } |
| | | } |
| | | return null; |
| | |
| | | public float getEventX(MotionEvent event) { |
| | | if (mRelativeModeEnabled) { |
| | | return event.getAxisValue(MotionEvent.AXIS_RELATIVE_X); |
| | | } |
| | | else { |
| | | } else { |
| | | return event.getX(0); |
| | | } |
| | | } |
| | |
| | | public float getEventY(MotionEvent event) { |
| | | if (mRelativeModeEnabled) { |
| | | return event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y); |
| | | } |
| | | else { |
| | | } else { |
| | | return event.getY(0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 { |
| | | // Generic Motion (mouse hover, joystick...) events go here |
| | |
| | | if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) { |
| | | if (enabled) { |
| | | SDLActivity.getContentView().requestPointerCapture(); |
| | | } |
| | | else { |
| | | } else { |
| | | SDLActivity.getContentView().releasePointerCapture(); |
| | | } |
| | | mRelativeModeEnabled = enabled; |
| | | return true; |
| | | } |
| | | else |
| | | { |
| | | } else { |
| | | return false; |
| | | } |
| | | } |