SCI: debugger / fix diskdump + list commands

diskdump: support for audio36+sync36
list: always show tuple for audio36+sync36
This commit is contained in:
Martin Kiewitz 2015-03-18 23:30:32 +01:00
parent 7a9514567f
commit 9a9f569f3b
2 changed files with 174 additions and 76 deletions

View File

@ -660,10 +660,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 +696,90 @@ bool Console::cmdDiskDump(int argc, const char **argv) {
return true;
}
if (strcmp(argv[2], "*") == 0) {
resNumFrom = 0;
resNumTo = 65535;
} else {
resNumFrom = atoi(argv[2]);
resNumTo = resNumFrom;
ResourceType resourceType = parseResourceType(argv[1]);
if (resourceType == kResourceTypeInvalid) {
debugPrintf("Resource type '%s' is not valid\n", argv[1]);
return true;
}
ResourceType res = parseResourceType(argv[1]);
if (res == 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);
}
if (strcmp(argv[2], "*") == 0) {
resourceAll = true;
} else {
switch (resourceType) {
case kResourceTypeAudio36:
case kResourceTypeSync36:
if (!parseResourceNumber36(argv[2], resourceNumber, resourceTuple)) {
return true;
}
break;
default:
resourceNumber = atoi(argv[2]);
break;
}
}
if (resourceType == kResourceTypeInvalid) {
debugPrintf("Resource type '%s' is not valid\n", argv[1]);
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 +819,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");
@ -1124,52 +1266,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");

View File

@ -68,6 +68,7 @@ private:
bool cmdSaid(int argc, const char **argv);
// Resources
bool cmdDiskDump(int argc, const char **argv);
void cmdDiskDumpWorker(ResourceType resourceType, int resourceNumber, uint32 resourceTuple);
bool cmdHexDump(int argc, const char **argv);
bool cmdResourceId(int argc, const char **argv);
bool cmdResourceInfo(int argc, const char **argv);
@ -157,6 +158,7 @@ private:
bool cmdViewAccumulatorObject(int argc, const char **argv);
bool parseInteger(const char *argument, int &result);
bool parseResourceNumber36(const char *userParameter, uint16 &resourceNumber, uint32 &resourceTuple);
void printBasicVarInfo(reg_t variable);