diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kevent.cpp | 16 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 4 | ||||
-rw-r--r-- | engines/sci/graphics/cursor.cpp | 35 | ||||
-rw-r--r-- | engines/sci/graphics/cursor.h | 10 |
5 files changed, 64 insertions, 3 deletions
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 29447d99a1..5fb2948a4b 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -44,7 +44,6 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) { int mask = argv[0].toUint16(); reg_t obj = argv[1]; SciEvent curEvent; - int oldx, oldy; int modifier_mask = getSciVersion() <= SCI_VERSION_01 ? SCI_KEYMOD_ALL : SCI_KEYMOD_NO_FOOLOCK; SegManager *segMan = s->_segMan; Common::Point mousePos; @@ -69,13 +68,24 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) { return make_reg(0, 1); } - oldx = mousePos.x; - oldy = mousePos.y; curEvent = g_sci->getEventManager()->getSciEvent(mask); if (g_sci->getVocabulary()) g_sci->getVocabulary()->parser_event = NULL_REG; // Invalidate parser event + if (s->_cursorWorkaroundActive) { + // ffs: GfxCursor::setPosition() + // we check, if actual cursor position is inside given rect + // if that's the case, we switch ourself off. Otherwise + // we simulate the original set position to the scripts + if (s->_cursorWorkaroundRect.contains(mousePos.x, mousePos.y)) { + s->_cursorWorkaroundActive = false; + } else { + mousePos.x = s->_cursorWorkaroundPoint.x; + mousePos.y = s->_cursorWorkaroundPoint.y; + } + } + writeSelectorValue(segMan, obj, SELECTOR(x), mousePos.x); writeSelectorValue(segMan, obj, SELECTOR(y), mousePos.y); diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index bbdab6f7f0..732f075257 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -112,6 +112,8 @@ void EngineState::reset(bool isRestoring) { _chosenQfGImportItem = 0; + _cursorWorkaroundActive = false; + scriptStepCounter = 0; scriptGCInterval = GC_INTERVAL; } diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 42294fa08c..d0ddd5ca06 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -147,6 +147,10 @@ public: uint _chosenQfGImportItem; // Remembers the item selected in QfG import rooms + bool _cursorWorkaroundActive; // ffs. GfxCursor::setPosition() + Common::Point _cursorWorkaroundPoint; + Common::Rect _cursorWorkaroundRect; + public: /* VM Information */ diff --git a/engines/sci/graphics/cursor.cpp b/engines/sci/graphics/cursor.cpp index a906899113..8e69d034c8 100644 --- a/engines/sci/graphics/cursor.cpp +++ b/engines/sci/graphics/cursor.cpp @@ -266,6 +266,16 @@ void GfxCursor::kernelSetMacCursor(GuiResourceId viewNum, int loopNum, int celNu kernelShow(); } +// this list contains all mandatory set cursor changes, that need special handling +// ffs. GfxCursor::setPosition (below) +// Game, newPosition, validRect +static const SciCursorSetPositionWorkarounds setPositionWorkarounds[] = { + { GID_ISLANDBRAIN, 84, 109, 46, 76, 174, 243 }, // island of dr. brain / game menu + { GID_LSL5, 23, 171, 0, 0, 26, 320 }, // larry 5 / skip forward helper + { GID_QFG1VGA, 64, 174, 40, 37, 74, 284 }, // Quest For Glory 1 VGA / run/walk/sleep sub-menu + { (SciGameId)0, -1, -1, -1, -1, -1, -1 } +}; + void GfxCursor::setPosition(Common::Point pos) { // Don't set position, when cursor is not visible. // This fixes eco quest 1 (floppy) right at the start, which is setting @@ -282,6 +292,31 @@ void GfxCursor::setPosition(Common::Point pos) { _screen->adjustToUpscaledCoordinates(pos.y, pos.x); g_system->warpMouse(pos.x, pos.y); } + + // Some games display a new menu, set mouse position somewhere within and + // expect it to be in there. This is fine for a real mouse, but on wii using + // wii-mote or touch interfaces this won't work. In fact on those platforms + // the menus will close immediately because of that behaviour. + // We identify those cases and set a reaction-rect. If the mouse it outside + // of that rect, we won't report the position back to the scripts. + // As soon as the mouse was inside once, we will revert to normal behaviour + // Currently this code is enabled for all platforms, especially because we can't + // differentiate between e.g. Windows used via mouse and Windows used via touchscreen + // The workaround won't hurt real-mouse platforms + const SciGameId gameId = g_sci->getGameId(); + const SciCursorSetPositionWorkarounds *workaround; + workaround = setPositionWorkarounds; + while (workaround->newPositionX != -1) { + if (workaround->gameId == gameId + && ((workaround->newPositionX == pos.x) && (workaround->newPositionY == pos.y))) { + EngineState *s = g_sci->getEngineState(); + s->_cursorWorkaroundActive = true; + s->_cursorWorkaroundPoint = pos; + s->_cursorWorkaroundRect = Common::Rect(workaround->rectLeft, workaround->rectTop, workaround->rectRight, workaround->rectBottom); + return; + } + workaround++; + } } Common::Point GfxCursor::getPosition() { diff --git a/engines/sci/graphics/cursor.h b/engines/sci/graphics/cursor.h index 787841f5be..10cd5d8a85 100644 --- a/engines/sci/graphics/cursor.h +++ b/engines/sci/graphics/cursor.h @@ -40,6 +40,16 @@ class GfxPalette; typedef Common::HashMap<int, GfxView *> CursorCache; +struct SciCursorSetPositionWorkarounds { + SciGameId gameId; + int16 newPositionY; + int16 newPositionX; + int16 rectTop; + int16 rectLeft; + int16 rectBottom; + int16 rectRight; +}; + class GfxCursor { public: GfxCursor(ResourceManager *resMan, GfxPalette *palette, GfxScreen *screen); |