aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2017-09-13 19:55:14 -0500
committerColin Snover2017-10-15 13:24:21 -0500
commitcd538ffffab9e49443da4ee043916d8dc22c3c07 (patch)
treeaebfd4a4009e2653a743241875a0ce27cad07065
parent319ab07fe0900e6ec2f89666b544e695edca6dde (diff)
downloadscummvm-rg350-cd538ffffab9e49443da4ee043916d8dc22c3c07.tar.gz
scummvm-rg350-cd538ffffab9e49443da4ee043916d8dc22c3c07.tar.bz2
scummvm-rg350-cd538ffffab9e49443da4ee043916d8dc22c3c07.zip
BACKENDS: Do not send mouse events to games occurring outside the game draw rect
-rw-r--r--backends/events/sdl/sdl-events.cpp36
-rw-r--r--backends/events/sdl/sdl-events.h2
-rw-r--r--backends/graphics/sdl/sdl-graphics.cpp39
-rw-r--r--backends/graphics/sdl/sdl-graphics.h4
-rw-r--r--backends/graphics/windowed.h9
5 files changed, 63 insertions, 27 deletions
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index db4aa21ef1..6f34420674 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -169,13 +169,15 @@ int SdlEventSource::mapKey(SDLKey sdlKey, SDLMod mod, Uint16 unicode) {
}
}
-void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
+bool SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
event.mouse.x = x;
event.mouse.y = y;
if (_graphicsManager) {
- _graphicsManager->notifyMousePosition(event.mouse);
+ return _graphicsManager->notifyMousePosition(event.mouse);
}
+
+ return true;
}
bool SdlEventSource::handleKbdMouse(Common::Event &event) {
@@ -307,8 +309,7 @@ bool SdlEventSource::handleKbdMouse(Common::Event &event) {
if (_km.x != oldKmX || _km.y != oldKmY) {
event.type = Common::EVENT_MOUSEMOVE;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
- return true;
+ return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
}
}
}
@@ -548,7 +549,9 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
// 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.
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ if (!processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER)) {
+ return false;
+ }
if (yDir < 0) {
event.type = Common::EVENT_WHEELDOWN;
return true;
@@ -739,12 +742,12 @@ bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) {
bool SdlEventSource::handleMouseMotion(SDL_Event &ev, Common::Event &event) {
event.type = Common::EVENT_MOUSEMOVE;
- processMouseEvent(event, ev.motion.x, ev.motion.y);
+
// update KbdMouse
_km.x = ev.motion.x * MULTIPLIER;
_km.y = ev.motion.y * MULTIPLIER;
- return true;
+ return processMouseEvent(event, ev.motion.x, ev.motion.y);
}
bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) {
@@ -765,12 +768,11 @@ bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event)
else
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;
+ return processMouseEvent(event, ev.button.x, ev.button.y);
}
bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
@@ -784,21 +786,21 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
#endif
else
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;
+ return processMouseEvent(event, ev.button.x, ev.button.y);
}
bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONDOWN;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONDOWN;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else {
event.type = Common::EVENT_KEYDOWN;
switch (ev.jbutton.button) {
@@ -819,17 +821,17 @@ bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
break;
}
+ return true;
}
- return true;
}
bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONUP;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONUP;
- processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else {
event.type = Common::EVENT_KEYUP;
switch (ev.jbutton.button) {
@@ -850,8 +852,8 @@ bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
event.kbd.ascii = mapKey(SDLK_F5, (SDLMod)ev.key.keysym.mod, 0);
break;
}
+ return true;
}
- return true;
}
bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index cf445e9e2c..1d701f5ecf 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -117,7 +117,7 @@ protected:
* Assigns the mouse coords to the mouse event. Furthermore notify the
* graphics manager about the position change.
*/
- virtual void processMouseEvent(Common::Event &event, int x, int y);
+ virtual bool processMouseEvent(Common::Event &event, int x, int y);
/**
* Remaps key events. This allows platforms to configure
diff --git a/backends/graphics/sdl/sdl-graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp
index 6ce0bc7bac..e6699df1cd 100644
--- a/backends/graphics/sdl/sdl-graphics.cpp
+++ b/backends/graphics/sdl/sdl-graphics.cpp
@@ -169,22 +169,47 @@ bool SdlGraphicsManager::showMouse(const bool visible) {
return WindowedGraphicsManager::showMouse(visible);
}
-void SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
+bool SdlGraphicsManager::notifyMousePosition(Common::Point &mouse) {
int showCursor = SDL_DISABLE;
- if (!_activeArea.drawRect.contains(mouse)) {
+ bool valid = true;
+ if (_activeArea.drawRect.contains(mouse)) {
+ _cursorLastInActiveArea = true;
+ } else {
mouse.x = CLIP<int>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right - 1);
mouse.y = CLIP<int>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom - 1);
- if (_window->mouseIsGrabbed()) {
+ if (_window->mouseIsGrabbed() ||
+ // Keep the mouse inside the game area during dragging to prevent an
+ // event mismatch where the mouseup event gets lost because it is
+ // performed outside of the game area
+ (_cursorLastInActiveArea && SDL_GetMouseState(nullptr, nullptr) != 0)) {
setSystemMousePosition(mouse.x, mouse.y);
- } else if (_cursorVisible) {
- showCursor = SDL_ENABLE;
+ } else {
+ // Allow the in-game mouse to get a final movement event to the edge
+ // of the window if the mouse was moved out of the game area
+ if (_cursorLastInActiveArea) {
+ _cursorLastInActiveArea = false;
+ } else if (_cursorVisible) {
+ // Keep sending events to the game if the cursor is invisible,
+ // since otherwise if a game lets you skip a cutscene by
+ // clicking and the user moved the mouse outside the active
+ // area, the clicks wouldn't do anything, which would be
+ // confusing
+ valid = false;
+ }
+
+ if (_cursorVisible) {
+ showCursor = SDL_ENABLE;
+ }
}
}
SDL_ShowCursor(showCursor);
- setMousePosition(mouse.x, mouse.y);
- mouse = convertWindowToVirtual(mouse.x, mouse.y);
+ if (valid) {
+ setMousePosition(mouse.x, mouse.y);
+ mouse = convertWindowToVirtual(mouse.x, mouse.y);
+ }
+ return valid;
}
void SdlGraphicsManager::handleResizeImpl(const int width, const int height) {
diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h
index 772bc88637..993a1c3db6 100644
--- a/backends/graphics/sdl/sdl-graphics.h
+++ b/backends/graphics/sdl/sdl-graphics.h
@@ -84,8 +84,10 @@ public:
*
* @param mouse The mouse position in window coordinates, which must be
* converted synchronously to virtual coordinates.
+ * @returns true if the mouse was in a valid position for the game and
+ * should cause the event to be sent to the game.
*/
- virtual void notifyMousePosition(Common::Point &mouse);
+ virtual bool notifyMousePosition(Common::Point &mouse);
virtual bool showMouse(const bool visible) override;
diff --git a/backends/graphics/windowed.h b/backends/graphics/windowed.h
index 52bb96c2cf..1d4958c9d6 100644
--- a/backends/graphics/windowed.h
+++ b/backends/graphics/windowed.h
@@ -39,7 +39,8 @@ public:
_cursorVisible(false),
_cursorX(0),
_cursorY(0),
- _cursorNeedsRedraw(false) {}
+ _cursorNeedsRedraw(false),
+ _cursorLastInActiveArea(true) {}
virtual void showOverlay() override {
if (_overlayVisible)
@@ -304,6 +305,12 @@ protected:
bool _cursorNeedsRedraw;
/**
+ * Whether the last position of the system cursor was within the active area
+ * of the window.
+ */
+ bool _cursorLastInActiveArea;
+
+ /**
* The position of the mouse cursor, in window coordinates.
*/
int _cursorX, _cursorY;