aboutsummaryrefslogtreecommitdiff
path: root/engines/mohawk
diff options
context:
space:
mode:
authorAlyssa Milburn2011-08-17 09:28:51 +0200
committerAlyssa Milburn2011-08-17 09:28:51 +0200
commitae287ccee58ebf68ab6125e5bbb4d8a44874330e (patch)
tree2f4cee4b2940466b8a578962e0174c6f89077a40 /engines/mohawk
parentf5255288eabc0527c4c6b727a9db6b8d09a31206 (diff)
parente36832bbf84cba88fe6b17e1634fab0d550f13df (diff)
downloadscummvm-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.cpp37
-rw-r--r--engines/mohawk/detection_tables.h84
-rw-r--r--engines/mohawk/dialogs.cpp18
-rw-r--r--engines/mohawk/dialogs.h1
-rw-r--r--engines/mohawk/graphics.cpp11
-rw-r--r--engines/mohawk/graphics.h4
-rw-r--r--engines/mohawk/myst.cpp6
-rw-r--r--engines/mohawk/myst.h1
-rw-r--r--engines/mohawk/myst_stacks/demo.cpp98
-rw-r--r--engines/mohawk/myst_stacks/demo.h14
-rw-r--r--engines/mohawk/myst_stacks/myst.h4
-rw-r--r--engines/mohawk/myst_stacks/preview.cpp211
-rw-r--r--engines/mohawk/myst_stacks/preview.h27
-rw-r--r--engines/mohawk/myst_stacks/slides.cpp10
-rw-r--r--engines/mohawk/riven.cpp175
-rw-r--r--engines/mohawk/riven.h8
-rw-r--r--engines/mohawk/riven_external.cpp32
-rw-r--r--engines/mohawk/riven_vars.cpp8
-rw-r--r--engines/mohawk/sound.cpp2
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));