aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Bouclet2016-11-05 14:47:02 +0100
committerEugene Sandulenko2017-07-03 08:50:10 +0200
commit22926a1835079f31fa778f2f2eb4e645c451457a (patch)
tree5c622ae7a0ef933ccfe0abe18aec7f7d3b42542d
parentefcf38f95f14272efd8ace91747a45bd53c74b57 (diff)
downloadscummvm-rg350-22926a1835079f31fa778f2f2eb4e645c451457a.tar.gz
scummvm-rg350-22926a1835079f31fa778f2f2eb4e645c451457a.tar.bz2
scummvm-rg350-22926a1835079f31fa778f2f2eb4e645c451457a.zip
MOHAWK: Move the timer callbacks to the stacks
-rw-r--r--engines/mohawk/riven.cpp203
-rw-r--r--engines/mohawk/riven.h10
-rw-r--r--engines/mohawk/riven_stack.cpp4
-rw-r--r--engines/mohawk/riven_stack.h3
-rw-r--r--engines/mohawk/riven_stacks/bspit.cpp17
-rw-r--r--engines/mohawk/riven_stacks/bspit.h1
-rw-r--r--engines/mohawk/riven_stacks/gspit.cpp18
-rw-r--r--engines/mohawk/riven_stacks/gspit.h3
-rw-r--r--engines/mohawk/riven_stacks/jspit.cpp151
-rw-r--r--engines/mohawk/riven_stacks/jspit.h9
-rw-r--r--engines/mohawk/riven_stacks/pspit.cpp51
-rw-r--r--engines/mohawk/riven_stacks/pspit.h5
-rw-r--r--engines/mohawk/riven_stacks/rspit.cpp18
-rw-r--r--engines/mohawk/riven_stacks/rspit.h2
14 files changed, 263 insertions, 232 deletions
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<TimerProc>(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<void> TimerProc;
+
+#define TIMER(cls, method) \
+ new Common::Functor0Mem<void, cls>(this, &cls::method)
void doVideoTimer(VideoHandle handle, bool force);
@@ -131,7 +134,7 @@ private:
void initVars();
// Timer
- TimerProc _timerProc;
+ Common::SharedPtr<TimerProc> _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<BSpit *>(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