[Scummvm-git-logs] scummvm master -> cd173c8739668108c664c220244ae5e83238c87d
bgK
bastien.bouclet at gmail.com
Mon Mar 9 19:00:37 UTC 2020
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d94c7c3bcc SDL: Move the keyboard mouse to a subclass of SdlEventSource
e66e35a3fd COMMON: Move isMouseEvent from Keymapper to Common
568d882e80 KEYMAPPER: Introduce a Virtual Mouse event source
cd173c8739 3DS: Use the shared virtual mouse
Commit: d94c7c3bcc7ea0dee89bd167c037a422d0c31989
https://github.com/scummvm/scummvm/commit/d94c7c3bcc7ea0dee89bd167c037a422d0c31989
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2020-03-09T20:00:31+01:00
Commit Message:
SDL: Move the keyboard mouse to a subclass of SdlEventSource
And deprecate it. The new Virtual Mouse system is expected to replace
it.
Changed paths:
A backends/events/sdl/legacy-sdl-events.cpp
A backends/events/sdl/legacy-sdl-events.h
backends/events/dinguxsdl/dinguxsdl-events.h
backends/events/gph/gph-events.h
backends/events/openpandora/op-events.cpp
backends/events/psp2sdl/psp2sdl-events.cpp
backends/events/psp2sdl/psp2sdl-events.h
backends/events/samsungtvsdl/samsungtvsdl-events.h
backends/events/sdl/sdl-events.cpp
backends/events/sdl/sdl-events.h
backends/events/switchsdl/switchsdl-events.cpp
backends/events/switchsdl/switchsdl-events.h
backends/events/symbiansdl/symbiansdl-events.h
backends/events/webossdl/webossdl-events.cpp
backends/graphics/sdl/sdl-graphics.cpp
backends/graphics/windowed.h
backends/module.mk
backends/platform/sdl/sdl.cpp
diff --git a/backends/events/dinguxsdl/dinguxsdl-events.h b/backends/events/dinguxsdl/dinguxsdl-events.h
index 0ed0a9923e..b7928b84d9 100644
--- a/backends/events/dinguxsdl/dinguxsdl-events.h
+++ b/backends/events/dinguxsdl/dinguxsdl-events.h
@@ -23,9 +23,9 @@
#ifndef BACKENDS_EVENTS_SDL_DINGUX_H
#define BACKENDS_EVENTS_SDL_DINGUX_H
-#include "backends/events/sdl/sdl-events.h"
+#include "backends/events/sdl/legacy-sdl-events.h"
-class DINGUXSdlEventSource : public SdlEventSource {
+class DINGUXSdlEventSource : public LegacySdlEventSource {
protected:
bool remapKey(SDL_Event &ev, Common::Event &event);
};
diff --git a/backends/events/gph/gph-events.h b/backends/events/gph/gph-events.h
index bdcb62d8c2..b9bcf1332d 100644
--- a/backends/events/gph/gph-events.h
+++ b/backends/events/gph/gph-events.h
@@ -23,13 +23,13 @@
#if !defined(BACKEND_EVENTS_GPH_H) && !defined(DISABLE_DEFAULT_EVENTMANAGER)
#define BACKEND_EVENTS_GPH_H
-#include "backends/events/sdl/sdl-events.h"
+#include "backends/events/sdl/legacy-sdl-events.h"
/*
* SDL Events manager for GPH devices.
*/
-class GPHEventSource : public SdlEventSource {
+class GPHEventSource : public LegacySdlEventSource {
public:
GPHEventSource();
diff --git a/backends/events/openpandora/op-events.cpp b/backends/events/openpandora/op-events.cpp
index bcc2bd8190..7a196dbfb1 100644
--- a/backends/events/openpandora/op-events.cpp
+++ b/backends/events/openpandora/op-events.cpp
@@ -82,10 +82,6 @@ bool OPEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
else
event.type = Common::EVENT_LBUTTONDOWN; /* For normal mice etc. */
- // update KbdMouse
- _km.x = ev.button.x * MULTIPLIER;
- _km.y = ev.button.y * MULTIPLIER;
-
return processMouseEvent(event, ev.button.x, ev.button.y);
}
@@ -113,9 +109,6 @@ bool OPEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
return false;
processMouseEvent(event, ev.button.x, ev.button.y);
- // update KbdMouse
- _km.x = ev.button.x * MULTIPLIER;
- _km.y = ev.button.y * MULTIPLIER;
return true;
}
@@ -130,18 +123,18 @@ bool OPEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
switch (ev.key.keysym.sym) {
case SDLK_LEFT:
event.type = (ev.type == SDL_KEYDOWN) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ processMouseEvent(event, _mouseY, _mouseY);
return true;
break;
case SDLK_RIGHT:
event.type = (ev.type == SDL_KEYDOWN) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ processMouseEvent(event, _mouseX, _mouseY);
return true;
break;
#if defined(SDL_BUTTON_MIDDLE)
case SDLK_UP:
event.type = (ev.type == SDL_KEYDOWN) ? Common::EVENT_MBUTTONDOWN : Common::EVENT_MBUTTONUP;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ processMouseEvent(event, _mouseX, _mouseY);
return true;
break;
#endif
@@ -154,12 +147,12 @@ bool OPEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
switch (ev.key.keysym.sym) {
case SDLK_HOME:
event.type = Common::EVENT_LBUTTONDOWN;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ processMouseEvent(event, _mouseX, _mouseY);
return true;
break;
case SDLK_END:
event.type = Common::EVENT_RBUTTONDOWN;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ processMouseEvent(event, _mouseX, _mouseY);
return true;
break;
case SDLK_PAGEDOWN:
@@ -192,12 +185,12 @@ bool OPEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
switch (ev.key.keysym.sym) {
case SDLK_HOME:
event.type = Common::EVENT_LBUTTONUP;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ processMouseEvent(event, _mouseX, _mouseY);
return true;
break;
case SDLK_END:
event.type = Common::EVENT_RBUTTONUP;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ processMouseEvent(event, _mouseX, _mouseY);
return true;
break;
case SDLK_PAGEDOWN:
diff --git a/backends/events/psp2sdl/psp2sdl-events.cpp b/backends/events/psp2sdl/psp2sdl-events.cpp
index b14493c345..38a0ee0932 100644
--- a/backends/events/psp2sdl/psp2sdl-events.cpp
+++ b/backends/events/psp2sdl/psp2sdl-events.cpp
@@ -103,8 +103,8 @@ void PSP2EventSource::preprocessFingerDown(SDL_Event *event) {
// id (for multitouch)
SDL_FingerID id = event->tfinger.fingerId;
- int x = _km.x / MULTIPLIER;
- int y = _km.y / MULTIPLIER;
+ int x = _mouseX;
+ int y = _mouseY;
if (port == 0 && !ConfMan.getBool("frontpanel_touchpad_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
@@ -147,8 +147,8 @@ void PSP2EventSource::preprocessFingerUp(SDL_Event *event) {
}
}
- int x = _km.x / MULTIPLIER;
- int y = _km.y / MULTIPLIER;
+ int x = _mouseX;
+ int y = _mouseY;
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
@@ -219,8 +219,10 @@ void PSP2EventSource::preprocessFingerMotion(SDL_Event *event) {
}
if (numFingersDown >= 1) {
- int x = _km.x / MULTIPLIER;
- int y = _km.y / MULTIPLIER;
+ int x = _mouseX;
+ int y = _mouseY;
+ int xMax = _graphicsManager->getWindowWidth() - 1;
+ int yMax = _graphicsManager->getWindowHeight() - 1;
if (port == 0 && !ConfMan.getBool("frontpanel_touchpad_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
@@ -267,23 +269,23 @@ void PSP2EventSource::preprocessFingerMotion(SDL_Event *event) {
// convert touch events to relative mouse pointer events
// track sub-pixel relative finger motion using the MULTIPLIER
- _hiresDX += (event->tfinger.dx * 1.25 * speedFactor * _km.x_max * MULTIPLIER);
- _hiresDY += (event->tfinger.dy * 1.25 * speedFactor * _km.y_max * MULTIPLIER);
+ _hiresDX += (event->tfinger.dx * 1.25 * speedFactor * xMax * MULTIPLIER);
+ _hiresDY += (event->tfinger.dy * 1.25 * speedFactor * yMax * MULTIPLIER);
int xRel = _hiresDX / MULTIPLIER;
int yRel = _hiresDY / MULTIPLIER;
- x = (_km.x / MULTIPLIER) + xRel;
- y = (_km.y / MULTIPLIER) + yRel;
+ x = _mouseX + xRel;
+ y = _mousey + yRel;
_hiresDX %= MULTIPLIER;
_hiresDY %= MULTIPLIER;
}
- if (x > _km.x_max) {
- x = _km.x_max;
+ if (x > xMax) {
+ x = xMax;
} else if (x < 0) {
x = 0;
}
- if (y > _km.y_max) {
- y = _km.y_max;
+ if (y > yMax) {
+ y = yMax;
} else if (y < 0) {
y = 0;
}
@@ -311,8 +313,8 @@ void PSP2EventSource::preprocessFingerMotion(SDL_Event *event) {
if (numFingersDownLong >= 2) {
// starting drag, so push mouse down at current location (back)
// or location of "oldest" finger (front)
- int mouseDownX = _km.x / MULTIPLIER;
- int mouseDownY = _km.y / MULTIPLIER;
+ int mouseDownX = _mouseX;
+ int mouseDownY = _mousey;
if (port == 0 && !ConfMan.getBool("frontpanel_touchpad_mode")) {
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
@@ -372,8 +374,8 @@ void PSP2EventSource::preprocessFingerMotion(SDL_Event *event) {
}
void PSP2EventSource::convertTouchXYToGameXY(float touchX, float touchY, int *gameX, int *gameY) {
- int screenH = _km.y_max;
- int screenW = _km.x_max;
+ int screenH = _graphicsManager->getWindowHeight();
+ int screenW = _graphicsManager->getWindowWidth();
const int dispW = TOUCHSCREEN_WIDTH;
const int dispH = TOUCHSCREEN_HEIGHT;
@@ -395,8 +397,8 @@ void PSP2EventSource::convertTouchXYToGameXY(float touchX, float touchY, int *ga
float dispTouchX = (touchX * (float)dispW);
float dispTouchY = (touchY * (float)dispH);
- *gameX = CLIP((int)((dispTouchX - x) / sx), 0, (int)_km.x_max);
- *gameY = CLIP((int)((dispTouchY - y) / sy), 0, (int)_km.y_max);
+ *gameX = CLIP((int)((dispTouchX - x) / sx), 0, screenW - 1);
+ *gameY = CLIP((int)((dispTouchY - y) / sy), 0, screenH - 1);
}
void PSP2EventSource::finishSimulatedMouseClicks() {
@@ -414,8 +416,8 @@ void PSP2EventSource::finishSimulatedMouseClicks() {
SDL_Event ev;
ev.type = SDL_MOUSEBUTTONUP;
ev.button.button = simulatedButton;
- ev.button.x = _km.x / MULTIPLIER;
- ev.button.y = _km.y / MULTIPLIER;
+ ev.button.x = _mouseX;
+ ev.button.y = _mousey;
SDL_PushEvent(&ev);
_simulatedClickStartTime[port][i] = 0;
diff --git a/backends/events/psp2sdl/psp2sdl-events.h b/backends/events/psp2sdl/psp2sdl-events.h
index f37d51c46b..11e97ec5b9 100644
--- a/backends/events/psp2sdl/psp2sdl-events.h
+++ b/backends/events/psp2sdl/psp2sdl-events.h
@@ -42,7 +42,8 @@ private:
MAX_TAP_TIME = 250, // taps longer than this will not result in mouse click events
MAX_TAP_MOTION_DISTANCE = 10, // max distance finger motion in Vita screen pixels to be considered a tap
SIMULATED_CLICK_DURATION = 50, // time in ms how long simulated mouse clicks should be
- }; // track three fingers per panel
+ MULTIPLIER = 16 // multiplier for sub-pixel resolution
+ };
typedef struct {
int id; // -1: no touch
diff --git a/backends/events/samsungtvsdl/samsungtvsdl-events.h b/backends/events/samsungtvsdl/samsungtvsdl-events.h
index be3dfef8fd..a831992061 100644
--- a/backends/events/samsungtvsdl/samsungtvsdl-events.h
+++ b/backends/events/samsungtvsdl/samsungtvsdl-events.h
@@ -23,12 +23,12 @@
#if !defined(BACKEND_EVENTS_SDL_SAMSUNGTV_H) && !defined(DISABLE_DEFAULT_EVENTMANAGER)
#define BACKEND_EVENTS_SDL_SAMSUNGTV_H
-#include "backends/events/sdl/sdl-events.h"
+#include "backends/events/sdl/legacy-sdl-events.h"
/**
* SDL events manager for Samsung TV
*/
-class SamsungTVSdlEventSource : public SdlEventSource {
+class SamsungTVSdlEventSource : public LegacySdlEventSource {
protected:
virtual bool remapKey(SDL_Event &ev, Common::Event &event);
};
diff --git a/backends/events/sdl/legacy-sdl-events.cpp b/backends/events/sdl/legacy-sdl-events.cpp
new file mode 100644
index 0000000000..5cc061c317
--- /dev/null
+++ b/backends/events/sdl/legacy-sdl-events.cpp
@@ -0,0 +1,309 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#if defined(SDL_BACKEND)
+
+#include "backends/events/sdl/legacy-sdl-events.h"
+
+// #define JOY_INVERT_Y
+#define JOY_XAXIS 0
+#define JOY_YAXIS 1
+
+LegacySdlEventSource::LegacySdlEventSource() {
+ // Reset mouse state
+ memset(&_km, 0, sizeof(_km));
+}
+
+void LegacySdlEventSource::updateKbdMouse() {
+ uint32 curTime = g_system->getMillis(true);
+ if (curTime < _km.last_time + _km.delay_time) {
+ return;
+ }
+
+ _km.last_time = curTime;
+ if (_km.x_down_count == 1) {
+ _km.x_down_time = curTime;
+ _km.x_down_count = 2;
+ }
+ if (_km.y_down_count == 1) {
+ _km.y_down_time = curTime;
+ _km.y_down_count = 2;
+ }
+
+ if (_km.x_vel || _km.y_vel) {
+ if (_km.x_down_count) {
+ if (curTime > _km.x_down_time + 300) {
+ if (_km.x_vel > 0)
+ _km.x_vel += MULTIPLIER;
+ else
+ _km.x_vel -= MULTIPLIER;
+ } else if (curTime > _km.x_down_time + 200) {
+ if (_km.x_vel > 0)
+ _km.x_vel = 5 * MULTIPLIER;
+ else
+ _km.x_vel = -5 * MULTIPLIER;
+ }
+ }
+ if (_km.y_down_count) {
+ if (curTime > _km.y_down_time + 300) {
+ if (_km.y_vel > 0)
+ _km.y_vel += MULTIPLIER;
+ else
+ _km.y_vel -= MULTIPLIER;
+ } else if (curTime > _km.y_down_time + 200) {
+ if (_km.y_vel > 0)
+ _km.y_vel = 5 * MULTIPLIER;
+ else
+ _km.y_vel = -5 * MULTIPLIER;
+ }
+ }
+
+ int16 speedFactor = computeJoystickMouseSpeedFactor();
+
+ // - The modifier key makes the mouse movement slower
+ // - The extra factor "delay/speedFactor" ensures velocities
+ // are independent of the kbdMouse update rate
+ // - all velocities were originally chosen
+ // at a delay of 25, so that is the reference used here
+ // - note: operator order is important to avoid overflow
+ if (_km.modifier) {
+ _km.x += ((_km.x_vel / 10) * ((int16)_km.delay_time)) / speedFactor;
+ _km.y += ((_km.y_vel / 10) * ((int16)_km.delay_time)) / speedFactor;
+ } else {
+ _km.x += (_km.x_vel * ((int16)_km.delay_time)) / speedFactor;
+ _km.y += (_km.y_vel * ((int16)_km.delay_time)) / speedFactor;
+ }
+
+ if (_km.x < 0) {
+ _km.x = 0;
+ _km.x_vel = -1 * MULTIPLIER;
+ _km.x_down_count = 1;
+ } else if (_km.x > _km.x_max * MULTIPLIER) {
+ _km.x = _km.x_max * MULTIPLIER;
+ _km.x_vel = 1 * MULTIPLIER;
+ _km.x_down_count = 1;
+ }
+
+ if (_km.y < 0) {
+ _km.y = 0;
+ _km.y_vel = -1 * MULTIPLIER;
+ _km.y_down_count = 1;
+ } else if (_km.y > _km.y_max * MULTIPLIER) {
+ _km.y = _km.y_max * MULTIPLIER;
+ _km.y_vel = 1 * MULTIPLIER;
+ _km.y_down_count = 1;
+ }
+ }
+}
+
+bool LegacySdlEventSource::handleKbdMouse(Common::Event &event) {
+ int32 oldKmX = _km.x;
+ int32 oldKmY = _km.y;
+
+ updateKbdMouse();
+
+ if (_km.x != oldKmX || _km.y != oldKmY) {
+ if (_graphicsManager) {
+ _graphicsManager->getWindow()->warpMouseInWindow((Uint16)(_km.x / MULTIPLIER), (Uint16)(_km.y / MULTIPLIER));
+ }
+
+ event.type = Common::EVENT_MOUSEMOVE;
+ return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ }
+
+ return false;
+}
+
+bool LegacySdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
+ if (ev.jaxis.axis == JOY_XAXIS) {
+ _km.joy_x = ev.jaxis.value;
+ return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
+ } else if (ev.jaxis.axis == JOY_YAXIS) {
+ _km.joy_y = ev.jaxis.value;
+ return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
+ }
+
+ return SdlEventSource::handleJoyAxisMotion(ev, event);
+}
+
+int16 LegacySdlEventSource::computeJoystickMouseSpeedFactor() const {
+ int16 speedFactor;
+
+ switch (ConfMan.getInt("kbdmouse_speed")) {
+ // 0.25 keyboard pointer speed
+ case 0:
+ speedFactor = 100;
+ break;
+ // 0.5 speed
+ case 1:
+ speedFactor = 50;
+ break;
+ // 0.75 speed
+ case 2:
+ speedFactor = 33;
+ break;
+ // 1.0 speed
+ case 3:
+ speedFactor = 25;
+ break;
+ // 1.25 speed
+ case 4:
+ speedFactor = 20;
+ break;
+ // 1.5 speed
+ case 5:
+ speedFactor = 17;
+ break;
+ // 1.75 speed
+ case 6:
+ speedFactor = 14;
+ break;
+ // 2.0 speed
+ case 7:
+ speedFactor = 12;
+ break;
+ default:
+ speedFactor = 25;
+ }
+
+ // Scale the mouse cursor speed with the display size so moving across
+ // the screen takes a reasonable amount of time at higher resolutions.
+ return speedFactor * 480 / _km.y_max;
+}
+
+bool LegacySdlEventSource::handleAxisToMouseMotion(int16 xAxis, int16 yAxis) {
+#ifdef JOY_INVERT_Y
+ yAxis = -yAxis;
+#endif
+
+ // conversion factor between keyboard mouse and joy axis value
+ int vel_to_axis = (1500 / MULTIPLIER);
+
+ // radial and scaled deadzone
+
+ float analogX = (float)xAxis;
+ float analogY = (float)yAxis;
+ float deadZone = (float)ConfMan.getInt("joystick_deadzone") * 1000.0f;
+
+ float magnitude = sqrt(analogX * analogX + analogY * analogY);
+
+ if (magnitude >= deadZone) {
+ _km.x_down_count = 0;
+ _km.y_down_count = 0;
+ float scalingFactor = 1.0f / magnitude * (magnitude - deadZone) / (32769.0f - deadZone);
+ _km.x_vel = (int16)(analogX * scalingFactor * 32768.0f / vel_to_axis);
+ _km.y_vel = (int16)(analogY * scalingFactor * 32768.0f / vel_to_axis);
+ } else {
+ _km.x_vel = 0;
+ _km.y_vel = 0;
+ }
+
+ return false;
+}
+
+void LegacySdlEventSource::resetKeyboardEmulation(int16 x_max, int16 y_max) {
+ _km.x_max = x_max;
+ _km.y_max = y_max;
+ _km.delay_time = 12;
+ _km.last_time = 0;
+ _km.modifier = false;
+ _km.joy_x = 0;
+ _km.joy_y = 0;
+}
+
+void LegacySdlEventSource::checkScreenChange() {
+ if (!_graphicsManager) {
+ return;
+ }
+
+ int newMaxX = _graphicsManager->getWindowWidth() - 1;
+ int newMaxY = _graphicsManager->getWindowHeight() - 1;
+
+ if (_km.x_max != newMaxX || _km.y_max != newMaxY) {
+ resetKeyboardEmulation(newMaxX, newMaxY);
+ }
+}
+
+bool LegacySdlEventSource::pollEvent(Common::Event &event) {
+ checkScreenChange();
+
+ bool handled = SdlEventSource::pollEvent(event);
+ if (handled) {
+ return true;
+ }
+
+ // Handle mouse control via analog joystick and keyboard
+ if (handleKbdMouse(event)) {
+ return true;
+ }
+
+ return false;
+}
+
+bool LegacySdlEventSource::handleMouseMotion(SDL_Event &ev, Common::Event &event) {
+ // update KbdMouse
+ _km.x = ev.motion.x * MULTIPLIER;
+ _km.y = ev.motion.y * MULTIPLIER;
+
+ return SdlEventSource::handleMouseMotion(ev, event);
+}
+
+bool LegacySdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
+ // update KbdMouse
+ _km.x = ev.motion.x * MULTIPLIER;
+ _km.y = ev.motion.y * MULTIPLIER;
+
+ return SdlEventSource::handleMouseButtonDown(ev, event);
+}
+
+bool LegacySdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
+ // update KbdMouse
+ _km.x = ev.motion.x * MULTIPLIER;
+ _km.y = ev.motion.y * MULTIPLIER;
+
+ return SdlEventSource::handleMouseButtonUp(ev, event);
+}
+
+bool LegacySdlEventSource::handleControllerButton(const SDL_Event &ev, Common::Event &event, bool buttonUp) {
+ if (event.joystick.button == Common::JOYSTICK_BUTTON_RIGHT_SHOULDER) {
+ // Right shoulder is the modifier button that makes the mouse go slower.
+ _km.modifier = !buttonUp;
+ }
+
+ return SdlEventSource::handleControllerButton(ev, event, buttonUp);
+}
+
+bool LegacySdlEventSource::handleControllerAxisMotion(const SDL_Event &ev, Common::Event &event) {
+ if (ev.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX) {
+ _km.joy_x = ev.caxis.value;
+ return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
+ } else if (ev.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY) {
+ _km.joy_y = ev.caxis.value;
+ return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
+ }
+
+ return SdlEventSource::handleControllerAxisMotion(ev, event);
+}
+
+#endif
diff --git a/backends/events/sdl/legacy-sdl-events.h b/backends/events/sdl/legacy-sdl-events.h
new file mode 100644
index 0000000000..f4a437e7a4
--- /dev/null
+++ b/backends/events/sdl/legacy-sdl-events.h
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKEND_EVENTS_SDL_LEGACY_H
+#define BACKEND_EVENTS_SDL_LEGACY_H
+
+#include "backends/events/sdl/sdl-events.h"
+
+// multiplier used to increase resolution for keyboard/joystick mouse
+#define MULTIPLIER 16
+
+class LegacySdlEventSource : public SdlEventSource {
+public:
+ LegacySdlEventSource();
+
+ bool pollEvent(Common::Event &event) override;
+
+ void checkScreenChange();
+
+protected:
+ /** @name Keyboard mouse emulation
+ * Disabled by fingolfin 2004-12-18.
+ * I am keeping the rest of the code in for now, since the joystick
+ * code (or rather, "hack") uses it, too.
+ */
+ //@{
+
+ struct KbdMouse {
+ int32 x, y;
+ int16 x_vel, y_vel, x_max, y_max, x_down_count, y_down_count, joy_x, joy_y;
+ uint32 last_time, delay_time, x_down_time, y_down_time;
+ bool modifier;
+ };
+ KbdMouse _km;
+
+ virtual void updateKbdMouse();
+ virtual bool handleKbdMouse(Common::Event &event);
+
+ //@}
+
+ bool handleMouseMotion(SDL_Event &ev, Common::Event &event) override;
+ bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event) override;
+ bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event) override;
+ bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) override;
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ bool handleControllerButton(const SDL_Event &ev, Common::Event &event, bool buttonUp) override;
+ bool handleControllerAxisMotion(const SDL_Event &ev, Common::Event &event) override;
+#endif
+
+ /**
+ * Update the virtual mouse according to a joystick or game controller axis position change
+ */
+ virtual bool handleAxisToMouseMotion(int16 xAxis, int16 yAxis);
+
+ /**
+ * Compute the virtual mouse movement speed factor according to the 'kbdmouse_speed' setting.
+ * The speed factor is scaled with the display size.
+ */
+ int16 computeJoystickMouseSpeedFactor() const;
+
+ /**
+ * Resets keyboard emulation after a video screen change
+ */
+ void resetKeyboardEmulation(int16 x_max, int16 y_max);
+
+};
+
+#endif
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 1f6e56b660..a218457248 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -33,10 +33,6 @@
#include "engines/engine.h"
#include "gui/gui-manager.h"
-// #define JOY_INVERT_Y
-#define JOY_XAXIS 0
-#define JOY_YAXIS 1
-
#if SDL_VERSION_ATLEAST(2, 0, 0)
#define GAMECONTROLLERDB_FILE "gamecontrollerdb.txt"
@@ -87,14 +83,12 @@ void SdlEventSource::loadGameControllerMappingFile() {
#endif
SdlEventSource::SdlEventSource()
- : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0), _queuedFakeMouseMove(false), _lastHatPosition(SDL_HAT_CENTERED)
+ : EventSource(), _scrollLock(false), _joystick(0), _lastScreenID(0), _graphicsManager(0), _queuedFakeMouseMove(false),
+ _lastHatPosition(SDL_HAT_CENTERED), _mouseX(0), _mouseY(0)
#if SDL_VERSION_ATLEAST(2, 0, 0)
, _queuedFakeKeyUp(false), _fakeKeyUp(), _controller(nullptr)
#endif
{
- // Reset mouse state
- memset(&_km, 0, sizeof(_km));
-
int joystick_num = ConfMan.getInt("joystick_num");
if (joystick_num >= 0) {
// Initialize SDL joystick subsystem
@@ -182,6 +176,9 @@ int SdlEventSource::mapKey(SDL_Keycode sdlKey, SDL_Keymod mod, Uint16 unicode) {
}
bool SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
+ _mouseX = x;
+ _mouseY = y;
+
event.mouse.x = x;
event.mouse.y = y;
@@ -192,151 +189,6 @@ bool SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
return true;
}
-void SdlEventSource::updateKbdMouse() {
- uint32 curTime = g_system->getMillis(true);
- if (curTime < _km.last_time + _km.delay_time) {
- return;
- }
-
- _km.last_time = curTime;
- if (_km.x_down_count == 1) {
- _km.x_down_time = curTime;
- _km.x_down_count = 2;
- }
- if (_km.y_down_count == 1) {
- _km.y_down_time = curTime;
- _km.y_down_count = 2;
- }
-
- if (_km.x_vel || _km.y_vel) {
- if (_km.x_down_count) {
- if (curTime > _km.x_down_time + 300) {
- if (_km.x_vel > 0)
- _km.x_vel += MULTIPLIER;
- else
- _km.x_vel -= MULTIPLIER;
- } else if (curTime > _km.x_down_time + 200) {
- if (_km.x_vel > 0)
- _km.x_vel = 5 * MULTIPLIER;
- else
- _km.x_vel = -5 * MULTIPLIER;
- }
- }
- if (_km.y_down_count) {
- if (curTime > _km.y_down_time + 300) {
- if (_km.y_vel > 0)
- _km.y_vel += MULTIPLIER;
- else
- _km.y_vel -= MULTIPLIER;
- } else if (curTime > _km.y_down_time + 200) {
- if (_km.y_vel > 0)
- _km.y_vel = 5 * MULTIPLIER;
- else
- _km.y_vel = -5 * MULTIPLIER;
- }
- }
-
- int16 speedFactor = computeJoystickMouseSpeedFactor();
-
- // - The modifier key makes the mouse movement slower
- // - The extra factor "delay/speedFactor" ensures velocities
- // are independent of the kbdMouse update rate
- // - all velocities were originally chosen
- // at a delay of 25, so that is the reference used here
- // - note: operator order is important to avoid overflow
- if (_km.modifier) {
- _km.x += ((_km.x_vel / 10) * ((int16)_km.delay_time)) / speedFactor;
- _km.y += ((_km.y_vel / 10) * ((int16)_km.delay_time)) / speedFactor;
- } else {
- _km.x += (_km.x_vel * ((int16)_km.delay_time)) / speedFactor;
- _km.y += (_km.y_vel * ((int16)_km.delay_time)) / speedFactor;
- }
-
- if (_km.x < 0) {
- _km.x = 0;
- _km.x_vel = -1 * MULTIPLIER;
- _km.x_down_count = 1;
- } else if (_km.x > _km.x_max * MULTIPLIER) {
- _km.x = _km.x_max * MULTIPLIER;
- _km.x_vel = 1 * MULTIPLIER;
- _km.x_down_count = 1;
- }
-
- if (_km.y < 0) {
- _km.y = 0;
- _km.y_vel = -1 * MULTIPLIER;
- _km.y_down_count = 1;
- } else if (_km.y > _km.y_max * MULTIPLIER) {
- _km.y = _km.y_max * MULTIPLIER;
- _km.y_vel = 1 * MULTIPLIER;
- _km.y_down_count = 1;
- }
- }
-}
-
-bool SdlEventSource::handleKbdMouse(Common::Event &event) {
- int32 oldKmX = _km.x;
- int32 oldKmY = _km.y;
-
- updateKbdMouse();
-
- if (_km.x != oldKmX || _km.y != oldKmY) {
- if (_graphicsManager) {
- _graphicsManager->getWindow()->warpMouseInWindow((Uint16)(_km.x / MULTIPLIER), (Uint16)(_km.y / MULTIPLIER));
- }
-
- event.type = Common::EVENT_MOUSEMOVE;
- return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
- }
-
- return false;
-}
-
-int16 SdlEventSource::computeJoystickMouseSpeedFactor() const {
- int16 speedFactor;
-
- switch (ConfMan.getInt("kbdmouse_speed")) {
- // 0.25 keyboard pointer speed
- case 0:
- speedFactor = 100;
- break;
- // 0.5 speed
- case 1:
- speedFactor = 50;
- break;
- // 0.75 speed
- case 2:
- speedFactor = 33;
- break;
- // 1.0 speed
- case 3:
- speedFactor = 25;
- break;
- // 1.25 speed
- case 4:
- speedFactor = 20;
- break;
- // 1.5 speed
- case 5:
- speedFactor = 17;
- break;
- // 1.75 speed
- case 6:
- speedFactor = 14;
- break;
- // 2.0 speed
- case 7:
- speedFactor = 12;
- break;
- default:
- speedFactor = 25;
- }
-
- // Scale the mouse cursor speed with the display size so moving across
- // the screen takes a reasonable amount of time at higher resolutions.
- return speedFactor * 480 / _km.y_max;
-}
-
void SdlEventSource::SDLModToOSystemKeyFlags(SDL_Keymod mod, Common::Event &event) {
event.kbd.flags = 0;
@@ -590,11 +442,6 @@ bool SdlEventSource::pollEvent(Common::Event &event) {
return true;
}
- // Handle mouse control via analog joystick and keyboard
- if (handleKbdMouse(event)) {
- return true;
- }
-
return false;
}
@@ -616,11 +463,10 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
case SDL_MOUSEWHEEL: {
Sint32 yDir = ev.wheel.y;
- // HACK: It seems we want the mouse coordinates supplied
- // with a mouse wheel event. However, SDL2 does not supply
- // these, thus we use whatever we got last time. It seems
- // these are always stored in _km.x, _km.y.
- if (!processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER)) {
+ // We want the mouse coordinates supplied with a mouse wheel event.
+ // However, SDL2 does not supply these, thus we use whatever we got
+ // last time.
+ if (!processMouseEvent(event, _mouseX, _mouseY)) {
return false;
}
if (yDir < 0) {
@@ -798,10 +644,6 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
bool SdlEventSource::handleMouseMotion(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_MOUSEMOVE;
- // update KbdMouse
- _km.x = ev.motion.x * MULTIPLIER;
- _km.y = ev.motion.y * MULTIPLIER;
-
return processMouseEvent(event, ev.motion.x, ev.motion.y);
}
@@ -831,10 +673,6 @@ bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event)
else
return false;
- // update KbdMouse
- _km.x = ev.button.x * MULTIPLIER;
- _km.y = ev.button.y * MULTIPLIER;
-
return processMouseEvent(event, ev.button.x, ev.button.y);
}
@@ -858,10 +696,6 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
else
return false;
- // update KbdMouse
- _km.x = ev.button.x * MULTIPLIER;
- _km.y = ev.button.y * MULTIPLIER;
-
return processMouseEvent(event, ev.button.x, ev.button.y);
}
@@ -951,16 +785,6 @@ bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
}
bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
-
- // TODO: Move hardcoded axis to mouse motion code to the keymapper
- if (ev.jaxis.axis == JOY_XAXIS) {
- _km.joy_x = ev.jaxis.value;
- return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
- } else if (ev.jaxis.axis == JOY_YAXIS) {
- _km.joy_y = ev.jaxis.value;
- return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
- }
-
event.type = Common::EVENT_JOYAXIS_MOTION;
event.joystick.axis = ev.jaxis.axis;
event.joystick.position = ev.jaxis.value;
@@ -1071,25 +895,10 @@ bool SdlEventSource::handleControllerButton(const SDL_Event &ev, Common::Event &
event.type = buttonUp ? Common::EVENT_JOYBUTTON_UP : Common::EVENT_JOYBUTTON_DOWN;
event.joystick.button = button;
- if (event.joystick.button == Common::JOYSTICK_BUTTON_RIGHT_SHOULDER) {
- // Right shoulder is the modifier button that makes the mouse go slower.
- _km.modifier = !buttonUp;
- }
-
return true;
}
bool SdlEventSource::handleControllerAxisMotion(const SDL_Event &ev, Common::Event &event) {
-
- // TODO: Move hardcoded axis to mouse motion code to the keymapper
- if (ev.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX) {
- _km.joy_x = ev.caxis.value;
- return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
- } else if (ev.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY) {
- _km.joy_y = ev.caxis.value;
- return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
- }
-
event.type = Common::EVENT_JOYAXIS_MOTION;
event.joystick.axis = ev.caxis.axis;
event.joystick.position = ev.caxis.value;
@@ -1098,50 +907,10 @@ bool SdlEventSource::handleControllerAxisMotion(const SDL_Event &ev, Common::Eve
}
#endif
-bool SdlEventSource::handleAxisToMouseMotion(int16 xAxis, int16 yAxis) {
-#ifdef JOY_INVERT_Y
- yAxis = -yAxis;
-#endif
-
- // conversion factor between keyboard mouse and joy axis value
- int vel_to_axis = (1500 / MULTIPLIER);
-
- // radial and scaled deadzone
-
- float analogX = (float)xAxis;
- float analogY = (float)yAxis;
- float deadZone = (float)ConfMan.getInt("joystick_deadzone") * 1000.0f;
-
- float magnitude = sqrt(analogX * analogX + analogY * analogY);
-
- if (magnitude >= deadZone) {
- _km.x_down_count = 0;
- _km.y_down_count = 0;
- float scalingFactor = 1.0f / magnitude * (magnitude - deadZone) / (32769.0f - deadZone);
- _km.x_vel = (int16)(analogX * scalingFactor * 32768.0f / vel_to_axis);
- _km.y_vel = (int16)(analogY * scalingFactor * 32768.0f / vel_to_axis);
- } else {
- _km.x_vel = 0;
- _km.y_vel = 0;
- }
-
- return false;
-}
-
bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
return false;
}
-void SdlEventSource::resetKeyboardEmulation(int16 x_max, int16 y_max) {
- _km.x_max = x_max;
- _km.y_max = y_max;
- _km.delay_time = 12;
- _km.last_time = 0;
- _km.modifier = false;
- _km.joy_x = 0;
- _km.joy_y = 0;
-}
-
void SdlEventSource::fakeWarpMouse(const int x, const int y) {
_queuedFakeMouseMove = true;
_fakeMouseMove.type = Common::EVENT_MOUSEMOVE;
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index 54a7d5ef01..746e7f8d59 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -28,9 +28,6 @@
#include "common/events.h"
-// multiplier used to increase resolution for keyboard/joystick mouse
-#define MULTIPLIER 16
-
// Type names which changed between SDL 1.2 and SDL 2.
#if !SDL_VERSION_ATLEAST(2, 0, 0)
typedef SDLKey SDL_Keycode;
@@ -53,11 +50,6 @@ public:
*/
virtual bool pollEvent(Common::Event &event);
- /**
- * Resets keyboard emulation after a video screen change
- */
- virtual void resetKeyboardEmulation(int16 x_max, int16 y_max);
-
/**
* Emulates a mouse movement that would normally be caused by a mouse warp
* of the system mouse.
@@ -65,26 +57,12 @@ public:
void fakeWarpMouse(const int x, const int y);
protected:
- /** @name Keyboard mouse emulation
- * Disabled by fingolfin 2004-12-18.
- * I am keeping the rest of the code in for now, since the joystick
- * code (or rather, "hack") uses it, too.
- */
- //@{
-
- struct KbdMouse {
- int32 x, y;
- int16 x_vel, y_vel, x_max, y_max, x_down_count, y_down_count, joy_x, joy_y;
- uint32 last_time, delay_time, x_down_time, y_down_time;
- bool modifier;
- };
- KbdMouse _km;
-
- //@}
-
/** Scroll lock state - since SDL doesn't track it */
bool _scrollLock;
+ int _mouseX;
+ int _mouseY;
+
/** Joystick */
SDL_Joystick *_joystick;
@@ -151,8 +129,6 @@ protected:
virtual bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyHatMotion(SDL_Event &ev, Common::Event &event);
- virtual void updateKbdMouse();
- virtual bool handleKbdMouse(Common::Event &event);
#if SDL_VERSION_ATLEAST(2, 0, 0)
virtual bool handleJoystickAdded(const SDL_JoyDeviceEvent &event);
@@ -164,17 +140,6 @@ protected:
//@}
- /**
- * Update the virtual mouse according to a joystick or game controller axis position change
- */
- virtual bool handleAxisToMouseMotion(int16 xAxis, int16 yAxis);
-
- /**
- * Compute the virtual mouse movement speed factor according to the 'kbdmouse_speed' setting.
- * The speed factor is scaled with the display size.
- */
- int16 computeJoystickMouseSpeedFactor() const;
-
/**
* Assigns the mouse coords to the mouse event. Furthermore notify the
* graphics manager about the position change.
diff --git a/backends/events/switchsdl/switchsdl-events.cpp b/backends/events/switchsdl/switchsdl-events.cpp
index 54f6784f4b..ff750b20d8 100644
--- a/backends/events/switchsdl/switchsdl-events.cpp
+++ b/backends/events/switchsdl/switchsdl-events.cpp
@@ -97,8 +97,8 @@ void SwitchEventSource::preprocessFingerDown(SDL_Event *event) {
// id (for multitouch)
SDL_FingerID id = event->tfinger.fingerId;
- int x = _km.x / MULTIPLIER;
- int y = _km.y / MULTIPLIER;
+ int x = _mouseX;
+ int y = _mouseY;
if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
@@ -141,8 +141,8 @@ void SwitchEventSource::preprocessFingerUp(SDL_Event *event) {
}
}
- int x = _km.x / MULTIPLIER;
- int y = _km.y / MULTIPLIER;
+ int x = _mouseX;
+ int y = _mouseY;
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
@@ -213,8 +213,10 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {
}
if (numFingersDown >= 1) {
- int x = _km.x / MULTIPLIER;
- int y = _km.y / MULTIPLIER;
+ int x = _mouseX;
+ int y = _mouseY;
+ int xMax = _graphicsManager->getWindowWidth() - 1;
+ int yMax = _graphicsManager->getWindowHeight() - 1;
if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
@@ -253,14 +255,14 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {
// convert touch events to relative mouse pointer events
// Whenever an SDL_event involving the mouse is processed,
- // _km.x/y are truncated from subpixel precision to regular pixel precision.
- // Therefore, there's no need here to deal with subpixel precision in _km.x/y.
- x = (_km.x / MULTIPLIER + (event->tfinger.dx * 1.25 * speedFactor * _km.x_max));
- y = (_km.y / MULTIPLIER + (event->tfinger.dy * 1.25 * speedFactor * _km.y_max));
+ // _mouseX/Y are truncated from subpixel precision to regular pixel precision.
+ // Therefore, there's no need here to deal with subpixel precision in _mouseX/Y.
+ x = (_mouseX + (event->tfinger.dx * 1.25 * speedFactor * xMax));
+ y = (_mouseY + (event->tfinger.dy * 1.25 * speedFactor * yMax));
}
- x = CLIP(x, 0, (int)_km.x_max);
- y = CLIP(y, 0, (int)_km.y_max);
+ x = CLIP(x, 0, xMax);
+ y = CLIP(y, 0, yMax);
// update the current finger's coordinates so we can track it later
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
@@ -285,8 +287,8 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {
if (numFingersDownLong >= 2) {
// starting drag, so push mouse down at current location (back)
// or location of "oldest" finger (front)
- int mouseDownX = _km.x / MULTIPLIER;
- int mouseDownY = _km.y / MULTIPLIER;
+ int mouseDownX = _mouseX;
+ int mouseDownY = _mouseY;
if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
@@ -346,8 +348,8 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {
}
void SwitchEventSource::convertTouchXYToGameXY(float touchX, float touchY, int *gameX, int *gameY) {
- int screenH = _km.y_max;
- int screenW = _km.x_max;
+ int screenH = _graphicsManager->getWindowHeight();
+ int screenW = _graphicsManager->getWindowWidth();
const int dispW = TOUCHSCREEN_WIDTH;
const int dispH = TOUCHSCREEN_HEIGHT;
@@ -369,8 +371,8 @@ void SwitchEventSource::convertTouchXYToGameXY(float touchX, float touchY, int *
float dispTouchX = (touchX * (float)dispW);
float dispTouchY = (touchY * (float)dispH);
- *gameX = CLIP((int)((dispTouchX - x) / sx), 0, (int)_km.x_max);
- *gameY = CLIP((int)((dispTouchY - y) / sy), 0, (int)_km.y_max);
+ *gameX = CLIP((int)((dispTouchX - x) / sx), 0, screenW);
+ *gameY = CLIP((int)((dispTouchY - y) / sy), 0, screenH);
}
void SwitchEventSource::finishSimulatedMouseClicks() {
@@ -388,8 +390,8 @@ void SwitchEventSource::finishSimulatedMouseClicks() {
SDL_Event ev;
ev.type = SDL_MOUSEBUTTONUP;
ev.button.button = simulatedButton;
- ev.button.x = _km.x / MULTIPLIER;
- ev.button.y = _km.y / MULTIPLIER;
+ ev.button.x = _mouseX;
+ ev.button.y = _mouseY;
SDL_PushEvent(&ev);
_simulatedClickStartTime[port][i] = 0;
diff --git a/backends/events/switchsdl/switchsdl-events.h b/backends/events/switchsdl/switchsdl-events.h
index 6a5076bac3..8aa41b2301 100644
--- a/backends/events/switchsdl/switchsdl-events.h
+++ b/backends/events/switchsdl/switchsdl-events.h
@@ -45,7 +45,8 @@ private:
MAX_TAP_TIME = 250, // taps longer than this will not result in mouse click events
MAX_TAP_MOTION_DISTANCE = 10, // max distance finger motion in Vita screen pixels to be considered a tap
SIMULATED_CLICK_DURATION = 50, // time in ms how long simulated mouse clicks should be
- }; // track three fingers per panel
+ MULTIPLIER = 16 // multiplier for sub-pixel resolution
+ };
typedef struct {
int id; // -1: no touch
diff --git a/backends/events/symbiansdl/symbiansdl-events.h b/backends/events/symbiansdl/symbiansdl-events.h
index 0393e398f0..9b107dc0f4 100644
--- a/backends/events/symbiansdl/symbiansdl-events.h
+++ b/backends/events/symbiansdl/symbiansdl-events.h
@@ -23,14 +23,14 @@
#if !defined(BACKEND_EVENTS_SYMBIAN_SDL_H) && !defined(DISABLE_DEFAULT_EVENTMANAGER)
#define BACKEND_EVENTS_SYMBIAN_SDL_H
-#include "backends/events/sdl/sdl-events.h"
+#include "backends/events/sdl/legacy-sdl-events.h"
#define TOTAL_ZONES 3
/**
* SDL events manager for Symbian
*/
-class SymbianSdlEventSource : public SdlEventSource {
+class SymbianSdlEventSource : public LegacySdlEventSource {
public:
SymbianSdlEventSource();
diff --git a/backends/events/webossdl/webossdl-events.cpp b/backends/events/webossdl/webossdl-events.cpp
index 643276a8e9..ad94891c6a 100644
--- a/backends/events/webossdl/webossdl-events.cpp
+++ b/backends/events/webossdl/webossdl-events.cpp
@@ -150,9 +150,6 @@ bool WebOSSdlEventSource::handleMouseButtonDown(SDL_Event &ev,
_dragging = true;
event.type = Common::EVENT_LBUTTONDOWN;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
}
// If we're not in trackpad mode, move the cursor to the tap
if (!_trackpadMode) {
@@ -161,17 +158,11 @@ bool WebOSSdlEventSource::handleMouseButtonDown(SDL_Event &ev,
// If we're already clicking, hold it until after the move.
if (event.type == Common::EVENT_LBUTTONDOWN) {
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
g_system->getEventManager()->pushEvent(event);
}
// Move the mouse
event.type = Common::EVENT_MOUSEMOVE;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
}
// Watch for a double-tap-triggered drag
_dragStartTime = g_system->getMillis();
@@ -200,9 +191,6 @@ bool WebOSSdlEventSource::handleMouseButtonUp(SDL_Event &ev,
if (ev.button.which == 0 && _dragging) {
event.type = Common::EVENT_LBUTTONUP;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
_dragging = false;
} else {
// If it was the first finger and the click hasn't been
@@ -211,9 +199,6 @@ bool WebOSSdlEventSource::handleMouseButtonUp(SDL_Event &ev,
!_fingerDown[1] && !_fingerDown[2]) {
event.type = Common::EVENT_LBUTTONUP;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
g_system->getEventManager()->pushEvent(event);
event.type = Common::EVENT_LBUTTONDOWN;
if (_queuedDragTime > 0)
@@ -224,9 +209,6 @@ bool WebOSSdlEventSource::handleMouseButtonUp(SDL_Event &ev,
// right mouse click.
event.type = Common::EVENT_RBUTTONDOWN;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
_queuedRUpTime = g_system->getMillis() + QUEUED_RUP_DELAY;
} else if (ev.button.which == 2 &&
_fingerDown[0] && _fingerDown[1]) {
@@ -235,9 +217,6 @@ bool WebOSSdlEventSource::handleMouseButtonUp(SDL_Event &ev,
// as a right click.
event.type = Common::EVENT_MBUTTONUP;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
g_system->getEventManager()->pushEvent(event);
event.type = Common::EVENT_MBUTTONDOWN;
_fingerDown[1] = false;
@@ -284,9 +263,6 @@ bool WebOSSdlEventSource::handleMouseMotion(SDL_Event &ev,
}
event.type = Common::EVENT_MOUSEMOVE;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
}
break;
case 1:
@@ -431,18 +407,12 @@ bool WebOSSdlEventSource::pollEvent(Common::Event &event) {
} else if (_queuedRUpTime != 0 && curTime >= _queuedRUpTime) {
event.type = Common::EVENT_RBUTTONUP;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
_queuedRUpTime = 0;
return true;
} else if (_queuedDragTime != 0 && curTime >= _queuedDragTime) {
event.type = Common::EVENT_LBUTTONDOWN;
_dragging = true;
processMouseEvent(event, _curX, _curY);
- // update KbdMouse
- _km.x = _curX * MULTIPLIER;
- _km.y = _curY * MULTIPLIER;
_queuedDragTime = 0;
return true;
}
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index b45b229d31..36dde9a26e 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -235,7 +235,6 @@ void SdlGraphicsManager::setSystemMousePosition(const int x, const int y) {
}
void SdlGraphicsManager::handleResizeImpl(const int width, const int height, const int xdpi, const int ydpi) {
- _eventSource->resetKeyboardEmulation(width - 1, height - 1);
_forceRedraw = true;
}
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
index 99115275de..b85124e78a 100644
--- a/backends/graphics/windowed.h
+++ b/backends/graphics/windowed.h
@@ -86,6 +86,9 @@ public:
}
}
+ int getWindowWidth() const { return _windowWidth; }
+ int getWindowHeight() const { return _windowHeight; }
+
protected:
/**
* @returns whether or not the game screen must have aspect ratio correction
diff --git a/backends/module.mk b/backends/module.mk
index 5c914d07f8..b5d7736698 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -137,6 +137,7 @@ endif
# derive from the SDL backend, and they all need the following files.
ifdef SDL_BACKEND
MODULE_OBJS += \
+ events/sdl/legacy-sdl-events.o \
events/sdl/sdl-events.o \
graphics/sdl/sdl-graphics.o \
graphics/surfacesdl/surfacesdl-graphics.o \
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index 20b488aa84..de1fd3380e 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -40,7 +40,7 @@
#endif
#include "backends/events/default/default-events.h"
-#include "backends/events/sdl/sdl-events.h"
+#include "backends/events/sdl/legacy-sdl-events.h"
#include "backends/keymapper/hardware-input.h"
#include "backends/mutex/sdl/sdl-mutex.h"
#include "backends/timer/sdl/sdl-timer.h"
@@ -203,7 +203,7 @@ void OSystem_SDL::initBackend() {
// Create the default event source, in case a custom backend
// manager didn't provide one yet.
if (_eventSource == 0)
- _eventSource = new SdlEventSource();
+ _eventSource = new LegacySdlEventSource();
if (_eventManager == nullptr) {
DefaultEventManager *eventManager = new DefaultEventManager(_eventSource);
Commit: e66e35a3fd4b4a3c3b6dafcd7453433f44bfde01
https://github.com/scummvm/scummvm/commit/e66e35a3fd4b4a3c3b6dafcd7453433f44bfde01
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2020-03-09T20:00:31+01:00
Commit Message:
COMMON: Move isMouseEvent from Keymapper to Common
Changed paths:
A common/events.cpp
R common/EventDispatcher.cpp
backends/keymapper/keymapper.cpp
backends/keymapper/keymapper.h
common/events.h
common/module.mk
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
index 869c7969f8..6dc5f36659 100644
--- a/backends/keymapper/keymapper.cpp
+++ b/backends/keymapper/keymapper.cpp
@@ -257,22 +257,6 @@ Keymapper::IncomingEventType Keymapper::convertToIncomingEventType(const Event &
}
}
-bool Keymapper::isMouseEvent(const Event &event) {
- return event.type == EVENT_LBUTTONDOWN
- || event.type == EVENT_LBUTTONUP
- || event.type == EVENT_RBUTTONDOWN
- || event.type == EVENT_RBUTTONUP
- || event.type == EVENT_MBUTTONDOWN
- || event.type == EVENT_MBUTTONUP
- || event.type == EVENT_WHEELDOWN
- || event.type == EVENT_WHEELUP
- || event.type == EVENT_X1BUTTONDOWN
- || event.type == EVENT_X1BUTTONUP
- || event.type == EVENT_X2BUTTONDOWN
- || event.type == EVENT_X2BUTTONUP
- || event.type == EVENT_MOUSEMOVE;
-}
-
Event Keymapper::executeAction(const Action *action, const Event &incomingEvent) {
Event outgoingEvent = Event(action->event);
diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h
index 708732a85f..6f1cf1cb88 100644
--- a/backends/keymapper/keymapper.h
+++ b/backends/keymapper/keymapper.h
@@ -160,7 +160,6 @@ private:
Event executeAction(const Action *act, const Event &incomingEvent);
EventType convertStartToEnd(EventType eventType);
IncomingEventType convertToIncomingEventType(const Event &ev) const;
- static bool isMouseEvent(const Event &event);
void hardcodedEventMapping(Event ev);
void resetInputState();
diff --git a/common/EventDispatcher.cpp b/common/events.cpp
similarity index 85%
rename from common/EventDispatcher.cpp
rename to common/events.cpp
index 3f7da512b0..529ef7ff26 100644
--- a/common/EventDispatcher.cpp
+++ b/common/events.cpp
@@ -24,6 +24,30 @@
namespace Common {
+bool isMouseEvent(const Event &event) {
+ return event.type == EVENT_LBUTTONDOWN
+ || event.type == EVENT_LBUTTONUP
+ || event.type == EVENT_RBUTTONDOWN
+ || event.type == EVENT_RBUTTONUP
+ || event.type == EVENT_MBUTTONDOWN
+ || event.type == EVENT_MBUTTONUP
+ || event.type == EVENT_X1BUTTONDOWN
+ || event.type == EVENT_X1BUTTONUP
+ || event.type == EVENT_X2BUTTONDOWN
+ || event.type == EVENT_X2BUTTONUP
+ || event.type == EVENT_WHEELDOWN
+ || event.type == EVENT_WHEELUP
+ || event.type == EVENT_MOUSEMOVE;
+}
+
+EventSource::~EventSource() {}
+
+EventObserver::~EventObserver() {}
+
+EventMapper::~EventMapper() {}
+
+EventManager::~EventManager() {}
+
EventDispatcher::EventDispatcher() : _mapper(nullptr) {
}
diff --git a/common/events.h b/common/events.h
index d7a39d52d4..b781f35cca 100644
--- a/common/events.h
+++ b/common/events.h
@@ -221,6 +221,13 @@ struct Event {
}
};
+/**
+ * Determinates whether an event is a mouse event
+ *
+ * Mouse events have valid mouse coordinates
+ */
+bool isMouseEvent(const Event &event);
+
/**
* A source of Events.
*
@@ -229,7 +236,7 @@ struct Event {
*/
class EventSource {
public:
- virtual ~EventSource() {}
+ virtual ~EventSource();
/**
* Queries a event from the source.
@@ -287,7 +294,7 @@ public:
*/
class EventObserver {
public:
- virtual ~EventObserver() {}
+ virtual ~EventObserver();
/**
* Notifies the observer of an incoming event.
@@ -317,7 +324,7 @@ public:
*/
class EventMapper {
public:
- virtual ~EventMapper() {}
+ virtual ~EventMapper();
/**
* Map an incoming event to one or more action events
@@ -423,8 +430,7 @@ class Keymapper;
*/
class EventManager : NonCopyable {
public:
- EventManager() {}
- virtual ~EventManager() {}
+ virtual ~EventManager();
enum {
LBUTTON = 1 << MOUSE_BUTTON_LEFT,
diff --git a/common/module.mk b/common/module.mk
index 717d37a7f1..6769ce3f3b 100644
--- a/common/module.mk
+++ b/common/module.mk
@@ -7,7 +7,7 @@ MODULE_OBJS := \
dcl.o \
debug.o \
error.o \
- EventDispatcher.o \
+ events.o \
file.o \
fs.o \
gui_options.o \
Commit: 568d882e80dc41066943b3bb5e1742ca41b5c99a
https://github.com/scummvm/scummvm/commit/568d882e80dc41066943b3bb5e1742ca41b5c99a
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2020-03-09T20:00:31+01:00
Commit Message:
KEYMAPPER: Introduce a Virtual Mouse event source
The Virtual Mouse is meant to provide a way to control the mouse cursor
on system without a physical mouse. It provides keymapper actions that
are expected to be bound to game controller axes or buttons.
Changed paths:
A backends/keymapper/virtual-mouse.cpp
A backends/keymapper/virtual-mouse.h
backends/events/default/default-events.cpp
backends/events/default/default-events.h
backends/keymapper/action.h
backends/keymapper/keymap.cpp
backends/keymapper/keymapper.cpp
backends/module.mk
backends/platform/sdl/sdl.cpp
common/events.h
po/POTFILES
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index e29d9c3da5..8781b1ce7f 100644
--- a/backends/events/default/default-events.cpp
+++ b/backends/events/default/default-events.cpp
@@ -30,7 +30,7 @@
#include "backends/events/default/default-events.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymapper.h"
-#include "backends/keymapper/remap-widget.h"
+#include "backends/keymapper/virtual-mouse.h"
#include "backends/vkeybd/virtual-keyboard.h"
#include "engines/engine.h"
@@ -58,13 +58,15 @@ DefaultEventManager::DefaultEventManager(Common::EventSource *boss) :
#ifdef ENABLE_VKEYBD
_vk = nullptr;
#endif
+
+ _virtualMouse = new Common::VirtualMouse(&_dispatcher);
+
_keymapper = new Common::Keymapper(this);
- // EventDispatcher will automatically free the keymapper
_dispatcher.registerMapper(_keymapper);
- _remap = false;
}
DefaultEventManager::~DefaultEventManager() {
+ delete _virtualMouse;
#ifdef ENABLE_VKEYBD
delete _vk;
#endif
@@ -372,6 +374,8 @@ Common::Keymap *DefaultEventManager::getGlobalKeymap() {
act->setEvent(EVENT_DEBUGGER);
globalKeymap->addAction(act);
+ _virtualMouse->addActionsToKeymap(globalKeymap);
+
return globalKeymap;
}
diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h
index 11d523af04..7696c08303 100644
--- a/backends/events/default/default-events.h
+++ b/backends/events/default/default-events.h
@@ -31,6 +31,7 @@ class Keymapper;
#ifdef ENABLE_VKEYBD
class VirtualKeyboard;
#endif
+class VirtualMouse;
}
@@ -39,8 +40,9 @@ class DefaultEventManager : public Common::EventManager, Common::EventObserver {
Common::VirtualKeyboard *_vk;
#endif
+ Common::VirtualMouse *_virtualMouse;
+
Common::Keymapper *_keymapper;
- bool _remap;
Common::ArtificialEventSource _artificialEventSource;
diff --git a/backends/keymapper/action.h b/backends/keymapper/action.h
index a8e46e8d9c..f798d2f50a 100644
--- a/backends/keymapper/action.h
+++ b/backends/keymapper/action.h
@@ -68,6 +68,12 @@ public:
event.customType = evtType;
}
+ void setCustomBackendActionAxisEvent(const CustomEventType evtType) {
+ event = Event();
+ event.type = EVENT_CUSTOM_BACKEND_ACTION_AXIS;
+ event.customType = evtType;
+ }
+
void setCustomEngineActionEvent(const CustomEventType evtType) {
event = Event();
event.type = EVENT_CUSTOM_ENGINE_ACTION_START;
diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp
index 409aff6a2c..64b8c3ddaa 100644
--- a/backends/keymapper/keymap.cpp
+++ b/backends/keymapper/keymap.cpp
@@ -171,9 +171,19 @@ Keymap::ActionArray Keymap::getMappedActions(const Event &event) const {
return _hwActionMap[hardwareInput];
}
case EVENT_JOYAXIS_MOTION: {
- bool positiveHalf = event.joystick.position >= 0;
- HardwareInput hardwareInput = HardwareInput::createJoystickHalfAxis("", event.joystick.axis, positiveHalf, "");
- return _hwActionMap[hardwareInput];
+ if (event.joystick.position != 0) {
+ bool positiveHalf = event.joystick.position >= 0;
+ HardwareInput hardwareInput = HardwareInput::createJoystickHalfAxis("", event.joystick.axis, positiveHalf, "");
+ return _hwActionMap[hardwareInput];
+ } else {
+ // Axis position zero is part of both half axes, and triggers actions bound to both
+ Keymap::ActionArray actions;
+ HardwareInput hardwareInputPos = HardwareInput::createJoystickHalfAxis("", event.joystick.axis, true, "");
+ HardwareInput hardwareInputNeg = HardwareInput::createJoystickHalfAxis("", event.joystick.axis, false, "");
+ actions.push_back(_hwActionMap[hardwareInputPos]);
+ actions.push_back(_hwActionMap[hardwareInputNeg]);
+ return actions;
+ }
}
case EVENT_CUSTOM_BACKEND_HARDWARE: {
HardwareInput hardwareInput = HardwareInput::createCustom("", event.customType, "");
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
index 6dc5f36659..c3d5b9ed0c 100644
--- a/backends/keymapper/keymapper.cpp
+++ b/backends/keymapper/keymapper.cpp
@@ -261,6 +261,23 @@ Event Keymapper::executeAction(const Action *action, const Event &incomingEvent)
Event outgoingEvent = Event(action->event);
IncomingEventType incomingType = convertToIncomingEventType(incomingEvent);
+
+ if (outgoingEvent.type == EVENT_JOYAXIS_MOTION
+ || outgoingEvent.type == EVENT_CUSTOM_BACKEND_ACTION_AXIS) {
+ if (incomingEvent.type == EVENT_JOYAXIS_MOTION) {
+ // At the moment only half-axes can be bound to actions, hence taking
+ // the absolute value. If full axes were to be mappable, the action
+ // could carry the information allowing to distinguish cases here.
+ outgoingEvent.joystick.position = ABS(incomingEvent.joystick.position);
+ } else if (incomingType == kIncomingEventStart) {
+ outgoingEvent.joystick.position = JOYAXIS_MAX;
+ } else if (incomingType == kIncomingEventEnd) {
+ outgoingEvent.joystick.position = 0;
+ }
+
+ return outgoingEvent;
+ }
+
if (incomingType == kIncomingEventIgnored) {
outgoingEvent.type = EVENT_INVALID;
return outgoingEvent;
diff --git a/backends/keymapper/virtual-mouse.cpp b/backends/keymapper/virtual-mouse.cpp
new file mode 100644
index 0000000000..0adf3a2a92
--- /dev/null
+++ b/backends/keymapper/virtual-mouse.cpp
@@ -0,0 +1,219 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "backends/keymapper/virtual-mouse.h"
+
+#include "backends/keymapper/action.h"
+#include "backends/keymapper/keymap.h"
+
+#include "common/config-manager.h"
+#include "common/system.h"
+#include "common/translation.h"
+
+#include "gui/gui-manager.h"
+
+namespace Common {
+
+VirtualMouse::VirtualMouse(EventDispatcher *eventDispatcher) :
+ _eventDispatcher(eventDispatcher),
+ _inputAxisPositionX(0),
+ _inputAxisPositionY(0),
+ _mouseVelocityX(0.f),
+ _mouseVelocityY(0.f),
+ _slowModifier(1.f),
+ _subPixelRemainderX(0.f),
+ _subPixelRemainderY(0.f),
+ _lastUpdateMillis(0) {
+ _eventDispatcher->registerSource(this, false);
+ _eventDispatcher->registerObserver(this, 10, false);
+}
+
+VirtualMouse::~VirtualMouse() {
+ _eventDispatcher->unregisterObserver(this);
+ _eventDispatcher->unregisterSource(this);
+}
+
+bool VirtualMouse::pollEvent(Event &event) {
+ // Update the virtual mouse once per frame (assuming 60Hz)
+ uint32 curTime = g_system->getMillis(true);
+ if (curTime < _lastUpdateMillis + kUpdateDelay) {
+ return false;
+ }
+ _lastUpdateMillis = curTime;
+
+ // Adjust the speed of the cursor according to the virtual screen resolution
+ Common::Rect screenSize;
+ if (g_gui.isActive()) {
+ screenSize = Common::Rect(g_system->getOverlayWidth(), g_system->getOverlayHeight());
+ } else {
+ screenSize = Common::Rect(g_system->getWidth(), g_system->getHeight());
+ }
+
+ float screenSizeSpeedModifier = screenSize.width() / (float)kDefaultScreenWidth;
+
+ // Compute the movement delta when compared to the previous update
+ float deltaX = _subPixelRemainderX + _mouseVelocityX * _slowModifier * screenSizeSpeedModifier * 10.f;
+ float deltaY = _subPixelRemainderY + _mouseVelocityY * _slowModifier * screenSizeSpeedModifier * 10.f;
+
+ Common::Point delta;
+ delta.x = deltaX;
+ delta.y = deltaY;
+
+ // Keep track of sub-pixel movement so the cursor ultimately moves,
+ // even when configured at very low speeds.
+ _subPixelRemainderX = deltaX - delta.x;
+ _subPixelRemainderY = deltaY - delta.y;
+
+ if (delta.x == 0 && delta.y == 0) {
+ return false;
+ }
+
+ // Send a mouse event
+ Common::Point oldPos = g_system->getEventManager()->getMousePos();
+
+ event.type = Common::EVENT_MOUSEMOVE;
+ event.mouse = oldPos + delta;
+
+ event.mouse.x = CLIP<int16>(event.mouse.x, 0, screenSize.width());
+ event.mouse.y = CLIP<int16>(event.mouse.y, 0, screenSize.height());
+
+ g_system->warpMouse(event.mouse.x, event.mouse.y);
+
+ return true;
+}
+
+bool VirtualMouse::notifyEvent(const Event &event) {
+ if (event.type != EVENT_CUSTOM_BACKEND_ACTION_AXIS) {
+ return false;
+ }
+
+ switch (event.customType) {
+ case kCustomActionVirtualAxisUp:
+ if (event.joystick.position == 0 && _inputAxisPositionY > 0) {
+ return true; // Ignore axis reset events if we are already going in the other direction
+ }
+
+ handleAxisMotion(_inputAxisPositionX, -event.joystick.position);
+ return true;
+ case kCustomActionVirtualAxisDown:
+ if (event.joystick.position == 0 && _inputAxisPositionY < 0) {
+ return true;
+ }
+
+ handleAxisMotion(_inputAxisPositionX, event.joystick.position);
+ return true;
+ case kCustomActionVirtualAxisLeft:
+ if (event.joystick.position == 0 && _inputAxisPositionX > 0) {
+ return true;
+ }
+
+ handleAxisMotion(-event.joystick.position, _inputAxisPositionY);
+ return true;
+ case kCustomActionVirtualAxisRight:
+ if (event.joystick.position == 0 && _inputAxisPositionX < 0) {
+ return true;
+ }
+
+ handleAxisMotion(event.joystick.position, _inputAxisPositionY);
+ return true;
+ case kCustomActionVirtualMouseSlow:
+ _slowModifier = 0.9f * (1.f - event.joystick.position / (float)JOYAXIS_MAX) + 0.1f;
+ return true;
+ }
+
+ return false;
+}
+
+void VirtualMouse::addActionsToKeymap(Keymap *keymap) {
+ Action *act;
+
+ act = new Action("VMOUSEUP", _("Virtual mouse up"));
+ act->addDefaultInputMapping("JOY_LEFT_STICK_Y-");
+ act->setCustomBackendActionAxisEvent(VirtualMouse::kCustomActionVirtualAxisUp);
+ keymap->addAction(act);
+
+ act = new Action("VMOUSEDOWN", _("Virtual mouse down"));
+ act->addDefaultInputMapping("JOY_LEFT_STICK_Y+");
+ act->setCustomBackendActionAxisEvent(VirtualMouse::kCustomActionVirtualAxisDown);
+ keymap->addAction(act);
+
+ act = new Action("VMOUSELEFT", _("Virtual mouse left"));
+ act->addDefaultInputMapping("JOY_LEFT_STICK_X-");
+ act->setCustomBackendActionAxisEvent(VirtualMouse::kCustomActionVirtualAxisLeft);
+ keymap->addAction(act);
+
+ act = new Action("VMOUSERIGHT", _("Virtual mouse right"));
+ act->addDefaultInputMapping("JOY_LEFT_STICK_X+");
+ act->setCustomBackendActionAxisEvent(VirtualMouse::kCustomActionVirtualAxisRight);
+ keymap->addAction(act);
+
+ act = new Action("VMOUSESLOW", _("Slow down virtual mouse"));
+ act->addDefaultInputMapping("JOY_RIGHT_SHOULDER");
+ act->setCustomBackendActionAxisEvent(VirtualMouse::kCustomActionVirtualMouseSlow);
+ keymap->addAction(act);
+}
+
+void VirtualMouse::handleAxisMotion(int16 axisPositionX, int16 axisPositionY) {
+ _inputAxisPositionX = axisPositionX;
+ _inputAxisPositionY = axisPositionY;
+
+ float analogX = (float)_inputAxisPositionX;
+ float analogY = (float)_inputAxisPositionY;
+ float deadZone = (float)ConfMan.getInt("joystick_deadzone") * 1000.0f;
+
+ float magnitude = sqrtf(analogX * analogX + analogY * analogY);
+
+ if (magnitude >= deadZone) {
+ float scalingFactor = 1.0f / magnitude * (magnitude - deadZone) / (JOYAXIS_MAX - deadZone);
+ float speedFactor = computeJoystickMouseSpeedFactor();
+ _mouseVelocityX = analogX * scalingFactor * speedFactor;
+ _mouseVelocityY = analogY * scalingFactor * speedFactor;
+ } else {
+ _mouseVelocityX = 0.f;
+ _mouseVelocityY = 0.f;
+ }
+}
+
+float VirtualMouse::computeJoystickMouseSpeedFactor() const {
+ switch (ConfMan.getInt("kbdmouse_speed")) {
+ case 0:
+ return 0.25; // 0.25 keyboard pointer speed
+ case 1:
+ return 0.5; // 0.5 speed
+ case 2:
+ return 0.75; // 0.75 speed
+ case 3:
+ return 1.0; // 1.0 speed
+ case 4:
+ return 1.25; // 1.25 speed
+ case 5:
+ return 1.5; // 1.5 speed
+ case 6:
+ return 1.75; // 1.75 speed
+ case 7:
+ return 2.0; // 2.0 speed
+ default:
+ return 1.0;
+ }
+}
+
+} // End of namespace Common
diff --git a/backends/keymapper/virtual-mouse.h b/backends/keymapper/virtual-mouse.h
new file mode 100644
index 0000000000..58c0f29799
--- /dev/null
+++ b/backends/keymapper/virtual-mouse.h
@@ -0,0 +1,91 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef BACKENDS_KEYMAPPER_VIRTUAL_MOUSE_H
+#define BACKENDS_KEYMAPPER_VIRTUAL_MOUSE_H
+
+#include "common/scummsys.h"
+
+#include "common/events.h"
+
+namespace Common {
+
+class EventDispatcher;
+class Keymap;
+
+/**
+ * The Virtual Mouse can produce mouse move events on systems without a physical mouse.
+ *
+ * It is useful for moving the mouse cursor using a gamepad or a keyboard.
+ *
+ * This class defines a keymap with actions for moving the cursor in all four directions.
+ * The keymapper produces custom backend events whenever keys bound to these actions are
+ * pressed. This class handles the events through its EventObserver interface and produces
+ * mouse move events when necesssary through its EventSource interface.
+ */
+class VirtualMouse : public EventSource, public EventObserver {
+public:
+ VirtualMouse(EventDispatcher *eventDispatcher);
+ ~VirtualMouse() override;
+
+ // EventSource API
+ bool pollEvent(Event &event) override;
+
+ // EventObserver API
+ bool notifyEvent(const Event &event) override;
+
+ /** Add the virtual mouse keymapper actions to a keymap */
+ void addActionsToKeymap(Keymap *keymap);
+
+private:
+ static const int32 kUpdateDelay = 12;
+ static const int32 kDefaultScreenWidth = 640;
+
+ enum {
+ kCustomActionVirtualAxisUp = 10000,
+ kCustomActionVirtualAxisDown = 10001,
+ kCustomActionVirtualAxisLeft = 10002,
+ kCustomActionVirtualAxisRight = 10003,
+ kCustomActionVirtualMouseSlow = 10004
+ };
+
+ void handleAxisMotion(int16 axisPositionX, int16 axisPositionY);
+ float computeJoystickMouseSpeedFactor() const;
+
+ EventDispatcher *_eventDispatcher;
+
+ int16 _inputAxisPositionX;
+ int16 _inputAxisPositionY;
+
+ float _mouseVelocityX;
+ float _mouseVelocityY;
+ float _slowModifier;
+
+ float _subPixelRemainderX;
+ float _subPixelRemainderY;
+
+ uint32 _lastUpdateMillis;
+};
+
+} // End of namespace Common
+
+#endif // #ifndef BACKENDS_KEYMAPPER_VIRTUAL_MOUSE_H
diff --git a/backends/module.mk b/backends/module.mk
index b5d7736698..caea5bb11c 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -15,6 +15,7 @@ MODULE_OBJS := \
keymapper/keymapper.o \
keymapper/remap-widget.o \
keymapper/standard-actions.o \
+ keymapper/virtual-mouse.o \
log/log.o \
midi/alsa.o \
midi/dmedia.o \
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index de1fd3380e..79b9ae5006 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -203,7 +203,7 @@ void OSystem_SDL::initBackend() {
// Create the default event source, in case a custom backend
// manager didn't provide one yet.
if (_eventSource == 0)
- _eventSource = new LegacySdlEventSource();
+ _eventSource = new SdlEventSource();
if (_eventManager == nullptr) {
DefaultEventManager *eventManager = new DefaultEventManager(_eventSource);
diff --git a/common/events.h b/common/events.h
index b781f35cca..d314acf0d2 100644
--- a/common/events.h
+++ b/common/events.h
@@ -76,6 +76,7 @@ enum EventType {
EVENT_CUSTOM_BACKEND_ACTION_START = 18,
EVENT_CUSTOM_BACKEND_ACTION_END = 19,
+ EVENT_CUSTOM_BACKEND_ACTION_AXIS = 34,
EVENT_CUSTOM_ENGINE_ACTION_START = 20,
EVENT_CUSTOM_ENGINE_ACTION_END = 21,
diff --git a/po/POTFILES b/po/POTFILES
index b72a56ae46..abdef12d73 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -65,6 +65,7 @@ backends/graphics/surfacesdl/surfacesdl-graphics.cpp
backends/graphics/sdl/sdl-graphics.cpp
backends/keymapper/hardware-input.cpp
backends/keymapper/remap-widget.cpp
+backends/keymapper/virtual-mouse.cpp
backends/midi/windows.cpp
backends/networking/sdl_net/handlers/createdirectoryhandler.cpp
backends/networking/sdl_net/handlers/downloadfilehandler.cpp
Commit: cd173c8739668108c664c220244ae5e83238c87d
https://github.com/scummvm/scummvm/commit/cd173c8739668108c664c220244ae5e83238c87d
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2020-03-09T20:00:31+01:00
Commit Message:
3DS: Use the shared virtual mouse
Changed paths:
backends/platform/3ds/config.cpp
backends/platform/3ds/config.h
backends/platform/3ds/options-dialog.cpp
backends/platform/3ds/options-dialog.h
backends/platform/3ds/osystem-events.cpp
backends/platform/3ds/osystem-graphics.cpp
diff --git a/backends/platform/3ds/config.cpp b/backends/platform/3ds/config.cpp
index 4c567c2920..a160ac9950 100644
--- a/backends/platform/3ds/config.cpp
+++ b/backends/platform/3ds/config.cpp
@@ -58,7 +58,6 @@ void loadConfig() {
config.showCursor = confGetBool("showcursor", true);
config.snapToBorder = confGetBool("snaptoborder", true);
config.stretchToFit = confGetBool("stretchtofit", false);
- config.sensitivity = confGetInt("sensitivity", -5);
config.screen = confGetInt("screen", kScreenBoth);
// Turn off the backlight of any screen not used
@@ -83,7 +82,6 @@ void saveConfig() {
confSetBool("showcursor", config.showCursor);
confSetBool("snaptoborder", config.snapToBorder);
confSetBool("stretchtofit", config.stretchToFit);
- confSetInt("sensitivity", config.sensitivity);
confSetInt("screen", config.screen);
ConfMan.flushToDisk();
}
diff --git a/backends/platform/3ds/config.h b/backends/platform/3ds/config.h
index 02560b2040..346cf19ca4 100644
--- a/backends/platform/3ds/config.h
+++ b/backends/platform/3ds/config.h
@@ -31,7 +31,6 @@ struct Config {
bool showCursor;
bool snapToBorder;
bool stretchToFit;
- int sensitivity;
int screen;
};
diff --git a/backends/platform/3ds/options-dialog.cpp b/backends/platform/3ds/options-dialog.cpp
index a6155e0f70..e83ec34db7 100644
--- a/backends/platform/3ds/options-dialog.cpp
+++ b/backends/platform/3ds/options-dialog.cpp
@@ -59,13 +59,6 @@ OptionsDialog::OptionsDialog() : GUI::Dialog(20, 20, 280, 200) {
_screenBottomRadioWidget = new GUI::RadiobuttonWidget(this, 190, 50, 80, 20, _screenRadioGroup, kScreenBottom, _c("Bottom", "3ds-screen"));
_screenBothRadioWidget = new GUI::RadiobuttonWidget(this, 155, 70, 80, 20, _screenRadioGroup, kScreenBoth, _c("Both", "3ds-screen"));
_screenRadioGroup->setValue(config.screen);
-
- new GUI::StaticTextWidget(this, 0, 100, 110, 15, _("C-Pad Sensitivity:"), Graphics::kTextAlignRight);
- _sensitivity = new GUI::SliderWidget(this, 115, 100, 160, 15);
- _sensitivity->setMinValue(-15);
- _sensitivity->setMaxValue(30);
- _sensitivity->setValue(config.sensitivity);
- _sensitivity->setFlags(GUI::WIDGET_CLEARBG);
}
OptionsDialog::~OptionsDialog() {
@@ -84,10 +77,6 @@ bool OptionsDialog::getStretchToFit() const {
return _stretchToFitCheckbox->getState();
}
-int OptionsDialog::getSensitivity() const {
- return _sensitivity->getValue();
-}
-
int OptionsDialog::getScreen() const {
return _screenRadioGroup->getValue();
}
diff --git a/backends/platform/3ds/options-dialog.h b/backends/platform/3ds/options-dialog.h
index 68ff75e242..1922791c75 100644
--- a/backends/platform/3ds/options-dialog.h
+++ b/backends/platform/3ds/options-dialog.h
@@ -61,7 +61,6 @@ public:
protected:
void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
- GUI::SliderWidget *_sensitivity;
GUI::CheckboxWidget *_showCursorCheckbox;
GUI::CheckboxWidget *_snapToBorderCheckbox;
GUI::CheckboxWidget *_stretchToFitCheckbox;
diff --git a/backends/platform/3ds/osystem-events.cpp b/backends/platform/3ds/osystem-events.cpp
index d4d47f3e0e..87e7a033f8 100644
--- a/backends/platform/3ds/osystem-events.cpp
+++ b/backends/platform/3ds/osystem-events.cpp
@@ -73,6 +73,8 @@ const Common::HardwareInputTableEntry ctrMouseButtons[] = {
{ nullptr, 0, nullptr }
};
+static const int16 CIRCLE_MAX = 160;
+
static void pushEventQueue(Common::Queue<Common::Event> *queue, Common::Event &event) {
Common::StackLock lock(*eventMutex);
queue->push(event);
@@ -93,10 +95,8 @@ static void eventThreadFunc(void *arg) {
auto eventQueue = (Common::Queue<Common::Event> *)arg;
uint32 touchStartTime = osys->getMillis();
- touchPosition lastTouch = {0, 0};
- float cursorDeltaX = 0;
- float cursorDeltaY = 0;
- int circleDeadzone = 20;
+ touchPosition lastTouch = {0, 0};
+ circlePosition lastCircle = {0, 0};
int borderSnapZone = 6;
Common::Event event;
@@ -106,25 +106,13 @@ static void eventThreadFunc(void *arg) {
} while (osys->sleeping && !osys->exiting);
hidScanInput();
- touchPosition touch;
- circlePosition circle;
u32 held = hidKeysHeld();
u32 keysPressed = hidKeysDown();
u32 keysReleased = hidKeysUp();
- // C-Pad used to control the cursor
- hidCircleRead(&circle);
- if (circle.dx < circleDeadzone && circle.dx > -circleDeadzone) {
- circle.dx = 0;
- }
- if (circle.dy < circleDeadzone && circle.dy > -circleDeadzone) {
- circle.dy = 0;
- }
- cursorDeltaX = (0.0002f + config.sensitivity / 100000.f) * circle.dx * abs(circle.dx);
- cursorDeltaY = (0.0002f + config.sensitivity / 100000.f) * circle.dy * abs(circle.dy);
-
// Touch screen events
if (held & KEY_TOUCH) {
+ touchPosition touch;
hidTouchRead(&touch);
if (config.snapToBorder) {
if (touch.px < borderSnapZone) {
@@ -143,7 +131,6 @@ static void eventThreadFunc(void *arg) {
osys->transformPoint(touch);
- osys->warpMouse(touch.px, touch.py);
event.mouse.x = touch.px;
event.mouse.y = touch.py;
@@ -174,21 +161,28 @@ static void eventThreadFunc(void *arg) {
event.type = Common::EVENT_LBUTTONUP;
pushEventQueue(eventQueue, event);
}
- } else if (cursorDeltaX != 0 || cursorDeltaY != 0) {
- float scaleRatio = osys->getScaleRatio();
+ }
- lastTouch.px += cursorDeltaX / scaleRatio;
- lastTouch.py -= cursorDeltaY / scaleRatio;
+ // C-Pad events
+ circlePosition circle;
+ hidCircleRead(&circle);
- osys->clipPoint(lastTouch);
- osys->warpMouse(lastTouch.px, lastTouch.py);
+ if (circle.dx != lastCircle.dx) {
+ event.type = Common::EVENT_JOYAXIS_MOTION;
+ event.joystick.axis = Common::JOYSTICK_AXIS_LEFT_STICK_X;
+ event.joystick.position = (int32)circle.dx * Common::JOYAXIS_MAX / CIRCLE_MAX;
+ pushEventQueue(eventQueue, event);
+ }
- event.mouse.x = lastTouch.px;
- event.mouse.y = lastTouch.py;
- event.type = Common::EVENT_MOUSEMOVE;
+ if (circle.dy != lastCircle.dy) {
+ event.type = Common::EVENT_JOYAXIS_MOTION;
+ event.joystick.axis = Common::JOYSTICK_AXIS_LEFT_STICK_Y;
+ event.joystick.position = -(int32)circle.dy * Common::JOYAXIS_MAX / CIRCLE_MAX;
pushEventQueue(eventQueue, event);
}
+ lastCircle = circle;
+
// Button events
doJoyEvent(eventQueue, keysPressed, keysReleased, KEY_L, Common::JOYSTICK_BUTTON_LEFT_SHOULDER);
doJoyEvent(eventQueue, keysPressed, keysReleased, KEY_R, Common::JOYSTICK_BUTTON_RIGHT_SHOULDER);
@@ -367,6 +361,11 @@ bool OSystem_3DS::pollEvent(Common::Event &event) {
}
event = _eventQueue.pop();
+
+ if (Common::isMouseEvent(event)) {
+ warpMouse(event.mouse.x, event.mouse.y);
+ }
+
return true;
}
@@ -458,7 +457,6 @@ void OSystem_3DS::runOptionsDialog() {
config.showCursor = dialog.getShowCursor();
config.snapToBorder = dialog.getSnapToBorder();
config.stretchToFit = dialog.getStretchToFit();
- config.sensitivity = dialog.getSensitivity();
config.screen = dialog.getScreen();
saveConfig();
diff --git a/backends/platform/3ds/osystem-graphics.cpp b/backends/platform/3ds/osystem-graphics.cpp
index b4ff84cbca..ad2b1d3ca0 100644
--- a/backends/platform/3ds/osystem-graphics.cpp
+++ b/backends/platform/3ds/osystem-graphics.cpp
@@ -123,7 +123,9 @@ void OSystem_3DS::destroy3DSGraphics() {
bool OSystem_3DS::hasFeature(OSystem::Feature f) {
return (f == OSystem::kFeatureCursorPalette ||
- f == OSystem::kFeatureOverlaySupportsAlpha);
+ f == OSystem::kFeatureOverlaySupportsAlpha ||
+ f == OSystem::kFeatureKbdMouseSpeed ||
+ f == OSystem::kFeatureJoystickDeadzone);
}
void OSystem_3DS::setFeatureState(OSystem::Feature f, bool enable) {
More information about the Scummvm-git-logs
mailing list