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.cpp649
1 files changed, 531 insertions, 118 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index e233c4cba4..b20ed3f8be 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -41,9 +41,7 @@
#include "sci/graphics/cache.h"
#include "sci/graphics/cursor.h"
#include "sci/graphics/screen.h"
-#include "sci/graphics/paint.h"
#include "sci/graphics/paint16.h"
-#include "sci/graphics/paint32.h"
#include "sci/graphics/palette.h"
#include "sci/graphics/ports.h"
#include "sci/graphics/view.h"
@@ -54,8 +52,8 @@
#include "sci/video/seq_decoder.h"
#ifdef ENABLE_SCI32
#include "sci/graphics/frameout.h"
+#include "sci/graphics/paint32.h"
#include "video/coktel_decoder.h"
-#include "sci/video/robot_decoder.h"
#endif
#include "common/file.h"
@@ -137,8 +135,12 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
registerCmd("wl", WRAP_METHOD(Console, cmdWindowList)); // alias
registerCmd("plane_list", WRAP_METHOD(Console, cmdPlaneList));
registerCmd("pl", WRAP_METHOD(Console, cmdPlaneList)); // alias
+ registerCmd("visible_plane_list", WRAP_METHOD(Console, cmdVisiblePlaneList));
+ registerCmd("vpl", WRAP_METHOD(Console, cmdVisiblePlaneList)); // alias
registerCmd("plane_items", WRAP_METHOD(Console, cmdPlaneItemList));
registerCmd("pi", WRAP_METHOD(Console, cmdPlaneItemList)); // alias
+ registerCmd("visible_plane_items", WRAP_METHOD(Console, cmdVisiblePlaneItemList));
+ registerCmd("vpi", WRAP_METHOD(Console, cmdVisiblePlaneItemList)); // alias
registerCmd("saved_bits", WRAP_METHOD(Console, cmdSavedBits));
registerCmd("show_saved_bits", WRAP_METHOD(Console, cmdShowSavedBits));
// Segments
@@ -190,6 +192,7 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
registerCmd("send", WRAP_METHOD(Console, cmdSend));
registerCmd("go", WRAP_METHOD(Console, cmdGo));
registerCmd("logkernel", WRAP_METHOD(Console, cmdLogKernel));
+ registerCmd("vocab994", WRAP_METHOD(Console, cmdMapVocab994));
// Breakpoints
registerCmd("bp_list", WRAP_METHOD(Console, cmdBreakpointList));
registerCmd("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias
@@ -209,6 +212,11 @@ Console::Console(SciEngine *engine) : GUI::Debugger(),
registerCmd("bpe", WRAP_METHOD(Console, cmdBreakpointFunction)); // alias
// VM
registerCmd("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
+ registerCmd("script_objects", WRAP_METHOD(Console, cmdScriptObjects));
+ registerCmd("scro", WRAP_METHOD(Console, cmdScriptObjects));
+ registerCmd("script_strings", WRAP_METHOD(Console, cmdScriptStrings));
+ registerCmd("scrs", WRAP_METHOD(Console, cmdScriptStrings));
+ registerCmd("script_said", WRAP_METHOD(Console, cmdScriptSaid));
registerCmd("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
registerCmd("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias
registerCmd("vl", WRAP_METHOD(Console, cmdVMVarlist)); // alias
@@ -257,8 +265,6 @@ void Console::postEnter() {
#ifdef ENABLE_SCI32
} else if (_videoFile.hasSuffix(".vmd")) {
videoDecoder = new Video::AdvancedVMDDecoder();
- } else if (_videoFile.hasSuffix(".rbt")) {
- videoDecoder = new RobotDecoder(_engine->getPlatform() == Common::kPlatformMacintosh);
} else if (_videoFile.hasSuffix(".duk")) {
duckMode = true;
videoDecoder = new Video::AVIDecoder();
@@ -325,6 +331,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
debugPrintf("debugflag_list - Lists the available debug flags and their status\n");
debugPrintf("debugflag_enable - Enables a debug flag\n");
debugPrintf("debugflag_disable - Disables a debug flag\n");
+ debugPrintf("debuglevel - Shows or sets debug level\n");
debugPrintf("\n");
debugPrintf("Commands\n");
debugPrintf("--------\n");
@@ -375,7 +382,9 @@ bool Console::cmdHelp(int argc, const char **argv) {
debugPrintf(" animate_list / al - Shows the current list of objects in kAnimate's draw list (SCI0 - SCI1.1)\n");
debugPrintf(" window_list / wl - Shows a list of all the windows (ports) in the draw list (SCI0 - SCI1.1)\n");
debugPrintf(" plane_list / pl - Shows a list of all the planes in the draw list (SCI2+)\n");
+ debugPrintf(" visible_plane_list / vpl - Shows a list of all the planes in the visible draw list (SCI2+)\n");
debugPrintf(" plane_items / pi - Shows a list of all items for a plane (SCI2+)\n");
+ debugPrintf(" visible_plane_items / vpi - Shows a list of all items for a plane in the visible draw list (SCI2+)\n");
debugPrintf(" saved_bits - List saved bits on the hunk\n");
debugPrintf(" show_saved_bits - Display saved bits\n");
debugPrintf("\n");
@@ -477,15 +486,19 @@ 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()));
+ debugPrintf("PseudoMouse ability: %s\n", _engine->_features->detectPseudoMouseAbility() == kPseudoMouseAbilityTrue ? "yes" : "no");
#ifdef ENABLE_SCI32
- if (getSciVersion() >= SCI_VERSION_2)
- debugPrintf("kString type: %s\n", (_engine->_features->detectSci2StringFunctionType() == kSci2StringFunctionOld) ? "SCI2 (old)" : "SCI2.1 (new)");
- if (getSciVersion() == SCI_VERSION_2_1)
+ if ((getSciVersion() >= SCI_VERSION_2_1_EARLY) && (getSciVersion() <= SCI_VERSION_2_1_LATE))
debugPrintf("SCI2.1 kernel table: %s\n", (_engine->_features->detectSci21KernelType() == SCI_VERSION_2) ? "modified 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("Uses 16 bit color matching: %s\n", g_sci->_gfxPalette->isUsing16bitColorMatch() ? "yes" : "no");
+ if (getSciVersion() <= SCI_VERSION_1_1) {
+ debugPrintf("kAnimate fastCast enabled: %s\n", g_sci->_gfxAnimate->isFastCastEnabled() ? "yes" : "no");
+ }
+ if (getSciVersion() < SCI_VERSION_2) {
+ debugPrintf("Uses palette merging: %s\n", g_sci->_gfxPalette16->isMerging() ? "yes" : "no");
+ debugPrintf("Uses 16 bit color matching: %s\n", g_sci->_gfxPalette16->isUsing16bitColorMatch() ? "yes" : "no");
+ }
debugPrintf("Resource volume version: %s\n", g_sci->getResMan()->getVolVersionDesc());
debugPrintf("Resource map version: %s\n", g_sci->getResMan()->getMapVersionDesc());
debugPrintf("Contains selector vocabulary (vocab.997): %s\n", hasVocab997 ? "yes" : "no");
@@ -660,10 +673,33 @@ bool Console::cmdRegisters(int argc, const char **argv) {
return true;
}
+bool Console::parseResourceNumber36(const char *userParameter, uint16 &resourceNumber, uint32 &resourceTuple) {
+ int userParameterLen = strlen(userParameter);
+
+ if (userParameterLen != 10) {
+ debugPrintf("Audio36/Sync36 resource numbers must be specified as RRRNNVVCCS\n");
+ debugPrintf("where RRR is the resource number/map\n");
+ debugPrintf(" NN is the noun\n");
+ debugPrintf(" VV is the verb\n");
+ debugPrintf(" CC is the cond\n");
+ debugPrintf(" S is the seq\n");
+ return false;
+ }
+
+ // input: RRRNNVVCCS
+ resourceNumber = strtol(Common::String(userParameter, 3).c_str(), 0, 36);
+ uint16 noun = strtol(Common::String(userParameter + 3, 2).c_str(), 0, 36);
+ uint16 verb = strtol(Common::String(userParameter + 5, 2).c_str(), 0, 36);
+ uint16 cond = strtol(Common::String(userParameter + 7, 2).c_str(), 0, 36);
+ uint16 seq = strtol(Common::String(userParameter + 9, 1).c_str(), 0, 36);
+ resourceTuple = ((noun & 0xff) << 24) | ((verb & 0xff) << 16) | ((cond & 0xff) << 8) | (seq & 0xff);
+ return true;
+}
+
bool Console::cmdDiskDump(int argc, const char **argv) {
- int resNumFrom = 0;
- int resNumTo = 0;
- int resNumCur = 0;
+ bool resourceAll = false;
+ uint16 resourceNumber = 0;
+ uint32 resourceTuple = 0;
if (argc != 3) {
debugPrintf("Dumps the specified resource to disk as a patch file\n");
@@ -673,42 +709,90 @@ bool Console::cmdDiskDump(int argc, const char **argv) {
return true;
}
+ ResourceType resourceType = parseResourceType(argv[1]);
+ if (resourceType == kResourceTypeInvalid) {
+ debugPrintf("Resource type '%s' is not valid\n", argv[1]);
+ return true;
+ }
+
if (strcmp(argv[2], "*") == 0) {
- resNumFrom = 0;
- resNumTo = 65535;
+ resourceAll = true;
} else {
- resNumFrom = atoi(argv[2]);
- resNumTo = resNumFrom;
+ switch (resourceType) {
+ case kResourceTypeAudio36:
+ case kResourceTypeSync36:
+ if (!parseResourceNumber36(argv[2], resourceNumber, resourceTuple)) {
+ return true;
+ }
+ break;
+ default:
+ resourceNumber = atoi(argv[2]);
+ break;
+ }
}
- ResourceType res = parseResourceType(argv[1]);
-
- if (res == kResourceTypeInvalid)
+ if (resourceType == kResourceTypeInvalid) {
debugPrintf("Resource type '%s' is not valid\n", argv[1]);
- else {
- for (resNumCur = resNumFrom; resNumCur <= resNumTo; resNumCur++) {
- Resource *resource = _engine->getResMan()->findResource(ResourceId(res, resNumCur), 0);
- if (resource) {
- char outFileName[50];
- sprintf(outFileName, "%s.%03d", getResourceTypeName(res), resNumCur);
- Common::DumpFile *outFile = new Common::DumpFile();
- outFile->open(outFileName);
- resource->writeToStream(outFile);
- outFile->finalize();
- outFile->close();
- delete outFile;
- debugPrintf("Resource %s.%03d (located in %s) has been dumped to disk\n", argv[1], resNumCur, resource->getResourceLocation().c_str());
- } else {
- if (resNumFrom == resNumTo) {
- debugPrintf("Resource %s.%03d not found\n", argv[1], resNumCur);
- }
- }
+ return true;
+ }
+
+ if (resourceAll) {
+ // "*" used, dump everything of that type
+ Common::List<ResourceId> resources = _engine->getResMan()->listResources(resourceType, -1);
+ Common::sort(resources.begin(), resources.end());
+
+ Common::List<ResourceId>::iterator itr;
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
+ resourceNumber = itr->getNumber();
+ resourceTuple = itr->getTuple();
+ cmdDiskDumpWorker(resourceType, resourceNumber, resourceTuple);
}
+ } else {
+ // id was given, dump only this resource
+ cmdDiskDumpWorker(resourceType, resourceNumber, resourceTuple);
}
return true;
}
+void Console::cmdDiskDumpWorker(ResourceType resourceType, int resourceNumber, uint32 resourceTuple) {
+ const char *resourceTypeName = getResourceTypeName(resourceType);
+ ResourceId resourceId;
+ Resource *resource = NULL;
+ char outFileName[50];
+
+ switch (resourceType) {
+ case kResourceTypeAudio36:
+ case kResourceTypeSync36: {
+ resourceId = ResourceId(resourceType, resourceNumber, resourceTuple);
+ resource = _engine->getResMan()->findResource(resourceId, 0);
+ sprintf(outFileName, "%s", resourceId.toPatchNameBase36().c_str());
+ // patch filename is: [type:1 char] [map:3 chars] [noun:2 chars] [verb:2 chars] "." [cond: 2 chars] [seq:1 char]
+ // e.g. "@5EG0000.014"
+ break;
+ }
+ default:
+ resourceId = ResourceId(resourceType, resourceNumber);
+ resource = _engine->getResMan()->findResource(resourceId, 0);
+ sprintf(outFileName, "%s.%03d", resourceTypeName, resourceNumber);
+ // patch filename is: [resourcetype].[resourcenumber]
+ // e.g. "Script.0"
+ break;
+ }
+
+ if (resource) {
+ Common::DumpFile *outFile = new Common::DumpFile();
+ outFile->open(outFileName);
+ resource->writeToStream(outFile);
+ outFile->finalize();
+ outFile->close();
+ delete outFile;
+ debugPrintf("Resource %s (located in %s) has been dumped to disk\n", outFileName, resource->getResourceLocation().c_str());
+ } else {
+ debugPrintf("Resource %s not found\n", outFileName);
+ }
+}
+
bool Console::cmdHexDump(int argc, const char **argv) {
if (argc != 3) {
debugPrintf("Dumps the specified resource to standard output\n");
@@ -748,6 +832,77 @@ bool Console::cmdResourceId(int argc, const char **argv) {
return true;
}
+bool Console::cmdList(int argc, const char **argv) {
+ int selectedMapNumber = -1;
+ Common::List<ResourceId> resources;
+ Common::List<ResourceId>::iterator itr;
+ int displayCount = 0;
+ int currentMap = -1;
+
+ if (argc < 2) {
+ debugPrintf("Lists all the resources of a given type\n");
+ cmdResourceTypes(argc, argv);
+ return true;
+ }
+
+ ResourceType resourceType = parseResourceType(argv[1]);
+ if (resourceType == kResourceTypeInvalid) {
+ debugPrintf("Unknown resource type: '%s'\n", argv[1]);
+ return true;
+ }
+
+ switch (resourceType) {
+ case kResourceTypeAudio36:
+ case kResourceTypeSync36:
+ if (argc != 3) {
+ debugPrintf("Please specify map number (-1: all maps)\n");
+ return true;
+ }
+ selectedMapNumber = atoi(argv[2]);
+ resources = _engine->getResMan()->listResources(resourceType, selectedMapNumber);
+ Common::sort(resources.begin(), resources.end());
+
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
+ const uint16 map = itr->getNumber();
+ const uint32 resourceTuple = itr->getTuple();
+ const uint16 noun = (resourceTuple >> 24) & 0xff;
+ const uint16 verb = (resourceTuple >> 16) & 0xff;
+ const uint16 cond = (resourceTuple >> 8) & 0xff;
+ const uint16 seq = resourceTuple & 0xff;
+
+ if (currentMap != map) {
+ if (displayCount % 3)
+ debugPrintf("\n");
+ debugPrintf("Map %04x (%i):\n", map, map);
+ currentMap = map;
+ displayCount = 0;
+ }
+
+ if (displayCount % 3 == 0)
+ debugPrintf(" ");
+
+ debugPrintf("%02x %02x %02x %02x (%3i %3i %3i %3i) ", noun, verb, cond, seq, noun, verb, cond, seq);
+
+ if (++displayCount % 3 == 0)
+ debugPrintf("\n");
+ }
+ break;
+ default:
+ resources = _engine->getResMan()->listResources(resourceType);
+ Common::sort(resources.begin(), resources.end());
+
+ for (itr = resources.begin(); itr != resources.end(); ++itr) {
+ debugPrintf("%8i", itr->getNumber());
+ if (++displayCount % 10 == 0)
+ debugPrintf("\n");
+ }
+ break;
+ }
+
+ debugPrintf("\n");
+ return true;
+}
+
bool Console::cmdDissectScript(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Examines a script\n");
@@ -849,7 +1004,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) {
for (; resNumber <= resMax; resNumber++) {
script = _engine->getResMan()->findResource(ResourceId(restype, resNumber), 0);
if (script) {
- unsigned int seeker = 0, seekerold = 0;
+ uint32 seeker = 0, seekerold = 0;
uint32 comppos = 0;
int output_script_name = 0;
@@ -899,7 +1054,7 @@ bool Console::cmdVerifyScripts(int argc, const char **argv) {
if (!script)
debugPrintf("Error: script %d couldn't be loaded\n", itr->getNumber());
- if (getSciVersion() <= SCI_VERSION_2_1) {
+ if (getSciVersion() <= SCI_VERSION_2_1_LATE) {
heap = _engine->getResMan()->findResource(ResourceId(kResourceTypeHeap, itr->getNumber()), false);
if (!heap)
debugPrintf("Error: script %d doesn't have a corresponding heap\n", itr->getNumber());
@@ -1124,52 +1279,6 @@ bool Console::cmdMapInstrument(int argc, const char **argv) {
return true;
}
-bool Console::cmdList(int argc, const char **argv) {
- if (argc < 2) {
- debugPrintf("Lists all the resources of a given type\n");
- cmdResourceTypes(argc, argv);
- return true;
- }
-
-
- ResourceType res = parseResourceType(argv[1]);
- if (res == kResourceTypeInvalid)
- debugPrintf("Unknown resource type: '%s'\n", argv[1]);
- else {
- int number = -1;
-
- if ((res == kResourceTypeAudio36) || (res == kResourceTypeSync36)) {
- if (argc != 3) {
- debugPrintf("Please specify map number (-1: all maps)\n");
- return true;
- }
- number = atoi(argv[2]);
- }
-
- Common::List<ResourceId> resources = _engine->getResMan()->listResources(res, number);
- Common::sort(resources.begin(), resources.end());
-
- int cnt = 0;
- Common::List<ResourceId>::iterator itr;
- for (itr = resources.begin(); itr != resources.end(); ++itr) {
- if (number == -1) {
- debugPrintf("%8i", itr->getNumber());
- if (++cnt % 10 == 0)
- debugPrintf("\n");
- } else if (number == (int)itr->getNumber()) {
- const uint32 tuple = itr->getTuple();
- debugPrintf("(%3i, %3i, %3i, %3i) ", (tuple >> 24) & 0xff, (tuple >> 16) & 0xff,
- (tuple >> 8) & 0xff, tuple & 0xff);
- if (++cnt % 4 == 0)
- debugPrintf("\n");
- }
- }
- debugPrintf("\n");
- }
-
- return true;
-}
-
bool Console::cmdSaveGame(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Saves the current game state to the hard disk\n");
@@ -1401,7 +1510,7 @@ bool Console::cmdSaid(int argc, const char **argv) {
}
// TODO: Maybe turn this into a proper said spec compiler
- unsigned int len = 0;
+ uint32 len = 0;
for (p++; p < argc; p++) {
if (strcmp(argv[p], ",") == 0) {
spec[len++] = 0xf0;
@@ -1438,7 +1547,7 @@ bool Console::cmdSaid(int argc, const char **argv) {
spec[len++] = 0xfe;
spec[len++] = 0xf6;
} else {
- unsigned int s = strtol(argv[p], 0, 16);
+ uint32 s = strtol(argv[p], 0, 16);
if (s >= 0xf0 && s <= 0xff) {
spec[len++] = s;
} else {
@@ -1511,7 +1620,7 @@ bool Console::cmdParserNodes(int argc, const char **argv) {
bool Console::cmdSetPalette(int argc, const char **argv) {
if (argc < 2) {
- debugPrintf("Sets a palette resource\n");
+ debugPrintf("Sets a palette resource (SCI16)\n");
debugPrintf("Usage: %s <resourceId>\n", argv[0]);
debugPrintf("where <resourceId> is the number of the palette resource to set\n");
return true;
@@ -1519,7 +1628,14 @@ bool Console::cmdSetPalette(int argc, const char **argv) {
uint16 resourceId = atoi(argv[1]);
- _engine->_gfxPalette->kernelSetFromResource(resourceId, true);
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ debugPrintf("This SCI version does not support this command\n");
+ return true;
+ }
+#endif
+
+ _engine->_gfxPalette16->kernelSetFromResource(resourceId, true);
return true;
}
@@ -1538,7 +1654,7 @@ bool Console::cmdDrawPic(int argc, const char **argv) {
#endif
uint16 resourceId = atoi(argv[1]);
- _engine->_gfxPaint->kernelDrawPicture(resourceId, 100, false, false, false, 0);
+ _engine->_gfxPaint16->kernelDrawPicture(resourceId, 100, false, false, false, 0);
_engine->_gfxScreen->copyToScreen();
_engine->sleep(2000);
@@ -1667,6 +1783,21 @@ bool Console::cmdPlaneList(int argc, const char **argv) {
return true;
}
+bool Console::cmdVisiblePlaneList(int argc, const char **argv) {
+#ifdef ENABLE_SCI32
+ if (_engine->_gfxFrameout) {
+ debugPrintf("Visible plane list:\n");
+ _engine->_gfxFrameout->printVisiblePlaneList(this);
+ } else {
+ debugPrintf("This SCI version does not have a list of planes\n");
+ }
+#else
+ debugPrintf("SCI32 isn't included in this compiled executable\n");
+#endif
+ return true;
+}
+
+
bool Console::cmdPlaneItemList(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Shows the list of items for a plane\n");
@@ -1695,6 +1826,34 @@ bool Console::cmdPlaneItemList(int argc, const char **argv) {
return true;
}
+bool Console::cmdVisiblePlaneItemList(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Shows the list of items for a plane\n");
+ debugPrintf("Usage: %s <plane address>\n", argv[0]);
+ return true;
+ }
+
+ reg_t planeObject = NULL_REG;
+
+ if (parse_reg_t(_engine->_gamestate, argv[1], &planeObject, false)) {
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+#ifdef ENABLE_SCI32
+ if (_engine->_gfxFrameout) {
+ debugPrintf("Visible plane item list:\n");
+ _engine->_gfxFrameout->printVisiblePlaneItemList(this, planeObject);
+ } else {
+ debugPrintf("This SCI version does not have a list of plane items\n");
+ }
+#else
+ debugPrintf("SCI32 isn't included in this compiled executable\n");
+#endif
+ return true;
+}
+
bool Console::cmdSavedBits(int argc, const char **argv) {
SegManager *segman = _engine->_gamestate->_segMan;
SegmentId id = segman->findSegmentByType(SEG_TYPE_HUNK);
@@ -1708,7 +1867,7 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
for (uint i = 0; i < entries.size(); ++i) {
uint16 offset = entries[i].getOffset();
- const Hunk& h = hunks->_table[offset];
+ const Hunk& h = hunks->at(offset);
if (strcmp(h.type, "SaveBits()") == 0) {
byte* memoryPtr = (byte *)h.mem;
@@ -1775,7 +1934,7 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
return true;
}
- const Hunk& h = hunks->_table[memoryHandle.getOffset()];
+ const Hunk& h = hunks->at(memoryHandle.getOffset());
if (strcmp(h.type, "SaveBits()") != 0) {
debugPrintf("Invalid address.\n");
@@ -1919,6 +2078,10 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
case SEG_TYPE_STRING:
debugPrintf("T SCI32 strings (%d)", (*(StringTable *)mobj).entries_used);
break;
+
+ case SEG_TYPE_BITMAP:
+ debugPrintf("T SCI32 bitmaps (%d)", (*(BitmapTable *)mobj).entries_used);
+ break;
#endif
default:
@@ -1991,32 +2154,32 @@ bool Console::segmentInfo(int nr) {
break;
case SEG_TYPE_CLONES: {
- CloneTable *ct = (CloneTable *)mobj;
+ CloneTable &ct = *(CloneTable *)mobj;
debugPrintf("clones\n");
- for (uint i = 0; i < ct->_table.size(); i++)
- if (ct->isValidEntry(i)) {
+ for (uint i = 0; i < ct.size(); i++)
+ if (ct.isValidEntry(i)) {
reg_t objpos = make_reg(nr, i);
debugPrintf(" [%04x] %s; copy of ", i, _engine->_gamestate->_segMan->getObjectName(objpos));
// Object header
- const Object *obj = _engine->_gamestate->_segMan->getObject(ct->_table[i].getPos());
+ const Object *obj = _engine->_gamestate->_segMan->getObject(ct[i].getPos());
if (obj)
- debugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()),
- _engine->_gamestate->_segMan->getObjectName(ct->_table[i].getPos()),
+ debugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct[i].getPos()),
+ _engine->_gamestate->_segMan->getObjectName(ct[i].getPos()),
obj->getVarCount(), obj->getMethodCount());
}
}
break;
case SEG_TYPE_LISTS: {
- ListTable *lt = (ListTable *)mobj;
+ ListTable &lt = *(ListTable *)mobj;
debugPrintf("lists\n");
- for (uint i = 0; i < lt->_table.size(); i++)
- if (lt->isValidEntry(i)) {
+ for (uint i = 0; i < lt.size(); i++)
+ if (lt.isValidEntry(i)) {
debugPrintf(" [%04x]: ", i);
- printList(&(lt->_table[i]));
+ printList(&lt[i]);
}
}
break;
@@ -2027,13 +2190,13 @@ bool Console::segmentInfo(int nr) {
}
case SEG_TYPE_HUNK: {
- HunkTable *ht = (HunkTable *)mobj;
+ HunkTable &ht = *(HunkTable *)mobj;
- debugPrintf("hunk (total %d)\n", ht->entries_used);
- for (uint i = 0; i < ht->_table.size(); i++)
- if (ht->isValidEntry(i)) {
+ debugPrintf("hunk (total %d)\n", ht.entries_used);
+ for (uint i = 0; i < ht.size(); i++)
+ if (ht.isValidEntry(i)) {
debugPrintf(" [%04x] %d bytes at %p, type=%s\n",
- i, ht->_table[i].size, ht->_table[i].mem, ht->_table[i].type);
+ i, ht[i].size, ht[i].mem, ht[i].type);
}
}
break;
@@ -2053,6 +2216,9 @@ bool Console::segmentInfo(int nr) {
case SEG_TYPE_ARRAY:
debugPrintf("SCI32 arrays\n");
break;
+ case SEG_TYPE_BITMAP:
+ debugPrintf("SCI32 bitmaps\n");
+ break;
#endif
default :
@@ -2172,6 +2338,7 @@ bool Console::cmdStartSound(int argc, const char **argv) {
return true;
}
+ // TODO: Maybe also add a playBed option.
g_sci->_soundCmd->startNewSound(number);
return cmdExit(0, 0);
}
@@ -2198,9 +2365,10 @@ bool Console::cmdToggleSound(int argc, const char **argv) {
Common::String newState = argv[2];
newState.toLowercase();
- if (newState == "play")
- g_sci->_soundCmd->processPlaySound(id);
- else if (newState == "stop")
+ if (newState == "play") {
+ // Maybe also have a 'playbed' option. (Second argument to processPlaySound.)
+ g_sci->_soundCmd->processPlaySound(id, false);
+ } else if (newState == "stop")
g_sci->_soundCmd->processStopSound(id, false);
else
debugPrintf("New state can either be 'play' or 'stop'");
@@ -2410,9 +2578,14 @@ bool Console::cmdVMVars(int argc, const char **argv) {
case 1:
case 2:
case 3: {
- // for global, local, temp and param, we need an index
if (argc < 3) {
- debugPrintf("Variable number must be specified for requested type\n");
+ for (int i = 0; i < s->variablesMax[varType]; ++i) {
+ curValue = &s->variables[varType][i];
+ debugPrintf("%s var %d == %04x:%04x", varNames[varType], i, PRINT_REG(*curValue));
+ printBasicVarInfo(*curValue);
+ debugPrintf("\n");
+ }
+
return true;
}
if (argc > 4) {
@@ -2647,6 +2820,12 @@ bool Console::cmdViewReference(int argc, const char **argv) {
hexDumpReg(array->getRawData(), array->getSize(), 4, 0, true);
break;
}
+ case SEG_TYPE_BITMAP: {
+ debugPrintf("SCI32 bitmap:\n");
+ const SciBitmap *bitmap = _engine->_gamestate->_segMan->lookupBitmap(reg);
+ Common::hexdump((const byte *) bitmap->getRawData(), bitmap->getRawSize(), 16, 0);
+ break;
+ }
#endif
default: {
const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg);
@@ -2730,6 +2909,186 @@ bool Console::cmdScriptSteps(int argc, const char **argv) {
return true;
}
+bool Console::cmdScriptObjects(int argc, const char **argv) {
+ int curScriptNr = -1;
+
+ if (argc < 2) {
+ debugPrintf("Shows all objects inside a specified script.\n");
+ debugPrintf("Usage: %s <script number>\n", argv[0]);
+ debugPrintf("Example: %s 999\n", argv[0]);
+ debugPrintf("<script number> may be * to show objects inside all loaded scripts\n");
+ return true;
+ }
+
+ if (strcmp(argv[1], "*") == 0) {
+ // get said-strings of all currently loaded scripts
+ curScriptNr = -1;
+ } else {
+ curScriptNr = atoi(argv[1]);
+ }
+
+ printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_OBJECT);
+ return true;
+}
+
+bool Console::cmdScriptStrings(int argc, const char **argv) {
+ int curScriptNr = -1;
+
+ if (argc < 2) {
+ debugPrintf("Shows all strings inside a specified script.\n");
+ debugPrintf("Usage: %s <script number>\n", argv[0]);
+ debugPrintf("Example: %s 999\n", argv[0]);
+ debugPrintf("<script number> may be * to show strings inside all loaded scripts\n");
+ return true;
+ }
+
+ if (strcmp(argv[1], "*") == 0) {
+ // get strings of all currently loaded scripts
+ curScriptNr = -1;
+ } else {
+ curScriptNr = atoi(argv[1]);
+ }
+
+ printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_STRING);
+ return true;
+}
+
+bool Console::cmdScriptSaid(int argc, const char **argv) {
+ int curScriptNr = -1;
+
+ if (argc < 2) {
+ debugPrintf("Shows all said-strings inside a specified script.\n");
+ debugPrintf("Usage: %s <script number>\n", argv[0]);
+ debugPrintf("Example: %s 999\n", argv[0]);
+ debugPrintf("<script number> may be * to show said-strings inside all loaded scripts\n");
+ return true;
+ }
+
+ if (strcmp(argv[1], "*") == 0) {
+ // get said-strings of all currently loaded scripts
+ curScriptNr = -1;
+ } else {
+ curScriptNr = atoi(argv[1]);
+ }
+
+ printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_SAID);
+ return true;
+}
+
+void Console::printOffsets(int scriptNr, uint16 showType) {
+ SegManager *segMan = _engine->_gamestate->_segMan;
+ Vocabulary *vocab = _engine->_vocabulary;
+ SegmentId curSegmentNr;
+ Common::List<SegmentId> segmentNrList;
+
+ SegmentType curSegmentType = SEG_TYPE_INVALID;
+ SegmentObj *curSegmentObj = NULL;
+ Script *curScriptObj = NULL;
+ const byte *curScriptData = NULL;
+
+ segmentNrList.clear();
+ if (scriptNr < 0) {
+ // get offsets of all currently loaded scripts
+ for (curSegmentNr = 0; curSegmentNr < segMan->_heap.size(); curSegmentNr++) {
+ curSegmentObj = segMan->_heap[curSegmentNr];
+ if (curSegmentObj && curSegmentObj->getType() == SEG_TYPE_SCRIPT) {
+ segmentNrList.push_back(curSegmentNr);
+ }
+ }
+
+ } else {
+ curSegmentNr = segMan->getScriptSegment(scriptNr);
+ if (!curSegmentNr) {
+ debugPrintf("Script %d is currently not loaded/available\n", scriptNr);
+ return;
+ }
+ segmentNrList.push_back(curSegmentNr);
+ }
+
+ const offsetLookupArrayType *scriptOffsetLookupArray;
+ offsetLookupArrayType::const_iterator arrayIterator;
+ int showTypeCount = 0;
+
+ reg_t objectPos;
+ const char *objectNamePtr = NULL;
+ const byte *stringPtr = NULL;
+ const byte *saidPtr = NULL;
+
+ Common::List<SegmentId>::iterator it;
+ const Common::List<SegmentId>::iterator end = segmentNrList.end();
+
+ for (it = segmentNrList.begin(); it != end; it++) {
+ curSegmentNr = *it;
+ // get object of this segment
+ curSegmentObj = segMan->getSegmentObj(curSegmentNr);
+ if (!curSegmentObj)
+ continue;
+
+ curSegmentType = curSegmentObj->getType();
+ if (curSegmentType != SEG_TYPE_SCRIPT) // safety check
+ continue;
+
+ curScriptObj = (Script *)curSegmentObj;
+ debugPrintf("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr);
+ debugN("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr);
+
+ // now print the list
+ scriptOffsetLookupArray = curScriptObj->getOffsetArray();
+ curScriptData = curScriptObj->getBuf();
+ showTypeCount = 0;
+
+ for (arrayIterator = scriptOffsetLookupArray->begin(); arrayIterator != scriptOffsetLookupArray->end(); arrayIterator++) {
+ if (arrayIterator->type == showType) {
+ switch (showType) {
+ case SCI_SCR_OFFSET_TYPE_OBJECT:
+ objectPos = make_reg(curSegmentNr, arrayIterator->offset);
+ objectNamePtr = segMan->getObjectName(objectPos);
+ debugPrintf(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr);
+ debugN(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr);
+ break;
+ case SCI_SCR_OFFSET_TYPE_STRING:
+ stringPtr = curScriptData + arrayIterator->offset;
+ debugPrintf(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize);
+ debugN(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize);
+ break;
+ case SCI_SCR_OFFSET_TYPE_SAID:
+ saidPtr = curScriptData + arrayIterator->offset;
+ debugPrintf(" %03d:%04x:\n", arrayIterator->id, arrayIterator->offset);
+ debugN(" %03d:%04x: ", arrayIterator->id, arrayIterator->offset);
+ vocab->debugDecipherSaidBlock(saidPtr);
+ debugN("\n");
+ break;
+ default:
+ break;
+ }
+ showTypeCount++;
+ }
+ }
+
+ if (showTypeCount == 0) {
+ switch (showType) {
+ case SCI_SCR_OFFSET_TYPE_OBJECT:
+ debugPrintf(" no objects\n");
+ debugN(" no objects\n");
+ break;
+ case SCI_SCR_OFFSET_TYPE_STRING:
+ debugPrintf(" no strings\n");
+ debugN(" no strings\n");
+ break;
+ case SCI_SCR_OFFSET_TYPE_SAID:
+ debugPrintf(" no said-strings\n");
+ debugN(" no said-strings\n");
+ break;
+ default:
+ break;
+ }
+ }
+
+ debugPrintf("\n");
+ debugN("\n");
+ }
+}
+
bool Console::cmdBacktrace(int argc, const char **argv) {
debugPrintf("Call stack (current base: 0x%x):\n", _engine->_gamestate->executionStackBase);
Common::List<ExecStack>::const_iterator iter;
@@ -2755,7 +3114,10 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
break;
case EXEC_STACK_TYPE_KERNEL: // Kernel function
- debugPrintf(" %x:[%x] k%s(", i, call.debugOrigin, _engine->getKernel()->getKernelName(call.debugSelector).c_str());
+ if (call.debugKernelSubFunction == -1)
+ debugPrintf(" %x:[%x] k%s(", i, call.debugOrigin, _engine->getKernel()->getKernelName(call.debugKernelFunction).c_str());
+ else
+ debugPrintf(" %x:[%x] k%s(", i, call.debugOrigin, _engine->getKernel()->getKernelName(call.debugKernelFunction, call.debugKernelSubFunction).c_str());
break;
case EXEC_STACK_TYPE_VARSELECTOR:
@@ -3209,6 +3571,7 @@ bool Console::cmdSend(int argc, const char **argv) {
// We call run_engine explictly so we can restore the value of r_acc
// after execution.
run_vm(_engine->_gamestate);
+ _engine->_gamestate->xs = old_xstack;
}
@@ -3619,6 +3982,55 @@ bool Console::cmdSfx01Track(int argc, const char **argv) {
return true;
}
+bool Console::cmdMapVocab994(int argc, const char **argv) {
+ EngineState *s = _engine->_gamestate; // for the several defines in this function
+ reg_t reg;
+
+ if (argc != 4) {
+ debugPrintf("Attempts to map a range of vocab.994 entries to a given class\n");
+ debugPrintf("Usage: %s <class addr> <first> <last>\n", argv[0]);
+ return true;
+ }
+
+ if (parse_reg_t(_engine->_gamestate, argv[1], &reg, false)) {
+ debugPrintf("Invalid address passed.\n");
+ debugPrintf("Check the \"addresses\" command on how to use addresses\n");
+ return true;
+ }
+
+ Resource *resource = _engine->_resMan->findResource(ResourceId(kResourceTypeVocab, 994), 0);
+ const Object *obj = s->_segMan->getObject(reg);
+ uint16 *data = (uint16 *) resource->data;
+ uint32 first = atoi(argv[2]);
+ uint32 last = atoi(argv[3]);
+ Common::Array<bool> markers;
+
+ markers.resize(_engine->getKernel()->getSelectorNamesSize());
+ if (!obj->isClass() && getSciVersion() != SCI_VERSION_3)
+ obj = s->_segMan->getObject(obj->getSuperClassSelector());
+
+ first = MIN(first, (uint32) (resource->size / 2 - 2));
+ last = MIN(last, (uint32) (resource->size / 2 - 2));
+
+ for (uint32 i = first; i <= last; ++i) {
+ uint16 ofs = data[i];
+
+ if (obj && ofs < obj->getVarCount()) {
+ uint16 varSelector = obj->getVarSelector(ofs);
+ debugPrintf("%d: property at index %04x of %s is %s %s\n", i, ofs,
+ s->_segMan->derefString(obj->getNameSelector()),
+ _engine->getKernel()->getSelectorName(varSelector).c_str(),
+ markers[varSelector] ? "(repeat!)" : "");
+ markers[varSelector] = true;
+ }
+ else {
+ debugPrintf("%d: property at index %04x doesn't match up with %s\n", i, ofs,
+ s->_segMan->derefString(obj->getNameSelector()));
+ }
+ }
+
+ return true;
+}
bool Console::cmdQuit(int argc, const char **argv) {
if (argc != 2) {
}
@@ -3977,7 +4389,7 @@ void Console::printList(List *list) {
return;
}
- node = &(nt->_table[pos.getOffset()]);
+ node = &nt->at(pos.getOffset());
debugPrintf("\t%04x:%04x : %04x:%04x -> %04x:%04x\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value));
@@ -4007,7 +4419,7 @@ int Console::printNode(reg_t addr) {
return 1;
}
- list = &(lt->_table[addr.getOffset()]);
+ list = &lt->at(addr.getOffset());
debugPrintf("%04x:%04x : first x last = (%04x:%04x, %04x:%04x)\n", PRINT_REG(addr), PRINT_REG(list->first), PRINT_REG(list->last));
} else {
@@ -4026,7 +4438,7 @@ int Console::printNode(reg_t addr) {
debugPrintf("Address does not contain a node\n");
return 1;
}
- node = &(nt->_table[addr.getOffset()]);
+ node = &nt->at(addr.getOffset());
debugPrintf("%04x:%04x : prev x next = (%04x:%04x, %04x:%04x); maps %04x:%04x -> %04x:%04x\n",
PRINT_REG(addr), PRINT_REG(node->pred), PRINT_REG(node->succ), PRINT_REG(node->key), PRINT_REG(node->value));
@@ -4057,7 +4469,8 @@ int Console::printObject(reg_t pos) {
debugPrintf(" ");
if (var_container && i < var_container->getVarCount()) {
uint16 varSelector = var_container->getVarSelector(i);
- debugPrintf("[%03x] %s = ", varSelector, _engine->getKernel()->getSelectorName(varSelector).c_str());
+ // Times two commented out for now for easy parsing of vocab.994
+ debugPrintf("(%04x) [%03x] %s = ", i /* *2 */, varSelector, _engine->getKernel()->getSelectorName(varSelector).c_str());
} else
debugPrintf("p#%x = ", i);