From 5174832e314b4c63ac2a7fd89c09f48fafc68a69 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Tue, 14 Jun 2011 10:35:58 -0400 Subject: MOHAWK: Finish implementation of Riven's storeMovieOpcode opcode --- engines/mohawk/mohawk.h | 7 ++++++- engines/mohawk/riven.cpp | 13 +++++++++++++ engines/mohawk/riven.h | 2 ++ engines/mohawk/riven_scripts.cpp | 26 ++++++++++---------------- engines/mohawk/riven_scripts.h | 4 +++- engines/mohawk/video.cpp | 12 +++++++++++- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/engines/mohawk/mohawk.h b/engines/mohawk/mohawk.h index b189f82040..f0618f7374 100644 --- a/engines/mohawk/mohawk.h +++ b/engines/mohawk/mohawk.h @@ -28,6 +28,8 @@ #include "engines/engine.h" +#include "mohawk/video.h" + class OSystem; namespace Common { @@ -76,7 +78,6 @@ struct MohawkGameDescription; class Sound; class PauseDialog; class MohawkArchive; -class VideoManager; class CursorManager; class MohawkEngine : public ::Engine { @@ -112,6 +113,10 @@ public: void pauseGame(); + // Check if events should be done based on a video's current time + // (currently only used for Riven's storeMovieOpcode function) + virtual void doVideoTimer(VideoHandle handle, bool force) {} + private: PauseDialog *_pauseDialog; void pauseEngineIntern(bool); diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 57a0ac717d..3514afdb61 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -833,6 +833,19 @@ void MohawkEngine_Riven::installCardTimer() { } } +void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) { + assert(handle != NULL_VID_HANDLE); + + uint16 id = _scriptMan->getStoredMovieOpcodeID(); + + if (handle != _video->findVideoHandleRiven(id)) // Check if we've got a video match + return; + + // Run the opcode if we can at this point + if (force || _video->getElapsedTime(handle) >= _scriptMan->getStoredMovieOpcodeTime()) + _scriptMan->runStoredMovieOpcode(); +} + 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 c80f497e37..c7d36e585d 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -131,6 +131,8 @@ public: typedef void (*TimerProc)(MohawkEngine_Riven *vm); + void doVideoTimer(VideoHandle handle, bool force); + private: MohawkArchive *_extrasFile; // We need a separate handle for the extra data RivenConsole *_console; diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp index b3d5369a84..8abce10f3b 100644 --- a/engines/mohawk/riven_scripts.cpp +++ b/engines/mohawk/riven_scripts.cpp @@ -536,6 +536,10 @@ void RivenScript::fadeAmbientSounds(uint16 op, uint16 argc, uint16 *argv) { // Command 38: Store an opcode for use when playing a movie (movie id, time high, time low, opcode, arguments...) void RivenScript::storeMovieOpcode(uint16 op, uint16 argc, uint16 *argv) { + // This opcode is used to delay an opcode's usage based on the elapsed + // time of a specified movie. However, every use in the game is for + // delaying an activateSLST opcode. + uint32 scriptSize = 6 + (argc - 4) * 2; // Create our dummy script @@ -557,13 +561,11 @@ void RivenScript::storeMovieOpcode(uint16 op, uint16 argc, uint16 *argv) { // Store the script RivenScriptManager::StoredMovieOpcode storedOp; storedOp.script = script; - storedOp.time = delayTime + _vm->getTotalPlayTime(); + storedOp.time = delayTime; storedOp.id = argv[0]; - // TODO: Actually store the movie and call it in our movie loop - // For now, just delete the script and move on - //_vm->_scriptMan->setStoredMovieOpcode(storedOp); - delete script; + // Store the opcode for later + _vm->_scriptMan->setStoredMovieOpcode(storedOp); } else { // Run immediately if we have no delay script->runScript(); @@ -716,18 +718,10 @@ void RivenScriptManager::setStoredMovieOpcode(const StoredMovieOpcode &op) { _storedMovieOpcode.time = op.time; } -void RivenScriptManager::runStoredMovieOpcode(uint16 id) { +void RivenScriptManager::runStoredMovieOpcode() { if (_storedMovieOpcode.script) { - if (_storedMovieOpcode.id == id) { - // If we've passed the time, run our script - if (_vm->getTotalPlayTime() >= _storedMovieOpcode.time) { - _storedMovieOpcode.script->runScript(); - clearStoredMovieOpcode(); - } - } else { - // We're on a completely different video, kill off any remaining opcode - clearStoredMovieOpcode(); - } + _storedMovieOpcode.script->runScript(); + clearStoredMovieOpcode(); } } diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h index 75d4592e55..2932ba5939 100644 --- a/engines/mohawk/riven_scripts.h +++ b/engines/mohawk/riven_scripts.h @@ -141,8 +141,10 @@ public: uint16 id; }; + uint16 getStoredMovieOpcodeID() { return _storedMovieOpcode.id; } + uint32 getStoredMovieOpcodeTime() { return _storedMovieOpcode.time; } void setStoredMovieOpcode(const StoredMovieOpcode &op); - void runStoredMovieOpcode(uint16 id); + void runStoredMovieOpcode(); void clearStoredMovieOpcode(); private: diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp index 0a74d058c9..eec6256276 100644 --- a/engines/mohawk/video.cpp +++ b/engines/mohawk/video.cpp @@ -133,6 +133,7 @@ void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) { break; case Common::KEYCODE_ESCAPE: continuePlaying = false; + _vm->doVideoTimer(videoHandle, true); break; default: break; @@ -208,14 +209,20 @@ bool VideoManager::updateMovies() { if (_videoStreams[i].loop) { _videoStreams[i]->seekToTime(_videoStreams[i].start); } else { + // Check the video time one last time before deleting it + _vm->doVideoTimer(i, true); delete _videoStreams[i].video; _videoStreams[i].clear(); continue; } } + // Nothing more to do if we're paused + if (_videoStreams[i]->isPaused()) + continue; + // Check if we need to draw a frame - if (!_videoStreams[i]->isPaused() && _videoStreams[i]->needsUpdate()) { + if (_videoStreams[i]->needsUpdate()) { const Graphics::Surface *frame = _videoStreams[i]->decodeNextFrame(); Graphics::Surface *convertedFrame = 0; @@ -266,6 +273,9 @@ bool VideoManager::updateMovies() { } } } + + // Check the video time + _vm->doVideoTimer(i, false); } // Return true if we need to update the screen -- cgit v1.2.3