diff options
Diffstat (limited to 'engines/mohawk/myst_scripts.cpp')
-rw-r--r-- | engines/mohawk/myst_scripts.cpp | 137 |
1 files changed, 98 insertions, 39 deletions
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp index a8cd643e2c..b67c109acc 100644 --- a/engines/mohawk/myst_scripts.cpp +++ b/engines/mohawk/myst_scripts.cpp @@ -23,6 +23,7 @@ * */ +#include "mohawk/cursors.h" #include "mohawk/myst.h" #include "mohawk/graphics.h" #include "mohawk/myst_scripts.h" @@ -33,6 +34,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 +92,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 +111,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 +131,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 +170,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 +211,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 +226,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 +265,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 +299,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, @@ -294,17 +344,16 @@ void MystScriptParser::varUnusedCheck(uint16 op, uint16 var) { } void MystScriptParser::unknown(uint16 op, uint16 var, uint16 argc, uint16 *argv) { - // NOTE: printf used here instead of debug, so unknown opcodes are always reported... - printf("Unimplemented opcode 0x%02x (%d)\n", op, op); - printf("\tUses var %d\n", var); - printf("\tArg count = %d\n", argc); - if (argc) - printf("\tArgs: "); - for (uint16 i = 0; i < argc; i++) { - if (i == argc - 1) - printf("%d\n", argv[i]); - else - printf("%d, ", argv[i]); + warning("Unimplemented opcode 0x%02x (%d)", op, op); + warning("\tUses var %d", var); + warning("\tArg count = %d", argc); + if (argc) { + Common::String str; + str += Common::String::format("%d", argv[0]); + for (uint16 i = 1; i < argc; i++) { + str += Common::String::format(", %d", argv[i]); + } + warning("\tArgs: %s\n", str.c_str()); } } @@ -382,9 +431,10 @@ void MystScriptParser::opcode_4(uint16 op, uint16 var, uint16 argc, uint16 *argv // the general case, rather than this image blit... uint16 var_value = _vm->_varStore->getVar(var); if (var_value < _vm->_view.scriptResCount) { - if (_vm->_view.scriptResources[var_value].type == 1) // TODO: Add Symbols for Types + 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)); - else + _vm->_gfx->updateScreen(); + } else warning("Opcode %d: Script Resource %d Type Not Image", op, var_value); } else warning("Opcode %d: var %d value %d outside Script Resource Range %d", op, var, var_value, _vm->_view.scriptResCount); @@ -953,7 +1003,7 @@ void MystScriptParser::opcode_35(uint16 op, uint16 var, uint16 argc, uint16 *arg debugC(kDebugScript, "\tdelay: %d", delay); _vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333)); - _vm->_system->updateScreen(); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(delay * 100); _vm->changeToCard(cardId); } else @@ -968,7 +1018,7 @@ void MystScriptParser::changeCursor(uint16 op, uint16 var, uint16 argc, uint16 * debugC(kDebugScript, "Cursor: %d", argv[0]); // TODO: Not sure if this needs to change mainCursor or similar... - _vm->_gfx->changeCursor(argv[0]); + _vm->_cursor->setCursor(argv[0]); } else unknown(op, var, argc, argv); } @@ -978,7 +1028,7 @@ void MystScriptParser::hideCursor(uint16 op, uint16 var, uint16 argc, uint16 *ar if (argc == 0) { debugC(kDebugScript, "Opcode %d: Hide Cursor", op); - _vm->_gfx->hideCursor(); + _vm->_cursor->hideCursor(); } else unknown(op, var, argc, argv); } @@ -988,7 +1038,7 @@ void MystScriptParser::showCursor(uint16 op, uint16 var, uint16 argc, uint16 *ar if (argc == 0) { debugC(kDebugScript, "Opcode %d: Show Cursor", op); - _vm->_gfx->showCursor(); + _vm->_cursor->showCursor(); } else unknown(op, var, argc, argv); } @@ -1529,7 +1579,7 @@ void MystScriptParser::opcode_102(uint16 op, uint16 var, uint16 argc, uint16 *ar debugC(kDebugScript, "\tstartTime: %d", startTime); debugC(kDebugScript, "\tendTime: %d", endTime); - printf("TODO: Opcode %d Movie Time Index %d to %d\n", op, startTime, endTime); + warning("TODO: Opcode %d Movie Time Index %d to %d", op, startTime, endTime); // TODO: Need version of playMovie blocking which allows selection // of start and finish points. _vm->_video->playMovie(_vm->wrapMovieFilename("bkroom", kStoneshipStack), 159, 99); @@ -1686,6 +1736,7 @@ void MystScriptParser::opcode_104(uint16 op, uint16 var, uint16 argc, uint16 *ar // TODO: Need to load the image ids from Script Resources structure of VIEW for (uint16 imageId = 3595; imageId <= 3601; imageId++) { _vm->_gfx->copyImageToScreen(imageId, rect); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(50); } @@ -2488,7 +2539,7 @@ void MystScriptParser::opcode_121(uint16 op, uint16 var, uint16 argc, uint16 *ar uint16 startTime = argv[0]; uint16 endTime = argv[1]; - printf("TODO: Opcode %d Movie Time Index %d to %d\n", op, startTime, endTime); + warning("TODO: Opcode %d Movie Time Index %d to %d\n", op, startTime, endTime); // TODO: Need version of playMovie blocking which allows selection // of start and finish points. _vm->_video->playMovie(_vm->wrapMovieFilename("ewindow", kMechanicalStack), 253, 0); @@ -2516,6 +2567,7 @@ void MystScriptParser::opcode_122(uint16 op, uint16 var, uint16 argc, uint16 *ar // TODO: Need to load the image ids from Script Resources structure of VIEW for (uint16 imageId = 3601; imageId >= 3595; imageId--) { _vm->_gfx->copyImageToScreen(imageId, rect); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(50); } @@ -2550,7 +2602,7 @@ void MystScriptParser::opcode_123(uint16 op, uint16 var, uint16 argc, uint16 *ar uint16 start_time = argv[0]; uint16 end_time = argv[1]; - printf("TODO: Opcode %d Movie Time Index %d to %d\n", op, start_time, end_time); + warning("TODO: Opcode %d Movie Time Index %d to %d\n", op, start_time, end_time); // TODO: Need version of playMovie blocking which allows selection // of start and finish points. // TODO: Not 100% sure about movie position @@ -3143,8 +3195,10 @@ void MystScriptParser::opcode_200_run() { else rect = Common::Rect(0, 0, 544, 333); - if (curImageIndex != lastImageIndex) + if (curImageIndex != lastImageIndex) { _vm->_gfx->copyImageToScreen(g_opcode200Parameters.imageBaseId + curImageIndex, rect); + _vm->_gfx->updateScreen(); + } // TODO: Comparison with original engine shows that this simple solution // may not be the correct one and the choice of which sound @@ -3166,6 +3220,7 @@ void MystScriptParser::opcode_200_run() { // Note: The modulus by 6 is because the 6th image is the one at imageBaseId _vm->_gfx->copyImageToScreen(g_opcode200Parameters.imageBaseId + curImageIndex % 6, Common::Rect(0, 0, 544, 333)); + _vm->_gfx->updateScreen(); _vm->_varStore->setVar(g_opcode200Parameters.var, curImageIndex + 1); g_opcode200Parameters.lastCardTime = _vm->_system->getMillis(); @@ -3380,6 +3435,7 @@ void MystScriptParser::opcode_201(uint16 op, uint16 var, uint16 argc, uint16 *ar case kIntroStack: _vm->_system->delayMillis(4 * 1000); _vm->_gfx->copyImageToScreen(4, Common::Rect(0, 0, 544, 333)); + _vm->_gfx->updateScreen(); // TODO : Wait until video ends, then change to card 5 break; case kSeleniticStack: @@ -4328,6 +4384,8 @@ void MystScriptParser::opcode_211_run(void) { lastGridState[i] = gridState[i]; } + _vm->_gfx->updateScreen(); + // Var 23 contains boolean for whether pattern matches correct book pattern i.e. Pattern 158 if (gridState[0] == 0xc3 && gridState[1] == 0x6b && gridState[2] == 0xa3 && gridState[3] == 0x93 && gridState[4] == 0xcc && gridState[5] == 0xfa) @@ -4657,6 +4715,7 @@ void MystScriptParser::opcode_298(uint16 op, uint16 var, uint16 argc, uint16 *ar _vm->_system->delayMillis(20 * 1000); for (uint16 imageId = 3001; imageId <= 3012; imageId++) { _vm->_gfx->copyImageToScreen(imageId, Common::Rect(0, 0, 544, 333)); + _vm->_gfx->updateScreen(); _vm->_system->delayMillis(5 * 1000); } break; |