diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/console.cpp | 244 | ||||
-rw-r--r-- | engines/sci/console.h | 2 |
2 files changed, 172 insertions, 74 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index a3abf606d0..3f5548aac7 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -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; } + 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 +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"); diff --git a/engines/sci/console.h b/engines/sci/console.h index c8e99f78f7..6d024082b5 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -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); |