diff options
30 files changed, 1048 insertions, 497 deletions
diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h index e0f8635568..4b87b6464f 100644 --- a/engines/mohawk/livingbooks.h +++ b/engines/mohawk/livingbooks.h @@ -27,6 +27,7 @@ #include "mohawk/console.h" #include "mohawk/livingbooks_graphics.h" #include "mohawk/sound.h" +#include "mohawk/video.h" #include "common/ini-file.h" #include "common/rect.h" diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk index 7022c23780..de0f205219 100644 --- a/engines/mohawk/module.mk +++ b/engines/mohawk/module.mk @@ -61,6 +61,7 @@ MODULE_OBJS += \ riven_sound.o \ riven_stack.o \ riven_vars.o \ + riven_video.o \ riven_stacks/aspit.o \ riven_stacks/bspit.o \ riven_stacks/domespit.o \ diff --git a/engines/mohawk/mohawk.h b/engines/mohawk/mohawk.h index fe2c15739c..c6781ae448 100644 --- a/engines/mohawk/mohawk.h +++ b/engines/mohawk/mohawk.h @@ -28,8 +28,6 @@ #include "engines/engine.h" -#include "mohawk/video.h" - class OSystem; namespace Common { @@ -111,10 +109,6 @@ 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; diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index f8b302b8d9..52784e58e4 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -46,8 +46,8 @@ #include "mohawk/riven_stacks/pspit.h" #include "mohawk/riven_stacks/rspit.h" #include "mohawk/riven_stacks/tspit.h" +#include "mohawk/riven_video.h" #include "mohawk/dialogs.h" -#include "mohawk/video.h" #include "mohawk/console.h" namespace Mohawk { @@ -118,7 +118,7 @@ Common::Error MohawkEngine_Riven::run() { SearchMan.add("arcriven.z", &_installerArchive, 0, false); _gfx = new RivenGraphics(this); - _video = new VideoManager(this); + _video = new RivenVideoManager(this); _sound = new RivenSoundManager(this); _console = new RivenConsole(this); _saveLoad = new RivenSaveLoad(this, _saveFileMan); @@ -221,6 +221,9 @@ void MohawkEngine_Riven::doFrame() { _stack->onMouseUp(_eventMan->getMousePos()); _inventory->checkClick(_eventMan->getMousePos()); break; + case Common::EVENT_KEYUP: + _stack->keyForceUp(); + break; case Common::EVENT_KEYDOWN: switch (event.kbd.keycode) { case Common::KEYCODE_d: @@ -263,6 +266,8 @@ void MohawkEngine_Riven::doFrame() { } break; default: + // TODO: Pass the keypress to the game only if it was not consumed by the engine + _stack->onKeyPressed(event.kbd.keycode); break; } break; @@ -310,8 +315,7 @@ void MohawkEngine_Riven::changeToStack(uint16 n) { return; // Stop any videos playing - _video->stopVideos(); - _video->clearMLST(); + _video->removeVideos(); // Clear the graphics cache; images aren't used across stack boundaries _gfx->clearCache(); @@ -423,7 +427,7 @@ void MohawkEngine_Riven::refreshCard() { // Clear any timer still floating around removeTimer(); - _card->enter(); + _card->enter(true); if (_showHotspots) _card->drawHotspotRects(); @@ -498,19 +502,6 @@ void MohawkEngine_Riven::removeTimer() { _timerTime = 0; } -void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) { - assert(handle); - - uint16 id = _scriptMan->getStoredMovieOpcodeID(); - - if (handle != _video->findVideoRiven(id)) // Check if we've got a video match - return; - - // Run the opcode if we can at this point - if (force || handle->getTime() >= _scriptMan->getStoredMovieOpcodeTime()) - _scriptMan->runStoredMovieOpcode(); -} - void MohawkEngine_Riven::addZipVisitedCard(uint16 cardId, uint16 cardNameId) { Common::String cardName = getStack()->getName(kCardNames, cardNameId); if (cardName.empty()) diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index a8e9939b43..1cb8d9dbdf 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -25,7 +25,6 @@ #include "mohawk/installer_archive.h" #include "mohawk/mohawk.h" -#include "mohawk/riven_scripts.h" #include "common/hashmap.h" #include "common/hash-str.h" @@ -43,8 +42,10 @@ class RivenOptionsDialog; class RivenStack; class RivenCard; class RivenHotspot; +class RivenScriptManager; class RivenSoundManager; class RivenInventory; +class RivenVideoManager; // Riven Stack Types enum { @@ -83,7 +84,7 @@ public: MohawkEngine_Riven(OSystem *syst, const MohawkGameDescription *gamedesc); virtual ~MohawkEngine_Riven(); - VideoManager *_video; + RivenVideoManager *_video; RivenSoundManager *_sound; RivenGraphics *_gfx; Common::RandomSource *_rnd; @@ -103,7 +104,6 @@ public: #define TIMER(cls, method) \ new Common::Functor0Mem<void, cls>(this, &cls::method) - void doVideoTimer(VideoHandle handle, bool force); void doFrame(); private: diff --git a/engines/mohawk/riven_card.cpp b/engines/mohawk/riven_card.cpp index 99ee902799..cc9e8128d3 100644 --- a/engines/mohawk/riven_card.cpp +++ b/engines/mohawk/riven_card.cpp @@ -25,6 +25,7 @@ #include "mohawk/cursors.h" #include "mohawk/riven_graphics.h" #include "mohawk/riven_stack.h" +#include "mohawk/riven_video.h" #include "mohawk/resource.h" #include "mohawk/riven.h" @@ -52,7 +53,7 @@ RivenCard::~RivenCard() { _vm->_gfx->clearWaterEffects(); _vm->_gfx->clearFliesEffect(); - _vm->_video->stopVideos(); + _vm->_video->closeVideos(); } void RivenCard::loadCardResource(uint16 id) { @@ -65,7 +66,7 @@ void RivenCard::loadCardResource(uint16 id) { delete inStream; } -void RivenCard::enter() { +void RivenCard::enter(bool unkMovies) { setCurrentCardVariable(); _vm->_activatedPLST = false; @@ -516,7 +517,7 @@ void RivenCard::dump() const { for (uint i = 0; i < _movieList.size(); i++) { debug("== Movie %d ==", _movieList[i].index); debug("movieID: %d", _movieList[i].movieID); - debug("code: %d", _movieList[i].code); + debug("playbackSlot: %d", _movieList[i].playbackSlot); debug("left: %d", _movieList[i].left); debug("top: %d", _movieList[i].top); debug("u0[0]: %d", _movieList[i].u0[0]); @@ -539,7 +540,7 @@ void RivenCard::loadCardMovieList(uint16 id) { MLSTRecord &mlstRecord = _movieList[i]; mlstRecord.index = mlstStream->readUint16BE(); mlstRecord.movieID = mlstStream->readUint16BE(); - mlstRecord.code = mlstStream->readUint16BE(); + mlstRecord.playbackSlot = mlstStream->readUint16BE(); mlstRecord.left = mlstStream->readUint16BE(); mlstRecord.top = mlstStream->readUint16BE(); @@ -571,6 +572,13 @@ MLSTRecord RivenCard::getMovie(uint16 index) const { error("Could not find movie %d in card %d", index, _id); } +void RivenCard::playMovie(uint16 index, bool queue) { + if (index > 0 && index <= _movieList.size()) { + RivenScriptPtr script = _vm->_scriptMan->createScriptFromData(1, kRivenCommandActivateMLSTAndPlay, 1, index); + _vm->_scriptMan->runScript(script, queue); + } +} + RivenHotspot::RivenHotspot(MohawkEngine_Riven *vm, Common::ReadStream *stream) : _vm(vm) { loadFromStream(stream); diff --git a/engines/mohawk/riven_card.h b/engines/mohawk/riven_card.h index 27e6ec2ca8..a736a604b6 100644 --- a/engines/mohawk/riven_card.h +++ b/engines/mohawk/riven_card.h @@ -25,7 +25,6 @@ #include "mohawk/riven_scripts.h" #include "mohawk/riven_sound.h" -#include "mohawk/video.h" #include "common/rect.h" #include "common/system.h" @@ -33,6 +32,7 @@ namespace Mohawk { class RivenHotspot; +struct MLSTRecord; /** * A game view @@ -57,7 +57,7 @@ public: }; /** Initialization routine used to draw a card for the first time or to refresh it */ - void enter(); + void enter(bool unkMovies); /** Run the card's leave scripts */ void leave(); @@ -80,6 +80,9 @@ public: /** Get the card's sound description with the specified index */ SLSTRecord getSound(uint16 index) const; + /** Play the card's movie with the specified index */ + void playMovie(uint16 index, bool queue = false); + /** Get the card's movie description with the specified index */ MLSTRecord getMovie(uint16 index) const; @@ -177,6 +180,18 @@ private: Common::Array<WaterEffectRecord> _waterEffectList; }; +struct MLSTRecord { + uint16 index; + uint16 movieID; + uint16 playbackSlot; + uint16 left; + uint16 top; + uint16 u0[3]; + uint16 loop; + uint16 volume; + uint16 u1; +}; + /** * A Card Hotspot * diff --git a/engines/mohawk/riven_graphics.cpp b/engines/mohawk/riven_graphics.cpp index 04562f82ba..a4fd6d0aa7 100644 --- a/engines/mohawk/riven_graphics.cpp +++ b/engines/mohawk/riven_graphics.cpp @@ -282,6 +282,7 @@ RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm _screenUpdateNesting = 0; _screenUpdateRunning = false; + _enableCardUpdateScript = true; _scheduledTransition = kRivenTransitionNone; _dirtyScreen = false; @@ -651,7 +652,9 @@ void RivenGraphics::applyScreenUpdate(bool force) { if (_screenUpdateNesting <= 0 && !_screenUpdateRunning) { _screenUpdateRunning = true; - _vm->getCard()->runScript(kCardUpdateScript); + if (_enableCardUpdateScript) { + _vm->getCard()->runScript(kCardUpdateScript); + } _vm->_sound->triggerDrawSound(); updateScreen(); @@ -686,6 +689,17 @@ void RivenGraphics::updateEffects() { } } +void RivenGraphics::copySystemRectToScreen(const Common::Rect &rect) { + Graphics::Surface *screen = _vm->_system->lockScreen(); + _mainScreen->copyRectToSurface(*screen, rect.left, rect.top, rect); + _effectScreen->copyRectToSurface(*screen, rect.left, rect.top, rect); + _vm->_system->unlockScreen(); +} + +void RivenGraphics::enableCardUpdateScript(bool enable) { + _enableCardUpdateScript = enable; +} + const FliesEffect::FliesEffectData FliesEffect::_firefliesParameters = { true, true, diff --git a/engines/mohawk/riven_graphics.h b/engines/mohawk/riven_graphics.h index b09eefbded..6b63a869ba 100644 --- a/engines/mohawk/riven_graphics.h +++ b/engines/mohawk/riven_graphics.h @@ -59,6 +59,7 @@ public: // Screen updates void beginScreenUpdate(); void applyScreenUpdate(bool force = false); + void enableCardUpdateScript(bool enable); void copyImageToScreen(uint16 image, uint32 left, uint32 top, uint32 right, uint32 bottom); void updateScreen(const Common::Rect &updateRect = Common::Rect(0, 0, 608, 392)); @@ -67,6 +68,9 @@ public: void drawExtrasImage(uint16 id, const Common::Rect &dstRect); void drawExtrasImageToScreen(uint16 id, const Common::Rect &rect); + /** Copy a rect from the system screen to the game screen */ + void copySystemRectToScreen(const Common::Rect &rect); + Graphics::Surface *getEffectScreen(); Graphics::Surface *getBackScreen(); @@ -101,6 +105,7 @@ private: MohawkBitmap *_bitmapDecoder; int _screenUpdateNesting; bool _screenUpdateRunning; + bool _enableCardUpdateScript; // Water Effects struct SFXERecord { diff --git a/engines/mohawk/riven_scripts.cpp b/engines/mohawk/riven_scripts.cpp index 8c6c9745a1..e6ebd6e281 100644 --- a/engines/mohawk/riven_scripts.cpp +++ b/engines/mohawk/riven_scripts.cpp @@ -27,7 +27,7 @@ #include "mohawk/riven_scripts.h" #include "mohawk/riven_sound.h" #include "mohawk/riven_stack.h" -#include "mohawk/video.h" +#include "mohawk/riven_video.h" #include "common/memstream.h" #include "common/debug-channels.h" @@ -509,9 +509,9 @@ void RivenSimpleCommand::incrementVariable(uint16 op, uint16 argc, uint16 *argv) // Command 28: disable a movie void RivenSimpleCommand::disableMovie(uint16 op, uint16 argc, uint16 *argv) { - VideoEntryPtr video = _vm->_video->findVideoRiven(argv[0]); + RivenVideo *video = _vm->_video->openSlot(argv[0]); if (video) - video->setEnabled(false); + video->disable(); } // Command 29: disable all movies @@ -521,26 +521,29 @@ void RivenSimpleCommand::disableAllMovies(uint16 op, uint16 argc, uint16 *argv) // Command 31: enable a movie void RivenSimpleCommand::enableMovie(uint16 op, uint16 argc, uint16 *argv) { - VideoEntryPtr video = _vm->_video->findVideoRiven(argv[0]); - if (video) - video->setEnabled(true); + RivenVideo *video = _vm->_video->openSlot(argv[0]); + video->enable(); } // Command 32: play foreground movie - blocking (movie_id) void RivenSimpleCommand::playMovieBlocking(uint16 op, uint16 argc, uint16 *argv) { - _vm->_cursor->hideCursor(); - _vm->_video->playMovieBlockingRiven(argv[0]); - _vm->_cursor->showCursor(); + RivenVideo *video = _vm->_video->openSlot(argv[0]); + video->setLooping(false); + video->enable(); + video->playBlocking(); } // Command 33: play background movie - nonblocking (movie_id) void RivenSimpleCommand::playMovie(uint16 op, uint16 argc, uint16 *argv) { - _vm->_video->playMovieRiven(argv[0]); + RivenVideo *video = _vm->_video->openSlot(argv[0]); + video->enable(); + video->play(); } // Command 34: stop a movie void RivenSimpleCommand::stopMovie(uint16 op, uint16 argc, uint16 *argv) { - _vm->_video->stopMovieRiven(argv[0]); + RivenVideo *video = _vm->_video->openSlot(argv[0]); + video->stop(); } // Command 36: unknown @@ -611,8 +614,12 @@ void RivenSimpleCommand::activateSLST(uint16 op, uint16 argc, uint16 *argv) { // Command 41: activate MLST record and play void RivenSimpleCommand::activateMLSTAndPlay(uint16 op, uint16 argc, uint16 *argv) { - _vm->_video->activateMLST(_vm->getCard()->getMovie(argv[0])); - _vm->_video->playMovieRiven(argv[0]); + MLSTRecord mlstRecord = _vm->getCard()->getMovie(argv[0]); + activateMLST(mlstRecord); + + RivenVideo *video = _vm->_video->openSlot(mlstRecord.playbackSlot); + video->enable(); + video->play(); } // Command 43: activate BLST record (card hotspot enabling lists) @@ -644,7 +651,16 @@ void RivenSimpleCommand::zipMode(uint16 op, uint16 argc, uint16 *argv) { // Command 46: activate MLST record (movie lists) void RivenSimpleCommand::activateMLST(uint16 op, uint16 argc, uint16 *argv) { - _vm->_video->activateMLST(_vm->getCard()->getMovie(argv[0])); + MLSTRecord mlstRecord = _vm->getCard()->getMovie(argv[0]); + activateMLST(mlstRecord); +} + +void RivenSimpleCommand::activateMLST(const MLSTRecord &mlstRecord) const { + RivenVideo *ptr = _vm->_video->openSlot(mlstRecord.playbackSlot); + ptr->load(mlstRecord.movieID); + ptr->moveTo(mlstRecord.left, mlstRecord.top); + ptr->setLooping(mlstRecord.loop != 0); + ptr->setVolume(mlstRecord.volume); } Common::String RivenSimpleCommand::describe() const { diff --git a/engines/mohawk/riven_scripts.h b/engines/mohawk/riven_scripts.h index d052a02787..cac01fbcea 100644 --- a/engines/mohawk/riven_scripts.h +++ b/engines/mohawk/riven_scripts.h @@ -91,6 +91,7 @@ enum RivenCommandType { class MohawkEngine_Riven; class RivenCommand; class RivenScript; +struct MLSTRecord; typedef Common::SharedPtr<RivenScript> RivenScriptPtr; typedef Common::SharedPtr<RivenCommand> RivenCommandPtr; @@ -264,6 +265,8 @@ private: void setupOpcodes(); Common::String describe() const; + void activateMLST(const MLSTRecord &mlst) const; + DECLARE_OPCODE(empty) { warning ("Unknown Opcode %04x", op); } // Opcodes diff --git a/engines/mohawk/riven_sound.cpp b/engines/mohawk/riven_sound.cpp index 354ba2dcce..36dbab67bb 100644 --- a/engines/mohawk/riven_sound.cpp +++ b/engines/mohawk/riven_sound.cpp @@ -26,11 +26,13 @@ #include "audio/audiostream.h" #include "mohawk/riven_sound.h" +#include "mohawk/riven.h" +#include "mohawk/riven_card.h" #include "mohawk/sound.h" namespace Mohawk { -RivenSoundManager::RivenSoundManager(MohawkEngine *vm) : +RivenSoundManager::RivenSoundManager(MohawkEngine_Riven *vm) : _vm(vm), _effect(nullptr), _mainAmbientSoundId(-1), @@ -68,8 +70,9 @@ void RivenSoundManager::playSound(uint16 id, uint16 volume, bool playOnDraw) { } } -void RivenSoundManager::playSound(const Common::String &name, uint16 volume, bool playOnDraw) { - uint16 id =_vm->findResourceID(ID_TWAV, name); +void RivenSoundManager::playCardSound(const Common::String &name, uint16 volume, bool playOnDraw) { + Common::String fullName = Common::String::format("%d_%s_1", _vm->getCard()->getId(), name.c_str()); + uint16 id =_vm->findResourceID(ID_TWAV, fullName); playSound(id, volume, playOnDraw); } @@ -307,7 +310,7 @@ bool RivenSoundManager::isEffectPlaying() const { return _effect != nullptr && _effect->isPlaying(); } -RivenSound::RivenSound(MohawkEngine *vm, Audio::RewindableAudioStream *rewindStream) : +RivenSound::RivenSound(MohawkEngine_Riven *vm, Audio::RewindableAudioStream *rewindStream) : _vm(vm), _volume(Audio::Mixer::kMaxChannelVolume), _balance(0), diff --git a/engines/mohawk/riven_sound.h b/engines/mohawk/riven_sound.h index bd9237d9a6..a929c43087 100644 --- a/engines/mohawk/riven_sound.h +++ b/engines/mohawk/riven_sound.h @@ -34,7 +34,7 @@ class RewindableAudioStream; namespace Mohawk { -class MohawkEngine; +class MohawkEngine_Riven; class RivenSound; /** @@ -65,7 +65,7 @@ struct SLSTRecord { */ class RivenSoundManager { public: - RivenSoundManager(MohawkEngine *vm); + RivenSoundManager(MohawkEngine_Riven *vm); ~RivenSoundManager(); /** @@ -78,7 +78,7 @@ public: void playSound(uint16 id, uint16 volume = 255, bool playOnDraw = false); /** Play an effect sound by its resource name */ - void playSound(const Common::String &name, uint16 volume = 255, bool playOnDraw = false); + void playCardSound(const Common::String &name, uint16 volume = 255, bool playOnDraw = false); /** Start playing the scheduled on-draw effect sound, if any. Called by the GraphicsManager. */ void triggerDrawSound(); @@ -120,7 +120,7 @@ private: kFadeInNewSounds = 2 }; - MohawkEngine *_vm; + MohawkEngine_Riven *_vm; int16 _mainAmbientSoundId; AmbientSoundList _ambientSounds; @@ -154,7 +154,7 @@ private: */ class RivenSound { public: - RivenSound(MohawkEngine *vm, Audio::RewindableAudioStream *rewindStream); + RivenSound(MohawkEngine_Riven *vm, Audio::RewindableAudioStream *rewindStream); ~RivenSound(); /** Start playing the sound stream passed to the constructor */ @@ -185,7 +185,7 @@ private: static byte convertVolume(uint16 volume); static int8 convertBalance(int16 balance); - MohawkEngine *_vm; + MohawkEngine_Riven *_vm; Audio::SoundHandle _handle; Audio::RewindableAudioStream *_stream; diff --git a/engines/mohawk/riven_stack.cpp b/engines/mohawk/riven_stack.cpp index 490e4b538b..a7b348b285 100644 --- a/engines/mohawk/riven_stack.cpp +++ b/engines/mohawk/riven_stack.cpp @@ -26,6 +26,7 @@ #include "mohawk/riven.h" #include "mohawk/riven_card.h" #include "mohawk/riven_graphics.h" +#include "mohawk/riven_video.h" #include "mohawk/resource.h" #include "common/events.h" @@ -37,7 +38,8 @@ namespace Mohawk { RivenStack::RivenStack(MohawkEngine_Riven *vm, uint16 id) : _vm(vm), _id(id), - _mouseIsDown(false) { + _mouseIsDown(false), + _keyPressed(Common::KEYCODE_INVALID) { loadResourceNames(); loadCardIdMap(); setCurrentStackVariable(); @@ -178,10 +180,11 @@ void RivenStack::runDemoBoundaryDialog() { dialog.runModal(); } -void RivenStack::runEndGame(uint16 video, uint32 delay) { +void RivenStack::runEndGame(uint16 videoCode, uint32 delay) { _vm->_sound->stopAllSLST(); - _vm->_video->playMovieRiven(video); - runCredits(video, delay); + RivenVideo *video = _vm->_video->openSlot(videoCode); + video->play(); + runCredits(videoCode, delay); } void RivenStack::runCredits(uint16 video, uint32 delay) { @@ -190,7 +193,7 @@ void RivenStack::runCredits(uint16 video, uint32 delay) { _vm->_gfx->beginCredits(); uint nextCreditsFrameStart = 0; - VideoEntryPtr videoPtr = _vm->_video->findVideoRiven(video); + RivenVideo *videoPtr = _vm->_video->getSlot(video); while (!_vm->shouldQuit() && _vm->_gfx->getCurCreditsImage() <= 320) { if (videoPtr->getCurFrame() >= (int32)videoPtr->getFrameCount() - 1) { @@ -207,8 +210,10 @@ void RivenStack::runCredits(uint16 video, uint32 delay) { _vm->_gfx->updateCredits(); } - } else if (_vm->_video->updateMovies()) + } else { + _vm->_video->updateMovies(); _vm->_system->updateScreen(); + } Common::Event event; while (_vm->_system->getEventManager()->pollEvent(event)) @@ -290,6 +295,18 @@ void RivenStack::onFrame() { _vm->_scriptMan->runScript(script, true); } +Common::KeyCode RivenStack::keyGetPressed() const { + return _keyPressed; +} + +void RivenStack::keyForceUp() { + _keyPressed = Common::KEYCODE_INVALID; +} + +void RivenStack::onKeyPressed(const Common::KeyCode keyCode) { + _keyPressed = keyCode; +} + RivenNameList::RivenNameList() { } diff --git a/engines/mohawk/riven_stack.h b/engines/mohawk/riven_stack.h index 0ef267e421..e2bee44851 100644 --- a/engines/mohawk/riven_stack.h +++ b/engines/mohawk/riven_stack.h @@ -23,6 +23,7 @@ #ifndef RIVEN_STACK_H #define RIVEN_STACK_H +#include "common/keyboard.h" #include "common/hash-str.h" #include "common/ptr.h" #include "common/rect.h" @@ -129,13 +130,22 @@ public: /** Force the left mouse button to be considered unpressed until the next mouse click */ void mouseForceUp(); + /** Handle a key press event */ + void onKeyPressed(const Common::KeyCode keyCode); + + /** Get the pressed keyboard key if any */ + Common::KeyCode keyGetPressed() const; + + /** Force the keyboard to be considered unpressed until the next key press */ + void keyForceUp(); + // Common external commands void xflies(uint16 argc, uint16 *argv); // Start the "flies" effect // TODO: Misc stuff move elsewhere uint16 getComboDigit(uint32 correctCombo, uint32 digit); void runDemoBoundaryDialog(); - void runEndGame(uint16 video, uint32 delay); + void runEndGame(uint16 videoCode, uint32 delay); void runCredits(uint16 video, uint32 delay); protected: @@ -171,6 +181,8 @@ private: CommandsMap _commands; + Common::KeyCode _keyPressed; + bool _mouseIsDown; Common::Point _mousePosition; Common::Point _mouseDragStartPosition; diff --git a/engines/mohawk/riven_stacks/aspit.cpp b/engines/mohawk/riven_stacks/aspit.cpp index 27b4c8939f..04173bb394 100644 --- a/engines/mohawk/riven_stacks/aspit.cpp +++ b/engines/mohawk/riven_stacks/aspit.cpp @@ -27,6 +27,7 @@ #include "mohawk/riven_graphics.h" #include "mohawk/riven_inventory.h" #include "mohawk/riven_sound.h" +#include "mohawk/riven_video.h" #include "common/translation.h" @@ -38,27 +39,27 @@ namespace RivenStacks { ASpit::ASpit(MohawkEngine_Riven *vm) : RivenStack(vm, kStackAspit) { - REGISTER_COMMAND(ASpit, xastartupbtnhide); - REGISTER_COMMAND(ASpit, xasetupcomplete); - REGISTER_COMMAND(ASpit, xaatrusopenbook); - REGISTER_COMMAND(ASpit, xaatrusbookback); - REGISTER_COMMAND(ASpit, xaatrusbookprevpage); - REGISTER_COMMAND(ASpit, xaatrusbooknextpage); - REGISTER_COMMAND(ASpit, xacathopenbook); - REGISTER_COMMAND(ASpit, xacathbookback); - REGISTER_COMMAND(ASpit, xacathbookprevpage); - REGISTER_COMMAND(ASpit, xacathbooknextpage); - REGISTER_COMMAND(ASpit, xtrapbookback); - REGISTER_COMMAND(ASpit, xatrapbookclose); - REGISTER_COMMAND(ASpit, xatrapbookopen); - REGISTER_COMMAND(ASpit, xarestoregame); - REGISTER_COMMAND(ASpit, xadisablemenureturn); - REGISTER_COMMAND(ASpit, xaenablemenureturn); - REGISTER_COMMAND(ASpit, xalaunchbrowser); - REGISTER_COMMAND(ASpit, xadisablemenuintro); - REGISTER_COMMAND(ASpit, xaenablemenuintro); - REGISTER_COMMAND(ASpit, xademoquit); - REGISTER_COMMAND(ASpit, xaexittomain); + REGISTER_COMMAND(ASpit, xastartupbtnhide); // Inaccurate but sufficient + REGISTER_COMMAND(ASpit, xasetupcomplete); // Inaccurate but sufficient + REGISTER_COMMAND(ASpit, xaatrusopenbook); // Done + REGISTER_COMMAND(ASpit, xaatrusbookback); // Done + REGISTER_COMMAND(ASpit, xaatrusbookprevpage); // Done + REGISTER_COMMAND(ASpit, xaatrusbooknextpage); // Done +// REGISTER_COMMAND(ASpit, xacathopenbook); +// REGISTER_COMMAND(ASpit, xacathbookback); +// REGISTER_COMMAND(ASpit, xacathbookprevpage); +// REGISTER_COMMAND(ASpit, xacathbooknextpage); +// REGISTER_COMMAND(ASpit, xtrapbookback); +// REGISTER_COMMAND(ASpit, xatrapbookclose); +// REGISTER_COMMAND(ASpit, xatrapbookopen); + REGISTER_COMMAND(ASpit, xarestoregame); // Done +// REGISTER_COMMAND(ASpit, xadisablemenureturn); +// REGISTER_COMMAND(ASpit, xaenablemenureturn); +// REGISTER_COMMAND(ASpit, xalaunchbrowser); +// REGISTER_COMMAND(ASpit, xadisablemenuintro); +// REGISTER_COMMAND(ASpit, xaenablemenuintro); +// REGISTER_COMMAND(ASpit, xademoquit); +// REGISTER_COMMAND(ASpit, xaexittomain); } void ASpit::xastartupbtnhide(uint16 argc, uint16 *argv) { @@ -69,8 +70,9 @@ void ASpit::xastartupbtnhide(uint16 argc, uint16 *argv) { void ASpit::xasetupcomplete(uint16 argc, uint16 *argv) { // The original game sets an ini entry to disable the setup button and use the // start button only. It's safe to ignore this part of the command. - _vm->_sound->stopSound(); - _vm->changeToCard(1); + uint16 menuCardId = getCardStackId(0xE2E); + RivenScriptPtr goToMenuScript = _vm->_scriptMan->createScriptFromData(1, kRivenCommandChangeCard, 1, menuCardId); + _vm->_scriptMan->runScript(goToMenuScript, false); } void ASpit::xaatrusopenbook(uint16 argc, uint16 *argv) { @@ -116,9 +118,7 @@ bool ASpit::pageTurn(RivenTransition transition) { else soundName = "aPage2"; - Common::String fullSoundName = Common::String::format("%d_%s_1", _vm->getCard()->getId(), soundName); - - _vm->_sound->playSound(fullSoundName, 51, true); + _vm->_sound->playCardSound(soundName, 51, true); // Now update the screen :) _vm->_gfx->scheduleTransition(transition); diff --git a/engines/mohawk/riven_stacks/bspit.cpp b/engines/mohawk/riven_stacks/bspit.cpp index c5fedd7a59..72aa2946a8 100644 --- a/engines/mohawk/riven_stacks/bspit.cpp +++ b/engines/mohawk/riven_stacks/bspit.cpp @@ -26,6 +26,7 @@ #include "mohawk/riven.h" #include "mohawk/riven_card.h" #include "mohawk/riven_graphics.h" +#include "mohawk/riven_video.h" #include "common/events.h" @@ -35,25 +36,25 @@ namespace RivenStacks { BSpit::BSpit(MohawkEngine_Riven *vm) : DomeSpit(vm, kStackBspit, "bSliders.190", "bSliderBG.190") { - REGISTER_COMMAND(BSpit, xblabopenbook); - REGISTER_COMMAND(BSpit, xblabbookprevpage); - REGISTER_COMMAND(BSpit, xblabbooknextpage); - REGISTER_COMMAND(BSpit, xsoundplug); - REGISTER_COMMAND(BSpit, xbchangeboiler); - REGISTER_COMMAND(BSpit, xbupdateboiler); - REGISTER_COMMAND(BSpit, xbsettrap); - REGISTER_COMMAND(BSpit, xbcheckcatch); - REGISTER_COMMAND(BSpit, xbait); - REGISTER_COMMAND(BSpit, xbfreeytram); - REGISTER_COMMAND(BSpit, xbaitplate); - REGISTER_COMMAND(BSpit, xbisland190_opencard); - REGISTER_COMMAND(BSpit, xbisland190_resetsliders); - REGISTER_COMMAND(BSpit, xbisland190_slidermd); - REGISTER_COMMAND(BSpit, xbisland190_slidermw); - REGISTER_COMMAND(BSpit, xbscpbtn); - REGISTER_COMMAND(BSpit, xbisland_domecheck); - REGISTER_COMMAND(BSpit, xvalvecontrol); - REGISTER_COMMAND(BSpit, xbchipper); +// REGISTER_COMMAND(BSpit, xblabopenbook); +// REGISTER_COMMAND(BSpit, xblabbookprevpage); +// REGISTER_COMMAND(BSpit, xblabbooknextpage); +// REGISTER_COMMAND(BSpit, xsoundplug); +// REGISTER_COMMAND(BSpit, xbchangeboiler); +// REGISTER_COMMAND(BSpit, xbupdateboiler); +// REGISTER_COMMAND(BSpit, xbsettrap); +// REGISTER_COMMAND(BSpit, xbcheckcatch); +// REGISTER_COMMAND(BSpit, xbait); +// REGISTER_COMMAND(BSpit, xbfreeytram); +// REGISTER_COMMAND(BSpit, xbaitplate); +// REGISTER_COMMAND(BSpit, xbisland190_opencard); +// REGISTER_COMMAND(BSpit, xbisland190_resetsliders); +// REGISTER_COMMAND(BSpit, xbisland190_slidermd); +// REGISTER_COMMAND(BSpit, xbisland190_slidermw); +// REGISTER_COMMAND(BSpit, xbscpbtn); +// REGISTER_COMMAND(BSpit, xbisland_domecheck); +// REGISTER_COMMAND(BSpit, xvalvecontrol); +// REGISTER_COMMAND(BSpit, xbchipper); } void BSpit::xblabopenbook(uint16 argc, uint16 *argv) { @@ -137,59 +138,59 @@ void BSpit::xbchangeboiler(uint16 argc, uint16 *argv) { uint32 platform = _vm->_vars["bblrgrt"]; // Stop any background videos - _vm->_video->stopVideos(); + _vm->_video->closeVideos(); if (argv[0] == 1) { // Water is filling/draining from the boiler if (water == 0) { if (platform == 1) - _vm->_video->activateMLST(_vm->getCard()->getMovie(12)); + _vm->getCard()->playMovie(12); else - _vm->_video->activateMLST(_vm->getCard()->getMovie(10)); + _vm->getCard()->playMovie(10); } else if (heat == 1) { if (platform == 1) - _vm->_video->activateMLST(_vm->getCard()->getMovie(22)); + _vm->getCard()->playMovie(22); else - _vm->_video->activateMLST(_vm->getCard()->getMovie(19)); + _vm->getCard()->playMovie(19); } else { if (platform == 1) - _vm->_video->activateMLST(_vm->getCard()->getMovie(16)); + _vm->getCard()->playMovie(16); else - _vm->_video->activateMLST(_vm->getCard()->getMovie(13)); + _vm->getCard()->playMovie(13); } } else if (argv[0] == 2 && water != 0) { if (heat == 1) { // Turning on the heat if (platform == 1) - _vm->_video->activateMLST(_vm->getCard()->getMovie(23)); + _vm->getCard()->playMovie(23); else - _vm->_video->activateMLST(_vm->getCard()->getMovie(20)); + _vm->getCard()->playMovie(20); } else { // Turning off the heat if (platform == 1) - _vm->_video->activateMLST(_vm->getCard()->getMovie(18)); + _vm->getCard()->playMovie(18); else - _vm->_video->activateMLST(_vm->getCard()->getMovie(15)); + _vm->getCard()->playMovie(15); } } else if (argv[0] == 3) { if (platform == 1) { // Lowering the platform if (water == 1) { if (heat == 1) - _vm->_video->activateMLST(_vm->getCard()->getMovie(24)); + _vm->getCard()->playMovie(24); else - _vm->_video->activateMLST(_vm->getCard()->getMovie(17)); + _vm->getCard()->playMovie(17); } else - _vm->_video->activateMLST(_vm->getCard()->getMovie(11)); + _vm->getCard()->playMovie(11); } else { // Raising the platform if (water == 1) { if (heat == 1) - _vm->_video->activateMLST(_vm->getCard()->getMovie(21)); + _vm->getCard()->playMovie(21); else - _vm->_video->activateMLST(_vm->getCard()->getMovie(14)); + _vm->getCard()->playMovie(14); } else - _vm->_video->activateMLST(_vm->getCard()->getMovie(9)); + _vm->getCard()->playMovie(9); } } @@ -198,26 +199,28 @@ void BSpit::xbchangeboiler(uint16 argc, uint16 *argv) { else if (argv[0] == 2) _vm->getCard()->playSound(1); - _vm->_cursor->setCursor(kRivenHideCursor); - _vm->_video->playMovieBlockingRiven(11); + RivenVideo *video = _vm->_video->openSlot(11); + video->playBlocking(); } void BSpit::xbupdateboiler(uint16 argc, uint16 *argv) { if (_vm->_vars["bheat"] != 0) { if (_vm->_vars["bblrgrt"] == 0) { - _vm->_video->activateMLST(_vm->getCard()->getMovie(8)); - _vm->_video->playMovieRiven(8); + _vm->getCard()->playMovie(8); } else { - _vm->_video->activateMLST(_vm->getCard()->getMovie(7)); - _vm->_video->playMovieRiven(7); + _vm->getCard()->playMovie(7); } } else { - VideoEntryPtr video = _vm->_video->findVideoRiven(7); - if (video) - video->setEnabled(false); - video = _vm->_video->findVideoRiven(8); - if (video) - video->setEnabled(false); + RivenVideo *video = _vm->_video->getSlot(7); + if (video) { + video->disable(); + video->stop(); + } + video = _vm->_video->getSlot(8); + if (video) { + video->disable(); + video->stop(); + } } } @@ -324,17 +327,22 @@ void BSpit::xbfreeytram(uint16 argc, uint16 *argv) { mlstId = 12; break; default: + // The original did rand(13, 14) mlstId = _vm->_rnd->getRandomNumberRng(13, 15); break; } - // Activate the MLST and play the video - _vm->_video->activateMLST(_vm->getCard()->getMovie(mlstId)); - _vm->_video->playMovieBlockingRiven(11); + // Play the video + _vm->getCard()->playMovie(mlstId); + RivenVideo *first = _vm->_video->openSlot(11); + first->playBlocking(); // Now play the second movie - _vm->_video->activateMLST(_vm->getCard()->getMovie(mlstId + 5)); - _vm->_video->playMovieBlockingRiven(12); + _vm->getCard()->playMovie(mlstId + 5); + RivenVideo *second = _vm->_video->openSlot(12); + second->playBlocking(); + + _vm->getCard()->drawPicture(4); } void BSpit::xbaitplate(uint16 argc, uint16 *argv) { @@ -432,27 +440,31 @@ void BSpit::xvalvecontrol(uint16 argc, uint16 *argv) { valve = 1; _vm->_cursor->setCursor(kRivenHideCursor); _vm->_system->updateScreen(); - _vm->_video->playMovieBlockingRiven(2); + RivenVideo *video = _vm->_video->openSlot(2); + video->playBlocking(); _vm->refreshCard(); } else if (valve == 1) { if (changeX >= 0 && changeY >= 10) { valve = 0; _vm->_cursor->setCursor(kRivenHideCursor); _vm->_system->updateScreen(); - _vm->_video->playMovieBlockingRiven(3); + RivenVideo *video = _vm->_video->openSlot(3); + video->playBlocking(); _vm->refreshCard(); } else if (changeX <= -10 && changeY <= 10) { valve = 2; _vm->_cursor->setCursor(kRivenHideCursor); _vm->_system->updateScreen(); - _vm->_video->playMovieBlockingRiven(1); + RivenVideo *video = _vm->_video->openSlot(1); + video->playBlocking(); _vm->refreshCard(); } } else if (valve == 2 && changeX >= 10) { valve = 1; _vm->_cursor->setCursor(kRivenHideCursor); _vm->_system->updateScreen(); - _vm->_video->playMovieBlockingRiven(4); + RivenVideo *video = _vm->_video->openSlot(4); + video->playBlocking(); _vm->refreshCard(); } done = true; @@ -485,8 +497,10 @@ void BSpit::xvalvecontrol(uint16 argc, uint16 *argv) { void BSpit::xbchipper(uint16 argc, uint16 *argv) { // Why is this an external command....? - if (_vm->_vars["bvalve"] == 2) - _vm->_video->playMovieBlockingRiven(2); + if (_vm->_vars["bvalve"] == 2) { + RivenVideo *video = _vm->_video->openSlot(2); + video->playBlocking(); + } } } // End of namespace RivenStacks diff --git a/engines/mohawk/riven_stacks/domespit.cpp b/engines/mohawk/riven_stacks/domespit.cpp index 6a1d26bf11..7aaa7d6b6b 100644 --- a/engines/mohawk/riven_stacks/domespit.cpp +++ b/engines/mohawk/riven_stacks/domespit.cpp @@ -26,6 +26,7 @@ #include "mohawk/riven.h" #include "mohawk/riven_card.h" #include "mohawk/riven_graphics.h" +#include "mohawk/riven_video.h" #include "common/events.h" @@ -44,13 +45,15 @@ DomeSpit::DomeSpit(MohawkEngine_Riven *vm, uint16 id, const char *sliderBmpName, void DomeSpit::runDomeButtonMovie() { // This command just plays the video of the button moving down and up. - _vm->_video->playMovieBlockingRiven(2); + // The original displayed images of the button going down + RivenVideo *video = _vm->_video->openSlot(2); + video->playBlocking(); } void DomeSpit::runDomeCheck() { // Check if we clicked while the golden frame was showing - VideoEntryPtr video = _vm->_video->findVideoRiven(1); + const RivenVideo *video = _vm->_video->getSlot(1); assert(video); int32 curFrame = video->getCurFrame(); diff --git a/engines/mohawk/riven_stacks/gspit.cpp b/engines/mohawk/riven_stacks/gspit.cpp index 836dd272fc..dd41e62cf2 100644 --- a/engines/mohawk/riven_stacks/gspit.cpp +++ b/engines/mohawk/riven_stacks/gspit.cpp @@ -26,6 +26,7 @@ #include "mohawk/riven.h" #include "mohawk/riven_card.h" #include "mohawk/riven_sound.h" +#include "mohawk/riven_video.h" #include "common/events.h" @@ -35,26 +36,26 @@ namespace RivenStacks { GSpit::GSpit(MohawkEngine_Riven *vm) : DomeSpit(vm, kStackGspit, "gsliders.190", "gsliderbg.190") { - REGISTER_COMMAND(GSpit, xgresetpins); - REGISTER_COMMAND(GSpit, xgrotatepins); - REGISTER_COMMAND(GSpit, xgpincontrols); - REGISTER_COMMAND(GSpit, xgisland25_opencard); - REGISTER_COMMAND(GSpit, xgisland25_resetsliders); - REGISTER_COMMAND(GSpit, xgisland25_slidermd); - REGISTER_COMMAND(GSpit, xgisland25_slidermw); - REGISTER_COMMAND(GSpit, xgscpbtn); - REGISTER_COMMAND(GSpit, xgisland1490_domecheck); - REGISTER_COMMAND(GSpit, xgplateau3160_dopools); - REGISTER_COMMAND(GSpit, xgwt200_scribetime); - REGISTER_COMMAND(GSpit, xgwt900_scribe); - REGISTER_COMMAND(GSpit, xgplaywhark); - REGISTER_COMMAND(GSpit, xgrviewer); - REGISTER_COMMAND(GSpit, xgwharksnd); - REGISTER_COMMAND(GSpit, xglview_prisonoff); - REGISTER_COMMAND(GSpit, xglview_villageoff); - REGISTER_COMMAND(GSpit, xglviewer); - REGISTER_COMMAND(GSpit, xglview_prisonon); - REGISTER_COMMAND(GSpit, xglview_villageon); +// REGISTER_COMMAND(GSpit, xgresetpins); +// REGISTER_COMMAND(GSpit, xgrotatepins); +// REGISTER_COMMAND(GSpit, xgpincontrols); +// REGISTER_COMMAND(GSpit, xgisland25_opencard); +// REGISTER_COMMAND(GSpit, xgisland25_resetsliders); +// REGISTER_COMMAND(GSpit, xgisland25_slidermd); +// REGISTER_COMMAND(GSpit, xgisland25_slidermw); +// REGISTER_COMMAND(GSpit, xgscpbtn); +// REGISTER_COMMAND(GSpit, xgisland1490_domecheck); +// REGISTER_COMMAND(GSpit, xgplateau3160_dopools); +// REGISTER_COMMAND(GSpit, xgwt200_scribetime); +// REGISTER_COMMAND(GSpit, xgwt900_scribe); +// REGISTER_COMMAND(GSpit, xgplaywhark); +// REGISTER_COMMAND(GSpit, xgrviewer); +// REGISTER_COMMAND(GSpit, xgwharksnd); +// REGISTER_COMMAND(GSpit, xglview_prisonoff); +// REGISTER_COMMAND(GSpit, xglview_villageoff); +// REGISTER_COMMAND(GSpit, xglviewer); +// REGISTER_COMMAND(GSpit, xglview_prisonon); +// REGISTER_COMMAND(GSpit, xglview_villageon); } void GSpit::lowerPins() { @@ -75,10 +76,10 @@ void GSpit::lowerPins() { uint32 &upMovie = _vm->_vars["gupmoov"]; // Play the video of the pins going down - VideoEntryPtr handle = _vm->_video->playMovieRiven(upMovie); - assert(handle); - handle->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 550, 600)); - _vm->_video->waitUntilMovieEnds(handle); + RivenVideo *video = _vm->_video->openSlot(upMovie); + assert(video); + video->setBounds(startTime, startTime + 550); + video->playBlocking(); upMovie = 0; } @@ -107,10 +108,10 @@ void GSpit::xgrotatepins(uint16 argc, uint16 *argv) { _vm->_sound->playSound(12); // Play the video of the pins rotating - VideoEntryPtr handle = _vm->_video->playMovieRiven(_vm->_vars["gupmoov"]); - assert(handle); - handle->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 1215, 600)); - _vm->_video->waitUntilMovieEnds(handle); + RivenVideo *video = _vm->_video->openSlot(_vm->_vars["gupmoov"]); + assert(video); + video->setBounds(startTime, startTime + 1215); + video->playBlocking(); } void GSpit::xgpincontrols(uint16 argc, uint16 *argv) { @@ -193,11 +194,11 @@ void GSpit::xgpincontrols(uint16 argc, uint16 *argv) { _vm->_sound->playSound(14); // Actually play the movie - VideoEntryPtr handle = _vm->_video->playMovieRiven(pinMovieCodes[imagePos - 1]); + RivenVideo *handle = _vm->_video->openSlot(pinMovieCodes[imagePos - 1]); assert(handle); uint32 startTime = 9630 - pinPos * 600; - handle->setBounds(Audio::Timestamp(0, startTime, 600), Audio::Timestamp(0, startTime + 550, 600)); - _vm->_video->waitUntilMovieEnds(handle); + handle->setBounds(startTime, startTime + 550); + handle->playBlocking(); // Update the relevant variables _vm->_vars["gupmoov"] = pinMovieCodes[imagePos - 1]; @@ -233,7 +234,8 @@ void GSpit::xgplateau3160_dopools(uint16 argc, uint16 *argv) { // Play the deactivation of a pool if one is active and a different one is activated _vm->_cursor->setCursor(kRivenHideCursor); _vm->_system->updateScreen(); - _vm->_video->playMovieBlockingRiven(_vm->_vars["glkbtns"] * 2); + RivenVideo *video = _vm->_video->openSlot(_vm->_vars["glkbtns"] * 2); + video->playBlocking(); } void GSpit::xgwt200_scribetime(uint16 argc, uint16 *argv) { @@ -273,10 +275,10 @@ void GSpit::xgrviewer(uint16 argc, uint16 *argv) { uint32 newPos = curPos + buttonPos; // Now play the movie - VideoEntryPtr handle = _vm->_video->playMovieRiven(1); - assert(handle); - handle->setBounds(Audio::Timestamp(0, s_viewerTimeIntervals[curPos], 600), Audio::Timestamp(0, s_viewerTimeIntervals[newPos], 600)); - _vm->_video->waitUntilMovieEnds(handle); + RivenVideo *video = _vm->_video->openSlot(1); + assert(video); + video->setBounds(s_viewerTimeIntervals[curPos], s_viewerTimeIntervals[newPos]); + video->playBlocking(); // Set the new position and let the card's scripts take over again curPos = newPos % 6; // Clip it to 0-5 @@ -307,24 +309,25 @@ void GSpit::xgplaywhark(uint16 argc, uint16 *argv) { // Activate the correct video based on the amount of times we've been visited switch (wharkVisits) { case 1: - _vm->_video->activateMLST(_vm->getCard()->getMovie(3)); + _vm->getCard()->playMovie(3); break; case 2: // One of two random videos - _vm->_video->activateMLST(_vm->getCard()->getMovie(4 + _vm->_rnd->getRandomBit())); + _vm->getCard()->playMovie(4 + _vm->_rnd->getRandomBit()); break; case 3: // One of two random videos - _vm->_video->activateMLST(_vm->getCard()->getMovie(6 + _vm->_rnd->getRandomBit())); + _vm->getCard()->playMovie(6 + _vm->_rnd->getRandomBit()); break; case 4: // Red alert! Shields online! Brace yourself for impact! - _vm->_video->activateMLST(_vm->getCard()->getMovie(8)); + _vm->getCard()->playMovie(8); break; } // For whatever reason the devs felt fit, code 31 is used for all of the videos - _vm->_video->playMovieBlockingRiven(31); + RivenVideo *video = _vm->_video->openSlot(31); + video->playBlocking(); _vm->refreshCard(); } @@ -344,10 +347,10 @@ void GSpit::xglviewer(uint16 argc, uint16 *argv) { uint32 newPos = curPos + buttonPos; // Now play the movie - VideoEntryPtr handle = _vm->_video->playMovieRiven(1); - assert(handle); - handle->setBounds(Audio::Timestamp(0, s_viewerTimeIntervals[curPos], 600), Audio::Timestamp(0, s_viewerTimeIntervals[newPos], 600)); - _vm->_video->waitUntilMovieEnds(handle); + RivenVideo *video = _vm->_video->openSlot(1); + assert(video); + video->setBounds(s_viewerTimeIntervals[curPos], s_viewerTimeIntervals[newPos]); + video->playBlocking(); // Set the new position to the variable curPos = newPos % 6; // Clip it to 0-5 @@ -393,11 +396,12 @@ void GSpit::catherineViewerIdleTimer() { cathState = 3; // Begin playing the new movie - _vm->_video->activateMLST(_vm->getCard()->getMovie(movie)); - VideoEntryPtr video = _vm->_video->playMovieRiven(30); + _vm->getCard()->playMovie(movie); + RivenVideo *video = _vm->_video->openSlot(30); + video->play(); // Reset the timer - _vm->installTimer(TIMER(GSpit, catherineViewerIdleTimer), video->getDuration().msecs() + _vm->_rnd->getRandomNumber(60) * 1000); + _vm->installTimer(TIMER(GSpit, catherineViewerIdleTimer), video->getDuration() + _vm->_rnd->getRandomNumber(60) * 1000); } void GSpit::xglview_prisonon(uint16 argc, uint16 *argv) { @@ -427,17 +431,19 @@ void GSpit::xglview_prisonon(uint16 argc, uint16 *argv) { // Turn on the viewer _vm->_cursor->hideCursor(); - _vm->_video->playMovieBlockingRiven(turnOnMovie); + RivenVideo *turnOn = _vm->_video->openSlot(turnOnMovie); + turnOn->playBlocking(); _vm->_cursor->showCursor(); uint32 timeUntilNextMovie; // Begin playing a movie immediately if Catherine is already in the viewer if (cathMovie == 8 || (cathMovie >= 13 && cathMovie <= 16)) { - _vm->_video->activateMLST(_vm->getCard()->getMovie(cathMovie)); - VideoEntryPtr video = _vm->_video->playMovieRiven(30); + _vm->getCard()->playMovie(cathMovie); + RivenVideo *video = _vm->_video->openSlot(30); + video->play(); - timeUntilNextMovie = video->getDuration().msecs() + _vm->_rnd->getRandomNumber(60) * 1000; + timeUntilNextMovie = video->getDuration() + _vm->_rnd->getRandomNumber(60) * 1000; } else { // Otherwise, just redraw the imager timeUntilNextMovie = _vm->_rnd->getRandomNumberRng(10, 20) * 1000; @@ -458,9 +464,10 @@ void GSpit::xglview_prisonoff(uint16 argc, uint16 *argv) { _vm->removeTimer(); // Play the 'turn off' movie after stopping any videos still playing - _vm->_video->stopVideos(); + _vm->_video->closeVideos(); _vm->_cursor->hideCursor(); - _vm->_video->playMovieBlockingRiven(5); + RivenVideo *video = _vm->_video->openSlot(5); + video->playBlocking(); _vm->_cursor->showCursor(); // Redraw the viewer diff --git a/engines/mohawk/riven_stacks/jspit.cpp b/engines/mohawk/riven_stacks/jspit.cpp index 1df55017a9..81994e3f3a 100644 --- a/engines/mohawk/riven_stacks/jspit.cpp +++ b/engines/mohawk/riven_stacks/jspit.cpp @@ -35,35 +35,35 @@ namespace RivenStacks { JSpit::JSpit(MohawkEngine_Riven *vm) : DomeSpit(vm, kStackJspit, "jsliders.190", "jsliderbg.190") { - REGISTER_COMMAND(JSpit, xreseticons); - REGISTER_COMMAND(JSpit, xicon); - REGISTER_COMMAND(JSpit, xcheckicons); - REGISTER_COMMAND(JSpit, xtoggleicon); - REGISTER_COMMAND(JSpit, xjtunnel103_pictfix); - REGISTER_COMMAND(JSpit, xjtunnel104_pictfix); - REGISTER_COMMAND(JSpit, xjtunnel105_pictfix); - REGISTER_COMMAND(JSpit, xjtunnel106_pictfix); - REGISTER_COMMAND(JSpit, xvga1300_carriage); - REGISTER_COMMAND(JSpit, xjdome25_resetsliders); - REGISTER_COMMAND(JSpit, xjdome25_slidermd); - REGISTER_COMMAND(JSpit, xjdome25_slidermw); - REGISTER_COMMAND(JSpit, xjscpbtn); - REGISTER_COMMAND(JSpit, xjisland3500_domecheck); - REGISTER_COMMAND(JSpit, xhandlecontroldown); - REGISTER_COMMAND(JSpit, xhandlecontrolmid); - REGISTER_COMMAND(JSpit, xhandlecontrolup); - REGISTER_COMMAND(JSpit, xjplaybeetle_550); - REGISTER_COMMAND(JSpit, xjplaybeetle_600); - REGISTER_COMMAND(JSpit, xjplaybeetle_950); - REGISTER_COMMAND(JSpit, xjplaybeetle_1050); - REGISTER_COMMAND(JSpit, xjplaybeetle_1450); - REGISTER_COMMAND(JSpit, xjlagoon700_alert); - REGISTER_COMMAND(JSpit, xjlagoon800_alert); - REGISTER_COMMAND(JSpit, xjlagoon1500_alert); - REGISTER_COMMAND(JSpit, xschool280_playwhark); - REGISTER_COMMAND(JSpit, xjschool280_resetleft); - REGISTER_COMMAND(JSpit, xjschool280_resetright); - REGISTER_COMMAND(JSpit, xjatboundary); +// REGISTER_COMMAND(JSpit, xreseticons); +// REGISTER_COMMAND(JSpit, xicon); +// REGISTER_COMMAND(JSpit, xcheckicons); +// REGISTER_COMMAND(JSpit, xtoggleicon); +// REGISTER_COMMAND(JSpit, xjtunnel103_pictfix); +// REGISTER_COMMAND(JSpit, xjtunnel104_pictfix); +// REGISTER_COMMAND(JSpit, xjtunnel105_pictfix); +// REGISTER_COMMAND(JSpit, xjtunnel106_pictfix); +// REGISTER_COMMAND(JSpit, xvga1300_carriage); +// REGISTER_COMMAND(JSpit, xjdome25_resetsliders); +// REGISTER_COMMAND(JSpit, xjdome25_slidermd); +// REGISTER_COMMAND(JSpit, xjdome25_slidermw); +// REGISTER_COMMAND(JSpit, xjscpbtn); +// REGISTER_COMMAND(JSpit, xjisland3500_domecheck); +// REGISTER_COMMAND(JSpit, xhandlecontroldown); +// REGISTER_COMMAND(JSpit, xhandlecontrolmid); +// REGISTER_COMMAND(JSpit, xhandlecontrolup); +// REGISTER_COMMAND(JSpit, xjplaybeetle_550); +// REGISTER_COMMAND(JSpit, xjplaybeetle_600); +// REGISTER_COMMAND(JSpit, xjplaybeetle_950); +// REGISTER_COMMAND(JSpit, xjplaybeetle_1050); +// REGISTER_COMMAND(JSpit, xjplaybeetle_1450); +// REGISTER_COMMAND(JSpit, xjlagoon700_alert); +// REGISTER_COMMAND(JSpit, xjlagoon800_alert); +// REGISTER_COMMAND(JSpit, xjlagoon1500_alert); +// REGISTER_COMMAND(JSpit, xschool280_playwhark); +// REGISTER_COMMAND(JSpit, xjschool280_resetleft); +// REGISTER_COMMAND(JSpit, xjschool280_resetright); +// REGISTER_COMMAND(JSpit, xjatboundary); } void JSpit::xreseticons(uint16 argc, uint16 *argv) { @@ -224,19 +224,23 @@ void JSpit::xvga1300_carriage(uint16 argc, uint16 *argv) { _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor _vm->_system->updateScreen(); // Update - _vm->_video->playMovieBlockingRiven(1); // Play handle movie + RivenVideo *handleVideo = _vm->_video->openSlot(1); // Play handle movie + handleVideo->playBlocking(); _vm->_gfx->scheduleTransition(kRivenTransitionPanDown); _vm->changeToCard(_vm->getStack()->getCardStackId(0x18e77)); // Change to card facing up _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor (again) _vm->_system->updateScreen(); // Update - _vm->_video->playMovieBlockingRiven(4); // Play carriage beginning to drop + RivenVideo *beginDropVideo = _vm->_video->openSlot(4); // Play carriage beginning to drop + beginDropVideo->playBlocking(); _vm->_gfx->scheduleTransition(kRivenTransitionPanUp); _vm->changeToCard(_vm->getStack()->getCardStackId(0x183a9)); // Change to card looking straight again - _vm->_video->playMovieBlockingRiven(2); + RivenVideo *video = _vm->_video->openSlot(2); + video->playBlocking(); if (_vm->_vars["jgallows"] == 1) { // If the gallows is open, play the up movie and return - _vm->_video->playMovieBlockingRiven(3); + RivenVideo *upVideo = _vm->_video->openSlot(3); + upVideo->playBlocking(); return; } @@ -274,10 +278,14 @@ void JSpit::xvga1300_carriage(uint16 argc, uint16 *argv) { _vm->changeToCard(_vm->getStack()->getCardStackId(0x18ab5)); // Turn right _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor _vm->_system->updateScreen(); // Update - _vm->_video->playMovieBlockingRiven(1); // Play carriage ride movie + RivenVideo *rideVideo = _vm->_video->openSlot(1); // Play carriage ride movie + rideVideo->playBlocking(); _vm->changeToCard(_vm->getStack()->getCardStackId(0x17167)); // We have arrived at the top - } else - _vm->_video->playMovieBlockingRiven(3); // Too slow! + } else { + + RivenVideo *tooSlowVideo = _vm->_video->openSlot(3); // Too slow! + tooSlowVideo->playBlocking(); + } } void JSpit::xjdome25_resetsliders(uint16 argc, uint16 *argv) { @@ -339,8 +347,10 @@ void JSpit::xhandlecontrolup(uint16 argc, uint16 *argv) { // If we've moved the handle down, go down a floor if (changeLevel == -1) { - _vm->_video->playMovieBlockingRiven(1); - _vm->_video->playMovieBlockingRiven(2); + RivenVideo *firstVideo = _vm->_video->openSlot(1); + firstVideo->playBlocking(); + RivenVideo *secondVideo = _vm->_video->openSlot(2); + secondVideo->playBlocking(); _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e374)); } } @@ -350,8 +360,10 @@ void JSpit::xhandlecontroldown(uint16 argc, uint16 *argv) { // If we've moved the handle up, go up a floor if (changeLevel == 1) { - _vm->_video->playMovieBlockingRiven(1); - _vm->_video->playMovieBlockingRiven(2); + RivenVideo *firstVideo = _vm->_video->openSlot(1); + firstVideo->playBlocking(); + RivenVideo *secondVideo = _vm->_video->openSlot(2); + secondVideo->playBlocking(); _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e374)); } } @@ -363,25 +375,31 @@ void JSpit::xhandlecontrolmid(uint16 argc, uint16 *argv) { return; // Play the handle moving video + RivenVideo *handleVideo; if (changeLevel == 1) - _vm->_video->playMovieBlockingRiven(7); + handleVideo = _vm->_video->openSlot(7); else - _vm->_video->playMovieBlockingRiven(6); + handleVideo = _vm->_video->openSlot(6); + handleVideo->playBlocking(); // If the whark's mouth is open, close it uint32 &mouthVar = _vm->_vars["jwmouth"]; if (mouthVar == 1) { - _vm->_video->playMovieBlockingRiven(3); - _vm->_video->playMovieBlockingRiven(8); + RivenVideo *closeVideo1 = _vm->_video->openSlot(3); + closeVideo1->playBlocking(); + RivenVideo *closeVideo2 = _vm->_video->openSlot(8); + closeVideo2->playBlocking(); mouthVar = 0; } // Play the elevator video and then change the card if (changeLevel == 1) { - _vm->_video->playMovieBlockingRiven(5); + RivenVideo *elevatorVideo = _vm->_video->openSlot(5); + elevatorVideo->playBlocking(); _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e597)); } else { - _vm->_video->playMovieBlockingRiven(4); + RivenVideo *elevatorVideo = _vm->_video->openSlot(4); + elevatorVideo->playBlocking(); _vm->changeToCard(_vm->getStack()->getCardStackId(0x1e29c)); } } @@ -420,7 +438,7 @@ void JSpit::xjlagoon700_alert(uint16 argc, uint16 *argv) { return; } - VideoEntryPtr sunnerAlertVideo = _vm->_video->playMovieRiven(1); + RivenVideo *sunnerAlertVideo = _vm->_video->openSlot(1); // Wait for a click while the alert video is playing sunnersPlayVideo(sunnerAlertVideo, 0x7BEB); @@ -433,14 +451,16 @@ void JSpit::xjlagoon800_alert(uint16 argc, uint16 *argv) { if (sunners == 0) { // Show the sunners alert video - VideoEntryPtr sunnerAlertVideo = _vm->_video->playMovieRiven(1); + RivenVideo *sunnerAlertVideo = _vm->_video->openSlot(1); // Wait for a click while the alert video is playing sunnersPlayVideo(sunnerAlertVideo, 0xB6CA); } else if (sunners == 1) { // Show the sunners leaving if you moved forward in their "alert" status - _vm->_video->playMovieBlockingRiven(2); - _vm->_video->playMovieBlockingRiven(6); + RivenVideo *leaving1 = _vm->_video->openSlot(2); + leaving1->playBlocking(); + RivenVideo *leaving2 = _vm->_video->openSlot(6); + leaving2->playBlocking(); sunners = 2; _vm->refreshCard(); } @@ -453,19 +473,22 @@ void JSpit::xjlagoon1500_alert(uint16 argc, uint16 *argv) { if (sunners == 0) { // Show the sunners alert video - _vm->_video->playMovieBlockingRiven(3); + RivenVideo *alertVideo = _vm->_video->openSlot(3); + alertVideo->playBlocking(); } else if (sunners == 1) { // Show the sunners leaving if you moved forward in their "alert" status - _vm->_video->playMovieBlockingRiven(2); + RivenVideo *leavingVideo = _vm->_video->openSlot(2); + leavingVideo->playBlocking(); sunners = 2; _vm->refreshCard(); } } -void JSpit::sunnersPlayVideo(VideoEntryPtr &video, uint32 destCardGlobalId) { +void JSpit::sunnersPlayVideo(RivenVideo *video, uint32 destCardGlobalId) { uint32 &sunners = _vm->_vars["jsunners"]; mouseForceUp(); + video->play(); while (!video->endOfVideo() && !_vm->shouldQuit()) { _vm->doFrame(); @@ -491,7 +514,7 @@ void JSpit::sunnersTopStairsTimer() { // 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); + RivenVideo *oldVideo = _vm->_video->getSlot(1); uint32 timerTime = 500; if (!oldVideo || oldVideo->endOfVideo()) { @@ -500,9 +523,10 @@ void JSpit::sunnersTopStairsTimer() { 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)); + RivenVideo *video = _vm->_video->openSlot(_vm->_rnd->getRandomNumberRng(1, 3)); + video->play(); - timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(2, 15) * 1000; + timerTime = video->getDuration() + _vm->_rnd->getRandomNumberRng(2, 15) * 1000; } sunnerTime = timerTime + _vm->getTotalPlayTime(); @@ -521,7 +545,7 @@ void JSpit::sunnersMidStairsTimer() { // 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); + RivenVideo *oldVideo = _vm->_video->getSlot(1); uint32 timerTime = 500; if (!oldVideo || oldVideo->endOfVideo()) { @@ -538,9 +562,10 @@ void JSpit::sunnersMidStairsTimer() { else if (randValue == 5) movie = 3; - VideoEntryPtr video = _vm->_video->playMovieRiven(movie); + RivenVideo *video = _vm->_video->openSlot(movie); + video->play(); - timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(1, 10) * 1000; + timerTime = video->getDuration() + _vm->_rnd->getRandomNumberRng(1, 10) * 1000; } sunnerTime = timerTime + _vm->getTotalPlayTime(); @@ -559,7 +584,7 @@ void JSpit::sunnersLowerStairsTimer() { // 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); + RivenVideo *oldVideo = _vm->_video->getSlot(1); uint32 timerTime = 500; if (!oldVideo || oldVideo->endOfVideo()) { @@ -568,9 +593,10 @@ void JSpit::sunnersLowerStairsTimer() { 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)); + RivenVideo *video = _vm->_video->openSlot(_vm->_rnd->getRandomNumberRng(3, 5)); + video->play(); - timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(1, 30) * 1000; + timerTime = video->getDuration() + _vm->_rnd->getRandomNumberRng(1, 30) * 1000; } sunnerTime = timerTime + _vm->getTotalPlayTime(); @@ -589,7 +615,7 @@ void JSpit::sunnersBeachTimer() { // 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); + RivenVideo *oldvideo = _vm->_video->getSlot(3); uint32 timerTime = 500; if (!oldvideo || oldvideo->endOfVideo()) { @@ -601,10 +627,11 @@ void JSpit::sunnersBeachTimer() { // 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); + _vm->getCard()->playMovie(mlstID); + RivenVideo *video = _vm->_video->openSlot(mlstID); + video->play(); - timerTime = video->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(1, 30) * 1000; + timerTime = video->getDuration() + _vm->_rnd->getRandomNumberRng(1, 30) * 1000; } sunnerTime = timerTime + _vm->getTotalPlayTime(); @@ -658,7 +685,8 @@ void JSpit::xschool280_playwhark(uint16 argc, uint16 *argv) { _vm->_system->updateScreen(); // Play the spin movie - _vm->_video->playMovieBlockingRiven(spinMLST); + RivenVideo *spinVideo = _vm->_video->openSlot(spinMLST); + spinVideo->playBlocking(); // Get our random number and redraw the area uint16 number = _vm->_rnd->getRandomNumberRng(1, 10); @@ -667,16 +695,17 @@ void JSpit::xschool280_playwhark(uint16 argc, uint16 *argv) { // Handle movement // (11560/600)s is the length of each of the two movies. We divide it into 19 parts // (one for each of the possible positions the villager can have). - VideoEntryPtr handle = _vm->_video->playMovieRiven(doomMLST); - Audio::Timestamp startTime = Audio::Timestamp(0, (11560 / 19) * (*posVar), 600); + RivenVideo *video = _vm->_video->openSlot(doomMLST); + uint32 startTime = (11560 / 19) * (*posVar); *posVar += number; // Adjust to the end - Audio::Timestamp endTime = Audio::Timestamp(0, (11560 / 19) * (*posVar), 600); - handle->setBounds(startTime, endTime); - _vm->_video->waitUntilMovieEnds(handle); + uint32 endTime = (11560 / 19) * (*posVar); + video->setBounds(startTime, endTime); + video->playBlocking(); if (*posVar > 19) { // The villager has died :( - _vm->_video->playMovieBlockingRiven(snackMLST); + RivenVideo *snackVideo = _vm->_video->openSlot(snackMLST); + snackVideo->playBlocking(); redrawWharkNumberPuzzle(overlayPLST, number); *posVar = 0; } diff --git a/engines/mohawk/riven_stacks/jspit.h b/engines/mohawk/riven_stacks/jspit.h index 9ce32bc4fe..9bd35a59b5 100644 --- a/engines/mohawk/riven_stacks/jspit.h +++ b/engines/mohawk/riven_stacks/jspit.h @@ -24,7 +24,7 @@ #define RIVEN_STACKS_JSPIT_H #include "mohawk/riven_stacks/domespit.h" -#include "mohawk/video.h" +#include "mohawk/riven_video.h" namespace Mohawk { namespace RivenStacks { @@ -94,7 +94,7 @@ private: int jspitElevatorLoop(); void redrawWharkNumberPuzzle(uint16 overlay, uint16 number); - void sunnersPlayVideo(VideoEntryPtr &video, uint32 destCardGlobalId); + void sunnersPlayVideo(RivenVideo *video, uint32 destCardGlobalId); }; } // End of namespace RivenStacks diff --git a/engines/mohawk/riven_stacks/ospit.cpp b/engines/mohawk/riven_stacks/ospit.cpp index 12328de744..82e2d34e2f 100644 --- a/engines/mohawk/riven_stacks/ospit.cpp +++ b/engines/mohawk/riven_stacks/ospit.cpp @@ -26,6 +26,7 @@ #include "mohawk/riven.h" #include "mohawk/riven_card.h" #include "mohawk/riven_graphics.h" +#include "mohawk/riven_video.h" #include "common/events.h" @@ -35,14 +36,14 @@ namespace RivenStacks { OSpit::OSpit(MohawkEngine_Riven *vm) : RivenStack(vm, kStackOspit) { - REGISTER_COMMAND(OSpit, xorollcredittime); - REGISTER_COMMAND(OSpit, xbookclick); - REGISTER_COMMAND(OSpit, xooffice30_closebook); - REGISTER_COMMAND(OSpit, xobedroom5_closedrawer); - REGISTER_COMMAND(OSpit, xogehnopenbook); - REGISTER_COMMAND(OSpit, xogehnbookprevpage); - REGISTER_COMMAND(OSpit, xogehnbooknextpage); - REGISTER_COMMAND(OSpit, xgwatch); +// REGISTER_COMMAND(OSpit, xorollcredittime); +// REGISTER_COMMAND(OSpit, xbookclick); +// REGISTER_COMMAND(OSpit, xooffice30_closebook); +// REGISTER_COMMAND(OSpit, xobedroom5_closedrawer); +// REGISTER_COMMAND(OSpit, xogehnopenbook); +// REGISTER_COMMAND(OSpit, xogehnbookprevpage); +// REGISTER_COMMAND(OSpit, xogehnbooknextpage); +// REGISTER_COMMAND(OSpit, xgwatch); } void OSpit::xorollcredittime(uint16 argc, uint16 *argv) { @@ -72,7 +73,7 @@ void OSpit::xbookclick(uint16 argc, uint16 *argv) { _vm->_system->updateScreen(); // Let's hook onto our video - VideoEntryPtr video = _vm->_video->findVideoRiven(argv[0]); + RivenVideo *video = _vm->_video->getSlot(argv[0]); // Convert from the standard QuickTime base time to milliseconds // The values are in terms of 1/600 of a second. @@ -93,8 +94,8 @@ void OSpit::xbookclick(uint16 argc, uint16 *argv) { // Just let the video play while we wait until Gehn opens the trap book for us while (video->getTime() < startTime && !_vm->shouldQuit()) { - if (_vm->_video->updateMovies()) - _vm->_system->updateScreen(); + _vm->_video->updateMovies(); + _vm->_system->updateScreen(); Common::Event event; while (_vm->_system->getEventManager()->pollEvent(event)) @@ -118,7 +119,7 @@ void OSpit::xbookclick(uint16 argc, uint16 *argv) { // OK, Gehn has opened the trap book and has asked us to go in. Let's watch // and see what the player will do... while (video->getTime() < endTime && !_vm->shouldQuit()) { - bool updateScreen = _vm->_video->updateMovies(); + _vm->_video->updateMovies(); Common::Event event; while (_vm->_system->getEventManager()->pollEvent(event)) { @@ -128,18 +129,18 @@ void OSpit::xbookclick(uint16 argc, uint16 *argv) { _vm->_cursor->setCursor(kRivenOpenHandCursor); else _vm->_cursor->setCursor(kRivenMainCursor); - updateScreen = true; break; case Common::EVENT_LBUTTONUP: if (hotspotRect.contains(_vm->_system->getEventManager()->getMousePos())) { // OK, we've used the trap book! We go for ride lady! _vm->_scriptMan->stopAllScripts(); // Stop all running scripts (so we don't remain in the cage) - _vm->_video->stopVideos(); // Stop all videos + _vm->_video->closeVideos(); // Stop all videos _vm->_cursor->setCursor(kRivenHideCursor); // Hide the cursor _vm->getCard()->drawPicture(3); // Black out the screen _vm->_sound->playSound(0); // Play the link sound - _vm->_video->activateMLST(_vm->getCard()->getMovie(7)); // Activate Gehn Link Video - _vm->_video->playMovieBlockingRiven(1); // Play Gehn Link Video + _vm->getCard()->playMovie(7); // Activate Gehn Link Video + RivenVideo *linkVideo = _vm->_video->openSlot(1); // Play Gehn Link Video + linkVideo->playBlocking(); _vm->_vars["agehn"] = 4; // Set Gehn to the trapped state _vm->_vars["atrapbook"] = 1; // We've got the trap book again _vm->_sound->playSound(0); // Play the link sound again @@ -152,8 +153,7 @@ void OSpit::xbookclick(uint16 argc, uint16 *argv) { } } - if (updateScreen && !_vm->shouldQuit()) - _vm->_system->updateScreen(); + _vm->_system->updateScreen(); _vm->_system->delayMillis(10); } @@ -176,7 +176,7 @@ void OSpit::xbookclick(uint16 argc, uint16 *argv) { } // There was no click, so just play the rest of the video. - _vm->_video->waitUntilMovieEnds(video); + video->playBlocking(); } void OSpit::xooffice30_closebook(uint16 argc, uint16 *argv) { @@ -189,7 +189,8 @@ void OSpit::xooffice30_closebook(uint16 argc, uint16 *argv) { book = 0; // Play the movie - _vm->_video->playMovieBlockingRiven(1); + RivenVideo *video = _vm->_video->openSlot(1); + video->playBlocking(); // Set the hotspots into their correct states RivenHotspot *closeBook = _vm->getCard()->getHotspotByName("closeBook"); @@ -207,7 +208,8 @@ void OSpit::xooffice30_closebook(uint16 argc, uint16 *argv) { void OSpit::xobedroom5_closedrawer(uint16 argc, uint16 *argv) { // Close the drawer if open when clicking on the journal. - _vm->_video->playMovieBlockingRiven(2); + RivenVideo *video = _vm->_video->openSlot(2); + video->playBlocking(); _vm->_vars["ostanddrawer"] = 0; } @@ -278,8 +280,9 @@ void OSpit::xgwatch(uint16 argc, uint16 *argv) { } // Now play the video for the watch - _vm->_video->activateMLST(_vm->getCard()->getMovie(1)); - _vm->_video->playMovieBlockingRiven(1); + _vm->getCard()->playMovie(1); + RivenVideo *watchVideo = _vm->_video->openSlot(1); + watchVideo->playBlocking(); // And, finally, refresh _vm->refreshCard(); diff --git a/engines/mohawk/riven_stacks/pspit.cpp b/engines/mohawk/riven_stacks/pspit.cpp index e2bfec0f95..63f921dcd9 100644 --- a/engines/mohawk/riven_stacks/pspit.cpp +++ b/engines/mohawk/riven_stacks/pspit.cpp @@ -26,6 +26,7 @@ #include "mohawk/riven.h" #include "mohawk/riven_card.h" #include "mohawk/riven_sound.h" +#include "mohawk/riven_video.h" namespace Mohawk { namespace RivenStacks { @@ -33,13 +34,13 @@ namespace RivenStacks { PSpit::PSpit(MohawkEngine_Riven *vm) : DomeSpit(vm, kStackPspit, "psliders.25", "psliderbg.25") { - REGISTER_COMMAND(PSpit, xpisland990_elevcombo); - REGISTER_COMMAND(PSpit, xpscpbtn); - REGISTER_COMMAND(PSpit, xpisland290_domecheck); - REGISTER_COMMAND(PSpit, xpisland25_opencard); - REGISTER_COMMAND(PSpit, xpisland25_resetsliders); - REGISTER_COMMAND(PSpit, xpisland25_slidermd); - REGISTER_COMMAND(PSpit, xpisland25_slidermw); +// REGISTER_COMMAND(PSpit, xpisland990_elevcombo); +// REGISTER_COMMAND(PSpit, xpscpbtn); +// REGISTER_COMMAND(PSpit, xpisland290_domecheck); +// REGISTER_COMMAND(PSpit, xpisland25_opencard); +// REGISTER_COMMAND(PSpit, xpisland25_resetsliders); +// REGISTER_COMMAND(PSpit, xpisland25_slidermd); +// REGISTER_COMMAND(PSpit, xpisland25_slidermw); } void PSpit::catherineIdleTimer() { @@ -67,9 +68,10 @@ void PSpit::catherineIdleTimer() { cathState = 1; // Play the movie, blocking - _vm->_video->activateMLST(_vm->getCard()->getMovie(movie)); + _vm->getCard()->playMovie(movie); _vm->_cursor->hideCursor(); - _vm->_video->playMovieBlockingRiven(movie); + RivenVideo *video = _vm->_video->openSlot(movie); + video->playBlocking(); _vm->_cursor->showCursor(); _vm->_system->updateScreen(); diff --git a/engines/mohawk/riven_stacks/rspit.cpp b/engines/mohawk/riven_stacks/rspit.cpp index 49fac73346..bfb305e415 100644 --- a/engines/mohawk/riven_stacks/rspit.cpp +++ b/engines/mohawk/riven_stacks/rspit.cpp @@ -26,6 +26,7 @@ #include "mohawk/riven_card.h" #include "mohawk/riven_graphics.h" #include "mohawk/riven_inventory.h" +#include "mohawk/riven_video.h" namespace Mohawk { namespace RivenStacks { @@ -33,10 +34,10 @@ namespace RivenStacks { RSpit::RSpit(MohawkEngine_Riven *vm) : RivenStack(vm, kStackRspit) { - REGISTER_COMMAND(RSpit, xrshowinventory); - REGISTER_COMMAND(RSpit, xrhideinventory); - REGISTER_COMMAND(RSpit, xrcredittime); - REGISTER_COMMAND(RSpit, xrwindowsetup); +// REGISTER_COMMAND(RSpit, xrshowinventory); +// REGISTER_COMMAND(RSpit, xrhideinventory); +// REGISTER_COMMAND(RSpit, xrcredittime); +// REGISTER_COMMAND(RSpit, xrwindowsetup); } void RSpit::xrcredittime(uint16 argc, uint16 *argv) { @@ -64,11 +65,12 @@ void RSpit::xrhideinventory(uint16 argc, uint16 *argv) { 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); + _vm->getCard()->playMovie(movie); + RivenVideo *video = _vm->_video->openSlot(movie); + video->play(); // Ensure the next video starts after this one ends - uint32 timeUntilNextVideo = handle->getDuration().msecs() + _vm->_rnd->getRandomNumberRng(38, 58) * 1000; + uint32 timeUntilNextVideo = video->getDuration() + _vm->_rnd->getRandomNumberRng(38, 58) * 1000; // Save the time in case we leave the card and return _vm->_vars["rvillagetime"] = timeUntilNextVideo + _vm->getTotalPlayTime(); diff --git a/engines/mohawk/riven_stacks/tspit.cpp b/engines/mohawk/riven_stacks/tspit.cpp index 1903a897c6..89eb16581a 100644 --- a/engines/mohawk/riven_stacks/tspit.cpp +++ b/engines/mohawk/riven_stacks/tspit.cpp @@ -27,6 +27,7 @@ #include "mohawk/riven_card.h" #include "mohawk/riven_graphics.h" #include "mohawk/riven_inventory.h" +#include "mohawk/riven_video.h" #include "common/events.h" @@ -36,29 +37,32 @@ namespace RivenStacks { TSpit::TSpit(MohawkEngine_Riven *vm) : DomeSpit(vm, kStackTspit, "tsliders.190", "tsliderbg.190") { - REGISTER_COMMAND(TSpit, xtexterior300_telescopedown); - REGISTER_COMMAND(TSpit, xtexterior300_telescopeup); - REGISTER_COMMAND(TSpit, xtisland390_covercombo); - REGISTER_COMMAND(TSpit, xtatrusgivesbooks); - REGISTER_COMMAND(TSpit, xtchotakesbook); - REGISTER_COMMAND(TSpit, xthideinventory); - REGISTER_COMMAND(TSpit, xt7500_checkmarbles); - REGISTER_COMMAND(TSpit, xt7600_setupmarbles); - REGISTER_COMMAND(TSpit, xt7800_setup); - REGISTER_COMMAND(TSpit, xdrawmarbles); - REGISTER_COMMAND(TSpit, xtakeit); - REGISTER_COMMAND(TSpit, xtscpbtn); - REGISTER_COMMAND(TSpit, xtisland4990_domecheck); - REGISTER_COMMAND(TSpit, xtisland5056_opencard); - REGISTER_COMMAND(TSpit, xtisland5056_resetsliders); - REGISTER_COMMAND(TSpit, xtisland5056_slidermd); - REGISTER_COMMAND(TSpit, xtisland5056_slidermw); - REGISTER_COMMAND(TSpit, xtatboundary); + REGISTER_COMMAND(TSpit, xtexterior300_telescopedown); // TODO: Check endgame + REGISTER_COMMAND(TSpit, xtexterior300_telescopeup); // TODO: Check endgame + REGISTER_COMMAND(TSpit, xtisland390_covercombo); // Done + REGISTER_COMMAND(TSpit, xtatrusgivesbooks); // Done + REGISTER_COMMAND(TSpit, xtchotakesbook); // Done + REGISTER_COMMAND(TSpit, xthideinventory); // Done +// REGISTER_COMMAND(TSpit, xt7500_checkmarbles); +// REGISTER_COMMAND(TSpit, xt7600_setupmarbles); +// REGISTER_COMMAND(TSpit, xt7800_setup); +// REGISTER_COMMAND(TSpit, xdrawmarbles); +// REGISTER_COMMAND(TSpit, xtakeit); +// REGISTER_COMMAND(TSpit, xtscpbtn); +// REGISTER_COMMAND(TSpit, xtisland4990_domecheck); +// REGISTER_COMMAND(TSpit, xtisland5056_opencard); +// REGISTER_COMMAND(TSpit, xtisland5056_resetsliders); +// REGISTER_COMMAND(TSpit, xtisland5056_slidermd); +// REGISTER_COMMAND(TSpit, xtisland5056_slidermw); +// REGISTER_COMMAND(TSpit, xtatboundary); } void TSpit::xtexterior300_telescopedown(uint16 argc, uint16 *argv) { // First, show the button movie - _vm->_video->playMovieBlockingRiven(3); + RivenVideo *buttonVideo = _vm->_video->openSlot(3); + buttonVideo->seek(0); + buttonVideo->enable(); + buttonVideo->playBlocking(); // Don't do anything else if the telescope power is off if (_vm->_vars["ttelevalve"] == 0) @@ -67,61 +71,41 @@ void TSpit::xtexterior300_telescopedown(uint16 argc, uint16 *argv) { uint32 &telescopePos = _vm->_vars["ttelescope"]; uint32 &telescopeCover = _vm->_vars["ttelecover"]; - if (telescopePos == 1) { - // We're at the bottom, which means one of two things can happen... - if (telescopeCover == 1 && _vm->_vars["ttelepin"] == 1) { - // ...if the cover is open and the pin is up, the game is now over. - if (_vm->_vars["pcage"] == 2) { - // The best ending: Catherine is free, Gehn is trapped, Atrus comes to rescue you. - // And now we fall back to Earth... all the way... - _vm->_video->activateMLST(_vm->getCard()->getMovie(8)); - runEndGame(8, 5000); - } else if (_vm->_vars["agehn"] == 4) { - // The ok ending: Catherine is still trapped, Gehn is trapped, Atrus comes to rescue you. - // Nice going! Catherine and the islanders are all dead now! Just go back to your home... - _vm->_video->activateMLST(_vm->getCard()->getMovie(9)); - runEndGame(9, 5000); - } else if (_vm->_vars["atrapbook"] == 1) { - // The bad ending: Catherine is trapped, Gehn is free, Atrus gets shot by Gehn, - // And then you get shot by Cho. Nice going! Catherine and the islanders are dead - // and you have just set Gehn free from Riven, not to mention you're dead. - _vm->_video->activateMLST(_vm->getCard()->getMovie(10)); - runEndGame(10, 5000); - } else { - // The impossible ending: You don't have Catherine's journal and yet you were somehow - // able to open the hatch on the telescope. The game provides an ending for those who - // cheat, load a saved game with the combo, or just guess the telescope combo. Atrus - // doesn't come and you just fall into the fissure. - _vm->_video->activateMLST(_vm->getCard()->getMovie(11)); - runEndGame(11, 5000); - } - } else { - // ...the telescope can't move down anymore. - // Play the sound of not being able to move - _vm->_cursor->setCursor(kRivenHideCursor); - _vm->_system->updateScreen(); - _vm->_sound->playSound(13); - } - } else { + if (telescopePos != 1) { // We're not at the bottom, and we can move down again // Play a piece of the moving down movie - static const uint32 timeIntervals[] = { 4320, 3440, 2560, 1760, 880, 0 }; + static const uint32 timeIntervals[] = { 4320, 3440, 2660, 1760, 880, 0 }; uint16 movieCode = telescopeCover ? 1 : 2; - VideoEntryPtr handle = _vm->_video->playMovieRiven(movieCode); - handle->setBounds(Audio::Timestamp(0, timeIntervals[telescopePos], 600), Audio::Timestamp(0, timeIntervals[telescopePos - 1], 600)); - _vm->_sound->playSound(14); // Play the moving sound - _vm->_video->waitUntilMovieEnds(handle); + RivenVideo *video = _vm->_video->openSlot(movieCode); + video->enable(); + video->setBounds(timeIntervals[telescopePos], timeIntervals[telescopePos - 1] + 7); + _vm->_sound->playCardSound("tTeleMove"); // Play the moving sound + video->playBlocking(); // Now move the telescope down a position and refresh telescopePos--; - _vm->refreshCard(); + _vm->getCard()->enter(false); + return; + } + + // We're at the bottom, which means one of two things can happen... + if (telescopeCover == 1 && _vm->_vars["ttelepin"] == 1) { + // ...if the cover is open and the pin is up, the game is now over. + xtopenfissure(); + } else { + // ...the telescope can't move down anymore. + // Play the sound of not being able to move + _vm->_sound->playCardSound("tTelDnMore"); } } void TSpit::xtexterior300_telescopeup(uint16 argc, uint16 *argv) { // First, show the button movie - _vm->_video->playMovieBlockingRiven(3); + RivenVideo *buttonVideo = _vm->_video->openSlot(3); + buttonVideo->seek(0); + buttonVideo->enable(); + buttonVideo->playBlocking(); // Don't do anything else if the telescope power is off if (_vm->_vars["ttelevalve"] == 0) @@ -132,23 +116,49 @@ void TSpit::xtexterior300_telescopeup(uint16 argc, uint16 *argv) { // Check if we can't move up anymore if (telescopePos == 5) { // Play the sound of not being able to move - _vm->_cursor->setCursor(kRivenHideCursor); - _vm->_system->updateScreen(); - _vm->_sound->playSound(13); + _vm->_sound->playCardSound("tTelDnMore"); return; } // Play a piece of the moving up movie static const uint32 timeIntervals[] = { 0, 800, 1680, 2560, 3440, 4320 }; uint16 movieCode = _vm->_vars["ttelecover"] ? 4 : 5; - VideoEntryPtr handle = _vm->_video->playMovieRiven(movieCode); - handle->setBounds(Audio::Timestamp(0, timeIntervals[telescopePos - 1], 600), Audio::Timestamp(0, timeIntervals[telescopePos], 600)); - _vm->_sound->playSound(14); // Play the moving sound - _vm->_video->waitUntilMovieEnds(handle); + RivenVideo *video = _vm->_video->openSlot(movieCode); + video->enable(); + video->setBounds(timeIntervals[telescopePos - 1], timeIntervals[telescopePos] + 7); + _vm->_sound->playCardSound("tTeleMove"); // Play the moving sound + video->playBlocking(); // Now move the telescope up a position and refresh telescopePos++; - _vm->refreshCard(); + _vm->getCard()->enter(false); +} + +void TSpit::xtopenfissure() { + if (_vm->_vars["pcage"] == 2) { + // The best ending: Catherine is free, Gehn is trapped, Atrus comes to rescue you. + // And now we fall back to Earth... all the way... + _vm->getCard()->playMovie(8); + runEndGame(8, 5000); + } else if (_vm->_vars["agehn"] == 4) { + // The ok ending: Catherine is still trapped, Gehn is trapped, Atrus comes to rescue you. + // Nice going! Catherine and the islanders are all dead now! Just go back to your home... + _vm->getCard()->playMovie(9); + runEndGame(9, 5000); + } else if (_vm->_vars["atrapbook"] == 1) { + // The bad ending: Catherine is trapped, Gehn is free, Atrus gets shot by Gehn, + // And then you get shot by Cho. Nice going! Catherine and the islanders are dead + // and you have just set Gehn free from Riven, not to mention you're dead. + _vm->getCard()->playMovie(10); + runEndGame(10, 5000); + } else { + // The impossible ending: You don't have Catherine's journal and yet you were somehow + // able to open the hatch on the telescope. The game provides an ending for those who + // cheat, load a saved game with the combo, or just guess the telescope combo. Atrus + // doesn't come and you just fall into the fissure. + _vm->getCard()->playMovie(11); + runEndGame(11, 5000); + } } void TSpit::xtisland390_covercombo(uint16 argc, uint16 *argv) { @@ -169,20 +179,14 @@ void TSpit::xtisland390_covercombo(uint16 argc, uint16 *argv) { // Atrus' Journal and Trap Book are added to inventory void TSpit::xtatrusgivesbooks(uint16 argc, uint16 *argv) { // Give the player Atrus' Journal and the Trap book - _vm->_vars["aatrusbook"] = 1; - _vm->_vars["atrapbook"] = 1; } // Trap Book is removed from inventory void TSpit::xtchotakesbook(uint16 argc, uint16 *argv) { - // And now Cho takes the trap book. Sure, this isn't strictly - // necessary to add and them remove the trap book... but it - // seems better to do this ;) - _vm->_vars["atrapbook"] = 0; + // And now Cho takes the trap book } void TSpit::xthideinventory(uint16 argc, uint16 *argv) { - _vm->_inventory->hide(); } // Marble Puzzle related constants diff --git a/engines/mohawk/riven_stacks/tspit.h b/engines/mohawk/riven_stacks/tspit.h index 6b9e7efdf3..9811f6143b 100644 --- a/engines/mohawk/riven_stacks/tspit.h +++ b/engines/mohawk/riven_stacks/tspit.h @@ -40,8 +40,9 @@ public: // External commands - Telescope void xtexterior300_telescopedown(uint16 argc, uint16 *argv); void xtexterior300_telescopeup(uint16 argc, uint16 *argv); + void xtopenfissure(); - // External commands - Telescope cover buttons. Button is the button number (1...5). + // External commands - Telescope cover buttons. Button is the button number (1...5). void xtisland390_covercombo(uint16 argc, uint16 *argv); // Param1: button // External commands - Atrus' Journal and Trap Book are added to inventory diff --git a/engines/mohawk/riven_video.cpp b/engines/mohawk/riven_video.cpp new file mode 100644 index 0000000000..375af47ffe --- /dev/null +++ b/engines/mohawk/riven_video.cpp @@ -0,0 +1,341 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "mohawk/riven_video.h" + +#include "mohawk/cursors.h" +#include "mohawk/resource.h" +#include "mohawk/riven.h" +#include "mohawk/riven_graphics.h" +#include "mohawk/riven_scripts.h" +#include "mohawk/riven_stack.h" + +#include "common/system.h" + +#include "graphics/surface.h" + +#include "video/qt_decoder.h" + +namespace Mohawk { + +RivenVideo::RivenVideo(MohawkEngine_Riven *vm, uint16 code) : + _vm(vm), + _id(0), + _slot(code), + _x(0), + _y(0), + _loop(false), + _enabled(false), + _video(nullptr), + _playing(false) { +} + +RivenVideo::~RivenVideo() { + delete _video; +} + +void RivenVideo::load(uint16 id) { + if (id == _id && _video) { + return; + } + + close(); + + _id = id; + _video = new Video::QuickTimeDecoder(); + _video->setChunkBeginOffset(_vm->getResourceOffset(ID_TMOV, id)); + _video->loadStream(_vm->getResource(ID_TMOV, id)); +} + +void RivenVideo::close() { + stop(); + + delete _video; + _video = nullptr; +} + +bool RivenVideo::endOfVideo() const { + return !_video || _video->endOfVideo(); +} + +int RivenVideo::getCurFrame() const { + assert(_video); + return _video->getCurFrame(); +} + +uint32 RivenVideo::getFrameCount() const { + assert(_video); + return _video->getFrameCount(); +} + +uint32 RivenVideo::getTime() const { + assert(_video); + return _video->getTime(); +} + +uint32 RivenVideo::getDuration() const { + assert(_video); + return _video->getDuration().msecs(); +} + +void RivenVideo::setBounds(uint32 startTime, uint32 endTime) { + assert(_video); + _video->setEndTime(Audio::Timestamp(0, endTime, 600)); + _video->seek(Audio::Timestamp(0, startTime, 600)); +} + +void RivenVideo::seek(uint32 time) { + assert(_video); + + if (time == 0) { + // Fast path + _video->rewind(); + } else { + _video->seek(Audio::Timestamp(0, time, 600)); + } +} + +void RivenVideo::pause(bool isPaused) { + if (_video) { + _video->pauseVideo(isPaused); + } +} + +void RivenVideo::stop() { + if (_video) { + _video->stop(); + } + _playing = false; +} + +bool RivenVideo::isPlaying() const { + return _playing; +} + +int RivenVideo::getVolume() const { + assert(_video); + return _video->getVolume(); +} + +void RivenVideo::setVolume(int volume) { + assert(_video); + _video->setVolume(CLIP(volume, 0, 255)); +} + +RivenVideoManager::RivenVideoManager(MohawkEngine_Riven *vm) : _vm(vm) { +} + +RivenVideoManager::~RivenVideoManager() { + removeVideos(); +} + +void RivenVideoManager::pauseVideos() { + for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) + (*it)->pause(true); +} + +void RivenVideoManager::resumeVideos() { + for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) + (*it)->pause(false); +} + +void RivenVideoManager::closeVideos() { + for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) { + (*it)->close(); + } +} + +void RivenVideoManager::removeVideos() { + for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) { + delete *it; + } + + _videos.clear(); +} + +void RivenVideoManager::updateMovies() { + for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) { + RivenVideo *video = *it; + // Check of the video has reached the end + if (video->endOfVideo()) { + if (video->isPlaying() && video->isLooping()) { + // Seek back if looping + video->seek(0); + } else { + continue; + } + } + + // Check if we need to draw a frame + if (video->needsUpdate()) { + video->drawNextFrame(); + } + } +} + +void RivenVideo::drawNextFrame() { + const Graphics::Surface *frame = _video->decodeNextFrame(); + + if (!frame || !isEnabled()) { + return; + } + + Graphics::Surface *convertedFrame = nullptr; + Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); + + if (frame->format != pixelFormat) { + // Convert to the current screen format + convertedFrame = frame->convertTo(pixelFormat, _video->getPalette()); + frame = convertedFrame; + } + + g_system->copyRectToScreen(frame->getPixels(), frame->pitch, + _x, _y, _video->getWidth(), _video->getHeight()); + + // Delete 8bpp conversion surface + if (convertedFrame) { + convertedFrame->free(); + delete convertedFrame; + } +} + +bool RivenVideo::needsUpdate() const { + return _video && _video->isPlaying() && !_video->isPaused() && _video->needsUpdate(); +} + +void RivenVideo::playBlocking(int32 endTime) { + _vm->_cursor->hideCursor(); + + if (!_playing) { + play(); + } + + // Sanity check + if (isLooping()) + error("Called playBlocking() on a looping video"); + + bool playTillEnd; + if (endTime == -1) { + playTillEnd = true; + } else { + playTillEnd = false; + _video->setEndTime(Audio::Timestamp(0, endTime, 600)); + } + + if (playTillEnd) { + enable(); + } + + bool continuePlaying = true; + while (!endOfVideo() && !_vm->shouldQuit() && continuePlaying) { + // Draw a frame + _vm->doFrame(); + + // Handle skipping + if (playTillEnd && _vm->getStack()->keyGetPressed() == Common::KEYCODE_ESCAPE) { + continuePlaying = false; + + // Seek to the last frame + _video->seek(_video->getDuration().addMsecs(-1)); + + _vm->getStack()->mouseForceUp(); + _vm->getStack()->keyForceUp(); + } + } + + if (playTillEnd) { + disable(); + stop(); + } + + // Execute the stored opcode + uint16 storedOpcodeId = _vm->_scriptMan->getStoredMovieOpcodeID(); + uint32 storedOpcodeTime = _vm->_scriptMan->getStoredMovieOpcodeTime(); + if (_id == storedOpcodeId && getTime() >= storedOpcodeTime) { // CHECKME: Suspicious use of time units + _vm->_scriptMan->runStoredMovieOpcode(); + } + + _vm->_cursor->showCursor(); +} + +void RivenVideo::play() { + if (!_video) { + load(_id); + } + + if (_video->endOfVideo()) { + _video->rewind(); + } + + _video->start(); + _playing = true; +} + +void RivenVideo::enable() { + _enabled = true; +} + +void RivenVideo::disable() { + if (needsUpdate()) { + drawNextFrame(); + } + + if (_video) { + Common::Rect targetRect = Common::Rect(_video->getWidth(), _video->getHeight()); + targetRect.translate(_x, _y); + + _vm->_gfx->copySystemRectToScreen(targetRect); + } + + _enabled = false; +} + +void RivenVideoManager::disableAllMovies() { + debug(2, "Disabling all movies"); + for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) + (*it)->disable(); +} + +RivenVideo *RivenVideoManager::openSlot(uint16 slot) { + // If this video is already playing, return that handle + RivenVideo *oldHandle = getSlot(slot); + if (oldHandle) + return oldHandle; + + // Create the video + RivenVideo *video = new RivenVideo(_vm, slot); + + // Add it to the video list + _videos.push_back(video); + + return video; +} + +RivenVideo *RivenVideoManager::getSlot(uint16 slot) { + for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) + if ((*it)->getSlot() == slot) + return *it; + + return nullptr; +} + +} // End of namespace Mohawk diff --git a/engines/mohawk/riven_video.h b/engines/mohawk/riven_video.h new file mode 100644 index 0000000000..d5025a28e2 --- /dev/null +++ b/engines/mohawk/riven_video.h @@ -0,0 +1,164 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef MOHAWK_RIVEN_VIDEO_H +#define MOHAWK_RIVEN_VIDEO_H + +#include "common/list.h" +#include "common/noncopyable.h" + +namespace Video { +class QuickTimeDecoder; +} + +namespace Mohawk { + +class MohawkEngine_Riven; + +/** + * A video monitored by the VideoManager + */ +class RivenVideo : private Common::NonCopyable { +public: + RivenVideo(MohawkEngine_Riven *vm, uint16 code); + ~RivenVideo(); + + /** Load the video from the archive */ + void load(uint16 id); + + /** Free resources allocated for the movie, but allow to load it again later */ + void close(); + + /** Start playing the video */ + void play(); + + /** Play the video until it completes or reaches the specified timestamp */ + void playBlocking(int32 endTime = -1); + + /** Has the video reached its end? */ + bool endOfVideo() const; + + /** Is the video looping? */ + bool isLooping() const { return _loop; } + + /** Is the video enabled? (Drawing to the screen) */ + bool isEnabled() const { return _enabled; } + + /** Get the ID of the video */ + uint16 getId() const { return _id; } + + /** Get the slot used by the video in the video manager */ + uint16 getSlot() const { return _slot; } + + /** Get the current frame of the video */ + int getCurFrame() const; + + /** Get the frame count of the video */ + uint32 getFrameCount() const; + + /** Get the current time position of the video */ + uint32 getTime() const; + + /** Get the duration of the video */ + uint32 getDuration() const; + + /** Move the video to the specified coordinates */ + void moveTo(uint16 x, uint16 y) { _x = x; _y = y; } + + /** Set the video to loop (true) or not (false) */ + void setLooping(bool loop) { _loop = loop; } + + /** Enable the video */ + void enable(); + + /** Disable the video */ + void disable(); + + /** + * Set the bounds of the video + * + * This automatically seeks to the start time + */ + void setBounds(uint32 startTime, uint32 endTime); + + /** Seek to the given time */ + void seek(uint32 time); + + /** Pause the video */ + void pause(bool isPaused); + + /** Stop playing the video */ + void stop(); + + /** Is the video playing? */ + bool isPlaying() const; + + /** Get the volume of the video */ + int getVolume() const; + + /** Set the volume of the video */ + void setVolume(int volume); + + void drawNextFrame(); + + bool needsUpdate() const; +private: + // Non-changing variables + MohawkEngine_Riven *_vm; + Video::QuickTimeDecoder *_video; + uint16 _id; + uint16 _slot; + + // Playback variables + uint16 _x; + uint16 _y; + bool _loop; + bool _enabled; + bool _playing; +}; + +class RivenVideoManager { +public: + RivenVideoManager(MohawkEngine_Riven *vm); + ~RivenVideoManager(); + + void updateMovies(); + void pauseVideos(); + void resumeVideos(); + void closeVideos(); + void removeVideos(); + void disableAllMovies(); + + RivenVideo *openSlot(uint16 slot); + RivenVideo *getSlot(uint16 slot); + +private: + MohawkEngine_Riven *_vm; + + // Keep tabs on any videos playing + typedef Common::List<RivenVideo *> VideoList; + VideoList _videos; +}; + +} // End of namespace Mohawk + +#endif diff --git a/engines/mohawk/video.cpp b/engines/mohawk/video.cpp index cfc60153cb..eec0e9a7a0 100644 --- a/engines/mohawk/video.cpp +++ b/engines/mohawk/video.cpp @@ -235,7 +235,6 @@ void VideoManager::waitUntilMovieEnds(VideoHandle videoHandle) { break; case Common::KEYCODE_ESCAPE: continuePlaying = false; - _vm->doVideoTimer(videoHandle, true); break; default: break; @@ -326,9 +325,6 @@ bool VideoManager::updateMovies() { } } - // Check the video time - _vm->doVideoTimer(VideoHandle(*it), false); - // Remember to increase the iterator it++; } @@ -405,68 +401,6 @@ bool VideoManager::drawNextFrame(VideoEntryPtr videoEntry) { return true; } -void VideoManager::activateMLST(const MLSTRecord &mlst) { - // Make sure we don't have any duplicates - for (uint32 j = 0; j < _mlstRecords.size(); j++) - if (_mlstRecords[j].index == mlst.index || _mlstRecords[j].code == mlst.code) { - _mlstRecords.remove_at(j); - j--; - } - - _mlstRecords.push_back(mlst); -} - -void VideoManager::clearMLST() { - _mlstRecords.clear(); -} - -VideoEntryPtr VideoManager::playMovieRiven(uint16 id) { - for (uint16 i = 0; i < _mlstRecords.size(); i++) { - if (_mlstRecords[i].code == id) { - debug(1, "Play tMOV %d (non-blocking) at (%d, %d) %s, Volume = %d", _mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].loop != 0 ? "looping" : "non-looping", _mlstRecords[i].volume); - - VideoEntryPtr ptr = open(_mlstRecords[i].movieID); - if (ptr) { - ptr->moveTo(_mlstRecords[i].left, _mlstRecords[i].top); - ptr->setLooping(_mlstRecords[i].loop != 0); - ptr->setVolume(_mlstRecords[i].volume); - ptr->start(); - } - - return ptr; - } - } - - return VideoEntryPtr(); -} - -void VideoManager::playMovieBlockingRiven(uint16 id) { - for (uint16 i = 0; i < _mlstRecords.size(); i++) { - if (_mlstRecords[i].code == id) { - debug(1, "Play tMOV %d (blocking) at (%d, %d), Volume = %d", _mlstRecords[i].movieID, _mlstRecords[i].left, _mlstRecords[i].top, _mlstRecords[i].volume); - VideoEntryPtr ptr = open(_mlstRecords[i].movieID); - ptr->moveTo(_mlstRecords[i].left, _mlstRecords[i].top); - ptr->setVolume(_mlstRecords[i].volume); - ptr->start(); - waitUntilMovieEnds(VideoHandle(ptr)); - return; - } - } -} - -void VideoManager::stopMovieRiven(uint16 id) { - debug(2, "Stopping movie %d", id); - VideoEntryPtr video = findVideoRiven(id); - if (video) - removeEntry(video); -} - -void VideoManager::disableAllMovies() { - debug(2, "Disabling all movies"); - for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) - (*it)->setEnabled(false); -} - VideoEntryPtr VideoManager::open(uint16 id) { // If this video is already playing, return that handle VideoHandle oldHandle = findVideoHandle(id); @@ -520,16 +454,6 @@ VideoEntryPtr VideoManager::open(const Common::String &fileName) { return entry; } -VideoEntryPtr VideoManager::findVideoRiven(uint16 id) { - for (uint16 i = 0; i < _mlstRecords.size(); i++) - if (_mlstRecords[i].code == id) - for (VideoList::iterator it = _videos.begin(); it != _videos.end(); it++) - if ((*it)->getID() == _mlstRecords[i].movieID) - return *it; - - return VideoEntryPtr(); -} - VideoHandle VideoManager::findVideoHandle(uint16 id) { if (id == 0) return VideoHandle(); diff --git a/engines/mohawk/video.h b/engines/mohawk/video.h index c3d04ea58c..c59c4af96a 100644 --- a/engines/mohawk/video.h +++ b/engines/mohawk/video.h @@ -39,18 +39,6 @@ namespace Mohawk { class MohawkEngine; -struct MLSTRecord { - uint16 index; - uint16 movieID; - uint16 code; - uint16 left; - uint16 top; - uint16 u0[3]; - uint16 loop; - uint16 volume; - uint16 u1; -}; - /** * A video monitored by the VideoManager */ @@ -317,14 +305,6 @@ public: void stopVideos(); bool isVideoPlaying(); - // Riven-related functions - void activateMLST(const MLSTRecord &mlst); - void clearMLST(); - void disableAllMovies(); - VideoEntryPtr playMovieRiven(uint16 id); - void playMovieBlockingRiven(uint16 id); - VideoEntryPtr findVideoRiven(uint16 id); - void stopMovieRiven(uint16 id); void waitUntilMovieEnds(const VideoEntryPtr &video); // Handle functions @@ -337,9 +317,6 @@ public: private: MohawkEngine *_vm; - // Riven-related variables - Common::Array<MLSTRecord> _mlstRecords; - // Keep tabs on any videos playing typedef Common::List<VideoEntryPtr> VideoList; VideoList _videos; |