aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mohawk/console.cpp4
-rw-r--r--engines/mohawk/mohawk.cpp10
-rw-r--r--engines/mohawk/mohawk.h1
-rw-r--r--engines/mohawk/myst.cpp119
-rw-r--r--engines/mohawk/myst.h19
-rw-r--r--engines/mohawk/myst_saveload.h3
-rw-r--r--engines/mohawk/myst_scripts.cpp74
-rw-r--r--engines/mohawk/myst_scripts.h5
-rw-r--r--engines/mohawk/myst_scripts_myst.cpp31
-rw-r--r--engines/mohawk/myst_scripts_selenitic.cpp705
-rw-r--r--engines/mohawk/myst_scripts_selenitic.h53
-rw-r--r--engines/mohawk/resource.cpp26
-rw-r--r--engines/mohawk/resource.h1
-rw-r--r--engines/mohawk/sound.cpp21
-rw-r--r--engines/mohawk/sound.h2
15 files changed, 758 insertions, 316 deletions
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index e4fe9e0f8b..1e669c2b20 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -86,9 +86,9 @@ bool MystConsole::Cmd_Var(int argc, const char **argv) {
}
if (argc > 2)
- _vm->_varStore->setVar((uint16)atoi(argv[1]), (uint32)atoi(argv[2]));
+ _vm->_scriptParser->setVarValue((uint16)atoi(argv[1]), (uint16)atoi(argv[2]));
- DebugPrintf("%d = %d\n", (uint16)atoi(argv[1]), _vm->_varStore->getVar((uint16)atoi(argv[1])));
+ DebugPrintf("%d = %d\n", (uint16)atoi(argv[1]), _vm->_scriptParser->getVar((uint16)atoi(argv[1])));
return true;
}
diff --git a/engines/mohawk/mohawk.cpp b/engines/mohawk/mohawk.cpp
index 623f251e1a..fbe52da998 100644
--- a/engines/mohawk/mohawk.cpp
+++ b/engines/mohawk/mohawk.cpp
@@ -134,4 +134,14 @@ uint16 MohawkEngine::findResourceID(uint32 tag, const Common::String &resName) {
return 0xFFFF;
}
+Common::String MohawkEngine::getResourceName(uint32 tag, uint16 id) {
+ for (uint32 i = 0; i < _mhk.size(); i++)
+ if (_mhk[i]->hasResource(tag, id)) {
+ return _mhk[i]->getName(tag, id);
+ }
+
+ error("Could not find a \'%s\' resource with ID %04x", tag2str(tag), id);
+ return 0;
+}
+
} // End of namespace Mohawk
diff --git a/engines/mohawk/mohawk.h b/engines/mohawk/mohawk.h
index e7d1902790..125296c03d 100644
--- a/engines/mohawk/mohawk.h
+++ b/engines/mohawk/mohawk.h
@@ -108,6 +108,7 @@ public:
bool hasResource(uint32 tag, const Common::String &resName);
uint32 getResourceOffset(uint32 tag, uint16 id);
uint16 findResourceID(uint32 type, const Common::String &resName);
+ Common::String getResourceName(uint32 tag, uint16 id);
void pauseGame();
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index 1a237db916..d8460e6201 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -247,12 +247,12 @@ Common::Error MohawkEngine_Myst::run() {
else if (getFeatures() & GF_DEMO)
changeToStack(kDemoStack);
else
- changeToStack(kIntroStack);
+ changeToStack(kSeleniticStack);
if (getFeatures() & GF_DEMO)
changeToCard(2000);
else
- changeToCard(1);
+ changeToCard(1282);
// Load game from launcher/command line if requested
if (ConfMan.hasKey("save_slot") && !(getFeatures() & GF_DEMO)) {
@@ -416,10 +416,10 @@ void MohawkEngine_Myst::changeToCard(uint16 card) {
// Handle images
if (_view.conditionalImageCount != 0) {
for (uint16 i = 0; i < _view.conditionalImageCount; i++) {
- if (_varStore->getVar(_view.conditionalImages[i].var) < _view.conditionalImages[i].numStates)
- _gfx->copyImageToScreen(_view.conditionalImages[i].values[_varStore->getVar(_view.conditionalImages[i].var)], Common::Rect(0, 0, 544, 333));
+ if (_scriptParser->getVar(_view.conditionalImages[i].var) < _view.conditionalImages[i].numStates)
+ _gfx->copyImageToScreen(_view.conditionalImages[i].values[_scriptParser->getVar(_view.conditionalImages[i].var)], Common::Rect(0, 0, 544, 333));
else
- warning("Conditional image %d variable %d: %d exceeds maximum state of %d", i, _view.conditionalImages[i].var, _varStore->getVar(_view.conditionalImages[i].var), _view.conditionalImages[i].numStates-1);
+ warning("Conditional image %d variable %d: %d exceeds maximum state of %d", i, _view.conditionalImages[i].var, _scriptParser->getVar(_view.conditionalImages[i].var), _view.conditionalImages[i].numStates-1);
}
} else if (_view.mainImage != 0)
_gfx->copyImageToScreen(_view.mainImage, Common::Rect(0, 0, 544, 333));
@@ -429,7 +429,7 @@ void MohawkEngine_Myst::changeToCard(uint16 card) {
uint16 soundActionVolume = 0;
if (_view.sound == kMystSoundActionConditional) {
- uint16 soundVarValue = _varStore->getVar(_view.soundVar);
+ uint16 soundVarValue = _scriptParser->getVar(_view.soundVar);
if (soundVarValue >= _view.soundCount)
warning("Conditional sound variable outside range");
else {
@@ -846,7 +846,7 @@ void MohawkEngine_Myst::checkCursorHints() {
for (uint16 i = 0; i < _cursorHintCount; i++)
if (_cursorHints[i].id == _curResource && _resources[_cursorHints[i].id]->isEnabled()) {
if (_cursorHints[i].cursor == -1) {
- uint16 var_value = _varStore->getVar(_cursorHints[i].variableHint.var);
+ uint16 var_value = _scriptParser->getVar(_cursorHints[i].variableHint.var);
if (var_value >= _cursorHints[i].variableHint.numStates)
warning("Variable %d Out of Range in variable HINT Resource %d", _cursorHints[i].variableHint.var, i);
@@ -1111,7 +1111,7 @@ void MystResourceType7::drawDataToScreen() {
else if (_numSubResources != 0)
warning("Type 7 Resource with _numSubResources of %d, but no control variable", _numSubResources);
} else {
- uint16 varValue = _vm->_varStore->getVar(_var7);
+ uint16 varValue = _vm->_scriptParser->getVar(_var7);
if (_numSubResources == 1 && varValue != 0)
_subResources[0]->drawDataToScreen();
@@ -1131,7 +1131,7 @@ void MystResourceType7::handleAnimation() {
else if (_numSubResources != 0)
warning("Type 7 Resource with _numSubResources of %d, but no control variable", _numSubResources);
} else {
- uint16 varValue = _vm->_varStore->getVar(_var7);
+ uint16 varValue = _vm->_scriptParser->getVar(_var7);
if (_numSubResources == 1 && varValue != 0)
_subResources[0]->handleAnimation();
@@ -1151,7 +1151,7 @@ void MystResourceType7::handleMouseUp() {
else if (_numSubResources != 0)
warning("Type 7 Resource with _numSubResources of %d, but no control variable", _numSubResources);
} else {
- uint16 varValue = _vm->_varStore->getVar(_var7);
+ uint16 varValue = _vm->_scriptParser->getVar(_var7);
if (_numSubResources == 1 && varValue != 0)
_subResources[0]->handleMouseUp();
@@ -1171,7 +1171,7 @@ void MystResourceType7::handleMouseDown() {
else if (_numSubResources != 0)
warning("Type 7 Resource with _numSubResources of %d, but no control variable", _numSubResources);
} else {
- uint16 varValue = _vm->_varStore->getVar(_var7);
+ uint16 varValue = _vm->_scriptParser->getVar(_var7);
if (_numSubResources == 1 && varValue != 0)
_subResources[0]->handleMouseDown();
@@ -1191,7 +1191,7 @@ void MystResourceType7::handleMouseEnter() {
else if (_numSubResources != 0)
warning("Type 7 Resource with _numSubResources of %d, but no control variable", _numSubResources);
} else {
- uint16 varValue = _vm->_varStore->getVar(_var7);
+ uint16 varValue = _vm->_scriptParser->getVar(_var7);
if (_numSubResources == 1 && varValue != 0)
_subResources[0]->handleMouseEnter();
@@ -1211,7 +1211,7 @@ void MystResourceType7::handleMouseLeave() {
else if (_numSubResources != 0)
warning("Type 7 Resource with _numSubResources of %d, but no control variable", _numSubResources);
} else {
- uint16 varValue = _vm->_varStore->getVar(_var7);
+ uint16 varValue = _vm->_scriptParser->getVar(_var7);
if (_numSubResources == 1 && varValue != 0)
_subResources[0]->handleMouseLeave();
@@ -1277,7 +1277,7 @@ void MystResourceType8::drawDataToScreen() {
} else if (_numSubImages != 0)
warning("Type 8 Resource with _numSubImages of %d, but no control variable", _numSubImages);
} else {
- uint16 varValue = _vm->_varStore->getVar(_var8);
+ uint16 varValue = _vm->_scriptParser->getVar(_var8);
if (_numSubImages == 1 && varValue != 0) {
subImageId = 0;
@@ -1306,8 +1306,54 @@ void MystResourceType8::drawDataToScreen() {
imageToDraw = _vm->_view.mainImage;
else {
for (uint16 i = 0; i < _vm->_view.conditionalImageCount; i++)
- if (_vm->_varStore->getVar(_vm->_view.conditionalImages[i].var) < _vm->_view.conditionalImages[i].numStates)
- imageToDraw = _vm->_view.conditionalImages[i].values[_vm->_varStore->getVar(_vm->_view.conditionalImages[i].var)];
+ if (_vm->_scriptParser->getVar(_vm->_view.conditionalImages[i].var) < _vm->_view.conditionalImages[i].numStates)
+ imageToDraw = _vm->_view.conditionalImages[i].values[_vm->_scriptParser->getVar(_vm->_view.conditionalImages[i].var)];
+ }
+ } else
+ imageToDraw = _subImages[subImageId].wdib;
+
+ _vm->_gfx->copyImageSectionToScreen(imageToDraw, _subImages[subImageId].rect, _rect);
+ }
+}
+
+void MystResourceType8::drawConditionalDataToScreen(uint16 state) {
+ // Need to call overidden Type 7 function to ensure
+ // switch section is processed correctly.
+ MystResourceType7::drawDataToScreen();
+
+ bool drawSubImage = false;
+ int16 subImageId = 0;
+
+
+ if (_numSubImages == 1 && state != 0) {
+ subImageId = 0;
+ drawSubImage = true;
+ } else if (_numSubImages != 0) {
+ if (state < _numSubImages) {
+ subImageId = state;
+ drawSubImage = true;
+ } else
+ warning("Type 8 Image Var %d: %d exceeds number of subImages %d", _var8, state, _numSubImages);
+ }
+
+
+ if (drawSubImage) {
+ uint16 imageToDraw = 0;
+
+ if (_subImages[subImageId].wdib == 0xFFFF) {
+ // TODO: Think the reason for problematic screen updates in some rects is that they
+ // are these -1 cases.
+ // They need to be redrawn i.e. if the Myst marker switches are changed, but I don't think
+ // the rects are valid. This does not matter in the original engine as the screen update redraws
+ // the VIEW images, followed by the RLST resource images, and -1 for the WDIB is interpreted as
+ // "Do Not Draw Image" i.e so the VIEW image is shown through.. We need to fix screen update
+ // to do this same behaviour.
+ if (_vm->_view.conditionalImageCount == 0)
+ imageToDraw = _vm->_view.mainImage;
+ else {
+ for (uint16 i = 0; i < _vm->_view.conditionalImageCount; i++)
+ if (_vm->_scriptParser->getVar(_vm->_view.conditionalImages[i].var) < _vm->_view.conditionalImages[i].numStates)
+ imageToDraw = _vm->_view.conditionalImages[i].values[_vm->_scriptParser->getVar(_vm->_view.conditionalImages[i].var)];
}
} else
imageToDraw = _subImages[subImageId].wdib;
@@ -1380,8 +1426,22 @@ MystResourceType10::~MystResourceType10() {
delete[] _lists[i].list;
}
+void MystResourceType10::handleMouseDown() {
+ _mouseDown = true;
+
+ _vm->_scriptParser->runOpcode(_mouseDownOpcode);
+}
+
void MystResourceType10::handleMouseUp() {
- // TODO
+ _mouseDown = false;
+
+ _vm->_scriptParser->runOpcode(_mouseUpOpcode);
+}
+
+void MystResourceType10::handleAnimation() {
+ if (_mouseDown) {
+ _vm->_scriptParser->runOpcode(_mouseDragOpcode);
+ }
}
MystResourceType11::MystResourceType11(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) : MystResourceType8(vm, rlstStream, parent) {
@@ -1433,7 +1493,7 @@ MystResourceType11::MystResourceType11(MohawkEngine_Myst *vm, Common::SeekableRe
}
}
- warning("TODO: Card contains Type 11 Resource - Function not yet implemented");
+ _mouseDown = false;
}
MystResourceType11::~MystResourceType11() {
@@ -1441,16 +1501,21 @@ MystResourceType11::~MystResourceType11() {
delete[] _lists[i].list;
}
+void MystResourceType11::handleMouseDown() {
+ _mouseDown = true;
+
+ _vm->_scriptParser->runOpcode(_mouseDownOpcode);
+}
+
void MystResourceType11::handleMouseUp() {
- // TODO
-
- // HACK: Myst Card 4059 (Fireplace Code Book) to usuable state
- if (_mouseDownOpcode == 191) {
- uint16 tmp = _vm->_varStore->getVar(0);
- if (tmp > 0)
- _vm->_varStore->setVar(0, tmp - 1);
- } else if (_mouseDownOpcode == 190) {
- _vm->_varStore->setVar(0, _vm->_varStore->getVar(0) + 1);
+ _mouseDown = false;
+
+ _vm->_scriptParser->runOpcode(_mouseUpOpcode);
+}
+
+void MystResourceType11::handleAnimation() {
+ if (_mouseDown) {
+ _vm->_scriptParser->runOpcode(_mouseDragOpcode);
}
}
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 3126fdd4fc..fcd9e709a3 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -157,6 +157,7 @@ public:
bool contains(Common::Point point) { return _rect.contains(point); }
virtual void drawDataToScreen() {}
+ virtual void drawConditionalDataToScreen(uint16 state) {}
virtual void handleAnimation() {}
virtual Common::Rect getRect() { return _rect; }
bool isEnabled() { return _enabled; }
@@ -232,15 +233,17 @@ public:
MystResourceType8(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent);
virtual ~MystResourceType8();
void drawDataToScreen();
+ void drawConditionalDataToScreen(uint16 state);
uint16 getType8Var();
-protected:
- uint16 _var8;
- uint16 _numSubImages;
struct SubImage {
uint16 wdib;
Common::Rect rect;
} *_subImages;
+
+protected:
+ uint16 _var8;
+ uint16 _numSubImages;
};
// No MystResourceType9!
@@ -249,6 +252,8 @@ class MystResourceType10 : public MystResourceType8 {
public:
MystResourceType10(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent);
virtual ~MystResourceType10();
+ void handleAnimation();
+ void handleMouseDown();
void handleMouseUp();
protected:
@@ -263,12 +268,16 @@ protected:
uint16 listCount;
uint16 *list;
} _lists[4];
+
+ bool _mouseDown;
};
class MystResourceType11 : public MystResourceType8 {
public:
MystResourceType11(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent);
virtual ~MystResourceType11();
+ void handleAnimation();
+ void handleMouseDown();
void handleMouseUp();
protected:
@@ -283,6 +292,8 @@ protected:
uint16 listCount;
uint16 *list;
} _lists[3];
+
+ bool _mouseDown;
};
class MystResourceType12 : public MystResourceType8 {
@@ -366,6 +377,7 @@ public:
MystGraphics *_gfx;
MystSaveLoad *_saveLoad;
MystScriptParser *_scriptParser;
+ Common::Array<MystResource*> _resources;
bool _showResourceRects;
void setResourceEnabled(uint16 resourceId, bool enable);
@@ -400,7 +412,6 @@ private:
void loadHelp(uint16 id);
- Common::Array<MystResource*> _resources;
void loadResources();
void drawResourceRects();
void checkCurrentResource();
diff --git a/engines/mohawk/myst_saveload.h b/engines/mohawk/myst_saveload.h
index 33dd9a7e07..f24d1addc3 100644
--- a/engines/mohawk/myst_saveload.h
+++ b/engines/mohawk/myst_saveload.h
@@ -201,10 +201,11 @@ public:
void initMystVariables(MystVariables *_tv);
void debug_printMystVariables(MystVariables *_tv);
+
+ MystVariables *_v;
private:
MohawkEngine_Myst *_vm;
Common::SaveFileManager *_saveFileMan;
- MystVariables *_v;
};
} // End of namespace Mohawk
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 976a6d50a6..fcc2680faa 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -97,7 +97,8 @@ void MystScriptParser::setupOpcodes() {
OPCODE(7, opcode_7),
OPCODE(8, opcode_8),
OPCODE(9, opcode_9),
- // Opcode 10 to 11 Not Present
+ OPCODE(10, opcode_10),
+ // Opcode 11 Not Present
OPCODE(12, altDest),
OPCODE(13, altDest),
OPCODE(14, opcode_14),
@@ -111,7 +112,7 @@ void MystScriptParser::setupOpcodes() {
OPCODE(22, opcode_22),
OPCODE(23, opcode_23),
OPCODE(24, playSound),
- // Opcode 25 Not Present
+ // Opcode 25 Not Present, original calls replaceSound
OPCODE(26, opcode_26),
OPCODE(27, playSoundBlocking),
OPCODE(28, opcode_28),
@@ -211,6 +212,22 @@ MystScript MystScriptParser::readScript(Common::SeekableReadStream *stream, Myst
return script;
}
+uint16 MystScriptParser::getVar(uint16 var) {
+ warning("Unimplemented var getter 0x%02x (%d)", var, var);
+ return _vm->_varStore->getVar(var);
+}
+
+void MystScriptParser::toggleVar(uint16 var) {
+ warning("Unimplemented var toggle 0x%02x (%d)", var, var);
+ _vm->_varStore->setVar(var, (_vm->_varStore->getVar(var) + 1) % 2);
+}
+
+bool MystScriptParser::setVarValue(uint16 var, uint16 value) {
+ warning("Unimplemented var setter 0x%02x (%d)", var, var);
+ _vm->_varStore->setVar(var, value);
+ return false;
+}
+
// NOTE: Check to be used on Opcodes where var is thought
// not to be used. This emits a warning if var is nonzero.
// It is possible that the opcode does use var 0 in this case,
@@ -240,33 +257,19 @@ void MystScriptParser::NOP(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
}
void MystScriptParser::toggleBoolean(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc == 0) {
- debugC(kDebugScript, "Opcode %d: toggleBoolean() var %d", op, var);
- // HACK: This Mech Card seems to be a special case... Are there others,
- // or a more general definition of this opcode?
- if (_vm->getCurStack() == kMechanicalStack && _vm->getCurCard() == 6267)
- _vm->_varStore->setVar(var, (_vm->_varStore->getVar(var) + 1) % 10);
- else
- _vm->_varStore->setVar(var, !_vm->_varStore->getVar(var));
- } else
- unknown(op, var, argc, argv);
+ toggleVar(var);
}
void MystScriptParser::setVar(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc == 1) {
- debugC(kDebugScript, "Opcode %d: setVar var %d = %d", op, var, argv[0]);
-
- _vm->_varStore->setVar(var, argv[0]);
- } else
- unknown(op, var, argc, argv);
+ setVarValue(var, argv[0]);
}
void MystScriptParser::altDest(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
if (argc == 1) {
// TODO: Work out any differences between opcode 2, 12 and 13..
- debugC(kDebugScript, "Opcode %d: altDest var %d: %d", op, var, _vm->_varStore->getVar(var));
+ debugC(kDebugScript, "Opcode %d: altDest var %d: %d", op, var, getVar(var));
- if (_vm->_varStore->getVar(var))
+ if (getVar(var))
_vm->changeToCard(argv[0]);
else if (_invokingResource != NULL)
_vm->changeToCard(_invokingResource->getDest());
@@ -282,17 +285,17 @@ void MystScriptParser::takePage(uint16 op, uint16 var, uint16 argc, uint16 *argv
debugC(kDebugScript, "Opcode %d: takePage Var %d CursorId %d", op, var, cursorId);
- if (_vm->_varStore->getVar(var)) {
+ if (getVar(var)) {
_vm->setMainCursor(cursorId);
- _vm->_varStore->setVar(var, 0);
+ setVarValue(var, 0);
// Return pages that are already held
if (var == 102)
- _vm->_varStore->setVar(103, 1);
+ setVarValue(103, 1);
if (var == 103)
- _vm->_varStore->setVar(102, 1);
+ setVarValue(102, 1);
}
} else
unknown(op, var, argc, argv);
@@ -306,7 +309,7 @@ void MystScriptParser::opcode_4(uint16 op, uint16 var, uint16 argc, uint16 *argv
// as it breaks Selenitic Card 1257, though this may be due to screen update. Also,
// this may actually be a "Force Card Reload" or "VIEW conditional re-evaluation".. in
// the general case, rather than this image blit...
- uint16 var_value = _vm->_varStore->getVar(var);
+ uint16 var_value = getVar(var);
if (var_value < _vm->_view.scriptResCount) {
if (_vm->_view.scriptResources[var_value].type == 1) { // TODO: Add Symbols for Types
_vm->_gfx->copyImageToScreen(_vm->_view.scriptResources[var_value].id, Common::Rect(0, 0, 544, 333));
@@ -389,15 +392,18 @@ void MystScriptParser::opcode_9(uint16 op, uint16 var, uint16 argc, uint16 *argv
unknown(op, var, argc, argv);
}
+void MystScriptParser::opcode_10(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ varUnusedCheck(op, var);
+
+ unknown(op, var, argc, argv);
+}
+
void MystScriptParser::opcode_14(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
if (argc == 1) {
debugC(kDebugScript, "Opcode %d: Unknown, 1 Argument: %d", op, argv[0]);
debugC(kDebugScript, "\tVar: %d", var);
- // TODO: Function Unknown...
- // Function looks like it changes the Var8 of the invoking resource to argument value..
- // Most calls seem to have var = 0, but used in Myst Card 4500 (Execute Button)
- // with Var 105..
+ _invokingResource->drawConditionalDataToScreen(argv[0]);
} else
unknown(op, var, argc, argv);
}
@@ -408,7 +414,7 @@ void MystScriptParser::dropPage(uint16 op, uint16 var, uint16 argc, uint16 *argv
debugC(kDebugScript, "\tvar: %d", var);
// TODO: Need to check where this is used
- _vm->_varStore->setVar(var, 1);
+ setVarValue(var, 1);
} else
unknown(op, var, argc, argv);
}
@@ -674,8 +680,8 @@ void MystScriptParser::opcode_28(uint16 op, uint16 var, uint16 argc, uint16 *arg
imageToDraw = _vm->_view.mainImage;
else {
for (uint16 i = 0; i < _vm->_view.conditionalImageCount; i++)
- if (_vm->_varStore->getVar(_vm->_view.conditionalImages[i].var) < _vm->_view.conditionalImages[i].numStates)
- imageToDraw = _vm->_view.conditionalImages[i].values[_vm->_varStore->getVar(_vm->_view.conditionalImages[i].var)];
+ if (getVar(_vm->_view.conditionalImages[i].var) < _vm->_view.conditionalImages[i].numStates)
+ imageToDraw = _vm->_view.conditionalImages[i].values[getVar(_vm->_view.conditionalImages[i].var)];
}
_vm->_gfx->copyImageSectionToScreen(imageToDraw, rect, rect);
} else
@@ -747,7 +753,7 @@ void MystScriptParser::opcode_30(uint16 op, uint16 var, uint16 argc, uint16 *arg
} else if (soundAction == kMystSoundActionConditional) {
debugC(kDebugScript, "Conditional sound list");
uint16 condVar = argv[decodeIdx++];
- uint16 condVarValue = _vm->_varStore->getVar(condVar);
+ uint16 condVarValue = getVar(condVar);
uint16 condCount = argv[decodeIdx++];
debugC(kDebugScript, "\tcondVar: %d = %d", condVar, condVarValue);
@@ -820,7 +826,7 @@ void MystScriptParser::opcode_31(uint16 op, uint16 var, uint16 argc, uint16 *arg
debugC(kDebugScript, "\tsoundId0: %d", soundId0);
debugC(kDebugScript, "\tsoundId1: %d", soundId1);
- if (_vm->_varStore->getVar(var)) {
+ if (getVar(var)) {
if (soundId1)
_vm->_sound->playSound(soundId1);
} else {
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index 59974d9003..ea8d8b92f6 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -72,6 +72,10 @@ public:
virtual void disableInitOpcodes() = 0;
virtual void runPersistentOpcodes() = 0;
+ virtual uint16 getVar(uint16 var);
+ virtual void toggleVar(uint16 var);
+ virtual bool setVarValue(uint16 var, uint16 value);
+
DECLARE_OPCODE(unknown);
DECLARE_OPCODE(toggleBoolean);
@@ -83,6 +87,7 @@ public:
DECLARE_OPCODE(opcode_7);
DECLARE_OPCODE(opcode_8);
DECLARE_OPCODE(opcode_9);
+ DECLARE_OPCODE(opcode_10);
DECLARE_OPCODE(opcode_14);
DECLARE_OPCODE(dropPage);
DECLARE_OPCODE(opcode_16);
diff --git a/engines/mohawk/myst_scripts_myst.cpp b/engines/mohawk/myst_scripts_myst.cpp
index 7cbef15c54..9dce227318 100644
--- a/engines/mohawk/myst_scripts_myst.cpp
+++ b/engines/mohawk/myst_scripts_myst.cpp
@@ -63,6 +63,7 @@ void MystScriptParser_Myst::setupOpcodes() {
OPCODE(7, opcode_7),
OPCODE(8, opcode_8),
OPCODE(9, opcode_9),
+ OPCODE(10, opcode_10),
// TODO: Opcode 10 to 11 Not Present
OPCODE(12, altDest),
OPCODE(13, altDest),
@@ -2130,21 +2131,21 @@ void MystScriptParser_Myst::opcode_200(uint16 op, uint16 var, uint16 argc, uint1
// change is performed.
// Play Intro Movies..
- if ((_vm->getFeatures() & GF_ME) && _vm->getPlatform() == Common::kPlatformMacintosh) {
- _vm->_video->playMovieCentered(_vm->wrapMovieFilename("mattel", kIntroStack));
- _vm->_video->playMovieCentered(_vm->wrapMovieFilename("presto", kIntroStack));
- } else
- _vm->_video->playMovieCentered(_vm->wrapMovieFilename("broder", kIntroStack));
-
- _vm->_video->playMovieCentered(_vm->wrapMovieFilename("cyanlogo", kIntroStack));
-
- if (!(_vm->getFeatures() & GF_DEMO)) { // The demo doesn't have the intro video
- if ((_vm->getFeatures() & GF_ME) && _vm->getPlatform() == Common::kPlatformMacintosh)
- // intro.mov uses Sorenson, introc uses Cinepak. Otherwise, they're the same.
- _vm->_video->playMovieCentered(_vm->wrapMovieFilename("introc", kIntroStack));
- else
- _vm->_video->playMovieCentered(_vm->wrapMovieFilename("intro", kIntroStack));
- }
+// if ((_vm->getFeatures() & GF_ME) && _vm->getPlatform() == Common::kPlatformMacintosh) {
+// _vm->_video->playMovieCentered(_vm->wrapMovieFilename("mattel", kIntroStack));
+// _vm->_video->playMovieCentered(_vm->wrapMovieFilename("presto", kIntroStack));
+// } else
+// _vm->_video->playMovieCentered(_vm->wrapMovieFilename("broder", kIntroStack));
+//
+// _vm->_video->playMovieCentered(_vm->wrapMovieFilename("cyanlogo", kIntroStack));
+//
+// if (!(_vm->getFeatures() & GF_DEMO)) { // The demo doesn't have the intro video
+// if ((_vm->getFeatures() & GF_ME) && _vm->getPlatform() == Common::kPlatformMacintosh)
+// // intro.mov uses Sorenson, introc uses Cinepak. Otherwise, they're the same.
+// _vm->_video->playMovieCentered(_vm->wrapMovieFilename("introc", kIntroStack));
+// else
+// _vm->_video->playMovieCentered(_vm->wrapMovieFilename("intro", kIntroStack));
+// }
_vm->changeToCard(_vm->getCurCard()+1);
break;
diff --git a/engines/mohawk/myst_scripts_selenitic.cpp b/engines/mohawk/myst_scripts_selenitic.cpp
index c2b42f844e..dc256f4226 100644
--- a/engines/mohawk/myst_scripts_selenitic.cpp
+++ b/engines/mohawk/myst_scripts_selenitic.cpp
@@ -23,9 +23,11 @@
*
*/
+#include "mohawk/cursors.h"
#include "mohawk/myst.h"
#include "mohawk/graphics.h"
#include "mohawk/myst_scripts_selenitic.h"
+#include "mohawk/myst_saveload.h"
#include "mohawk/sound.h"
#include "mohawk/video.h"
@@ -50,8 +52,7 @@ void MystScriptParser_Selenitic::setupOpcodes() {
static const MystOpcode myst_opcodes[] = {
// "Standard" Opcodes
- { 0, &MystScriptParser::toggleBoolean, "toggleBoolean" },
- //OPCODE(0, toggleBoolean),
+ OPCODE(0, toggleBoolean),
OPCODE(1, setVar),
OPCODE(2, altDest),
OPCODE(3, takePage),
@@ -61,6 +62,7 @@ void MystScriptParser_Selenitic::setupOpcodes() {
OPCODE(7, opcode_7),
OPCODE(8, opcode_8),
OPCODE(9, opcode_9),
+ OPCODE(10, opcode_10),
// TODO: Opcode 10 to 11 Not Present
OPCODE(12, altDest),
OPCODE(13, altDest),
@@ -100,15 +102,21 @@ void MystScriptParser_Selenitic::setupOpcodes() {
// TODO: Opcodes 47 to 99 Not Present
// "Stack-Specific" Opcodes
+ SPECIFIC_OPCODE(100, opcode_100),
SPECIFIC_OPCODE(101, opcode_101),
- SPECIFIC_OPCODE(105, opcode_105),
- SPECIFIC_OPCODE(106, opcode_106),
- SPECIFIC_OPCODE(107, opcode_107),
- SPECIFIC_OPCODE(108, opcode_108),
- SPECIFIC_OPCODE(109, opcode_109),
+ SPECIFIC_OPCODE(102, opcode_102),
+ SPECIFIC_OPCODE(103, opcode_103),
+ SPECIFIC_OPCODE(104, opcode_104),
+ SPECIFIC_OPCODE(105, opcode_105_109),
+ SPECIFIC_OPCODE(106, opcode_105_109),
+ SPECIFIC_OPCODE(107, opcode_105_109),
+ SPECIFIC_OPCODE(108, opcode_105_109),
+ SPECIFIC_OPCODE(109, opcode_105_109),
SPECIFIC_OPCODE(110, opcode_110),
SPECIFIC_OPCODE(111, opcode_111),
SPECIFIC_OPCODE(115, opcode_115),
+ SPECIFIC_OPCODE(116, NOP),
+ SPECIFIC_OPCODE(117, opcode_117),
// "Init" Opcodes
SPECIFIC_OPCODE(200, opcode_200),
@@ -127,23 +135,148 @@ void MystScriptParser_Selenitic::setupOpcodes() {
}
void MystScriptParser_Selenitic::disableInitOpcodes() {
- opcode_200_disable();
- opcode_201_disable();
- opcode_202_disable();
opcode_203_disable();
- opcode_204_disable();
- opcode_205_disable();
- opcode_206_disable();
}
void MystScriptParser_Selenitic::runPersistentOpcodes() {
- opcode_200_run();
- opcode_201_run();
- opcode_202_run();
opcode_203_run();
- opcode_204_run();
- opcode_205_run();
- opcode_206_run();
+}
+
+uint16 MystScriptParser_Selenitic::getVar(uint16 var) {
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
+
+ switch(var) {
+ case 0: // Sound receiver emitters enabled
+ return selenitic_vars[4];
+ case 1:
+ return selenitic_vars[1];
+ case 2:
+ return selenitic_vars[2];
+ case 3:
+ return selenitic_vars[0];
+ case 4:
+ return selenitic_vars[3];
+ case 5: // Sound receiver opened
+ return selenitic_vars[5];
+ case 6: // Tunnel lights
+ return selenitic_vars[6];
+ case 8: // Viewer
+ return 0;
+ case 9: // Sound receiver selected source
+ return selenitic_vars[7] == 0;
+ case 10:
+ return selenitic_vars[7] == 1;
+ case 11:
+ return selenitic_vars[7] == 2;
+ case 12:
+ return selenitic_vars[7] == 3;
+ case 13:
+ return selenitic_vars[7] == 4;
+ case 14: // Sound receiver position
+ return (*_sound_receiver_position) / 1000;
+ case 15:
+ return ((*_sound_receiver_position) / 100) % 10;
+ case 16:
+ return ((*_sound_receiver_position) / 10) % 10;
+ case 17:
+ return (*_sound_receiver_position) % 10;
+ case 26:
+ return _sound_receiver_sigma_pressed;
+ default:
+ return MystScriptParser::getVar(var);
+ }
+}
+
+void MystScriptParser_Selenitic::toggleVar(uint16 var) {
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
+
+ switch(var) {
+ case 0: // Sound receiver emitters enabled
+ selenitic_vars[4] = (selenitic_vars[4] + 1) % 2;
+ break;
+ case 1:
+ selenitic_vars[1] = (selenitic_vars[1] + 1) % 2;
+ break;
+ case 2:
+ selenitic_vars[2] = (selenitic_vars[2] + 1) % 2;
+ break;
+ case 3:
+ selenitic_vars[0] = (selenitic_vars[0] + 1) % 2;
+ break;
+ case 4:
+ selenitic_vars[3] = (selenitic_vars[3] + 1) % 2;
+ break;
+ case 5: // Sound receiver opened
+ selenitic_vars[5] = (selenitic_vars[5] + 1) % 2;
+ break;
+ case 6: // Tunnel lights
+ selenitic_vars[6] = (selenitic_vars[6] + 1) % 2;
+ break;
+ default:
+ MystScriptParser::toggleVar(var);
+ break;
+ }
+}
+
+bool MystScriptParser_Selenitic::setVarValue(uint16 var, uint16 value) {
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
+ bool refresh = false;
+
+ switch (var) {
+ case 0: // Sound receiver emitters enabled
+ if (selenitic_vars[4] != value) {
+ selenitic_vars[4] = value;
+ refresh = true;
+ }
+ break;
+ case 1:
+ if (selenitic_vars[1] != value) {
+ selenitic_vars[1] = value;
+ refresh = true;
+ }
+ break;
+ case 2:
+ if (selenitic_vars[2] != value) {
+ selenitic_vars[2] = value;
+ refresh = true;
+ }
+ break;
+ case 3:
+ if (selenitic_vars[0] != value) {
+ selenitic_vars[0] = value;
+ refresh = true;
+ }
+ break;
+ case 4:
+ if (selenitic_vars[3] != value) {
+ selenitic_vars[3] = value;
+ refresh = true;
+ }
+ break;
+ case 5: // Sound receiver opened
+ if (selenitic_vars[5] != value) {
+ selenitic_vars[5] = value;
+ refresh = true;
+ }
+ break;
+ case 6: // Tunnel lights
+ if (selenitic_vars[6] != value) {
+ selenitic_vars[6] = value;
+ refresh = true;
+ }
+ break;
+ default:
+ refresh = MystScriptParser::setVarValue(var, value);
+ break;
+ }
+
+ return refresh;
+}
+
+void MystScriptParser_Selenitic::opcode_100(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ varUnusedCheck(op, var);
+
+ unknown(op, var, argc, argv);
}
void MystScriptParser_Selenitic::opcode_101(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -161,69 +294,162 @@ void MystScriptParser_Selenitic::opcode_101(uint16 op, uint16 var, uint16 argc,
unknown(op, var, argc, argv);
}
-void MystScriptParser_Selenitic::opcode_105(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc == 1) {
- uint16 soundId = argv[0];
+/**
+ * Sound receiver sigma button
+ */
+void MystScriptParser_Selenitic::opcode_102(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
+
+ _vm->_cursor->hideCursor();
+
+ _sound_receiver_current_source->drawConditionalDataToScreen(0);
+
+ uint16 *oldPosition = _sound_receiver_position;
+ uint16 source = 0;
+
+ for (uint i = 0; i < 5; i++) {
+ switch (i) {
+ case 0:
+ source = 3;
+ break;
+ case 1:
+ source = 0;
+ break;
+ case 2:
+ source = 4;
+ break;
+ case 3:
+ source = 1;
+ break;
+ case 4:
+ source = 2;
+ break;
+ }
- debugC(kDebugScript, "Opcode %d: Sound Receiver Water Button", op);
- debugC(kDebugScript, "\tvar: %d", var);
+ _sound_receiver_position = &selenitic_vars[8 + source];
+ _vm->_sound->stopSound();
+ _vm->_sound->playSound(2287);
+ sound_receiver_draw_view();
+ uint16 soundId = sound_receiver_current_sound(source, *_sound_receiver_position);
+ _vm->_sound->replaceSound(soundId);
+ _vm->_system->delayMillis(1000);
+ }
- // TODO: Complete Function including Var Change?
- _vm->_sound->playSound(soundId);
- } else
- unknown(op, var, argc, argv);
+ _sound_receiver_position = oldPosition;
+ _sound_receiver_sigma_pressed = true;
+ _vm->_sound->stopSound();
+
+ _sound_receiver_sources[selenitic_vars[7]]->drawConditionalDataToScreen(1);
+
+ sound_receiver_draw_view();
+
+ _vm->_cursor->showCursor();
}
-void MystScriptParser_Selenitic::opcode_106(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc == 1) {
- uint16 soundId = argv[0];
+/**
+ * Sound receiver right button
+ */
+void MystScriptParser_Selenitic::opcode_103(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ varUnusedCheck(op, var);
- debugC(kDebugScript, "Opcode %d: Sound Receiver Volcanic Crack Button", op);
- debugC(kDebugScript, "\tvar: %d", var);
+ sound_receiver_left_right(1);
+}
- // TODO: Complete Function including Var Change?
- _vm->_sound->playSound(soundId);
- } else
- unknown(op, var, argc, argv);
+/**
+ * Sound receiver left button
+ */
+void MystScriptParser_Selenitic::opcode_104(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ varUnusedCheck(op, var);
+
+ sound_receiver_left_right(2);
}
-void MystScriptParser_Selenitic::opcode_107(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc == 1) {
- uint16 soundId = argv[0];
+void MystScriptParser_Selenitic::sound_receiver_left_right(uint direction) {
- debugC(kDebugScript, "Opcode %d: Sound Receiver Clock Button", op);
- debugC(kDebugScript, "\tvar: %d", var);
+ if (_sound_receiver_sigma_pressed) {
+ _sound_receiver_sigma_button->drawConditionalDataToScreen(0);
+ _sound_receiver_sigma_pressed = false;
+ }
- // TODO: Complete Function including Var Change?
- _vm->_sound->playSound(soundId);
- } else
- unknown(op, var, argc, argv);
+ if (direction == 1) {
+ _sound_receiver_right_button->drawConditionalDataToScreen(1);
+ } else {
+ _sound_receiver_left_button->drawConditionalDataToScreen(1);
+ }
+
+ _vm->_sound->stopSound();
+
+ _sound_receiver_direction = direction;
+ _sound_receiver_speed = 1;
+ _sound_receiver_start_time = _vm->_system->getMillis();
+
+ sound_receiver_update();
}
-void MystScriptParser_Selenitic::opcode_108(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc == 1) {
- uint16 soundId = argv[0];
+void MystScriptParser_Selenitic::sound_receiver_update() {
+ if (_sound_receiver_direction == 1) {
+ *_sound_receiver_position = ((*_sound_receiver_position) + _sound_receiver_speed) % 3600;
+ } else if (_sound_receiver_direction == 2) {
+ *_sound_receiver_position = ((*_sound_receiver_position) - _sound_receiver_speed) % 3600;
+ }
- debugC(kDebugScript, "Opcode %d: Sound Receiver Crystal Rocks Button", op);
- debugC(kDebugScript, "\tvar: %d", var);
+ sound_receiver_draw_view();
+}
- // TODO: Complete Function including Var Change?
- _vm->_sound->playSound(soundId);
- } else
- unknown(op, var, argc, argv);
+void MystScriptParser_Selenitic::sound_receiver_draw_view() {
+ uint32 left = ((*_sound_receiver_position) * 1800) / 3600;
+
+ _sound_receiver_viewer->_subImages->rect.left = left;
+ _sound_receiver_viewer->_subImages->rect.right = left + 136;
+
+ _sound_receiver_viewer->drawConditionalDataToScreen(0);
+
+ sound_receiver_draw_angle();
+}
+
+void MystScriptParser_Selenitic::sound_receiver_draw_angle() {
+ draw_digit(_sound_receiver_angle_1);
+ draw_digit(_sound_receiver_angle_2);
+ draw_digit(_sound_receiver_angle_3);
+ draw_digit(_sound_receiver_angle_4);
}
-void MystScriptParser_Selenitic::opcode_109(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- if (argc == 1) {
- uint16 soundId = argv[0];
+void MystScriptParser_Selenitic::draw_digit(MystResource *_resource) {
+ _resource->drawConditionalDataToScreen(getVar(_resource->getType8Var()));
+}
- debugC(kDebugScript, "Opcode %d: Sound Receiver Wind Button", op);
- debugC(kDebugScript, "\tvar: %d", var);
+/**
+ * Sound receiver source selection buttons
+ */
+void MystScriptParser_Selenitic::opcode_105_109(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
- // TODO: Complete Function including Var Change?
- _vm->_sound->playSound(soundId);
- } else
- unknown(op, var, argc, argv);
+ if (_sound_receiver_sigma_pressed) {
+ _sound_receiver_sigma_button->drawConditionalDataToScreen(0);
+ _sound_receiver_sigma_pressed = false;
+ }
+
+ _vm->_cursor->hideCursor();
+
+ uint pressed_button = var - 9;
+
+ if (selenitic_vars[7] != pressed_button) {
+ selenitic_vars[7] = pressed_button;
+
+ _sound_receiver_position = &selenitic_vars[8 + pressed_button];
+ _sound_receiver_current_source = _sound_receiver_sources[pressed_button];
+
+ _vm->_sound->stopSound();
+
+ uint16 sound_id = argv[0];
+ _vm->_sound->playSound(sound_id);
+
+ _sound_receiver_current_source->drawConditionalDataToScreen(1);
+
+ sound_receiver_draw_view();
+ }
+
+ _vm->_cursor->showCursor();
}
void MystScriptParser_Selenitic::opcode_110(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -268,16 +494,7 @@ void MystScriptParser_Selenitic::opcode_110(uint16 op, uint16 var, uint16 argc,
}
void MystScriptParser_Selenitic::opcode_111(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- varUnusedCheck(op, var);
-
- if (argc == 0) {
- // Used on Card 1245 (Sound Receiver)
- // Used by Source Selection Buttons...
-
- debugC(kDebugScript, "Opcode %d: Unknown", op);
- // TODO: Fill in Function...
- } else
- unknown(op, var, argc, argv);
+ sound_receiver_update_sound();
}
void MystScriptParser_Selenitic::opcode_115(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -317,125 +534,92 @@ void MystScriptParser_Selenitic::opcode_115(uint16 op, uint16 var, uint16 argc,
unknown(op, var, argc, argv);
}
-// Selenitic Stack Movies For Maze Runner (Card 1191)
-static const char* kHCMovPathSelenitic[36] = {
- "backa1",
- "backe1",
- "backf0",
- "backf1",
- "backl0",
- "backl1",
- "backo0",
- "backo1",
- "backp0",
- "backp1",
- "backr0",
- "backr1",
- "backs0",
- "backs1",
- "forwa1",
- "forwe0",
- "forwf0",
- "forwf1",
- "forwl0",
- "forwl1",
- "forwo0",
- "forwo1",
- "forwp0",
- "forwp1",
- "forwr0",
- "forwr1",
- "forws0",
- "forws1",
- "left00",
- "left01",
- "left10",
- "left11",
- "right00",
- "right01",
- "right10",
- "right11"
-};
+void MystScriptParser_Selenitic::opcode_117(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
+ varUnusedCheck(op, var);
-static struct {
- bool enabled;
-} g_opcode200Parameters;
+ uint16 old_direction = _sound_receiver_direction;
-void MystScriptParser_Selenitic::opcode_200_run() {
- if (g_opcode200Parameters.enabled) {
- // Used on Card 1191 (Maze Runner)
+ if (_sound_receiver_direction) {
+ _sound_receiver_direction = 0;
+
+ sound_receiver_update_sound();
- // TODO: Implementation Movie Function..
- if (false) {
- _vm->_video->playMovie(_vm->wrapMovieFilename(kHCMovPathSelenitic[0], kSeleniticStack), 201, 26);
+ if (old_direction == 1) {
+ _sound_receiver_right_button->drawConditionalDataToScreen(0);
+ } else {
+ _sound_receiver_left_button->drawConditionalDataToScreen(0);
}
+
}
}
-void MystScriptParser_Selenitic::opcode_200_disable() {
- g_opcode200Parameters.enabled = false;
-}
+// Selenitic Stack Movies For Maze Runner (Card 1191)
+//static const char* kHCMovPathSelenitic[36] = {
+// "backa1",
+// "backe1",
+// "backf0",
+// "backf1",
+// "backl0",
+// "backl1",
+// "backo0",
+// "backo1",
+// "backp0",
+// "backp1",
+// "backr0",
+// "backr1",
+// "backs0",
+// "backs1",
+// "forwa1",
+// "forwe0",
+// "forwf0",
+// "forwf1",
+// "forwl0",
+// "forwl1",
+// "forwo0",
+// "forwo1",
+// "forwp0",
+// "forwp1",
+// "forwr0",
+// "forwr1",
+// "forws0",
+// "forws1",
+// "left00",
+// "left01",
+// "left10",
+// "left11",
+// "right00",
+// "right01",
+// "right10",
+// "right11"
+//};
void MystScriptParser_Selenitic::opcode_200(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
// Used for Card 1191 (Maze Runner)
if (argc == 0) {
- g_opcode200Parameters.enabled = true;
+
} else
unknown(op, var, argc, argv);
}
-static struct {
- bool enabled;
-} g_opcode201Parameters;
-
-void MystScriptParser_Selenitic::opcode_201_run() {
-
- if (g_opcode201Parameters.enabled) {
- // Used for Card 1191 (Maze Runner)
-
- // TODO: Fill in Function...
- }
-}
-
-void MystScriptParser_Selenitic::opcode_201_disable() {
- g_opcode201Parameters.enabled = false;
-}
-
void MystScriptParser_Selenitic::opcode_201(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
// Used for Card 1191 (Maze Runner)
if (argc == 0) {
- g_opcode201Parameters.enabled = true;
+
} else
unknown(op, var, argc, argv);
}
-static struct {
- bool enabled;
-} g_opcode202Parameters;
-
-void MystScriptParser_Selenitic::opcode_202_run(void) {
- if (g_opcode202Parameters.enabled) {
- // Used for Card 1191 (Maze Runner)
-
- // TODO: Fill in function...
- }
-}
-
-void MystScriptParser_Selenitic::opcode_202_disable(void) {
- g_opcode202Parameters.enabled = false;
-}
-
void MystScriptParser_Selenitic::opcode_202(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
// Used for Card 1191 (Maze Runner)
if (argc == 0) {
- g_opcode202Parameters.enabled = true;
+
} else
unknown(op, var, argc, argv);
}
@@ -446,8 +630,125 @@ static struct {
void MystScriptParser_Selenitic::opcode_203_run(void) {
if (g_opcode203Parameters.enabled) {
- // Used for Card 1245 (Sound Receiver)
- // TODO: Fill in Logic to Change Viewer Display etc.?
+ if (_sound_receiver_start_time) {
+ if (_sound_receiver_direction) {
+ uint32 current_time = _vm->_system->getMillis();
+
+ if (_sound_receiver_speed == 50) {
+ if (current_time > _sound_receiver_start_time + 500) {
+ sound_receiver_increase_speed();
+ }
+ } else {
+ if (current_time > _sound_receiver_start_time + 1000) {
+ sound_receiver_increase_speed();
+ }
+ }
+
+ if (current_time > _sound_receiver_start_time + 100) {
+ sound_receiver_update();
+ }
+
+ } else if (!_sound_receiver_sigma_pressed) {
+ sound_receiver_update_sound();
+ }
+ }
+ }
+}
+
+void MystScriptParser_Selenitic::sound_receiver_increase_speed() {
+ switch (_sound_receiver_speed) {
+ case 1:
+ _sound_receiver_speed = 10;
+ break;
+ case 10:
+ _sound_receiver_speed = 50;
+ break;
+ case 50:
+ _sound_receiver_speed = 100;
+ break;
+ }
+}
+
+void MystScriptParser_Selenitic::sound_receiver_update_sound() {
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
+
+ uint16 soundId = sound_receiver_current_sound(selenitic_vars[7], *_sound_receiver_position);
+ _vm->_sound->replaceSound(soundId);
+}
+
+uint16 MystScriptParser_Selenitic::sound_receiver_current_sound(uint16 source, uint16 position) {
+ uint16 solution;
+ bool sourceEnabled;
+ sound_receiver_solution(source, solution, sourceEnabled);
+
+ uint16 soundIdGood;
+ uint16 soundIdNear;
+ uint16 soundId = 1245;
+
+ switch (source) {
+ case 0:
+ soundIdNear = 3245;
+ soundIdGood = 3093;
+ break;
+ case 1:
+ soundIdNear = 5245;
+ soundIdGood = 5093;
+ break;
+ case 2:
+ soundIdNear = 6245;
+ soundIdGood = 6093;
+ break;
+ case 3:
+ soundIdNear = 2245;
+ soundIdGood = 2093;
+ break;
+ case 4:
+ soundIdNear = 4245;
+ soundIdGood = 4093;
+ break;
+ }
+
+ if (sourceEnabled) {
+ if (position == solution) {
+ soundId = soundIdGood;
+ } else if (position > solution && position <= solution + 50) {
+ _sound_receiver_left_button->drawConditionalDataToScreen(2);
+ _sound_receiver_left_button->drawConditionalDataToScreen(0);
+ soundId = soundIdNear;
+ } else if (position < solution && position >= solution - 50) {
+ _sound_receiver_right_button->drawConditionalDataToScreen(2);
+ _sound_receiver_right_button->drawConditionalDataToScreen(0);
+ soundId = soundIdNear;
+ }
+ }
+
+ return soundId;
+}
+
+void MystScriptParser_Selenitic::sound_receiver_solution(uint16 source, uint16 &solution, bool &enabled) {
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
+
+ switch (source) {
+ case 0:
+ enabled = selenitic_vars[0];
+ solution = 1534;
+ break;
+ case 1:
+ enabled = selenitic_vars[1];
+ solution = 1303;
+ break;
+ case 2:
+ enabled = selenitic_vars[2];
+ solution = 556;
+ break;
+ case 3:
+ enabled = selenitic_vars[3];
+ solution = 150;
+ break;
+ case 4:
+ enabled = selenitic_vars[4];
+ solution = 2122;
+ break;
}
}
@@ -459,25 +760,28 @@ void MystScriptParser_Selenitic::opcode_203(uint16 op, uint16 var, uint16 argc,
varUnusedCheck(op, var);
// Used for Card 1245 (Sound Receiver)
- if (argc == 0) {
- g_opcode203Parameters.enabled = true;
- } else
- unknown(op, var, argc, argv);
-}
-
-static struct {
- bool enabled;
-} g_opcode204Parameters;
-
-void MystScriptParser_Selenitic::opcode_204_run(void) {
- if (g_opcode204Parameters.enabled) {
- // Used for Card 1147 (Sound Code Lock)
- // TODO: Fill in code for Sound Lock...
- }
-}
-
-void MystScriptParser_Selenitic::opcode_204_disable(void) {
- g_opcode204Parameters.enabled = false;
+ g_opcode203Parameters.enabled = true;
+ uint16 *selenitic_vars = _vm->_saveLoad->_v->selenitic_vars;
+
+ _sound_receiver_right_button = _vm->_resources[0];
+ _sound_receiver_left_button = _vm->_resources[1];
+ _sound_receiver_sigma_button = _vm->_resources[2];
+ _sound_receiver_sources[4] = _vm->_resources[3];
+ _sound_receiver_sources[3] = _vm->_resources[4];
+ _sound_receiver_sources[2] = _vm->_resources[5];
+ _sound_receiver_sources[1] = _vm->_resources[6];
+ _sound_receiver_sources[0] = _vm->_resources[7];
+ _sound_receiver_viewer = static_cast<MystResourceType8 *>(_vm->_resources[8]);
+ _sound_receiver_angle_1 = _vm->_resources[10];
+ _sound_receiver_angle_2 = _vm->_resources[11];
+ _sound_receiver_angle_3 = _vm->_resources[12];
+ _sound_receiver_angle_4 = _vm->_resources[13];
+
+ uint16 current_source = selenitic_vars[7];
+ _sound_receiver_position = &selenitic_vars[8 + current_source];
+ _sound_receiver_current_source = _sound_receiver_sources[current_source];
+
+ _sound_receiver_sigma_pressed = false;
}
void MystScriptParser_Selenitic::opcode_204(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
@@ -485,58 +789,27 @@ void MystScriptParser_Selenitic::opcode_204(uint16 op, uint16 var, uint16 argc,
// Used for Card 1147 (Sound Code Lock)
if (argc == 0) {
- g_opcode204Parameters.enabled = true;
+
} else
unknown(op, var, argc, argv);
}
-static struct {
- bool enabled;
-} g_opcode205Parameters;
-
-void MystScriptParser_Selenitic::opcode_205_run(void) {
- if (g_opcode205Parameters.enabled) {
- // Used for Card 1191 (Maze Runner)
- // TODO: Fill in function...
- }
-}
-
-void MystScriptParser_Selenitic::opcode_205_disable(void) {
- g_opcode205Parameters.enabled = false;
-}
-
void MystScriptParser_Selenitic::opcode_205(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
// Used for Card 1191 (Maze Runner)
if (argc == 0) {
- g_opcode205Parameters.enabled = true;
+
} else
unknown(op, var, argc, argv);
}
-static struct {
- bool enabled;
-} g_opcode206Parameters;
-
-void MystScriptParser_Selenitic::opcode_206_run(void) {
- if (g_opcode206Parameters.enabled) {
- // Used for Card 1191 (Maze Runner)
- // TODO: Fill in function...
- }
-}
-
-void MystScriptParser_Selenitic::opcode_206_disable(void) {
- g_opcode206Parameters.enabled = false;
-}
-
void MystScriptParser_Selenitic::opcode_206(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
varUnusedCheck(op, var);
// Used for Card 1191 (Maze Runner)
-
if (argc == 0) {
- g_opcode206Parameters.enabled = true;
+
} else
unknown(op, var, argc, argv);
}
diff --git a/engines/mohawk/myst_scripts_selenitic.h b/engines/mohawk/myst_scripts_selenitic.h
index 6295d6b913..ea6e0e31f1 100644
--- a/engines/mohawk/myst_scripts_selenitic.h
+++ b/engines/mohawk/myst_scripts_selenitic.h
@@ -47,31 +47,23 @@ public:
private:
void setupOpcodes();
+ uint16 getVar(uint16 var);
+ void toggleVar(uint16 var);
+ bool setVarValue(uint16 var, uint16 value);
- void opcode_200_run();
- void opcode_200_disable();
- void opcode_201_run();
- void opcode_201_disable();
- void opcode_202_run();
- void opcode_202_disable();
void opcode_203_run();
void opcode_203_disable();
- void opcode_204_run();
- void opcode_204_disable();
- void opcode_205_run();
- void opcode_205_disable();
- void opcode_206_run();
- void opcode_206_disable();
+ DECLARE_OPCODE(opcode_100);
DECLARE_OPCODE(opcode_101);
- DECLARE_OPCODE(opcode_105);
- DECLARE_OPCODE(opcode_106);
- DECLARE_OPCODE(opcode_107);
- DECLARE_OPCODE(opcode_108);
- DECLARE_OPCODE(opcode_109);
+ DECLARE_OPCODE(opcode_102);
+ DECLARE_OPCODE(opcode_103);
+ DECLARE_OPCODE(opcode_104);
+ DECLARE_OPCODE(opcode_105_109);
DECLARE_OPCODE(opcode_110);
DECLARE_OPCODE(opcode_111);
DECLARE_OPCODE(opcode_115);
+ DECLARE_OPCODE(opcode_117);
DECLARE_OPCODE(opcode_200);
DECLARE_OPCODE(opcode_201);
@@ -80,6 +72,33 @@ private:
DECLARE_OPCODE(opcode_204);
DECLARE_OPCODE(opcode_205);
DECLARE_OPCODE(opcode_206);
+
+ bool _sound_receiver_sigma_pressed; // 6
+ MystResource *_sound_receiver_sources[5]; // 92 -> 108
+ MystResource *_sound_receiver_current_source; // 112
+ uint16 *_sound_receiver_position; // 116
+ uint16 _sound_receiver_direction; // 120
+ uint16 _sound_receiver_speed; // 122
+ uint32 _sound_receiver_start_time; //124
+ MystResourceType8 *_sound_receiver_viewer; // 128
+ MystResource *_sound_receiver_right_button; // 132
+ MystResource *_sound_receiver_left_button; // 136
+ MystResource *_sound_receiver_angle_1; // 140
+ MystResource *_sound_receiver_angle_2; // 144
+ MystResource *_sound_receiver_angle_3; // 148
+ MystResource *_sound_receiver_angle_4; // 152
+ MystResource *_sound_receiver_sigma_button; // 156
+
+ void sound_receiver_left_right(uint direction);
+ void sound_receiver_update();
+ void sound_receiver_draw_view();
+ void sound_receiver_draw_angle();
+ void sound_receiver_increase_speed();
+ void sound_receiver_update_sound();
+ uint16 sound_receiver_current_sound(uint16 source, uint16 position);
+ void sound_receiver_solution(uint16 source, uint16 &solution, bool &enabled);
+
+ void draw_digit(MystResource *_resource);
};
}
diff --git a/engines/mohawk/resource.cpp b/engines/mohawk/resource.cpp
index ee82bb4cea..abade641eb 100644
--- a/engines/mohawk/resource.cpp
+++ b/engines/mohawk/resource.cpp
@@ -260,6 +260,32 @@ bool MohawkArchive::hasResource(uint32 tag, const Common::String &resName) {
return getIDIndex(typeIndex, resName) >= 0;
}
+Common::String MohawkArchive::getName(uint32 tag, uint16 id) {
+ if (!_mhk)
+ return 0;
+
+ int16 typeIndex = getTypeIndex(tag);
+
+ if (typeIndex < 0)
+ return 0;
+
+ int16 idIndex = -1;
+
+ for (uint16 i = 0; i < _types[typeIndex].resTable.resources; i++)
+ if (_types[typeIndex].resTable.entries[i].id == id) {
+ idIndex = _types[typeIndex].resTable.entries[i].index;
+ break;
+ }
+
+ assert(idIndex >= 0);
+
+ for (uint16 i = 0; i < _types[typeIndex].nameTable.num; i++)
+ if (_types[typeIndex].nameTable.entries[i].index == idIndex)
+ return _types[typeIndex].nameTable.entries[i].name;
+
+ return 0; // not found
+}
+
uint32 MohawkArchive::getOffset(uint32 tag, uint16 id) {
assert(_mhk);
diff --git a/engines/mohawk/resource.h b/engines/mohawk/resource.h
index 675c8f3f8c..8aa186b54a 100644
--- a/engines/mohawk/resource.h
+++ b/engines/mohawk/resource.h
@@ -186,6 +186,7 @@ public:
virtual Common::SeekableReadStream *getResource(uint32 tag, uint16 id);
virtual uint32 getOffset(uint32 tag, uint16 id);
virtual uint16 findResourceID(uint32 type, const Common::String &resName);
+ Common::String getName(uint32 tag, uint16 id);
protected:
Common::SeekableReadStream *_mhk;
diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp
index d801907bd0..41d7000ad8 100644
--- a/engines/mohawk/sound.cpp
+++ b/engines/mohawk/sound.cpp
@@ -96,6 +96,8 @@ Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
audStream = Audio::makeWAVStream(_vm->getResource(ID_MSND, id), DisposeAfterUse::YES);
} else
audStream = makeMohawkWaveStream(_vm->getResource(ID_MSND, id));
+
+ handle->name = _vm->getResourceName(ID_MSND, id);
break;
case GType_ZOOMBINI:
audStream = makeMohawkWaveStream(_vm->getResource(ID_SND, id));
@@ -119,6 +121,25 @@ Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
return NULL;
}
+Audio::SoundHandle *Sound::replaceSound(uint16 id, byte volume, bool loop) {
+ debug (0, "Replacing sound %d", id);
+
+ //TODO: The original engine does fading
+
+ Common::String name = _vm->getResourceName(ID_MSND, id);
+
+ // Check if sound is already playing
+ for (uint32 i = 0; i < _handles.size(); i++) {
+ if (_vm->_mixer->isSoundHandleActive(_handles[i].handle)
+ && name.equals(_handles[i].name)) {
+ return &_handles[i].handle;
+ }
+ }
+
+ stopSound();
+ return playSound(id, volume, loop);
+}
+
void Sound::playSoundBlocking(uint16 id, byte volume) {
Audio::SoundHandle *handle = playSound(id, volume);
diff --git a/engines/mohawk/sound.h b/engines/mohawk/sound.h
index e0674500fa..386eb78991 100644
--- a/engines/mohawk/sound.h
+++ b/engines/mohawk/sound.h
@@ -66,6 +66,7 @@ struct SndHandle {
Audio::SoundHandle handle;
SndHandleType type;
uint16 id;
+ Common::String name;
};
struct SLSTSndHandle {
@@ -120,6 +121,7 @@ public:
~Sound();
Audio::SoundHandle *playSound(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false);
+ Audio::SoundHandle *replaceSound(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume, bool loop = false);
void playSoundBlocking(uint16 id, byte volume = Audio::Mixer::kMaxChannelVolume);
void playMidi(uint16 id);
void stopSound();