Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(jup): jup template #192

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![build](https://github.com/xensik/gsc-tool/workflows/Build/badge.svg)](https://github.com/xensik/gsc-tool/actions)
[![sonar](https://sonarcloud.io/api/project_badges/measure?project=xensik_gsc-tool&metric=alert_status)](https://sonarcloud.io/summary/overall?id=xensik_gsc-tool)
[![build](https://github.com/xensik/gsc-tool/workflows/Build/badge.svg)](https://github.com/xensik/gsc-tool/actions)
[![issues](https://img.shields.io/github/issues/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/issues)
[![license](https://img.shields.io/github/license/xensik/gsc-tool.svg)](https://github.com/xensik/gsc-tool/blob/dev/LICENSE)
[![releases](https://img.shields.io/github/v/release/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/releases)
Expand All @@ -23,6 +23,7 @@ A utility to compile & decompile IW engine game scripts.
- **T7** *(Call of Duty: Black Ops III)* `PC` *(Decompiler)*
- **T8** *(Call of Duty: Black Ops 4)* ***\*WIP\****
- **T9** *(Call of Duty: Black Ops Cold War)* ***\*WIP\****
- **JUP** *(Call of Duty: Modern Warfare III (2023)* ***\*WIP\****

## Usage
``gsc-tool [OPTIONS..] <path>``
Expand All @@ -33,11 +34,11 @@ A utility to compile & decompile IW engine game scripts.

``-m, --mode <mode>`` [REQUIRED] one of: `asm`, `disasm`, `comp`, `decomp`, `parse`

``-g, --game <game>`` [REQUIRED] one of: `iw5`, `iw6`, `iw7`, `iw8`, `iw9`, `s1`, `s2`, `s4`, `h1`, `h2`, `t6` `t7` `t8` `t9`
``-g, --game <game>`` [REQUIRED] one of: `iw5`, `iw6`, `iw7`, `iw8`, `iw9`, `s1`, `s2`, `s4`, `h1`, `h2`, `t6` `t7` `t8` `t9` `jup`

``-s, --system <system>`` [REQUIRED] one of: `pc`, `ps3`, `ps4`, `ps5`, `xb2` (*360*), `xb3` (*One*), `xb4` (*Series X|S*), `wiiu`

``-d, --dev`` Enable developer mode (generate bytecode map).
``-d, --dev`` Enable developer mode (dev blocks & generate bytecode map).

``-z, --zonetool`` Enable zonetool mode (use .cgsc files).

Expand Down
1 change: 1 addition & 0 deletions include/xsk/arc/common/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ enum class engine : u8
t7,
t8,
t9,
jup
};

struct props
Expand Down
24 changes: 24 additions & 0 deletions include/xsk/arc/engine/jup.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2024 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.

#pragma once

#include "xsk/stdinc.hpp"
#include "xsk/arc/context.hpp"

namespace xsk::arc::jup
{

constexpr usize code_count = 0;
constexpr usize hash_count = 0;
constexpr u64 header_magic = 0x38000A0D43534780;

class context : public arc::context
{
public:
context();
};

} // namespace xsk::arc::jup
32 changes: 32 additions & 0 deletions src/arc/engine/jup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.

#include "xsk/arc/engine/jup.hpp"

namespace xsk::arc::jup
{

extern std::array<std::pair<u16, opcode>, code_count> const code_list;
// extern std::array<std::pair<u32, char const*>, hash_count> const hash_list;

context::context() : arc::context(props::v3, engine::jup, endian::little, system::pc, header_magic)
{
code_map_.reserve(code_list.size());
code_map_rev_.reserve(code_list.size());
// hash_map_.reserve(hash_list.size());

for (auto const& entry : code_list)
{
code_map_.insert({ entry.first, entry.second });
code_map_rev_.insert({ entry.second, entry.first });
}

// for (auto const& entry : hash_list)
// {
// hash_map_.insert({ entry.first, entry.second });
// }
}

} // namespace xsk::arc::jup
15 changes: 15 additions & 0 deletions src/arc/engine/jup_code.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2024 xensik. All rights reserved.
//
// Use of this source code is governed by a GNU GPLv3 license
// that can be found in the LICENSE file.

#include "xsk/arc/engine/jup.hpp"

namespace xsk::arc::jup
{

extern std::array<std::pair<u16, opcode>, code_count> const code_list
{{
}};

} // namespace xsk::arc::jup
120 changes: 83 additions & 37 deletions src/tool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "xsk/arc/engine/t7.hpp"
#include "xsk/arc/engine/t8.hpp"
#include "xsk/arc/engine/t9.hpp"
#include "xsk/arc/engine/jup.hpp"
#include "xsk/version.hpp"
#include "cxxopts.hpp"

Expand All @@ -41,7 +42,7 @@ namespace xsk
enum class result : i32 { success = 0, failure = 1 };
enum class fenc { _, source, assembly, binary, src_bin };
enum class mode { _, assemble, disassemble, compile, decompile, parse, rename };
enum class game { _, iw5, iw6, iw7, iw8, iw9, s1, s2, s4, h1, h2, t6, t7, t8, t9 };
enum class game { _, iw5, iw6, iw7, iw8, iw9, s1, s2, s4, h1, h2, t6, t7, t8, t9, jup };
enum class mach { _, pc, ps3, ps4, ps5, xb2, xb3, xb4, wiiu };

std::unordered_map<std::string_view, fenc> const gsc_exts =
Expand Down Expand Up @@ -92,6 +93,7 @@ std::unordered_map<std::string_view, game> const games =
{ "t7", game::t7 },
{ "t8", game::t8 },
{ "t9", game::t9 },
{ "jup", game::jup },
};

std::map<game, std::string_view> const games_rev =
Expand All @@ -110,6 +112,7 @@ std::map<game, std::string_view> const games_rev =
{ game::t7, "t7" },
{ game::t8, "t8" },
{ game::t9, "t9" },
{ game::jup, "jup" },
};

std::unordered_map<std::string_view, mach> const machs =
Expand Down Expand Up @@ -763,6 +766,9 @@ auto disassemble_file(game game, mach mach, fs::path const& file, fs::path rel)
{
try
{
if (game > game::t7)
throw std::runtime_error("not implemented");

rel = fs::path{ games_rev.at(game) } / rel / file.filename().replace_extension((file.extension().string().starts_with(".gsc") ? ".gscasm" : ".cscasm"));

auto data = utils::file::read(file.string());
Expand Down Expand Up @@ -822,6 +828,9 @@ auto decompile_file(game game, mach mach, fs::path const& file, fs::path rel) ->
{
try
{
if (game > game::t7)
throw std::runtime_error("not implemented");

rel = fs::path{ games_rev.at(game) } / rel / file.filename();

auto data = utils::file::read(file);
Expand All @@ -841,10 +850,33 @@ auto decompile_file(game game, mach mach, fs::path const& file, fs::path rel) ->
}
}

auto parse_file(game, mach, fs::path const&, fs::path) -> result
auto parse_file(game game, mach mach, fs::path file, fs::path rel) -> result
{
std::cerr << std::format("not implemented for treyarch\n");
return result::failure;
try
{
if (game != game::t6)
throw std::runtime_error("not implemented");

rel = fs::path{ games_rev.at(game) } / rel / file.filename();

auto data = utils::file::read(file);

if (!std::memcmp(&data[0], "\x80GSC", 4))
{
std::cerr << std::format("{} at {}\n", "already compiled", file.generic_string());
return result::success;
}

auto prog = contexts[game][mach]->source().parse_program(file.string(), data);
utils::file::save(fs::path{ "parsed" } / rel, contexts[game][mach]->source().dump(*prog));
std::cout << std::format("parsed {}\n", rel.generic_string());
return result::success;
}
catch (std::exception const& e)
{
std::cerr << std::format("{} at {}\n", e.what(), file.generic_string());
return result::failure;
}
}

auto rename_file(game, mach, fs::path const&, fs::path) -> result
Expand Down Expand Up @@ -910,42 +942,55 @@ auto init_t7(mach mach, bool dev) -> void
}
}

auto init_t8(mach /*mach*/, bool /*dev*/) -> void
auto init_t8(mach mach, bool dev) -> void
{
throw std::runtime_error("not implemented");

// if (contexts[game::t8].contains(mach)) return;

// switch (mach)
// {
// case mach::pc:
// {
// contexts[game::t8][mach] = std::make_unique<t8::context>();
// contexts[game::t8][mach]->init(build::prod, fs_read);
// break;
// }
// default:
// throw std::runtime_error("not implemented");
// }
if (contexts[game::t8].contains(mach)) return;

switch (mach)
{
case mach::pc:
{
contexts[game::t8][mach] = std::make_unique<t8::context>();
contexts[game::t8][mach]->init(dev ? build::dev : build::prod, fs_read);
break;
}
default:
throw std::runtime_error("not implemented");
}
}

auto init_t9(mach mach, bool dev) -> void
{
if (contexts[game::t9].contains(mach)) return;

switch (mach)
{
case mach::pc:
{
contexts[game::t9][mach] = std::make_unique<t9::context>();
contexts[game::t9][mach]->init(dev ? build::dev : build::prod, fs_read);
break;
}
default:
throw std::runtime_error("not implemented");
}
}

auto init_t9(mach /*mach*/, bool /*dev*/) -> void
auto init_jup(mach mach, bool dev) -> void
{
throw std::runtime_error("not implemented");

// if (contexts[game::t9].contains(mach)) return;

// switch (mach)
// {
// case mach::pc:
// {
// contexts[game::t9][mach] = std::make_unique<t9::context>();
// contexts[game::t9][mach]->init(build::prod, fs_read);
// break;
// }
// default:
// throw std::runtime_error("not implemented");
// }
if (contexts[game::jup].contains(mach)) return;

switch (mach)
{
case mach::pc:
{
contexts[game::jup][mach] = std::make_unique<jup::context>();
contexts[game::jup][mach]->init(dev ? build::dev : build::prod, fs_read);
break;
}
default:
throw std::runtime_error("not implemented");
}
}

auto init(game game, mach mach, bool dev) -> void
Expand All @@ -968,6 +1013,7 @@ auto init(game game, mach mach, bool dev) -> void
case game::t7: init_t7(mach, dev); break;
case game::t8: init_t8(mach, dev); break;
case game::t9: init_t9(mach, dev); break;
case game::jup: init_jup(mach, dev); break;
default: break;
}
}
Expand Down Expand Up @@ -1102,7 +1148,7 @@ auto main(u32 argc, char** argv) -> result

options.add_options()
("m,mode","[REQUIRED] one of: asm, disasm, comp, decomp, parse, rename", cxxopts::value<std::string>(), "<mode>")
("g,game", "[REQUIRED] one of: iw5, iw6, iw7, iw8, iw9, s1, s2, s4, h1, h2, t6, t7, t8, t9", cxxopts::value<std::string>(), "<game>")
("g,game", "[REQUIRED] one of: iw5, iw6, iw7, iw8, iw9, s1, s2, s4, h1, h2, t6, t7, t8, t9, jup", cxxopts::value<std::string>(), "<game>")
("s,system", "[REQUIRED] one of: pc, ps3, ps4, ps5, xb2 (360), xb3 (One), xb4 (Series X|S), wiiu", cxxopts::value<std::string>(), "<system>")
("p,path", "File or directory to process.", cxxopts::value<std::string>())
("d,dev", "Enable developer mode (dev blocks & generate bytecode map).", cxxopts::value<bool>()->implicit_value("true"))
Expand Down
Loading