ANDROID: Improve support for gamepads and joysticks

Detect motion on DPAD (HATs), and on right stick as separately from the left stick

Also detect left and right trigger presses (when available)
This commit is contained in:
Antoniou Athanasios 2023-04-04 22:08:30 +03:00 committed by antoniou79
parent fd5a5a2156
commit 12c5b7bb2b
4 changed files with 244 additions and 91 deletions

View File

@ -128,10 +128,10 @@ private:
int _eventScaleX;
int _eventScaleY;
int _touch_mode;
int _touchpad_scale;
int _trackball_scale;
int _dpad_scale;
int _joystick_scale;
int _touchpad_scale; // Used in events.cpp
int _trackball_scale; // Used in events.cpp
int _dpad_scale; // Used in events.cpp
int _joystick_scale; // TODO This seems currently unused. Is it needed?
// int _fingersDown;
int _firstPointerId;
int _secondPointerId;

View File

@ -52,6 +52,19 @@ static inline T scalef(T in, float numerator, float denominator) {
static const int kQueuedInputEventDelay = 50;
// analog joystick axis id (for internal use) - Should match the logic in ScummVMEventsModern.java
enum {
// auxilliary movement axis bitflags
JE_JOY_AXIS_X_bf = 0x01, // (0x01 << 0)
JE_JOY_AXIS_Y_bf = 0x02, // (0x01 << 1)
JE_JOY_AXIS_HAT_X_bf = 0x04, // (0x01 << 2)
JE_JOY_AXIS_HAT_Y_bf = 0x08, // (0x01 << 3)
JE_JOY_AXIS_Z_bf = 0x10, // (0x01 << 4)
JE_JOY_AXIS_RZ_bf = 0x20, // (0x01 << 5)
JE_JOY_AXIS_LTRIGGER_bf = 0x40, // (0x01 << 6)
JE_JOY_AXIS_RTRIGGER_bf = 0x80 // (0x01 << 7)
};
// event type
enum {
JE_SYS_KEY = 0,
@ -1281,21 +1294,69 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
case AMOTION_EVENT_ACTION_MOVE:
e.type = Common::EVENT_JOYAXIS_MOTION;
e.joystick.axis = Common::JOYSTICK_AXIS_LEFT_STICK_X;
e.joystick.position = CLIP<int32>(arg2, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
switch (arg4) {
case JE_JOY_AXIS_X_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_LEFT_STICK_X;
e.joystick.position = CLIP<int32>(arg2, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
break;
e.joystick.axis = Common::JOYSTICK_AXIS_LEFT_STICK_Y;
e.joystick.position = CLIP<int32>(arg3, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
case JE_JOY_AXIS_Y_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_LEFT_STICK_Y;
e.joystick.position = CLIP<int32>(arg2, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
break;
case JE_JOY_AXIS_HAT_X_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_HAT_X;
e.joystick.position = CLIP<int32>(arg2, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
break;
case JE_JOY_AXIS_HAT_Y_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_HAT_Y;
e.joystick.position = CLIP<int32>(arg2, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
break;
case JE_JOY_AXIS_Z_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_RIGHT_STICK_X;
e.joystick.position = CLIP<int32>(arg2, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
break;
case JE_JOY_AXIS_RZ_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_RIGHT_STICK_Y;
e.joystick.position = CLIP<int32>(arg2, Common::JOYAXIS_MIN, Common::JOYAXIS_MAX);
pushEvent(e);
break;
case JE_JOY_AXIS_LTRIGGER_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_LEFT_TRIGGER;
e.joystick.position = CLIP<int32>(arg2, 0, Common::JOYAXIS_MAX);
pushEvent(e);
break;
case JE_JOY_AXIS_RTRIGGER_bf:
e.joystick.axis = Common::JOYSTICK_AXIS_RIGHT_TRIGGER;
e.joystick.position = CLIP<int32>(arg2, 0, Common::JOYAXIS_MAX);
pushEvent(e);
break;
default:
// unsupported axis case
break;
}
break;
case AKEY_EVENT_ACTION_DOWN:
e.type = Common::EVENT_JOYBUTTON_DOWN;
break;
case AKEY_EVENT_ACTION_UP:
e.type = Common::EVENT_JOYBUTTON_UP;
break;
default:
LOGE("unhandled jaction on joystick: %d", arg1);
return;

View File

@ -6,7 +6,6 @@ import android.os.Looper;
import android.os.Message;
import android.content.Context;
//import android.util.Log;
import android.util.Log;
import android.view.KeyEvent;
import android.view.KeyCharacterMap;
import android.view.MotionEvent;
@ -64,8 +63,8 @@ public class ScummVMEventsBase implements
public static final int TOUCH_MODE_GAMEPAD = 2;
public static final int TOUCH_MODE_MAX = 3;
public static final int JOYSTICK_AXIS_MAX = 32767;
public static final float JOYSTICK_AXIS_HAT_SCALE = 0.33f;
public static final int JOYSTICK_AXIS_MAX = 32767; // matches the definition in common/events of "const int16 JOYAXIS_MAX = 32767;"
public static final float JOYSTICK_AXIS_HAT_SCALE = 0.66f; // ie. 2/3 to be applied to JOYSTICK_AXIS_MAX
final protected Context _context;
final protected ScummVM _scummvm;
@ -391,11 +390,12 @@ public class ScummVMEventsBase implements
// We delegate these keypresses to ScummVM's keymapper as JOYSTICK_BUTTON_DPAD presses.
// (JOYSTICK_BUTTON_DPAD_UP, JOYSTICK_BUTTON_DPAD_DOWN, JOYSTICK_BUTTON_DPAD_LEFT, JOYSTICK_BUTTON_DPAD_RIGHT and JOYSTICK_BUTTON_DPAD_CENTER)
// By default mapped to virtual mouse (VMOUSE).
// As virtual mouse, cursor may be too fast/hard to control, so it's recommended to set and use a VMOUSESLOW binding too.
// TODO Maybe add a checkbox in backend to toggle virtual mouse slow/fast, so that the user does not have to press two buttons
// at the same time. (Simultaneous button pressing may work on physical TV remote controls, but may not work on apps for remote controls)
// As virtual mouse, cursor may be too fast/hard to control, so it's recommended to set and use a VMOUSESLOW binding too,
// (Simultaneous button pressing may work on physical TV remote controls, but may not work on apps for remote controls)
// or adjust the Pointer Speed setting from the "Control" tab.
// NOTE 2 Modern gamepads/ game controllers treat the "DPAD" cross buttons as HATs that produce movement events
// and *not* DPAD_UP/DOWN/LEFT/RIGHT button press events. Hence, for those controllers these DPAD key events won't be triggered.
// Those are handled in ScummVMEventsModern class within its onGenericMotionEvent() implementation.
//
// fall-through
case KeyEvent.KEYCODE_BUTTON_A:

View File

@ -44,7 +44,7 @@ public class ScummVMEventsModern extends ScummVMEventsBase {
if(listener != null) {
switch (msg.what) {
case MSG_REPEAT:
if (listener.repeatMove()) {
if (listener.repeatMove(0, false)) {
Message repeat = Message.obtain(this, MSG_REPEAT);
sendMessageDelayed(repeat, REPEAT_INTERVAL);
}
@ -65,8 +65,20 @@ public class ScummVMEventsModern extends ScummVMEventsBase {
}
private ScummVMEventsModernHandler mHandler = new ScummVMEventsModernHandler(this);
private float repeatingX = 0.0f;
private float repeatingY = 0.0f;
private float[] repeatingCenteredAxisValuesArray = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
// auxilliary movement axis bitflags
// Also repeated (and used) in android's events.cpp (JE_JOYSTICK case)
private static final int AXIS_X_bf = 0x01; // (0x01 << 0)
private static final int AXIS_Y_bf = 0x02; // (0x01 << 1)
private static final int AXIS_HAT_X_bf = 0x04; // (0x01 << 2)
private static final int AXIS_HAT_Y_bf = 0x08; // (0x01 << 3)
private static final int AXIS_Z_bf = 0x10; // (0x01 << 4)
private static final int AXIS_RZ_bf = 0x20; // (0x01 << 5)
private static final int AXIS_LTRIGGER_bf = 0x40; // (0x01 << 6)
private static final int AXIS_RTRIGGER_bf = 0x80; // (0x01 << 7)
private int repeatingAxisIdBitFlags = 0x00;
private static float getCenteredAxis(MotionEvent event, InputDevice device, int axisId, int historyPos) {
final InputDevice.MotionRange range = device.getMotionRange(axisId, event.getSource());
@ -78,18 +90,7 @@ public class ScummVMEventsModern extends ScummVMEventsBase {
if (range != null) {
final float axisFlat = range.getFlat();
final float axisMin = range.getMin();
// final float axisMax = range.getMax();
final float axisRange = range.getRange();
// final float axisRes = range.getResolution();
// final float axisFuzz = range.getFuzz();
// if (axisId == MotionEvent.AXIS_X
// || axisId == MotionEvent.AXIS_HAT_X
// || axisId == MotionEvent.AXIS_Z) {
// Log.d(ScummVM.LOG_TAG, "Flat X= " + axisFlat);
// } else {
// Log.d(ScummVM.LOG_TAG, "Flat Y= " + axisFlat);
// }
float axisVal = (historyPos < 0) ? event.getAxisValue( axisId, actionPointerIndex) : event.getHistoricalAxisValue( axisId, actionPointerIndex, historyPos);
// Normalize
@ -98,9 +99,16 @@ public class ScummVMEventsModern extends ScummVMEventsBase {
// Ignore axis values that are within the 'flat' region of the
// joystick axis center.
if (Math.abs(value) > axisFlat) {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") > " + axisFlat + " (flat) - raw val=" + axisVal);
return value;
}
// else {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") <= " + axisFlat + "(flat) - raw val=" + axisVal);
// }
}
// else {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + "- getCenteredAxis() range was null!");
// }
return 0;
}
@ -110,86 +118,169 @@ public class ScummVMEventsModern extends ScummVMEventsBase {
}
}
private boolean repeatMove() {
_scummvm.pushEvent(JE_JOYSTICK, MotionEvent.ACTION_MOVE,
(int) (repeatingX * JOYSTICK_AXIS_MAX),
(int) (repeatingY * JOYSTICK_AXIS_MAX),
0, 0, 0);
private boolean repeatMove(final int axisBitFlags, boolean useArgumentAxis) {
// The argument axisFlags has flags set for the axis that have movement.
// Send pushEvents per axis (with bitflag set) as opposed to using a version of pushEvent with many arguments.
int axisBfs = axisBitFlags;
if (!useArgumentAxis) {
axisBfs = repeatingAxisIdBitFlags;
}
for (int i = 0; i < repeatingCenteredAxisValuesArray.length; ++i) {
if ((axisBfs & (0x01 << i)) != 0) {
_scummvm.pushEvent(JE_JOYSTICK, MotionEvent.ACTION_MOVE,
(int) (repeatingCenteredAxisValuesArray[i] * JOYSTICK_AXIS_MAX),
0,
axisBfs & (0x01 << i), 0, 0);
}
}
return true;
}
private void processJoystickInput(MotionEvent event, int historyPos) {
// TODO: make left stick, right stick, and d-pad distinguishable
// from each other. Also, handle analog triggers.
InputDevice inputDevice = event.getDevice();
// Calculate the horizontal distance to move by
// using the input value from one of these physical controls:
// the left control stick, hat axis, or the right control stick.
float x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos);
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - LEFT: x= " +x);
if (x == 0) {
// reducing to 1/3 since hat axis is non-analog, and 100% of axis max
// is way too fast when used for cursor movement
x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos) * JOYSTICK_AXIS_HAT_SCALE;
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - HAT: x= " +x);
}
if (x == 0) {
x = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos);
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - RIGHT: x= " +x);
}
// // DEBUG LOGGING CODE
// final int actionPointerIndex = event.getActionIndex();
//
// final int[] allAxisIdArray = {MotionEvent.AXIS_X, MotionEvent.AXIS_Y, MotionEvent.AXIS_Z,
// MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, MotionEvent.AXIS_RZ,
// MotionEvent.AXIS_RTRIGGER, MotionEvent.AXIS_LTRIGGER,
// MotionEvent.AXIS_HAT_X, MotionEvent.AXIS_HAT_Y,
// MotionEvent.AXIS_WHEEL, MotionEvent.AXIS_VSCROLL, MotionEvent.AXIS_HSCROLL, MotionEvent.AXIS_SCROLL,
// MotionEvent.AXIS_RELATIVE_X, MotionEvent.AXIS_RELATIVE_Y, MotionEvent.AXIS_DISTANCE,
// MotionEvent.AXIS_THROTTLE, MotionEvent.AXIS_TILT, MotionEvent.AXIS_GAS, MotionEvent.AXIS_BRAKE, MotionEvent.AXIS_RUDDER,
// MotionEvent.AXIS_GENERIC_1, MotionEvent.AXIS_GENERIC_2, MotionEvent.AXIS_GENERIC_3, MotionEvent.AXIS_GENERIC_4,
// MotionEvent.AXIS_GENERIC_5, MotionEvent.AXIS_GENERIC_6, MotionEvent.AXIS_GENERIC_7, MotionEvent.AXIS_GENERIC_8,
// MotionEvent.AXIS_GENERIC_9, MotionEvent.AXIS_GENERIC_10, MotionEvent.AXIS_GENERIC_11, MotionEvent.AXIS_GENERIC_12,
// MotionEvent.AXIS_GENERIC_13, MotionEvent.AXIS_GENERIC_14, MotionEvent.AXIS_GENERIC_15, MotionEvent.AXIS_GENERIC_16};
//
// // These correspond to our bitflags order for movement/repetition
// final String[] axisBitFlagIndexToString = {"LEFT_JOY_X", "LEFT_JOY_Y", "HAT_X", "HAT_Y", "RIGHT_JOY_X", "RIGHT_JOY_Y", "LEFT_TRIGGER", "RIGHT_TRIGGER"};
//
// for (int i = 0; i < allAxisIdArray.length; ++i) {
// float axisVal = event.getAxisValue(allAxisIdArray[i], actionPointerIndex);
// if (Math.abs(axisVal) > 0.0f) {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK MOTION ON AXIS: " + MotionEvent.axisToString(allAxisIdArray[i]) + " id: " + allAxisIdArray[i] + " for (raw): " + axisVal);
// }
// }
// // END OF DEBUG LOGGING CODE
// Calculate the vertical distance to move by
// using the input value from one of these physical controls:
// the left control stick, hat switch, or the right control stick.
float y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos);
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - LEFT: y= " +y);
if (y == 0) {
y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos) * JOYSTICK_AXIS_HAT_SCALE;
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - HAT: y= " +y);
}
if (y == 0) {
y = getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos);
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - RIGHT: y= " +y);
}
// Scaling the HAT movement to 1/3 causes it to be filtered out by the backend (see backends/keymapper/hardware-input.cpp, method: findHardwareInput() )
// ie. "Ignore incomplete presses for remapping purposes" (lower than 1/2 of Common::JOYAXIS_MAX which is defined as 32767 in common/events.h)
// Hence we scale to 2/3 since hat axis is non-analog, and 100% of axis max is way too fast when used for cursor movement
// extra filter to stop repetition in order to avoid cases when android does not send onGenericMotionEvent()
// for small x or y (while abs is still larger than range.getflat())
// In such case we would end up with a slow moving "mouse" cursor - so we need this extra filter
if (Math.abs(x) < 0.2f && Math.abs(y) < 0.2f) {
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - pushEvent(): STOPPED: " + (int)(x * 100) + " y= " + (int)(y * 100));
removeMessages();
// do the move, then signal the joystick has returned to center pos
repeatMove();
repeatingX = 0.0f;
repeatingY = 0.0f;
repeatMove();
} else {
//Log.d(ScummVM.LOG_TAG, "JOYSTICK - pushEvent(): x= " + (int)(x * 100) + " y= " + (int)(y * 100));
if (repeatingX != 0.0f || repeatingY != 0.0f) {
// already repeating - just update the movement co-ords
repeatingX = x;
repeatingY = y;
} else {
// start repeating
//removeMessages();
repeatingX = x;
repeatingY = y;
Message msg = mHandler.obtainMessage(MSG_REPEAT);
mHandler.sendMessageDelayed(msg, REPEAT_START_DELAY);
repeatMove();
// Calculate the distance(s) to move by - for each supported AXIS
// ie. the left control stick, hat switch, the right control stick, or the R/L triggers
// NOTE The order of entries in the moveDistanceArray array is important. It corresponds to our auxilliary movement axis bitflags values order
float[] centeredAxisValuesArray = {getCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos),
getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos),
getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
getCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
getCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos),
getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos),
getCenteredAxis(event, inputDevice, MotionEvent.AXIS_LTRIGGER, historyPos),
getCenteredAxis(event, inputDevice, MotionEvent.AXIS_RTRIGGER, historyPos)};
float currX = 0.0f;
float absCurrX = 0.0f;
float currY = 0.0f;
float absCurrY = 0.0f;
int stoppingMovementAxisIdBitFlags = 0;
int prevRepeatingAxisIdBitFlags = repeatingAxisIdBitFlags;
for (int i = 0; i < centeredAxisValuesArray.length; ++i) {
currX = centeredAxisValuesArray[i];
absCurrX = Math.abs(currX);
// 0-6 we deal with x-axis, y-axis together for LEFT STICK, HAT (DPAD), RIGHT STICK.
if (i < 5) {
currY = centeredAxisValuesArray[i+1];
absCurrY = Math.abs(currY);
}
// TODO Make this limit dependant on the ConfMan joystick_deadzone setting -- but avoid using frequenct JNI to get the value
// The virtual mouse already uses joystick_deadzone to handle input, along with the "kbdmouse_speed". (see backends/keymapper/virtual-mouse.cpp)
// PSP also uses joystick_deadzone for its input so maybe we could do something similar. (see backends/platform/psp/input.cpp).
// If this filtering goes to the native side (eg. in backends/platform/android/events.cpp) we'll still need to somehow update the repeating-axis bitflag.
if (absCurrX < 0.209f
&& (i >= 5 || absCurrY < 0.209f)) {
// When on all the axis for the current contol (or the only axis) we have negligible movement that could still be greater than "flat" range,
// we do extra filter to stop repetition in order to avoid cases when Android does not send onGenericMotionEvent()
// for small x or y (while abs is still greater than range.getflat())!
// In such case we would end up with a slow moving "mouse" cursor - so we need this extra filter.
// If previously we had movement on at least one of the axis for the current control (or the only axis),
// then stop movement, reset values to 0 and clear pertinent repeating axis bitflags.
if ((prevRepeatingAxisIdBitFlags & (0x01 << i)) != 0
|| (i >= 5 && (prevRepeatingAxisIdBitFlags & (0x01 << (i+1))) != 0)) {
// if (i < 5) {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + ", " + axisBitFlagIndexToString[i+1] + "- pushEvent(): STOPPED: x=" + (int)(currX * 100) + " y=" + (int)(currY * 100));
// } else {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + "- pushEvent(): STOPPED: x=" + (int)(currX * 100));
// }
// do the move, then signal the joystick has returned to center pos
stoppingMovementAxisIdBitFlags = 0;
repeatingCenteredAxisValuesArray[i] = currX;
stoppingMovementAxisIdBitFlags |= (0x01 << i);
if (i < 5) {
repeatingCenteredAxisValuesArray[i+1] = currY;
stoppingMovementAxisIdBitFlags |= (0x01 << (i+1));
}
repeatMove(stoppingMovementAxisIdBitFlags, true);
repeatingCenteredAxisValuesArray[i] = 0.0f;
repeatingAxisIdBitFlags &= ~(0x01 << i);
if (i < 5) {
repeatingCenteredAxisValuesArray[i+1] = 0.0f;
repeatingAxisIdBitFlags &= ~(0x01 << (i+1));
}
// This return-to-zero (center pos) is sent as an explicit extra event, so it's considered "movement" on the axis
repeatMove(stoppingMovementAxisIdBitFlags, true);
}
} else {
// Here we have significant movement on at least one of the axis for the current control (or the only axis).
// if (i < 5) {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + ", " + axisBitFlagIndexToString[i+1] + "- update movement: x= " + (int)(currX * 100) + " y= " + (int)(currY * 100));
// } else {
// Log.d(ScummVM.LOG_TAG, "JOYSTICK " + axisBitFlagIndexToString[i] + "- update movement: x= " + (int)(currX * 100));
// }
// We update the axis values (for controls like sticks or hats we update both pertinent axis values here)
// and set the respsective repetition bit flag(s).
repeatingCenteredAxisValuesArray[i] = currX; // X AXIS
repeatingAxisIdBitFlags |= (0x01 << i);
if (i < 5) {
repeatingCenteredAxisValuesArray[i+1] = currY; // Y AXIS
repeatingAxisIdBitFlags |= (0x01 << (i+1));
}
}
if (i < 5) ++i; // skip next index as we handled it already in this case
}
if (repeatingAxisIdBitFlags == 0) {
// Only removeMessages() if all motions are supposed to stop, ie final moving stick/hat/trigger etc???
removeMessages();
} else if (prevRepeatingAxisIdBitFlags == 0) {
// Start repetition message sending (sendMessageDelayed)
Message msg = mHandler.obtainMessage(MSG_REPEAT);
mHandler.sendMessageDelayed(msg, REPEAT_START_DELAY);
repeatMove(repeatingAxisIdBitFlags, true);
}
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
// TODO Make Use of MotionEvent.getToolType() ie. for handling TOOL_TYPE_FINGER/ TOOL_TYPE_MOUSE/ TOOL_TYPE_STYLUS/ TOOL_TYPE_UNKNOWN?
// Check that the event came from a joystick
if (((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK
|| (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0)) {
switch(event.getActionMasked()) {
case MotionEvent.ACTION_MOVE:
InputDevice inputDevice = event.getDevice();
//Log.d(ScummVM.LOG_TAG, "JOYSTICK GENERIC MOTION: MOVE, Devname=" + inputDevice.getName() + " pid=" + inputDevice.getProductId() + " vid=" + inputDevice.getVendorId());
// NOTE In Android 12 (on some early version patch) support for PS5's DualSense broke, and the key mappings are messed up.
// This was fixed in another Android 12 patch, but not all devices got that. (eg Redmi 9 Pro does not have this update)
// Details about this here: https://stackoverflow.com/questions/68190869/dualshock-5-and-android
// Not much we can do about this.
// Process all historical movement samples in the batch
final int historySize = event.getHistorySize();
@ -232,6 +323,7 @@ public class ScummVMEventsModern extends ScummVMEventsBase {
break;
}
}
//Log.d(ScummVM.LOG_TAG, "MOTION NOT HANDLED, source: " + event.getSource() + " event: "+ event.getActionMasked());
// this basically returns false since the super just returns false
return super.onGenericMotionEvent(event);
}