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

jak x: preliminary type definition decomp work #3633

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
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
13 changes: 13 additions & 0 deletions .vs/launch.vs.json
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,19 @@
"--config-override \"{\\\"decompile_code\\\": false, \\\"levels_extract\\\": true, \\\"allowed_objects\\\": []}\""
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "decompiler.exe (bin\\decompiler.exe)",
"name": "Decompiler - Jak X",
"args": [
"${workspaceRoot}/decompiler/config/jakx/jakx_config.jsonc",
"${workspaceRoot}/iso_data",
"${workspaceRoot}/decompiler_out",
"--version",
"pal"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
Expand Down
2 changes: 2 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ tasks:
- 'python ./scripts/tasks/update-env.py --game jak2'
set-game-jak3:
- 'python ./scripts/tasks/update-env.py --game jak3'
set-game-jakx:
- 'python ./scripts/tasks/update-env.py --game jakx'
set-decomp-ntscv1:
desc: "aka black label"
cmds:
Expand Down
5 changes: 3 additions & 2 deletions common/audio/audio_formats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ void write_wave_file(const std::vector<s16>& left_samples,
}

std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader,
const bool stereo) {
const bool stereo,
const u32 version) {
std::vector<s16> left_samples;
std::vector<s16> right_samples;
s32 left_sample_prev[2] = {0, 0};
Expand Down Expand Up @@ -85,7 +86,7 @@ std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader,
break;
}

if (stereo && bytes_read == 0x2000) {
if (stereo && bytes_read == (version == 3 ? 0x1000 : 0x2000)) {
// switch streams
processing_left_chunk = !processing_left_chunk;
bytes_read = 0;
Expand Down
4 changes: 3 additions & 1 deletion common/audio/audio_formats.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ void write_wave_file(const std::vector<s16>& left_samples,
s32 sample_rate,
const fs::path& name);

std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader, const bool mono);
std::pair<std::vector<s16>, std::vector<s16>> decode_adpcm(BinaryReader& reader,
const bool mono,
const u32 version);

std::vector<u8> encode_adpcm(const std::vector<s16>& samples);
11 changes: 11 additions & 0 deletions common/goal_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ constexpr int LEVEL_MAX = 10;
constexpr int LEVEL_TOTAL = LEVEL_MAX + 1;
} // namespace jak3

namespace jakx {
// for now, we don't have the ability to extend the size of the symbol table
constexpr s32 GOAL_MAX_SYMBOLS = 0x4000;
// amount of levels in level heap
constexpr int LEVEL_MAX = 10;
// total amount of levels, including ones outside level heap (default-level)
constexpr int LEVEL_TOTAL = LEVEL_MAX + 1;
} // namespace jakx

constexpr s32 max_symbols(GameVersion version) {
switch (version) {
case GameVersion::Jak1:
Expand All @@ -79,6 +88,8 @@ constexpr s32 max_symbols(GameVersion version) {
return jak2::GOAL_MAX_SYMBOLS;
case GameVersion::Jak3:
return jak3::GOAL_MAX_SYMBOLS;
case GameVersion::JakX:
return jakx::GOAL_MAX_SYMBOLS;
}
}

Expand Down
2 changes: 2 additions & 0 deletions common/symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ constexpr int true_symbol_offset(GameVersion version) {
return jak1_symbols::FIX_SYM_TRUE;
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
return jak2_symbols::FIX_SYM_TRUE;
}
}
Expand All @@ -344,6 +345,7 @@ constexpr int empty_pair_offset_from_s7(GameVersion version) {
return jak1_symbols::FIX_SYM_EMPTY_PAIR;
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
// minus 1 for the symbol table pointer's offset.
return jak2_symbols::S7_OFF_FIX_SYM_EMPTY_PAIR;
}
Expand Down
1 change: 1 addition & 0 deletions common/type_system/TypeSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,7 @@ void TypeSystem::add_builtin_types(GameVersion version) {
break;
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
symbol_type = add_builtin_structure("object", "symbol", true);
symbol_type->override_offset(1);
break;
Expand Down
23 changes: 21 additions & 2 deletions common/util/FontUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ const std::unordered_map<std::string, GameTextVersion> sTextVerEnumMap = {
{"jak1-v1", GameTextVersion::JAK1_V1},
{"jak1-v2", GameTextVersion::JAK1_V2},
{"jak2", GameTextVersion::JAK2},
{"jak3", GameTextVersion::JAK3}};
{"jak3", GameTextVersion::JAK3},
{"jakx", GameTextVersion::JAKX}};

const std::string& get_text_version_name(GameTextVersion version) {
for (auto& [name, ver] : sTextVerEnumMap) {
Expand Down Expand Up @@ -1926,6 +1927,21 @@ GameTextFontBank g_font_bank_jak3(GameTextVersion::JAK3,
&s_replace_info_jak2,
&s_passthrus_jak2);

/*!
* ================================
* GAME TEXT FONT BANK - JAK X
* ================================
* This font is used in:
* - Jak X
*/

// TODO cyrillic

GameTextFontBank g_font_bank_jakx(GameTextVersion::JAKX,
&s_encode_info_jak2,
&s_replace_info_jak2,
&s_passthrus_jak2);

/*!
* ========================
* GAME TEXT FONT BANK LIST
Expand All @@ -1937,7 +1953,8 @@ std::map<GameTextVersion, GameTextFontBank*> g_font_banks = {
{GameTextVersion::JAK1_V1, &g_font_bank_jak1_v1},
{GameTextVersion::JAK1_V2, &g_font_bank_jak1_v2},
{GameTextVersion::JAK2, &g_font_bank_jak2},
{GameTextVersion::JAK3, &g_font_bank_jak3}};
{GameTextVersion::JAK3, &g_font_bank_jak3},
{GameTextVersion::JAKX, &g_font_bank_jakx}};

const GameTextFontBank* get_font_bank(GameTextVersion version) {
return g_font_banks.at(version);
Expand All @@ -1952,6 +1969,8 @@ const GameTextFontBank* get_font_bank_from_game_version(GameVersion version) {
return get_font_bank(GameTextVersion::JAK2);
case GameVersion::Jak3:
return get_font_bank(GameTextVersion::JAK3);
case GameVersion::JakX:
return get_font_bank(GameTextVersion::JAKX);
default:
ASSERT_MSG(false, "Unsupported game for get_font_bank_from_game_version");
}
Expand Down
3 changes: 2 additions & 1 deletion common/util/dgo_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ std::string get_object_file_name(const std::string& original_name, const u8* dat
const std::string art_group_text_strings[] = {
fmt::format("/src/next/data/art-group{}/", versions::jak1::ART_FILE_VERSION),
fmt::format("/src/jak2/final/art-group{}/", versions::jak2::ART_FILE_VERSION),
fmt::format("/src/jak3/final/art-group{}/", versions::jak3::ART_FILE_VERSION)};
fmt::format("/src/jak3/final/art-group{}/", versions::jak3::ART_FILE_VERSION),
fmt::format("/src/jakx/final/art-group{}/", versions::jakx::ART_FILE_VERSION)};
const std::string suffix = "-ag.go";

for (auto& art_group_text : art_group_text_strings) {
Expand Down
8 changes: 7 additions & 1 deletion common/versions/versions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ GameVersion game_name_to_version(const std::string& name) {
return GameVersion::Jak2;
} else if (name == "jak3") {
return GameVersion::Jak3;
} else if (name == "jakx") {
return GameVersion::JakX;
} else {
ASSERT_MSG(false, fmt::format("invalid game name: {}", name));
}
Expand All @@ -30,6 +32,8 @@ std::string version_to_game_name(GameVersion v) {
return "jak2";
case GameVersion::Jak3:
return "jak3";
case GameVersion::JakX:
return "jakx";
default:
ASSERT_MSG(false, fmt::format("no game_name for version: {} found", fmt::underlying(v)));
}
Expand All @@ -43,14 +47,16 @@ std::string version_to_game_name_external(GameVersion v) {
return "Jak 2";
case GameVersion::Jak3:
return "Jak 3";
case GameVersion::JakX:
return "Jak X";
default:
ASSERT_MSG(false, fmt::format("no game_name for version: {} found", fmt::underlying(v)));
}
}

std::vector<std::string> valid_game_version_names() {
return {game_version_names[GameVersion::Jak1], game_version_names[GameVersion::Jak2],
game_version_names[GameVersion::Jak3]};
game_version_names[GameVersion::Jak3], game_version_names[GameVersion::JakX]};
}

std::string build_revision() {
Expand Down
15 changes: 11 additions & 4 deletions common/versions/versions.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ constexpr u32 DGO_FILE_VERSION = 1;
constexpr u32 TX_PAGE_VERSION = 8;
} // namespace jak3

namespace jakx {
constexpr u32 ART_FILE_VERSION = 8;
constexpr u32 LEVEL_FILE_VERSION = 36;
constexpr u32 DGO_FILE_VERSION = 1;
constexpr u32 TX_PAGE_VERSION = 8;
} // namespace jakx

} // namespace versions

// GOAL kernel version (OpenGOAL changes this version from the game's version)
Expand All @@ -48,17 +55,17 @@ constexpr int KERNEL_VERSION_MINOR = 0;
constexpr int IRX_VERSION_MAJOR = 2;
constexpr int IRX_VERSION_MINOR = 0;

enum class GameVersion { Jak1 = 1, Jak2 = 2, Jak3 = 3 };
enum class GameVersion { Jak1 = 1, Jak2 = 2, Jak3 = 3, JakX = 4 };

// TODO: most usages of this are currently stubs for jak 3
template <typename T>
struct PerGameVersion {
constexpr PerGameVersion(T jak1, T jak2, T jak3) : data{jak1, jak2, jak3} {}
constexpr PerGameVersion(T jak1, T jak2, T jak3, T jakx) : data{jak1, jak2, jak3, jakx} {}
constexpr const T& operator[](GameVersion v) const { return data[(int)v - 1]; }
T data[3];
T data[4];
};

constexpr PerGameVersion<const char*> game_version_names = {"jak1", "jak2", "jak3"};
constexpr PerGameVersion<const char*> game_version_names = {"jak1", "jak2", "jak3", "jakx"};

GameVersion game_name_to_version(const std::string& name);
bool valid_game_version(const std::string& name);
Expand Down
1 change: 1 addition & 0 deletions decompiler/IR2/Form.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3254,6 +3254,7 @@ goos::Object DefskelgroupElement::to_form_internal(const Env& env) const {
}
break;
case GameVersion::Jak3:
case GameVersion::JakX:
if (m_static_info.version != 8) {
forms.push_back(pretty_print::to_symbol(fmt::format(":version {}", m_static_info.version)));
}
Expand Down
2 changes: 2 additions & 0 deletions decompiler/IR2/Form.h
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,8 @@ class DefpartElement : public FormElement {
case GameVersion::Jak2:
case GameVersion::Jak3:
return field_id == 72;
case GameVersion::JakX:
return field_id == 71;
default:
ASSERT_MSG(false, fmt::format("unknown version for is_sp_end"));
return false;
Expand Down
9 changes: 5 additions & 4 deletions decompiler/ObjectFile/ObjectFileDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,8 @@ std::string ObjectFileDB::process_tpages(TextureDB& tex_db,
case GameVersion::Jak3:
animated_slots = jak3_animated_texture_slots();
break;
case GameVersion::JakX:
break;
default:
ASSERT_NOT_REACHED();
}
Expand Down Expand Up @@ -856,18 +858,17 @@ std::string ObjectFileDB::process_all_spool_subtitles(const Config& cfg,
}
}

std::string ObjectFileDB::process_game_text_files(const Config& cfg) {
std::string ObjectFileDB::process_game_text_files(const Config& cfg, std::string text_string) {
try {
lg::info("- Finding game text...");
std::string text_string = "COMMON";
Timer timer;
int file_count = 0;
int string_count = 0;
int char_count = 0;
std::unordered_map<int, std::unordered_map<int, std::string>> text_by_language_by_id;

for_each_obj([&](ObjectFileData& data) {
if (data.name_in_dgo.substr(1) == text_string) {
if (data.name_in_dgo.ends_with(text_string)) {
file_count++;
auto statistics = process_game_text(data, cfg.text_version);
string_count += statistics.total_text;
Expand Down Expand Up @@ -923,7 +924,7 @@ void get_joint_info(ObjectFileDB& db, ObjectFileData& obj, JointGeo jg) {
const auto& words = obj.linked_data.words_by_seg.at(MAIN_SEGMENT);
for (size_t i = 0; i < jg.length; ++i) {
u32 label = 0x0;
if (db.version() == GameVersion::Jak3) {
if (db.version() >= GameVersion::Jak3) {
label = words.at((jg.offset / 4) + 11 + i).label_id();
} else {
label = words.at((jg.offset / 4) + 7 + i).label_id();
Expand Down
2 changes: 1 addition & 1 deletion decompiler/ObjectFile/ObjectFileDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ class ObjectFileDB {
const Config& cfg,
const fs::path& dump_out);
std::string process_game_count_file();
std::string process_game_text_files(const Config& cfg);
std::string process_game_text_files(const Config& cfg, std::string text_string = "COMMON");
std::string process_all_spool_subtitles(const Config& cfg, const fs::path& image_out);

const ObjectFileData& lookup_record(const ObjectFileRecord& rec) const;
Expand Down
1 change: 1 addition & 0 deletions decompiler/analysis/atomic_op_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,7 @@ std::unique_ptr<AtomicOp> convert_5(const Instruction& i0,
break;
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
process_offset = 48;
break;
default:
Expand Down
3 changes: 2 additions & 1 deletion decompiler/analysis/cfg_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1430,7 +1430,7 @@ Form* try_sc_as_type_of_jak2(FormPool& pool, Function& f, const ShortCircuit* vt
f.ir2.env.disable_def(b2_delay_op.dst(), f.warnings);
f.ir2.env.disable_use(shift_left->expr().get_arg(0).var());

if (f.ir2.env.version != GameVersion::Jak3) {
if (f.ir2.env.version != GameVersion::Jak3 && f.ir2.env.version != GameVersion::JakX) {
f.warnings.warning("Using new Jak 2 rtype-of");
}
return b0_ptr;
Expand Down Expand Up @@ -1574,6 +1574,7 @@ Form* try_sc_as_type_of(FormPool& pool, Function& f, const ShortCircuit* vtx, Ga
return try_sc_as_type_of_jak1(pool, f, vtx);
case GameVersion::Jak2:
case GameVersion::Jak3:
case GameVersion::JakX:
return try_sc_as_type_of_jak2(pool, f, vtx);
default:
ASSERT(false);
Expand Down
Loading
Loading