From 22926a1835079f31fa778f2f2eb4e645c451457a Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Sat, 5 Nov 2016 14:47:02 +0100 Subject: MOHAWK: Move the timer callbacks to the stacks --- engines/mohawk/riven.cpp | 203 +--------------------------------- engines/mohawk/riven.h | 10 +- engines/mohawk/riven_stack.cpp | 4 + engines/mohawk/riven_stack.h | 3 + engines/mohawk/riven_stacks/bspit.cpp | 17 +-- engines/mohawk/riven_stacks/bspit.h | 1 + engines/mohawk/riven_stacks/gspit.cpp | 18 +-- engines/mohawk/riven_stacks/gspit.h | 3 + engines/mohawk/riven_stacks/jspit.cpp | 151 +++++++++++++++++++++++++ engines/mohawk/riven_stacks/jspit.h | 9 ++ engines/mohawk/riven_stacks/pspit.cpp | 51 +++++++++ engines/mohawk/riven_stacks/pspit.h | 5 + engines/mohawk/riven_stacks/rspit.cpp | 18 +-- engines/mohawk/riven_stacks/rspit.h | 2 + 14 files changed, 263 insertions(+), 232 deletions(-) (limited to 'engines') diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 1b69e35d78..7951d0f487 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -434,7 +434,7 @@ void MohawkEngine_Riven::refreshCard() { updateCurrentHotspot(); // Finally, install any hardcoded timer - installCardTimer(); + _stack->installCardTimer(); } void MohawkEngine_Riven::updateCurrentHotspot() { @@ -554,9 +554,9 @@ Common::Error MohawkEngine_Riven::saveGameState(int slot, const Common::String & return _saveLoad->saveGame(slot, desc); } -void MohawkEngine_Riven::installTimer(TimerProc proc, uint32 time) { +void MohawkEngine_Riven::installTimer(TimerProc *proc, uint32 time) { removeTimer(); - _timerProc = proc; + _timerProc = Common::SharedPtr(proc); _timerTime = time + getTotalPlayTime(); } @@ -566,208 +566,15 @@ void MohawkEngine_Riven::checkTimer() { // NOTE: If the specified timer function is called, it is its job to remove the timer! if (getTotalPlayTime() >= _timerTime) { - TimerProc proc = _timerProc; - proc(this); + (*_timerProc)(); } } void MohawkEngine_Riven::removeTimer() { - _timerProc = 0; + _timerProc.reset(); _timerTime = 0; } -static void catherineIdleTimer(MohawkEngine_Riven *vm) { - uint32 &cathCheck = vm->_vars["pcathcheck"]; - uint32 &cathState = vm->_vars["acathstate"]; - uint16 movie; - - // Choose a random movie based on where Catherine is - if (cathCheck == 0) { - static const int movieList[] = { 5, 6, 7, 8 }; - cathCheck = 1; - movie = movieList[vm->_rnd->getRandomNumber(3)]; - } else if (cathState == 1) { - static const int movieList[] = { 11, 14 }; - movie = movieList[vm->_rnd->getRandomBit()]; - } else { - static const int movieList[] = { 9, 10, 12, 13 }; - movie = movieList[vm->_rnd->getRandomNumber(3)]; - } - - // Update her state if she moves from left/right or right/left, resp. - if (movie == 5 || movie == 7 || movie == 11 || movie == 14) - cathState = 2; - else - cathState = 1; - - // Play the movie, blocking - vm->_video->activateMLST(vm->getCard()->getMovie(movie)); - vm->_cursor->hideCursor(); - vm->_video->playMovieBlockingRiven(movie); - vm->_cursor->showCursor(); - vm->_system->updateScreen(); - - // Install the next timer for the next video - uint32 timeUntilNextMovie = vm->_rnd->getRandomNumber(120) * 1000; - - vm->_vars["pcathtime"] = timeUntilNextMovie + vm->getTotalPlayTime(); - - vm->installTimer(&catherineIdleTimer, timeUntilNextMovie); -} - -static void sunnersTopStairsTimer(MohawkEngine_Riven *vm) { - // If the sunners are gone, we have no video to play - if (vm->_vars["jsunners"] != 0) { - vm->removeTimer(); - return; - } - - // Play a random sunners video if the script one is not playing already - // and then set a new timer for when the new video should be played - - VideoEntryPtr oldVideo = vm->_video->findVideoRiven(1); - uint32 timerTime = 500; - - if (!oldVideo || oldVideo->endOfVideo()) { - uint32 &sunnerTime = vm->_vars["jsunnertime"]; - - if (sunnerTime == 0) { - timerTime = vm->_rnd->getRandomNumberRng(2, 15) * 1000; - } else if (sunnerTime < vm->getTotalPlayTime()) { - VideoEntryPtr video = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(1, 3)); - - timerTime = video->getDuration().msecs() + vm->_rnd->getRandomNumberRng(2, 15) * 1000; - } - - sunnerTime = timerTime + vm->getTotalPlayTime(); - } - - vm->installTimer(&sunnersTopStairsTimer, timerTime); -} - -static void sunnersMidStairsTimer(MohawkEngine_Riven *vm) { - // If the sunners are gone, we have no video to play - if (vm->_vars["jsunners"] != 0) { - vm->removeTimer(); - return; - } - - // Play a random sunners video if the script one is not playing already - // and then set a new timer for when the new video should be played - - VideoEntryPtr oldVideo = vm->_video->findVideoRiven(1); - uint32 timerTime = 500; - - if (!oldVideo || oldVideo->endOfVideo()) { - uint32 &sunnerTime = vm->_vars["jsunnertime"]; - - if (sunnerTime == 0) { - timerTime = vm->_rnd->getRandomNumberRng(1, 10) * 1000; - } else if (sunnerTime < vm->getTotalPlayTime()) { - // Randomize the video - int randValue = vm->_rnd->getRandomNumber(5); - uint16 movie = 4; - if (randValue == 4) - movie = 2; - else if (randValue == 5) - movie = 3; - - VideoEntryPtr video = vm->_video->playMovieRiven(movie); - - timerTime = video->getDuration().msecs() + vm->_rnd->getRandomNumberRng(1, 10) * 1000; - } - - sunnerTime = timerTime + vm->getTotalPlayTime(); - } - - vm->installTimer(&sunnersMidStairsTimer, timerTime); -} - -static void sunnersLowerStairsTimer(MohawkEngine_Riven *vm) { - // If the sunners are gone, we have no video to play - if (vm->_vars["jsunners"] != 0) { - vm->removeTimer(); - return; - } - - // Play a random sunners video if the script one is not playing already - // and then set a new timer for when the new video should be played - - VideoEntryPtr oldVideo = vm->_video->findVideoRiven(1); - uint32 timerTime = 500; - - if (!oldVideo || oldVideo->endOfVideo()) { - uint32 &sunnerTime = vm->_vars["jsunnertime"]; - - if (sunnerTime == 0) { - timerTime = vm->_rnd->getRandomNumberRng(1, 30) * 1000; - } else if (sunnerTime < vm->getTotalPlayTime()) { - VideoEntryPtr video = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(3, 5)); - - timerTime = video->getDuration().msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000; - } - - sunnerTime = timerTime + vm->getTotalPlayTime(); - } - - vm->installTimer(&sunnersLowerStairsTimer, timerTime); -} - -static void sunnersBeachTimer(MohawkEngine_Riven *vm) { - // If the sunners are gone, we have no video to play - if (vm->_vars["jsunners"] != 0) { - vm->removeTimer(); - return; - } - - // Play a random sunners video if the script one is not playing already - // and then set a new timer for when the new video should be played - - VideoEntryPtr oldvideo = vm->_video->findVideoRiven(3); - uint32 timerTime = 500; - - if (!oldvideo || oldvideo->endOfVideo()) { - uint32 &sunnerTime = vm->_vars["jsunnertime"]; - - if (sunnerTime == 0) { - timerTime = vm->_rnd->getRandomNumberRng(1, 30) * 1000; - } else if (sunnerTime < vm->getTotalPlayTime()) { - // Unlike the other cards' scripts which automatically - // activate the MLST, we have to set it manually here. - uint16 mlstID = vm->_rnd->getRandomNumberRng(3, 8); - vm->_video->activateMLST(vm->getCard()->getMovie(mlstID)); - VideoEntryPtr video = vm->_video->playMovieRiven(mlstID); - - timerTime = video->getDuration().msecs() + vm->_rnd->getRandomNumberRng(1, 30) * 1000; - } - - sunnerTime = timerTime + vm->getTotalPlayTime(); - } - - vm->installTimer(&sunnersBeachTimer, timerTime); -} - -void MohawkEngine_Riven::installCardTimer() { - switch (_stack->getCurrentCardGlobalId()) { - case 0x3a85: // Top of elevator on prison island - // Handle Catherine hardcoded videos - installTimer(&catherineIdleTimer, _rnd->getRandomNumberRng(1, 33) * 1000); - break; - case 0x77d6: // Sunners, top of stairs - installTimer(&sunnersTopStairsTimer, 500); - break; - case 0x79bd: // Sunners, middle of stairs - installTimer(&sunnersMidStairsTimer, 500); - break; - case 0x7beb: // Sunners, bottom of stairs - installTimer(&sunnersLowerStairsTimer, 500); - break; - case 0xb6ca: // Sunners, shoreline - installTimer(&sunnersBeachTimer, 500); - break; - } -} - void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) { assert(handle); diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index 131d28548c..73245e983e 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -107,7 +107,10 @@ public: Common::Error saveGameState(int slot, const Common::String &desc); bool hasFeature(EngineFeature f) const; - typedef void (*TimerProc)(MohawkEngine_Riven *vm); + typedef Common::Functor0 TimerProc; + +#define TIMER(cls, method) \ + new Common::Functor0Mem(this, &cls::method) void doVideoTimer(VideoHandle handle, bool force); @@ -131,7 +134,7 @@ private: void initVars(); // Timer - TimerProc _timerProc; + Common::SharedPtr _timerProc; uint32 _timerTime; // Miscellaneous @@ -165,8 +168,7 @@ public: void delayAndUpdate(uint32 ms); // Timer - void installTimer(TimerProc proc, uint32 time); - void installCardTimer(); + void installTimer(TimerProc *proc, uint32 time); void checkTimer(); void removeTimer(); diff --git a/engines/mohawk/riven_stack.cpp b/engines/mohawk/riven_stack.cpp index ab79b788f4..c375097d7f 100644 --- a/engines/mohawk/riven_stack.cpp +++ b/engines/mohawk/riven_stack.cpp @@ -219,6 +219,10 @@ void RivenStack::runCredits(uint16 video, uint32 delay) { _vm->setGameOver(); } +void RivenStack::installCardTimer() { + +} + RivenNameList::RivenNameList() { } diff --git a/engines/mohawk/riven_stack.h b/engines/mohawk/riven_stack.h index d8098f7ab0..e1e5455c3b 100644 --- a/engines/mohawk/riven_stack.h +++ b/engines/mohawk/riven_stack.h @@ -107,6 +107,9 @@ public: /** Write all of the stack's data including its cards to standard output */ void dump() const; + /** Install a timer for the current card if one is defined */ + virtual void installCardTimer(); + // Common external commands void xflies(uint16 argc, uint16 *argv); // Start the "flies" effect diff --git a/engines/mohawk/riven_stacks/bspit.cpp b/engines/mohawk/riven_stacks/bspit.cpp index f94098a398..acc24f24be 100644 --- a/engines/mohawk/riven_stacks/bspit.cpp +++ b/engines/mohawk/riven_stacks/bspit.cpp @@ -221,19 +221,12 @@ void BSpit::xbupdateboiler(uint16 argc, uint16 *argv) { } } -static void ytramTrapTimer(MohawkEngine_Riven *vm) { +void BSpit::ytramTrapTimer() { // Remove this timer - vm->removeTimer(); - - // FIXME: Improve the timer system (use a functor ?) + _vm->removeTimer(); // Check if we've caught a Ytram - BSpit *bspit = dynamic_cast(vm->getStack()); - if (!bspit) { - error("Unexpected stack type in 'ytramTrapTimer'"); - } - - bspit->checkYtramCatch(true); + checkYtramCatch(true); } void BSpit::xbsettrap(uint16 argc, uint16 *argv) { @@ -244,7 +237,7 @@ void BSpit::xbsettrap(uint16 argc, uint16 *argv) { _vm->_vars["bytramtime"] = timeUntilCatch + _vm->getTotalPlayTime(); // And set the timer too - _vm->installTimer(&ytramTrapTimer, timeUntilCatch); + _vm->installTimer(TIMER(BSpit, ytramTrapTimer), timeUntilCatch); } void BSpit::checkYtramCatch(bool playSound) { @@ -255,7 +248,7 @@ void BSpit::checkYtramCatch(bool playSound) { // 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()); + _vm->installTimer(TIMER(BSpit, ytramTrapTimer), ytramTime - _vm->getTotalPlayTime()); return; } diff --git a/engines/mohawk/riven_stacks/bspit.h b/engines/mohawk/riven_stacks/bspit.h index 7e810f26eb..135776e8bd 100644 --- a/engines/mohawk/riven_stacks/bspit.h +++ b/engines/mohawk/riven_stacks/bspit.h @@ -67,6 +67,7 @@ public: void xbchipper(uint16 argc, uint16 *argv); // Time callback + void ytramTrapTimer(); void checkYtramCatch(bool playSound); }; diff --git a/engines/mohawk/riven_stacks/gspit.cpp b/engines/mohawk/riven_stacks/gspit.cpp index b70a12c635..a53d0a1b85 100644 --- a/engines/mohawk/riven_stacks/gspit.cpp +++ b/engines/mohawk/riven_stacks/gspit.cpp @@ -368,20 +368,20 @@ void GSpit::xglview_villageoff(uint16 argc, uint16 *argv) { _vm->getCard()->drawPicture(1); } -static void catherineViewerIdleTimer(MohawkEngine_Riven *vm) { - uint32 &cathState = vm->_vars["gcathstate"]; +void GSpit::catherineViewerIdleTimer() { + uint32 &cathState = _vm->_vars["gcathstate"]; uint16 movie; // Choose a new movie if (cathState == 1) { static const int movieList[] = { 9, 10, 19, 19, 21, 21 }; - movie = movieList[vm->_rnd->getRandomNumber(5)]; + movie = movieList[_vm->_rnd->getRandomNumber(5)]; } else if (cathState == 2) { static const int movieList[] = { 18, 20, 22 }; - movie = movieList[vm->_rnd->getRandomNumber(2)]; + movie = movieList[_vm->_rnd->getRandomNumber(2)]; } else { static const int movieList[] = { 11, 11, 12, 17, 17, 17, 17, 23 }; - movie = movieList[vm->_rnd->getRandomNumber(7)]; + movie = movieList[_vm->_rnd->getRandomNumber(7)]; } // Update Catherine's state @@ -393,11 +393,11 @@ static void catherineViewerIdleTimer(MohawkEngine_Riven *vm) { cathState = 3; // Begin playing the new movie - vm->_video->activateMLST(vm->getCard()->getMovie(movie)); - VideoEntryPtr video = vm->_video->playMovieRiven(30); + _vm->_video->activateMLST(_vm->getCard()->getMovie(movie)); + VideoEntryPtr video = _vm->_video->playMovieRiven(30); // Reset the timer - vm->installTimer(&catherineViewerIdleTimer, video->getDuration().msecs() + vm->_rnd->getRandomNumber(60) * 1000); + _vm->installTimer(TIMER(GSpit, catherineViewerIdleTimer), video->getDuration().msecs() + _vm->_rnd->getRandomNumber(60) * 1000); } void GSpit::xglview_prisonon(uint16 argc, uint16 *argv) { @@ -445,7 +445,7 @@ void GSpit::xglview_prisonon(uint16 argc, uint16 *argv) { } // Create the timer for the next video - _vm->installTimer(&catherineViewerIdleTimer, timeUntilNextMovie); + _vm->installTimer(TIMER(GSpit, catherineViewerIdleTimer), timeUntilNextMovie); } void GSpit::xglview_prisonoff(uint16 argc, uint16 *argv) { diff --git a/engines/mohawk/riven_stacks/gspit.h b/engines/mohawk/riven_stacks/gspit.h index 045d47a2b4..e7f21692cc 100644 --- a/engines/mohawk/riven_stacks/gspit.h +++ b/engines/mohawk/riven_stacks/gspit.h @@ -65,6 +65,9 @@ public: void xglview_prisonon(uint16 argc, uint16 *argv); void xglview_villageon(uint16 argc, uint16 *argv); + // Timer handlers + void catherineViewerIdleTimer(); + private: void lowerPins(); }; diff --git a/engines/mohawk/riven_stacks/jspit.cpp b/engines/mohawk/riven_stacks/jspit.cpp index 582c1d6080..5ac65b347e 100644 --- a/engines/mohawk/riven_stacks/jspit.cpp +++ b/engines/mohawk/riven_stacks/jspit.cpp @@ -451,6 +451,138 @@ void JSpit::xjlagoon1500_alert(uint16 argc, uint16 *argv) { } } +void JSpit::sunnersTopStairsTimer() { + // If the sunners are gone, we have no video to play + if (_vm->_vars["jsunners"] != 0) { + _vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoEntryPtr oldVideo = _vm->_video->findVideoRiven(1); + uint32 timerTime = 500; + + if (!oldVideo || oldVideo->endOfVideo()) { + uint32 &sunnerTime = _vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = _vm->_rnd->getRandomNumberRng(2, 15) * 1000; + } else if (sunnerTime < _vm->getTotalPlayTime()) { + VideoEntryPtr video = _vm->_video->playMovieRiven(_vm->_rnd->getRandomNumberRng(1, 3)); + + timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(2, 15) * 1000; + } + + sunnerTime = timerTime + _vm->getTotalPlayTime(); + } + + _vm->installTimer(TIMER(JSpit, sunnersTopStairsTimer), timerTime); +} + +void JSpit::sunnersMidStairsTimer() { + // If the sunners are gone, we have no video to play + if (_vm->_vars["jsunners"] != 0) { + _vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoEntryPtr oldVideo = _vm->_video->findVideoRiven(1); + uint32 timerTime = 500; + + if (!oldVideo || oldVideo->endOfVideo()) { + uint32 &sunnerTime = _vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = _vm->_rnd->getRandomNumberRng(1, 10) * 1000; + } else if (sunnerTime < _vm->getTotalPlayTime()) { + // Randomize the video + int randValue = _vm->_rnd->getRandomNumber(5); + uint16 movie = 4; + if (randValue == 4) + movie = 2; + else if (randValue == 5) + movie = 3; + + VideoEntryPtr video = _vm->_video->playMovieRiven(movie); + + timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(1, 10) * 1000; + } + + sunnerTime = timerTime + _vm->getTotalPlayTime(); + } + + _vm->installTimer(TIMER(JSpit, sunnersMidStairsTimer), timerTime); +} + +void JSpit::sunnersLowerStairsTimer() { + // If the sunners are gone, we have no video to play + if (_vm->_vars["jsunners"] != 0) { + _vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoEntryPtr oldVideo = _vm->_video->findVideoRiven(1); + uint32 timerTime = 500; + + if (!oldVideo || oldVideo->endOfVideo()) { + uint32 &sunnerTime = _vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = _vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } else if (sunnerTime < _vm->getTotalPlayTime()) { + VideoEntryPtr video = _vm->_video->playMovieRiven(_vm->_rnd->getRandomNumberRng(3, 5)); + + timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } + + sunnerTime = timerTime + _vm->getTotalPlayTime(); + } + + _vm->installTimer(TIMER(JSpit, sunnersLowerStairsTimer), timerTime); +} + +void JSpit::sunnersBeachTimer() { + // If the sunners are gone, we have no video to play + if (_vm->_vars["jsunners"] != 0) { + _vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoEntryPtr oldvideo = _vm->_video->findVideoRiven(3); + uint32 timerTime = 500; + + if (!oldvideo || oldvideo->endOfVideo()) { + uint32 &sunnerTime = _vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = _vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } else if (sunnerTime < _vm->getTotalPlayTime()) { + // Unlike the other cards' scripts which automatically + // activate the MLST, we have to set it manually here. + uint16 mlstID = _vm->_rnd->getRandomNumberRng(3, 8); + _vm->_video->activateMLST(_vm->getCard()->getMovie(mlstID)); + VideoEntryPtr video = _vm->_video->playMovieRiven(mlstID); + + timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } + + sunnerTime = timerTime + _vm->getTotalPlayTime(); + } + + _vm->installTimer(TIMER(JSpit, sunnersBeachTimer), timerTime); +} + void JSpit::xjschool280_resetleft(uint16 argc, uint16 *argv) { // Dummy function. This resets the unneeded video timing variable (dropLeftStart) in // the DVD version. @@ -533,5 +665,24 @@ void JSpit::xjatboundary(uint16 argc, uint16 *argv) { runDemoBoundaryDialog(); } +void JSpit::installCardTimer() { + switch (getCurrentCardGlobalId()) { + case 0x77d6: // Sunners, top of stairs + _vm->installTimer(TIMER(JSpit, sunnersTopStairsTimer), 500); + break; + case 0x79bd: // Sunners, middle of stairs + _vm->installTimer(TIMER(JSpit, sunnersMidStairsTimer), 500); + break; + case 0x7beb: // Sunners, bottom of stairs + _vm->installTimer(TIMER(JSpit, sunnersLowerStairsTimer), 500); + break; + case 0xb6ca: // Sunners, shoreline + _vm->installTimer(TIMER(JSpit, sunnersBeachTimer), 500); + break; + default: + RivenStack::installCardTimer(); + } +} + } // End of namespace RivenStacks } // End of namespace Mohawk diff --git a/engines/mohawk/riven_stacks/jspit.h b/engines/mohawk/riven_stacks/jspit.h index d9f5ead2a1..bf9158875c 100644 --- a/engines/mohawk/riven_stacks/jspit.h +++ b/engines/mohawk/riven_stacks/jspit.h @@ -35,6 +35,9 @@ class JSpit : public DomeSpit { public: JSpit(MohawkEngine_Riven *vm); + // RivenStack API + virtual void installCardTimer() override; + // External commands - Rebel Tunnel Puzzle void xreseticons(uint16 argc, uint16 *argv); void xicon(uint16 argc, uint16 *argv); @@ -80,6 +83,12 @@ public: // External commands - Demo-specific void xjatboundary(uint16 argc, uint16 *argv); + // Timer callbacks + void sunnersTopStairsTimer(); + void sunnersMidStairsTimer(); + void sunnersLowerStairsTimer(); + void sunnersBeachTimer(); + private: int jspitElevatorLoop(); void redrawWharkNumberPuzzle(uint16 overlay, uint16 number); diff --git a/engines/mohawk/riven_stacks/pspit.cpp b/engines/mohawk/riven_stacks/pspit.cpp index ae10bd0211..4c80849d86 100644 --- a/engines/mohawk/riven_stacks/pspit.cpp +++ b/engines/mohawk/riven_stacks/pspit.cpp @@ -22,7 +22,9 @@ #include "mohawk/riven_stacks/pspit.h" +#include "mohawk/cursors.h" #include "mohawk/riven.h" +#include "mohawk/riven_card.h" #include "mohawk/riven_sound.h" namespace Mohawk { @@ -40,6 +42,45 @@ PSpit::PSpit(MohawkEngine_Riven *vm) : REGISTER_COMMAND(PSpit, xpisland25_slidermw); } +void PSpit::catherineIdleTimer() { + uint32 &cathCheck = _vm->_vars["pcathcheck"]; + uint32 &cathState = _vm->_vars["acathstate"]; + uint16 movie; + + // Choose a random movie based on where Catherine is + if (cathCheck == 0) { + static const int movieList[] = { 5, 6, 7, 8 }; + cathCheck = 1; + movie = movieList[_vm->_rnd->getRandomNumber(3)]; + } else if (cathState == 1) { + static const int movieList[] = { 11, 14 }; + movie = movieList[_vm->_rnd->getRandomBit()]; + } else { + static const int movieList[] = { 9, 10, 12, 13 }; + movie = movieList[_vm->_rnd->getRandomNumber(3)]; + } + + // Update her state if she moves from left/right or right/left, resp. + if (movie == 5 || movie == 7 || movie == 11 || movie == 14) + cathState = 2; + else + cathState = 1; + + // Play the movie, blocking + _vm->_video->activateMLST(_vm->getCard()->getMovie(movie)); + _vm->_cursor->hideCursor(); + _vm->_video->playMovieBlockingRiven(movie); + _vm->_cursor->showCursor(); + _vm->_system->updateScreen(); + + // Install the next timer for the next video + uint32 timeUntilNextMovie = _vm->_rnd->getRandomNumber(120) * 1000; + + _vm->_vars["pcathtime"] = timeUntilNextMovie + _vm->getTotalPlayTime(); + + _vm->installTimer(TIMER(PSpit, catherineIdleTimer), timeUntilNextMovie); +} + void PSpit::xpisland990_elevcombo(uint16 argc, uint16 *argv) { // Play button sound based on argv[0] _vm->_sound->playSound(argv[0] + 5); @@ -84,5 +125,15 @@ void PSpit::xpisland25_slidermw(uint16 argc, uint16 *argv) { checkSliderCursorChange(14); } +void PSpit::installCardTimer() { + if (getCurrentCardGlobalId() == 0x3a85) { + // Top of elevator on prison island + // Handle Catherine hardcoded videos + _vm->installTimer(TIMER(PSpit, catherineIdleTimer), _vm->_rnd->getRandomNumberRng(1, 33) * 1000); + } else { + RivenStack::installCardTimer(); + } +} + } // End of namespace RivenStacks } // End of namespace Mohawk diff --git a/engines/mohawk/riven_stacks/pspit.h b/engines/mohawk/riven_stacks/pspit.h index ca09417713..ec0186a727 100644 --- a/engines/mohawk/riven_stacks/pspit.h +++ b/engines/mohawk/riven_stacks/pspit.h @@ -35,6 +35,9 @@ class PSpit : public DomeSpit { public: PSpit(MohawkEngine_Riven *vm); + // RivenStack API + virtual void installCardTimer() override; + // External commands - Prison Elevator void xpisland990_elevcombo(uint16 argc, uint16 *argv); // Param1: button @@ -46,6 +49,8 @@ public: void xpisland25_slidermd(uint16 argc, uint16 *argv); void xpisland25_slidermw(uint16 argc, uint16 *argv); + // Timer callbacks + void catherineIdleTimer(); }; } // End of namespace RivenStacks diff --git a/engines/mohawk/riven_stacks/rspit.cpp b/engines/mohawk/riven_stacks/rspit.cpp index 992319d9dd..a7431a6e7f 100644 --- a/engines/mohawk/riven_stacks/rspit.cpp +++ b/engines/mohawk/riven_stacks/rspit.cpp @@ -60,20 +60,20 @@ void RSpit::xrhideinventory(uint16 argc, uint16 *argv) { _vm->_gfx->hideInventory(); } -static void rebelPrisonWindowTimer(MohawkEngine_Riven *vm) { +void RSpit::rebelPrisonWindowTimer() { // Randomize a video out in the middle of Tay - uint16 movie = vm->_rnd->getRandomNumberRng(2, 13); - vm->_video->activateMLST(vm->getCard()->getMovie(movie)); - VideoEntryPtr handle = vm->_video->playMovieRiven(movie); + uint16 movie = _vm->_rnd->getRandomNumberRng(2, 13); + _vm->_video->activateMLST(_vm->getCard()->getMovie(movie)); + VideoEntryPtr handle = _vm->_video->playMovieRiven(movie); // Ensure the next video starts after this one ends - uint32 timeUntilNextVideo = handle->getDuration().msecs() + vm->_rnd->getRandomNumberRng(38, 58) * 1000; + uint32 timeUntilNextVideo = handle->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(38, 58) * 1000; // Save the time in case we leave the card and return - vm->_vars["rvillagetime"] = timeUntilNextVideo + vm->getTotalPlayTime(); + _vm->_vars["rvillagetime"] = timeUntilNextVideo + _vm->getTotalPlayTime(); // Reinstall this timer with the new time - vm->installTimer(&rebelPrisonWindowTimer, timeUntilNextVideo); + _vm->installTimer(TIMER(RSpit, rebelPrisonWindowTimer), timeUntilNextVideo); } void RSpit::xrwindowsetup(uint16 argc, uint16 *argv) { @@ -83,7 +83,7 @@ void RSpit::xrwindowsetup(uint16 argc, uint16 *argv) { // If we have time leftover from a previous run, set up the timer again if (_vm->getTotalPlayTime() < villageTime) { - _vm->installTimer(&rebelPrisonWindowTimer, villageTime - _vm->getTotalPlayTime()); + _vm->installTimer(TIMER(RSpit, rebelPrisonWindowTimer), villageTime - _vm->getTotalPlayTime()); return; } @@ -106,7 +106,7 @@ void RSpit::xrwindowsetup(uint16 argc, uint16 *argv) { // the timer to reinstall itself... // Install our timer and we're on our way - _vm->installTimer(&rebelPrisonWindowTimer, timeUntilNextVideo); + _vm->installTimer(TIMER(RSpit, rebelPrisonWindowTimer), timeUntilNextVideo); } diff --git a/engines/mohawk/riven_stacks/rspit.h b/engines/mohawk/riven_stacks/rspit.h index c46537c3ff..fe219444d6 100644 --- a/engines/mohawk/riven_stacks/rspit.h +++ b/engines/mohawk/riven_stacks/rspit.h @@ -41,6 +41,8 @@ public: void xrhideinventory(uint16 argc, uint16 *argv); void xrwindowsetup(uint16 argc, uint16 *argv); + // Timer callbacks + void rebelPrisonWindowTimer(); }; } // End of namespace RivenStacks -- cgit v1.2.3