MOHAWK: Finish implementation of Riven's storeMovieOpcode opcode

This commit is contained in:
Matthew Hoops 2011-06-14 10:35:58 -04:00
parent de96474672
commit 5174832e31
6 changed files with 45 additions and 19 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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:

View File

@ -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