diff --git a/3rdParty/SDL2/CMakeLists.txt b/3rdParty/SDL2/CMakeLists.txt index 32117e506..97d057a9a 100644 --- a/3rdParty/SDL2/CMakeLists.txt +++ b/3rdParty/SDL2/CMakeLists.txt @@ -15,7 +15,7 @@ set(SDL_TEST_ENABLED_BY_DEFAULT OFF) include(functions/FetchContent_MakeAvailableExcludeFromAll) include(FetchContent) FetchContent_Declare(SDL2 - URL https://github.com/libsdl-org/SDL/archive/5d1e6b28d9c97e5223281c0f0189f6c99a564b70.tar.gz - URL_HASH MD5=44c74cf0a55cccba738c5c4271bd23cd + URL https://github.com/libsdl-org/SDL/archive/8b39eb9b1ff885978816dd9663277608187e8676.tar.gz + URL_HASH MD5=3cf9bf5f20375aa5dcc529193c809967 ) FetchContent_MakeAvailableExcludeFromAll(SDL2) diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java index b5e243f33..30e9416a4 100644 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java @@ -170,7 +170,7 @@ public class HIDDeviceManager { Log.i(TAG," Interface protocol: " + mUsbInterface.getInterfaceProtocol()); Log.i(TAG," Endpoint count: " + mUsbInterface.getEndpointCount()); - // Get endpoint details + // Get endpoint details for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++) { UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi); @@ -277,6 +277,7 @@ public class HIDDeviceManager { 0x0738, // Mad Catz 0x0e6f, // PDP 0x0f0d, // Hori + 0x10f5, // Turtle Beach 0x1532, // Razer Wildcat 0x20d6, // PowerA 0x24c6, // PowerA @@ -526,7 +527,7 @@ public class HIDDeviceManager { for (HIDDevice device : mDevicesById.values()) { device.setFrozen(frozen); } - } + } } ////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java index 82373d9d6..85ecbded4 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java @@ -24,7 +24,7 @@ public class SDLControllerManager public static native int nativeAddJoystick(int device_id, String name, String desc, int vendor_id, int product_id, boolean is_accelerometer, int button_mask, - int naxes, int nhats, int nballs); + int naxes, int axis_mask, int nhats, int nballs); public static native int nativeRemoveJoystick(int device_id); public static native int nativeAddHaptic(int device_id, String name); public static native int nativeRemoveHaptic(int device_id); @@ -168,6 +168,32 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler { arg1Axis = MotionEvent.AXIS_GAS; } + // Make sure the AXIS_Z is sorted between AXIS_RY and AXIS_RZ. + // This is because the usual pairing are: + // - AXIS_X + AXIS_Y (left stick). + // - AXIS_RX, AXIS_RY (sometimes the right stick, sometimes triggers). + // - AXIS_Z, AXIS_RZ (sometimes the right stick, sometimes triggers). + // This sorts the axes in the above order, which tends to be correct + // for Xbox-ish game pads that have the right stick on RX/RY and the + // triggers on Z/RZ. + // + // Gamepads that don't have AXIS_Z/AXIS_RZ but use + // AXIS_LTRIGGER/AXIS_RTRIGGER are unaffected by this. + // + // References: + // - https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input + // - https://www.kernel.org/doc/html/latest/input/gamepad.html + if (arg0Axis == MotionEvent.AXIS_Z) { + arg0Axis = MotionEvent.AXIS_RZ - 1; + } else if (arg0Axis > MotionEvent.AXIS_Z && arg0Axis < MotionEvent.AXIS_RZ) { + --arg0Axis; + } + if (arg1Axis == MotionEvent.AXIS_Z) { + arg1Axis = MotionEvent.AXIS_RZ - 1; + } else if (arg1Axis > MotionEvent.AXIS_Z && arg1Axis < MotionEvent.AXIS_RZ) { + --arg1Axis; + } + return arg0Axis - arg1Axis; } } @@ -210,7 +236,7 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler { 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); + getButtonMask(joystickDevice), joystick.axes.size(), getAxisMask(joystick.axes), joystick.hats.size()/2, 0); } } } @@ -291,6 +317,9 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler { public int getVendorId(InputDevice joystickDevice) { return 0; } + public int getAxisMask(List ranges) { + return -1; + } public int getButtonMask(InputDevice joystickDevice) { return -1; } @@ -308,6 +337,43 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 { return joystickDevice.getVendorId(); } + @Override + public int getAxisMask(List ranges) { + // For compatibility, keep computing the axis mask like before, + // only really distinguishing 2, 4 and 6 axes. + int axis_mask = 0; + if (ranges.size() >= 2) { + // ((1 << SDL_GAMEPAD_AXIS_LEFTX) | (1 << SDL_GAMEPAD_AXIS_LEFTY)) + axis_mask |= 0x0003; + } + if (ranges.size() >= 4) { + // ((1 << SDL_GAMEPAD_AXIS_RIGHTX) | (1 << SDL_GAMEPAD_AXIS_RIGHTY)) + axis_mask |= 0x000c; + } + if (ranges.size() >= 6) { + // ((1 << SDL_GAMEPAD_AXIS_LEFT_TRIGGER) | (1 << SDL_GAMEPAD_AXIS_RIGHT_TRIGGER)) + axis_mask |= 0x0030; + } + // Also add an indicator bit for whether the sorting order has changed. + // This serves to disable outdated gamecontrollerdb.txt mappings. + boolean have_z = false; + boolean have_past_z_before_rz = false; + for (InputDevice.MotionRange range : ranges) { + int axis = range.getAxis(); + if (axis == MotionEvent.AXIS_Z) { + have_z = true; + } else if (axis > MotionEvent.AXIS_Z && axis < MotionEvent.AXIS_RZ) { + have_past_z_before_rz = true; + } + } + if (have_z && have_past_z_before_rz) { + // If both these exist, the compare() function changed sorting order. + // Set a bit to indicate this fact. + axis_mask |= 0x8000; + } + return axis_mask; + } + @Override public int getButtonMask(InputDevice joystickDevice) { int button_mask = 0; diff --git a/android-project/gradlew b/android-project/gradlew index 9d82f7891..3427607f4 100755 --- a/android-project/gradlew +++ b/android-project/gradlew @@ -126,8 +126,8 @@ if $cygwin ; then # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + CHECK=`echo "$arg"|grep -E -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|grep -E -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`