[Scummvm-git-logs] scummvm master -> f9251fc030cc1a89625ecfab481ba491f4a507c3
antoniou79
noreply at scummvm.org
Thu Nov 7 15:51:01 UTC 2024
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f9251fc030 ANDROID: Improve multitap gesture handling for direct touch mode
Commit: f9251fc030cc1a89625ecfab481ba491f4a507c3
https://github.com/scummvm/scummvm/commit/f9251fc030cc1a89625ecfab481ba491f4a507c3
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2024-11-07T17:50:47+02:00
Commit Message:
ANDROID: Improve multitap gesture handling for direct touch mode
More guards were added to hopefully link the mouse down and up events that should be executed in sequence, albeit delayed
Also a new case was added for a delayed mouse up event (in JE_MULTI) to avoid it being executed out of order / too soon.
Changed paths:
backends/platform/android/android.h
backends/platform/android/events.cpp
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index 3942f0647ed..4c89a514a3c 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -101,7 +101,10 @@ private:
static const int kQueuedInputEventDelay = 50;
struct EventWithDelay : public Common::Event {
- /** The time which the delay starts counting from */
+ /** An original timestamp that identifies this event and the delayed ones connected to it that will follow */
+ uint32 originTimeMillis;
+
+ /** The time which the delay starts counting from. It can be set to be later than originTimeMillis */
uint32 referTimeMillis;
/** The delay for the event to be handled */
@@ -113,10 +116,11 @@ private:
/** A status flag indicating whether the "connected" event was handled */
bool connectedTypeExecuted;
- EventWithDelay() : referTimeMillis(0), delayMillis(0), connectedType(Common::EVENT_INVALID), connectedTypeExecuted(false) {
+ EventWithDelay() : originTimeMillis(0), referTimeMillis(0), delayMillis(0), connectedType(Common::EVENT_INVALID), connectedTypeExecuted(false) {
}
void reset() {
+ originTimeMillis = 0;
referTimeMillis = 0;
delayMillis = 0;
connectedType = Common::EVENT_INVALID;
diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp
index cc605e9425c..6b6328671bc 100644
--- a/backends/platform/android/events.cpp
+++ b/backends/platform/android/events.cpp
@@ -814,19 +814,21 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
Common::Event ev1 = ev0;
ev1.type = down; // mouse down
_event_queue_lock->lock();
+ uint32 originTimeForDelayedEventGrp = getMillis(true);
if (_touch_mode != TOUCH_MODE_TOUCHPAD) {
// In this case the mouse move is done in "direct mode"
// ie. the cursor jumps to where the tap occurred
// so we don't have relMouse coordinates to set for the event
// However, in Direct Touch mode, some games seem to expect a delay
- // between the move event and the subsequence mouse down event (eg. Curse of Monkey Island, Tony Tough)
- // Thus, thie Mouse Button Down event is also sent with a delay
+ // between the move event and the subsequent mouse down event (eg. Curse of Monkey Island, Tony Tough)
+ // Thus, this Mouse Button Down event is also sent with a delay
_event_queue.push(ev0);
_delayedMouseBtnDownEvent.mouse = ev1.mouse;
_delayedMouseBtnDownEvent.type = down;
- _delayedMouseBtnDownEvent.referTimeMillis = getMillis(true);
+ _delayedMouseBtnDownEvent.referTimeMillis = originTimeForDelayedEventGrp;
+ _delayedMouseBtnDownEvent.originTimeMillis = originTimeForDelayedEventGrp;
_delayedMouseBtnDownEvent.delayMillis = kQueuedInputEventDelay;
- _delayedMouseBtnDownEvent.connectedType = ev0.type;
+ _delayedMouseBtnDownEvent.connectedType = ev0.type; // Common::EVENT_MOUSEMOVE
_delayedMouseBtnDownEvent.connectedTypeExecuted = false;
} else {
_event_queue.push(ev1);
@@ -837,9 +839,10 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
// Mouse-up event is handled with a small delay as some engines require such a delay for mouse up events (Gob, Toonstruck)
// See bug ticket: https://bugs.scummvm.org/ticket/5942
// LOGD("JE_TAP - VALID: ev0: mx %d my %d t: %d | ev1: mx %d my %d t: %d | ev2: mx %d my %d t: %d", ev0.mouse.x, ev0.mouse.y, ev0.type, ev1.mouse.x, ev1.mouse.y, ev1.type, ev2.mouse.x, ev2.mouse.y, ev2.type);
- _delayedMouseBtnUpEvent.referTimeMillis = getMillis(true);
+ _delayedMouseBtnUpEvent.referTimeMillis = originTimeForDelayedEventGrp;
+ _delayedMouseBtnUpEvent.originTimeMillis = originTimeForDelayedEventGrp;
_delayedMouseBtnUpEvent.delayMillis = kQueuedInputEventDelay;
- _delayedMouseBtnUpEvent.connectedType = ev1.type;
+ _delayedMouseBtnUpEvent.connectedType = ev1.type; // down (EVENT_MBUTTONDOWN, EVENT_RBUTTONDOWN, EVENT_LBUTTONDOWN)
_delayedMouseBtnUpEvent.connectedTypeExecuted = false;
_event_queue_lock->unlock();
}
@@ -1042,8 +1045,12 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
ev1.type = multitype;
if (ev1.type == Common::EVENT_RBUTTONDOWN || ev1.type == Common::EVENT_MBUTTONDOWN) {
+ // INFO: Cases for delayed actions:
+ // JE_MULTI: MV + DelayedDown + possible DelayedUp (Direct Touch)
+ // JE_TAP: MV + DelayedDown + DelayedUp (Direct Touch)
+ // JE_TAP: Down + DelayedUp (Touchpad)
pushDelayedTouchMouseBtnEvents();
-
+ uint32 originTimeForDelayedEventGrp = getMillis(true);
if (_touch_mode != TOUCH_MODE_TOUCHPAD) {
// Only send an early move event if:
// - in direct touch mode
@@ -1052,14 +1059,32 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
_event_queue.push(ev0);
_delayedMouseBtnDownEvent.mouse = ev1.mouse;
_delayedMouseBtnDownEvent.type = ev1.type;
- _delayedMouseBtnDownEvent.referTimeMillis = getMillis(true);
+ _delayedMouseBtnDownEvent.referTimeMillis = originTimeForDelayedEventGrp;
+ _delayedMouseBtnDownEvent.originTimeMillis = originTimeForDelayedEventGrp;
_delayedMouseBtnDownEvent.delayMillis = kQueuedInputEventDelay;
- _delayedMouseBtnDownEvent.connectedType = ev0.type;
+ _delayedMouseBtnDownEvent.connectedType = ev0.type; // Common::EVENT_MOUSEMOVE
_delayedMouseBtnDownEvent.connectedTypeExecuted = false;
_event_queue_lock->unlock();
} else {
pushEvent(ev1);
}
+ } else if (ev1.type == Common::EVENT_RBUTTONUP || ev1.type == Common::EVENT_MBUTTONUP) {
+ if (_touch_mode != TOUCH_MODE_TOUCHPAD && _delayedMouseBtnDownEvent.delayMillis > 0) {
+ // This is a case when the mouse up event for the multitouch gesture was sent too soon
+ // after the last down event (which in direct touch mode is "scheduled" for delayed execution)
+ // In that case, the mouse up event has to be delayed as well
+ _event_queue_lock->lock();
+ _delayedMouseBtnUpEvent.mouse = ev1.mouse;
+ _delayedMouseBtnUpEvent.type = ev1.type;
+ _delayedMouseBtnUpEvent.referTimeMillis = getMillis(true);
+ _delayedMouseBtnUpEvent.originTimeMillis = _delayedMouseBtnDownEvent.originTimeMillis;
+ _delayedMouseBtnUpEvent.delayMillis = kQueuedInputEventDelay;
+ _delayedMouseBtnUpEvent.connectedType = _delayedMouseBtnDownEvent.type;
+ _delayedMouseBtnUpEvent.connectedTypeExecuted = false;
+ _event_queue_lock->unlock();
+ } else {
+ pushEvent(ev1);
+ }
} else if (ev1.type != Common::EVENT_INVALID) {
pushEvent(ev1);
}
@@ -1460,8 +1485,20 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
_event_queue_lock->lock();
- // We currently allow only one delayed event at any time, and it's always a mouse up event that comes from a touch event/gesture
- // Handling multiple delayed events gets complicated and is practically unnecessary too
+ // We currently allow only one delayed event group at any time,
+ // and it's always for events that come from a touch event/gesture.
+ // "Group" here means that these events are connected,
+ // and have to be executed one after the other in sequence,
+ // respecting the set delay for each of them.
+ // As of yet, the cases for delayed events are as follows:
+ // -- Direct Touch Mode --
+ // JE_MULTI: MOVE (instant) -> MOUSE_DOWN (DELAYED) -> MOUSE_UP (POSSIBLY DELAYED, BUT NOT ALWAYS)
+ // JE_TAP: MOVE (instant) -> MOUSE_DOWN (DELAYED) -> MOUSE_UP (DELAYED)
+ //
+ // -- Touchpad Emulation Mode --
+ // JE_TAP: DOWN (instant) -> MOUSE_UP (DELAYED)
+ //
+ // Handling multiple delayed event groups gets complicated and is practically unnecessary too
if (_delayedMouseBtnDownEvent.delayMillis > 0
&& _delayedMouseBtnDownEvent.connectedTypeExecuted
&& (getMillis(true) - _delayedMouseBtnDownEvent.referTimeMillis > _delayedMouseBtnDownEvent.delayMillis)) {
@@ -1469,8 +1506,10 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
event = evHP;
if ((_delayedMouseBtnUpEvent.delayMillis > 0)
&& (event.type == _delayedMouseBtnUpEvent.connectedType)) {
- _delayedMouseBtnUpEvent.connectedTypeExecuted = true;
- _delayedMouseBtnUpEvent.referTimeMillis = getMillis(true);
+ if (_delayedMouseBtnDownEvent.originTimeMillis == _delayedMouseBtnUpEvent.originTimeMillis) {
+ _delayedMouseBtnUpEvent.connectedTypeExecuted = true;
+ _delayedMouseBtnUpEvent.referTimeMillis = getMillis(true);
+ }
}
_delayedMouseBtnDownEvent.reset();
} else if (_delayedMouseBtnUpEvent.delayMillis > 0
@@ -1486,11 +1525,13 @@ bool OSystem_Android::pollEvent(Common::Event &event) {
} else {
event = _event_queue.pop();
if ((_delayedMouseBtnDownEvent.delayMillis > 0)
- && (event.type == _delayedMouseBtnDownEvent.connectedType)) {
+ && (event.type == _delayedMouseBtnDownEvent.connectedType
+ && _delayedMouseBtnDownEvent.connectedTypeExecuted == false)) {
_delayedMouseBtnDownEvent.connectedTypeExecuted = true;
_delayedMouseBtnDownEvent.referTimeMillis = getMillis(true);
} else if ((_delayedMouseBtnUpEvent.delayMillis > 0)
- && (event.type == _delayedMouseBtnUpEvent.connectedType)) {
+ && (event.type == _delayedMouseBtnUpEvent.connectedType
+ && _delayedMouseBtnUpEvent.connectedTypeExecuted == false)) {
_delayedMouseBtnUpEvent.connectedTypeExecuted = true;
_delayedMouseBtnUpEvent.referTimeMillis = getMillis(true);
}
@@ -1518,17 +1559,20 @@ void OSystem_Android::pushEvent(const Common::Event &event1, const Common::Event
_event_queue_lock->unlock();
}
+// This method force-feeds the pending delayed event to the queue
+// and hopes for the best, while not ignoring the new delayed events that follow.
+// This is done for responsiveness, albeit obviously it's not an ideal solution.
void OSystem_Android::pushDelayedTouchMouseBtnEvents() {
_event_queue_lock->lock();
- Common::Event evHP;
+ Common::Event evHP1, evHP2;
if (_delayedMouseBtnDownEvent.delayMillis > 0) {
- evHP = _delayedMouseBtnDownEvent;
- _event_queue.push(_delayedMouseBtnDownEvent);
+ evHP1 = _delayedMouseBtnDownEvent;
+ _event_queue.push(evHP1);
_delayedMouseBtnDownEvent.reset();
}
if (_delayedMouseBtnUpEvent.delayMillis > 0) {
- evHP = _delayedMouseBtnUpEvent;
- _event_queue.push(_delayedMouseBtnUpEvent);
+ evHP2 = _delayedMouseBtnUpEvent;
+ _event_queue.push(evHP2);
_delayedMouseBtnUpEvent.reset();
}
_event_queue_lock->unlock();
More information about the Scummvm-git-logs
mailing list