ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

console.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/stark/console.h"
00024 
00025 #include "engines/stark/formats/xarc.h"
00026 #include "engines/stark/resources/object.h"
00027 #include "engines/stark/resources/anim.h"
00028 #include "engines/stark/resources/level.h"
00029 #include "engines/stark/resources/location.h"
00030 #include "engines/stark/resources/knowledge.h"
00031 #include "engines/stark/resources/root.h"
00032 #include "engines/stark/resources/script.h"
00033 #include "engines/stark/resources/knowledgeset.h"
00034 #include "engines/stark/resources/item.h"
00035 #include "engines/stark/resources/textureset.h"
00036 #include "engines/stark/services/archiveloader.h"
00037 #include "engines/stark/services/dialogplayer.h"
00038 #include "engines/stark/services/global.h"
00039 #include "engines/stark/services/resourceprovider.h"
00040 #include "engines/stark/services/userinterface.h"
00041 #include "engines/stark/services/services.h"
00042 #include "engines/stark/services/staticprovider.h"
00043 #include "engines/stark/tools/decompiler.h"
00044 
00045 #include <limits.h>
00046 #include "common/file.h"
00047 
00048 namespace Stark {
00049 
00050 Console::Console() :
00051         GUI::Debugger() {
00052     registerCmd("dumpArchive",          WRAP_METHOD(Console, Cmd_DumpArchive));
00053     registerCmd("dumpRoot",             WRAP_METHOD(Console, Cmd_DumpRoot));
00054     registerCmd("dumpStatic",           WRAP_METHOD(Console, Cmd_DumpStatic));
00055     registerCmd("dumpGlobal",           WRAP_METHOD(Console, Cmd_DumpGlobal));
00056     registerCmd("dumpLevel",            WRAP_METHOD(Console, Cmd_DumpLevel));
00057     registerCmd("dumpKnowledge",        WRAP_METHOD(Console, Cmd_DumpKnowledge));
00058     registerCmd("dumpLocation",         WRAP_METHOD(Console, Cmd_DumpLocation));
00059     registerCmd("listScripts",          WRAP_METHOD(Console, Cmd_ListScripts));
00060     registerCmd("enableScript",         WRAP_METHOD(Console, Cmd_EnableScript));
00061     registerCmd("forceScript",          WRAP_METHOD(Console, Cmd_ForceScript));
00062     registerCmd("decompileScript",      WRAP_METHOD(Console, Cmd_DecompileScript));
00063     registerCmd("testDecompiler",       WRAP_METHOD(Console, Cmd_TestDecompiler));
00064     registerCmd("listAnimations",       WRAP_METHOD(Console, Cmd_ListAnimations));
00065     registerCmd("forceAnimation",       WRAP_METHOD(Console, Cmd_ForceAnimation));
00066     registerCmd("listInventoryItems",   WRAP_METHOD(Console, Cmd_ListInventoryItems));
00067     registerCmd("listLocations",        WRAP_METHOD(Console, Cmd_ListLocations));
00068     registerCmd("location",             WRAP_METHOD(Console, Cmd_Location));
00069     registerCmd("chapter",              WRAP_METHOD(Console, Cmd_Chapter));
00070     registerCmd("changeLocation",       WRAP_METHOD(Console, Cmd_ChangeLocation));
00071     registerCmd("changeChapter",        WRAP_METHOD(Console, Cmd_ChangeChapter));
00072     registerCmd("changeKnowledge",      WRAP_METHOD(Console, Cmd_ChangeKnowledge));
00073     registerCmd("enableInventoryItem",  WRAP_METHOD(Console, Cmd_EnableInventoryItem));
00074     registerCmd("extractAllTextures",   WRAP_METHOD(Console, Cmd_ExtractAllTextures));
00075 }
00076 
00077 Console::~Console() {
00078 }
00079 
00080 bool Console::Cmd_DumpArchive(int argc, const char **argv) {
00081     if (argc != 2) {
00082         debugPrintf("Extract all the files from a game archive\n");
00083         debugPrintf("The destination folder, named 'dump', is in the location ResidualVM was launched from\n");
00084         debugPrintf("Usage :\n");
00085         debugPrintf("dumpArchive [path to archive]\n");
00086         return true;
00087     }
00088 
00089     Formats::XARCArchive xarc;
00090     if (!xarc.open(argv[1])) {
00091         debugPrintf("Can't open archive with name '%s'\n", argv[1]);
00092         return true;
00093     }
00094 
00095     Common::ArchiveMemberList members;
00096     xarc.listMembers(members);
00097 
00098     for (Common::ArchiveMemberList::const_iterator it = members.begin(); it != members.end(); it++) {
00099         Common::String fileName = Common::String::format("dump/%s", it->get()->getName().c_str());
00100 
00101         // Open the output file
00102         Common::DumpFile outFile;
00103         if (!outFile.open(fileName, true)) {
00104             debugPrintf("Unable to open file '%s' for writing\n", fileName.c_str());
00105             return true;
00106         }
00107 
00108         // Copy the archive content to the output file using a temporary buffer
00109         Common::SeekableReadStream *inStream = it->get()->createReadStream();
00110         uint8 *buf = new uint8[inStream->size()];
00111 
00112         inStream->read(buf, inStream->size());
00113         outFile.write(buf, inStream->size());
00114 
00115         delete[] buf;
00116         delete inStream;
00117         outFile.close();
00118 
00119         debugPrintf("Extracted '%s'\n", it->get()->getName().c_str());
00120     }
00121 
00122     return true;
00123 }
00124 
00125 bool Console::Cmd_DumpRoot(int argc, const char **argv) {
00126     Resources::Root *root = StarkGlobal->getRoot();
00127     if (root) {
00128         root->print();
00129     } else {
00130         debugPrintf("The global root has not been loaded\n");
00131     }
00132 
00133     return true;
00134 }
00135 
00136 bool Console::Cmd_DumpGlobal(int argc, const char **argv) {
00137     Resources::Level *level = StarkGlobal->getLevel();
00138     if (level) {
00139         level->print();
00140     } else {
00141         debugPrintf("The global level has not been loaded\n");
00142     }
00143 
00144     return true;
00145 }
00146 
00147 bool Console::Cmd_DumpStatic(int argc, const char **argv) {
00148     // Static resources are initialized in the beginning of the running
00149     StarkStaticProvider->getLevel()->print();
00150 
00151     return true;
00152 }
00153 
00154 bool Console::Cmd_DumpLevel(int argc, const char **argv) {
00155     Current *current = StarkGlobal->getCurrent();
00156     if (current) {
00157         current->getLevel()->print();
00158     } else {
00159         debugPrintf("Game levels have not been loaded\n");
00160     }
00161 
00162     return true;
00163 }
00164 
00165 bool Console::Cmd_DumpKnowledge(int argc, const char **argv) {
00166     Current *current = StarkGlobal->getCurrent();
00167 
00168     if (!current) {
00169         debugPrintf("Game levels have not been loaded\n");
00170         return true;
00171     }
00172 
00173     Resources::Level *level = current->getLevel();
00174     Resources::Location *location = current->getLocation();
00175     Common::Array<Resources::Knowledge *> knowledge = level->listChildrenRecursive<Resources::Knowledge>();
00176     knowledge.insert_at(knowledge.size(), location->listChildrenRecursive<Resources::Knowledge>());
00177     Common::Array<Resources::Knowledge *>::iterator it;
00178     for (it = knowledge.begin(); it != knowledge.end(); ++it) {
00179         (*it)->print();
00180     }
00181     return true;
00182 }
00183 
00184 bool Console::Cmd_ChangeKnowledge(int argc, const char **argv) {
00185     Current *current = StarkGlobal->getCurrent();
00186 
00187     if (!current) {
00188         debugPrintf("Game levels have not been loaded\n");
00189         return true;
00190     }
00191 
00192     uint index = 0;
00193     char type = 0;
00194 
00195     if (argc >= 4) {
00196         index = atoi(argv[1]);
00197         type = argv[2][0];
00198         if (type == 'b' || type == 'i') {
00199             Resources::Level *level = current->getLevel();
00200             Resources::Location *location = current->getLocation();
00201             Common::Array<Resources::Knowledge *> knowledgeArr = level->listChildrenRecursive<Resources::Knowledge>();
00202             knowledgeArr.insert_at(knowledgeArr.size(), location->listChildrenRecursive<Resources::Knowledge>());
00203             if (index < knowledgeArr.size() ) {
00204                 Resources::Knowledge *knowledge = knowledgeArr[index];
00205                 if (type == 'b') {
00206                     knowledge->setBooleanValue(atoi(argv[3]));
00207                 } else if (type == 'i') {
00208                     knowledge->setIntegerValue(atoi(argv[3]));
00209                 }
00210                 return true;
00211             } else {
00212                 debugPrintf("Invalid index %d, only %d indices available\n", index, knowledgeArr.size());
00213             }
00214         } else {
00215             debugPrintf("Invalid type: %c, only b and i are available\n", type);
00216         }
00217     } else if (argc > 1 ) {
00218         debugPrintf("Too few args\n");
00219     }
00220 
00221     debugPrintf("Change the value of some knowledge. Use dumpKnowledge to get an id\n");
00222     debugPrintf("Usage :\n");
00223     debugPrintf("changeKnowledge [id] [type] [value]\n");
00224     debugPrintf("available types: b(inary), i(nteger)\n");
00225     return true;
00226 }
00227 
00228 Common::Array<Resources::Script *> Console::listAllLocationScripts() const {
00229     Common::Array<Resources::Script *> scripts;
00230 
00231     Resources::Level *level = StarkGlobal->getCurrent()->getLevel();
00232     Resources::Location *location = StarkGlobal->getCurrent()->getLocation();
00233     scripts.push_back(level->listChildrenRecursive<Resources::Script>());
00234     scripts.push_back(location->listChildrenRecursive<Resources::Script>());
00235 
00236     return scripts;
00237 }
00238 
00239 bool Console::Cmd_ListScripts(int argc, const char **argv) {
00240     Current *current = StarkGlobal->getCurrent();
00241     if (!current) {
00242         debugPrintf("Game levels have not been loaded\n");
00243         return true;
00244     }
00245 
00246     Common::Array<Resources::Script *> scripts = listAllLocationScripts();
00247 
00248     for (uint i = 0; i < scripts.size(); i++) {
00249         Resources::Script *script = scripts[i];
00250 
00251         debugPrintf("%d: %s - enabled: %d", i, script->getName().c_str(), script->isEnabled());
00252 
00253         // Print which resource is causing the script to wait
00254         if (script->isSuspended()) {
00255             Resources::Object *suspending = script->getSuspendingResource();
00256             if (suspending) {
00257                 debugPrintf(", waiting for: %s (%s)", suspending->getName().c_str(), suspending->getType().getName());
00258             } else {
00259                 debugPrintf(", paused");
00260             }
00261         }
00262 
00263         debugPrintf("\n");
00264     }
00265 
00266     return true;
00267 }
00268 
00269 bool Console::Cmd_EnableScript(int argc, const char **argv) {
00270     Current *current = StarkGlobal->getCurrent();
00271     if (!current) {
00272         debugPrintf("Game levels have not been loaded\n");
00273         return true;
00274     }
00275 
00276     uint index = 0;
00277 
00278     if (argc >= 2) {
00279         index = atoi(argv[1]);
00280 
00281         bool value = true;
00282         if (argc >= 3) {
00283             value = atoi(argv[2]);
00284         }
00285 
00286         Common::Array<Resources::Script *> scripts = listAllLocationScripts();
00287         if (index < scripts.size() ) {
00288             Resources::Script *script = scripts[index];
00289             script->enable(value);
00290             return true;
00291         } else {
00292             debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
00293         }
00294     }
00295 
00296     debugPrintf("Enable or disable a script. Use listScripts to get an id\n");
00297     debugPrintf("Usage :\n");
00298     debugPrintf("enableScript [id] (value)\n");
00299     return true;
00300 }
00301 
00302 bool Console::Cmd_ForceScript(int argc, const char **argv) {
00303     Current *current = StarkGlobal->getCurrent();
00304     if (!current) {
00305         debugPrintf("Game levels have not been loaded\n");
00306         return true;
00307     }
00308 
00309     uint index = 0;
00310 
00311     if (argc >= 2) {
00312         index = atoi(argv[1]);
00313 
00314         Common::Array<Resources::Script *> scripts = listAllLocationScripts();
00315         if (index < scripts.size() ) {
00316             Resources::Script *script = scripts[index];
00317             script->enable(true);
00318             script->goToNextCommand(); // Skip the begin command to avoid checks
00319             script->execute(Resources::Script::kCallModePlayerAction);
00320             return true;
00321         } else {
00322             debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
00323         }
00324     }
00325 
00326     debugPrintf("Force the execution of a script. Use listScripts to get an id\n");
00327     debugPrintf("Usage :\n");
00328     debugPrintf("forceScript [id]\n");
00329     return true;
00330 }
00331 
00332 bool Console::Cmd_DecompileScript(int argc, const char **argv) {
00333     Current *current = StarkGlobal->getCurrent();
00334     if (!current) {
00335         debugPrintf("Game levels have not been loaded\n");
00336         return true;
00337     }
00338 
00339     if (argc >= 2) {
00340         uint index = atoi(argv[1]);
00341 
00342         Common::Array<Resources::Script *> scripts = listAllLocationScripts();
00343         if (index < scripts.size()) {
00344             Resources::Script *script = scripts[index];
00345 
00346             Tools::Decompiler *decompiler = new Tools::Decompiler(script);
00347             if (decompiler->getError() != "") {
00348                 debugPrintf("Decompilation failure: %s\n", decompiler->getError().c_str());
00349             }
00350 
00351             debug("Script %d - %s:", index, script->getName().c_str());
00352             decompiler->printDecompiled();
00353 
00354             delete decompiler;
00355 
00356             return true;
00357         } else {
00358             debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
00359         }
00360     }
00361 
00362     debugPrintf("Decompile a script. Use listScripts to get an id\n");
00363     debugPrintf("Usage :\n");
00364     debugPrintf("decompileScript [id]\n");
00365     return true;
00366 }
00367 
00368 class ArchiveVisitor {
00369 public:
00370     virtual ~ArchiveVisitor() {}
00371     virtual void acceptLevelArchive(Resources::Level *level) = 0;
00372     virtual void acceptLocationArchive(Resources::Location *location) = 0;
00373 };
00374 
00375 void Console::walkAllArchives(ArchiveVisitor *visitor) {
00376     ArchiveLoader *archiveLoader = new ArchiveLoader();
00377 
00378     // Temporarily replace the global archive loader with our instance
00379     ArchiveLoader *gameArchiveLoader = StarkArchiveLoader;
00380     StarkArchiveLoader = archiveLoader;
00381 
00382     archiveLoader->load("x.xarc");
00383     Resources::Root *root = archiveLoader->useRoot<Resources::Root>("x.xarc");
00384 
00385     // Find all the levels
00386     Common::Array<Resources::Level *> levels = root->listChildren<Resources::Level>();
00387 
00388     // Loop over the levels
00389     for (uint i = 0; i < levels.size(); i++) {
00390         Resources::Level *level = levels[i];
00391 
00392         Common::String levelArchive = archiveLoader->buildArchiveName(level);
00393         debug("%s - %s", levelArchive.c_str(), level->getName().c_str());
00394 
00395         // Load the detailed level archive
00396         archiveLoader->load(levelArchive);
00397         level = archiveLoader->useRoot<Resources::Level>(levelArchive);
00398 
00399         // Visit the level archive
00400         visitor->acceptLevelArchive(level);
00401 
00402         Common::Array<Resources::Location *> locations = level->listChildren<Resources::Location>();
00403 
00404         // Loop over the locations
00405         for (uint j = 0; j < locations.size(); j++) {
00406             Resources::Location *location = locations[j];
00407 
00408             Common::String locationArchive = archiveLoader->buildArchiveName(level, location);
00409             debug("%s - %s", locationArchive.c_str(), location->getName().c_str());
00410 
00411             // Load the detailed location archive
00412             archiveLoader->load(locationArchive);
00413             location = archiveLoader->useRoot<Resources::Location>(locationArchive);
00414 
00415             // Visit the location archive
00416             visitor->acceptLocationArchive(location);
00417 
00418             archiveLoader->returnRoot(locationArchive);
00419             archiveLoader->unloadUnused();
00420         }
00421 
00422         archiveLoader->returnRoot(levelArchive);
00423         archiveLoader->unloadUnused();
00424     }
00425 
00426     // Restore the global archive loader
00427     StarkArchiveLoader = gameArchiveLoader;
00428 
00429     delete archiveLoader;
00430 }
00431 
00432 class DecompilingArchiveVisitor : public ArchiveVisitor {
00433 public:
00434     DecompilingArchiveVisitor() :
00435         _totalScripts(0),
00436         _okScripts(0) {}
00437 
00438     void acceptLevelArchive(Resources::Level *level) override {
00439         decompileScriptChildren(level);
00440     }
00441 
00442     void acceptLocationArchive(Resources::Location *location) override {
00443         decompileScriptChildren(location);
00444     }
00445 
00446     int getTotalScripts() const { return _totalScripts; }
00447     int getOKScripts() const { return _okScripts; }
00448 
00449 private:
00450     int _totalScripts;
00451     int _okScripts;
00452 
00453     void decompileScriptChildren(Resources::Object *resource) {
00454         Common::Array<Resources::Script *> scripts = resource->listChildrenRecursive<Resources::Script>();
00455 
00456         for (uint i = 0; i < scripts.size(); i++) {
00457             Resources::Script *script = scripts[i];
00458 
00459             Tools::Decompiler decompiler(script);
00460             _totalScripts++;
00461 
00462             Common::String result;
00463             if (decompiler.getError() == "") {
00464                 result = "OK";
00465                 _okScripts++;
00466             } else {
00467                 result = decompiler.getError();
00468             }
00469 
00470             debug("%d - %s: %s", script->getIndex(), script->getName().c_str(), result.c_str());
00471         }
00472     }
00473 };
00474 
00475 bool Console::Cmd_TestDecompiler(int argc, const char **argv) {
00476     DecompilingArchiveVisitor visitor;
00477     walkAllArchives(&visitor);
00478 
00479     debugPrintf("Successfully decompiled %d scripts out of %d\n", visitor.getOKScripts(), visitor.getTotalScripts());
00480 
00481     return true;
00482 }
00483 
00484 class TextureExtractingArchiveVisitor : public ArchiveVisitor {
00485 public:
00486     void acceptLevelArchive(Resources::Level *level) override {
00487         decompileScriptChildren(level);
00488     }
00489 
00490     void acceptLocationArchive(Resources::Location *location) override {
00491         decompileScriptChildren(location);
00492     }
00493 
00494 private:
00495     void decompileScriptChildren(Resources::Object *resource) {
00496         Common::Array<Resources::TextureSet *> textureSets = resource->listChildrenRecursive<Resources::TextureSet>();
00497 
00498         for (uint i = 0; i < textureSets.size(); i++) {
00499             Resources::TextureSet *textureSet = textureSets[i];
00500             textureSet->extractArchive();
00501         }
00502     }
00503 };
00504 
00505 bool Console::Cmd_ExtractAllTextures(int argc, const char **argv) {
00506     TextureExtractingArchiveVisitor visitor;
00507     walkAllArchives(&visitor);
00508 
00509     return true;
00510 }
00511 
00512 Common::Array<Resources::Anim *> Console::listAllLocationAnimations() const {
00513     Common::Array<Resources::Anim *> animations;
00514 
00515     Resources::Level *level = StarkGlobal->getCurrent()->getLevel();
00516     Resources::Location *location = StarkGlobal->getCurrent()->getLocation();
00517     animations.push_back(level->listChildrenRecursive<Resources::Anim>());
00518     animations.push_back(location->listChildrenRecursive<Resources::Anim>());
00519 
00520     return animations;
00521 }
00522 
00523 bool Console::Cmd_ListAnimations(int argc, const char **argv) {
00524     Current *current = StarkGlobal->getCurrent();
00525     if (!current) {
00526         debugPrintf("This command is only available in game.\n");
00527         return true;
00528     }
00529 
00530     Common::Array<Resources::Anim *> animations = listAllLocationAnimations();
00531 
00532     for (uint i = 0; i < animations.size(); i++) {
00533         Resources::Anim *anim = animations[i];
00534         Resources::Item *item = anim->findParent<Resources::Item>();
00535 
00536         debugPrintf("%d: %s - %s - in use: %d\n", i, item->getName().c_str(), anim->getName().c_str(), anim->isInUse());
00537     }
00538 
00539     return true;
00540 }
00541 
00542 bool Console::Cmd_ForceAnimation(int argc, const char **argv) {
00543     Current *current = StarkGlobal->getCurrent();
00544     if (!current) {
00545         debugPrintf("This command is only available in game.\n");
00546         return true;
00547     }
00548 
00549     if (argc < 2) {
00550         debugPrintf("Force the execution of an animation. Use listAnimations to get an id\n");
00551         debugPrintf("Usage :\n");
00552         debugPrintf("forceAnimation [id]\n");
00553         return true;
00554     }
00555 
00556     uint index = atoi(argv[1]);
00557 
00558     Common::Array<Resources::Anim *> animations = listAllLocationAnimations();
00559     if (index >= animations.size() ) {
00560         debugPrintf("Invalid animation %d\n", index);
00561         return true;
00562     }
00563 
00564     Resources::Anim *anim = animations[index];
00565     Resources::Item *item = anim->findParent<Resources::Item>();
00566     Resources::ItemVisual *sceneItem = item->getSceneInstance();
00567 
00568     if (!sceneItem->isEnabled()) {
00569         sceneItem->setEnabled(true);
00570     }
00571 
00572     sceneItem->playActionAnim(anim);
00573 
00574     return false;
00575 }
00576 
00577 bool Console::Cmd_DumpLocation(int argc, const char **argv) {
00578     if (StarkStaticProvider->isStaticLocation()) {
00579         StarkStaticProvider->getLocation()->print();
00580         return true;
00581     }
00582 
00583     Current *current = StarkGlobal->getCurrent();
00584     if (current) {
00585         current->getLocation()->print();
00586     } else {
00587         debugPrintf("Locations have not been loaded\n");
00588     }
00589 
00590     return true;
00591 }
00592 
00593 bool Console::Cmd_ListInventoryItems(int argc, const char **argv) {
00594     Resources::KnowledgeSet *inventory = StarkGlobal->getInventory();
00595 
00596     if (!inventory) {
00597         debugPrintf("The inventory has not been loaded\n");
00598         return true;
00599     }
00600 
00601     Common::Array<Resources::Item*> inventoryItems = inventory->listChildren<Resources::Item>(Resources::Item::kItemInventory);
00602     Common::Array<Resources::Item*>::iterator it = inventoryItems.begin();
00603     for (int i = 0; it != inventoryItems.end(); ++it, i++) {
00604         debugPrintf("Item %d: %s%s\n", i, (*it)->getName().c_str(), (*it)->isEnabled() ? " (enabled)" : "");
00605     }
00606 
00607     return true;
00608 }
00609 
00610 bool Console::Cmd_EnableInventoryItem(int argc, const char **argv) {
00611     Resources::KnowledgeSet *inventory = StarkGlobal->getInventory();
00612 
00613     if (!inventory) {
00614         debugPrintf("The inventory has not been loaded\n");
00615         return true;
00616     }
00617 
00618     if (argc != 2) {
00619         debugPrintf("Enable a specific inventory item. Use listInventoryItems to get an id\n");
00620         debugPrintf("Usage :\n");
00621         debugPrintf("enableInventoryItem [id]\n");
00622         return true;
00623     }
00624 
00625     uint num = atoi(argv[1]);
00626     Common::Array<Resources::Item*> inventoryItems = inventory->listChildren<Resources::Item>(Resources::Item::kItemInventory);
00627     if (num < inventoryItems.size()) {
00628         inventoryItems[num]->setEnabled(true);
00629     } else {
00630         debugPrintf("Invalid index %d, only %d indices available\n", num, inventoryItems.size());
00631     }
00632 
00633     return true;
00634 }
00635 
00636 bool Console::Cmd_ListLocations(int argc, const char **argv) {
00637     ArchiveLoader *archiveLoader = new ArchiveLoader();
00638 
00639     // Temporarily replace the global archive loader with our instance
00640     ArchiveLoader *gameArchiveLoader = StarkArchiveLoader;
00641     StarkArchiveLoader = archiveLoader;
00642 
00643     archiveLoader->load("x.xarc");
00644     Resources::Root *root = archiveLoader->useRoot<Resources::Root>("x.xarc");
00645 
00646     // Find all the levels
00647     Common::Array<Resources::Level *> levels = root->listChildren<Resources::Level>();
00648 
00649     // Loop over the levels
00650     for (uint i = 0; i < levels.size(); i++) {
00651         Resources::Level *level = levels[i];
00652 
00653         Common::String levelArchive = archiveLoader->buildArchiveName(level);
00654         debugPrintf("%s - %s\n", levelArchive.c_str(), level->getName().c_str());
00655 
00656         // Load the detailed level archive
00657         archiveLoader->load(levelArchive);
00658         level = archiveLoader->useRoot<Resources::Level>(levelArchive);
00659 
00660         Common::Array<Resources::Location *> locations = level->listChildren<Resources::Location>();
00661 
00662         // Loop over the locations
00663         for (uint j = 0; j < locations.size(); j++) {
00664             Resources::Location *location = locations[j];
00665 
00666             Common::String roomArchive = archiveLoader->buildArchiveName(level, location);
00667             debugPrintf("%s - %s\n", roomArchive.c_str(), location->getName().c_str());
00668         }
00669 
00670         archiveLoader->returnRoot(levelArchive);
00671         archiveLoader->unloadUnused();
00672     }
00673 
00674     // Restore the global archive loader
00675     StarkArchiveLoader = gameArchiveLoader;
00676 
00677     delete archiveLoader;
00678 
00679     return true;
00680 }
00681 
00682 bool Console::Cmd_ChangeLocation(int argc, const char **argv) {
00683     if (argc >= 3) {
00684         // Assert indices
00685         Common::String xarcFileName = Common::String::format("%s/%s/%s.xarc", argv[1], argv[2], argv[2]);
00686         if (!Common::File::exists(xarcFileName)) {
00687             debugPrintf("Invalid location %s %s. Use listLocations to get correct indices\n", argv[1], argv[2]);
00688             return true;
00689         }
00690 
00691         uint levelIndex = strtol(argv[1] , nullptr, 16);
00692         uint locationIndex = strtol(argv[2] , nullptr, 16);
00693 
00694         StarkUserInterface->changeScreen(Screen::kScreenGame);
00695 
00696         if (!StarkGlobal->getRoot()) {
00697             StarkResourceProvider->initGlobal();
00698         }
00699 
00700         StarkResourceProvider->requestLocationChange(levelIndex, locationIndex);
00701 
00702         return false;
00703     } else if (argc > 1) {
00704         debugPrintf("Too few args\n");
00705     }
00706 
00707     debugPrintf("Change the current location. Use listLocations to get indices\n");
00708     debugPrintf("Usage :\n");
00709     debugPrintf("changeLocation [level] [location]\n");
00710     return true;
00711 }
00712 
00713 bool Console::Cmd_ChangeChapter(int argc, const char **argv) {
00714     if (!StarkGlobal->getLevel()) {
00715         debugPrintf("The global level has not been loaded\n");
00716         return true;
00717     }
00718 
00719     if (argc != 2) {
00720         debugPrintf("Change the current chapter\n");
00721         debugPrintf("Usage :\n");
00722         debugPrintf("changeChapter [value]\n");
00723         return true;
00724     }
00725 
00726     char *endPtr = nullptr;
00727     long value = strtol(argv[1], &endPtr, 10);
00728     if (*endPtr == '\0' && value >= 0 && value <= INT_MAX)
00729         StarkGlobal->setCurrentChapter((int32) value);
00730     else
00731         debugPrintf("Invalid chapter\n");
00732 
00733     return true;
00734 }
00735 
00736 bool Console::Cmd_Location(int argc, const char **argv) {
00737     Current *current = StarkGlobal->getCurrent();
00738 
00739     if (!current) {
00740         debugPrintf("Game levels have not been loaded\n");
00741         return true;
00742     }
00743 
00744     if (argc != 1) {
00745         debugPrintf("Display the current location\n");
00746         debugPrintf("Usage :\n");
00747         debugPrintf("location\n");
00748         return true;
00749     }
00750 
00751     debugPrintf("location: %02x %02x\n", current->getLevel()->getIndex(), current->getLocation()->getIndex());
00752 
00753     return true;
00754 }
00755 
00756 bool Console::Cmd_Chapter(int argc, const char **argv) {
00757     if (!StarkGlobal->getLevel()) {
00758         debugPrintf("The global level has not been loaded\n");
00759         return true;
00760     }
00761 
00762     if (argc != 1) {
00763         debugPrintf("Display the current chapter\n");
00764         debugPrintf("Usage :\n");
00765         debugPrintf("chapter\n");
00766         return true;
00767     }
00768 
00769     int32 value = StarkGlobal->getCurrentChapter();
00770 
00771     debugPrintf("chapter: %d\n", value);
00772 
00773     return true;
00774 }
00775 
00776 } // End of namespace Stark


Generated on Sat Sep 26 2020 05:01:02 for ResidualVM by doxygen 1.7.1
curved edge   curved edge