From 0bbd43eb3217bb04184ba9e1b27e43424a899c89 Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Sat, 13 Aug 2011 20:18:23 +0200 Subject: MOHAWK: Implement Myst demo opcodes 298 and 299, sneak preview speech. --- engines/mohawk/graphics.cpp | 8 ++ engines/mohawk/graphics.h | 2 + engines/mohawk/myst_stacks/myst.h | 4 +- engines/mohawk/myst_stacks/preview.cpp | 166 +++++++++++++++++++++++++++------ engines/mohawk/myst_stacks/preview.h | 19 +++- engines/mohawk/sound.cpp | 2 +- 6 files changed, 169 insertions(+), 32 deletions(-) diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp index b3653b1fdf..25a327bc14 100644 --- a/engines/mohawk/graphics.cpp +++ b/engines/mohawk/graphics.cpp @@ -672,6 +672,14 @@ void MystGraphics::simulatePreviousDrawDelay(const Common::Rect &dest) { _nextAllowedDrawTime = time + _constantDrawDelay + dest.height() * dest.width() / _proportionalDrawDelay; } +void MystGraphics::fadeToBlack() { + // TODO: Implement +} + +void MystGraphics::fadeFromBlack() { + // TODO: Implement +} + #endif // ENABLE_MYST #ifdef ENABLE_RIVEN diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h index d7057f48cf..c5ce016f0a 100644 --- a/engines/mohawk/graphics.h +++ b/engines/mohawk/graphics.h @@ -129,6 +129,8 @@ public: void drawRect(Common::Rect rect, RectState state); void drawLine(const Common::Point &p1, const Common::Point &p2, uint32 color); void enableDrawingTimeSimulation(bool enable); + void fadeToBlack(); + void fadeFromBlack(); protected: MohawkSurface *decodeImage(uint16 id); diff --git a/engines/mohawk/myst_stacks/myst.h b/engines/mohawk/myst_stacks/myst.h index 9510d371d7..e9bff08cb4 100644 --- a/engines/mohawk/myst_stacks/myst.h +++ b/engines/mohawk/myst_stacks/myst.h @@ -40,8 +40,8 @@ public: Myst(MohawkEngine_Myst *vm); ~Myst(); - void disablePersistentScripts(); - void runPersistentScripts(); + virtual void disablePersistentScripts(); + virtual void runPersistentScripts(); private: void setupOpcodes(); diff --git a/engines/mohawk/myst_stacks/preview.cpp b/engines/mohawk/myst_stacks/preview.cpp index 07e4fa6e57..0e720c6112 100644 --- a/engines/mohawk/myst_stacks/preview.cpp +++ b/engines/mohawk/myst_stacks/preview.cpp @@ -60,13 +60,24 @@ void Preview::setupOpcodes() { OVERRIDE_OPCODE(199, opcode_199); // "Init" Opcodes - OPCODE(298, opcode_298); - OPCODE(299, opcode_299); + OPCODE(298, o_speech_init); + OPCODE(299, o_library_init); } #undef OPCODE #undef OVERRIDE_OPCODE +void Preview::disablePersistentScripts() { + Myst::disablePersistentScripts(); +} + +void Preview::runPersistentScripts() { + Myst::runPersistentScripts(); + + if (_speechRunning) + speech_run(); +} + void Preview::opcode_196(uint16 op, uint16 var, uint16 argc, uint16 *argv) { varUnusedCheck(op, var); @@ -103,37 +114,138 @@ void Preview::opcode_199(uint16 op, uint16 var, uint16 argc, uint16 *argv) { // Voice Over and Card Advance? } -void Preview::opcode_298(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); +void Preview::speechUpdateCue() { + // This is a callback in the original, handling audio events. + if (!_vm->_sound->isPlaying(3001)) { + return; + } - // Used for Card 3000 (Closed Myst Book) - // TODO: Fill in logic. - // Start Voice Over... which controls book opening - _vm->_sound->replaceSoundMyst(3001); - - // then link to Myst - Trigger of Hotspot? then opcode 199/196/197 for voice over continue? - // TODO: Sync Voice and Actions to Original - // TODO: Flash Library Red - // TODO: Move to run process based delay to prevent - // blocking... - _vm->_system->updateScreen(); - _vm->_system->delayMillis(20 * 1000); - - for (uint16 imageId = 3001; imageId <= 3012; imageId++) { - _vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333)); - _vm->_system->updateScreen(); - _vm->_system->delayMillis(5 * 1000); + uint samples = _vm->_sound->getNumSamplesPlayed(3001); + for (int16 i = 0; i < _cueList.pointCount; i++) { + if (_cueList.points[i].sampleFrame > samples) + return; + if (i > _currentCue - 1) { + _currentCue++; + debugC(kDebugScript, "Sneak speech advanced to cue %d", _currentCue); + } } } -void Preview::opcode_299(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); +void Preview::speech_run() { + uint32 time = _vm->_system->getMillis(); + + // Update current speech sound cue + speechUpdateCue(); + + switch (_speechStep) { + case 0: // Start Voice Over... which controls book opening + _currentCue = 0; + _vm->_sound->playSound(3001, Audio::Mixer::kMaxChannelVolume, false, &_cueList); + + _speechStep++; + break; + case 1: // Open book + if (_currentCue >= 1) { + _vm->changeToCard(3001, true); + + _speechStep++; + } + break; + case 2: // Go to Myst + if (_currentCue >= 2) { + _vm->_gfx->fadeToBlack(); + _vm->changeToCard(3002, true); + _vm->_gfx->fadeFromBlack(); + + _speechStep++; + } + break; + case 3: // Start blinking the library + if (_currentCue >= 3) { + _libraryState = 1; + _speechNextTime = 0; + _speechStep++; + } + break; + case 4: // Library blinking, zoom in library + if (_currentCue >= 4) { + _library->drawConditionalDataToScreen(0); + + _vm->changeToCard(3003, true); + + _speechNextTime = time + 2000; + _speechStep++; + } else { + if (time < _speechNextTime) + break; + + _library->drawConditionalDataToScreen(_libraryState); + _libraryState = (_libraryState + 1) % 2; + _speechNextTime = time + 500; + } + break; + case 5: // Go to library near view + if (time < _speechNextTime) + break; + + _vm->changeToCard(3004, true); + _speechNextTime = time + 2000; + _speechStep++; + break; + case 6: // Fade to courtyard + if (time < _speechNextTime) + break; + + _vm->_gfx->fadeToBlack(); + _vm->changeToCard(3005, true); + _vm->_gfx->fadeFromBlack(); + _speechNextTime = time + 1000; + _speechStep++; + break; + case 7: // Walk to library + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + if (time < _speechNextTime) + break; + + _vm->changeToCard(3006 + _speechStep - 7, true); + _speechNextTime = time + 2000; + _speechStep++; + break; + case 14: // Go to playable library card + if (time < _speechNextTime) + break; + + _vm->changeToCard(4329, true); + + _speechRunning = false; + _globals.currentAge = 2; + + _vm->_cursor->showCursor(); + break; + default: + warning("Unknown speech step"); + break; + } +} + +void Preview::o_speech_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Speech init", op); + + // Used for Card 3000 (Closed Myst Book) + _speechStep = 0; + _speechRunning = true; +} + +void Preview::o_library_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Library init", op); // Used for Card 3002 (Myst Island Overview) - // TODO: Fill in logic. - // Zoom into Island? - // On this card is a Type 8 controlled by Var 0, which - // can change the Myst Library to Red.. + _library = static_cast(_invokingResource); } } // End of namespace MystStacks diff --git a/engines/mohawk/myst_stacks/preview.h b/engines/mohawk/myst_stacks/preview.h index 7e4e418eef..a884be8d4d 100644 --- a/engines/mohawk/myst_stacks/preview.h +++ b/engines/mohawk/myst_stacks/preview.h @@ -40,6 +40,9 @@ public: Preview(MohawkEngine_Myst *vm); ~Preview(); + void disablePersistentScripts(); + void runPersistentScripts(); + private: void setupOpcodes(); @@ -48,8 +51,20 @@ private: DECLARE_OPCODE(opcode_198); DECLARE_OPCODE(opcode_199); - DECLARE_OPCODE(opcode_298); - DECLARE_OPCODE(opcode_299); + DECLARE_OPCODE(o_speech_init); + DECLARE_OPCODE(o_library_init); + + uint16 _libraryState; // 4 + MystResourceType8 *_library; // 32 + + bool _speechRunning; + uint _speechStep; + CueList _cueList; + int16 _currentCue; + uint32 _speechNextTime; // 6 + + void speech_run(); + void speechUpdateCue(); }; } // End of namespace MystStacks diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp index 68b60515be..f92bebf10e 100644 --- a/engines/mohawk/sound.cpp +++ b/engines/mohawk/sound.cpp @@ -85,7 +85,7 @@ Audio::AudioStream *Sound::makeAudioStream(uint16 id, CueList *cueList) { if (_vm->getFeatures() & GF_ME) audStream = Audio::makeWAVStream(_vm->getResource(ID_MSND, convertMystID(id)), DisposeAfterUse::YES); else - audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id)); + audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id), cueList); break; case GType_ZOOMBINI: audStream = makeMohawkWaveStream(_vm->getResource(ID_SND, id)); -- cgit v1.2.3