aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/console.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/console.cpp')
-rw-r--r--engines/sci/console.cpp378
1 files changed, 273 insertions, 105 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 79f63fded4..4d458a42c8 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -39,6 +39,7 @@
#include "sci/sound/midiparser_sci.h"
#include "sci/sound/music.h"
#include "sci/sound/drivers/mididriver.h"
+#include "sci/sound/drivers/map-mt32-to-gm.h"
#include "sci/graphics/cursor.h"
#include "sci/graphics/screen.h"
#include "sci/graphics/paint.h"
@@ -57,6 +58,8 @@
#include "common/file.h"
#include "common/savefile.h"
+#include "engines/util.h"
+
namespace Sci {
int g_debug_sleeptime_factor = 1;
@@ -67,7 +70,7 @@ bool g_debug_track_mouse_clicks = false;
static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeValue);
Console::Console(SciEngine *engine) : GUI::Debugger(),
- _engine(engine), _debugState(engine->_debugState), _enterTime(0) {
+ _engine(engine), _debugState(engine->_debugState) {
// Variables
DVar_Register("sleeptime_factor", &g_debug_sleeptime_factor, DVAR_INT, 0);
@@ -103,7 +106,6 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
DCmd_Register("list", WRAP_METHOD(Console, cmdList));
DCmd_Register("hexgrep", WRAP_METHOD(Console, cmdHexgrep));
DCmd_Register("verify_scripts", WRAP_METHOD(Console, cmdVerifyScripts));
- DCmd_Register("show_instruments", WRAP_METHOD(Console, cmdShowInstruments));
// Game
DCmd_Register("save_game", WRAP_METHOD(Console, cmdSaveGame));
DCmd_Register("restore_game", WRAP_METHOD(Console, cmdRestoreGame));
@@ -145,6 +147,8 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
DCmd_Register("stopallsounds", WRAP_METHOD(Console, cmdStopAllSounds));
DCmd_Register("sfx01_header", WRAP_METHOD(Console, cmdSfx01Header));
DCmd_Register("sfx01_track", WRAP_METHOD(Console, cmdSfx01Track));
+ DCmd_Register("show_instruments", WRAP_METHOD(Console, cmdShowInstruments));
+ DCmd_Register("map_instrument", WRAP_METHOD(Console, cmdMapInstrument));
// Script
DCmd_Register("addresses", WRAP_METHOD(Console, cmdAddresses));
DCmd_Register("registers", WRAP_METHOD(Console, cmdRegisters));
@@ -166,6 +170,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
DCmd_Register("snk", WRAP_METHOD(Console, cmdStepCallk)); // alias
DCmd_Register("disasm", WRAP_METHOD(Console, cmdDisassemble));
DCmd_Register("disasm_addr", WRAP_METHOD(Console, cmdDisassembleAddress));
+ DCmd_Register("find_callk", WRAP_METHOD(Console, cmdFindKernelFunctionCall));
DCmd_Register("send", WRAP_METHOD(Console, cmdSend));
DCmd_Register("go", WRAP_METHOD(Console, cmdGo));
DCmd_Register("logkernel", WRAP_METHOD(Console, cmdLogKernel));
@@ -218,20 +223,19 @@ Console::~Console() {
}
void Console::preEnter() {
- if (g_sci && g_sci->_soundCmd)
- g_sci->_soundCmd->pauseAll(true);
- _enterTime = g_system->getMillis();
+ _engine->pauseEngine(true);
}
-void Console::postEnter() {
- if (g_sci && g_sci->_soundCmd)
- g_sci->_soundCmd->pauseAll(false);
+extern void playVideo(Graphics::VideoDecoder *videoDecoder);
+void Console::postEnter() {
if (!_videoFile.empty()) {
- _engine->_gfxCursor->kernelHide();
-
Graphics::VideoDecoder *videoDecoder = 0;
+#ifdef ENABLE_SCI32
+ bool duckMode = false;
+#endif
+
if (_videoFile.hasSuffix(".seq")) {
SeqDecoder *seqDecoder = new SeqDecoder();
seqDecoder->setFrameDelay(_videoFrameDelay);
@@ -240,51 +244,51 @@ void Console::postEnter() {
} else if (_videoFile.hasSuffix(".vmd")) {
videoDecoder = new Graphics::VMDDecoder(g_system->getMixer());
#endif
+ } else if (_videoFile.hasSuffix(".duk")) {
+#ifdef ENABLE_SCI32
+ duckMode = true;
+ videoDecoder = new Graphics::AviDecoder(g_system->getMixer());
+#else
+ warning("Duck videos require SCI32 support compiled in");
+#endif
} else if (_videoFile.hasSuffix(".avi")) {
videoDecoder = new Graphics::AviDecoder(g_system->getMixer());
}
if (videoDecoder && videoDecoder->loadFile(_videoFile)) {
- uint16 x = (g_system->getWidth() - videoDecoder->getWidth()) / 2;
- uint16 y = (g_system->getHeight() - videoDecoder->getHeight()) / 2;
- bool skipVideo = false;
+ _engine->_gfxCursor->kernelHide();
- if (videoDecoder->hasDirtyPalette())
- videoDecoder->setSystemPalette();
-
- while (!g_engine->shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) {
- if (videoDecoder->needsUpdate()) {
- Graphics::Surface *frame = videoDecoder->decodeNextFrame();
- if (frame) {
- g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+#ifdef ENABLE_SCI32
+ // Duck videos are 16bpp, so we need to change pixel formats
+ int oldWidth = g_system->getWidth();
+ int oldHeight = g_system->getHeight();
+ if (duckMode) {
+ Common::List<Graphics::PixelFormat> formats;
+ formats.push_back(videoDecoder->getPixelFormat());
+ initGraphics(640, 480, true, formats);
+
+ if (g_system->getScreenFormat().bytesPerPixel != videoDecoder->getPixelFormat().bytesPerPixel)
+ error("Could not switch screen format for the duck video");
+ }
+#endif
- if (videoDecoder->hasDirtyPalette())
- videoDecoder->setSystemPalette();
+ playVideo(videoDecoder);
- g_system->updateScreen();
- }
- }
-
- Common::Event event;
- while (g_system->getEventManager()->pollEvent(event)) {
- if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
- skipVideo = true;
- }
+#ifdef ENABLE_SCI32
+ // Switch back to 8bpp if we played a duck video
+ if (duckMode)
+ initGraphics(oldWidth, oldHeight, oldWidth > 320);
+#endif
- g_system->delayMillis(10);
- }
-
- delete videoDecoder;
+ _engine->_gfxCursor->kernelShow();
} else
warning("Could not play video %s\n", _videoFile.c_str());
- _engine->_gfxCursor->kernelShow();
_videoFile.clear();
_videoFrameDelay = 0;
}
- // Subtract the time we were running the debugger from the game running time
- _engine->_gamestate->gameStartTime += g_system->getMillis() - _enterTime;
+ _engine->pauseEngine(false);
}
bool Console::cmdHelp(int argc, const char **argv) {
@@ -332,7 +336,6 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" list - Lists all the resources of a given type\n");
DebugPrintf(" hexgrep - Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers\n");
DebugPrintf(" verify_scripts - Performs sanity checks on SCI1.1-SCI2.1 game scripts (e.g. if they're up to 64KB in total)\n");
- DebugPrintf(" show_instruments - Shows the instruments of a specific song, or all songs\n");
DebugPrintf("\n");
DebugPrintf("Game:\n");
DebugPrintf(" save_game - Saves the current game state to the hard disk\n");
@@ -372,6 +375,8 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" is_sample - Shows information on a given sound resource, if it's a PCM sample\n");
DebugPrintf(" sfx01_header - Dumps the header of a SCI01 song\n");
DebugPrintf(" sfx01_track - Dumps a track of a SCI01 song\n");
+ DebugPrintf(" show_instruments - Shows the instruments of a specific song, or all songs\n");
+ DebugPrintf(" map_instrument - Dynamically maps an MT-32 instrument to a GM instrument\n");
DebugPrintf("\n");
DebugPrintf("Script:\n");
DebugPrintf(" addresses - Provides information on how to pass addresses\n");
@@ -447,6 +452,10 @@ bool Console::cmdGetVersion(int argc, const char **argv) {
DebugPrintf("Lofs type: %s\n", getSciVersionDesc(_engine->_features->detectLofsType()));
DebugPrintf("Move count type: %s\n", (_engine->_features->handleMoveCount()) ? "increment" : "ignore");
DebugPrintf("SetCursor type: %s\n", getSciVersionDesc(_engine->_features->detectSetCursorType()));
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2)
+ DebugPrintf("kString type: %s\n", (_engine->_features->detectSci2StringFunctionType() == kSci2StringFunctionOld) ? "SCI2 (old)" : "SCI2.1 (new)");
+#endif
DebugPrintf("View type: %s\n", viewTypeDesc[g_sci->getResMan()->getViewType()]);
DebugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette->isMerging() ? "yes" : "no");
DebugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc());
@@ -763,7 +772,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) {
if (argc < 4) {
DebugPrintf("Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers.\n");
DebugPrintf("Usage: %s <resource type> <resource number> <search string>\n", argv[0]);
- DebugPrintf("<resource number> can be a specific resource number, or \"all\" for all of the resources of the specified type\n", argv[0]);
+ DebugPrintf("<resource number> can be a specific resource number, or \"all\" for all of the resources of the specified type\n");
DebugPrintf("EXAMPLES:\n hexgrep script all e8 03 c8 00\n hexgrep pic 042 fe");
cmdResourceTypes(argc, argv);
return true;
@@ -830,7 +839,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) {
bool Console::cmdVerifyScripts(int argc, const char **argv) {
if (getSciVersion() < SCI_VERSION_1_1) {
- DebugPrintf("This script check is only meant for SCI1.1-SCI2.1 games\n");
+ DebugPrintf("This script check is only meant for SCI1.1-SCI3 games\n");
return true;
}
@@ -838,7 +847,7 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) {
Common::sort(resources->begin(), resources->end());
Common::List<ResourceId>::iterator itr = resources->begin();
- DebugPrintf("%d SCI1.1-SCI2.1 scripts found, performing sanity checks...\n", resources->size());
+ DebugPrintf("%d SCI1.1-SCI3 scripts found, performing sanity checks...\n", resources->size());
Resource *script, *heap;
while (itr != resources->end()) {
@@ -846,13 +855,19 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) {
if (!script)
DebugPrintf("Error: script %d couldn't be loaded\n", itr->getNumber());
- heap = _engine->getResMan()->findResource(ResourceId(kResourceTypeHeap, itr->getNumber()), false);
- if (!heap)
- DebugPrintf("Error: script %d doesn't have a corresponding heap\n", itr->getNumber());
-
- if (script && heap && (script->size + heap->size > 65535))
- DebugPrintf("Error: script and heap %d together are larger than 64KB (%d bytes)\n",
- itr->getNumber(), script->size + heap->size);
+ if (getSciVersion() <= SCI_VERSION_2_1) {
+ heap = _engine->getResMan()->findResource(ResourceId(kResourceTypeHeap, itr->getNumber()), false);
+ if (!heap)
+ DebugPrintf("Error: script %d doesn't have a corresponding heap\n", itr->getNumber());
+
+ if (script && heap && (script->size + heap->size > 65535))
+ DebugPrintf("Error: script and heap %d together are larger than 64KB (%d bytes)\n",
+ itr->getNumber(), script->size + heap->size);
+ } else { // SCI3
+ if (script && script->size > 65535)
+ DebugPrintf("Error: script %d is larger than 64KB (%d bytes)\n",
+ itr->getNumber(), script->size);
+ }
++itr;
}
@@ -863,6 +878,14 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) {
return true;
}
+// Same as in sound/drivers/midi.cpp
+uint8 getGmInstrument(const Mt32ToGmMap &Mt32Ins) {
+ if (Mt32Ins.gmInstr == MIDI_MAPPED_TO_RHYTHM)
+ return Mt32Ins.gmRhythmKey + 0x80;
+ else
+ return Mt32Ins.gmInstr;
+}
+
bool Console::cmdShowInstruments(int argc, const char **argv) {
int songNumber = -1;
@@ -951,15 +974,14 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
DebugPrintf(" %d", instrument);
instruments[instrument]++;
instrumentsSongs[instrument][itr->getNumber()] = true;
+ } else {
+ channelData++;
}
break;
case 0xD:
channelData++; // param1
break;
case 0xB:
- channelData++; // param1
- channelData++; // param2
- break;
case 0x8:
case 0x9:
case 0xA:
@@ -1005,7 +1027,16 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
DebugPrintf("%d, ", i);
}
DebugPrintf("\n\n");
+ }
+
+ DebugPrintf("Instruments not mapped in the MT32->GM map: ");
+ for (int i = 0; i < 128; i++) {
+ if (instruments[i] > 0 && getGmInstrument(Mt32MemoryTimbreMaps[i]) == MIDI_UNMAPPED)
+ DebugPrintf("%d, ", i);
+ }
+ DebugPrintf("\n\n");
+ if (songNumber == -1) {
DebugPrintf("Used instruments in songs:\n");
for (int i = 0; i < 128; i++) {
if (instruments[i] > 0) {
@@ -1025,6 +1056,43 @@ bool Console::cmdShowInstruments(int argc, const char **argv) {
return true;
}
+bool Console::cmdMapInstrument(int argc, const char **argv) {
+ if (argc != 4) {
+ DebugPrintf("Maps an MT-32 custom instrument to a GM instrument on the fly\n\n");
+ DebugPrintf("Usage %s <MT-32 instrument name> <GM instrument> <GM rhythm key>\n", argv[0]);
+ DebugPrintf("Each MT-32 instrument is always 10 characters and is mapped to either a GM instrument, or a GM rhythm key\n");
+ DebugPrintf("A value of 255 (0xff) signifies an unmapped instrument\n");
+ DebugPrintf("Please replace the spaces in the instrument name with underscores (\"_\"). They'll be converted to spaces afterwards\n\n");
+ DebugPrintf("Example: %s test_0__XX 1 255\n", argv[0]);
+ DebugPrintf("The above example will map the MT-32 instrument \"test 0 XX\" to GM instrument 1\n\n");
+ } else {
+ if (Mt32dynamicMappings != NULL) {
+ Mt32ToGmMap newMapping;
+ char *instrumentName = new char[11];
+ Common::strlcpy(instrumentName, argv[1], 11);
+
+ for (uint16 i = 0; i < strlen(instrumentName); i++)
+ if (instrumentName[i] == '_')
+ instrumentName[i] = ' ';
+
+ newMapping.name = instrumentName;
+ newMapping.gmInstr = atoi(argv[2]);
+ newMapping.gmRhythmKey = atoi(argv[3]);
+ Mt32dynamicMappings->push_back(newMapping);
+ }
+ }
+
+ DebugPrintf("Current dynamic mappings:\n");
+ if (Mt32dynamicMappings != NULL) {
+ const Mt32ToGmMapList::iterator end = Mt32dynamicMappings->end();
+ for (Mt32ToGmMapList::iterator it = Mt32dynamicMappings->begin(); it != end; ++it) {
+ DebugPrintf("\"%s\" -> %d / %d\n", (*it).name, (*it).gmInstr, (*it).gmRhythmKey);
+ }
+ }
+
+ return true;
+}
+
bool Console::cmdList(int argc, const char **argv) {
if (argc < 2) {
DebugPrintf("Lists all the resources of a given type\n");
@@ -1041,7 +1109,7 @@ bool Console::cmdList(int argc, const char **argv) {
if ((res == kResourceTypeAudio36) || (res == kResourceTypeSync36)) {
if (argc != 3) {
- DebugPrintf("Please specify map number\n");
+ DebugPrintf("Please specify map number (-1: all maps)\n");
return true;
}
number = atoi(argv[2]);
@@ -1140,14 +1208,18 @@ bool Console::cmdRestartGame(int argc, const char **argv) {
}
bool Console::cmdClassTable(int argc, const char **argv) {
- DebugPrintf("Available classes:\n");
+ DebugPrintf("Available classes (parse a parameter to filter the table by a specific class):\n");
+
for (uint i = 0; i < _engine->_gamestate->_segMan->classTableSize(); i++) {
Class temp = _engine->_gamestate->_segMan->_classTable[i];
if (temp.reg.segment) {
- DebugPrintf(" Class 0x%x (%s) at %04x:%04x (script 0x%x)\n", i,
- _engine->_gamestate->_segMan->getObjectName(temp.reg),
- PRINT_REG(temp.reg),
- temp.script);
+ const char *className = _engine->_gamestate->_segMan->getObjectName(temp.reg);
+ if (argc == 1 || (argc == 2 && !strcmp(className, argv[1]))) {
+ DebugPrintf(" Class 0x%x (%s) at %04x:%04x (script %d)\n", i,
+ className,
+ PRINT_REG(temp.reg),
+ temp.script);
+ } else DebugPrintf(" Class 0x%x (not loaded; can't get name) (script %d)\n", i, temp.script);
}
}
@@ -1327,9 +1399,9 @@ bool Console::cmdSaid(int argc, const char **argv) {
}
spec[len++] = 0xFF;
- printf("Matching '%s' against:", string);
+ debugN("Matching '%s' against:", string);
_engine->getVocabulary()->debugDecipherSaidBlock(spec);
- printf("\n");
+ debugN("\n");
ResultWordListList words;
bool res = _engine->getVocabulary()->tokenizeString(words, string, &error);
@@ -1491,7 +1563,7 @@ bool Console::cmdPicVisualize(int argc, const char **argv) {
bool Console::cmdPlayVideo(int argc, const char **argv) {
if (argc < 2) {
- DebugPrintf("Plays a SEQ, AVI or VMD video.\n");
+ DebugPrintf("Plays a SEQ, AVI, DUK or VMD video.\n");
DebugPrintf("Usage: %s <video file name> <delay>\n", argv[0]);
DebugPrintf("The video file name should include the extension\n");
DebugPrintf("Delay is only used in SEQ videos and is measured in ticks (default: 10)\n");
@@ -1501,7 +1573,7 @@ bool Console::cmdPlayVideo(int argc, const char **argv) {
Common::String filename = argv[1];
filename.toLowercase();
- if (filename.hasSuffix(".seq") || filename.hasSuffix(".avi") || filename.hasSuffix(".vmd")) {
+ if (filename.hasSuffix(".seq") || filename.hasSuffix(".avi") || filename.hasSuffix(".vmd") || filename.hasSuffix(".duk")) {
_videoFile = filename;
_videoFrameDelay = (argc == 2) ? 10 : atoi(argv[2]);
return Cmd_Exit(0, 0);
@@ -2546,13 +2618,18 @@ bool Console::cmdStepCallk(int argc, const char **argv) {
}
bool Console::cmdDisassemble(int argc, const char **argv) {
- if (argc != 3) {
+ if (argc < 3) {
DebugPrintf("Disassembles a method by name.\n");
- DebugPrintf("Usage: %s <object> <method>\n", argv[0]);
+ DebugPrintf("Usage: %s <object> <method> <options>\n", argv[0]);
+ DebugPrintf("Valid options are:\n");
+ DebugPrintf(" bwt : Print byte/word tag\n");
+ DebugPrintf(" bc : Print bytecode\n");
return true;
}
reg_t objAddr = NULL_REG;
+ bool printBytecode = false;
+ bool printBWTag = false;
if (parse_reg_t(_engine->_gamestate, argv[1], &objAddr, false)) {
DebugPrintf("Invalid address passed.\n");
@@ -2579,8 +2656,15 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
return true;
}
+ for (int i = 3; i < argc; i++) {
+ if (!scumm_stricmp(argv[i], "bwt"))
+ printBytecode = true;
+ else if (!scumm_stricmp(argv[i], "bc"))
+ printBWTag = true;
+ }
+
do {
- addr = disassemble(_engine->_gamestate, addr, 0, 0);
+ addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
} while (addr.offset > 0);
return true;
@@ -2598,9 +2682,9 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
}
reg_t vpc = NULL_REG;
- int op_count = 1;
- int do_bwc = 0;
- int do_bytes = 0;
+ int opCount = 1;
+ bool printBWTag = false;
+ bool printBytes = false;
int size;
if (parse_reg_t(_engine->_gamestate, argv[1], &vpc, false)) {
@@ -2614,25 +2698,109 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
for (int i = 2; i < argc; i++) {
if (!scumm_stricmp(argv[i], "bwt"))
- do_bwc = 1;
+ printBWTag = true;
else if (!scumm_stricmp(argv[i], "bc"))
- do_bytes = 1;
+ printBytes = true;
else if (toupper(argv[i][0]) == 'C')
- op_count = atoi(argv[i] + 1);
+ opCount = atoi(argv[i] + 1);
else {
DebugPrintf("Invalid option '%s'\n", argv[i]);
return true;
}
}
- if (op_count < 0) {
+ if (opCount < 0) {
DebugPrintf("Invalid op_count\n");
return true;
}
do {
- vpc = disassemble(_engine->_gamestate, vpc, do_bwc, do_bytes);
- } while ((vpc.offset > 0) && (vpc.offset + 6 < size) && (--op_count));
+ vpc = disassemble(_engine->_gamestate, vpc, printBWTag, printBytes);
+ } while ((vpc.offset > 0) && (vpc.offset + 6 < size) && (--opCount));
+
+ return true;
+}
+
+bool Console::cmdFindKernelFunctionCall(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Finds the scripts and methods that call a specific kernel function.\n");
+ DebugPrintf("Usage: %s <kernel function>\n", argv[0]);
+ DebugPrintf("Example: %s Display\n", argv[0]);
+ return true;
+ }
+
+ // Find the number of the kernel function call
+ int kernelFuncNum = _engine->getKernel()->findKernelFuncPos(argv[1]);
+
+ if (kernelFuncNum < 0) {
+ DebugPrintf("Invalid kernel function requested\n");
+ return true;
+ }
+
+ Common::List<ResourceId> *resources = _engine->getResMan()->listResources(kResourceTypeScript);
+ Common::sort(resources->begin(), resources->end());
+ Common::List<ResourceId>::iterator itr = resources->begin();
+
+ DebugPrintf("%d scripts found, dissassembling...\n", resources->size());
+
+ int scriptSegment;
+ Script *script;
+ SegManager *segMan = _engine->getEngineState()->_segMan;
+
+ while (itr != resources->end()) {
+ if (_engine->getGameId() == GID_KQ5 && itr->getNumber() == 980) {
+ // Ignore script 980 in KQ5. Seems to be a leftover, as it
+ // uses a superclass from script 988, which doesn't exist
+ itr++;
+ continue;
+ }
+
+ // Load script
+ scriptSegment = segMan->instantiateScript(itr->getNumber());
+ script = segMan->getScript(scriptSegment);
+
+ // Iterate through all the script's objects
+ ObjMap::iterator it;
+ const ObjMap::iterator end = script->_objects.end();
+ for (it = script->_objects.begin(); it != end; ++it) {
+ const Object *obj = segMan->getObject(it->_value.getPos());
+ const char *objName = segMan->getObjectName(it->_value.getPos());
+
+ // Now dissassemble each method of the script object
+ for (uint16 i = 0; i < obj->getMethodCount(); i++) {
+ reg_t fptr = obj->getFunction(i);
+ uint16 offset = fptr.offset;
+ int16 opparams[4];
+ byte extOpcode;
+ byte opcode;
+
+ while (true) {
+ offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);
+ opcode = extOpcode >> 1;
+
+ if (opcode == op_callk) {
+ uint16 kFuncNum = opparams[0];
+ uint16 argc2 = opparams[1];
+
+ if (kFuncNum == kernelFuncNum) {
+ DebugPrintf("Called from script %d, object %s, method %s(%d) with %d parameters\n",
+ itr->getNumber(), objName,
+ _engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), i, argc2);
+ }
+ }
+
+ // Check for end of function/script
+ if (opcode == op_ret || offset >= script->getBufSize())
+ break;
+ } // while (true)
+ } // for (uint16 i = 0; i < obj->getMethodCount(); i++)
+ } // for (it = script->_objects.begin(); it != end; ++it)
+
+ segMan->uninstantiateScript(itr->getNumber());
+ ++itr;
+ }
+
+ delete resources;
return true;
}
@@ -2641,7 +2809,7 @@ bool Console::cmdSend(int argc, const char **argv) {
if (argc < 3) {
DebugPrintf("Sends a message to an object.\n");
DebugPrintf("Usage: %s <object> <selector name> <param1> <param2> ... <paramn>\n", argv[0]);
- DebugPrintf("Example: send ?fooScript cue\n");
+ DebugPrintf("Example: %s ?fooScript cue\n", argv[0]);
return true;
}
@@ -3021,24 +3189,24 @@ static void midi_hexdump(byte *data, int size, int notational_offset) {
int blanks = 0;
offset += offset_mod;
- printf(" [%04x] %d\t",
+ debugN(" [%04x] %d\t",
old_offset + notational_offset, time);
cmd = data[offset];
if (!(cmd & 0x80)) {
cmd = prev;
if (prev < 0x80) {
- printf("Track broken at %x after"
+ debugN("Track broken at %x after"
" offset mod of %d\n",
offset + notational_offset, offset_mod);
Common::hexdump(data, size, 16, notational_offset);
return;
}
- printf("(rs %02x) ", cmd);
+ debugN("(rs %02x) ", cmd);
blanks += 8;
} else {
++offset;
- printf("%02x ", cmd);
+ debugN("%02x ", cmd);
blanks += 3;
}
prev = cmd;
@@ -3050,37 +3218,37 @@ static void midi_hexdump(byte *data, int size, int notational_offset) {
for (i = 0; i < pleft; i++) {
if (i == 0)
firstarg = data[offset];
- printf("%02x ", data[offset++]);
+ debugN("%02x ", data[offset++]);
blanks += 3;
}
while (blanks < 16) {
blanks += 4;
- printf(" ");
+ debugN(" ");
}
while (blanks < 20) {
++blanks;
- printf(" ");
+ debugN(" ");
}
if (cmd == SCI_MIDI_EOT)
- printf(";; EOT");
+ debugN(";; EOT");
else if (cmd == SCI_MIDI_SET_SIGNAL) {
if (firstarg == SCI_MIDI_SET_SIGNAL_LOOP)
- printf(";; LOOP point");
+ debugN(";; LOOP point");
else
- printf(";; CUE (%d)", firstarg);
+ debugN(";; CUE (%d)", firstarg);
} else if (SCI_MIDI_CONTROLLER(cmd)) {
if (firstarg == SCI_MIDI_CUMULATIVE_CUE)
- printf(";; CUE (cumulative)");
+ debugN(";; CUE (cumulative)");
else if (firstarg == SCI_MIDI_RESET_ON_SUSPEND)
- printf(";; RESET-ON-SUSPEND flag");
+ debugN(";; RESET-ON-SUSPEND flag");
}
- printf("\n");
+ debugN("\n");
if (old_offset >= offset) {
- printf("-- Not moving forward anymore,"
+ debugN("-- Not moving forward anymore,"
" aborting (%x/%x)\n", offset, old_offset);
return;
}
@@ -3518,7 +3686,7 @@ int Console::printObject(reg_t pos) {
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->_segMan->getObjectName(pos),
obj->getVarCount(), obj->getMethodCount());
- if (!obj->isClass())
+ if (!obj->isClass() && getSciVersion() != SCI_VERSION_3)
var_container = s->_segMan->getObject(obj->getSuperClassSelector());
DebugPrintf(" -- member variables:\n");
for (i = 0; (uint)i < obj->getVarCount(); i++) {
@@ -3559,22 +3727,22 @@ void Console::hexDumpReg(const reg_t *data, int len, int regsPerLine, int startO
byte c;
int offset = startOffset;
while (len >= regsPerLine) {
- printf("%06x: ", offset);
+ debugN("%06x: ", offset);
for (i = 0; i < regsPerLine; i++) {
- printf("%04x:%04x ", PRINT_REG(data[i]));
+ debugN("%04x:%04x ", PRINT_REG(data[i]));
}
- printf(" |");
+ debugN(" |");
for (i = 0; i < regsPerLine; i++) {
c = data[i].toUint16() & 0xff;
if (c < 32 || c >= 127)
c = '.';
- printf("%c", c);
+ debugN("%c", c);
c = data[i].toUint16() >> 8;
if (c < 32 || c >= 127)
c = '.';
- printf("%c", c);
+ debugN("%c", c);
}
- printf("|\n");
+ debugN("|\n");
data += regsPerLine;
len -= regsPerLine;
offset += regsPerLine * (isArray ? 1 : 2);
@@ -3583,27 +3751,27 @@ void Console::hexDumpReg(const reg_t *data, int len, int regsPerLine, int startO
if (len <= 0)
return;
- printf("%06x: ", offset);
+ debugN("%06x: ", offset);
for (i = 0; i < regsPerLine; i++) {
if (i < len)
- printf("%04x:%04x ", PRINT_REG(data[i]));
+ debugN("%04x:%04x ", PRINT_REG(data[i]));
else
- printf(" ");
+ debugN(" ");
}
- printf(" |");
+ debugN(" |");
for (i = 0; i < len; i++) {
c = data[i].toUint16() & 0xff;
if (c < 32 || c >= 127)
c = '.';
- printf("%c", c);
+ debugN("%c", c);
c = data[i].toUint16() >> 8;
if (c < 32 || c >= 127)
c = '.';
- printf("%c", c);
+ debugN("%c", c);
}
for (; i < regsPerLine; i++)
- printf(" ");
- printf("|\n");
+ debugN(" ");
+ debugN("|\n");
}
} // End of namespace Sci