support running recursive directory
This commit is contained in:
parent
11827cffa9
commit
ee64c3dd65
20
README.md
20
README.md
@ -15,17 +15,23 @@ A utility to compile & decompile IW engine game scripts.
|
|||||||
- **H1** *(Call of Duty: Modern Warfare Remastered)*
|
- **H1** *(Call of Duty: Modern Warfare Remastered)*
|
||||||
- **H2** *(Call of Duty: Modern Warfare 2 Campaign Remastered)*
|
- **H2** *(Call of Duty: Modern Warfare 2 Campaign Remastered)*
|
||||||
## Usage
|
## Usage
|
||||||
``./gsc-tool.exe <game> <mode> <file>``
|
``./gsc-tool.exe <mode> <game> <path>``
|
||||||
|
|
||||||
|
**modes**: `asm`, `disasm`, `comp`, `decomp`
|
||||||
|
|
||||||
|
**games**: `iw5`, `iw6`, `iw7`, `iw8`, `s1`, `s2`, `s4`, `h1`, `h2`
|
||||||
|
|
||||||
|
**paths**: `file`, `directory` (recursive process all files with mode extension)
|
||||||
|
|
||||||
|
for zonetool files (*.cgsc*, *.cgsc.stack*) use: `zasm`, `zdisasm`, `zcomp`, `zdecomp`
|
||||||
|
|
||||||
**game**: `-iw5`, `-iw6`, `-iw7`, `-iw8`, `-s1`, `-s2`, `-s4`, `-h1`, `-h2`
|
|
||||||
| Mode |Description | Output |
|
| Mode |Description | Output |
|
||||||
|:---------|:--------------------------|:------------|
|
|:---------|:--------------------------|:------------|
|
||||||
|`-asm` |assemble a `file.gscasm` |`file.gscbin`|
|
|`asm` |assemble a `file.gscasm` |`file.gscbin`|
|
||||||
|`-disasm` |dissasemble a `file.gscbin`|`file.gscasm`|
|
|`disasm` |dissasemble a `file.gscbin`|`file.gscasm`|
|
||||||
|`-comp` |compile a `file.gsc` |`file.gscbin`|
|
|`comp` |compile a `file.gsc` |`file.gscbin`|
|
||||||
|`-decomp` |decompile a `file.gscbin` |`file.gsc` |
|
|`decomp` |decompile a `file.gscbin` |`file.gsc` |
|
||||||
|
|
||||||
for zonetool files (*.cgsc*, *.cgsc.stack*) use: `-zasm`, `-zdisasm`, `-zcomp`, `-zdecomp`
|
|
||||||
## Format
|
## Format
|
||||||
- gsc-tool ``.gscbin`` format is a serialized ScriptFile struct: ***name***: null-term string, ***compressedLen***: 4 byte uint, ***len***: 4 byte uint, ***bytecodeLen***: 4 byte uint, ***buffer***: byte array[compressedLen], ***bytecode***: byte array[bytecodeLen].
|
- gsc-tool ``.gscbin`` format is a serialized ScriptFile struct: ***name***: null-term string, ***compressedLen***: 4 byte uint, ***len***: 4 byte uint, ***bytecodeLen***: 4 byte uint, ***buffer***: byte array[compressedLen], ***bytecode***: byte array[bytecodeLen].
|
||||||
|
|
||||||
|
@ -18,30 +18,55 @@
|
|||||||
namespace xsk::gsc
|
namespace xsk::gsc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
enum class encd { __, SOURCE, ASSEMBLY, BINARY };
|
||||||
enum class mode { __, ASM, DISASM, COMP, DECOMP };
|
enum class mode { __, ASM, DISASM, COMP, DECOMP };
|
||||||
enum class game { __, IW5, IW6, IW7, IW8, S1, S2, S4, H1, H2 };
|
enum class game { __, IW5, IW6, IW7, IW8, S1, S2, S4, H1, H2 };
|
||||||
|
|
||||||
std::map<std::string, mode> modes =
|
const std::map<std::string, encd> exts =
|
||||||
{
|
{
|
||||||
{ "-asm", mode::ASM },
|
{ ".gsc", encd::SOURCE },
|
||||||
{ "-disasm", mode::DISASM },
|
{ ".gscasm", encd::ASSEMBLY },
|
||||||
{ "-comp", mode::COMP },
|
{ ".cgsc", encd::BINARY },
|
||||||
{ "-decomp", mode::DECOMP },
|
{ ".gscbin", encd::BINARY },
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<std::string, game> games =
|
const std::map<std::string, mode> modes =
|
||||||
{
|
{
|
||||||
{ "-iw5", game::IW5 },
|
{ "asm", mode::ASM },
|
||||||
{ "-iw6", game::IW6 },
|
{ "disasm", mode::DISASM },
|
||||||
{ "-iw7", game::IW7 },
|
{ "comp", mode::COMP },
|
||||||
{ "-iw8", game::IW8 },
|
{ "decomp", mode::DECOMP },
|
||||||
{ "-s1", game::S1 },
|
|
||||||
{ "-s2", game::S2 },
|
|
||||||
{ "-s4", game::S4 },
|
|
||||||
{ "-h1", game::H1 },
|
|
||||||
{ "-h2", game::H2 },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::map<std::string, game> games =
|
||||||
|
{
|
||||||
|
{ "iw5", game::IW5 },
|
||||||
|
{ "iw6", game::IW6 },
|
||||||
|
{ "iw7", game::IW7 },
|
||||||
|
{ "iw8", game::IW8 },
|
||||||
|
{ "s1", game::S1 },
|
||||||
|
{ "s2", game::S2 },
|
||||||
|
{ "s4", game::S4 },
|
||||||
|
{ "h1", game::H1 },
|
||||||
|
{ "h2", game::H2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::map<mode, encd> encds =
|
||||||
|
{
|
||||||
|
{ mode::ASM , encd::ASSEMBLY },
|
||||||
|
{ mode::DISASM, encd::BINARY },
|
||||||
|
{ mode::COMP, encd::SOURCE },
|
||||||
|
{ mode::DECOMP, encd::BINARY },
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<game, std::unique_ptr<gsc::assembler>> assemblers;
|
||||||
|
std::map<game, std::unique_ptr<gsc::disassembler>> disassemblers;
|
||||||
|
std::map<game, std::unique_ptr<gsc::compiler>> compilers;
|
||||||
|
std::map<game, std::unique_ptr<gsc::decompiler>> decompilers;
|
||||||
|
std::map<mode, std::function<void(game game, std::string file)>> funcs;
|
||||||
|
|
||||||
|
bool zonetool = false;
|
||||||
|
|
||||||
auto overwrite_prompt(const std::string& file) -> bool
|
auto overwrite_prompt(const std::string& file) -> bool
|
||||||
{
|
{
|
||||||
auto overwrite = true;
|
auto overwrite = true;
|
||||||
@ -85,10 +110,11 @@ auto choose_resolver_file_name(uint32_t id, game& game) -> std::string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assemble_file(gsc::assembler& assembler, std::string file, bool zonetool)
|
void assemble_file(game game, std::string file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
const auto& assembler = assemblers[game];
|
||||||
const auto ext = std::string(".gscasm");
|
const auto ext = std::string(".gscasm");
|
||||||
const auto extpos = file.find(ext);
|
const auto extpos = file.find(ext);
|
||||||
|
|
||||||
@ -99,25 +125,25 @@ void assemble_file(gsc::assembler& assembler, std::string file, bool zonetool)
|
|||||||
|
|
||||||
auto data = utils::file::read(file + ext);
|
auto data = utils::file::read(file + ext);
|
||||||
|
|
||||||
assembler.assemble(file, data);
|
assembler->assemble(file, data);
|
||||||
|
|
||||||
if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin")))
|
if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin")))
|
||||||
{
|
{
|
||||||
if(zonetool)
|
if(zonetool)
|
||||||
{
|
{
|
||||||
utils::file::save(file + ".cgsc", assembler.output_script());
|
utils::file::save(file + ".cgsc", assembler->output_script());
|
||||||
utils::file::save(file + ".cgsc.stack", assembler.output_stack());
|
utils::file::save(file + ".cgsc.stack", assembler->output_stack());
|
||||||
std::cout << "assembled " << file << ".cgsc\n";
|
std::cout << "assembled " << file << ".cgsc\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gsc::asset script;
|
gsc::asset script;
|
||||||
|
|
||||||
auto uncompressed = assembler.output_stack();
|
auto uncompressed = assembler->output_stack();
|
||||||
auto compressed = utils::zlib::compress(uncompressed);
|
auto compressed = utils::zlib::compress(uncompressed);
|
||||||
|
|
||||||
script.name = file;
|
script.name = file;
|
||||||
script.bytecode = assembler.output_script();
|
script.bytecode = assembler->output_script();
|
||||||
script.buffer = std::move(compressed);
|
script.buffer = std::move(compressed);
|
||||||
script.len = uncompressed.size();
|
script.len = uncompressed.size();
|
||||||
script.compressedLen = script.buffer.size();
|
script.compressedLen = script.buffer.size();
|
||||||
@ -135,12 +161,16 @@ void assemble_file(gsc::assembler& assembler, std::string file, bool zonetool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void disassemble_file(gsc::disassembler& disassembler, std::string file, game& game, bool zonetool)
|
void disassemble_file(game game, std::string file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
const auto& disassembler = disassemblers[game];
|
||||||
|
|
||||||
if(zonetool)
|
if(zonetool)
|
||||||
{
|
{
|
||||||
|
if (file.find(".gscbin") != std::string::npos) return;
|
||||||
|
|
||||||
if (file.find(".stack") != std::string::npos)
|
if (file.find(".stack") != std::string::npos)
|
||||||
{
|
{
|
||||||
std::cerr << "Cannot disassemble stack files\n";
|
std::cerr << "Cannot disassemble stack files\n";
|
||||||
@ -158,10 +188,12 @@ void disassemble_file(gsc::disassembler& disassembler, std::string file, game& g
|
|||||||
auto script = utils::file::read(file + ".cgsc");
|
auto script = utils::file::read(file + ".cgsc");
|
||||||
auto stack = utils::file::read(file + ".cgsc.stack");
|
auto stack = utils::file::read(file + ".cgsc.stack");
|
||||||
|
|
||||||
disassembler.disassemble(file, script, stack);
|
disassembler->disassemble(file, script, stack);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (file.find(".cgsc") != std::string::npos) return;
|
||||||
|
|
||||||
const auto ext = std::string(".gscbin");
|
const auto ext = std::string(".gscbin");
|
||||||
const auto extpos = file.find(ext);
|
const auto extpos = file.find(ext);
|
||||||
|
|
||||||
@ -178,14 +210,14 @@ void disassemble_file(gsc::disassembler& disassembler, std::string file, game& g
|
|||||||
|
|
||||||
auto stack = utils::zlib::decompress(script.buffer, script.len);
|
auto stack = utils::zlib::decompress(script.buffer, script.len);
|
||||||
|
|
||||||
disassembler.disassemble(file, script.bytecode, stack);
|
disassembler->disassemble(file, script.bytecode, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto scriptid = std::filesystem::path(file).filename().string();
|
auto scriptid = std::filesystem::path(file).filename().string();
|
||||||
|
|
||||||
if (!isdigit(scriptid.data()[0]))
|
if (!isdigit(scriptid.data()[0]))
|
||||||
{
|
{
|
||||||
utils::file::save(file + ".gscasm", disassembler.output_data());
|
utils::file::save(file + ".gscasm", disassembler->output_data());
|
||||||
std::cout << "disassembled " << file << ".gscasm\n";
|
std::cout << "disassembled " << file << ".gscasm\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -201,7 +233,7 @@ void disassemble_file(gsc::disassembler& disassembler, std::string file, game& g
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::file::save(file + filename + ".gscasm", disassembler.output_data());
|
utils::file::save(file + filename + ".gscasm", disassembler->output_data());
|
||||||
std::cout << "disassembled " << file << filename << ".gscasm\n";
|
std::cout << "disassembled " << file << filename << ".gscasm\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,10 +243,12 @@ void disassemble_file(gsc::disassembler& disassembler, std::string file, game& g
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_file(gsc::assembler& assembler, gsc::compiler& compiler, std::string file, bool zonetool)
|
void compile_file(game game, std::string file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
const auto& assembler = assemblers[game];
|
||||||
|
const auto& compiler = compilers[game];
|
||||||
const auto ext = std::string(".gsc");
|
const auto ext = std::string(".gsc");
|
||||||
const auto extpos = file.find(ext);
|
const auto extpos = file.find(ext);
|
||||||
|
|
||||||
@ -224,30 +258,30 @@ void compile_file(gsc::assembler& assembler, gsc::compiler& compiler, std::strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto data = utils::file::read(file + ext);
|
auto data = utils::file::read(file + ext);
|
||||||
compiler.set_readf_callback(utils::file::read);
|
compiler->set_readf_callback(utils::file::read);
|
||||||
compiler.compile(file, data);
|
compiler->compile(file, data);
|
||||||
|
|
||||||
auto assembly = compiler.output();
|
auto assembly = compiler->output();
|
||||||
|
|
||||||
assembler.assemble(file, assembly);
|
assembler->assemble(file, assembly);
|
||||||
|
|
||||||
if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin")))
|
if (overwrite_prompt(file + (zonetool ? ".cgsc" : ".gscbin")))
|
||||||
{
|
{
|
||||||
if(zonetool)
|
if(zonetool)
|
||||||
{
|
{
|
||||||
utils::file::save(file + ".cgsc", assembler.output_script());
|
utils::file::save(file + ".cgsc", assembler->output_script());
|
||||||
utils::file::save(file + ".cgsc.stack", assembler.output_stack());
|
utils::file::save(file + ".cgsc.stack", assembler->output_stack());
|
||||||
std::cout << "compiled " << file << ".cgsc\n";
|
std::cout << "compiled " << file << ".cgsc\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gsc::asset script;
|
gsc::asset script;
|
||||||
|
|
||||||
auto uncompressed = assembler.output_stack();
|
auto uncompressed = assembler->output_stack();
|
||||||
auto compressed = utils::zlib::compress(uncompressed);
|
auto compressed = utils::zlib::compress(uncompressed);
|
||||||
|
|
||||||
script.name = file;
|
script.name = file;
|
||||||
script.bytecode = assembler.output_script();
|
script.bytecode = assembler->output_script();
|
||||||
script.buffer = std::move(compressed);
|
script.buffer = std::move(compressed);
|
||||||
script.len = uncompressed.size();
|
script.len = uncompressed.size();
|
||||||
script.compressedLen = script.buffer.size();
|
script.compressedLen = script.buffer.size();
|
||||||
@ -265,12 +299,17 @@ void compile_file(gsc::assembler& assembler, gsc::compiler& compiler, std::strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void decompile_file(gsc::disassembler& disassembler, gsc::decompiler& decompiler, std::string file, game& game, bool zonetool)
|
void decompile_file(game game, std::string file)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
const auto& disassembler = disassemblers[game];
|
||||||
|
const auto& decompiler = decompilers[game];
|
||||||
|
|
||||||
if(zonetool)
|
if(zonetool)
|
||||||
{
|
{
|
||||||
|
if (file.find(".gscbin") != std::string::npos) return;
|
||||||
|
|
||||||
if (file.find(".stack") != std::string::npos)
|
if (file.find(".stack") != std::string::npos)
|
||||||
{
|
{
|
||||||
std::cerr << "Cannot disassemble stack files\n";
|
std::cerr << "Cannot disassemble stack files\n";
|
||||||
@ -288,10 +327,12 @@ void decompile_file(gsc::disassembler& disassembler, gsc::decompiler& decompiler
|
|||||||
auto script = utils::file::read(file + ".cgsc");
|
auto script = utils::file::read(file + ".cgsc");
|
||||||
auto stack = utils::file::read(file + ".cgsc.stack");
|
auto stack = utils::file::read(file + ".cgsc.stack");
|
||||||
|
|
||||||
disassembler.disassemble(file, script, stack);
|
disassembler->disassemble(file, script, stack);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (file.find(".cgsc") != std::string::npos) return;
|
||||||
|
|
||||||
const auto ext = std::string(".gscbin");
|
const auto ext = std::string(".gscbin");
|
||||||
const auto extpos = file.find(ext);
|
const auto extpos = file.find(ext);
|
||||||
|
|
||||||
@ -308,18 +349,18 @@ void decompile_file(gsc::disassembler& disassembler, gsc::decompiler& decompiler
|
|||||||
|
|
||||||
auto stack = utils::zlib::decompress(script.buffer, script.len);
|
auto stack = utils::zlib::decompress(script.buffer, script.len);
|
||||||
|
|
||||||
disassembler.disassemble(file, script.bytecode, stack);
|
disassembler->disassemble(file, script.bytecode, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto output = disassembler.output();
|
auto output = disassembler->output();
|
||||||
|
|
||||||
decompiler.decompile(file, output);
|
decompiler->decompile(file, output);
|
||||||
|
|
||||||
auto scriptid = std::filesystem::path(file).filename().string();
|
auto scriptid = std::filesystem::path(file).filename().string();
|
||||||
|
|
||||||
if (!isdigit(scriptid.data()[0]))
|
if (!isdigit(scriptid.data()[0]))
|
||||||
{
|
{
|
||||||
utils::file::save(file + ".gsc", decompiler.output());
|
utils::file::save(file + ".gsc", decompiler->output());
|
||||||
std::cout << "decompiled " << file << ".gsc\n";
|
std::cout << "decompiled " << file << ".gsc\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -335,7 +376,7 @@ void decompile_file(gsc::disassembler& disassembler, gsc::decompiler& decompiler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::file::save(file + filename + ".gsc", decompiler.output());
|
utils::file::save(file + filename + ".gsc", decompiler->output());
|
||||||
std::cout << "decompiled " << file << filename << ".gsc\n";
|
std::cout << "decompiled " << file << filename << ".gsc\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,277 +386,139 @@ void decompile_file(gsc::disassembler& disassembler, gsc::decompiler& decompiler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_flags(int argc, char** argv, game& game, mode& mode, bool& zonetool)
|
void execute(mode mode, game game, const std::string& path)
|
||||||
|
{
|
||||||
|
if(std::filesystem::is_directory(path))
|
||||||
|
{
|
||||||
|
for(const auto& entry : std::filesystem::recursive_directory_iterator(path))
|
||||||
|
{
|
||||||
|
if(entry.is_regular_file())
|
||||||
|
{
|
||||||
|
auto it1 = encds.find(mode);
|
||||||
|
auto it2 = exts.find(entry.path().extension().string());
|
||||||
|
|
||||||
|
if(it1 != encds.end() && it2 != exts.end() && it1->second == it2->second)
|
||||||
|
{
|
||||||
|
funcs[mode](game, entry.path().string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(std::filesystem::is_regular_file(path))
|
||||||
|
{
|
||||||
|
funcs[mode](game, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_flags(int argc, char** argv, game& game, mode& mode, std::string& path)
|
||||||
{
|
{
|
||||||
if (argc != 4) return 1;
|
if (argc != 4) return 1;
|
||||||
|
|
||||||
std::string arg = utils::string::to_lower(argv[1]);
|
auto arg = utils::string::to_lower(argv[1]);
|
||||||
|
|
||||||
const auto it1 = games.find(arg);
|
if(arg.at(0) == 'z')
|
||||||
|
|
||||||
if (it1 != games.end())
|
|
||||||
{
|
{
|
||||||
game = it1->second;
|
arg.erase(arg.begin());
|
||||||
|
zonetool = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto it = modes.find(arg);
|
||||||
|
|
||||||
|
if (it != modes.end())
|
||||||
|
{
|
||||||
|
mode = it->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Unknown game '" << argv[1] << "'.\n\n";
|
std::cout << "Unknown mode '" << argv[1] << "'.\n\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = utils::string::to_lower(argv[2]);
|
arg = utils::string::to_lower(argv[2]);
|
||||||
|
|
||||||
if(arg.at(1) == 'z')
|
const auto itr = games.find(arg);
|
||||||
{
|
|
||||||
arg.erase(arg.begin() + 1);
|
|
||||||
zonetool = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto it2 = modes.find(arg);
|
if (itr != games.end())
|
||||||
|
|
||||||
if (it2 != modes.end())
|
|
||||||
{
|
{
|
||||||
mode = it2->second;
|
game = itr->second;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Unknown mode '" << argv[2] << "'.\n\n";
|
std::cout << "Unknown game '" << argv[2] << "'.\n\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path = utils::string::fordslash(argv[3]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_usage()
|
void print_usage()
|
||||||
{
|
{
|
||||||
std::cout << "usage: gsc-tool.exe <game> <mode> <file>\n";
|
std::cout << "usage: gsc-tool.exe <mode> <game> <path>\n";
|
||||||
std::cout << " * games: -iw5, -iw6, -iw7, -iw8, -s1, -s2, -s4, -h1, -h2\n";
|
std::cout << " * modes: asm, disasm, comp, decomp\n";
|
||||||
std::cout << " * modes: -asm, -disasm, -comp, -decomp\n";
|
std::cout << " * games: iw5, iw6, iw7, iw8, s1, s2, s4, h1, h2\n";
|
||||||
|
std::cout << " * paths: file or directory (recursive)\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t main(std::uint32_t argc, char** argv)
|
std::uint32_t main(std::uint32_t argc, char** argv)
|
||||||
{
|
{
|
||||||
std::string file = utils::string::fordslash(argv[argc - 1]);
|
auto path = ""s;
|
||||||
mode mode = mode::__;
|
mode mode = mode::__;
|
||||||
game game = game::__;
|
game game = game::__;
|
||||||
bool zonetool = false;
|
|
||||||
|
|
||||||
if (parse_flags(argc, argv, game, mode, zonetool))
|
assemblers[game::IW5] = std::make_unique<gsc::iw5::assembler>();
|
||||||
|
assemblers[game::IW6] = std::make_unique<gsc::iw6::assembler>();
|
||||||
|
assemblers[game::IW7] = std::make_unique<gsc::iw7::assembler>();
|
||||||
|
assemblers[game::IW8] = std::make_unique<gsc::iw8::assembler>();
|
||||||
|
assemblers[game::S1] = std::make_unique<gsc::s1::assembler>();
|
||||||
|
assemblers[game::S2] = std::make_unique<gsc::s2::assembler>();
|
||||||
|
assemblers[game::S4] = std::make_unique<gsc::s4::assembler>();
|
||||||
|
assemblers[game::H1] = std::make_unique<gsc::h1::assembler>();
|
||||||
|
assemblers[game::H2] = std::make_unique<gsc::h2::assembler>();
|
||||||
|
|
||||||
|
disassemblers[game::IW5] = std::make_unique<gsc::iw5::disassembler>();
|
||||||
|
disassemblers[game::IW6] = std::make_unique<gsc::iw6::disassembler>();
|
||||||
|
disassemblers[game::IW7] = std::make_unique<gsc::iw7::disassembler>();
|
||||||
|
disassemblers[game::IW8] = std::make_unique<gsc::iw8::disassembler>();
|
||||||
|
disassemblers[game::S1] = std::make_unique<gsc::s1::disassembler>();
|
||||||
|
disassemblers[game::S2] = std::make_unique<gsc::s2::disassembler>();
|
||||||
|
disassemblers[game::S4] = std::make_unique<gsc::s4::disassembler>();
|
||||||
|
disassemblers[game::H1] = std::make_unique<gsc::h1::disassembler>();
|
||||||
|
disassemblers[game::H2] = std::make_unique<gsc::h2::disassembler>();
|
||||||
|
|
||||||
|
compilers[game::IW5] = std::make_unique<gsc::iw5::compiler>(gsc::compilation_mode::release);
|
||||||
|
compilers[game::IW6] = std::make_unique<gsc::iw6::compiler>();
|
||||||
|
compilers[game::IW7] = std::make_unique<gsc::iw7::compiler>();
|
||||||
|
compilers[game::IW8] = std::make_unique<gsc::iw8::compiler>();
|
||||||
|
compilers[game::S1] = std::make_unique<gsc::s1::compiler>();
|
||||||
|
compilers[game::S2] = std::make_unique<gsc::s2::compiler>();
|
||||||
|
compilers[game::S4] = std::make_unique<gsc::s4::compiler>();
|
||||||
|
compilers[game::H1] = std::make_unique<gsc::h1::compiler>();
|
||||||
|
compilers[game::H2] = std::make_unique<gsc::h2::compiler>();
|
||||||
|
|
||||||
|
decompilers[game::IW5] = std::make_unique<gsc::iw5::decompiler>();
|
||||||
|
decompilers[game::IW6] = std::make_unique<gsc::iw6::decompiler>();
|
||||||
|
decompilers[game::IW7] = std::make_unique<gsc::iw7::decompiler>();
|
||||||
|
decompilers[game::IW8] = std::make_unique<gsc::iw8::decompiler>();
|
||||||
|
decompilers[game::S1] = std::make_unique<gsc::s1::decompiler>();
|
||||||
|
decompilers[game::S2] = std::make_unique<gsc::s2::decompiler>();
|
||||||
|
decompilers[game::S4] = std::make_unique<gsc::s4::decompiler>();
|
||||||
|
decompilers[game::H1] = std::make_unique<gsc::h1::decompiler>();
|
||||||
|
decompilers[game::H2] = std::make_unique<gsc::h2::decompiler>();
|
||||||
|
|
||||||
|
funcs[mode::ASM] = assemble_file;
|
||||||
|
funcs[mode::DISASM] = disassemble_file;
|
||||||
|
funcs[mode::COMP] = compile_file;
|
||||||
|
funcs[mode::DECOMP] = decompile_file;
|
||||||
|
|
||||||
|
if (parse_flags(argc, argv, game, mode, path))
|
||||||
{
|
{
|
||||||
print_usage();
|
print_usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == mode::ASM)
|
execute(mode, game, path);
|
||||||
{
|
|
||||||
if( game == game::IW5)
|
|
||||||
{
|
|
||||||
gsc::iw5::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW6)
|
|
||||||
{
|
|
||||||
iw6::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW7)
|
|
||||||
{
|
|
||||||
iw7::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW8)
|
|
||||||
{
|
|
||||||
iw8::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S1)
|
|
||||||
{
|
|
||||||
s1::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S2)
|
|
||||||
{
|
|
||||||
s2::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S4)
|
|
||||||
{
|
|
||||||
s4::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H1)
|
|
||||||
{
|
|
||||||
h1::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H2)
|
|
||||||
{
|
|
||||||
h2::assembler assembler;
|
|
||||||
assemble_file(assembler, file, zonetool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == mode::DISASM)
|
|
||||||
{
|
|
||||||
if (game == game::IW5)
|
|
||||||
{
|
|
||||||
gsc::iw5::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW6)
|
|
||||||
{
|
|
||||||
iw6::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW7)
|
|
||||||
{
|
|
||||||
iw7::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW8)
|
|
||||||
{
|
|
||||||
iw8::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S1)
|
|
||||||
{
|
|
||||||
s1::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S2)
|
|
||||||
{
|
|
||||||
s2::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S4)
|
|
||||||
{
|
|
||||||
s4::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H1)
|
|
||||||
{
|
|
||||||
h1::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H2)
|
|
||||||
{
|
|
||||||
h2::disassembler disassembler;
|
|
||||||
disassemble_file(disassembler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == mode::COMP)
|
|
||||||
{
|
|
||||||
if (game == game::IW5)
|
|
||||||
{
|
|
||||||
gsc::iw5::assembler assembler;
|
|
||||||
gsc::iw5::compiler compiler(gsc::compilation_mode::release);
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW6)
|
|
||||||
{
|
|
||||||
iw6::assembler assembler;
|
|
||||||
iw6::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW7)
|
|
||||||
{
|
|
||||||
iw7::assembler assembler;
|
|
||||||
iw7::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW8)
|
|
||||||
{
|
|
||||||
iw8::assembler assembler;
|
|
||||||
iw8::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S1)
|
|
||||||
{
|
|
||||||
s1::assembler assembler;
|
|
||||||
s1::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S2)
|
|
||||||
{
|
|
||||||
s2::assembler assembler;
|
|
||||||
s2::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S4)
|
|
||||||
{
|
|
||||||
s4::assembler assembler;
|
|
||||||
s4::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H1)
|
|
||||||
{
|
|
||||||
h1::assembler assembler;
|
|
||||||
h1::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H2)
|
|
||||||
{
|
|
||||||
h2::assembler assembler;
|
|
||||||
h2::compiler compiler;
|
|
||||||
compile_file(assembler, compiler, file ,zonetool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == mode::DECOMP)
|
|
||||||
{
|
|
||||||
if (game == game::IW5)
|
|
||||||
{
|
|
||||||
iw5::disassembler disassembler;
|
|
||||||
iw5::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW6)
|
|
||||||
{
|
|
||||||
iw6::disassembler disassembler;
|
|
||||||
iw6::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW7)
|
|
||||||
{
|
|
||||||
iw7::disassembler disassembler;
|
|
||||||
iw7::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::IW8)
|
|
||||||
{
|
|
||||||
iw8::disassembler disassembler;
|
|
||||||
iw8::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S1)
|
|
||||||
{
|
|
||||||
s1::disassembler disassembler;
|
|
||||||
s1::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S2)
|
|
||||||
{
|
|
||||||
s2::disassembler disassembler;
|
|
||||||
s2::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::S4)
|
|
||||||
{
|
|
||||||
s4::disassembler disassembler;
|
|
||||||
s4::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H1)
|
|
||||||
{
|
|
||||||
h1::disassembler disassembler;
|
|
||||||
h1::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
else if (game == game::H2)
|
|
||||||
{
|
|
||||||
h2::disassembler disassembler;
|
|
||||||
h2::decompiler decompiler;
|
|
||||||
decompile_file(disassembler, decompiler, file, game, zonetool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ namespace xsk::gsc
|
|||||||
class assembler
|
class assembler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~assembler() = default;
|
||||||
virtual auto output_script() -> std::vector<std::uint8_t> = 0;
|
virtual auto output_script() -> std::vector<std::uint8_t> = 0;
|
||||||
virtual auto output_stack() -> std::vector<std::uint8_t> = 0;
|
virtual auto output_stack() -> std::vector<std::uint8_t> = 0;
|
||||||
virtual void assemble(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
virtual void assemble(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||||
|
@ -11,6 +11,7 @@ namespace xsk::gsc
|
|||||||
class compiler
|
class compiler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~compiler() = default;
|
||||||
virtual auto output() -> std::vector<gsc::function_ptr> = 0;
|
virtual auto output() -> std::vector<gsc::function_ptr> = 0;
|
||||||
virtual void compile(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
virtual void compile(const std::string& file, std::vector<std::uint8_t>& data) = 0;
|
||||||
virtual void set_readf_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) = 0;
|
virtual void set_readf_callback(std::function<std::vector<std::uint8_t>(const std::string&)> func) = 0;
|
||||||
|
@ -11,6 +11,7 @@ namespace xsk::gsc
|
|||||||
class decompiler
|
class decompiler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~decompiler() = default;
|
||||||
virtual auto output() -> std::vector<std::uint8_t> = 0;
|
virtual auto output() -> std::vector<std::uint8_t> = 0;
|
||||||
virtual void decompile(const std::string& file, std::vector<gsc::function_ptr>& functions) = 0;
|
virtual void decompile(const std::string& file, std::vector<gsc::function_ptr>& functions) = 0;
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,7 @@ namespace xsk::gsc
|
|||||||
class disassembler
|
class disassembler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~disassembler() = default;
|
||||||
virtual auto output() -> std::vector<gsc::function_ptr> = 0;
|
virtual auto output() -> std::vector<gsc::function_ptr> = 0;
|
||||||
virtual auto output_data() -> std::vector<std::uint8_t> = 0;
|
virtual auto output_data() -> std::vector<std::uint8_t> = 0;
|
||||||
virtual void disassemble(const std::string& file, std::vector<std::uint8_t>& script, std::vector<std::uint8_t>& stack) = 0;
|
virtual void disassemble(const std::string& file, std::vector<std::uint8_t>& script, std::vector<std::uint8_t>& stack) = 0;
|
||||||
|
@ -11,26 +11,26 @@ namespace xsk::gsc
|
|||||||
class error : public std::runtime_error
|
class error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
error(const std::string& what) : std::runtime_error("[gsc]: "s + what) { }
|
error(const std::string& what) : std::runtime_error("[ERROR]: "s + what) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class asm_error : public std::runtime_error
|
class asm_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
asm_error(const std::string& what) : std::runtime_error("[gsc assembler]: "s + what) { }
|
asm_error(const std::string& what) : std::runtime_error("[ERROR]:assembler: "s + what) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class disasm_error : public std::runtime_error
|
class disasm_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
disasm_error(const std::string& what) : std::runtime_error("[gsc disassembler]: "s + what) { }
|
disasm_error(const std::string& what) : std::runtime_error("[ERROR]:disassembler: "s + what) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class comp_error : public std::runtime_error
|
class comp_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
comp_error(gsc::location loc, const std::string& what)
|
comp_error(gsc::location loc, const std::string& what)
|
||||||
: std::runtime_error("[gsc compiler]:" +
|
: std::runtime_error("[ERROR]:compiler:" +
|
||||||
*loc.begin.filename + ":" +
|
*loc.begin.filename + ":" +
|
||||||
std::to_string(loc.begin.line) + ":" +
|
std::to_string(loc.begin.line) + ":" +
|
||||||
std::to_string(loc.begin.column) + ": " + what) { }
|
std::to_string(loc.begin.column) + ": " + what) { }
|
||||||
@ -39,7 +39,7 @@ public:
|
|||||||
class decomp_error : public std::runtime_error
|
class decomp_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
decomp_error(const std::string& what) : std::runtime_error("[gsc decompiler]: "s + what) { }
|
decomp_error(const std::string& what) : std::runtime_error("[ERROR]:decompiler: "s + what) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xsk::gsc
|
} // namespace xsk::gsc
|
||||||
|
Loading…
Reference in New Issue
Block a user