2014-09-21 17:09:55 +02:00
|
|
|
/* ResidualVM - A 3D game interpreter
|
|
|
|
*
|
|
|
|
* ResidualVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the AUTHORS
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "engines/stark/console.h"
|
2015-01-03 07:39:54 +01:00
|
|
|
|
2015-01-14 18:10:09 +01:00
|
|
|
#include "engines/stark/formats/xarc.h"
|
2015-02-13 11:16:34 +01:00
|
|
|
#include "engines/stark/resources/object.h"
|
2014-12-28 14:23:54 +01:00
|
|
|
#include "engines/stark/resources/level.h"
|
|
|
|
#include "engines/stark/resources/location.h"
|
2015-02-24 19:51:57 +01:00
|
|
|
#include "engines/stark/resources/knowledge.h"
|
2014-12-28 14:23:54 +01:00
|
|
|
#include "engines/stark/resources/root.h"
|
2015-02-24 19:51:57 +01:00
|
|
|
#include "engines/stark/resources/script.h"
|
2015-01-11 10:39:24 +01:00
|
|
|
#include "engines/stark/services/archiveloader.h"
|
2015-02-24 20:52:15 +01:00
|
|
|
#include "engines/stark/services/dialogplayer.h"
|
2015-01-11 10:47:52 +01:00
|
|
|
#include "engines/stark/services/global.h"
|
2015-01-11 10:39:24 +01:00
|
|
|
#include "engines/stark/services/resourceprovider.h"
|
2015-01-11 11:01:01 +01:00
|
|
|
#include "engines/stark/services/services.h"
|
2015-02-22 11:26:31 +01:00
|
|
|
#include "engines/stark/services/staticprovider.h"
|
2016-05-26 20:40:24 +02:00
|
|
|
#include "engines/stark/tools/decompiler.h"
|
2014-09-21 17:09:55 +02:00
|
|
|
|
|
|
|
#include "common/file.h"
|
|
|
|
|
|
|
|
namespace Stark {
|
|
|
|
|
2016-06-01 18:14:27 +02:00
|
|
|
Console::Console() :
|
|
|
|
GUI::Debugger(),
|
|
|
|
_testDecompilerTotalScripts(0),
|
|
|
|
_testDecompilerOKScripts(0) {
|
2016-05-26 20:24:57 +02:00
|
|
|
registerCmd("dumpArchive", WRAP_METHOD(Console, Cmd_DumpArchive));
|
|
|
|
registerCmd("dumpRoot", WRAP_METHOD(Console, Cmd_DumpRoot));
|
|
|
|
registerCmd("dumpStatic", WRAP_METHOD(Console, Cmd_DumpStatic));
|
|
|
|
registerCmd("dumpGlobal", WRAP_METHOD(Console, Cmd_DumpGlobal));
|
|
|
|
registerCmd("dumpLevel", WRAP_METHOD(Console, Cmd_DumpLevel));
|
|
|
|
registerCmd("dumpKnowledge", WRAP_METHOD(Console, Cmd_DumpKnowledge));
|
|
|
|
registerCmd("dumpLocation", WRAP_METHOD(Console, Cmd_DumpLocation));
|
|
|
|
registerCmd("listScripts", WRAP_METHOD(Console, Cmd_ListScripts));
|
|
|
|
registerCmd("enableScript", WRAP_METHOD(Console, Cmd_EnableScript));
|
|
|
|
registerCmd("forceScript", WRAP_METHOD(Console, Cmd_ForceScript));
|
2016-05-26 20:40:24 +02:00
|
|
|
registerCmd("decompileScript", WRAP_METHOD(Console, Cmd_DecompileScript));
|
2016-06-01 18:14:27 +02:00
|
|
|
registerCmd("testDecompiler", WRAP_METHOD(Console, Cmd_TestDecompiler));
|
2016-05-26 20:24:57 +02:00
|
|
|
registerCmd("listInventory", WRAP_METHOD(Console, Cmd_ListInventory));
|
|
|
|
registerCmd("listLocations", WRAP_METHOD(Console, Cmd_ListLocations));
|
|
|
|
registerCmd("location", WRAP_METHOD(Console, Cmd_Location));
|
|
|
|
registerCmd("chapter", WRAP_METHOD(Console, Cmd_Chapter));
|
|
|
|
registerCmd("changeLocation", WRAP_METHOD(Console, Cmd_ChangeLocation));
|
|
|
|
registerCmd("changeChapter", WRAP_METHOD(Console, Cmd_ChangeChapter));
|
|
|
|
registerCmd("changeKnowledge", WRAP_METHOD(Console, Cmd_ChangeKnowledge));
|
|
|
|
registerCmd("enableInventoryItem", WRAP_METHOD(Console, Cmd_EnableInventoryItem));
|
2014-09-21 17:09:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Console::~Console() {
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Console::Cmd_DumpArchive(int argc, const char **argv) {
|
|
|
|
if (argc != 2) {
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("Extract all the files from a game archive\n");
|
|
|
|
debugPrintf("The destination folder, named 'dump', must exist in location ResidualVM was launched from\n");
|
2014-09-21 17:09:55 +02:00
|
|
|
debugPrintf("Usage :\n");
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("dumpArchive [path to archive]\n");
|
2014-09-21 17:09:55 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-13 12:52:32 +01:00
|
|
|
Formats::XARCArchive xarc;
|
2014-09-21 17:09:55 +02:00
|
|
|
if (!xarc.open(argv[1])) {
|
|
|
|
debugPrintf("Can't open archive with name '%s'\n", argv[1]);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::ArchiveMemberList members;
|
|
|
|
xarc.listMembers(members);
|
|
|
|
|
|
|
|
for (Common::ArchiveMemberList::const_iterator it = members.begin(); it != members.end(); it++) {
|
|
|
|
Common::String fileName = Common::String::format("dump/%s", it->get()->getName().c_str());
|
|
|
|
|
|
|
|
// Open the output file
|
|
|
|
Common::DumpFile outFile;
|
|
|
|
if (!outFile.open(fileName)) {
|
2014-09-28 08:51:44 +02:00
|
|
|
debugPrintf("Unable to open file '%s' for writing\n", fileName.c_str());
|
2014-09-21 17:09:55 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy the archive content to the output file using a temporary buffer
|
|
|
|
Common::SeekableReadStream *inStream = it->get()->createReadStream();
|
|
|
|
uint8 *buf = new uint8[inStream->size()];
|
|
|
|
|
|
|
|
inStream->read(buf, inStream->size());
|
|
|
|
outFile.write(buf, inStream->size());
|
|
|
|
|
|
|
|
delete[] buf;
|
|
|
|
delete inStream;
|
|
|
|
outFile.close();
|
|
|
|
|
2014-09-28 08:51:44 +02:00
|
|
|
debugPrintf("Extracted '%s'\n", it->get()->getName().c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-22 11:26:31 +01:00
|
|
|
bool Console::Cmd_DumpRoot(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Resources::Root *root = StarkGlobal->getRoot();
|
|
|
|
if (root) {
|
|
|
|
root->print();
|
|
|
|
} else {
|
|
|
|
debugPrintf("The global root has not been loaded\n");
|
|
|
|
}
|
2015-02-22 11:26:31 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-05 07:27:24 +01:00
|
|
|
bool Console::Cmd_DumpGlobal(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Resources::Level *level = StarkGlobal->getLevel();
|
|
|
|
if (level) {
|
|
|
|
level->print();
|
|
|
|
} else {
|
|
|
|
debugPrintf("The global level has not been loaded\n");
|
|
|
|
}
|
2014-12-28 11:50:12 +01:00
|
|
|
|
2015-01-05 07:27:24 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-22 11:26:31 +01:00
|
|
|
bool Console::Cmd_DumpStatic(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
// Static resources are initialized in the beginning of the running
|
2015-07-16 20:04:00 +02:00
|
|
|
StarkStaticProvider->getLevel()->print();
|
2015-02-22 11:26:31 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-05 07:27:24 +01:00
|
|
|
bool Console::Cmd_DumpLevel(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
if (current) {
|
|
|
|
current->getLevel()->print();
|
|
|
|
} else {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
}
|
2015-01-05 07:27:24 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2014-09-28 08:51:44 +02:00
|
|
|
|
2015-02-24 19:51:57 +01:00
|
|
|
bool Console::Cmd_DumpKnowledge(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
|
|
|
|
if (!current) {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Resources::Level *level = current->getLevel();
|
|
|
|
Resources::Location *location = current->getLocation();
|
2015-12-20 21:43:04 +01:00
|
|
|
Common::Array<Resources::Knowledge *> knowledge = level->listChildrenRecursive<Resources::Knowledge>();
|
2015-02-24 19:51:57 +01:00
|
|
|
knowledge.insert_at(knowledge.size(), location->listChildrenRecursive<Resources::Knowledge>());
|
2015-12-20 21:43:04 +01:00
|
|
|
Common::Array<Resources::Knowledge *>::iterator it;
|
2015-02-24 19:51:57 +01:00
|
|
|
for (it = knowledge.begin(); it != knowledge.end(); ++it) {
|
|
|
|
(*it)->print();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Console::Cmd_ChangeKnowledge(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
|
|
|
|
if (!current) {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-17 21:04:17 +01:00
|
|
|
uint index = 0;
|
2015-02-24 19:51:57 +01:00
|
|
|
char type = 0;
|
|
|
|
|
|
|
|
if (argc >= 4) {
|
|
|
|
index = atoi(argv[1]);
|
|
|
|
type = argv[2][0];
|
|
|
|
if (type == 'b' || type == 'i') {
|
2018-06-20 22:40:41 +08:00
|
|
|
Resources::Level *level = current->getLevel();
|
|
|
|
Resources::Location *location = current->getLocation();
|
2015-12-20 21:43:04 +01:00
|
|
|
Common::Array<Resources::Knowledge *> knowledgeArr = level->listChildrenRecursive<Resources::Knowledge>();
|
2015-02-24 19:51:57 +01:00
|
|
|
knowledgeArr.insert_at(knowledgeArr.size(), location->listChildrenRecursive<Resources::Knowledge>());
|
|
|
|
if (index < knowledgeArr.size() ) {
|
|
|
|
Resources::Knowledge *knowledge = knowledgeArr[index];
|
|
|
|
if (type == 'b') {
|
|
|
|
knowledge->setBooleanValue(atoi(argv[3]));
|
|
|
|
} else if (type == 'i') {
|
|
|
|
knowledge->setIntegerValue(atoi(argv[3]));
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
debugPrintf("Invalid index %d, only %d indices available\n", index, knowledgeArr.size());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
debugPrintf("Invalid type: %c, only b and i are available\n", type);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
debugPrintf("Too few args\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
debugPrintf("Change the value of some knowledge. Use dumpKnowledge to get an id\n");
|
|
|
|
debugPrintf("Usage :\n");
|
|
|
|
debugPrintf("changeKnowledge [id] [type] [value]\n");
|
|
|
|
debugPrintf("available types: b(inary), i(nteger)\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:36:39 +02:00
|
|
|
Common::Array<Resources::Script *> Console::listAllLocationScripts() const {
|
|
|
|
Common::Array<Resources::Script *> scripts;
|
|
|
|
|
2015-07-16 20:04:00 +02:00
|
|
|
Resources::Level *level = StarkGlobal->getCurrent()->getLevel();
|
|
|
|
Resources::Location *location = StarkGlobal->getCurrent()->getLocation();
|
2016-05-26 20:36:39 +02:00
|
|
|
scripts.push_back(level->listChildrenRecursive<Resources::Script>());
|
|
|
|
scripts.push_back(location->listChildrenRecursive<Resources::Script>());
|
|
|
|
|
|
|
|
return scripts;
|
|
|
|
}
|
2016-01-14 15:04:45 +01:00
|
|
|
|
2016-05-26 20:36:39 +02:00
|
|
|
bool Console::Cmd_ListScripts(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
if (!current) {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:36:39 +02:00
|
|
|
Common::Array<Resources::Script *> scripts = listAllLocationScripts();
|
|
|
|
|
|
|
|
for (uint i = 0; i < scripts.size(); i++) {
|
|
|
|
Resources::Script *script = scripts[i];
|
|
|
|
|
|
|
|
debugPrintf("%d: %s - enabled: %d", i, script->getName().c_str(), script->isEnabled());
|
2016-01-14 15:04:45 +01:00
|
|
|
|
|
|
|
// Print which resource is causing the script to wait
|
2016-05-26 20:36:39 +02:00
|
|
|
if (script->isSuspended()) {
|
|
|
|
Resources::Object *suspending = script->getSuspendingResource();
|
2016-01-14 15:04:45 +01:00
|
|
|
if (suspending) {
|
|
|
|
debugPrintf(", waiting for: %s (%s)", suspending->getName().c_str(), suspending->getType().getName());
|
|
|
|
} else {
|
|
|
|
debugPrintf(", paused");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
debugPrintf("\n");
|
2015-02-24 19:51:57 +01:00
|
|
|
}
|
2016-01-14 15:04:45 +01:00
|
|
|
|
2015-02-24 19:51:57 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Console::Cmd_EnableScript(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
if (!current) {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-17 21:04:17 +01:00
|
|
|
uint index = 0;
|
2015-02-24 19:51:57 +01:00
|
|
|
|
|
|
|
if (argc >= 2) {
|
|
|
|
index = atoi(argv[1]);
|
|
|
|
|
|
|
|
bool value = true;
|
|
|
|
if (argc >= 3) {
|
|
|
|
value = atoi(argv[2]);
|
|
|
|
}
|
2016-05-26 20:36:39 +02:00
|
|
|
|
|
|
|
Common::Array<Resources::Script *> scripts = listAllLocationScripts();
|
|
|
|
if (index < scripts.size() ) {
|
|
|
|
Resources::Script *script = scripts[index];
|
2015-02-24 19:51:57 +01:00
|
|
|
script->enable(value);
|
|
|
|
return true;
|
|
|
|
} else {
|
2016-05-26 20:36:39 +02:00
|
|
|
debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
|
2015-02-24 19:51:57 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
debugPrintf("Too few args\n");
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:36:39 +02:00
|
|
|
debugPrintf("Enable or disable a script. Use listScripts to get an id\n");
|
2015-02-24 19:51:57 +01:00
|
|
|
debugPrintf("Usage :\n");
|
|
|
|
debugPrintf("enableScript [id] (value)\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Console::Cmd_ForceScript(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
if (!current) {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-03-17 21:04:17 +01:00
|
|
|
uint index = 0;
|
2015-02-24 19:51:57 +01:00
|
|
|
|
|
|
|
if (argc >= 2) {
|
|
|
|
index = atoi(argv[1]);
|
|
|
|
|
2016-05-26 20:36:39 +02:00
|
|
|
Common::Array<Resources::Script *> scripts = listAllLocationScripts();
|
|
|
|
if (index < scripts.size() ) {
|
|
|
|
Resources::Script *script = scripts[index];
|
|
|
|
script->enable(true);
|
2015-07-14 09:53:02 +02:00
|
|
|
script->goToNextCommand(); // Skip the begin command to avoid checks
|
|
|
|
script->execute(Resources::Script::kCallModePlayerAction);
|
2015-02-24 19:51:57 +01:00
|
|
|
return true;
|
|
|
|
} else {
|
2016-05-26 20:36:39 +02:00
|
|
|
debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
|
2015-02-24 19:51:57 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
debugPrintf("Too few args\n");
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:36:39 +02:00
|
|
|
debugPrintf("Force the execution of a script. Use listScripts to get an id\n");
|
2015-02-24 19:51:57 +01:00
|
|
|
debugPrintf("Usage :\n");
|
2016-05-26 20:36:39 +02:00
|
|
|
debugPrintf("forceScript [id]\n");
|
2015-02-24 19:51:57 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:40:24 +02:00
|
|
|
bool Console::Cmd_DecompileScript(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
if (!current) {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:40:24 +02:00
|
|
|
if (argc >= 2) {
|
|
|
|
uint index = atoi(argv[1]);
|
|
|
|
|
|
|
|
Common::Array<Resources::Script *> scripts = listAllLocationScripts();
|
|
|
|
if (index < scripts.size()) {
|
|
|
|
Resources::Script *script = scripts[index];
|
|
|
|
|
|
|
|
Tools::Decompiler *decompiler = new Tools::Decompiler(script);
|
|
|
|
if (decompiler->getError() != "") {
|
|
|
|
debugPrintf("Decompilation failure: %s\n", decompiler->getError().c_str());
|
|
|
|
}
|
|
|
|
|
2016-06-02 13:10:45 +02:00
|
|
|
debug("Script %d - %s:", index, script->getName().c_str());
|
2016-05-26 20:40:24 +02:00
|
|
|
decompiler->printDecompiled();
|
|
|
|
|
|
|
|
delete decompiler;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
debugPrintf("Invalid index %d, only %d indices available\n", index, scripts.size());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
debugPrintf("Too few args\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
debugPrintf("Decompile a script. Use listScripts to get an id\n");
|
|
|
|
debugPrintf("Usage :\n");
|
|
|
|
debugPrintf("decompileScript [id]\n");
|
|
|
|
return true;
|
|
|
|
}
|
2015-02-24 19:51:57 +01:00
|
|
|
|
2016-06-01 18:14:27 +02:00
|
|
|
bool Console::Cmd_TestDecompiler(int argc, const char **argv) {
|
|
|
|
_testDecompilerTotalScripts = 0;
|
|
|
|
_testDecompilerOKScripts = 0;
|
|
|
|
|
|
|
|
ArchiveLoader *archiveLoader = new ArchiveLoader();
|
|
|
|
|
|
|
|
// Temporarily replace the global archive loader with our instance
|
|
|
|
ArchiveLoader *gameArchiveLoader = StarkArchiveLoader;
|
|
|
|
StarkArchiveLoader = archiveLoader;
|
|
|
|
|
|
|
|
archiveLoader->load("x.xarc");
|
|
|
|
Resources::Root *root = archiveLoader->useRoot<Resources::Root>("x.xarc");
|
|
|
|
|
|
|
|
// Find all the levels
|
|
|
|
Common::Array<Resources::Level *> levels = root->listChildren<Resources::Level>();
|
|
|
|
|
|
|
|
// Loop over the levels
|
|
|
|
for (uint i = 0; i < levels.size(); i++) {
|
|
|
|
Resources::Level *level = levels[i];
|
|
|
|
|
|
|
|
Common::String levelArchive = archiveLoader->buildArchiveName(level);
|
|
|
|
debug("%s - %s", levelArchive.c_str(), level->getName().c_str());
|
|
|
|
|
|
|
|
// Load the detailed level archive
|
|
|
|
archiveLoader->load(levelArchive);
|
|
|
|
level = archiveLoader->useRoot<Resources::Level>(levelArchive);
|
|
|
|
|
|
|
|
// Decompile all the scripts in the level archive
|
|
|
|
decompileScriptChildren(level);
|
|
|
|
|
|
|
|
Common::Array<Resources::Location *> locations = level->listChildren<Resources::Location>();
|
|
|
|
|
|
|
|
// Loop over the locations
|
|
|
|
for (uint j = 0; j < locations.size(); j++) {
|
|
|
|
Resources::Location *location = locations[j];
|
|
|
|
|
|
|
|
Common::String locationArchive = archiveLoader->buildArchiveName(level, location);
|
|
|
|
debug("%s - %s", locationArchive.c_str(), location->getName().c_str());
|
|
|
|
|
|
|
|
// Load the detailed location archive
|
|
|
|
archiveLoader->load(locationArchive);
|
|
|
|
location = archiveLoader->useRoot<Resources::Location>(locationArchive);
|
|
|
|
|
|
|
|
// Decompile all the scripts in the location archive
|
|
|
|
decompileScriptChildren(location);
|
|
|
|
|
|
|
|
archiveLoader->returnRoot(locationArchive);
|
|
|
|
archiveLoader->unloadUnused();
|
|
|
|
}
|
|
|
|
|
|
|
|
archiveLoader->returnRoot(levelArchive);
|
|
|
|
archiveLoader->unloadUnused();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Restore the global archive loader
|
|
|
|
StarkArchiveLoader = gameArchiveLoader;
|
|
|
|
|
|
|
|
delete archiveLoader;
|
|
|
|
|
|
|
|
debugPrintf("Successfully decompiled %d scripts out of %d\n", _testDecompilerOKScripts, _testDecompilerTotalScripts);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Console::decompileScriptChildren(Resources::Object *level) {
|
|
|
|
Common::Array<Resources::Script *> scripts = level->listChildrenRecursive<Resources::Script>();
|
|
|
|
|
|
|
|
for (uint j = 0; j < scripts.size(); j++) {
|
|
|
|
Resources::Script *script = scripts[j];
|
|
|
|
|
|
|
|
Tools::Decompiler *decompiler = new Tools::Decompiler(script);
|
|
|
|
_testDecompilerTotalScripts++;
|
|
|
|
|
|
|
|
Common::String result;
|
|
|
|
if (decompiler->getError() == "") {
|
|
|
|
result = "OK";
|
|
|
|
_testDecompilerOKScripts++;
|
|
|
|
} else {
|
|
|
|
result = decompiler->getError();
|
|
|
|
}
|
|
|
|
|
|
|
|
debug("%d - %s: %s", script->getIndex(), script->getName().c_str(), result.c_str());
|
|
|
|
|
|
|
|
delete decompiler;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-05 07:27:24 +01:00
|
|
|
bool Console::Cmd_DumpLocation(int argc, const char **argv) {
|
2018-05-09 21:48:01 +02:00
|
|
|
if (StarkStaticProvider->isStaticLocation()) {
|
|
|
|
StarkStaticProvider->getLocation()->print();
|
2018-06-20 22:40:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
if (current) {
|
|
|
|
current->getLocation()->print();
|
2018-05-09 21:48:01 +02:00
|
|
|
} else {
|
2018-06-20 22:40:41 +08:00
|
|
|
debugPrintf("Locations have not been loaded\n");
|
2018-05-09 21:48:01 +02:00
|
|
|
}
|
2014-10-05 19:25:00 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-25 15:17:43 +01:00
|
|
|
bool Console::Cmd_ListInventory(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
if (StarkGlobal->getInventory()) {
|
|
|
|
StarkGlobal->printInventory(argc != 2);
|
|
|
|
} else {
|
|
|
|
debugPrintf("The inventory has not been loaded\n");
|
|
|
|
}
|
2015-02-25 15:17:43 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-26 16:53:15 +01:00
|
|
|
bool Console::Cmd_EnableInventoryItem(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
if (!StarkGlobal->getInventory()) {
|
|
|
|
debugPrintf("The inventory has not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-26 16:53:15 +01:00
|
|
|
if (argc != 2) {
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("Enable a specific inventory item. Use listInventory to get an id\n");
|
2015-02-26 16:53:15 +01:00
|
|
|
debugPrintf("Usage :\n");
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("enableInventoryItem [id]\n");
|
2015-02-26 16:53:15 +01:00
|
|
|
return true;
|
|
|
|
}
|
2018-06-20 22:40:41 +08:00
|
|
|
|
2015-07-16 20:04:00 +02:00
|
|
|
StarkGlobal->enableInventoryItem(atoi(argv[1]));
|
2018-06-20 22:40:41 +08:00
|
|
|
|
2015-02-26 16:53:15 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-12-28 11:50:12 +01:00
|
|
|
bool Console::Cmd_ListLocations(int argc, const char **argv) {
|
|
|
|
ArchiveLoader *archiveLoader = new ArchiveLoader();
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2015-02-13 09:30:26 +01:00
|
|
|
// Temporarily replace the global archive loader with our instance
|
2015-07-16 20:04:00 +02:00
|
|
|
ArchiveLoader *gameArchiveLoader = StarkArchiveLoader;
|
|
|
|
StarkArchiveLoader = archiveLoader;
|
2015-02-13 09:30:26 +01:00
|
|
|
|
2014-12-28 11:50:12 +01:00
|
|
|
archiveLoader->load("x.xarc");
|
2015-02-13 11:10:44 +01:00
|
|
|
Resources::Root *root = archiveLoader->useRoot<Resources::Root>("x.xarc");
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2014-12-28 12:48:50 +01:00
|
|
|
// Find all the levels
|
2015-02-13 11:10:44 +01:00
|
|
|
Common::Array<Resources::Level *> levels = root->listChildren<Resources::Level>();
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2014-12-28 12:48:50 +01:00
|
|
|
// Loop over the levels
|
|
|
|
for (uint i = 0; i < levels.size(); i++) {
|
2015-02-13 11:10:44 +01:00
|
|
|
Resources::Level *level = levels[i];
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2014-12-28 14:23:54 +01:00
|
|
|
Common::String levelArchive = archiveLoader->buildArchiveName(level);
|
2014-10-05 19:25:00 +02:00
|
|
|
debugPrintf("%s - %s\n", levelArchive.c_str(), level->getName().c_str());
|
|
|
|
|
|
|
|
// Load the detailed level archive
|
2014-12-28 11:50:12 +01:00
|
|
|
archiveLoader->load(levelArchive);
|
2015-02-13 11:10:44 +01:00
|
|
|
level = archiveLoader->useRoot<Resources::Level>(levelArchive);
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2015-02-13 11:10:44 +01:00
|
|
|
Common::Array<Resources::Location *> locations = level->listChildren<Resources::Location>();
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2014-12-28 11:50:12 +01:00
|
|
|
// Loop over the locations
|
2014-12-28 12:48:50 +01:00
|
|
|
for (uint j = 0; j < locations.size(); j++) {
|
2015-02-13 11:10:44 +01:00
|
|
|
Resources::Location *location = locations[j];
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2014-12-28 14:23:54 +01:00
|
|
|
Common::String roomArchive = archiveLoader->buildArchiveName(level, location);
|
2014-12-28 11:50:12 +01:00
|
|
|
debugPrintf("%s - %s\n", roomArchive.c_str(), location->getName().c_str());
|
2014-10-05 19:25:00 +02:00
|
|
|
}
|
|
|
|
|
2014-12-28 11:50:12 +01:00
|
|
|
archiveLoader->returnRoot(levelArchive);
|
|
|
|
archiveLoader->unloadUnused();
|
2014-10-05 19:25:00 +02:00
|
|
|
}
|
|
|
|
|
2015-02-13 09:30:26 +01:00
|
|
|
// Restore the global archive loader
|
2015-07-16 20:04:00 +02:00
|
|
|
StarkArchiveLoader = gameArchiveLoader;
|
2015-02-13 09:30:26 +01:00
|
|
|
|
2014-12-28 11:50:12 +01:00
|
|
|
delete archiveLoader;
|
2014-10-05 19:25:00 +02:00
|
|
|
|
2014-09-21 17:09:55 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-03 07:39:54 +01:00
|
|
|
bool Console::Cmd_ChangeLocation(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
if (!StarkGlobal->getRoot()) {
|
|
|
|
debugPrintf("The global root has not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-03 07:39:54 +01:00
|
|
|
if (argc != 3) {
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("Change the current location. Use listLocations to get ids\n");
|
2015-01-03 07:39:54 +01:00
|
|
|
debugPrintf("Usage :\n");
|
|
|
|
debugPrintf("changeLocation [level] [location]\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint levelIndex = strtol(argv[1] , nullptr, 16);
|
|
|
|
uint locationIndex = strtol(argv[2] , nullptr, 16);
|
|
|
|
|
2015-07-16 20:04:00 +02:00
|
|
|
StarkResourceProvider->requestLocationChange(levelIndex, locationIndex);
|
2015-01-03 07:39:54 +01:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-02-13 09:19:47 +01:00
|
|
|
bool Console::Cmd_ChangeChapter(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
if (!StarkGlobal->getLevel()) {
|
|
|
|
debugPrintf("The global level has not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-13 09:19:47 +01:00
|
|
|
if (argc != 2) {
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("Change the current chapter\n");
|
2015-02-13 09:19:47 +01:00
|
|
|
debugPrintf("Usage :\n");
|
|
|
|
debugPrintf("changeChapter [value]\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 value = atoi(argv[1]);
|
|
|
|
|
2015-07-16 20:04:00 +02:00
|
|
|
StarkGlobal->setCurrentChapter(value);
|
2015-02-13 09:19:47 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Console::Cmd_Location(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
Current *current = StarkGlobal->getCurrent();
|
|
|
|
|
|
|
|
if (!current) {
|
|
|
|
debugPrintf("Game levels have not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-13 09:19:47 +01:00
|
|
|
if (argc != 1) {
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("Display the current location\n");
|
2015-02-13 09:19:47 +01:00
|
|
|
debugPrintf("Usage :\n");
|
|
|
|
debugPrintf("location\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
debugPrintf("location: %02x %02x\n", current->getLevel()->getIndex(), current->getLocation()->getIndex());
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Console::Cmd_Chapter(int argc, const char **argv) {
|
2018-06-20 22:40:41 +08:00
|
|
|
if (!StarkGlobal->getLevel()) {
|
|
|
|
debugPrintf("The global level has not been loaded\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-02-13 09:19:47 +01:00
|
|
|
if (argc != 1) {
|
2018-06-03 13:46:46 +02:00
|
|
|
debugPrintf("Display the current chapter\n");
|
2015-02-13 09:19:47 +01:00
|
|
|
debugPrintf("Usage :\n");
|
|
|
|
debugPrintf("chapter\n");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-07-16 20:04:00 +02:00
|
|
|
int32 value = StarkGlobal->getCurrentChapter();
|
2015-02-13 09:19:47 +01:00
|
|
|
|
|
|
|
debugPrintf("chapter: %d\n", value);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-21 17:09:55 +02:00
|
|
|
} // End of namespace Stark
|