From f0267d542f860a2f67f519a1dc5343e020927c81 Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Sat, 4 Feb 2017 14:34:45 +0100 Subject: MOHAWK: Keep turning pages while the mouse is pressed in Atrus' book --- engines/mohawk/riven.cpp | 26 ++++++++++- engines/mohawk/riven.h | 6 +-- engines/mohawk/riven_card.cpp | 4 +- engines/mohawk/riven_inventory.cpp | 2 +- engines/mohawk/riven_scripts.cpp | 22 +++++++++- engines/mohawk/riven_scripts.h | 9 +++- engines/mohawk/riven_stack.cpp | 10 +++-- engines/mohawk/riven_stack.h | 2 + engines/mohawk/riven_stacks/aspit.cpp | 83 +++++++++++++++++++++++++---------- engines/mohawk/riven_stacks/aspit.h | 3 ++ 10 files changed, 129 insertions(+), 38 deletions(-) diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 116b1e8688..1c40acd135 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -185,12 +185,12 @@ Common::Error MohawkEngine_Riven::run() { while (!shouldQuit()) - handleEvents(); + doFrame(); return Common::kNoError; } -void MohawkEngine_Riven::handleEvents() { +void MohawkEngine_Riven::doFrame() { // Update background running things checkTimer(); _sound->updateSLST(); @@ -277,6 +277,12 @@ void MohawkEngine_Riven::handleEvents() { _card->onMouseUpdate(); + if (!_scriptMan->runningQueuedScripts()) { + // Don't run queued scripts if we are calling from a queued script + // otherwise infinite looping will happen. + _scriptMan->runQueuedScripts(); + } + // Update the screen if we need to if (needsUpdate) _system->updateScreen(); @@ -553,6 +559,22 @@ bool MohawkEngine_Riven::isZipVisitedCard(const Common::String &hotspotName) con return foundMatch; } +bool MohawkEngine_Riven::canLoadGameStateCurrently() { + return !(getFeatures() & GF_DEMO); +} + +bool MohawkEngine_Riven::canSaveGameStateCurrently() { + if (getFeatures() & GF_DEMO) { + return false; + } + + if (_scriptMan->hasQueuedScripts()) { + return false; + } + + return true; +} + bool ZipMode::operator== (const ZipMode &z) const { return z.name == name && z.id == id; } diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index d44a340dc6..0dfba152bc 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -98,8 +98,8 @@ public: GUI::Debugger *getDebugger(); - bool canLoadGameStateCurrently() { return !(getFeatures() & GF_DEMO); } - bool canSaveGameStateCurrently() { return !(getFeatures() & GF_DEMO); } + bool canLoadGameStateCurrently(); + bool canSaveGameStateCurrently(); Common::Error loadGameState(int slot); Common::Error saveGameState(int slot, const Common::String &desc); bool hasFeature(EngineFeature f) const; @@ -110,6 +110,7 @@ public: new Common::Functor0Mem(this, &cls::method) void doVideoTimer(VideoHandle handle, bool force); + void doFrame(); private: MohawkArchive *_extrasFile; // We need a separate handle for the extra data @@ -121,7 +122,6 @@ private: // Stack/Card-related functions and variables RivenCard *_card; RivenStack *_stack; - void handleEvents(); // Hotspot related functions and variables bool _showHotspots; diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp index 93f194c610..09c72d5258 100644 --- a/engines/mohawk/riven_card.cpp +++ b/engines/mohawk/riven_card.cpp @@ -396,7 +396,7 @@ RivenScriptPtr RivenCard::onMouseMove(const Common::Point &mouse) { void RivenCard::onMouseDragUpdate() { if (_pressedHotspot) { RivenScriptPtr script = _pressedHotspot->getScript(kMouseDragScript); - _vm->_scriptMan->runScript(script, false); + _vm->_scriptMan->runScript(script, true); } } @@ -407,7 +407,7 @@ void RivenCard::onMouseUpdate() { } if (!script->empty()) { - _vm->_scriptMan->runScript(script, false); + _vm->_scriptMan->runScript(script, true); } else { updateMouseCursor(); } diff --git a/engines/mohawk/riven_inventory.cpp b/engines/mohawk/riven_inventory.cpp index 11a42f0ea5..f4f3df0721 100644 --- a/engines/mohawk/riven_inventory.cpp +++ b/engines/mohawk/riven_inventory.cpp @@ -196,7 +196,7 @@ void RivenInventory::backFromItemScript() const { // Return to where we were before entering the book RivenCommand *back = new RivenStackChangeCommand(_vm, backStackId, backCardId, true); RivenScriptPtr backScript = _vm->_scriptMan->createScriptWithCommand(back); - _vm->_scriptMan->runScript(backScript, false); + _vm->_scriptMan->runScript(backScript, true); } } // End of namespace Mohawk diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp index 27f0022446..7b95abb077 100644 --- a/engines/mohawk/riven_scripts.cpp +++ b/engines/mohawk/riven_scripts.cpp @@ -41,8 +41,10 @@ static void printTabs(byte tabs) { debugN("\t"); } -RivenScriptManager::RivenScriptManager(MohawkEngine_Riven *vm) { - _vm = vm; +RivenScriptManager::RivenScriptManager(MohawkEngine_Riven *vm) : + _vm(vm), + _runningQueuedScripts(false) { + _storedMovieOpcode.time = 0; _storedMovieOpcode.id = 0; } @@ -129,6 +131,18 @@ bool RivenScriptManager::hasQueuedScripts() const { return !_queue.empty(); } +void RivenScriptManager::runQueuedScripts() { + _runningQueuedScripts = true; + + for (uint i = 0; i < _queue.size(); i++) { + _queue[i]->run(); + } + + _queue.clear(); + + _runningQueuedScripts = false; +} + RivenScriptPtr RivenScriptManager::createScriptFromData(uint16 commandCount, ...) { va_list args; va_start(args, commandCount); @@ -169,6 +183,10 @@ RivenScriptPtr RivenScriptManager::createScriptWithCommand(RivenCommand *command return script; } +bool RivenScriptManager::runningQueuedScripts() const { + return _runningQueuedScripts; +} + RivenScript::RivenScript() { _continueRunning = true; } diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h index 7eb8674586..1a990c451b 100644 --- a/engines/mohawk/riven_scripts.h +++ b/engines/mohawk/riven_scripts.h @@ -118,7 +118,7 @@ typedef Common::Array RivenScriptList; * Script manager * * Reads scripts from raw data. - * Can run scripts immediatly, or store them for future execution. + * Can run scripts immediately, or store them for future execution. */ class RivenScriptManager { public: @@ -147,6 +147,11 @@ public: /** Are scripts running in the background */ bool hasQueuedScripts() const; + /** Run queued scripts */ + void runQueuedScripts(); + + bool runningQueuedScripts() const; + void stopAllScripts(); struct StoredMovieOpcode { @@ -165,6 +170,8 @@ private: MohawkEngine_Riven *_vm; Common::Array _queue; + bool _runningQueuedScripts; + StoredMovieOpcode _storedMovieOpcode; RivenCommandPtr readCommand(Common::ReadStream *stream); diff --git a/engines/mohawk/riven_stack.cpp b/engines/mohawk/riven_stack.cpp index 6fa1b15ad5..d842bca415 100644 --- a/engines/mohawk/riven_stack.cpp +++ b/engines/mohawk/riven_stack.cpp @@ -234,7 +234,7 @@ void RivenStack::onMouseDown(const Common::Point &mouse) { RivenScriptPtr script = _vm->getCard()->onMouseDown(mouse); if (!script->empty()) { - _vm->_scriptMan->runScript(script, false); + _vm->_scriptMan->runScript(script, true); } } } @@ -247,7 +247,7 @@ void RivenStack::onMouseUp(const Common::Point &mouse) { RivenScriptPtr script = _vm->getCard()->onMouseUp(mouse); if (!script->empty()) { - _vm->_scriptMan->runScript(script, false); + _vm->_scriptMan->runScript(script, true); } } } @@ -259,11 +259,15 @@ void RivenStack::onMouseMove(const Common::Point &mouse) { RivenScriptPtr script = _vm->getCard()->onMouseMove(mouse); if (!script->empty()) { - _vm->_scriptMan->runScript(script, false); + _vm->_scriptMan->runScript(script, true); } } } +bool RivenStack::mouseIsDown() const { + return _mouseIsDown; +} + RivenNameList::RivenNameList() { } diff --git a/engines/mohawk/riven_stack.h b/engines/mohawk/riven_stack.h index b08052e4e8..d30702eb73 100644 --- a/engines/mohawk/riven_stack.h +++ b/engines/mohawk/riven_stack.h @@ -120,6 +120,8 @@ public: /** Handle a mouse move event */ void onMouseMove(const Common::Point &mouse); + bool mouseIsDown() const; + // Common external commands void xflies(uint16 argc, uint16 *argv); // Start the "flies" effect diff --git a/engines/mohawk/riven_stacks/aspit.cpp b/engines/mohawk/riven_stacks/aspit.cpp index aabd7dba91..f930dfc8cf 100644 --- a/engines/mohawk/riven_stacks/aspit.cpp +++ b/engines/mohawk/riven_stacks/aspit.cpp @@ -99,44 +99,79 @@ void ASpit::xaatrusbookback(uint16 argc, uint16 *argv) { _vm->_inventory->backFromItemScript(); } -void ASpit::xaatrusbookprevpage(uint16 argc, uint16 *argv) { - // Get the page variable - uint32 &page = _vm->_vars["aatruspage"]; +bool ASpit::pageTurn(int16 transition) { + // Wait until the previous page turn sound completes + while (_vm->_sound->isEffectPlaying() && !_vm->shouldQuit()) { + if (!mouseIsDown()) { + return false; + } - // Decrement the page if it's not the first page - if (page == 1) - return; - page--; + _vm->doFrame(); + } // Play the page turning sound - if (_vm->getFeatures() & GF_DEMO) - _vm->_sound->playSound(4); + const char *soundName = nullptr; + if (_vm->_rnd->getRandomBit()) + soundName = "aPage1"; else - _vm->_sound->playSound(3); + soundName = "aPage2"; + + Common::String fullSoundName = Common::String::format("%d_%s_1", _vm->getCard()->getId(), soundName); + + _vm->_sound->playSound(fullSoundName, 51, true); // Now update the screen :) - _vm->_gfx->scheduleTransition(1); - _vm->getCard()->drawPicture(page); + _vm->_gfx->scheduleTransition(transition); + + return true; +} + +void ASpit::xaatrusbookprevpage(uint16 argc, uint16 *argv) { + // Get the page variable + uint32 &page = _vm->_vars["aatruspage"]; + + // Keep turning pages while the mouse is pressed + bool firstPageTurn = true; + while (mouseIsDown() || firstPageTurn) { + // Check for the first page + if (page == 1) + return; + + if (!pageTurn(1)) { + return; + } + + // Update the page number + page--; + firstPageTurn = false; + + _vm->getCard()->drawPicture(page); + _vm->doFrame(); + } } void ASpit::xaatrusbooknextpage(uint16 argc, uint16 *argv) { // Get the page variable uint32 &page = _vm->_vars["aatruspage"]; - // Increment the page if it's not the last page - if (((_vm->getFeatures() & GF_DEMO) && page == 6) || page == 10) - return; - page++; + // Keep turning pages while the mouse is pressed + bool firstPageTurn = true; + while ((mouseIsDown() || firstPageTurn) && !_vm->shouldQuit()) { + // Check for the last page + if (((_vm->getFeatures() & GF_DEMO) && page == 6) || page == 10) + return; - // Play the page turning sound - if (_vm->getFeatures() & GF_DEMO) - _vm->_sound->playSound(5); - else - _vm->_sound->playSound(4); + if (!pageTurn(0)) { + return; + } - // Now update the screen :) - _vm->_gfx->scheduleTransition(0); - _vm->getCard()->drawPicture(page); + // Update the page number + page++; + firstPageTurn = false; + + _vm->getCard()->drawPicture(page); + _vm->doFrame(); + } } void ASpit::xacathopenbook(uint16 argc, uint16 *argv) { diff --git a/engines/mohawk/riven_stacks/aspit.h b/engines/mohawk/riven_stacks/aspit.h index 60400dd5f6..d64214d91f 100644 --- a/engines/mohawk/riven_stacks/aspit.h +++ b/engines/mohawk/riven_stacks/aspit.h @@ -67,6 +67,9 @@ public: void xaenablemenuintro(uint16 argc, uint16 *argv); void xademoquit(uint16 argc, uint16 *argv); void xaexittomain(uint16 argc, uint16 *argv); + +private: + bool pageTurn(int16 transition); }; } // End of namespace RivenStacks -- cgit v1.2.3