diff options
author | Matthew Hoops | 2010-11-18 05:47:16 +0000 |
---|---|---|
committer | Matthew Hoops | 2010-11-18 05:47:16 +0000 |
commit | d9713965728b61b7f8e455287a595f250010399b (patch) | |
tree | 0aceaa69fafc20c9064a8ebbc9917cb409e44ae5 | |
parent | 8ebee136b6f6498bd99e667ac48298c8bdcd1133 (diff) | |
download | scummvm-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.cpp | 115 | ||||
-rw-r--r-- | engines/mohawk/myst.h | 12 | ||||
-rw-r--r-- | engines/mohawk/myst_scripts.cpp | 85 | ||||
-rw-r--r-- | engines/mohawk/myst_scripts.h | 28 |
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(); |