diff options
author | Alyssa Milburn | 2011-08-17 09:28:51 +0200 |
---|---|---|
committer | Alyssa Milburn | 2011-08-17 09:28:51 +0200 |
commit | ae287ccee58ebf68ab6125e5bbb4d8a44874330e (patch) | |
tree | 2f4cee4b2940466b8a578962e0174c6f89077a40 /engines/mohawk | |
parent | f5255288eabc0527c4c6b727a9db6b8d09a31206 (diff) | |
parent | e36832bbf84cba88fe6b17e1634fab0d550f13df (diff) | |
download | scummvm-rg350-ae287ccee58ebf68ab6125e5bbb4d8a44874330e.tar.gz scummvm-rg350-ae287ccee58ebf68ab6125e5bbb4d8a44874330e.tar.bz2 scummvm-rg350-ae287ccee58ebf68ab6125e5bbb4d8a44874330e.zip |
Merge remote-tracking branch 'origin/master' into soccer
Conflicts:
engines/scumm/he/logic_he.cpp
engines/scumm/he/logic_he.h
Diffstat (limited to 'engines/mohawk')
-rw-r--r-- | engines/mohawk/cursors.cpp | 37 | ||||
-rw-r--r-- | engines/mohawk/detection_tables.h | 84 | ||||
-rw-r--r-- | engines/mohawk/dialogs.cpp | 18 | ||||
-rw-r--r-- | engines/mohawk/dialogs.h | 1 | ||||
-rw-r--r-- | engines/mohawk/graphics.cpp | 11 | ||||
-rw-r--r-- | engines/mohawk/graphics.h | 4 | ||||
-rw-r--r-- | engines/mohawk/myst.cpp | 6 | ||||
-rw-r--r-- | engines/mohawk/myst.h | 1 | ||||
-rw-r--r-- | engines/mohawk/myst_stacks/demo.cpp | 98 | ||||
-rw-r--r-- | engines/mohawk/myst_stacks/demo.h | 14 | ||||
-rw-r--r-- | engines/mohawk/myst_stacks/myst.h | 4 | ||||
-rw-r--r-- | engines/mohawk/myst_stacks/preview.cpp | 211 | ||||
-rw-r--r-- | engines/mohawk/myst_stacks/preview.h | 27 | ||||
-rw-r--r-- | engines/mohawk/myst_stacks/slides.cpp | 10 | ||||
-rw-r--r-- | engines/mohawk/riven.cpp | 175 | ||||
-rw-r--r-- | engines/mohawk/riven.h | 8 | ||||
-rw-r--r-- | engines/mohawk/riven_external.cpp | 32 | ||||
-rw-r--r-- | engines/mohawk/riven_vars.cpp | 8 | ||||
-rw-r--r-- | engines/mohawk/sound.cpp | 2 |
19 files changed, 592 insertions, 159 deletions
diff --git a/engines/mohawk/cursors.cpp b/engines/mohawk/cursors.cpp index 78e099ccfe..cbd17e0b86 100644 --- a/engines/mohawk/cursors.cpp +++ b/engines/mohawk/cursors.cpp @@ -49,36 +49,13 @@ void CursorManager::hideCursor() { } void CursorManager::setDefaultCursor() { - static const byte defaultCursor[] = { - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, - 1, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, - 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, - 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, - 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 1, 2, 2, 1, 0, 0, 0, 0, - 1, 2, 2, 1, 1, 2, 2, 1, 0, 0, 0, 0, - 1, 2, 1, 0, 1, 1, 2, 2, 1, 0, 0, 0, - 1, 1, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 - }; - - static const byte bwPalette[] = { - 0x00, 0x00, 0x00, // Black - 0xFF, 0xFF, 0xFF // White - }; - - CursorMan.replaceCursor(defaultCursor, 12, 20, 0, 0, 0); - CursorMan.replaceCursorPalette(bwPalette, 1, 2); + Graphics::Cursor *cursor = Graphics::makeDefaultWinCursor(); + + CursorMan.replaceCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(), cursor->getHotspotX(), + cursor->getHotspotY(), cursor->getKeyColor()); + CursorMan.replaceCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount()); + + delete cursor; } void CursorManager::setCursor(uint16 id) { diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h index 01eac0aaba..a587d06760 100644 --- a/engines/mohawk/detection_tables.h +++ b/engines/mohawk/detection_tables.h @@ -653,6 +653,23 @@ static const MohawkGameDescription gameDescriptions[] = { "HARRY.EXE" }, + // part of "Super Living Books" compilation + // from rgemini, bug #3309343 + { + { + "harryhh", + "", + AD_ENTRY1("HARRY.512", "39d11399796dfa36d3f631d2d87e8b85"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_LIVINGBOOKSV1, + 0, + "HARRY.EXE" + }, + { { "carmentq", @@ -929,6 +946,23 @@ static const MohawkGameDescription gameDescriptions[] = { "TORTOISE.EXE" }, + // part of "Super Living Books" compilation + // from rgemini, bug #3309343 + { + { + "tortoise", + "", + AD_ENTRY1("TORTOISE.512", "e9ec7a6bc6b451c9e85e5b4f072d5143"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_LIVINGBOOKSV1, + 0, + "TORTOISE.EXE" + }, + // From afholman in bug#3309308 { { @@ -1053,6 +1087,23 @@ static const MohawkGameDescription gameDescriptions[] = { "ARTHUR.EXE" }, + // part of "Super Living Books" compilation + // from rgemini, bug #3309343 + { + { + "arthur", + "", + AD_ENTRY1("PAGES.512", "cd995d20d0d7b4642476fd76044b4e5b"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_LIVINGBOOKSV1, + GF_LB_10, + "ARTHUR.EXE" + }, + // From afholman in bug#3309308 { { @@ -1195,6 +1246,22 @@ static const MohawkGameDescription gameDescriptions[] = { "GRANDMA.EXE" }, + // from jjnryan in bug #3389857 + { + { + "grandma", + "v1.0", + AD_ENTRY1("PAGES.512", "613ca946bc8d91087fb7c10e9b84e88b"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_LIVINGBOOKSV1, + GF_LB_10, + "GRANDMA.EXE" + }, + { { "grandma", @@ -1366,6 +1433,23 @@ static const MohawkGameDescription gameDescriptions[] = { "NEWKID.EXE" }, + // part of "Super Living Books" compilation + // from rgemini, bug #3309343 + { + { + "newkid", + "", + AD_ENTRY1("NEWKID.512", "28a5aef3e6ef7e2ed7742485c25bdff6"), + Common::EN_ANY, + Common::kPlatformWindows, + ADGF_NO_FLAGS, + Common::GUIO_NONE + }, + GType_LIVINGBOOKSV1, + 0, + "NEWKID.EXE" + }, + // From aluff in bug#3309981 { { diff --git a/engines/mohawk/dialogs.cpp b/engines/mohawk/dialogs.cpp index 11e050aa72..2d1cc3bfa3 100644 --- a/engines/mohawk/dialogs.cpp +++ b/engines/mohawk/dialogs.cpp @@ -81,7 +81,8 @@ enum { kTransCmd = 'TRAN', kWaterCmd = 'WATR', kDropCmd = 'DROP', - kMapCmd = 'SMAP' + kMapCmd = 'SMAP', + kMenuCmd = 'MENU' }; #ifdef ENABLE_MYST @@ -97,6 +98,12 @@ MystOptionsDialog::MystOptionsDialog(MohawkEngine_Myst* vm) : GUI::OptionsDialog else _showMapButton = 0; + // Myst demo only has a menu + if (_vm->getFeatures() & GF_DEMO) + _returnToMenuButton = new GUI::ButtonWidget(this, 15, 95, 100, 25, _("~M~ain Menu"), 0, kMenuCmd); + else + _returnToMenuButton = 0; + new GUI::ButtonWidget(this, 95, 160, 120, 25, _("~O~K"), 0, GUI::kOKCmd); new GUI::ButtonWidget(this, 225, 160, 120, 25, _("~C~ancel"), 0, GUI::kCloseCmd); } @@ -113,6 +120,11 @@ void MystOptionsDialog::open() { _showMapButton->setEnabled(_vm->_scriptParser && _vm->_scriptParser->getMap()); + // Return to menu button is not enabled on the menu + if (_returnToMenuButton) + _returnToMenuButton->setEnabled(_vm->_scriptParser && + _vm->getCurStack() != kDemoStack); + // Zip mode is disabled in the demo if (_vm->getFeatures() & GF_DEMO) _zipModeCheckbox->setEnabled(false); @@ -137,6 +149,10 @@ void MystOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, ui _vm->_needsShowMap = true; close(); break; + case kMenuCmd: + _vm->_needsShowDemoMenu = true; + close(); + break; case GUI::kCloseCmd: close(); break; diff --git a/engines/mohawk/dialogs.h b/engines/mohawk/dialogs.h index 853ff30813..844c01ad26 100644 --- a/engines/mohawk/dialogs.h +++ b/engines/mohawk/dialogs.h @@ -83,6 +83,7 @@ private: GUI::CheckboxWidget *_transitionsCheckbox; GUI::ButtonWidget *_dropPageButton; GUI::ButtonWidget *_showMapButton; + GUI::ButtonWidget *_returnToMenuButton; }; #endif diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp index b3653b1fdf..35c9d478d8 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 @@ -913,7 +921,8 @@ void RivenGraphics::clearMainScreen() { } void RivenGraphics::fadeToBlack() { - // Self-explanatory + // The transition speed is forced to best here + setTransitionSpeed(kRivenTransitionSpeedBest); scheduleTransition(16); clearMainScreen(); runScheduledTransition(); diff --git a/engines/mohawk/graphics.h b/engines/mohawk/graphics.h index d7057f48cf..96357bbff1 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); @@ -194,6 +196,7 @@ public: void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392)); void runScheduledTransition(); void fadeToBlack(); + void setTransitionSpeed(uint32 speed) { _transitionSpeed = speed; } // Inventory void showInventory(); @@ -229,6 +232,7 @@ private: // Transitions int16 _scheduledTransition; Common::Rect _transitionRect; + uint32 _transitionSpeed; // Inventory void clearInventoryArea(); diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp index 342fa4e78c..eeb4594f3c 100644 --- a/engines/mohawk/myst.cpp +++ b/engines/mohawk/myst.cpp @@ -343,6 +343,7 @@ Common::Error MohawkEngine_Myst::run() { case Common::KEYCODE_F5: _needsPageDrop = false; _needsShowMap = false; + _needsShowDemoMenu = false; runDialog(*_optionsDialog); @@ -355,6 +356,11 @@ Common::Error MohawkEngine_Myst::run() { _scriptParser->showMap(); _needsShowMap = false; } + + if (_needsShowDemoMenu) { + changeToStack(kDemoStack, 2002, 0, 0); + _needsShowDemoMenu = false; + } break; default: break; diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h index ebcc3b445c..02f0a46e3f 100644 --- a/engines/mohawk/myst.h +++ b/engines/mohawk/myst.h @@ -167,6 +167,7 @@ public: bool _needsUpdate; bool _needsPageDrop; bool _needsShowMap; + bool _needsShowDemoMenu; MystView _view; MystGraphics *_gfx; diff --git a/engines/mohawk/myst_stacks/demo.cpp b/engines/mohawk/myst_stacks/demo.cpp index 5788f4b3a3..c9e806655e 100644 --- a/engines/mohawk/myst_stacks/demo.cpp +++ b/engines/mohawk/myst_stacks/demo.cpp @@ -20,16 +20,20 @@ * */ +#include "mohawk/cursors.h" +#include "mohawk/graphics.h" #include "mohawk/myst.h" #include "mohawk/myst_stacks/demo.h" -#include "gui/message.h" +#include "common/system.h" namespace Mohawk { namespace MystStacks { Demo::Demo(MohawkEngine_Myst *vm) : Intro(vm) { setupOpcodes(); + + _returnToMenuStep = 0; } Demo::~Demo() { @@ -47,15 +51,12 @@ Demo::~Demo() { void Demo::setupOpcodes() { // "Stack-Specific" Opcodes - OVERRIDE_OPCODE(100, opcode_100); - OPCODE(101, opcode_101); - OPCODE(102, opcode_102); + OVERRIDE_OPCODE(100, o_stopIntro); + OPCODE(101, o_fadeFromBlack); + OPCODE(102, o_fadeToBlack); // "Init" Opcodes - OVERRIDE_OPCODE(201, opcode_201); - - // "Exit" Opcodes - OVERRIDE_OPCODE(300, opcode_300); + OVERRIDE_OPCODE(201, o_returnToMenu_init); } #undef OPCODE @@ -64,61 +65,66 @@ void Demo::setupOpcodes() { void Demo::disablePersistentScripts() { Intro::disablePersistentScripts(); - _enabled201 = false; + _returnToMenuRunning = false; } void Demo::runPersistentScripts() { Intro::runPersistentScripts(); - if (_enabled201) { - // Used on Card 2001, 2002 and 2003 - - // TODO: Fill in Function... + if (_returnToMenuRunning) { + returnToMenu_run(); } } -void Demo::opcode_100(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - // TODO: Fill in Function... +void Demo::o_stopIntro(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Unk", op); + // The original also seems to stop the movies. Not needed with this engine. + _vm->_gfx->fadeToBlack(); } -void Demo::opcode_101(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); - - // Used on Card 2000, 2002 and 2003 - // Triggered by Click - if (argc == 0) { - // TODO: Fill in Logic.. Fade in? - } else - unknown(op, var, argc, argv); +void Demo::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Fade from black", op); + _vm->_gfx->fadeFromBlack(); } -void Demo::opcode_102(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); - - // Used on Card 2002 and 2003 - // Triggered by Click - if (argc == 0) { - // TODO: Fill in Logic.. Fade out? - } else - unknown(op, var, argc, argv); +void Demo::o_fadeToBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Fade to black", op); + _vm->_gfx->fadeToBlack(); } -void Demo::opcode_201(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); - - // Used on Card 2001, 2002 and 2003 - if (argc == 0) - _enabled201 = true; - else - unknown(op, var, argc, argv); +void Demo::returnToMenu_run() { + uint32 time = _vm->_system->getMillis(); + + if (time < _returnToMenuNextTime) + return; + + switch (_returnToMenuStep){ + case 0: + _vm->_gfx->fadeToBlack(); + _vm->changeToCard(2003, true); + _vm->_gfx->fadeFromBlack(); + + _returnToMenuStep++; + break; + case 1: + _vm->_gfx->fadeToBlack(); + _vm->changeToCard(2001, true); + _vm->_gfx->fadeFromBlack(); + _vm->_cursor->showCursor(); + + _returnToMenuStep++; + break; + default: + break; + } } +void Demo::o_returnToMenu_init(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Return to menu init", op); -void Demo::opcode_300(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - // Used on Card 2000 - varUnusedCheck(op, var); - - // TODO: Fill in Function... + // Used on Card 2001, 2002 and 2003 + _returnToMenuNextTime = _vm->_system->getMillis() + 5000; + _returnToMenuRunning = true; } } // End of namespace MystStacks diff --git a/engines/mohawk/myst_stacks/demo.h b/engines/mohawk/myst_stacks/demo.h index 4f8d68759b..c3e57cf7ae 100644 --- a/engines/mohawk/myst_stacks/demo.h +++ b/engines/mohawk/myst_stacks/demo.h @@ -46,15 +46,19 @@ public: private: void setupOpcodes(); - DECLARE_OPCODE(opcode_100); - DECLARE_OPCODE(opcode_101); - DECLARE_OPCODE(opcode_102); + DECLARE_OPCODE(o_stopIntro); + DECLARE_OPCODE(o_fadeFromBlack); + DECLARE_OPCODE(o_fadeToBlack); - DECLARE_OPCODE(opcode_201); + DECLARE_OPCODE(o_returnToMenu_init); DECLARE_OPCODE(opcode_300); - bool _enabled201; + bool _returnToMenuRunning; + uint16 _returnToMenuStep; // 42 + uint32 _returnToMenuNextTime; // 6 + + void returnToMenu_run(); }; } // End of namespace MystStacks 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..1b72c85d96 100644 --- a/engines/mohawk/myst_stacks/preview.cpp +++ b/engines/mohawk/myst_stacks/preview.cpp @@ -54,86 +54,187 @@ Preview::~Preview() { void Preview::setupOpcodes() { // "Stack-Specific" Opcodes - OVERRIDE_OPCODE(196, opcode_196); - OVERRIDE_OPCODE(197, opcode_197); - OVERRIDE_OPCODE(198, opcode_198); - OVERRIDE_OPCODE(199, opcode_199); + OVERRIDE_OPCODE(196, o_fadeToBlack); + OVERRIDE_OPCODE(197, o_fadeFromBlack); + OVERRIDE_OPCODE(198, o_stayHere); + OVERRIDE_OPCODE(199, o_speechStop); // "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::opcode_196(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); +void Preview::disablePersistentScripts() { + Myst::disablePersistentScripts(); +} + +void Preview::runPersistentScripts() { + Myst::runPersistentScripts(); - // Used on Card ... - // TODO: Finish Implementation... - // Voice Over and Card Advance? + if (_speechRunning) + speech_run(); } -void Preview::opcode_197(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); +void Preview::o_fadeToBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Fade to black", op); + _vm->_gfx->fadeToBlack(); +} - // Used on Card ... - // TODO: Finish Implementation... - // Voice Over and Card Advance? +void Preview::o_fadeFromBlack(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Fade from black", op); + _vm->_gfx->fadeFromBlack(); } -// TODO: Merge with Opcode 42? -void Preview::opcode_198(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); +void Preview::o_stayHere(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Stay here dialog", op); - if (argc == 0) { - // Nuh-uh! No leaving the library in the demo! - GUI::MessageDialog dialog("You can't leave the library in the demo."); - dialog.runModal(); - } else - unknown(op, var, argc, argv); + // Nuh-uh! No leaving the library in the demo! + GUI::MessageDialog dialog("You can't leave the library in the demo."); + dialog.runModal(); } -void Preview::opcode_199(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - varUnusedCheck(op, var); +void Preview::o_speechStop(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Speech stop", op); - // Used on Card ... - // TODO: Finish Implementation... - // Voice Over and Card Advance? + _speechRunning = false; + _globals.currentAge = 2; } -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<MystResourceType8 *>(_invokingResource); } } // End of namespace MystStacks diff --git a/engines/mohawk/myst_stacks/preview.h b/engines/mohawk/myst_stacks/preview.h index 7e4e418eef..1e4ff3efb4 100644 --- a/engines/mohawk/myst_stacks/preview.h +++ b/engines/mohawk/myst_stacks/preview.h @@ -40,16 +40,31 @@ public: Preview(MohawkEngine_Myst *vm); ~Preview(); + void disablePersistentScripts(); + void runPersistentScripts(); + private: void setupOpcodes(); - DECLARE_OPCODE(opcode_196); - DECLARE_OPCODE(opcode_197); - DECLARE_OPCODE(opcode_198); - DECLARE_OPCODE(opcode_199); + DECLARE_OPCODE(o_fadeToBlack); + DECLARE_OPCODE(o_fadeFromBlack); + DECLARE_OPCODE(o_stayHere); + DECLARE_OPCODE(o_speechStop); + + 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 - DECLARE_OPCODE(opcode_298); - DECLARE_OPCODE(opcode_299); + void speech_run(); + void speechUpdateCue(); }; } // End of namespace MystStacks diff --git a/engines/mohawk/myst_stacks/slides.cpp b/engines/mohawk/myst_stacks/slides.cpp index e9bb91c84d..943cb90071 100644 --- a/engines/mohawk/myst_stacks/slides.cpp +++ b/engines/mohawk/myst_stacks/slides.cpp @@ -61,18 +61,26 @@ void Slides::disablePersistentScripts() { void Slides::runPersistentScripts() { if (_cardSwapEnabled) { // Used on Cards... - if (_vm->_system->getMillis() > _nextCardTime) + if (_vm->_system->getMillis() > _nextCardTime) { + _vm->_gfx->fadeToBlack(); _vm->changeToCard(_nextCardID, true); + _vm->_gfx->fadeFromBlack(); + } } } void Slides::o_returnToMenu(uint16 op, uint16 var, uint16 argc, uint16 *argv) { + debugC(kDebugScript, "Opcode %d: Return to menu", op); + // Go to the information screens of the menu _vm->changeToStack(kDemoStack, 2002, 0, 0); } void Slides::o_setCardSwap(uint16 op, uint16 var, uint16 argc, uint16 *argv) { _nextCardID = argv[0]; + + debugC(kDebugScript, "Opcode %d: Set next card %d", op, _nextCardID); + _nextCardTime = _vm->_system->getMillis() + 5000; _cardSwapEnabled = true; } diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 612b8b3685..3e2fa4f979 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -150,6 +150,9 @@ Common::Error MohawkEngine_Riven::run() { return Common::kNoGameDataFoundError; } + // Set the transition speed + _gfx->setTransitionSpeed(_vars["transitionmode"]); + // Start at main cursor _cursor->setCursor(kRivenMainCursor); _cursor->showCursor(); @@ -209,8 +212,10 @@ void MohawkEngine_Riven::handleEvents() { needsUpdate = true; break; case Common::EVENT_LBUTTONDOWN: - if (_curHotspot >= 0) + if (_curHotspot >= 0) { + checkSunnerAlertClick(); runHotspotScript(_curHotspot, kMouseDownScript); + } break; case Common::EVENT_LBUTTONUP: // See RivenScript::switchCard() for more information on why we sometimes @@ -812,6 +817,138 @@ static void catherineIdleTimer(MohawkEngine_Riven *vm) { vm->installTimer(&catherineIdleTimer, timeUntilNextMovie); } +static void sunnersTopStairsTimer(MohawkEngine_Riven *vm) { + // If the sunners are gone, we have no video to play + if (vm->_vars["jsunners"] != 0) { + vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1); + uint32 timerTime = 500; + + if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) { + uint32 &sunnerTime = vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = vm->_rnd->getRandomNumberRng(2, 15) * 1000; + } else if (sunnerTime < vm->getTotalPlayTime()) { + VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(1, 3)); + + timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(2, 15) * 1000; + } + + sunnerTime = timerTime + vm->getTotalPlayTime(); + } + + vm->installTimer(&sunnersTopStairsTimer, timerTime); +} + +static void sunnersMidStairsTimer(MohawkEngine_Riven *vm) { + // If the sunners are gone, we have no video to play + if (vm->_vars["jsunners"] != 0) { + vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1); + uint32 timerTime = 500; + + if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) { + uint32 &sunnerTime = vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = vm->_rnd->getRandomNumberRng(1, 10) * 1000; + } else if (sunnerTime < vm->getTotalPlayTime()) { + // Randomize the video + int randValue = vm->_rnd->getRandomNumber(5); + uint16 movie = 4; + if (randValue == 4) + movie = 2; + else if (randValue == 5) + movie = 3; + + VideoHandle handle = vm->_video->playMovieRiven(movie); + + timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 10) * 1000; + } + + sunnerTime = timerTime + vm->getTotalPlayTime(); + } + + vm->installTimer(&sunnersMidStairsTimer, timerTime); +} + +static void sunnersLowerStairsTimer(MohawkEngine_Riven *vm) { + // If the sunners are gone, we have no video to play + if (vm->_vars["jsunners"] != 0) { + vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoHandle oldHandle = vm->_video->findVideoHandleRiven(1); + uint32 timerTime = 500; + + if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) { + uint32 &sunnerTime = vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } else if (sunnerTime < vm->getTotalPlayTime()) { + VideoHandle handle = vm->_video->playMovieRiven(vm->_rnd->getRandomNumberRng(3, 5)); + + timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } + + sunnerTime = timerTime + vm->getTotalPlayTime(); + } + + vm->installTimer(&sunnersLowerStairsTimer, timerTime); +} + +static void sunnersBeachTimer(MohawkEngine_Riven *vm) { + // If the sunners are gone, we have no video to play + if (vm->_vars["jsunners"] != 0) { + vm->removeTimer(); + return; + } + + // Play a random sunners video if the script one is not playing already + // and then set a new timer for when the new video should be played + + VideoHandle oldHandle = vm->_video->findVideoHandleRiven(3); + uint32 timerTime = 500; + + if (oldHandle == NULL_VID_HANDLE || vm->_video->endOfVideo(oldHandle)) { + uint32 &sunnerTime = vm->_vars["jsunnertime"]; + + if (sunnerTime == 0) { + timerTime = vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } else if (sunnerTime < vm->getTotalPlayTime()) { + // Unlike the other cards' scripts which automatically + // activate the MLST, we have to set it manually here. + uint16 mlstID = vm->_rnd->getRandomNumberRng(3, 8); + vm->_video->activateMLST(mlstID, vm->getCurCard()); + VideoHandle handle = vm->_video->playMovieRiven(mlstID); + + timerTime = vm->_video->getDuration(handle) + vm->_rnd->getRandomNumberRng(1, 30) * 1000; + } + + sunnerTime = timerTime + vm->getTotalPlayTime(); + } + + vm->installTimer(&sunnersBeachTimer, timerTime); +} + void MohawkEngine_Riven::installCardTimer() { switch (getCurCardRMAP()) { case 0x3a85: // Top of elevator on prison island @@ -819,16 +956,16 @@ void MohawkEngine_Riven::installCardTimer() { installTimer(&catherineIdleTimer, _rnd->getRandomNumberRng(1, 33) * 1000); break; case 0x77d6: // Sunners, top of stairs - // TODO: Background Sunner videos + installTimer(&sunnersTopStairsTimer, 500); break; case 0x79bd: // Sunners, middle of stairs - // TODO: Background Sunner videos + installTimer(&sunnersMidStairsTimer, 500); break; case 0x7beb: // Sunners, bottom of stairs - // TODO: Background Sunner videos + installTimer(&sunnersLowerStairsTimer, 500); break; case 0xb6ca: // Sunners, shoreline - // TODO: Background Sunner videos + installTimer(&sunnersBeachTimer, 500); break; } } @@ -846,6 +983,34 @@ void MohawkEngine_Riven::doVideoTimer(VideoHandle handle, bool force) { _scriptMan->runStoredMovieOpcode(); } +void MohawkEngine_Riven::checkSunnerAlertClick() { + // We need to do a manual hardcoded check for the sunners' + // alert movies. + + uint32 &sunners = _vars["jsunners"]; + + // If the sunners are gone, there's nothing for us to do + if (sunners != 0) + return; + + uint32 rmapCode = getCurCardRMAP(); + + // This is only for the mid/lower staircase sections + if (rmapCode != 0x79bd && rmapCode != 0x7beb) + return; + + // Only set the sunners variable on the forward hotspot + if ((rmapCode == 0x79bd && _curHotspot != 1) || (rmapCode == 0x7beb && _curHotspot != 2)) + return; + + // If the alert video is no longer playing, we have nothing left to do + VideoHandle handle = _video->findVideoHandleRiven(1); + if (handle == NULL_VID_HANDLE || _video->endOfVideo(handle)) + return; + + sunners = 1; +} + bool ZipMode::operator== (const ZipMode &z) const { return z.name == name && z.id == id; } diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index c7d36e585d..e99a9f78fc 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -67,6 +67,13 @@ enum { StackNames = 5 }; +enum RivenTransitionSpeed { + kRivenTransitionSpeedNone = 5000, + kRivenTransitionSpeedFastest = 5001, + kRivenTransitionSpeedNormal = 5002, + kRivenTransitionSpeedBest = 5003 +}; + // Rects for the inventory object positions (initialized in // MohawkEngine_Riven's constructor). extern Common::Rect *g_atrusJournalRect1; @@ -164,6 +171,7 @@ private: // Miscellaneous bool _gameOver; bool _ignoreNextMouseUp; + void checkSunnerAlertClick(); public: // Stack/card/script funtions diff --git a/engines/mohawk/riven_external.cpp b/engines/mohawk/riven_external.cpp index 60e94ea795..9e1365f8da 100644 --- a/engines/mohawk/riven_external.cpp +++ b/engines/mohawk/riven_external.cpp @@ -234,10 +234,10 @@ void RivenExternal::runCredits(uint16 video, uint32 delay) { // Set us up to start after delay ms nextCreditsFrameStart = _vm->_system->getMillis() + delay; } else if (_vm->_system->getMillis() >= nextCreditsFrameStart) { - // the first two frames stay on for 5 seconds + // the first two frames stay on for 4 seconds // the rest of the scroll updates happen at 30Hz if (_vm->_gfx->getCurCreditsImage() < 304) - nextCreditsFrameStart = _vm->_system->getMillis() + 5000; + nextCreditsFrameStart = _vm->_system->getMillis() + 4000; else nextCreditsFrameStart = _vm->_system->getMillis() + 1000 / 30; @@ -1889,21 +1889,42 @@ void RivenExternal::xjplaybeetle_1450(uint16 argc, uint16 *argv) { } void RivenExternal::xjlagoon700_alert(uint16 argc, uint16 *argv) { - // TODO: Sunner related + // Handle sunner reactions (mid-staircase) + + if (_vm->_vars["jsunners"] == 0) + _vm->_video->playMovieRiven(1); } void RivenExternal::xjlagoon800_alert(uint16 argc, uint16 *argv) { - // TODO: Sunner related + // Handle sunner reactions (lower-staircase) + + uint32 &sunners = _vm->_vars["jsunners"]; + + if (sunners == 0) { + // Show the sunners alert video + _vm->_video->playMovieRiven(1); + } else if (sunners == 1) { + // Show the sunners leaving if you moved forward in their "alert" status + _vm->_video->playMovieBlockingRiven(2); + _vm->_video->playMovieBlockingRiven(6); + sunners = 2; + _vm->refreshCard(); + } } void RivenExternal::xjlagoon1500_alert(uint16 argc, uint16 *argv) { - // Have the sunners move a bit as you get closer ;) + // Handle sunner reactions (beach) + uint32 &sunners = _vm->_vars["jsunners"]; + if (sunners == 0) { + // Show the sunners alert video _vm->_video->playMovieBlockingRiven(3); } else if (sunners == 1) { + // Show the sunners leaving if you moved forward in their "alert" status _vm->_video->playMovieBlockingRiven(2); sunners = 2; + _vm->refreshCard(); } } @@ -2726,6 +2747,7 @@ void RivenExternal::xtatboundary(uint16 argc, uint16 *argv) { void RivenExternal::xflies(uint16 argc, uint16 *argv) { // TODO: Activate the "flies" effect + debug(1, "STUB: xflies(): create %d %s fl%s", argv[1], (argv[0] == 0) ? "black" : "glowing", (argv[1] == 1) ? "y" : "ies"); } } // End of namespace Mohawk diff --git a/engines/mohawk/riven_vars.cpp b/engines/mohawk/riven_vars.cpp index 946e2e0496..ba5c343e07 100644 --- a/engines/mohawk/riven_vars.cpp +++ b/engines/mohawk/riven_vars.cpp @@ -268,7 +268,12 @@ static const char *variableNames[] = { }; uint32 &MohawkEngine_Riven::getStackVar(uint32 index) { - return _vars[getName(VariableNames, index)]; + Common::String name = getName(VariableNames, index); + + if (!_vars.contains(name)) + error("Could not find variable '%s' (stack variable %d)", name.c_str(), index); + + return _vars[name]; } void MohawkEngine_Riven::initVars() { @@ -299,6 +304,7 @@ void MohawkEngine_Riven::initVars() { _vars["bmagcar"] = 1; _vars["gnmagcar"] = 1; _vars["omusicplayer"] = 1; + _vars["transitionmode"] = kRivenTransitionSpeedFastest; // Randomize the telescope combination uint32 &teleCombo = _vars["tcorrectorder"]; 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)); |