mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-10 04:43:26 +00:00
SCI: debugger / fix diskdump + list commands
diskdump: support for audio36+sync36 list: always show tuple for audio36+sync36
This commit is contained in:
parent
7a9514567f
commit
9a9f569f3b
@ -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");
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user