[Scummvm-git-logs] scummvm master -> c7584e6f7fb1cf4c6ac93254595ad8e2241f0bc6
lephilousophe
noreply at scummvm.org
Tue Nov 12 21:40:08 UTC 2024
This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
76e69a770c ANDROID: Upgrade Gradle and Android Gradle Plugin
08f1383dc9 ANDROID: Use PointerIcon.TYPE_ARROW
fd3410ddd8 ANDROID: Align sections on 16K
5d58196643 ANDROID: Merge ScummVMEventsModern and ScummVMEventsBase
9a365241f9 ANDROID: Store the ScummVMActivity object in ScummVMEvents
5ea3ac6d51 ANDROID: Add support for predictive back gestures
a1393fac6b ANDROID: Target API level 35: Android 15 (Vanilla Ice Cream)
cc6a069c69 ANDROID: Rework the insets helper to handle cutouts and system bars
d9dcf93f65 ANDROID: Make ShortcutCreatorActivity edge-to-edge compliant
ac21b373e1 ANDROID: Make SplashActivity edge-to-edge compliant
c7584e6f7f ANDROID: Make custom shortcuts really custom
Commit: 76e69a770cbb40ec176babeaa0d18a2d91cec4ff
https://github.com/scummvm/scummvm/commit/76e69a770cbb40ec176babeaa0d18a2d91cec4ff
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Upgrade Gradle and Android Gradle Plugin
Changed paths:
dists/android/build.gradle
dists/android/gradle/wrapper/gradle-wrapper.properties
diff --git a/dists/android/build.gradle b/dists/android/build.gradle
index b65e04c2812..ba262c63f3d 100644
--- a/dists/android/build.gradle
+++ b/dists/android/build.gradle
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.5.1'
+ classpath 'com.android.tools.build:gradle:8.7.2'
}
}
diff --git a/dists/android/gradle/wrapper/gradle-wrapper.properties b/dists/android/gradle/wrapper/gradle-wrapper.properties
index b82aa23a4f0..df97d72b8b9 100644
--- a/dists/android/gradle/wrapper/gradle-wrapper.properties
+++ b/dists/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Commit: 08f1383dc9ae230f5606ef6ade7bbc368809c56b
https://github.com/scummvm/scummvm/commit/08f1383dc9ae230f5606ef6ade7bbc368809c56b
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Use PointerIcon.TYPE_ARROW
PointerIcon.TYPE_DEFAULT is deprecated and has always been equal to
TYPE_ARROW.
Changed paths:
backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
diff --git a/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java b/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
index ff80eb7c1e4..42c9c6a82d3 100644
--- a/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
+++ b/backends/platform/android/org/scummvm/scummvm/EditableSurfaceView.java
@@ -302,7 +302,7 @@ public class EditableSurfaceView extends SurfaceView {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Android N (Nougat) is Android 7.0
//SurfaceView main_surface = findViewById(R.id.main_surface);
- int type = show ? PointerIcon.TYPE_DEFAULT : PointerIcon.TYPE_NULL;
+ int type = show ? PointerIcon.TYPE_ARROW : PointerIcon.TYPE_NULL;
// https://stackoverflow.com/a/55482761
//Log.d(ScummVM.LOG_TAG, "captureMouse::showSystemMouseCursor3a");
setPointerIcon(PointerIcon.getSystemIcon(_context, type));
@@ -334,10 +334,10 @@ public class EditableSurfaceView extends SurfaceView {
if (_mouseIsInCapturedState) {
return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_NULL);
} else {
- return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_DEFAULT);
+ return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_ARROW);
}
} else {
- return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_DEFAULT);
+ return PointerIcon.getSystemIcon(_context, PointerIcon.TYPE_ARROW);
}
}
Commit: fd3410ddd84967406ec1e9ace7c918e323400234
https://github.com/scummvm/scummvm/commit/fd3410ddd84967406ec1e9ace7c918e323400234
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Align sections on 16K
This is needed for the future Android devices making use of 16K pages
Changed paths:
configure
diff --git a/configure b/configure
index 77011568651..482269b992b 100755
--- a/configure
+++ b/configure
@@ -3962,6 +3962,8 @@ case $_backend in
append_var INCLUDES '-I$(srcdir)/backends/platform/'$_backend
append_var CXXFLAGS "-Wa,--noexecstack"
append_var LDFLAGS "-Wl,-z,noexecstack"
+ # Newer Android devices will have 16K pages so we must be aligned
+ append_var LDFLAGS "-Wl,-z,max-page-size=16384"
# removed the following directive - was causing compilation issues when not also explicitly using --disable-mt32emu
# append_var INCLUDES "-isystem $ANDROID_NDK/sources/cxx-stl/system/include"
_sdl=no
Commit: 5d5819664334078a8f18bfcb2d5e8b5c67b0d9fb
https://github.com/scummvm/scummvm/commit/5d5819664334078a8f18bfcb2d5e8b5c67b0d9fb
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Merge ScummVMEventsModern and ScummVMEventsBase
The split was done to allow to support versions before HONEYCOMB_MR1 but
we don't support these versions anymore.
Changed paths:
A backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
R backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
R backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java
backends/platform/android/events.cpp
backends/platform/android/org/scummvm/scummvm/MouseHelper.java
backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp
index 6b6328671bc..65b0e96f970 100644
--- a/backends/platform/android/events.cpp
+++ b/backends/platform/android/events.cpp
@@ -48,7 +48,7 @@ static inline T scalef(T in, float numerator, float denominator) {
return static_cast<float>(in) * numerator / denominator;
}
-// analog joystick axis id (for internal use) - Should match the logic in ScummVMEventsModern.java
+// analog joystick axis id (for internal use) - Should match the logic in ScummVMEvents.java
enum {
// auxiliary movement axis bitflags
JE_JOY_AXIS_X_bf = 0x01, // (0x01 << 0)
@@ -853,9 +853,9 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
// arg2 = mouse y
// arg3 = AMOTION_EVENT_ACTION_DOWN, AMOTION_EVENT_ACTION_UP, AMOTION_EVENT_ACTION_MOVE
// NOTE: Typically in a double tap event:
- // Before the ACTION_DOWN event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEventsBase's onDown())
- // and then a JE_TAP event (action UP) via ScummVMEventsBase's onSingleTapUp().
- // Before the ACTION_UP event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEventsBase's onDown()).
+ // Before the ACTION_DOWN event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEvents's onDown())
+ // and then a JE_TAP event (action UP) via ScummVMEvents's onSingleTapUp().
+ // Before the ACTION_UP event, we also have ALREADY pushed a JE_DOWN event (via ScummVMEvents's onDown()).
// LOGD("JE_DOUBLE_TAP - x: %d y: %d, arg3: %d", arg1, arg2, arg3);
ev0.type = Common::EVENT_MOUSEMOVE;
diff --git a/backends/platform/android/org/scummvm/scummvm/MouseHelper.java b/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
index a8d2b1f6e8e..cde26ef1b41 100644
--- a/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
+++ b/backends/platform/android/org/scummvm/scummvm/MouseHelper.java
@@ -182,18 +182,18 @@ public class MouseHelper implements View.OnHoverListener {
@SuppressLint("InlinedApi")
public boolean onMouseEvent(MotionEvent e, boolean hover) {
- _scummvm.pushEvent(ScummVMEventsBase.JE_MOUSE_MOVE,
+ _scummvm.pushEvent(ScummVMEvents.JE_MOUSE_MOVE,
(int) e.getX(),
(int) e.getY(),
0,
0, 0, 0);
if (e.getActionMasked() == MotionEvent.ACTION_SCROLL) {
- // The call is coming from ScummVMEventsModern, from a GenericMotionEvent (scroll wheel movement)
+ // The call is coming from ScummVMEvents, from a GenericMotionEvent (scroll wheel movement)
// TODO Do we want the JE_MOUSE_MOVE event too in this case?
- int eventJEWheelUpDown = ScummVMEventsBase.JE_MOUSE_WHEEL_UP;
+ int eventJEWheelUpDown = ScummVMEvents.JE_MOUSE_WHEEL_UP;
if (e.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f) {
- eventJEWheelUpDown = ScummVMEventsBase.JE_MOUSE_WHEEL_DOWN;
+ eventJEWheelUpDown = ScummVMEvents.JE_MOUSE_WHEEL_DOWN;
}
//Log.d(ScummVM.LOG_TAG, "onMouseEvent Wheel Up/Down = " + eventJEWheelUpDown);
_scummvm.pushEvent(eventJEWheelUpDown,
@@ -217,31 +217,31 @@ public class MouseHelper implements View.OnHoverListener {
if (lmbDown) {
if (!_lmbPressed) {
// left mouse button was pressed just now
- _scummvm.pushEvent(ScummVMEventsBase.JE_LMB_DOWN, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
+ _scummvm.pushEvent(ScummVMEvents.JE_LMB_DOWN, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
}
_lmbPressed = true;
} else {
if (_lmbPressed) {
// left mouse button was released just now
- _scummvm.pushEvent(ScummVMEventsBase.JE_LMB_UP, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
+ _scummvm.pushEvent(ScummVMEvents.JE_LMB_UP, (int)e.getX(), (int)e.getY(), e.getButtonState(), 0, 0, 0);
}
_lmbPressed = false;
}
- _rmbPressed = handleButton(e, _rmbPressed, MotionEvent.BUTTON_SECONDARY, ScummVMEventsBase.JE_RMB_DOWN, ScummVMEventsBase.JE_RMB_UP);
- _mmbPressed = handleButton(e, _mmbPressed, MotionEvent.BUTTON_TERTIARY, ScummVMEventsBase.JE_MMB_DOWN, ScummVMEventsBase.JE_MMB_UP);
- _bmbPressed = handleButton(e, _bmbPressed, MotionEvent.BUTTON_BACK, ScummVMEventsBase.JE_BMB_DOWN, ScummVMEventsBase.JE_BMB_UP);
- _fmbPressed = handleButton(e, _fmbPressed, MotionEvent.BUTTON_FORWARD, ScummVMEventsBase.JE_FMB_DOWN, ScummVMEventsBase.JE_FMB_UP);
+ _rmbPressed = handleButton(e, _rmbPressed, MotionEvent.BUTTON_SECONDARY, ScummVMEvents.JE_RMB_DOWN, ScummVMEvents.JE_RMB_UP);
+ _mmbPressed = handleButton(e, _mmbPressed, MotionEvent.BUTTON_TERTIARY, ScummVMEvents.JE_MMB_DOWN, ScummVMEvents.JE_MMB_UP);
+ _bmbPressed = handleButton(e, _bmbPressed, MotionEvent.BUTTON_BACK, ScummVMEvents.JE_BMB_DOWN, ScummVMEvents.JE_BMB_UP);
+ _fmbPressed = handleButton(e, _fmbPressed, MotionEvent.BUTTON_FORWARD, ScummVMEvents.JE_FMB_DOWN, ScummVMEvents.JE_FMB_UP);
// Lint warning for BUTTON_STYLUS... "
// Field requires API level 23 (current min is 16): android.view.MotionEvent#BUTTON_STYLUS_PRIMARY"
// Field requires API level 23 (current min is 16): android.view.MotionEvent#BUTTON_STYLUS_SECONDARY"
// We suppress it:
//
// https://stackoverflow.com/a/48588149
- _srmbPressed = handleButton(e, _srmbPressed, MotionEvent.BUTTON_STYLUS_PRIMARY, ScummVMEventsBase.JE_RMB_DOWN, ScummVMEventsBase.JE_RMB_UP);
- _smmbPressed = handleButton(e, _smmbPressed, MotionEvent.BUTTON_STYLUS_SECONDARY, ScummVMEventsBase.JE_MMB_DOWN, ScummVMEventsBase.JE_MMB_UP);
+ _srmbPressed = handleButton(e, _srmbPressed, MotionEvent.BUTTON_STYLUS_PRIMARY, ScummVMEvents.JE_RMB_DOWN, ScummVMEvents.JE_RMB_UP);
+ _smmbPressed = handleButton(e, _smmbPressed, MotionEvent.BUTTON_STYLUS_SECONDARY, ScummVMEvents.JE_MMB_DOWN, ScummVMEvents.JE_MMB_UP);
}
return true;
}
diff --git a/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java b/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
index 5aa81511063..ba896691198 100644
--- a/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
+++ b/backends/platform/android/org/scummvm/scummvm/MultitouchHelper.java
@@ -1,9 +1,9 @@
package org.scummvm.scummvm;
-import static org.scummvm.scummvm.ScummVMEventsBase.JE_MOUSE_WHEEL_DOWN;
-import static org.scummvm.scummvm.ScummVMEventsBase.JE_MOUSE_WHEEL_UP;
-import static org.scummvm.scummvm.ScummVMEventsBase.JE_MULTI;
+import static org.scummvm.scummvm.ScummVMEvents.JE_MOUSE_WHEEL_DOWN;
+import static org.scummvm.scummvm.ScummVMEvents.JE_MOUSE_WHEEL_UP;
+import static org.scummvm.scummvm.ScummVMEvents.JE_MULTI;
import android.os.Handler;
import android.os.Looper;
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index f56f63efd69..a792ea29654 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -610,13 +610,13 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
resId = R.drawable.ic_action_keyboard;
} else {
switch(touchMode) {
- case ScummVMEventsBase.TOUCH_MODE_TOUCHPAD:
+ case ScummVMEvents.TOUCH_MODE_TOUCHPAD:
resId = R.drawable.ic_action_touchpad;
break;
- case ScummVMEventsBase.TOUCH_MODE_MOUSE:
+ case ScummVMEvents.TOUCH_MODE_MOUSE:
resId = R.drawable.ic_action_mouse;
break;
- case ScummVMEventsBase.TOUCH_MODE_GAMEPAD:
+ case ScummVMEvents.TOUCH_MODE_GAMEPAD:
resId = R.drawable.ic_action_gamepad;
break;
default:
@@ -663,7 +663,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
public void onClick(View v) {
runOnUiThread(new Runnable() {
public void run() {
- _scummvm.pushEvent(ScummVMEventsBase.JE_MENU, 0, 0, 0, 0, 0, 0);
+ _scummvm.pushEvent(ScummVMEvents.JE_MENU, 0, 0, 0, 0, 0, 0);
}
});
}
@@ -900,7 +900,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
}
private MyScummVM _scummvm;
- private ScummVMEventsBase _events;
+ private ScummVMEvents _events;
private MouseHelper _mouseHelper;
private Thread _scummvm_thread;
@@ -1031,11 +1031,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
//_mouseHelper.attach(_main_surface);
}
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
- _events = new ScummVMEventsModern(this, _scummvm, _mouseHelper);
- } else {
- _events = new ScummVMEventsBase(this, _scummvm, _mouseHelper);
- }
+ _events = new ScummVMEvents(this, _scummvm, _mouseHelper);
setupTouchModeBtn(_events.getTouchMode());
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
similarity index 63%
rename from backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
rename to backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index 65f1fce55a3..8ba7614b172 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -9,6 +9,7 @@ import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
+import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -17,7 +18,7 @@ import androidx.annotation.NonNull;
import java.lang.ref.WeakReference;
-public class ScummVMEventsBase implements
+public class ScummVMEvents implements
android.view.View.OnKeyListener,
android.view.View.OnTouchListener,
android.view.GestureDetector.OnGestureListener,
@@ -64,6 +65,23 @@ public class ScummVMEventsBase implements
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
+ // auxiliary movement axis bitflags
+ // Also repeated (and used) in android's events.cpp (JE_JOYSTICK case)
+ private static final int JOYSTICK_AXIS_X_bf = 0x01; // (0x01 << 0)
+ private static final int JOYSTICK_AXIS_Y_bf = 0x02; // (0x01 << 1)
+ private static final int JOYSTICK_AXIS_HAT_X_bf = 0x04; // (0x01 << 2)
+ private static final int JOYSTICK_AXIS_HAT_Y_bf = 0x08; // (0x01 << 3)
+ private static final int JOYSTICK_AXIS_Z_bf = 0x10; // (0x01 << 4)
+ private static final int JOYSTICK_AXIS_RZ_bf = 0x20; // (0x01 << 5)
+ private static final int JOYSTICK_AXIS_LTRIGGER_bf = 0x40; // (0x01 << 6)
+ private static final int JOYSTICK_AXIS_RTRIGGER_bf = 0x80; // (0x01 << 7)
+
+ private static final int REPEAT_INTERVAL = 20; // ~50 keys per second
+ private static final int REPEAT_START_DELAY = 40;
+
+ private final float[] _repeatingJoystickCenteredAxisValuesArray = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
+ private int _repeatingJoystickAxisIdBitFlags = 0x00;
+
final protected Context _context;
final protected ScummVM _scummvm;
final protected GestureDetector _gd;
@@ -80,18 +98,28 @@ public class ScummVMEventsBase implements
// https://stackoverflow.com/a/27826094
public static class ScummVMEventHandler extends Handler {
- private final WeakReference<ScummVMEventsBase> mListenerReference;
+ private final WeakReference<ScummVMEvents> mListenerReference;
- public ScummVMEventHandler(ScummVMEventsBase listener) {
+ public ScummVMEventHandler(ScummVMEvents listener) {
super(Looper.getMainLooper());
mListenerReference = new WeakReference<>(listener);
}
@Override
public synchronized void handleMessage(@NonNull Message msg) {
- ScummVMEventsBase listener = mListenerReference.get();
+ ScummVMEvents listener = mListenerReference.get();
if(listener != null) {
- listener.handleEVHMessage(msg);
+ switch (msg.what) {
+ case MSG_REPEAT:
+ if (listener.repeatMove(0, false)) {
+ Message repeat = Message.obtain(this, MSG_REPEAT);
+ sendMessageDelayed(repeat, REPEAT_INTERVAL);
+ }
+ break;
+ default:
+ listener.handleEVHMessage(msg);
+ break;
+ }
}
}
@@ -112,7 +140,7 @@ public class ScummVMEventsBase implements
// return new ScummVMEventHandler(this);
// }
- public ScummVMEventsBase(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
+ public ScummVMEvents(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
_context = context;
_scummvm = scummvm;
// Careful, _mouseHelper can be null (if HoverListener is not available for the device API -- old devices, API < 9)
@@ -131,6 +159,7 @@ public class ScummVMEventsBase implements
final static int MSG_SMENU_LONG_PRESS = 1;
final static int MSG_SBACK_LONG_PRESS = 2;
final static int MSG_LONG_TOUCH_EVENT = 3;
+ final static int MSG_REPEAT = 4;
private void handleEVHMessage(final Message msg) {
if (msg.what == MSG_SMENU_LONG_PRESS) {
@@ -214,8 +243,63 @@ public class ScummVMEventsBase implements
return true;
}
- public boolean onGenericMotionEvent(MotionEvent e) {
- // we don't manage the GenericMotionEvent
+ 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();
+
+ // Process the movements starting from the
+ // earliest historical position in the batch
+ for (int i = 0; i < historySize; ++i) {
+ // Process the event at historical position i
+ //Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m) hist: ");
+ processJoystickInput(event, i);
+ }
+
+ // Process the current movement sample in the batch (position -1)
+ //Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m): " );
+ processJoystickInput(event, -1);
+ return true;
+
+ default:
+ break;
+ }
+ } else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ //Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - onGenericMotionEvent(m) ");
+ //
+ // Check that the event might be a mouse scroll wheel (ACTION_SCROLL)
+ // Code inspired from https://stackoverflow.com/a/33086042
+ //
+ // NOTE Other GenericMotionEvent are also triggered for InputDevice of SOURCE_CLASS_POINTER (eg. physical mouse).
+ // These seem to be for button down/up events, which are handled along with pushing a JE_MOVE event
+ // in MouseHelper's onMouseEvent() called from onTouch().
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_SCROLL:
+ //Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - ACTION SCROLL");
+ // This action is not a touch event so it is delivered to
+ // View#onGenericMotionEvent(MotionEvent) rather than View#onTouchEvent(MotionEvent).
+ if (_mouseHelper != null) {
+ return _mouseHelper.onMouseEvent(event, false);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ //Log.d(ScummVM.LOG_TAG, "MOTION NOT HANDLED, source: " + event.getSource() + " event: "+ event.getActionMasked());
return false;
}
@@ -377,7 +461,7 @@ public class ScummVMEventsBase implements
// 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.
+ // Those are handled within onGenericMotionEvent().
//
if ((e.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD) {
type = JE_KEY;
@@ -718,4 +802,181 @@ public class ScummVMEventsBase implements
// Log.d(ScummVM.LOG_TAG, "onSingleTapConfirmed - double tap failed");
return true;
}
+
+ private static float getJoystickCenteredAxis(MotionEvent event, InputDevice device, int axisId, int historyPos) {
+ final InputDevice.MotionRange range = device.getMotionRange(axisId, event.getSource());
+ final int actionPointerIndex = event.getActionIndex();
+
+ // A joystick at rest does not always report an absolute position of
+ // (0,0). Use the getFlat() method to determine the range of values
+ // bounding the joystick axis center.
+ if (range != null) {
+ final float axisFlat = range.getFlat();
+ final float axisVal = (historyPos < 0) ? event.getAxisValue(range.getAxis(), actionPointerIndex) : event.getHistoricalAxisValue(range.getAxis(), actionPointerIndex, historyPos);
+
+ // Ignore axis values that are within the 'flat' region of the
+ // joystick axis center.
+ if (Math.abs(axisVal) > axisFlat) {
+// Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") > " + axisFlat + " (flat) - raw val=" + axisVal);
+ // This value is already normalized in [-1.0, 1.0] (for sticks and "hats") or [0.0, 1.0] (for triggers)
+ return axisVal;
+ }
+// 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;
+ }
+
+ 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 = _repeatingJoystickAxisIdBitFlags;
+ }
+ for (int i = 0; i < _repeatingJoystickCenteredAxisValuesArray.length; ++i) {
+ if ((axisBfs & (0x01 << i)) != 0) {
+ _scummvm.pushEvent(JE_JOYSTICK, MotionEvent.ACTION_MOVE,
+ (int) (_repeatingJoystickCenteredAxisValuesArray[i] * JOYSTICK_AXIS_MAX),
+ 0,
+ axisBfs & (0x01 << i), 0, 0);
+ }
+ }
+ return true;
+ }
+
+ private void processJoystickInput(MotionEvent event, int historyPos) {
+ InputDevice inputDevice = event.getDevice();
+
+// // 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
+
+ // 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
+
+ // 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 auxiliary movement axis bitflags values order
+ float[] centeredAxisValuesArray = {getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_X, historyPos),
+ getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_Y, historyPos),
+ getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_X, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
+ getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_HAT_Y, historyPos) * JOYSTICK_AXIS_HAT_SCALE,
+ getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_Z, historyPos),
+ getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_RZ, historyPos),
+ getJoystickCenteredAxis(event, inputDevice, MotionEvent.AXIS_LTRIGGER, historyPos),
+ getJoystickCenteredAxis(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 = _repeatingJoystickAxisIdBitFlags;
+
+ for (int i = 0; i < centeredAxisValuesArray.length; ++i) {
+ currX = centeredAxisValuesArray[i];
+ absCurrX = Math.abs(currX);
+
+ // 0 - 5 (ie. 4+1) 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 frequent 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 >= 6 || absCurrY < 0.209f)) {
+ // When on all the axis for the current control (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;
+ _repeatingJoystickCenteredAxisValuesArray[i] = currX;
+ stoppingMovementAxisIdBitFlags |= (0x01 << i);
+ if (i < 5) {
+ _repeatingJoystickCenteredAxisValuesArray[i+1] = currY;
+ stoppingMovementAxisIdBitFlags |= (0x01 << (i+1));
+ }
+ repeatMove(stoppingMovementAxisIdBitFlags, true);
+
+ _repeatingJoystickCenteredAxisValuesArray[i] = 0.0f;
+ _repeatingJoystickAxisIdBitFlags &= ~(0x01 << i);
+ if (i < 5) {
+ _repeatingJoystickCenteredAxisValuesArray[i+1] = 0.0f;
+ _repeatingJoystickAxisIdBitFlags &= ~(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 respective repetition bit flag(s).
+ _repeatingJoystickCenteredAxisValuesArray[i] = currX; // X AXIS
+ _repeatingJoystickAxisIdBitFlags |= (0x01 << i);
+ if (i < 5) {
+ _repeatingJoystickCenteredAxisValuesArray[i+1] = currY; // Y AXIS
+ _repeatingJoystickAxisIdBitFlags |= (0x01 << (i+1));
+ }
+ }
+ if (i < 5) ++i; // skip next index as we handled it already in this case
+ }
+
+ if (_repeatingJoystickAxisIdBitFlags == 0) {
+ // Only removeMessages() if all motions are supposed to stop, ie final moving stick/hat/trigger etc???
+ _handler.removeMessages(MSG_REPEAT);
+ } else if (prevRepeatingAxisIdBitFlags == 0) {
+ // Start repetition message sending (sendMessageDelayed)
+ Message msg = _handler.obtainMessage(MSG_REPEAT);
+ _handler.sendMessageDelayed(msg, REPEAT_START_DELAY);
+ repeatMove(_repeatingJoystickAxisIdBitFlags, true);
+ }
+ }
+
}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java
deleted file mode 100644
index 0b6187c18ad..00000000000
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsModern.java
+++ /dev/null
@@ -1,321 +0,0 @@
-package org.scummvm.scummvm;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-
-import androidx.annotation.NonNull;
-
-import java.lang.ref.WeakReference;
-
-// A class that extends the basic ScummVMEventsBase, supporting Android APIs > HONEYCOMB_MR1 (API 12)
-public class ScummVMEventsModern extends ScummVMEventsBase {
-
- private static final int MSG_REPEAT = 3;
- private static final int REPEAT_INTERVAL = 20; // ~50 keys per second
- private static final int REPEAT_START_DELAY = 40;
-
- public ScummVMEventsModern(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
- super(context, scummvm, mouseHelper);
- }
-
- // Custom handler code (to avoid mem leaks, see warning "This Handler Class Should Be Static Or Leaks Might Occurâ) based on:
- // https://stackoverflow.com/a/27826094
- public static class ScummVMEventsModernHandler extends Handler {
-
- private final WeakReference<ScummVMEventsModern> mListenerReference;
-
- public ScummVMEventsModernHandler(ScummVMEventsModern listener) {
- super(Looper.getMainLooper());
- mListenerReference = new WeakReference<>(listener);
- }
-
- @Override
- public synchronized void handleMessage(@NonNull Message msg) {
- ScummVMEventsModern listener = mListenerReference.get();
- if(listener != null) {
- switch (msg.what) {
- case MSG_REPEAT:
- if (listener.repeatMove(0, false)) {
- Message repeat = Message.obtain(this, MSG_REPEAT);
- sendMessageDelayed(repeat, REPEAT_INTERVAL);
- }
- break;
- }
- }
- }
-
- public void clear() {
- this.removeCallbacksAndMessages(null);
- }
- }
-
- @Override
- public void clearEventHandler() {
- super.clearEventHandler();
- mHandler.clear();
- }
-
- private final ScummVMEventsModernHandler mHandler = new ScummVMEventsModernHandler(this);
- private final float[] repeatingCenteredAxisValuesArray = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
-
- // auxiliary 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());
- final int actionPointerIndex = event.getActionIndex();
-
- // A joystick at rest does not always report an absolute position of
- // (0,0). Use the getFlat() method to determine the range of values
- // bounding the joystick axis center.
- if (range != null) {
- final float axisFlat = range.getFlat();
- final float axisVal = (historyPos < 0) ? event.getAxisValue(range.getAxis(), actionPointerIndex) : event.getHistoricalAxisValue(range.getAxis(), actionPointerIndex, historyPos);
-
- // Ignore axis values that are within the 'flat' region of the
- // joystick axis center.
- if (Math.abs(axisVal) > axisFlat) {
-// Log.d(ScummVM.LOG_TAG, "JOYSTICK axis: " + MotionEvent.axisToString(axisId) + " id: " + axisId + " - Math.abs(" + value + ") > " + axisFlat + " (flat) - raw val=" + axisVal);
- // This value is already normalized in [-1.0, 1.0] (for sticks and "hats") or [0.0, 1.0] (for triggers)
- return axisVal;
- }
-// 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;
- }
-
- private void removeMessages() {
- if (mHandler != null) {
- mHandler.removeMessages(MSG_REPEAT);
- }
- }
-
- 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) {
- InputDevice inputDevice = event.getDevice();
-
-// // 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
-
- // 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
-
- // 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 auxiliary 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 - 5 (ie. 4+1) 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 frequent 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 >= 6 || absCurrY < 0.209f)) {
- // When on all the axis for the current control (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 respective 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();
-
- // Process the movements starting from the
- // earliest historical position in the batch
- for (int i = 0; i < historySize; ++i) {
- // Process the event at historical position i
- //Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m) hist: ");
- processJoystickInput(event, i);
- }
-
- // Process the current movement sample in the batch (position -1)
- //Log.d(ScummVM.LOG_TAG, "JOYSTICK - onGenericMotionEvent(m): " );
- processJoystickInput(event, -1);
- return true;
-
- default:
- break;
- }
- } else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
- //Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - onGenericMotionEvent(m) ");
- //
- // Check that the event might be a mouse scroll wheel (ACTION_SCROLL)
- // Code inspired from https://stackoverflow.com/a/33086042
- //
- // NOTE Other GenericMotionEvent are also triggered for InputDevice of SOURCE_CLASS_POINTER (eg. physical mouse).
- // These seem to be for button down/up events, which are handled along with pushing a JE_MOVE event
- // in MouseHelper's onMouseEvent() called from ScummVMEventsBase onTouch().
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_SCROLL:
- //Log.d(ScummVM.LOG_TAG, "MOUSE PHYSICAL POINTER - ACTION SCROLL");
- // This action is not a touch event so it is delivered to
- // View#onGenericMotionEvent(MotionEvent) rather than View#onTouchEvent(MotionEvent).
- if (_mouseHelper != null) {
- return _mouseHelper.onMouseEvent(event, false);
- }
- break;
-
- default:
- 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);
- }
-}
Commit: 9a365241f9fb3449b1e5a59d3fe872530d4d6fc4
https://github.com/scummvm/scummvm/commit/9a365241f9fb3449b1e5a59d3fe872530d4d6fc4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Store the ScummVMActivity object in ScummVMEvents
This avoids unsafe casts and makes things cleaner.
Changed paths:
backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index 8ba7614b172..f0937085ba9 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -1,6 +1,5 @@
package org.scummvm.scummvm;
-import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -82,7 +81,7 @@ public class ScummVMEvents implements
private final float[] _repeatingJoystickCenteredAxisValuesArray = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
private int _repeatingJoystickAxisIdBitFlags = 0x00;
- final protected Context _context;
+ final protected ScummVMActivity _activity;
final protected ScummVM _scummvm;
final protected GestureDetector _gd;
final protected int _longPressTimeout;
@@ -140,15 +139,15 @@ public class ScummVMEvents implements
// return new ScummVMEventHandler(this);
// }
- public ScummVMEvents(Context context, ScummVM scummvm, MouseHelper mouseHelper) {
- _context = context;
+ public ScummVMEvents(ScummVMActivity activity, ScummVM scummvm, MouseHelper mouseHelper) {
+ _activity = activity;
_scummvm = scummvm;
// Careful, _mouseHelper can be null (if HoverListener is not available for the device API -- old devices, API < 9)
_mouseHelper = mouseHelper;
_multitouchHelper = new MultitouchHelper(_scummvm);
- _gd = new GestureDetector(context, this);
+ _gd = new GestureDetector(activity, this);
_gd.setOnDoubleTapListener(this);
_gd.setIsLongpressEnabled(false);
@@ -166,11 +165,11 @@ public class ScummVMEvents implements
// this toggles the android keyboard (see showVirtualKeyboard() in ScummVMActivity.java)
// when menu key is long-pressed
// InputMethodManager imm = (InputMethodManager)
-// _context.getSystemService(Context.INPUT_METHOD_SERVICE);
+// _activity.getSystemService(Context.INPUT_METHOD_SERVICE);
//
// if (imm != null)
// imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
- ((ScummVMActivity) _context).toggleScreenKeyboard();
+ _activity.toggleScreenKeyboard();
} else if (msg.what == MSG_SBACK_LONG_PRESS) {
_scummvm.pushEvent(JE_SYS_KEY,
KeyEvent.ACTION_DOWN,
@@ -360,8 +359,8 @@ public class ScummVMEvents implements
return true;
} else if (action == KeyEvent.ACTION_UP) {
// Hide keyboard
- if (((ScummVMActivity) _context).isScreenKeyboardShown()) {
- ((ScummVMActivity) _context).hideScreenKeyboard();
+ if (_activity.isScreenKeyboardShown()) {
+ _activity.hideScreenKeyboard();
}
return true;
}
@@ -626,13 +625,13 @@ public class ScummVMEvents implements
// }
if (ScummVMActivity.keyboardWithoutTextInputShown
- && ((ScummVMActivity) _context).isScreenKeyboardShown()
- && ((ScummVMActivity) _context).getScreenKeyboard().getY() <= event.getY() ) {
- event.offsetLocation(-((ScummVMActivity) _context).getScreenKeyboard().getX(), -((ScummVMActivity) _context).getScreenKeyboard().getY());
+ && _activity.isScreenKeyboardShown()
+ && _activity.getScreenKeyboard().getY() <= event.getY() ) {
+ event.offsetLocation(-_activity.getScreenKeyboard().getX(), -_activity.getScreenKeyboard().getY());
// TODO maybe call the onTouchEvent of something else here?
- ((ScummVMActivity) _context).getScreenKeyboard().onTouchEvent(event);
+ _activity.getScreenKeyboard().onTouchEvent(event);
// correct the offset for continuing handling the event
- event.offsetLocation(((ScummVMActivity) _context).getScreenKeyboard().getX(), ((ScummVMActivity) _context).getScreenKeyboard().getY());
+ event.offsetLocation(_activity.getScreenKeyboard().getX(), _activity.getScreenKeyboard().getY());
}
if (_mouseHelper != null) {
Commit: 5ea3ac6d514c5e7825848d74baf2371529e9b567
https://github.com/scummvm/scummvm/commit/5ea3ac6d514c5e7825848d74baf2371529e9b567
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Add support for predictive back gestures
This should make the code future proof.
With this flag enabled, the KEYCODE_BACK event is never sent through
the onKey callback but using a dedicated callback.
Changed paths:
backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
dists/android/AndroidManifest.xml
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
index f0937085ba9..e2e93137de2 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEvents.java
@@ -12,8 +12,11 @@ import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
import java.lang.ref.WeakReference;
@@ -127,6 +130,18 @@ public class ScummVMEvents implements
}
}
+ @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU)
+ private class OnBackInvoked implements OnBackInvokedCallback {
+ @Override
+ public void onBackInvoked() {
+ //Log.d(ScummVM.LOG_TAG,"Sending back key");
+ ScummVMEvents.this._scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK,
+ 0, 0, 0, 0);
+ ScummVMEvents.this._scummvm.pushEvent(JE_SYS_KEY, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK,
+ 0, 0, 0, 0);
+ }
+ }
+
final private ScummVMEventHandler _handler = new ScummVMEventHandler(this);
// /**
@@ -153,6 +168,10 @@ public class ScummVMEvents implements
_doubleTapMode = false;
_longPressTimeout = ViewConfiguration.getLongPressTimeout();
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ activity.getOnBackInvokedDispatcher().registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT, new OnBackInvoked());
+ }
}
final static int MSG_SMENU_LONG_PRESS = 1;
diff --git a/dists/android/AndroidManifest.xml b/dists/android/AndroidManifest.xml
index 07b2de9765b..5aef1b46948 100644
--- a/dists/android/AndroidManifest.xml
+++ b/dists/android/AndroidManifest.xml
@@ -41,6 +41,7 @@
android:allowBackup="true"
android:appCategory="game"
android:description="@string/app_desc"
+ android:enableOnBackInvokedCallback="true"
android:icon="@mipmap/scummvm"
android:label="@string/app_name${nameSuffix}"
android:requestLegacyExternalStorage="true">
Commit: a1393fac6b1ad8795ed00d3d529d43db244adf86
https://github.com/scummvm/scummvm/commit/a1393fac6b1ad8795ed00d3d529d43db244adf86
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Target API level 35: Android 15 (Vanilla Ice Cream)
Changed paths:
dists/android/build.gradle
diff --git a/dists/android/build.gradle b/dists/android/build.gradle
index ba262c63f3d..501837dfc5e 100644
--- a/dists/android/build.gradle
+++ b/dists/android/build.gradle
@@ -30,7 +30,7 @@ tasks.withType(JavaCompile).configureEach {
apply plugin: 'com.android.application'
android {
- compileSdk 34
+ compileSdk 35
ndkVersion "23.2.8568313"
namespace "org.scummvm.scummvm"
@@ -41,7 +41,7 @@ android {
base.archivesName = "ScummVM"
minSdkVersion 16
- targetSdkVersion 34
+ targetSdkVersion 35
versionName "2.9.0"
versionCode 2090001
Commit: cc6a069c69aac3cab84753cdffefd7563f8d7a57
https://github.com/scummvm/scummvm/commit/cc6a069c69aac3cab84753cdffefd7563f8d7a57
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Rework the insets helper to handle cutouts and system bars
Also fix copy paste bugs and linting errors from Android Studio.
Changed paths:
backends/platform/android/jni-android.cpp
backends/platform/android/jni-android.h
backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
backends/platform/android/org/scummvm/scummvm/ScummVM.java
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index af0c104250e..c8808bbc7dc 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -138,7 +138,7 @@ const JNINativeMethod JNI::_natives[] = {
(void *)JNI::syncVirtkeyboardState },
{ "setPause", "(Z)V",
(void *)JNI::setPause },
- { "systemInsetsUpdated", "([I)V",
+ { "systemInsetsUpdated", "([I[I[I)V",
(void *)JNI::systemInsetsUpdated },
{ "getNativeVersionInfo", "()Ljava/lang/String;",
(void *)JNI::getNativeVersionInfo }
@@ -968,10 +968,11 @@ void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
}
}
-void JNI::systemInsetsUpdated(JNIEnv *env, jobject self, jintArray insets) {
- assert(env->GetArrayLength(insets) == ARRAYSIZE(gestures_insets));
+void JNI::systemInsetsUpdated(JNIEnv *env, jobject self, jintArray gestureInsets, jintArray systemInsets, jintArray cutoutInsets) {
+ assert(env->GetArrayLength(gestureInsets) == ARRAYSIZE(gestures_insets));
- env->GetIntArrayRegion(insets, 0, ARRAYSIZE(gestures_insets), gestures_insets);
+ // TODO: handle systemInsets and cutoutInsets
+ env->GetIntArrayRegion(gestureInsets, 0, ARRAYSIZE(gestures_insets), gestures_insets);
}
jstring JNI::getNativeVersionInfo(JNIEnv *env, jobject self) {
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index 8b50dab0371..3ceb3f76f04 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -196,7 +196,7 @@ private:
static void syncVirtkeyboardState(JNIEnv *env, jobject self, jboolean newState);
static void setPause(JNIEnv *env, jobject self, jboolean value);
- static void systemInsetsUpdated(JNIEnv *env, jobject self, jintArray insets);
+ static void systemInsetsUpdated(JNIEnv *env, jobject self, jintArray gestureInsets, jintArray systemInsets, jintArray cutoutInsets);
static jstring getNativeVersionInfo(JNIEnv *env, jobject self);
static jstring convertToJString(JNIEnv *env, const Common::U32String &str);
diff --git a/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java b/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
index 07fbea39686..2d0dc9414db 100644
--- a/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
+++ b/backends/platform/android/org/scummvm/scummvm/CompatHelpers.java
@@ -16,6 +16,7 @@ import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
+import android.view.DisplayCutout;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
@@ -83,7 +84,7 @@ class CompatHelpers {
static class SystemInsets {
public interface SystemInsetsListener {
- void systemInsetsUpdated(int insets[]);
+ void systemInsetsUpdated(int[] gestureInsets, int[] systemInsets, int[] cutoutInsets);
}
public static void registerSystemInsetsListener(View v, SystemInsetsListener l) {
@@ -91,34 +92,87 @@ class CompatHelpers {
v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerR(l));
} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerQ(l));
- } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT_WATCH) {
- v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerKitKatW(l));
+ } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
+ v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerP(l));
+ } else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+ v.setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListenerLollipop(l));
} else {
// Not available
- int[] insets = new int[] { 0, 0, 0, 0 };
- l.systemInsetsUpdated(insets);
+ int[] gestureInsets = new int[] { 0, 0, 0, 0 };
+ int[] systemInsets = new int[] { 0, 0, 0, 0 };
+ int[] cutoutInsets = new int[] { 0, 0, 0, 0 };
+ l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
+ }
+ }
+
+ @RequiresApi(android.os.Build.VERSION_CODES.LOLLIPOP)
+ @SuppressWarnings("deprecation")
+ private static class OnApplyWindowInsetsListenerLollipop implements View.OnApplyWindowInsetsListener {
+ final private SystemInsetsListener l;
+
+ public OnApplyWindowInsetsListenerLollipop(SystemInsetsListener l) {
+ this.l = l;
+ }
+
+ @Override
+ public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
+ // No system gestures inset before Android Q
+ int[] gestureInsets = new int[] {
+ insets.getStableInsetLeft(),
+ insets.getStableInsetTop(),
+ insets.getStableInsetRight(),
+ insets.getStableInsetBottom()
+ };
+ int[] systemInsets = new int[] {
+ insets.getSystemWindowInsetLeft(),
+ insets.getSystemWindowInsetTop(),
+ insets.getSystemWindowInsetRight(),
+ insets.getSystemWindowInsetBottom()
+ };
+ // No cutouts before Android P
+ int[] cutoutInsets = new int[] { 0, 0, 0, 0 };
+ l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
+ return v.onApplyWindowInsets(insets);
}
}
- @RequiresApi(android.os.Build.VERSION_CODES.KITKAT_WATCH)
+ @RequiresApi(android.os.Build.VERSION_CODES.P)
@SuppressWarnings("deprecation")
- private static class OnApplyWindowInsetsListenerKitKatW implements View.OnApplyWindowInsetsListener {
- private SystemInsetsListener l;
+ private static class OnApplyWindowInsetsListenerP implements View.OnApplyWindowInsetsListener {
+ final private SystemInsetsListener l;
- public OnApplyWindowInsetsListenerKitKatW(SystemInsetsListener l) {
+ public OnApplyWindowInsetsListenerP(SystemInsetsListener l) {
this.l = l;
}
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
// No system gestures inset before Android Q
- int[] insetsArray = new int[] {
+ int[] gestureInsets = new int[] {
insets.getStableInsetLeft(),
insets.getStableInsetTop(),
insets.getStableInsetRight(),
insets.getStableInsetBottom()
};
- l.systemInsetsUpdated(insetsArray);
+ int[] systemInsets = new int[] {
+ insets.getSystemWindowInsetLeft(),
+ insets.getSystemWindowInsetTop(),
+ insets.getSystemWindowInsetRight(),
+ insets.getSystemWindowInsetBottom()
+ };
+ int[] cutoutInsets;
+ DisplayCutout cutout = insets.getDisplayCutout();
+ if (cutout == null) {
+ cutoutInsets = new int[] { 0, 0, 0, 0 };
+ } else {
+ cutoutInsets = new int[] {
+ cutout.getSafeInsetLeft(),
+ cutout.getSafeInsetTop(),
+ cutout.getSafeInsetRight(),
+ cutout.getSafeInsetBottom()
+ };
+ }
+ l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
return v.onApplyWindowInsets(insets);
}
}
@@ -126,7 +180,7 @@ class CompatHelpers {
@RequiresApi(android.os.Build.VERSION_CODES.Q)
@SuppressWarnings("deprecation")
private static class OnApplyWindowInsetsListenerQ implements View.OnApplyWindowInsetsListener {
- private SystemInsetsListener l;
+ final private SystemInsetsListener l;
public OnApplyWindowInsetsListenerQ(SystemInsetsListener l) {
this.l = l;
@@ -134,22 +188,40 @@ class CompatHelpers {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
- Insets insetsStruct = insets.getStableInsets();
- int[] insetsArray = new int[] {
+ Insets insetsStruct = insets.getSystemGestureInsets();
+ int[] gestureInsets = new int[] {
+ insetsStruct.left,
+ insetsStruct.top,
+ insetsStruct.right,
+ insetsStruct.bottom,
+ };
+ insetsStruct = insets.getSystemWindowInsets();
+ int[] systemInsets = new int[] {
insetsStruct.left,
insetsStruct.top,
insetsStruct.right,
insetsStruct.bottom,
};
- l.systemInsetsUpdated(insetsArray);
+ int[] cutoutInsets;
+ DisplayCutout cutout = insets.getDisplayCutout();
+ if (cutout == null) {
+ cutoutInsets = new int[] { 0, 0, 0, 0 };
+ } else {
+ cutoutInsets = new int[] {
+ cutout.getSafeInsetLeft(),
+ cutout.getSafeInsetTop(),
+ cutout.getSafeInsetRight(),
+ cutout.getSafeInsetBottom()
+ };
+ }
+ l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
return v.onApplyWindowInsets(insets);
}
}
@RequiresApi(android.os.Build.VERSION_CODES.R)
- @SuppressWarnings("deprecation")
private static class OnApplyWindowInsetsListenerR implements View.OnApplyWindowInsetsListener {
- private SystemInsetsListener l;
+ final private SystemInsetsListener l;
public OnApplyWindowInsetsListenerR(SystemInsetsListener l) {
this.l = l;
@@ -158,13 +230,32 @@ class CompatHelpers {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
Insets insetsStruct = insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemGestures());
- int[] insetsArray = new int[] {
+ int[] gestureInsets = new int[] {
insetsStruct.left,
insetsStruct.top,
insetsStruct.right,
insetsStruct.bottom,
};
- l.systemInsetsUpdated(insetsArray);
+ insetsStruct = insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars());
+ int[] systemInsets = new int[] {
+ insetsStruct.left,
+ insetsStruct.top,
+ insetsStruct.right,
+ insetsStruct.bottom,
+ };
+ int[] cutoutInsets;
+ DisplayCutout cutout = insets.getDisplayCutout();
+ if (cutout == null) {
+ cutoutInsets = new int[] { 0, 0, 0, 0 };
+ } else {
+ cutoutInsets = new int[] {
+ cutout.getSafeInsetLeft(),
+ cutout.getSafeInsetTop(),
+ cutout.getSafeInsetRight(),
+ cutout.getSafeInsetBottom()
+ };
+ }
+ l.systemInsetsUpdated(gestureInsets, systemInsets, cutoutInsets);
return v.onApplyWindowInsets(insets);
}
}
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index d8891cf2ad5..ced347e1ee3 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -71,7 +71,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback,
// CompatHelpers.WindowInsets.SystemInsetsListener interface
@Override
- final public native void systemInsetsUpdated(int insets[]);
+ final public native void systemInsetsUpdated(int[] gestureInsets, int[] systemInsets, int[] cutoutInsets);
// Callbacks from C++ peer instance
abstract protected void getDPI(float[] values);
Commit: d9dcf93f658fea2d5b09963cf5ef9e53cc9173c7
https://github.com/scummvm/scummvm/commit/d9dcf93f658fea2d5b09963cf5ef9e53cc9173c7
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Make ShortcutCreatorActivity edge-to-edge compliant
Changed paths:
A dists/android/res/values-v21/themes.xml
A dists/android/res/values-v30/themes.xml
backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
dists/android/res/layout/shortcut_creator_activity.xml
dists/android/res/values/themes.xml
diff --git a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
index 814a35b0d92..6ffb42a75d8 100644
--- a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
@@ -26,6 +26,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@@ -50,7 +51,7 @@ import java.util.List;
import java.util.Map;
-public class ShortcutCreatorActivity extends Activity {
+public class ShortcutCreatorActivity extends Activity implements CompatHelpers.SystemInsets.SystemInsetsListener {
final protected static String LOG_TAG = "ShortcutCreatorActivity";
private IconsCache _cache;
@@ -91,6 +92,8 @@ public class ShortcutCreatorActivity extends Activity {
super.onCreate(savedInstanceState);
setContentView(R.layout.shortcut_creator_activity);
+ CompatHelpers.SystemInsets.registerSystemInsetsListener(findViewById(R.id.shortcut_creator_root), this);
+
// We are only here to create a shortcut
if (!Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) {
finish();
@@ -154,6 +157,16 @@ public class ShortcutCreatorActivity extends Activity {
setResult(RESULT_CANCELED);
}
+ @Override
+ public void systemInsetsUpdated(int[] gestureInsets, int[] systemInsets, int[] cutoutInsets) {
+ LinearLayout root = findViewById(R.id.shortcut_creator_root);
+ // Ignore bottom as we have our list which can overflow
+ root.setPadding(
+ Math.max(systemInsets[0], cutoutInsets[0]),
+ Math.max(systemInsets[1], cutoutInsets[1]),
+ Math.max(systemInsets[2], cutoutInsets[2]), 0);
+ }
+
static private FileInputStream openFile(File path) {
try {
return new FileInputStream(path);
diff --git a/dists/android/res/layout/shortcut_creator_activity.xml b/dists/android/res/layout/shortcut_creator_activity.xml
index b1d2e160f9e..21a5452020c 100644
--- a/dists/android/res/layout/shortcut_creator_activity.xml
+++ b/dists/android/res/layout/shortcut_creator_activity.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/shortcut_creator_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
diff --git a/dists/android/res/values-v21/themes.xml b/dists/android/res/values-v21/themes.xml
new file mode 100644
index 00000000000..2094d8d62c5
--- /dev/null
+++ b/dists/android/res/values-v21/themes.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="ShortcutCreatorTheme_v21" parent="ShortcutCreatorTheme_v11">
+ <item name="android:windowTranslucentStatus">true</item>
+ <item name="android:windowTranslucentNavigation">true</item>
+ </style>
+</resources>
diff --git a/dists/android/res/values-v30/themes.xml b/dists/android/res/values-v30/themes.xml
new file mode 100644
index 00000000000..e8e96c57c8e
--- /dev/null
+++ b/dists/android/res/values-v30/themes.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="ShortcutCreatorTheme_v30" parent="ShortcutCreatorTheme_v21">
+ <item name="android:windowLayoutInDisplayCutoutMode">always</item>
+ </style>
+</resources>
diff --git a/dists/android/res/values/themes.xml b/dists/android/res/values/themes.xml
index 8e553cfb4fb..1cb7de54a0b 100644
--- a/dists/android/res/values/themes.xml
+++ b/dists/android/res/values/themes.xml
@@ -14,6 +14,16 @@
<style name="ShortcutCreatorThemeBase" parent="@android:style/Theme.DeviceDefault">
</style>
- <style name="ShortcutCreatorTheme" parent="ShortcutCreatorThemeBase">
+ <style name="ShortcutCreatorTheme_v11" parent="ShortcutCreatorThemeBase">
+ <item name="android:windowActionBar">false</item>
+ <item name="android:windowNoTitle">true</item>
+ </style>
+
+ <style name="ShortcutCreatorTheme_v21" parent="ShortcutCreatorTheme_v11">
+ </style>
+ <style name="ShortcutCreatorTheme_v30" parent="ShortcutCreatorTheme_v21">
+ </style>
+
+ <style name="ShortcutCreatorTheme" parent="ShortcutCreatorTheme_v30">
</style>
</resources>
Commit: ac21b373e1fe760d33b444855040d326ec5e93a8
https://github.com/scummvm/scummvm/commit/ac21b373e1fe760d33b444855040d326ec5e93a8
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Make SplashActivity edge-to-edge compliant
Changed paths:
dists/android/res/values-v21/themes.xml
dists/android/res/values-v30/themes.xml
dists/android/res/values/themes.xml
diff --git a/dists/android/res/values-v21/themes.xml b/dists/android/res/values-v21/themes.xml
index 2094d8d62c5..355580da9de 100644
--- a/dists/android/res/values-v21/themes.xml
+++ b/dists/android/res/values-v21/themes.xml
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
+ <style name="SplashTheme_v21" parent="SplashThemeBase">
+ <item name="android:windowTranslucentStatus">true</item>
+ <item name="android:windowTranslucentNavigation">true</item>
+ </style>
+
<style name="ShortcutCreatorTheme_v21" parent="ShortcutCreatorTheme_v11">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
diff --git a/dists/android/res/values-v30/themes.xml b/dists/android/res/values-v30/themes.xml
index e8e96c57c8e..72015e6ad4d 100644
--- a/dists/android/res/values-v30/themes.xml
+++ b/dists/android/res/values-v30/themes.xml
@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
+ <style name="SplashTheme_v30" parent="SplashTheme_v21">
+ <item name="android:windowLayoutInDisplayCutoutMode">always</item>
+ </style>
+
<style name="ShortcutCreatorTheme_v30" parent="ShortcutCreatorTheme_v21">
<item name="android:windowLayoutInDisplayCutoutMode">always</item>
</style>
diff --git a/dists/android/res/values/themes.xml b/dists/android/res/values/themes.xml
index 1cb7de54a0b..e3835a388ab 100644
--- a/dists/android/res/values/themes.xml
+++ b/dists/android/res/values/themes.xml
@@ -6,7 +6,15 @@
<item name="keyboardViewStyle">@style/View.CustomKeyboard</item>
</style>
- <style name="SplashTheme" parent="AppTheme">
+ <style name="SplashThemeBase" parent="AppTheme">
+ </style>
+
+ <style name="SplashTheme_v21" parent="SplashThemeBase">
+ </style>
+ <style name="SplashTheme_v30" parent="SplashTheme_v21">
+ </style>
+
+ <style name="SplashTheme" parent="SplashTheme_v30">
<item name="android:windowBackground">@drawable/splash</item>
</style>
Commit: c7584e6f7fb1cf4c6ac93254595ad8e2241f0bc6
https://github.com/scummvm/scummvm/commit/c7584e6f7fb1cf4c6ac93254595ad8e2241f0bc6
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2024-11-12T22:39:58+01:00
Commit Message:
ANDROID: Make custom shortcuts really custom
Before this change, the user may not have been able to set its own label
if a shortcut with the same name already existed.
Changed paths:
backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
diff --git a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
index 6ffb42a75d8..b0931031024 100644
--- a/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ShortcutCreatorActivity.java
@@ -256,9 +256,14 @@ public class ShortcutCreatorActivity extends Activity implements CompatHelpers.S
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
dialog.dismiss();
+ String label = desc.getText().toString();
+ // Generate an id which depends on the user description
+ // Without this, if the user changes the description but already has the same shortcut (also in the dynamic ones), the other label will be reused
+ String shortcutId = game.getTarget() + String.format("-%08x", label.hashCode());
+
Intent shortcut = new Intent(Intent.ACTION_MAIN, Uri.fromParts("scummvm", game.getTarget(), null),
ShortcutCreatorActivity.this, SplashActivity.class);
- Intent result = CompatHelpers.ShortcutCreator.createShortcutResultIntent(ShortcutCreatorActivity.this, game.getTarget(), shortcut,
+ Intent result = CompatHelpers.ShortcutCreator.createShortcutResultIntent(ShortcutCreatorActivity.this, shortcutId, shortcut,
desc.getText().toString(), icon, R.drawable.ic_no_game_icon);
setResult(RESULT_OK, result);
More information about the Scummvm-git-logs
mailing list