diff options
-rw-r--r-- | engines/mohawk/riven.cpp | 38 | ||||
-rw-r--r-- | engines/mohawk/riven.h | 3 | ||||
-rw-r--r-- | engines/mohawk/riven_card.cpp | 89 | ||||
-rw-r--r-- | engines/mohawk/riven_card.h | 25 | ||||
-rw-r--r-- | engines/mohawk/riven_external.cpp | 4 | ||||
-rw-r--r-- | engines/mohawk/riven_scripts.cpp | 12 | ||||
-rw-r--r-- | engines/mohawk/riven_scripts.h | 3 |
7 files changed, 130 insertions, 44 deletions
diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 4d30755a32..f31f12de0e 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -68,7 +68,6 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio _saveLoad = nullptr; _optionsDialog = nullptr; _card = nullptr; - _curHotspot = nullptr; removeTimer(); // NOTE: We can never really support CD swapping. All of the music files @@ -212,7 +211,7 @@ void MohawkEngine_Riven::handleEvents() { while (_eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_MOUSEMOVE: - checkHotspotChange(); + _card->onMouseMove(event.mouse); if (!(getFeatures() & GF_DEMO)) { // Check to show the inventory, but it is always "showing" in the demo @@ -225,19 +224,17 @@ void MohawkEngine_Riven::handleEvents() { needsUpdate = true; break; case Common::EVENT_LBUTTONDOWN: - if (_curHotspot) { + if (_card->getCurHotspot()) { checkSunnerAlertClick(); - _curHotspot->runScript(kMouseDownScript); } + _card->onMouseDown(_eventMan->getMousePos()); break; case Common::EVENT_LBUTTONUP: // See RivenScript::switchCard() for more information on why we sometimes // disable the next up event. if (!_ignoreNextMouseUp) { - if (_curHotspot) - _curHotspot->runScript(kMouseUpScript); - else - checkInventoryClick(); + _card->onMouseUp(_eventMan->getMousePos()); + checkInventoryClick(); } _ignoreNextMouseUp = false; break; @@ -291,8 +288,7 @@ void MohawkEngine_Riven::handleEvents() { } } - if (_curHotspot) - _curHotspot->runScript(kMouseInsideScript); + _card->onMouseUpdate(); // Update the screen if we need to if (needsUpdate) @@ -425,26 +421,8 @@ void MohawkEngine_Riven::refreshCard() { installCardTimer(); } -void MohawkEngine_Riven::checkHotspotChange() { - Common::Point mousePos = _eventMan->getMousePos(); - RivenHotspot *hotspot = _card->getHotspotContainingPoint(mousePos); - - if (hotspot) { - if (_curHotspot != hotspot) { - _curHotspot = hotspot; - _cursor->setCursor(hotspot->getMouseCursor()); - _system->updateScreen(); - } - } else { - _curHotspot = nullptr; - _cursor->setCursor(kRivenMainCursor); - _system->updateScreen(); - } -} - void MohawkEngine_Riven::updateCurrentHotspot() { - _curHotspot = nullptr; - checkHotspotChange(); + _card->onMouseMove(_eventMan->getMousePos()); } void MohawkEngine_Riven::checkInventoryClick() { @@ -848,7 +826,7 @@ void MohawkEngine_Riven::checkSunnerAlertClick() { return; // Only set the sunners variable on the forward hotspot - if (_curHotspot->getBlstId() != 3) + if (_card->getCurHotspot()->getBlstId() != 3) return; // If the alert video is no longer playing, we have nothing left to do diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index 53789af3d7..1c8f3f1509 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -145,7 +145,6 @@ private: // Hotspot related functions and variables void checkInventoryClick(); bool _showHotspots; - void checkHotspotChange(); // Variables void initVars(); @@ -173,9 +172,7 @@ public: uint32 getCurCardRMAP(); // Hotspot functions/variables - RivenHotspot *_curHotspot; Common::Array<ZipMode> _zipModeData; - RivenHotspot *getCurHotspot() const { return _curHotspot; } void updateCurrentHotspot(); void addZipVisitedCard(uint16 cardId, uint16 cardNameId); bool isZipVisitedCard(const Common::String &hotspotName) const; diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp index cdf9cf1a3e..15271b71c0 100644 --- a/engines/mohawk/riven_card.cpp +++ b/engines/mohawk/riven_card.cpp @@ -22,6 +22,7 @@ #include "mohawk/riven_card.h" +#include "mohawk/cursors.h" #include "mohawk/riven_graphics.h" #include "mohawk/resource.h" @@ -31,7 +32,9 @@ namespace Mohawk { RivenCard::RivenCard(MohawkEngine_Riven *vm, uint16 id) : _vm(vm), - _id(id) { + _id(id), + _hoveredHotspot(nullptr), + _pressedHotspot(nullptr) { loadCardResource(id); loadHotspots(id); loadCardPictureList(id); @@ -326,6 +329,82 @@ void RivenCard::activateWaterEffect(uint16 index) { } } +RivenHotspot *RivenCard::getCurHotspot() const { + return _hoveredHotspot; +} + +void RivenCard::onMouseDown(const Common::Point &mouse) { + onMouseMove(mouse); + + _pressedHotspot = _hoveredHotspot; + if (_pressedHotspot) { + RivenScriptPtr script = _pressedHotspot->getScript(kMouseDownScript); + _vm->_scriptMan->runScript(script, false); + } +} + +void RivenCard::onMouseUp(const Common::Point &mouse) { + onMouseMove(mouse); + + if (_pressedHotspot && _pressedHotspot == _hoveredHotspot) { + RivenScriptPtr script = _pressedHotspot->getScript(kMouseUpScript); + _vm->_scriptMan->runScript(script, false); + } + + _pressedHotspot = nullptr; +} + +void RivenCard::onMouseMove(const Common::Point &mouse) { + RivenHotspot *hotspot = getHotspotContainingPoint(mouse); + + if (hotspot) { + if (hotspot != _hoveredHotspot) { + if (_hoveredHotspot) { + RivenScriptPtr script = _hoveredHotspot->getScript(kMouseLeaveScript); + _vm->_scriptMan->runScript(script, false); + } + + _hoveredHotspot = hotspot; + RivenScriptPtr script = _hoveredHotspot->getScript(kMouseEnterScript); + _vm->_scriptMan->runScript(script, false); + } + } else { + _hoveredHotspot = nullptr; + } +} + +void RivenCard::onMouseDragUpdate() { + if (_pressedHotspot) { + RivenScriptPtr script = _pressedHotspot->getScript(kMouseDragScript); + _vm->_scriptMan->runScript(script, false); + } +} + +void RivenCard::onMouseUpdate() { + RivenScriptPtr script; + if (_hoveredHotspot) { + script = _hoveredHotspot->getScript(kMouseInsideScript); + } + + if (script && !script->empty()) { + _vm->_scriptMan->runScript(script, false); + } else { + updateMouseCursor(); + } +} + +void RivenCard::updateMouseCursor() { + uint16 cursor; + if (_hoveredHotspot) { + cursor = _hoveredHotspot->getMouseCursor(); + } else { + cursor = kRivenMainCursor; + } + + _vm->_cursor->setCursor(cursor); + _vm->_system->updateScreen(); +} + RivenHotspot::RivenHotspot(MohawkEngine_Riven *vm, Common::ReadStream *stream) : _vm(vm) { loadFromStream(stream); @@ -363,13 +442,13 @@ void RivenHotspot::loadFromStream(Common::ReadStream *stream) { _scripts = _vm->_scriptMan->readScripts(stream); } -void RivenHotspot::runScript(uint16 scriptType) { +RivenScriptPtr RivenHotspot::getScript(uint16 scriptType) const { for (uint16 i = 0; i < _scripts.size(); i++) if (_scripts[i].type == scriptType) { - RivenScriptPtr script = _scripts[i].script; - _vm->_scriptMan->runScript(script, false); - break; + return _scripts[i].script; } + + return RivenScriptPtr(); } bool RivenHotspot::isEnabled() const { diff --git a/engines/mohawk/riven_card.h b/engines/mohawk/riven_card.h index 007a26d7b6..98e65ae5ff 100644 --- a/engines/mohawk/riven_card.h +++ b/engines/mohawk/riven_card.h @@ -91,6 +91,8 @@ public: /** Get the hotspot with the specified BLST id */ RivenHotspot *getHotspotByBlstId(const uint16 blstId) const; + RivenHotspot *getCurHotspot() const; + /** Get all the hotspots in the card. To be used for debugging features only */ Common::Array<RivenHotspot *> getHotspots() const; @@ -100,6 +102,21 @@ public: /** Activate a water effect list entry */ void activateWaterEffect(uint16 index); + /** Handle a mouse down event */ + void onMouseDown(const Common::Point &mouse); + + /** Handle a mouse up event */ + void onMouseUp(const Common::Point &mouse); + + /** Handle a mouse move event */ + void onMouseMove(const Common::Point &mouse); + + /** Frame update handler for the mouse cursor */ + void onMouseUpdate(); + + /** Frame update handler for mouse dragging */ + void onMouseDragUpdate(); + private: void loadCardResource(uint16 id); void loadHotspots(uint16 id); @@ -131,12 +148,16 @@ private: RivenScriptList _scripts; Common::Array<RivenHotspot *> _hotspots; + RivenHotspot *_hoveredHotspot; + RivenHotspot *_pressedHotspot; // Resource lists Common::Array<Picture> _pictureList; Common::Array<SLSTRecord> _soundList; Common::Array<HotspotEnableRecord> _hotspotEnableList; Common::Array<WaterEffectRecord> _waterEffectList; + + void updateMouseCursor(); }; /** @@ -149,8 +170,8 @@ class RivenHotspot { public: RivenHotspot(MohawkEngine_Riven *vm, Common::ReadStream *stream); - /** Run one of the hotspot's scripts */ - void runScript(uint16 scriptType); + /** Get the one of the hotspot's scripts */ + RivenScriptPtr getScript(uint16 scriptType) const; /** Enable or disable the hotspot */ void enable(bool e); diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp index 1be119dc79..6740f13007 100644 --- a/engines/mohawk/riven_external.cpp +++ b/engines/mohawk/riven_external.cpp @@ -1368,7 +1368,7 @@ void RivenExternal::xgrviewer(uint16 argc, uint16 *argv) { } // Calculate how much we're moving - Common::String buttonName = _vm->_curHotspot->getName(); + Common::String buttonName = _vm->getCurCard()->getCurHotspot()->getName(); uint32 buttonPos = buttonName.lastChar() - '0'; uint32 &curPos = _vm->_vars["grviewpos"]; @@ -1439,7 +1439,7 @@ void RivenExternal::xglviewer(uint16 argc, uint16 *argv) { // (It shows the village from the middle of the lake) // Calculate how much we're moving - Common::String buttonName = _vm->_curHotspot->getName(); + Common::String buttonName = _vm->getCurCard()->getCurHotspot()->getName(); uint32 buttonPos = buttonName.lastChar() - '0'; uint32 &curPos = _vm->_vars["glviewpos"]; diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp index e951043aa5..6a86a98c82 100644 --- a/engines/mohawk/riven_scripts.cpp +++ b/engines/mohawk/riven_scripts.cpp @@ -114,6 +114,10 @@ void RivenScriptManager::clearStoredMovieOpcode() { } void RivenScriptManager::runScript(const RivenScriptPtr &script, bool queue) { + if (!script || script->empty()) { + return; + } + if (!queue) { script->run(); } else { @@ -179,6 +183,10 @@ void RivenScript::addCommand(RivenCommand *command) { _commands.push_back(command); } +bool RivenScript::empty() const { + return _commands.empty(); +} + RivenCommand::RivenCommand(MohawkEngine_Riven *vm) : _vm(vm) { @@ -601,10 +609,10 @@ void RivenSimpleCommand::activateFLST(uint16 op, uint16 argc, uint16 *argv) { // Command 45: do zip mode void RivenSimpleCommand::zipMode(uint16 op, uint16 argc, uint16 *argv) { - assert(_vm->getCurHotspot()); + assert(_vm->getCurCard() && _vm->getCurCard()->getCurHotspot()); // Check the ZIPS records to see if we have a match to the hotspot name - Common::String hotspotName = _vm->getCurHotspot()->getName(); + Common::String hotspotName = _vm->getCurCard()->getCurHotspot()->getName(); for (uint16 i = 0; i < _vm->_zipModeData.size(); i++) if (_vm->_zipModeData[i].name == hotspotName) { diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h index 8710026143..05cbd15f40 100644 --- a/engines/mohawk/riven_scripts.h +++ b/engines/mohawk/riven_scripts.h @@ -70,6 +70,9 @@ public: /** Append a command to the script */ void addCommand(RivenCommand *command); + /** True if the script does not contain any command */ + bool empty() const; + /** * Run the script * |