From 96c7f0d22d26e46f40c2c6499f620e2a1e3ecb9b Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Sun, 20 Mar 2011 16:12:09 -0400 Subject: MOHAWK: Implement the Ytram trap --- engines/mohawk/riven.cpp | 46 +++++++++++++++++++++---- engines/mohawk/riven.h | 12 +++++++ engines/mohawk/riven_external.cpp | 72 +++++++++++++++++++++++++++++++++++++-- engines/mohawk/riven_external.h | 1 + 4 files changed, 121 insertions(+), 10 deletions(-) (limited to 'engines') diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index e9742e0bc2..88ea8e7ccd 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -57,9 +57,10 @@ MohawkEngine_Riven::MohawkEngine_Riven(OSystem *syst, const MohawkGameDescriptio _gameOver = false; _activatedSLST = false; _ignoreNextMouseUp = false; - _extrasFile = NULL; + _extrasFile = 0; _curStack = aspit; - _hotspots = NULL; + _hotspots = 0; + removeTimer(); // NOTE: We can never really support CD swapping. All of the music files // (*_Sounds.mhk) are stored on disc 1. They are copied to the hard drive @@ -185,12 +186,13 @@ Common::Error MohawkEngine_Riven::run() { } void MohawkEngine_Riven::handleEvents() { - Common::Event event; - - // Update background videos and the water effect + // Update background running things + checkTimer(); bool needsUpdate = _gfx->runScheduledWaterEffects(); needsUpdate |= _video->updateMovies(); + Common::Event event; + while (_eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_MOUSEMOVE: @@ -376,6 +378,10 @@ void MohawkEngine_Riven::changeToCard(uint16 dest) { } void MohawkEngine_Riven::refreshCard() { + // Clear any timer still floating around, and then install any hardcoded one + removeTimer(); + installCardTimer(); + loadHotspots(_curCard); _gfx->_updatesEnabled = true; @@ -393,10 +399,9 @@ void MohawkEngine_Riven::refreshCard() { if (!_activatedSLST) _sound->playSLST(1, _curCard); - if (_showHotspots) { + if (_showHotspots) for (uint16 i = 0; i < _hotspotCount; i++) _gfx->drawRect(_hotspots[i].rect, _hotspots[i].enabled); - } // Now we need to redraw the cursor if necessary and handle mouse over scripts updateCurrentHotspot(); @@ -744,6 +749,33 @@ Common::String MohawkEngine_Riven::getStackName(uint16 stack) const { return rivenStackNames[stack]; } +void MohawkEngine_Riven::installTimer(TimerProc proc, uint32 time) { + removeTimer(); + _timerProc = proc; + _timerTime = time + getTotalPlayTime(); +} + +void MohawkEngine_Riven::checkTimer() { + if (!_timerProc) + return; + + // NOTE: If the specified timer function is called, it is its job to remove the timer! + if (getTotalPlayTime() >= _timerTime) { + TimerProc proc = _timerProc; + proc(this); + } +} + +void MohawkEngine_Riven::removeTimer() { + _timerProc = 0; + _timerTime = 0; +} + +void MohawkEngine_Riven::installCardTimer() { + // TODO: Handle sunners hardcoded videos + // TODO: Handle Catherine hardcoded videos +} + 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 60a31736d7..6eb02901bb 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -127,6 +127,8 @@ public: Common::Error saveGameState(int slot, const char *desc); bool hasFeature(EngineFeature f) const; + typedef void (*TimerProc)(MohawkEngine_Riven *vm); + private: MohawkArchive *_extrasFile; // We need a separate handle for the extra data RivenConsole *_console; @@ -152,6 +154,10 @@ private: uint32 *_vars; uint32 _varCount; + // Timer + TimerProc _timerProc; + uint32 _timerTime; + // Miscellaneous bool _gameOver; bool _ignoreNextMouseUp; @@ -195,6 +201,12 @@ public: bool _activatedSLST; void runLoadDialog(); void delayAndUpdate(uint32 ms); + + // Timer + void installTimer(TimerProc proc, uint32 time); + void installCardTimer(); + void checkTimer(); + void removeTimer(); }; } // End of namespace Mohawk diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp index 5424a07a3c..e3933243ed 100644 --- a/engines/mohawk/riven_external.cpp +++ b/engines/mohawk/riven_external.cpp @@ -870,12 +870,57 @@ void RivenExternal::xbupdateboiler(uint16 argc, uint16 *argv) { } } +static void ytramTrapTimer(MohawkEngine_Riven *vm) { + // Remove this timer + vm->removeTimer(); + + // Check if we've caught a Ytram + vm->_externalScriptHandler->checkYtramCatch(true); +} + void RivenExternal::xbsettrap(uint16 argc, uint16 *argv) { - // TODO: Set the Ytram trap + // Set the Ytram trap + + // We can catch the Ytram between 10 seconds and 3 minutes from now + uint32 timeUntilCatch = _vm->_rnd->getRandomNumberRng(1000 * 10, 1000 * 60 * 3); + *_vm->getVar("bytramtime") = timeUntilCatch + _vm->getTotalPlayTime(); + + // And set the timer too + _vm->installTimer(&ytramTrapTimer, timeUntilCatch); +} + +void RivenExternal::checkYtramCatch(bool playSound) { + // Check if we've caught a Ytram + + uint32 *ytramTime = _vm->getVar("bytramtime"); + + // If the trap still has not gone off, reinstall our timer + // This is in case you set the trap, walked away, and returned + if (_vm->getTotalPlayTime() < *ytramTime) { + _vm->installTimer(&ytramTrapTimer, *ytramTime - _vm->getTotalPlayTime()); + return; + } + + // Increment the movie per catch (max = 3) + uint32 *ytramMovie = _vm->getVar("bytram"); + *ytramMovie += 1; + if (*ytramMovie > 3) + *ytramMovie = 3; + + // Reset variables + *_vm->getVar("bytrapped") = 1; + *_vm->getVar("bbait") = 0; + *_vm->getVar("bytrap") = 0; + *ytramTime = 0; + + // Play the capture sound, if requested + if (playSound) + _vm->_sound->playSound(33); } void RivenExternal::xbcheckcatch(uint16 argc, uint16 *argv) { - // TODO: Check if we've caught a Ytram + // Just pass our parameter along... + checkYtramCatch(argv[0] != 0); } void RivenExternal::xbait(uint16 argc, uint16 *argv) { @@ -914,7 +959,28 @@ void RivenExternal::xbait(uint16 argc, uint16 *argv) { } void RivenExternal::xbfreeytram(uint16 argc, uint16 *argv) { - // TODO: Play a random Ytram movie + // Play a random Ytram movie after freeing it + uint16 mlstId; + + switch (*_vm->getVar("bytram")) { + case 1: + mlstId = 11; + break; + case 2: + mlstId = 12; + break; + default: + mlstId = _vm->_rnd->getRandomNumberRng(13, 15); + break; + } + + // Activate the MLST and play the video + _vm->_video->activateMLST(mlstId, _vm->getCurCard()); + _vm->_video->playMovieBlockingRiven(11); + + // Now play the second movie + _vm->_video->activateMLST(mlstId + 5, _vm->getCurCard()); + _vm->_video->playMovieBlockingRiven(12); } void RivenExternal::xbaitplate(uint16 argc, uint16 *argv) { diff --git a/engines/mohawk/riven_external.h b/engines/mohawk/riven_external.h index 90fdc664c1..034cd662f6 100644 --- a/engines/mohawk/riven_external.h +++ b/engines/mohawk/riven_external.h @@ -41,6 +41,7 @@ public: uint16 getComboDigit(uint32 correctCombo, uint32 digit); uint32 getDomeSliderState() { return _sliderState; } void setDomeSliderState(uint32 state) { _sliderState = state; } + void checkYtramCatch(bool playSound); private: MohawkEngine_Riven *_vm; -- cgit v1.2.3