aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2010-11-18 05:47:16 +0000
committerMatthew Hoops2010-11-18 05:47:16 +0000
commitd9713965728b61b7f8e455287a595f250010399b (patch)
tree0aceaa69fafc20c9064a8ebbc9917cb409e44ae5
parent8ebee136b6f6498bd99e667ac48298c8bdcd1133 (diff)
downloadscummvm-rg350-d9713965728b61b7f8e455287a595f250010399b.tar.gz
scummvm-rg350-d9713965728b61b7f8e455287a595f250010399b.tar.bz2
scummvm-rg350-d9713965728b61b7f8e455287a595f250010399b.zip
MOHAWK: Cleanup Myst script handling
Scripts are now loaded from a central place and are properly freed at the correct time. This fixes a regression from r54152. svn-id: r54309
-rw-r--r--engines/mohawk/myst.cpp115
-rw-r--r--engines/mohawk/myst.h12
-rw-r--r--engines/mohawk/myst_scripts.cpp85
-rw-r--r--engines/mohawk/myst_scripts.h28
4 files changed, 101 insertions, 139 deletions
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index bed917165c..9f822eb012 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -29,7 +29,6 @@
#include "mohawk/graphics.h"
#include "mohawk/myst.h"
-#include "mohawk/myst_scripts.h"
#include "mohawk/myst_saveload.h"
#include "mohawk/dialogs.h"
#include "mohawk/resource.h"
@@ -703,44 +702,10 @@ void MohawkEngine_Myst::runInitScript() {
debugC(kDebugINIT, "Running INIT script");
Common::SeekableReadStream *initStream = getRawData(ID_INIT, _view.init);
-
- uint16 scriptCount = initStream->readUint16LE();
-
- debugC(kDebugINIT, "\tOpcode Count: %d", scriptCount);
-
- MystScriptEntry *scripts = new MystScriptEntry[scriptCount];
-
- for (uint16 i = 0; i < scriptCount; i++) {
- // TODO: u0 is likely variable reference for boolean to
- // determine whether or not to execute opcode
- uint16 u0 = initStream->readUint16LE();
- scripts[i].opcode = initStream->readUint16LE();
- // If variable indicates not to execute opcode, rewrite to NOP
- //if (!_varStore->getVar(u0))
- // scripts[i].opcode = 0xFFFF;
- scripts[i].var = initStream->readUint16LE();
- scripts[i].numValues = initStream->readUint16LE();
- scripts[i].values = new uint16[scripts[i].numValues];
-
- debugC(kDebugINIT, "\tu0: %d", u0);
- debugC(kDebugINIT, "\tOpcode %d: %s", i, _scriptParser->getOpcodeDesc(scripts[i].opcode));
- debugC(kDebugINIT, "\t\tUses Variable %d", scripts[i].var);
- debugC(kDebugINIT, "\t\tHas %d Arguments:", scripts[i].numValues);
-
- for (uint16 j = 0; j < scripts[i].numValues; j++) {
- scripts[i].values[j] = initStream->readUint16LE();
- debugC(kDebugINIT, "\t\tArgument %d: %d", j, scripts[i].values[j]);
- }
- }
-
+ MystScript script = _scriptParser->readScript(initStream, kMystScriptInit);
delete initStream;
- _scriptParser->runScript(scriptCount, scripts);
-
- for (uint16 i = 0; i < scriptCount; i++)
- delete[] scripts[i].values;
- delete[] scripts;
-
+ _scriptParser->runScript(script);
_gfx->updateScreen();
}
@@ -753,49 +718,10 @@ void MohawkEngine_Myst::runExitScript() {
debugC(kDebugEXIT, "Running EXIT script");
Common::SeekableReadStream *exitStream = getRawData(ID_EXIT, _view.exit);
-
- uint16 scriptCount = exitStream->readUint16LE();
-
- debugC(kDebugEXIT, "\tOpcode Count: %d", scriptCount);
-
- MystScriptEntry *scripts = new MystScriptEntry[scriptCount];
-
- for (uint16 i = 0; i < scriptCount; i++) {
- // TODO: u0 is likely variable reference for boolean to
- // to determine whether or not to execute opcode (i.e. door
- // close noises only when door is open).
- uint16 u0 = exitStream->readUint16LE();
- scripts[i].opcode = exitStream->readUint16LE();
- // If variable indicates not to execute opcode, rewrite to NOP
- //if (!_varStore->getVar(u0))
- // scripts[i].opcode = 0xFFFF;
- scripts[i].var = exitStream->readUint16LE();
- scripts[i].numValues = exitStream->readUint16LE();
- scripts[i].values = new uint16[scripts[i].numValues];
-
- debugC(kDebugEXIT, "\tu0: %d", u0);
- debugC(kDebugEXIT, "\tOpcode %d: %s", i, _scriptParser->getOpcodeDesc(scripts[i].opcode));
- debugC(kDebugEXIT, "\t\tUses Variable %d", scripts[i].var);
- debugC(kDebugEXIT, "\t\tHas %d Arguments:", scripts[i].numValues);
-
- for (uint16 j = 0; j < scripts[i].numValues; j++) {
- scripts[i].values[j] = exitStream->readUint16LE();
- debugC(kDebugEXIT, "\t\tArgument %d: %d", j, scripts[i].values[j]);
- }
-
- uint16 u1 = exitStream->readUint16LE();
- if (u1 != 1)
- warning("Myst EXIT u1 not 1");
- }
-
+ MystScript script = _scriptParser->readScript(exitStream, kMystScriptExit);
delete exitStream;
- _scriptParser->runScript(scriptCount, scripts);
-
- for (uint16 i = 0; i < scriptCount; i++)
- delete[] scripts[i].values;
- delete[] scripts;
-
+ _scriptParser->runScript(script);
_gfx->updateScreen();
}
@@ -1059,40 +985,11 @@ void MystResource::handleMouseUp() {
MystResourceType5::MystResourceType5(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent) : MystResource(vm, rlstStream, parent) {
debugC(kDebugResource, "\tResource Type 5 Script:");
- _scripts = NULL;
- _scriptCount = rlstStream->readUint16LE();
-
- debugC(kDebugResource, "\tOpcode Count: %d", _scriptCount);
-
- if (_scriptCount == 0)
- return;
-
- _scripts = new MystScriptEntry[_scriptCount];
- for (uint16 i = 0; i < _scriptCount; i++) {
- _scripts[i].opcode = rlstStream->readUint16LE();
- _scripts[i].var = rlstStream->readUint16LE();
- _scripts[i].numValues = rlstStream->readUint16LE();
- _scripts[i].values = new uint16[_scripts[i].numValues];
-
- debugC(kDebugResource, "\tOpcode %d: %s", i, _vm->_scriptParser->getOpcodeDesc(_scripts[i].opcode));
- debugC(kDebugResource, "\t\tUses Variable %d", _scripts[i].var);
- debugC(kDebugResource, "\t\tHas %d Arguments:", _scripts[i].numValues);
-
- for (uint16 j = 0; j < _scripts[i].numValues; j++) {
- _scripts[i].values[j] = rlstStream->readUint16LE();
- debugC(kDebugResource, "\t\tArgument %d: %d", j, _scripts[i].values[j]);
- }
- }
-}
-
-MystResourceType5::~MystResourceType5() {
- for (uint16 i = 0; i < _scriptCount; i++)
- delete[] _scripts[i].values;
- delete[] _scripts;
+ _script = vm->_scriptParser->readScript(rlstStream, kMystScriptNormal);
}
void MystResourceType5::handleMouseUp() {
- _vm->_scriptParser->runScript(_scriptCount, _scripts, this);
+ _vm->_scriptParser->runScript(_script, this);
}
// In Myst/Making of Myst, the paths are hardcoded ala Windows style without extension. Convert them.
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 29f26704f9..fb74ec83bc 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -30,6 +30,7 @@
#include "mohawk/mohawk.h"
#include "mohawk/resource_cache.h"
#include "mohawk/myst_vars.h"
+#include "mohawk/myst_scripts.h"
#include "gui/saveload.h"
@@ -147,13 +148,6 @@ struct MystView {
uint16 exit;
};
-struct MystScriptEntry {
- uint16 opcode;
- uint16 var;
- uint16 numValues;
- uint16 *values;
-};
-
class MystResource {
public:
MystResource(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent);
@@ -188,12 +182,10 @@ protected:
class MystResourceType5 : public MystResource {
public:
MystResourceType5(MohawkEngine_Myst *vm, Common::SeekableReadStream *rlstStream, MystResource *parent);
- virtual ~MystResourceType5();
void handleMouseUp();
protected:
- uint16 _scriptCount;
- MystScriptEntry *_scripts;
+ MystScript _script;
};
class MystResourceType6 : public MystResourceType5 {
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index a4b493eab4..d9f1dfa4b6 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -33,6 +33,19 @@
namespace Mohawk {
+MystScriptEntry::MystScriptEntry() {
+ type = kMystScriptNone;
+ var = 0;
+ argc = 0;
+ argv = 0;
+ u0 = 0;
+ u1 = 0;
+}
+
+MystScriptEntry::~MystScriptEntry() {
+ delete[] argv;
+}
+
const uint8 stack_map[8] = {
kSeleniticStack,
kStoneshipStack,
@@ -78,12 +91,12 @@ void MystScriptParser::setupOpcodes() {
OPCODE(2, altDest),
OPCODE(3, takePage),
OPCODE(4, opcode_4),
- // TODO: Opcode 5 Not Present
+ // Opcode 5 Not Present
OPCODE(6, opcode_6),
OPCODE(7, opcode_7),
OPCODE(8, opcode_8),
OPCODE(9, opcode_9),
- // TODO: Opcode 10 to 11 Not Present
+ // Opcode 10 to 11 Not Present
OPCODE(12, altDest),
OPCODE(13, altDest),
OPCODE(14, opcode_14),
@@ -97,7 +110,7 @@ void MystScriptParser::setupOpcodes() {
OPCODE(22, opcode_22),
OPCODE(23, opcode_23),
OPCODE(24, playSound),
- // TODO: Opcode 25 Not Present
+ // Opcode 25 Not Present
OPCODE(26, opcode_26),
OPCODE(27, playSoundBlocking),
OPCODE(28, opcode_28),
@@ -117,9 +130,9 @@ void MystScriptParser::setupOpcodes() {
OPCODE(42, opcode_42),
OPCODE(43, opcode_43),
OPCODE(44, opcode_44),
- // TODO: Opcode 45 Not Present
+ // Opcode 45 Not Present
OPCODE(46, opcode_46),
- // TODO: Opcodes 47 to 99 Not Present
+ // Opcodes 47 to 99 Not Present
// "Stack-Specific" Opcodes
OPCODE(100, opcode_100),
@@ -156,18 +169,18 @@ void MystScriptParser::setupOpcodes() {
OPCODE(131, opcode_131),
OPCODE(132, opcode_132),
OPCODE(133, opcode_133),
- // TODO: Opcodes 134 to 146 Not Present
+ // Opcodes 134 to 146 Not Present
OPCODE(147, opcode_147),
- // TODO: Opcodes 148 to 163 Not Present
+ // Opcodes 148 to 163 Not Present
OPCODE(164, opcode_164),
- // TODO: Opcodes 165 to 168 Not Present
+ // Opcodes 165 to 168 Not Present
OPCODE(169, opcode_169),
- // TODO: Opcodes 170 to 181 Not Present
+ // Opcodes 170 to 181 Not Present
OPCODE(182, opcode_182),
OPCODE(183, opcode_183),
OPCODE(184, opcode_184),
OPCODE(185, opcode_185),
- // TODO: Opcodes 186 to 195 Not Present
+ // Opcodes 186 to 195 Not Present
OPCODE(196, opcode_196), // Demo only
OPCODE(197, opcode_197), // Demo only
OPCODE(198, opcode_198),
@@ -197,7 +210,7 @@ void MystScriptParser::setupOpcodes() {
OPCODE(220, opcode_220),
OPCODE(221, opcode_221),
OPCODE(222, opcode_222),
- // TODO: Opcodes 223 to 297 Not Present
+ // Opcodes 223 to 297 Not Present
OPCODE(298, opcode_298), // Demo only
OPCODE(299, opcode_299), // Demo only
@@ -212,9 +225,9 @@ void MystScriptParser::setupOpcodes() {
OPCODE(307, opcode_307),
OPCODE(308, opcode_308),
OPCODE(309, opcode_309),
- // TODO: Opcodes 310 to 311 Not Present
+ // Opcodes 310 to 311 Not Present
OPCODE(312, opcode_312),
- // TODO: Opcodes 313 and greater Not Present
+ // Opcodes 313 and greater Not Present
OPCODE(0xFFFF, NOP)
};
@@ -251,13 +264,14 @@ void MystScriptParser::runPersistentOpcodes() {
opcode_212_run();
}
-void MystScriptParser::runScript(uint16 scriptCount, MystScriptEntry *scripts, MystResource *invokingResource) {
+void MystScriptParser::runScript(MystScript script, MystResource *invokingResource) {
_invokingResource = invokingResource;
- debugC(kDebugScript, "Script Count: %d", scriptCount);
- for (uint16 i = 0; i < scriptCount; i++) {
- debugC(kDebugScript, "\tOpcode %d: %d", i, scripts[i].opcode);
- runOpcode(scripts[i].opcode, scripts[i].var, scripts[i].numValues, scripts[i].values);
+ debugC(kDebugScript, "Script Size: %d", script->size());
+ for (uint16 i = 0; i < script->size(); i++) {
+ MystScriptEntry &entry = script->operator[](i);
+ debugC(kDebugScript, "\tOpcode %d: %d", i, entry.opcode);
+ runOpcode(entry.opcode, entry.var, entry.argc, entry.argv);
}
}
@@ -284,6 +298,41 @@ const char *MystScriptParser::getOpcodeDesc(uint16 op) {
return "";
}
+MystScript MystScriptParser::readScript(Common::SeekableReadStream *stream, MystScriptType type) {
+ assert(stream);
+ assert(type != kMystScriptNone);
+
+ MystScript script = MystScript(new Common::Array<MystScriptEntry>());
+
+ uint16 opcodeCount = stream->readUint16LE();
+ script->resize(opcodeCount);
+
+ for (uint16 i = 0; i < opcodeCount; i++) {
+ MystScriptEntry &entry = script->operator[](i);
+ entry.type = type;
+
+ // u0 only exists in INIT and EXIT scripts
+ if (type != kMystScriptNormal)
+ entry.u0 = stream->readUint16LE();
+
+ entry.opcode = stream->readUint16LE();
+ entry.var = stream->readUint16LE();
+ entry.argc = stream->readUint16LE();
+
+ if (entry.argc > 0) {
+ entry.argv = new uint16[entry.argc];
+ for (uint16 j = 0; j < entry.argc; j++)
+ entry.argv[j] = stream->readUint16LE();
+ }
+
+ // u1 exists only in EXIT scripts
+ if (type == kMystScriptExit)
+ entry.u1 = stream->readUint16LE();
+ }
+
+ return script;
+}
+
// 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,
diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h
index a996421289..af8053bacf 100644
--- a/engines/mohawk/myst_scripts.h
+++ b/engines/mohawk/myst_scripts.h
@@ -26,6 +26,7 @@
#ifndef MYST_SCRIPTS_H
#define MYST_SCRIPTS_H
+#include "common/ptr.h"
#include "common/scummsys.h"
#include "common/util.h"
@@ -34,16 +35,39 @@ namespace Mohawk {
#define DECLARE_OPCODE(x) void x(uint16 op, uint16 var, uint16 argc, uint16 *argv)
class MohawkEngine_Myst;
-struct MystScriptEntry;
+class MystResource;
+
+enum MystScriptType {
+ kMystScriptNone,
+ kMystScriptNormal,
+ kMystScriptInit,
+ kMystScriptExit
+};
+
+struct MystScriptEntry {
+ MystScriptEntry();
+ ~MystScriptEntry();
+
+ MystScriptType type;
+ uint16 u0;
+ uint16 opcode;
+ uint16 var;
+ uint16 argc;
+ uint16 *argv;
+ uint16 u1;
+};
+
+typedef Common::SharedPtr<Common::Array<MystScriptEntry> > MystScript;
class MystScriptParser {
public:
MystScriptParser(MohawkEngine_Myst *vm);
~MystScriptParser();
- void runScript(uint16 scriptCount, MystScriptEntry *scripts, MystResource* invokingResource = NULL);
+ void runScript(MystScript script, MystResource *invokingResource = NULL);
void runOpcode(uint16 op, uint16 var = 0, uint16 argc = 0, uint16 *argv = NULL);
const char *getOpcodeDesc(uint16 op);
+ MystScript readScript(Common::SeekableReadStream *stream, MystScriptType type);
void disableInitOpcodes();
void runPersistentOpcodes();