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

engines/stark/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/services/archiveloader.h"
00036 #include "engines/stark/services/dialogplayer.h"
00037 #include "engines/stark/services/global.h"
00038 #include "engines/stark/services/resourceprovider.h"
00039 #include "engines/stark/services/userinterface.h"
00040 #include "engines/stark/services/services.h"
00041 #include "engines/stark/services/staticprovider.h"
00042 #include "engines/stark/tools/decompiler.h"
00043 
00044 #include <limits.h>
00045 #include "common/file.h"
00046 
00047 namespace Stark {
00048 
00049 Console::Console() :
00050         GUI::Debugger(),
00051         _testDecompilerTotalScripts(0),
00052         _testDecompilerOKScripts(0) {
00053     registerCmd("dumpArchive",          WRAP_METHOD(Console, Cmd_DumpArchive));
00054     registerCmd("dumpRoot",             WRAP_METHOD(Console, Cmd_DumpRoot));
00055     registerCmd("dumpStatic",           WRAP_METHOD(Console, Cmd_DumpStatic));
00056     registerCmd("dumpGlobal",           WRAP_METHOD(Console, Cmd_DumpGlobal));
00057     registerCmd("dumpLevel",            WRAP_METHOD(Console, Cmd_DumpLevel));
00058     registerCmd("dumpKnowledge",        WRAP_METHOD(Console, Cmd_DumpKnowledge));
00059     registerCmd("dumpLocation",         WRAP_METHOD(Console, Cmd_DumpLocation));
00060     registerCmd("listScripts",          WRAP_METHOD(Console, Cmd_ListScripts));
00061     registerCmd("enableScript",         WRAP_METHOD(Console, Cmd_EnableScript));
00062     registerCmd("forceScript",          WRAP_METHOD(Console, Cmd_ForceScript));
00063     registerCmd("decompileScript",      WRAP_METHOD(Console, Cmd_DecompileScript));
00064     registerCmd("testDecompiler",       WRAP_METHOD(Console, Cmd_TestDecompiler));
00065     registerCmd("listAnimations",       WRAP_METHOD(Console, Cmd_ListAnimations));
00066     registerCmd("forceAnimation",       WRAP_METHOD(Console, Cmd_ForceAnimation));
00067     registerCmd("listInventoryItems",   WRAP_METHOD(Console, Cmd_ListInventoryItems));
00068     registerCmd("listLocations",        WRAP_METHOD(Console, Cmd_ListLocations));
00069     registerCmd("location",             WRAP_METHOD(Console, Cmd_Location));
00070     registerCmd("chapter",              WRAP_METHOD(Console, Cmd_Chapter));
00071     registerCmd("changeLocation",       WRAP_METHOD(Console, Cmd_ChangeLocation));
00072     registerCmd("changeChapter",        WRAP_METHOD(Console, Cmd_ChangeChapter));
00073     registerCmd("changeKnowledge",      WRAP_METHOD(Console, Cmd_ChangeKnowledge));
00074     registerCmd("enableInventoryItem",  WRAP_METHOD(Console, Cmd_EnableInventoryItem));
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', must exist in 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)) {
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 {
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     } else {
00295         debugPrintf("Too few args\n");
00296     }
00297 
00298     debugPrintf("Enable or disable a script. Use listScripts to get an id\n");
00299     debugPrintf("Usage :\n");
00300     debugPrintf("enableScript [id] (value)\n");
00301     return true;
00302 }
00303 
00304 bool Console::Cmd_ForceScript(int argc, const char **argv) {
00305     Current *current = StarkGlobal->getCurrent();
00306     if (!current) {
00307         debugPrintf("Game levels have not been loaded\n");
00308         return true;
00309     }
00310 
00311     uint index = 0;
00312 
00313     if (argc >= 2) {
00314         index = atoi(argv[1]);
00315 
00316         Common::Array<Resources::Script *> scripts = listAllLocationScripts();
00317         if (index < scripts.size() ) {
00318             Resources::Script *script = scripts[index];
00319             script->enable(true);
00320             script->goToNextCommand(); // Skip the begin command to avoid checks
00321             script->execute(Resources::Script::kCallModePlayerAction);
00322             return true;
00323         } else {
00324             debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
00325         }
00326     } else {
00327         debugPrintf("Too few args\n");
00328     }
00329 
00330     debugPrintf("Force the execution of a script. Use listScripts to get an id\n");
00331     debugPrintf("Usage :\n");
00332     debugPrintf("forceScript [id]\n");
00333     return true;
00334 }
00335 
00336 bool Console::Cmd_DecompileScript(int argc, const char **argv) {
00337     Current *current = StarkGlobal->getCurrent();
00338     if (!current) {
00339         debugPrintf("Game levels have not been loaded\n");
00340         return true;
00341     }
00342 
00343     if (argc >= 2) {
00344         uint index = atoi(argv[1]);
00345 
00346         Common::Array<Resources::Script *> scripts = listAllLocationScripts();
00347         if (index < scripts.size()) {
00348             Resources::Script *script = scripts[index];
00349 
00350             Tools::Decompiler *decompiler = new Tools::Decompiler(script);
00351             if (decompiler->getError() != "") {
00352                 debugPrintf("Decompilation failure: %s\n", decompiler->getError().c_str());
00353             }
00354 
00355             debug("Script %d - %s:", index, script->getName().c_str());
00356             decompiler->printDecompiled();
00357 
00358             delete decompiler;
00359 
00360             return true;
00361         } else {
00362             debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
00363         }
00364     } else {
00365         debugPrintf("Too few args\n");
00366     }
00367 
00368     debugPrintf("Decompile a script. Use listScripts to get an id\n");
00369     debugPrintf("Usage :\n");
00370     debugPrintf("decompileScript [id]\n");
00371     return true;
00372 }
00373 
00374 bool Console::Cmd_TestDecompiler(int argc, const char **argv) {
00375     _testDecompilerTotalScripts = 0;
00376     _testDecompilerOKScripts = 0;
00377 
00378     ArchiveLoader *archiveLoader = new ArchiveLoader();
00379 
00380     // Temporarily replace the global archive loader with our instance
00381     ArchiveLoader *gameArchiveLoader = StarkArchiveLoader;
00382     StarkArchiveLoader = archiveLoader;
00383 
00384     archiveLoader->load("x.xarc");
00385     Resources::Root *root = archiveLoader->useRoot<Resources::Root>("x.xarc");
00386 
00387     // Find all the levels
00388     Common::Array<Resources::Level *> levels = root->listChildren<Resources::Level>();
00389 
00390     // Loop over the levels
00391     for (uint i = 0; i < levels.size(); i++) {
00392         Resources::Level *level = levels[i];
00393 
00394         Common::String levelArchive = archiveLoader->buildArchiveName(level);
00395         debug("%s - %s", levelArchive.c_str(), level->getName().c_str());
00396 
00397         // Load the detailed level archive
00398         archiveLoader->load(levelArchive);
00399         level = archiveLoader->useRoot<Resources::Level>(levelArchive);
00400 
00401         // Decompile all the scripts in the level archive
00402         decompileScriptChildren(level);
00403 
00404         Common::Array<Resources::Location *> locations = level->listChildren<Resources::Location>();
00405 
00406         // Loop over the locations
00407         for (uint j = 0; j < locations.size(); j++) {
00408             Resources::Location *location = locations[j];
00409 
00410             Common::String locationArchive = archiveLoader->buildArchiveName(level, location);
00411             debug("%s - %s", locationArchive.c_str(), location->getName().c_str());
00412 
00413             // Load the detailed location archive
00414             archiveLoader->load(locationArchive);
00415             location = archiveLoader->useRoot<Resources::Location>(locationArchive);
00416 
00417             // Decompile all the scripts in the location archive
00418             decompileScriptChildren(location);
00419 
00420             archiveLoader->returnRoot(locationArchive);
00421             archiveLoader->unloadUnused();
00422         }
00423 
00424         archiveLoader->returnRoot(levelArchive);
00425         archiveLoader->unloadUnused();
00426     }
00427 
00428     // Restore the global archive loader
00429     StarkArchiveLoader = gameArchiveLoader;
00430 
00431     delete archiveLoader;
00432 
00433     debugPrintf("Successfully decompiled %d scripts out of %d\n", _testDecompilerOKScripts, _testDecompilerTotalScripts);
00434 
00435     return true;
00436 }
00437 
00438 void Console::decompileScriptChildren(Resources::Object *level) {
00439     Common::Array<Resources::Script *> scripts = level->listChildrenRecursive<Resources::Script>();
00440 
00441     for (uint j = 0; j < scripts.size(); j++) {
00442         Resources::Script *script = scripts[j];
00443 
00444         Tools::Decompiler *decompiler = new Tools::Decompiler(script);
00445         _testDecompilerTotalScripts++;
00446 
00447         Common::String result;
00448         if (decompiler->getError() == "") {
00449             result = "OK";
00450             _testDecompilerOKScripts++;
00451         } else {
00452             result = decompiler->getError();
00453         }
00454 
00455         debug("%d - %s: %s", script->getIndex(), script->getName().c_str(), result.c_str());
00456 
00457         delete decompiler;
00458     }
00459 }
00460 
00461 Common::Array<Resources::Anim *> Console::listAllLocationAnimations() const {
00462     Common::Array<Resources::Anim *> animations;
00463 
00464     Resources::Level *level = StarkGlobal->getCurrent()->getLevel();
00465     Resources::Location *location = StarkGlobal->getCurrent()->getLocation();
00466     animations.push_back(level->listChildrenRecursive<Resources::Anim>());
00467     animations.push_back(location->listChildrenRecursive<Resources::Anim>());
00468 
00469     return animations;
00470 }
00471 
00472 bool Console::Cmd_ListAnimations(int argc, const char **argv) {
00473     Current *current = StarkGlobal->getCurrent();
00474     if (!current) {
00475         debugPrintf("This command is only available in game.\n");
00476         return true;
00477     }
00478 
00479     Common::Array<Resources::Anim *> animations = listAllLocationAnimations();
00480 
00481     for (uint i = 0; i < animations.size(); i++) {
00482         Resources::Anim *anim = animations[i];
00483         Resources::Item *item = anim->findParent<Resources::Item>();
00484 
00485         debugPrintf("%d: %s - %s - in use: %d\n", i, item->getName().c_str(), anim->getName().c_str(), anim->isInUse());
00486     }
00487 
00488     return true;
00489 }
00490 
00491 bool Console::Cmd_ForceAnimation(int argc, const char **argv) {
00492     Current *current = StarkGlobal->getCurrent();
00493     if (!current) {
00494         debugPrintf("This command is only available in game.\n");
00495         return true;
00496     }
00497 
00498     if (argc < 2) {
00499         debugPrintf("Force the execution of an animation. Use listAnimations to get an id\n");
00500         debugPrintf("Usage :\n");
00501         debugPrintf("forceAnimation [id]\n");
00502         return true;
00503     }
00504 
00505     uint index = atoi(argv[1]);
00506 
00507     Common::Array<Resources::Anim *> animations = listAllLocationAnimations();
00508     if (index >= animations.size() ) {
00509         debugPrintf("Invalid animation %d\n", index);
00510         return true;
00511     }
00512 
00513     Resources::Anim *anim = animations[index];
00514     Resources::Item *item = anim->findParent<Resources::Item>();
00515     Resources::ItemVisual *sceneItem = item->getSceneInstance();
00516 
00517     if (!sceneItem->isEnabled()) {
00518         sceneItem->setEnabled(true);
00519     }
00520 
00521     sceneItem->playActionAnim(anim);
00522 
00523     return false;
00524 }
00525 
00526 bool Console::Cmd_DumpLocation(int argc, const char **argv) {
00527     if (StarkStaticProvider->isStaticLocation()) {
00528         StarkStaticProvider->getLocation()->print();
00529         return true;
00530     }
00531 
00532     Current *current = StarkGlobal->getCurrent();
00533     if (current) {
00534         current->getLocation()->print();
00535     } else {
00536         debugPrintf("Locations have not been loaded\n");
00537     }
00538 
00539     return true;
00540 }
00541 
00542 bool Console::Cmd_ListInventoryItems(int argc, const char **argv) {
00543     Resources::KnowledgeSet *inventory = StarkGlobal->getInventory();
00544 
00545     if (!inventory) {
00546         debugPrintf("The inventory has not been loaded\n");
00547         return true;
00548     }
00549 
00550     Common::Array<Resources::Item*> inventoryItems = inventory->listChildren<Resources::Item>(Resources::Item::kItemInventory);
00551     Common::Array<Resources::Item*>::iterator it = inventoryItems.begin();
00552     for (int i = 0; it != inventoryItems.end(); ++it, i++) {
00553         debugPrintf("Item %d: %s%s\n", i, (*it)->getName().c_str(), (*it)->isEnabled() ? " (enabled)" : "");
00554     }
00555 
00556     return true;
00557 }
00558 
00559 bool Console::Cmd_EnableInventoryItem(int argc, const char **argv) {
00560     Resources::KnowledgeSet *inventory = StarkGlobal->getInventory();
00561 
00562     if (!inventory) {
00563         debugPrintf("The inventory has not been loaded\n");
00564         return true;
00565     }
00566 
00567     if (argc != 2) {
00568         debugPrintf("Enable a specific inventory item. Use listInventoryItems to get an id\n");
00569         debugPrintf("Usage :\n");
00570         debugPrintf("enableInventoryItem [id]\n");
00571         return true;
00572     }
00573 
00574     uint num = atoi(argv[1]);
00575     Common::Array<Resources::Item*> inventoryItems = inventory->listChildren<Resources::Item>(Resources::Item::kItemInventory);
00576     if (num < inventoryItems.size()) {
00577         inventoryItems[num]->setEnabled(true);
00578     } else {
00579         debugPrintf("Invalid index %d, only %d indices available\n", num, inventoryItems.size());
00580     }
00581 
00582     return true;
00583 }
00584 
00585 bool Console::Cmd_ListLocations(int argc, const char **argv) {
00586     ArchiveLoader *archiveLoader = new ArchiveLoader();
00587 
00588     // Temporarily replace the global archive loader with our instance
00589     ArchiveLoader *gameArchiveLoader = StarkArchiveLoader;
00590     StarkArchiveLoader = archiveLoader;
00591 
00592     archiveLoader->load("x.xarc");
00593     Resources::Root *root = archiveLoader->useRoot<Resources::Root>("x.xarc");
00594 
00595     // Find all the levels
00596     Common::Array<Resources::Level *> levels = root->listChildren<Resources::Level>();
00597 
00598     // Loop over the levels
00599     for (uint i = 0; i < levels.size(); i++) {
00600         Resources::Level *level = levels[i];
00601 
00602         Common::String levelArchive = archiveLoader->buildArchiveName(level);
00603         debugPrintf("%s - %s\n", levelArchive.c_str(), level->getName().c_str());
00604 
00605         // Load the detailed level archive
00606         archiveLoader->load(levelArchive);
00607         level = archiveLoader->useRoot<Resources::Level>(levelArchive);
00608 
00609         Common::Array<Resources::Location *> locations = level->listChildren<Resources::Location>();
00610 
00611         // Loop over the locations
00612         for (uint j = 0; j < locations.size(); j++) {
00613             Resources::Location *location = locations[j];
00614 
00615             Common::String roomArchive = archiveLoader->buildArchiveName(level, location);
00616             debugPrintf("%s - %s\n", roomArchive.c_str(), location->getName().c_str());
00617         }
00618 
00619         archiveLoader->returnRoot(levelArchive);
00620         archiveLoader->unloadUnused();
00621     }
00622 
00623     // Restore the global archive loader
00624     StarkArchiveLoader = gameArchiveLoader;
00625 
00626     delete archiveLoader;
00627 
00628     return true;
00629 }
00630 
00631 bool Console::Cmd_ChangeLocation(int argc, const char **argv) {
00632     if (argc != 3) {
00633         debugPrintf("Change the current location. Use listLocations to get indices\n");
00634         debugPrintf("Usage :\n");
00635         debugPrintf("changeLocation [level] [location]\n");
00636         return true;
00637     }
00638 
00639     // Assert indices
00640     Common::String xarcFileName = Common::String::format("%s/%s/%s.xarc", argv[1], argv[2], argv[2]);
00641     if (!Common::File::exists(xarcFileName)) {
00642         debugPrintf("Invalid location %s %s. Use listLocations to get correct indices\n", argv[1], argv[2]);
00643         return true;
00644     }
00645 
00646     uint levelIndex = strtol(argv[1] , nullptr, 16);
00647     uint locationIndex = strtol(argv[2] , nullptr, 16);
00648 
00649     StarkUserInterface->changeScreen(Screen::kScreenGame);
00650 
00651     if (!StarkGlobal->getRoot()) {
00652         StarkResourceProvider->initGlobal();
00653     }
00654 
00655     StarkResourceProvider->requestLocationChange(levelIndex, locationIndex);
00656 
00657     return false;
00658 }
00659 
00660 bool Console::Cmd_ChangeChapter(int argc, const char **argv) {
00661     if (!StarkGlobal->getLevel()) {
00662         debugPrintf("The global level has not been loaded\n");
00663         return true;
00664     }
00665 
00666     if (argc != 2) {
00667         debugPrintf("Change the current chapter\n");
00668         debugPrintf("Usage :\n");
00669         debugPrintf("changeChapter [value]\n");
00670         return true;
00671     }
00672 
00673     char *endPtr = nullptr;
00674     long value = strtol(argv[1], &endPtr, 10);
00675     if (*endPtr == '\0' && value >= 0 && value <= INT_MAX)
00676         StarkGlobal->setCurrentChapter((int32) value);
00677     else
00678         debugPrintf("Invalid chapter\n");
00679 
00680     return true;
00681 }
00682 
00683 bool Console::Cmd_Location(int argc, const char **argv) {
00684     Current *current = StarkGlobal->getCurrent();
00685 
00686     if (!current) {
00687         debugPrintf("Game levels have not been loaded\n");
00688         return true;
00689     }
00690 
00691     if (argc != 1) {
00692         debugPrintf("Display the current location\n");
00693         debugPrintf("Usage :\n");
00694         debugPrintf("location\n");
00695         return true;
00696     }
00697 
00698     debugPrintf("location: %02x %02x\n", current->getLevel()->getIndex(), current->getLocation()->getIndex());
00699 
00700     return true;
00701 }
00702 
00703 bool Console::Cmd_Chapter(int argc, const char **argv) {
00704     if (!StarkGlobal->getLevel()) {
00705         debugPrintf("The global level has not been loaded\n");
00706         return true;
00707     }
00708 
00709     if (argc != 1) {
00710         debugPrintf("Display the current chapter\n");
00711         debugPrintf("Usage :\n");
00712         debugPrintf("chapter\n");
00713         return true;
00714     }
00715 
00716     int32 value = StarkGlobal->getCurrentChapter();
00717 
00718     debugPrintf("chapter: %d\n", value);
00719 
00720     return true;
00721 }
00722 
00723 } // End of namespace Stark


Generated on Sat Feb 23 2019 05:00:59 for ResidualVM by doxygen 1.7.1
curved edge   curved edge