mirror of
https://github.com/open-goal/jak-project.git
synced 2024-11-26 16:00:52 +00:00
decompiler: some hacks to allow running decompiler on jak 3 v5 code files, improve all-types
generation (#2526)
Co-authored-by: water <awaterford111445@gmail.com>
This commit is contained in:
parent
5f8415320b
commit
bf961a36f4
@ -68,6 +68,8 @@ constexpr s32 max_symbols(GameVersion version) {
|
||||
return jak1::GOAL_MAX_SYMBOLS;
|
||||
case GameVersion::Jak2:
|
||||
return jak2::GOAL_MAX_SYMBOLS;
|
||||
case GameVersion::Jak3:
|
||||
return jak2::GOAL_MAX_SYMBOLS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,6 +159,7 @@ constexpr int true_symbol_offset(GameVersion version) {
|
||||
case GameVersion::Jak1:
|
||||
return jak1_symbols::FIX_SYM_TRUE;
|
||||
case GameVersion::Jak2:
|
||||
case GameVersion::Jak3:
|
||||
return jak2_symbols::FIX_SYM_TRUE;
|
||||
}
|
||||
}
|
||||
@ -168,6 +169,7 @@ constexpr int empty_pair_offset_from_s7(GameVersion version) {
|
||||
case GameVersion::Jak1:
|
||||
return jak1_symbols::FIX_SYM_EMPTY_PAIR;
|
||||
case GameVersion::Jak2:
|
||||
case GameVersion::Jak3:
|
||||
// minus 1 for the symbol table pointer's offset.
|
||||
return jak2_symbols::S7_OFF_FIX_SYM_EMPTY_PAIR;
|
||||
}
|
||||
|
@ -238,6 +238,9 @@ class Field {
|
||||
int offset() const { return m_offset; }
|
||||
bool skip_in_decomp() const { return m_skip_in_static_decomp; }
|
||||
bool user_placed() const { return m_placed_by_user; }
|
||||
void set_comment(const std::string& comment) { m_comment = comment; }
|
||||
const std::string& comment() const { return m_comment; }
|
||||
bool has_comment() const { return !m_comment.empty(); }
|
||||
bool operator==(const Field& other) const;
|
||||
bool operator!=(const Field& other) const { return !((*this) == other); }
|
||||
std::string diff(const Field& other) const;
|
||||
@ -274,6 +277,7 @@ class Field {
|
||||
int m_alignment = -1;
|
||||
bool m_skip_in_static_decomp = false;
|
||||
bool m_placed_by_user = false; // was this field placed manually by the user?
|
||||
std::string m_comment; // optional comment placed next to the field
|
||||
|
||||
double m_field_score = 0.;
|
||||
|
||||
|
@ -1027,6 +1027,7 @@ void TypeSystem::add_builtin_types(GameVersion version) {
|
||||
symbol_type = add_builtin_basic("basic", "symbol");
|
||||
break;
|
||||
case GameVersion::Jak2:
|
||||
case GameVersion::Jak3:
|
||||
symbol_type = add_builtin_structure("object", "symbol", true);
|
||||
symbol_type->override_offset(1);
|
||||
break;
|
||||
|
@ -24,7 +24,8 @@ void assert_string_empty_after(const char* str, int size) {
|
||||
std::string get_object_file_name(const std::string& original_name, u8* data, int size) {
|
||||
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/jak2/final/art-group{}/", versions::jak2::ART_FILE_VERSION),
|
||||
fmt::format("/src/jak3/final/art-group{}/", versions::jak3::ART_FILE_VERSION)};
|
||||
const std::string suffix = "-ag.go";
|
||||
|
||||
for (auto& art_group_text : art_group_text_strings) {
|
||||
|
@ -29,9 +29,12 @@ constexpr u32 ART_FILE_VERSION = 7;
|
||||
constexpr u32 LEVEL_FILE_VERSION = 36;
|
||||
constexpr u32 DGO_FILE_VERSION = 1;
|
||||
constexpr u32 TX_PAGE_VERSION = 8;
|
||||
|
||||
} // namespace jak2
|
||||
|
||||
namespace jak3 {
|
||||
constexpr u32 ART_FILE_VERSION = 8;
|
||||
}
|
||||
|
||||
} // namespace versions
|
||||
|
||||
// GOAL kernel version (OpenGOAL changes this version from the game's version)
|
||||
@ -42,7 +45,7 @@ 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 };
|
||||
enum class GameVersion { Jak1 = 1, Jak2 = 2, Jak3 = 3 };
|
||||
|
||||
template <typename T>
|
||||
struct PerGameVersion {
|
||||
|
@ -584,6 +584,13 @@ void Function::find_type_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts)
|
||||
int label_idx = -1;
|
||||
|
||||
for (const auto& instr : instructions) {
|
||||
// far labels
|
||||
if (label_idx != -1 && state == 5 &&
|
||||
!(instr.kind == InstructionKind::JALR && instr.get_dst(0).get_reg() == make_gpr(Reg::RA) &&
|
||||
instr.get_src(0).get_reg() == make_gpr(Reg::T9))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// look for lw xx, type(s7)
|
||||
if (instr.kind == InstructionKind::LW && instr.get_src(0).is_sym() &&
|
||||
instr.get_src(0).get_sym() == "type" && instr.get_src(1).get_reg() == make_gpr(Reg::S7)) {
|
||||
@ -630,8 +637,14 @@ void Function::find_type_defs(LinkedObjectFile& file, DecompilerTypeSystem& dts)
|
||||
|
||||
if (state == 4) {
|
||||
// look for ld a2, LXX(fp)
|
||||
if (instr.kind == InstructionKind::LD && instr.get_dst(0).get_reg() == make_gpr(Reg::A2) &&
|
||||
instr.get_src(0).is_label() && instr.get_src(1).get_reg() == make_gpr(Reg::FP)) {
|
||||
if ((instr.kind == InstructionKind::LD && instr.get_dst(0).get_reg() == make_gpr(Reg::A2) &&
|
||||
instr.get_src(0).is_label() && instr.get_src(1).get_reg() == make_gpr(Reg::FP))) {
|
||||
state = 5;
|
||||
label_idx = instr.get_src(0).get_label();
|
||||
continue;
|
||||
} else if ((instr.kind == InstructionKind::LUI &&
|
||||
instr.get_dst(0).get_reg() == make_gpr(Reg::V1) && instr.get_src(0).is_label())) {
|
||||
// far labels
|
||||
state = 5;
|
||||
label_idx = instr.get_src(0).get_label();
|
||||
continue;
|
||||
|
@ -624,7 +624,9 @@ void ObjectFileDB::write_disassembly(const fs::path& output_dir,
|
||||
std::string asm_functions;
|
||||
|
||||
for_each_obj([&](ObjectFileData& obj) {
|
||||
if ((obj.obj_version == 3 && disassemble_code) || (obj.obj_version != 3 && disassemble_data)) {
|
||||
if (((obj.obj_version == 3 || (obj.obj_version == 5 && obj.linked_data.has_any_functions())) &&
|
||||
disassemble_code) ||
|
||||
(obj.obj_version != 3 && disassemble_data)) {
|
||||
auto file_text = obj.linked_data.print_disassembly(print_hex);
|
||||
asm_functions += obj.linked_data.print_asm_function_disassembly(obj.to_unique_name());
|
||||
auto file_name = output_dir / (obj.to_unique_name() + ".asm");
|
||||
|
@ -321,7 +321,7 @@ void ObjectFileDB::ir2_analyze_all_types(const fs::path& output_file,
|
||||
const std::unordered_set<std::string>& bad_types) {
|
||||
std::vector<PerObjectAllTypeInfo> per_object;
|
||||
|
||||
DecompilerTypeSystem previous_game_ts(GameVersion::Jak1); // version here doesn't matter.
|
||||
DecompilerTypeSystem previous_game_ts(GameVersion::Jak2); // version here doesn't matter.
|
||||
if (previous_game_types) {
|
||||
previous_game_ts.parse_type_defs({*previous_game_types});
|
||||
}
|
||||
@ -329,44 +329,43 @@ void ObjectFileDB::ir2_analyze_all_types(const fs::path& output_file,
|
||||
TypeInspectorCache ti_cache;
|
||||
|
||||
for_each_obj([&](ObjectFileData& data) {
|
||||
if (data.obj_version != 3) {
|
||||
return;
|
||||
}
|
||||
if (data.obj_version == 3 || (data.obj_version == 5 && data.linked_data.has_any_functions())) {
|
||||
auto& object_result = per_object.emplace_back();
|
||||
object_result.object_name = data.to_unique_name();
|
||||
|
||||
auto& object_result = per_object.emplace_back();
|
||||
object_result.object_name = data.to_unique_name();
|
||||
// Go through the top-level segment first to identify the type names associated with each
|
||||
// symbol def
|
||||
for_each_function_in_seg_in_obj(TOP_LEVEL_SEGMENT, data, [&](Function& f) {
|
||||
inspect_top_level_for_metadata(f, data.linked_data, dts, previous_game_ts, object_result);
|
||||
});
|
||||
|
||||
// Go through the top-level segment first to identify the type names associated with each symbol
|
||||
// def
|
||||
for_each_function_in_seg_in_obj(TOP_LEVEL_SEGMENT, data, [&](Function& f) {
|
||||
inspect_top_level_for_metadata(f, data.linked_data, dts, previous_game_ts, object_result);
|
||||
});
|
||||
|
||||
// Handle the top level last, which is fine as all symbol_defs are always written after typedefs
|
||||
for_each_function_def_order_in_obj(data, [&](Function& f, int seg) {
|
||||
if (seg != TOP_LEVEL_SEGMENT) {
|
||||
if (f.is_inspect_method && bad_types.find(f.guessed_name.type_name) == bad_types.end()) {
|
||||
auto deftype_from_inspect =
|
||||
inspect_inspect_method(f, f.guessed_name.type_name, dts, data.linked_data,
|
||||
previous_game_ts, ti_cache, object_result);
|
||||
bool already_seen = object_result.type_info.count(f.guessed_name.type_name) > 0;
|
||||
if (!already_seen) {
|
||||
object_result.type_names_in_order.push_back(f.guessed_name.type_name);
|
||||
// Handle the top level last, which is fine as all symbol_defs are always written after
|
||||
// typedefs
|
||||
for_each_function_def_order_in_obj(data, [&](Function& f, int seg) {
|
||||
if (seg != TOP_LEVEL_SEGMENT) {
|
||||
if (f.is_inspect_method && bad_types.find(f.guessed_name.type_name) == bad_types.end()) {
|
||||
auto deftype_from_inspect =
|
||||
inspect_inspect_method(f, f.guessed_name.type_name, dts, data.linked_data,
|
||||
previous_game_ts, ti_cache, object_result);
|
||||
bool already_seen = object_result.type_info.count(f.guessed_name.type_name) > 0;
|
||||
if (!already_seen) {
|
||||
object_result.type_names_in_order.push_back(f.guessed_name.type_name);
|
||||
}
|
||||
auto& info = object_result.type_info[f.guessed_name.type_name];
|
||||
info.from_inspect_method = true;
|
||||
info.type_definition = deftype_from_inspect;
|
||||
} else {
|
||||
// no inspect methods
|
||||
// - can we solve custom print methods in a generic way? ie `entity-links`
|
||||
}
|
||||
auto& info = object_result.type_info[f.guessed_name.type_name];
|
||||
info.from_inspect_method = true;
|
||||
info.type_definition = deftype_from_inspect;
|
||||
} else {
|
||||
// no inspect methods
|
||||
// - can we solve custom print methods in a generic way? ie `entity-links`
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
for_each_function_in_seg_in_obj(TOP_LEVEL_SEGMENT, data, [&](Function& f) {
|
||||
object_result.symbol_defs += inspect_top_level_symbol_defines(
|
||||
f, data.linked_data, dts, previous_game_ts, object_result);
|
||||
});
|
||||
for_each_function_in_seg_in_obj(TOP_LEVEL_SEGMENT, data, [&](Function& f) {
|
||||
object_result.symbol_defs += inspect_top_level_symbol_defines(
|
||||
f, data.linked_data, dts, previous_game_ts, object_result);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
std::string result;
|
||||
@ -1180,7 +1179,7 @@ bool ObjectFileDB::lookup_function_type(const FunctionName& name,
|
||||
std::string ObjectFileDB::ir2_final_out(ObjectFileData& data,
|
||||
const std::vector<std::string>& imports,
|
||||
const std::unordered_set<std::string>& skip_functions) {
|
||||
if (data.obj_version == 3) {
|
||||
if (data.obj_version == 3 || (data.obj_version == 5 && data.linked_data.has_any_functions())) {
|
||||
std::string result;
|
||||
result += ";;-*-Lisp-*-\n";
|
||||
result += "(in-package goal)\n\n";
|
||||
|
@ -5,6 +5,11 @@
|
||||
|
||||
namespace decompiler {
|
||||
|
||||
// types with duplicate inspects
|
||||
static const std::vector<std::string> g_duplicate_inspects_jak3 = {
|
||||
"sky-vertex", "shadow-edge", "hfrag-poly4", "hfrag-poly9",
|
||||
"hfrag-poly25", "hfrag-mip-packet", "sprite-aux-list", "game-save"};
|
||||
|
||||
bool is_set_reg_to_int(AtomicOp* op, Register dst, s64 value) {
|
||||
// should be a set reg to int math 2 ir
|
||||
auto set = dynamic_cast<SetVarOp*>(op);
|
||||
@ -186,33 +191,63 @@ std::optional<u64> get_set_reg_to_u64_load(AtomicOp* op,
|
||||
const LinkedObjectFile& file) {
|
||||
auto lvo = dynamic_cast<LoadVarOp*>(op);
|
||||
if (!lvo) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// destination should be a register
|
||||
auto dest = lvo->get_set_destination();
|
||||
if (dst != dest.reg()) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (lvo->src().kind() != SimpleExpression::Kind::IDENTITY) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (lvo->size() != 8) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto& s = lvo->src().get_arg(0);
|
||||
if (!s.is_label()) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
auto lab = file.labels.at(s.label());
|
||||
|
||||
auto& low = file.words_by_seg.at(lab.target_segment).at(lab.offset / 4);
|
||||
auto& hi = file.words_by_seg.at(lab.target_segment).at((lab.offset / 4) + 1);
|
||||
if (low.kind() != LinkedWord::PLAIN_DATA || hi.kind() != LinkedWord::PLAIN_DATA) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
return ((u64)low.data) | (((u64)hi.data) << 32);
|
||||
}
|
||||
|
||||
std::optional<u64> get_set_reg_to_lui(AtomicOp* op, Register dst, const LinkedObjectFile& file) {
|
||||
auto lvo = dynamic_cast<SetVarOp*>(op);
|
||||
if (!lvo) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// destination should be a register
|
||||
auto dest = lvo->get_set_destination();
|
||||
if (dst != dest.reg()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (lvo->src().kind() != SimpleExpression::Kind::IDENTITY) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto& s = lvo->src().get_arg(0);
|
||||
if (!s.is_label()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto lab = file.labels.at(s.label());
|
||||
|
||||
auto& low = file.words_by_seg.at(lab.target_segment).at(lab.offset / 4);
|
||||
auto& hi = file.words_by_seg.at(lab.target_segment).at((lab.offset / 4) + 1);
|
||||
if (low.kind() != LinkedWord::PLAIN_DATA || hi.kind() != LinkedWord::PLAIN_DATA) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return ((u64)low.data) | (((u64)hi.data) << 32);
|
||||
}
|
||||
@ -246,13 +281,23 @@ std::optional<std::string> get_string_loaded_to_reg(AtomicOp* op,
|
||||
}
|
||||
|
||||
struct FieldPrint {
|
||||
static constexpr int NO_ARR = -1;
|
||||
static constexpr int DYNAMIC_ARRAY = -2;
|
||||
static constexpr int UNKNOWN_ARR_SIZE = -3;
|
||||
|
||||
char format = '\0';
|
||||
std::string field_name;
|
||||
std::string field_type_name;
|
||||
bool has_array = false;
|
||||
int array_size = -1;
|
||||
int array_size = NO_ARR;
|
||||
};
|
||||
|
||||
// if a field has a weird inspect, just return the FieldPrint instead of asserting,
|
||||
// there's too many edge cases in custom prints to account for all of them
|
||||
FieldPrint handle_custom_prints(FieldPrint& fp, const std::string& str) {
|
||||
return fp;
|
||||
}
|
||||
|
||||
FieldPrint get_field_print(const std::string& str) {
|
||||
int idx = 0;
|
||||
auto next = [&]() { return str.at(idx++); };
|
||||
@ -272,7 +317,10 @@ FieldPrint get_field_print(const std::string& str) {
|
||||
|
||||
// next the name:
|
||||
char name_char = next();
|
||||
while (name_char != ':' && name_char != '[') {
|
||||
if (name_char == '~') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
while (name_char != ':' && name_char != '[' && name_char != ' ') {
|
||||
field_print.field_name.push_back(name_char);
|
||||
name_char = next();
|
||||
}
|
||||
@ -281,6 +329,18 @@ FieldPrint get_field_print(const std::string& str) {
|
||||
if (name_char == '[') {
|
||||
int size = 0;
|
||||
char num_char = next();
|
||||
|
||||
// dynamic array using a ~D print
|
||||
// (format "~Tstack[~D] @ #x~X~%" (-> obj allocated-length) (-> obj stack))
|
||||
if (num_char == '~') {
|
||||
num_char = next();
|
||||
ASSERT(num_char == 'D');
|
||||
num_char = next();
|
||||
ASSERT(num_char == ']');
|
||||
// distinguish from dynamic arrays that are set to size 0
|
||||
field_print.array_size = size = FieldPrint::DYNAMIC_ARRAY;
|
||||
}
|
||||
|
||||
while (num_char >= '0' && num_char <= '9') {
|
||||
size = size * 10 + (num_char - '0');
|
||||
num_char = next();
|
||||
@ -290,30 +350,68 @@ FieldPrint get_field_print(const std::string& str) {
|
||||
|
||||
ASSERT(num_char == ']');
|
||||
char c = next();
|
||||
ASSERT(c == ' ');
|
||||
// (method 3 array) and some others have a colon instead of a space here
|
||||
if (c == ':') {
|
||||
c = next();
|
||||
}
|
||||
if (c != ' ') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
c = next();
|
||||
ASSERT(c == '@');
|
||||
if (c != '@') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
c = next();
|
||||
ASSERT(c == ' ');
|
||||
if (c != ' ') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
c = next();
|
||||
ASSERT(c == '#');
|
||||
if (c != '#') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
c = next();
|
||||
ASSERT(c == 'x');
|
||||
if (c != 'x') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
} else {
|
||||
// next a space
|
||||
char space_char = next();
|
||||
ASSERT(space_char == ' ');
|
||||
if (space_char != ' ') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
}
|
||||
|
||||
// next the format
|
||||
char fmt1 = next();
|
||||
// if there are extra spaces
|
||||
if (fmt1 == ' ') {
|
||||
while (fmt1 == ' ') {
|
||||
fmt1 = next();
|
||||
}
|
||||
}
|
||||
if (fmt1 == '~' && peek(0) != '`') { // normal ~_~%
|
||||
char fmt_code = next();
|
||||
field_print.format = fmt_code;
|
||||
char end1 = next();
|
||||
ASSERT(end1 == '~');
|
||||
if (end1 != '~') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
char end2 = next();
|
||||
ASSERT(end2 == '%');
|
||||
if (end2 != '%') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
ASSERT(idx == (int)str.size());
|
||||
} else if (fmt1 == '~' && (peek(0) == 'g' || peek(0) == 'G')) { // ~g~%
|
||||
char fmt_code = next();
|
||||
field_print.format = fmt_code;
|
||||
char end1 = next();
|
||||
if (end1 != '~') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
char end2 = next();
|
||||
if (end2 != '%') {
|
||||
return handle_custom_prints(field_print, str);
|
||||
}
|
||||
ASSERT(idx == (int)str.size());
|
||||
} else if (fmt1 == '#' && peek(0) == '<') { // struct #<my-struct @ #x~X>~%
|
||||
next();
|
||||
@ -331,6 +429,30 @@ FieldPrint get_field_print(const std::string& str) {
|
||||
field_print.format = 'X';
|
||||
|
||||
ASSERT(idx == (int)str.size());
|
||||
} else if (fmt1 == '#' && peek(4) == ':') { // #x~X : (enum-name
|
||||
// OR
|
||||
// #x~X : ~S~%
|
||||
if (peek(6) != '(' && peek(7) == 'S') {
|
||||
next();
|
||||
std::string expect_end = "~X : ~S~%";
|
||||
for (char i : expect_end) {
|
||||
char c = next();
|
||||
ASSERT(i == c);
|
||||
}
|
||||
field_print.format = 'X';
|
||||
} else {
|
||||
// skip to paren
|
||||
for (int i = 0; i < 7; i++) {
|
||||
next();
|
||||
}
|
||||
auto name = str.substr(idx);
|
||||
// some of these don't have the enum name
|
||||
if (!name.empty()) {
|
||||
name.pop_back();
|
||||
field_print.field_type_name = name;
|
||||
}
|
||||
field_print.format = 'X';
|
||||
}
|
||||
} else if (fmt1 == '#' && peek(0) == 'x') { // #x~X~%
|
||||
next();
|
||||
std::string expect_end = "~X~%";
|
||||
@ -364,17 +486,31 @@ FieldPrint get_field_print(const std::string& str) {
|
||||
}
|
||||
|
||||
else {
|
||||
throw std::runtime_error("other format nyi in get_field_print " + str.substr(idx));
|
||||
// throw std::runtime_error("other format nyi in get_field_print " + str.substr(idx));
|
||||
lg::print("other format nyi in get_field_print {}\n", str.substr(idx));
|
||||
}
|
||||
|
||||
return field_print;
|
||||
}
|
||||
|
||||
int get_start_idx_process(Function& function, const std::string& parent_type, Env& env) {
|
||||
int get_start_idx_process(Function& function,
|
||||
const std::string& parent_type,
|
||||
Env& env,
|
||||
TypeInspectorResult* result) {
|
||||
// hack
|
||||
if (function.name() == "(method 3 process-tree)" || function.name() == "(method 3 process)") {
|
||||
result->is_basic = true;
|
||||
return 7;
|
||||
}
|
||||
|
||||
if (parent_type == "process-focusable") {
|
||||
result->is_basic = true;
|
||||
}
|
||||
|
||||
if (function.basic_blocks.size() != 5) {
|
||||
lg::print("[iim] inspect {} had {} basic blocks, expected 5\n", function.name(),
|
||||
function.basic_blocks.size());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!function.ir2.atomic_ops) {
|
||||
@ -475,12 +611,27 @@ L2:
|
||||
}
|
||||
op_idx++;
|
||||
|
||||
if (!is_set_reg_to_symbol_value(aos.ops.at(op_idx).get(), Register(Reg::GPR, Reg::V1),
|
||||
parent_type)) {
|
||||
lg::print("[iim] op5 bad in {}: {} (bad set parent type)\n", aos.ops.at(op_idx)->to_string(env),
|
||||
function.name());
|
||||
return -1;
|
||||
// try to determine parent type for far labels
|
||||
if (parent_type == "UNKNOWN") {
|
||||
auto parent_op_str = aos.ops.at(op_idx)->to_string(env);
|
||||
auto parent_type_str = parent_op_str.substr(9);
|
||||
parent_type_str.pop_back();
|
||||
result->parent_type_name = parent_type_str;
|
||||
} else {
|
||||
if (!is_set_reg_to_symbol_value(aos.ops.at(op_idx).get(), Register(Reg::GPR, Reg::V1),
|
||||
parent_type)) {
|
||||
lg::print("[iim] op5 bad in {}: {} (bad set parent type)\n",
|
||||
aos.ops.at(op_idx)->to_string(env), function.name());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO check if this catches all cases or if there are false positives
|
||||
// hack to get correct field offsets for children of process
|
||||
if (result->parent_type_name != "structure") {
|
||||
result->is_basic = true;
|
||||
}
|
||||
|
||||
op_idx++;
|
||||
|
||||
if (aos.ops.at(op_idx).get()->to_string(env) != "(set! t9 (l.wu (+ v1 28)))") {
|
||||
@ -536,12 +687,15 @@ L3:
|
||||
int get_start_idx(Function& function,
|
||||
LinkedObjectFile& file,
|
||||
TypeInspectorResult* result,
|
||||
const std::string& /*parent_type*/,
|
||||
const std::string& parent_type,
|
||||
const std::string& type_name,
|
||||
Env& env) {
|
||||
if (function.basic_blocks.size() != 5) {
|
||||
lg::print("[iim] inspect {} had {} basic blocks, expected 5\n", function.name(),
|
||||
function.basic_blocks.size());
|
||||
if (parent_type == "basic") {
|
||||
result->is_basic = true;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -673,7 +827,9 @@ int get_start_idx(Function& function,
|
||||
|
||||
if (is_set_reg_to_symbol_ptr(aos.ops.at(op_idx).get(), Register(Reg::GPR, Reg::A3), type_name)) {
|
||||
result->is_basic = false;
|
||||
} else if (aos.ops.at(op_idx)->to_string(env) == "(set! a3 (l.wu (+ gp -4)))") {
|
||||
} else if (aos.ops.at(op_idx)->to_string(env) == "(set! a3 (l.wu (+ gp -4)))" ||
|
||||
aos.ops.at(op_idx)->to_string(env) == "(set! a3-0 (l.wu (+ a0-0 -4)))" ||
|
||||
aos.ops.at(op_idx)->to_string(env) == "(set! a3-0 (l.wu (+ obj -4)))") {
|
||||
result->is_basic = true;
|
||||
} else {
|
||||
lg::print("[iim] op 9 bad in {}: {}\n", aos.ops.at(op_idx)->to_string(env), function.name());
|
||||
@ -877,9 +1033,24 @@ int identify_array_field(int idx,
|
||||
Function& function,
|
||||
TypeInspectorResult* result,
|
||||
FieldPrint& print_info) {
|
||||
auto& get_op = function.ir2.atomic_ops->ops.at(idx++);
|
||||
AtomicOp* get_op;
|
||||
// dynamic array with ~D inspect print
|
||||
if (print_info.array_size == FieldPrint::DYNAMIC_ARRAY) {
|
||||
idx++;
|
||||
get_op = function.ir2.atomic_ops->ops.at(idx).get();
|
||||
} else {
|
||||
get_op = function.ir2.atomic_ops->ops.at(idx++).get();
|
||||
}
|
||||
int offset = 0;
|
||||
if (!get_ptr_offset(get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP), &offset)) {
|
||||
|
||||
bool ptr;
|
||||
if (print_info.array_size == FieldPrint::DYNAMIC_ARRAY) {
|
||||
ptr = get_ptr_offset(get_op, make_gpr(Reg::A3), make_gpr(Reg::GP), &offset);
|
||||
} else {
|
||||
ptr = get_ptr_offset(get_op, make_gpr(Reg::A2), make_gpr(Reg::GP), &offset);
|
||||
}
|
||||
|
||||
if (!ptr) {
|
||||
printf("bad get ptr offset %s\n", get_op->to_string(function.ir2.env).c_str());
|
||||
ASSERT(false);
|
||||
}
|
||||
@ -888,7 +1059,7 @@ int identify_array_field(int idx,
|
||||
}
|
||||
|
||||
Field field(print_info.field_name, TypeSpec("UNKNOWN"), offset);
|
||||
if (print_info.array_size) {
|
||||
if (print_info.array_size > 0) {
|
||||
field.set_array(print_info.array_size);
|
||||
} else {
|
||||
field.set_dynamic();
|
||||
@ -904,7 +1075,7 @@ int identify_struct_not_inline_field(int idx,
|
||||
auto load_info = get_load_info_from_set(function.ir2.atomic_ops->ops.at(idx++).get());
|
||||
|
||||
if (!(load_info.size == 4 && load_info.kind == LoadVarOp::Kind::UNSIGNED)) {
|
||||
result->warnings += "field " + print_info.field_type_name + " is likely a value type";
|
||||
result->warnings += "field " + print_info.field_type_name + " is likely a value type. ";
|
||||
}
|
||||
int offset = load_info.offset;
|
||||
if (result->is_basic) {
|
||||
@ -924,7 +1095,7 @@ int identify_struct_inline_field(int idx,
|
||||
int offset = 0;
|
||||
if (!get_ptr_offset(get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP), &offset)) {
|
||||
printf("bad get ptr offset %s\n", get_op->to_string(function.ir2.env).c_str());
|
||||
ASSERT(false);
|
||||
// ASSERT(false);
|
||||
}
|
||||
if (result->is_basic) {
|
||||
offset += BASIC_OFFSET;
|
||||
@ -946,12 +1117,12 @@ int identify_basic_field(int idx,
|
||||
ASSERT(load_info.kind == LoadVarOp::Kind::UNSIGNED || load_info.kind == LoadVarOp::Kind::SIGNED);
|
||||
TypeSpec field_type("basic");
|
||||
if (load_info.size == 8) {
|
||||
result->warnings += "field " + print_info.field_name + " uses ~A with a 64-bit load ";
|
||||
result->warnings += "field " + print_info.field_name + " uses ~A with a 64-bit load. ";
|
||||
field_type = TypeSpec("uint64");
|
||||
} else if (load_info.size == 4) {
|
||||
// I wonder if this actually "object", or some other type? It seems to be
|
||||
if (load_info.kind == LoadVarOp::Kind::SIGNED) {
|
||||
result->warnings += "field " + print_info.field_name + " uses ~A with a signed load ";
|
||||
result->warnings += "field " + print_info.field_name + " uses ~A with a signed load. ";
|
||||
}
|
||||
} else {
|
||||
ASSERT(false);
|
||||
@ -967,9 +1138,79 @@ int identify_basic_field(int idx,
|
||||
return idx;
|
||||
}
|
||||
|
||||
int identify_string_field(int idx,
|
||||
Function& function,
|
||||
LinkedObjectFile& file,
|
||||
TypeInspectorResult* result,
|
||||
FieldPrint& print_info) {
|
||||
(void)file;
|
||||
auto load_info = get_load_info_from_set(function.ir2.atomic_ops->ops.at(idx++).get());
|
||||
ASSERT(load_info.kind == LoadVarOp::Kind::UNSIGNED || load_info.kind == LoadVarOp::Kind::SIGNED);
|
||||
TypeSpec field_type("string");
|
||||
if (load_info.size == 8) {
|
||||
result->warnings += "field " + print_info.field_name + " uses ~S with a 64-bit load. ";
|
||||
field_type = TypeSpec("uint64");
|
||||
} else if (load_info.size == 4) {
|
||||
// I wonder if this actually "object", or some other type? It seems to be
|
||||
if (load_info.kind == LoadVarOp::Kind::SIGNED) {
|
||||
result->warnings += "field " + print_info.field_name + " uses ~S with a signed load. ";
|
||||
}
|
||||
} else {
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
int offset = load_info.offset;
|
||||
if (result->is_basic) {
|
||||
offset += BASIC_OFFSET;
|
||||
}
|
||||
|
||||
Field field(print_info.field_name, field_type, offset);
|
||||
result->fields_of_type.push_back(field);
|
||||
return idx;
|
||||
}
|
||||
|
||||
int identify_cstring_field(int idx,
|
||||
Function& function,
|
||||
LinkedObjectFile& file,
|
||||
TypeInspectorResult* result,
|
||||
FieldPrint& print_info) {
|
||||
(void)file;
|
||||
auto& get_op = function.ir2.atomic_ops->ops.at(idx++);
|
||||
// assuming unknown array size at first
|
||||
int size = FieldPrint::UNKNOWN_ARR_SIZE;
|
||||
int offset = 0;
|
||||
std::string comment;
|
||||
|
||||
// usually either a daddiu or lq
|
||||
if (!get_ptr_offset(get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP), &offset)) {
|
||||
// daddiu failed, try lq
|
||||
auto load_info = get_load_info_from_set(get_op.get());
|
||||
if (load_info.size == 16) {
|
||||
size = 16;
|
||||
offset = load_info.offset;
|
||||
comment = "field uses ~g print with a quadword load!";
|
||||
} else {
|
||||
printf("bad get ptr offset %s\n", get_op->to_string(function.ir2.env).c_str());
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
if (result->is_basic) {
|
||||
offset += BASIC_OFFSET;
|
||||
}
|
||||
|
||||
Field field(print_info.field_name, TypeSpec("uint8"), offset);
|
||||
field.set_array(size);
|
||||
if (!comment.empty()) {
|
||||
field.set_comment(comment);
|
||||
}
|
||||
result->fields_of_type.push_back(field);
|
||||
return idx;
|
||||
}
|
||||
|
||||
int detect(int idx, Function& function, LinkedObjectFile& file, TypeInspectorResult* result) {
|
||||
auto& get_format_op = function.ir2.atomic_ops->ops.at(idx++);
|
||||
if (!is_set_reg_to_symbol_value(get_format_op.get(), make_gpr(Reg::T9), "format")) {
|
||||
return idx;
|
||||
ASSERT_MSG(false,
|
||||
fmt::format("bad get format: {}\n", get_format_op->to_string(function.ir2.env)));
|
||||
}
|
||||
@ -985,13 +1226,35 @@ int detect(int idx, Function& function, LinkedObjectFile& file, TypeInspectorRes
|
||||
ASSERT_MSG(false, "bad sstr");
|
||||
}
|
||||
|
||||
// hack to ignore format print from enum->string and other unexpected stuff
|
||||
if (sstr->substr(0, 1) != "~" || sstr == "~T [~D]~2Tactor-group: ~`actor-group`P~%" ||
|
||||
sstr == "~T [~D]~2Tbuffer: ~A~%") {
|
||||
return idx;
|
||||
}
|
||||
|
||||
auto info = get_field_print(*sstr);
|
||||
|
||||
auto& first_get_op = function.ir2.atomic_ops->ops.at(idx);
|
||||
|
||||
if (is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP)) &&
|
||||
(info.format == 'D' || info.format == 'X' || info.format == 'e') && !info.has_array &&
|
||||
info.field_type_name.empty()) {
|
||||
// v1 load (process pointer):
|
||||
// lw t9, format(s7)
|
||||
// daddiu a0, s7, #t
|
||||
// daddiu a1, fp, L389
|
||||
// lwu v1, 12(gp)
|
||||
// beq s7, v1, L281
|
||||
// or a2, s7, r0
|
||||
// B1:
|
||||
// lwu v1, 0(v1)
|
||||
// lwu a2, 28(v1)
|
||||
// B2:
|
||||
// L281:
|
||||
// jalr ra, t9
|
||||
auto load_a2_gp = is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP));
|
||||
auto load_v1_gp = is_get_load(first_get_op.get(), make_gpr(Reg::V1), make_gpr(Reg::GP));
|
||||
|
||||
if ((load_a2_gp || load_v1_gp) &&
|
||||
(info.format == 'D' || info.format == 'd' || info.format == 'X' || info.format == 'e') &&
|
||||
!info.has_array && info.field_type_name.empty()) {
|
||||
idx = identify_int_field(idx, function, result, info);
|
||||
// it's a load!
|
||||
} else if (is_get_load(first_get_op.get(), make_fpr(0), make_gpr(Reg::GP)) &&
|
||||
@ -999,11 +1262,17 @@ int detect(int idx, Function& function, LinkedObjectFile& file, TypeInspectorRes
|
||||
info.format == 'X') &&
|
||||
!info.has_array && info.field_type_name.empty()) {
|
||||
idx = identify_float_field(idx, function, result, info);
|
||||
} else if (is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP)) &&
|
||||
info.format == 'A' && !info.has_array && info.field_type_name.empty()) {
|
||||
} else if ((load_a2_gp || load_v1_gp) && info.format == 'A' && !info.has_array &&
|
||||
info.field_type_name.empty()) {
|
||||
idx = identify_basic_field(idx, function, file, result, info);
|
||||
} else if (is_get_load(first_get_op.get(), make_gpr(Reg::A2), make_gpr(Reg::GP)) &&
|
||||
info.format == 'X' && !info.has_array && info.field_type_name.empty()) {
|
||||
} else if ((load_a2_gp || load_v1_gp) && info.format == 'S' && !info.has_array &&
|
||||
info.field_type_name.empty()) {
|
||||
idx = identify_string_field(idx, function, file, result, info);
|
||||
} else if ((load_a2_gp || load_v1_gp) && (info.format == 'G' || info.format == 'g') &&
|
||||
!info.has_array && info.field_type_name.empty()) {
|
||||
idx = identify_cstring_field(idx, function, file, result, info);
|
||||
} else if ((load_a2_gp || load_v1_gp) && info.format == 'X' && !info.has_array &&
|
||||
info.field_type_name.empty()) {
|
||||
idx = identify_pointer_field(idx, function, result, info);
|
||||
} else if (info.has_array && (info.format == 'X' || info.format == 'P') &&
|
||||
info.field_type_name.empty()) {
|
||||
@ -1020,14 +1289,51 @@ int detect(int idx, Function& function, LinkedObjectFile& file, TypeInspectorRes
|
||||
}
|
||||
|
||||
else {
|
||||
printf("couldn't do %s, %s\n", sstr->c_str(),
|
||||
printf("couldn't do %s, %s, adding unknown field\n", sstr->c_str(),
|
||||
first_get_op->to_string(function.ir2.env).c_str());
|
||||
return -1;
|
||||
// if all else fails, create an unknown field so the rest of the inspect can pass.
|
||||
Field unknown("UNKNOWN", TypeSpec("UNKNOWN"), -1);
|
||||
unknown.set_comment("field could not be read.");
|
||||
result->fields_of_type.push_back(unknown);
|
||||
return idx;
|
||||
}
|
||||
|
||||
if (!dynamic_cast<CallOp*>(function.ir2.atomic_ops->ops.at(idx++).get())) {
|
||||
CallOp* call_op;
|
||||
if (load_v1_gp) {
|
||||
call_op = dynamic_cast<CallOp*>(function.ir2.atomic_ops->ops.at(idx = idx + 3).get());
|
||||
} else {
|
||||
// dynamic array with ~D inspect print
|
||||
if (info.array_size == FieldPrint::DYNAMIC_ARRAY) {
|
||||
idx++;
|
||||
call_op = dynamic_cast<CallOp*>(function.ir2.atomic_ops->ops.at(idx++).get());
|
||||
} else {
|
||||
call_op = dynamic_cast<CallOp*>(function.ir2.atomic_ops->ops.at(idx++).get());
|
||||
}
|
||||
}
|
||||
|
||||
// inspect strings like "#x~X : ~S~%" load the field twice, once into a2, then into v1,
|
||||
// then have a bunch of string branches, so we just skip this, since we already have the field.
|
||||
//
|
||||
// lw t9, format(s7) ;; [218] (set! t9 format)
|
||||
// daddiu a0, s7, #t ;; [219] (set! a0 #t)
|
||||
// daddiu a1, fp, L503 ;; [220] (set! a1 L503) "~1Tclass: #x~X : ~S~%"
|
||||
// lhu a2, 26(gp) ;; [221] (set! a2 (l.hu (+ gp 26)))
|
||||
// lhu v1, 26(gp) ;; [222] (set! v1 (l.hu (+ gp 26)))
|
||||
// addiu a3, r0, 149 ;; [223] (set! a3 149)
|
||||
// bne v1, a3, L70 ;; [224] (b! (!= v1 a3) L70 (nop!))
|
||||
// sll r0, r0, 0
|
||||
|
||||
if (load_a2_gp) {
|
||||
auto load_v1_gp_again = is_get_load(function.ir2.atomic_ops->ops.at(idx - 1).get(),
|
||||
make_gpr(Reg::V1), make_gpr(Reg::GP));
|
||||
if (load_v1_gp_again) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (!call_op) {
|
||||
printf("bad call\n");
|
||||
ASSERT(false);
|
||||
// ASSERT(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1053,6 +1359,13 @@ std::string inspect_inspect_method(Function& inspect_method,
|
||||
result.type_size = flags.size;
|
||||
result.type_method_count = flags.methods;
|
||||
|
||||
// ignore duplicate inspects
|
||||
if (ti_cache.previous_results.find(type_name) != ti_cache.previous_results.end() &&
|
||||
!(std::find(g_duplicate_inspects_jak3.begin(), g_duplicate_inspects_jak3.end(), type_name) !=
|
||||
g_duplicate_inspects_jak3.end())) {
|
||||
return fmt::format(";; {} is already defined!\n", type_name);
|
||||
}
|
||||
|
||||
// Only set heap-base if it's different from the automatic one
|
||||
// A child (or child of a child) of process ALWAYS has heap-base set.
|
||||
if (flags.heap_base > 0) {
|
||||
@ -1081,7 +1394,8 @@ std::string inspect_inspect_method(Function& inspect_method,
|
||||
inspect_method.ir2.env);
|
||||
|
||||
if (idx < 0) {
|
||||
idx = get_start_idx_process(inspect_method, result.parent_type_name, inspect_method.ir2.env);
|
||||
idx = get_start_idx_process(inspect_method, result.parent_type_name, inspect_method.ir2.env,
|
||||
&result);
|
||||
}
|
||||
StructureType* old_game_type = nullptr;
|
||||
if (previous_game_ts.ts.fully_defined_type_exists(type_name)) {
|
||||
@ -1096,6 +1410,12 @@ std::string inspect_inspect_method(Function& inspect_method,
|
||||
object_file_meta);
|
||||
}
|
||||
while (idx < int(inspect_method.ir2.atomic_ops->ops.size()) - 2 && idx != -1) {
|
||||
// skip over non-format calls in inspects
|
||||
auto sstr = inspect_method.ir2.atomic_ops->ops.at(idx)->to_string(inspect_method.ir2.env);
|
||||
if (sstr.substr(sstr.size() - 7) != "format)") {
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
idx = detect(idx, inspect_method, file, &result);
|
||||
}
|
||||
|
||||
@ -1158,7 +1478,7 @@ bool allow_guess(const Field& field) {
|
||||
std::string TypeInspectorResult::print_as_deftype(
|
||||
StructureType* old_game_type,
|
||||
std::unordered_map<std::string, TypeInspectorResult>& previous_results,
|
||||
DecompilerTypeSystem& /*previous_game_ts*/,
|
||||
DecompilerTypeSystem& previous_game_ts,
|
||||
ObjectFileDB::PerObjectAllTypeInfo& object_file_meta) {
|
||||
std::string result;
|
||||
|
||||
@ -1216,7 +1536,12 @@ std::string TypeInspectorResult::print_as_deftype(
|
||||
int mods = 0;
|
||||
// mods are array size, :inline, :dynamic
|
||||
if (field.is_array() && !field.is_dynamic()) {
|
||||
mods += std::to_string(field.array_size()).size();
|
||||
// "??" for unknown array size
|
||||
if (field.array_size() == FieldPrint::UNKNOWN_ARR_SIZE) {
|
||||
mods += 2;
|
||||
} else {
|
||||
mods += std::to_string(field.array_size()).size();
|
||||
}
|
||||
}
|
||||
|
||||
if (field.is_inline()) {
|
||||
@ -1248,8 +1573,13 @@ std::string TypeInspectorResult::print_as_deftype(
|
||||
|
||||
std::string mods;
|
||||
if (field.is_array() && !field.is_dynamic()) {
|
||||
mods += std::to_string(field.array_size());
|
||||
mods += " ";
|
||||
if (field.array_size() == FieldPrint::UNKNOWN_ARR_SIZE) {
|
||||
mods += "??";
|
||||
mods += " ";
|
||||
} else {
|
||||
mods += std::to_string(field.array_size());
|
||||
mods += " ";
|
||||
}
|
||||
}
|
||||
|
||||
if (field.is_inline()) {
|
||||
@ -1284,6 +1614,9 @@ std::string TypeInspectorResult::print_as_deftype(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (field.has_comment()) {
|
||||
result += fmt::format(" ;; {}", field.comment());
|
||||
}
|
||||
|
||||
if (was_guess[field_idx]) {
|
||||
result += " ;; guessed by decompiler";
|
||||
@ -1337,21 +1670,21 @@ std::string TypeInspectorResult::print_as_deftype(
|
||||
// Print out states if we have em
|
||||
// - Could probably assume the process name comes first and associate it with the right type
|
||||
// but that may or may not be risky so, edit the types yourself...
|
||||
// if (method_states.size() > 0) {
|
||||
// result.append("(:states\n ");
|
||||
// for (const auto& [id, name] : method_states) {
|
||||
// result.append(name);
|
||||
// // Append old symbol def if we have it
|
||||
// auto it = previous_game_ts.symbol_types.find(name);
|
||||
// if (it != previous_game_ts.symbol_types.end()) {
|
||||
// result.append(fmt::format(" ;; {}", it->second.print()));
|
||||
// }
|
||||
// // Add symbol name to `already_seen_symbols`
|
||||
// object_file_meta.already_seen_symbols.insert(name);
|
||||
// result.append("\n ");
|
||||
// }
|
||||
// result.append(")\n ");
|
||||
//}
|
||||
if (method_states.size() > 0) {
|
||||
result.append("(:states\n ");
|
||||
for (const auto& [id, name] : method_states) {
|
||||
result.append(name);
|
||||
// Append old symbol def if we have it
|
||||
auto it = previous_game_ts.symbol_types.find(name);
|
||||
if (it != previous_game_ts.symbol_types.end()) {
|
||||
result.append(fmt::format(" ;; {}", it->second.print()));
|
||||
}
|
||||
// Add symbol name to `already_seen_symbols`
|
||||
object_file_meta.already_seen_symbols.insert(name);
|
||||
result.append("\n ");
|
||||
}
|
||||
result.append(")\n ");
|
||||
}
|
||||
|
||||
result.append(")\n");
|
||||
result += "|#\n";
|
||||
@ -1359,7 +1692,7 @@ std::string TypeInspectorResult::print_as_deftype(
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string get_regex_match(std::string form, std::regex regex) {
|
||||
std::string get_regex_match(const std::string& form, const std::regex& regex) {
|
||||
std::smatch matches;
|
||||
if (std::regex_search(form, matches, regex)) {
|
||||
if (matches.size() == 2) {
|
||||
@ -1369,7 +1702,7 @@ std::string get_regex_match(std::string form, std::regex regex) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string get_state_symbol_name(LinkedObjectFile& file, std::string label_name) {
|
||||
std::string get_state_symbol_name(LinkedObjectFile& file, const std::string& label_name) {
|
||||
try {
|
||||
auto& label = file.get_label_by_name(label_name);
|
||||
auto& label_words = file.words_by_seg.at(label.target_segment);
|
||||
@ -1391,7 +1724,7 @@ std::string get_state_symbol_name(LinkedObjectFile& file, std::string label_name
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_label_type_name(LinkedObjectFile& file, std::string label_name) {
|
||||
std::string get_label_type_name(LinkedObjectFile& file, const std::string& label_name) {
|
||||
try {
|
||||
auto& label = file.get_label_by_name(label_name);
|
||||
auto& label_words = file.words_by_seg.at(label.target_segment);
|
||||
@ -1433,7 +1766,7 @@ void inspect_top_level_for_metadata(Function& top_level,
|
||||
}
|
||||
|
||||
// Check for non-method states
|
||||
std::string last_seen_label = "";
|
||||
std::string last_seen_label;
|
||||
// TODO - safely increment op number
|
||||
for (int i = 0; i < (int)top_level.ir2.atomic_ops->ops.size(); i++) {
|
||||
const auto& aop = top_level.ir2.atomic_ops->ops.at(i);
|
||||
@ -1521,13 +1854,25 @@ void inspect_top_level_for_metadata(Function& top_level,
|
||||
const auto& aop_4 = top_level.ir2.atomic_ops->ops.at(i + 4);
|
||||
auto flags = get_set_reg_to_u64_load(aop_4.get(), Register(Reg::GPR, Reg::A2), file);
|
||||
if (!flags) {
|
||||
continue;
|
||||
// far label load
|
||||
// lui v1, L1352 ;; [ 24] (set! v1-10 L1352)
|
||||
// ori v1, v1, L1352
|
||||
// addu v1, fp, v1
|
||||
// ld a2, 0(v1) ;; [ 25] (set! a2-0 (l.d v1-10))
|
||||
flags = get_set_reg_to_lui(aop_4.get(), Register(Reg::GPR, Reg::V1), file);
|
||||
if (!flags) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// jalr ra, t9 ;; [ 25] (call! a0-0 a1-0 a2-0)
|
||||
const auto& aop_5 = top_level.ir2.atomic_ops->ops.at(i + 5);
|
||||
if (!dynamic_cast<CallOp*>(aop_5.get())) {
|
||||
continue;
|
||||
// far labels
|
||||
const auto& aop_6 = top_level.ir2.atomic_ops->ops.at(i + 6);
|
||||
if (!dynamic_cast<CallOp*>(aop_6.get())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (objectFile.type_info.count(*type_name) == 0) {
|
||||
|
@ -1795,6 +1795,7 @@ std::unique_ptr<AtomicOp> convert_5(const Instruction& i0,
|
||||
process_offset = 44;
|
||||
break;
|
||||
case GameVersion::Jak2:
|
||||
case GameVersion::Jak3:
|
||||
process_offset = 48;
|
||||
break;
|
||||
default:
|
||||
|
@ -1569,6 +1569,7 @@ Form* try_sc_as_type_of(FormPool& pool, Function& f, const ShortCircuit* vtx, Ga
|
||||
case GameVersion::Jak1:
|
||||
return try_sc_as_type_of_jak1(pool, f, vtx);
|
||||
case GameVersion::Jak2:
|
||||
case GameVersion::Jak3:
|
||||
return try_sc_as_type_of_jak2(pool, f, vtx);
|
||||
default:
|
||||
ASSERT(false);
|
||||
|
@ -25,7 +25,7 @@ nlohmann::json read_json_file_from_config(const nlohmann::json& json, const std:
|
||||
Config make_config_via_json(nlohmann::json& json) {
|
||||
Config config;
|
||||
int version_int = json.at("game_version").get<int>();
|
||||
ASSERT(version_int == 1 || version_int == 2);
|
||||
ASSERT(version_int == 1 || version_int == 2 || version_int == 3);
|
||||
config.game_version = (GameVersion)version_int;
|
||||
config.text_version = json.at("text_version").get<GameTextVersion>();
|
||||
config.game_name = json.at("game_name").get<std::string>();
|
||||
|
@ -26,5 +26,671 @@
|
||||
(define-extern stack-frame type)
|
||||
(define-extern global kheap)
|
||||
(define-extern kheap type)
|
||||
(define-extern pointer type)
|
||||
|
||||
(define-extern #t symbol)
|
||||
(define-extern #t symbol)
|
||||
(define-extern #f symbol)
|
||||
|
||||
;; some types we need.
|
||||
(declare-type sparticle-launch-group basic)
|
||||
(declare-type lightning-spec basic)
|
||||
(declare-type sparticle-launcher basic)
|
||||
(declare-type state basic)
|
||||
(declare-type res-lump basic)
|
||||
|
||||
;; kernel types
|
||||
(defenum link-flag
|
||||
:bitfield #t
|
||||
:type int32
|
||||
(output-load-msg 0)
|
||||
(output-load-true-msg 1)
|
||||
(execute-login 2)
|
||||
(print-login 3)
|
||||
(force-debug 4)
|
||||
(fast-link 5)
|
||||
)
|
||||
|
||||
(defenum language-enum
|
||||
:type int64
|
||||
(english)
|
||||
(french)
|
||||
(german)
|
||||
(spanish)
|
||||
(italian)
|
||||
(japanese)
|
||||
(korean)
|
||||
(uk-english)
|
||||
)
|
||||
|
||||
(define-extern *debug-segment* symbol)
|
||||
(define-extern nothing (function none))
|
||||
(define-extern _format (function _varargs_ object))
|
||||
(define-extern method-set! (function type int object none)) ;; may actually return function.
|
||||
(define-extern malloc (function symbol int pointer))
|
||||
(define-extern kmemopen (function kheap string none))
|
||||
(define-extern kmemclose (function none))
|
||||
(define-extern dgo-load (function string kheap link-flag int none))
|
||||
(define-extern *listener-function* (function object))
|
||||
(define-extern *enable-method-set* int)
|
||||
|
||||
(declare-type cpad-info basic)
|
||||
(declare-type mouse-info basic)
|
||||
(define-extern cpad-open (function cpad-info int cpad-info))
|
||||
(define-extern cpad-get-data (function cpad-info cpad-info))
|
||||
(define-extern scf-get-territory (function int)) ;; not actually a scf function...
|
||||
(define-extern mouse-get-data (function mouse-info none))
|
||||
(define-extern file-stream-open (function file-stream string symbol file-stream))
|
||||
(define-extern file-stream-close (function file-stream file-stream))
|
||||
(define-extern file-stream-length (function file-stream int))
|
||||
(define-extern file-stream-seek (function file-stream int int int))
|
||||
(define-extern file-stream-read (function file-stream pointer int int))
|
||||
(define-extern file-stream-write (function file-stream pointer uint uint))
|
||||
(define-extern reset-path (function none))
|
||||
(define-extern flush-cache (function int none))
|
||||
(define-extern gs-store-image (function object object object))
|
||||
(define-extern sync-path (function int int int))
|
||||
(define-extern file-stream-write (function file-stream pointer uint uint))
|
||||
(define-extern file-stream-close (function file-stream file-stream))
|
||||
(define-extern new-dynamic-structure (function symbol type int structure))
|
||||
(define-extern kernel-shutdown (function none))
|
||||
(define-extern scf-get-timeout (function int))
|
||||
(define-extern scf-get-inactive-timeout (function int))
|
||||
(define-extern syncv (function int int))
|
||||
(define-extern string->symbol (function string symbol))
|
||||
(define-extern link-begin (function pointer (pointer uint8) int kheap link-flag int))
|
||||
(define-extern link-resume (function int))
|
||||
(define-extern link-reset (function none))
|
||||
(define-extern kset-language (function language-enum int))
|
||||
(define-extern reset-graph (function int int int int none))
|
||||
|
||||
(declare-type sql-result basic)
|
||||
(define-extern sql-query (function string sql-result))
|
||||
|
||||
(define-extern loading-level kheap)
|
||||
(define-extern dma-sync (function pointer int int int))
|
||||
(define-extern unload (function string none))
|
||||
|
||||
|
||||
|
||||
(defenum kmalloc-flags
|
||||
:bitfield #t
|
||||
(align-16 4)
|
||||
(align-64 6)
|
||||
(align-256 8)
|
||||
(memset 12)
|
||||
(top 13)
|
||||
)
|
||||
|
||||
(define-extern kmalloc (function kheap int kmalloc-flags string pointer))
|
||||
|
||||
(define-extern *kernel-boot-message* symbol)
|
||||
(define-extern *kernel-boot-art-group* string)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; gcommon ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(deftype vec4s (uint128)
|
||||
((x float :offset 0)
|
||||
(y float :offset 32)
|
||||
(z float :offset 64)
|
||||
(w float :offset 96))
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(deftype vector (structure)
|
||||
((data float 4 :score -1 :offset-assert 0)
|
||||
(x float :offset 0)
|
||||
(y float :offset 4)
|
||||
(z float :offset 8)
|
||||
(w float :offset 12)
|
||||
(quad uint128 :offset 0 :score -1)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(deftype bfloat (basic)
|
||||
((data float :offset-assert 4)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x8
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
(deftype inline-array-class (basic)
|
||||
((length int32 :offset-assert 4)
|
||||
(allocated-length int32 :offset-assert 8)
|
||||
;; this is 16-byte aligned.
|
||||
;; children of inline-array-class should define their own data which overlays this one.
|
||||
(_data uint8 :score -50 :dynamic :offset 16)
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type int) _type_ 0))
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
(define-extern identity (function object object))
|
||||
(define-extern 1/ (function float float))
|
||||
(define-extern + (function int int int))
|
||||
(define-extern - (function int int int))
|
||||
(define-extern * (function int int int))
|
||||
(define-extern / (function int int int))
|
||||
(define-extern ash (function int int int))
|
||||
(define-extern mod (function int int int))
|
||||
(define-extern rem (function int int int))
|
||||
(define-extern abs (function int int))
|
||||
(define-extern min (function int int int))
|
||||
(define-extern max (function int int int))
|
||||
(define-extern logior (function int int int))
|
||||
(define-extern logand (function int int int))
|
||||
(define-extern lognor (function int int int))
|
||||
(define-extern logxor (function int int int))
|
||||
(define-extern lognot (function int int))
|
||||
(define-extern false-func (function symbol))
|
||||
(define-extern true-func (function symbol))
|
||||
(define-extern format (function _varargs_ object))
|
||||
(define-extern basic-type? (function basic type symbol))
|
||||
(define-extern type-type? (function type type symbol))
|
||||
(define-extern type? (function object type symbol))
|
||||
(define-extern find-parent-method (function type int function))
|
||||
(define-extern ref (function object int object))
|
||||
(define-extern last (function object object))
|
||||
(define-extern member (function object object object))
|
||||
(define-extern nmember (function basic object object))
|
||||
(define-extern assoc (function object object object))
|
||||
(define-extern assoce (function object object object))
|
||||
(define-extern nassoc (function string object object))
|
||||
(define-extern nassoce (function string object object))
|
||||
(define-extern append! (function object object object))
|
||||
(define-extern delete! (function object object pair))
|
||||
(define-extern delete-car! (function object object object))
|
||||
(define-extern insert-cons! (function object object pair))
|
||||
(define-extern sort (function pair (function object object object) pair))
|
||||
(define-extern mem-copy! (function pointer pointer int pointer))
|
||||
(define-extern qmem-copy<-! (function pointer pointer int pointer))
|
||||
(define-extern qmem-copy->! (function pointer pointer int pointer))
|
||||
(define-extern mem-set32! (function pointer int int pointer))
|
||||
(define-extern mem-or! (function pointer pointer int pointer))
|
||||
(define-extern quad-copy! (function pointer pointer int none))
|
||||
(define-extern fact (function int int))
|
||||
(define-extern *print-column* binteger)
|
||||
(define-extern print (function object object))
|
||||
(define-extern printl (function object object))
|
||||
(define-extern inspect (function object object))
|
||||
(define-extern mem-print (function (pointer uint32) int symbol))
|
||||
(define-extern *trace-list* pair)
|
||||
(define-extern print-tree-bitmask (function int int symbol))
|
||||
(define-extern breakpoint-range-set! (function uint uint uint int))
|
||||
(define-extern valid? (function object type string symbol object symbol))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; gstring-h ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; gkernel-h ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(declare-type process-tree basic)
|
||||
(declare-type process process-tree)
|
||||
(declare-type thread basic)
|
||||
(declare-type cpu-thread thread)
|
||||
(declare-type clock basic)
|
||||
(declare-type res-lump basic)
|
||||
(declare-type entity res-lump)
|
||||
(declare-type entity-actor entity)
|
||||
(declare-type event-message-block structure)
|
||||
(declare-type level basic)
|
||||
|
||||
(defenum process-mask
|
||||
:type uint32
|
||||
:bitfield #t
|
||||
(execute 0)
|
||||
(freeze 1)
|
||||
(pause 2)
|
||||
(menu 3)
|
||||
(progress 4)
|
||||
(actor-pause 5)
|
||||
(sleep 6)
|
||||
(sleep-code 7)
|
||||
(process-tree 8)
|
||||
(heap-shrunk 9)
|
||||
(going 10)
|
||||
(kernel-run 11)
|
||||
(no-kill 12)
|
||||
(movie 13)
|
||||
(dark-effect 14)
|
||||
(target 15)
|
||||
(sidekick 16)
|
||||
(crate 17)
|
||||
(bit18 18) ;; unused?
|
||||
(enemy 19)
|
||||
(camera 20)
|
||||
(platform 21)
|
||||
(ambient 22)
|
||||
(entity 23)
|
||||
(projectile 24)
|
||||
(bot 25)
|
||||
(collectable 26)
|
||||
(death 27)
|
||||
(no-track 28)
|
||||
(guard 29)
|
||||
(vehicle 30)
|
||||
(civilian 31)
|
||||
)
|
||||
(deftype process-tree (basic)
|
||||
((name string :offset-assert 4)
|
||||
(mask process-mask :offset-assert 8)
|
||||
(clock clock :offset-assert 12)
|
||||
(parent (pointer process-tree) :offset-assert 16)
|
||||
(brother (pointer process-tree) :offset-assert 20)
|
||||
(child (pointer process-tree) :offset-assert 24)
|
||||
(ppointer (pointer process) :offset-assert 28)
|
||||
(self process-tree :offset-assert 32)
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type string) _type_ 0)
|
||||
(activate (_type_ process-tree basic pointer) process-tree 9)
|
||||
(deactivate (_type_) none 10)
|
||||
(init-from-entity!
|
||||
"Typically the method that does the initial setup on the process, potentially using the [[entity-actor]] provided as part of that.
|
||||
This commonly includes things such as:
|
||||
- stack size
|
||||
- collision information
|
||||
- loading the skeleton group / bones
|
||||
- sounds"
|
||||
(_type_ entity-actor) none 11)
|
||||
(run-logic? (_type_) symbol 12)
|
||||
(process-tree-method-13 () none 13)
|
||||
)
|
||||
:size-assert #x24
|
||||
:method-count-assert 14
|
||||
:no-runtime-type
|
||||
)
|
||||
|
||||
(deftype kernel-context (basic)
|
||||
((prevent-from-run process-mask :offset-assert 4) ;; guessed by decompiler
|
||||
(require-for-run process-mask :offset-assert 8) ;; guessed by decompiler
|
||||
(allow-to-run process-mask :offset-assert 12) ;; guessed by decompiler
|
||||
(next-pid int32 :offset-assert 16)
|
||||
(fast-stack-top pointer :offset-assert 20) ;; guessed by decompiler
|
||||
(current-process process :offset-assert 24) ;; guessed by decompiler
|
||||
(relocating-process basic :offset-assert 28)
|
||||
(relocating-min int32 :offset-assert 32)
|
||||
(relocating-max int32 :offset-assert 36)
|
||||
(relocating-offset int32 :offset-assert 40)
|
||||
(relocating-level level :offset-assert 44) ;; guessing here
|
||||
(low-memory-message symbol :offset-assert 48) ;; guessed by decompiler
|
||||
(login-object basic :offset-assert 52)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x38
|
||||
:flag-assert #x900000038
|
||||
;; field relocating-level uses ~A with a signed load
|
||||
)
|
||||
|
||||
(deftype time-frame (int64)
|
||||
()
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
|
||||
(deftype clock (basic)
|
||||
((index int32 :offset-assert 4) ;; which clock we are, in *display*
|
||||
(mask process-mask :offset-assert 8) ;; mask for ticking
|
||||
(clock-ratio float :offset-assert 12) ;; how fast to run. 1.0 = realtime.
|
||||
(accum float :offset-assert 16) ;; fractional time for frame-counter (time-frame units)
|
||||
(integral-accum float :offset-assert 20) ;; fractional time for integral (time-frame untis)
|
||||
(frame-counter time-frame :offset-assert 24) ;; how much time has gone by since reset (time-frame units)
|
||||
(old-frame-counter time-frame :offset-assert 32) ;; the frame-counter on the last engine iteration
|
||||
(integral-frame-counter uint64 :offset-assert 40) ;; how many vsyncs have gone by since reset
|
||||
(old-integral-frame-counter uint64 :offset-assert 48) ;; the integral-frame-counter on the last engine iteration
|
||||
(sparticle-data vector :inline :offset-assert 64) ;; sparticle timescale info
|
||||
(seconds-per-frame float :offset-assert 80) ;; how many seconds (not time-frames) should go by in 1 vsync
|
||||
(frames-per-second float :offset-assert 84) ;; inverse of above
|
||||
(time-adjust-ratio float :offset-assert 88) ;; 1, if the game runs at 60fps NTSC with clock-ratio = 1.
|
||||
)
|
||||
:method-count-assert 15
|
||||
:size-assert #x5c
|
||||
:flag-assert #xf0000005c
|
||||
(:methods
|
||||
(new (symbol type int) _type_ 0)
|
||||
(update-rates! (_type_ float) float 9)
|
||||
(advance-by! (_type_ float) clock 10)
|
||||
(tick! (_type_) clock 11)
|
||||
(save! (_type_ (pointer uint64)) int 12)
|
||||
(load! (_type_ (pointer uint64)) int 13)
|
||||
(reset! (_type_) none 14)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftype thread (basic)
|
||||
((name symbol :offset-assert 4)
|
||||
(process process :offset-assert 8) ;; guessed by decompiler
|
||||
(previous thread :offset-assert 12) ;; guessed by decompiler
|
||||
(suspend-hook (function cpu-thread none) :offset-assert 16) ;; guessed by decompiler
|
||||
(resume-hook (function cpu-thread none) :offset-assert 20) ;; guessed by decompiler
|
||||
(pc pointer :offset-assert 24) ;; guessed by decompiler
|
||||
(sp pointer :offset-assert 28) ;; guessed by decompiler
|
||||
(stack-top pointer :offset-assert 32) ;; guessed by decompiler
|
||||
(stack-size int32 :offset-assert 36)
|
||||
)
|
||||
:method-count-assert 12
|
||||
:size-assert #x28
|
||||
:flag-assert #xc00000028
|
||||
(:methods
|
||||
(stack-size-set! (_type_ int) none 9)
|
||||
(thread-suspend (_type_) none 10)
|
||||
(thread-resume (_type_) none 11)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; modified for x86.
|
||||
(deftype cpu-thread (thread)
|
||||
((rreg uint64 7 :offset-assert 40)
|
||||
(freg float 8)
|
||||
|
||||
;; old values:
|
||||
;; (rreg uint64 8 :offset-assert 40) ;; guessed by decompiler
|
||||
;; (freg float 6 :offset-assert 104) ;; guessed by decompiler
|
||||
(stack uint8 :dynamic :offset-assert 128) ;; guessed by decompiler
|
||||
)
|
||||
:method-count-assert 12
|
||||
:size-assert #x80
|
||||
:flag-assert #xc00000080
|
||||
(:methods
|
||||
(new (symbol type process symbol int pointer) _type_ 0)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
(deftype dead-pool (process-tree)
|
||||
()
|
||||
:method-count-assert 16
|
||||
:size-assert #x24
|
||||
:flag-assert #x1000000024
|
||||
;; Failed to read fields.
|
||||
(:methods
|
||||
(new (symbol type int int string) _type_ 0)
|
||||
(get-process (_type_ type int) process 14)
|
||||
(return-process (_type_ process) none 15)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftype dead-pool-heap-rec (structure)
|
||||
((process process :offset-assert 0) ;; guessed by decompiler
|
||||
(prev dead-pool-heap-rec :offset-assert 4)
|
||||
(next dead-pool-heap-rec :offset-assert 8)
|
||||
)
|
||||
:pack-me
|
||||
:method-count-assert 9
|
||||
:size-assert #xc
|
||||
:flag-assert #x90000000c
|
||||
)
|
||||
|
||||
|
||||
(deftype dead-pool-heap (dead-pool)
|
||||
((allocated-length int32 :offset-assert 36)
|
||||
(compact-time uint32 :offset-assert 40)
|
||||
(compact-count-targ uint32 :offset-assert 44)
|
||||
(compact-count uint32 :offset-assert 48)
|
||||
(fill-percent float :offset-assert 52)
|
||||
(first-gap dead-pool-heap-rec :offset-assert 56)
|
||||
(first-shrink dead-pool-heap-rec :offset-assert 60)
|
||||
(heap kheap :inline :offset-assert 64)
|
||||
(alive-list dead-pool-heap-rec :inline :offset-assert 80)
|
||||
(last dead-pool-heap-rec :offset #x54 :offset-assert 84)
|
||||
(dead-list dead-pool-heap-rec :inline :offset-assert 92)
|
||||
(process-list dead-pool-heap-rec :inline :dynamic :offset-assert 104)
|
||||
)
|
||||
:method-count-assert 28
|
||||
:size-assert #x68
|
||||
:flag-assert #x1c00000068
|
||||
;; Failed to read fields.
|
||||
(:methods
|
||||
(new (symbol type string int int) _type_ 0)
|
||||
(init (_type_ symbol int) none 16)
|
||||
(compact (dead-pool-heap int) none 17)
|
||||
(shrink-heap (dead-pool-heap process) dead-pool-heap 18)
|
||||
(churn (dead-pool-heap int) none 19)
|
||||
(memory-used (_type_) int 20)
|
||||
(memory-total (_type_) int 21)
|
||||
(memory-free (dead-pool-heap) int 22)
|
||||
(compact-time (dead-pool-heap) uint 23)
|
||||
(gap-size (dead-pool-heap dead-pool-heap-rec) int 24)
|
||||
(gap-location (dead-pool-heap dead-pool-heap-rec) pointer 25)
|
||||
(find-gap (dead-pool-heap dead-pool-heap-rec) dead-pool-heap-rec 26)
|
||||
(find-gap-by-size (dead-pool-heap int) dead-pool-heap-rec 27)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype stack-frame (basic)
|
||||
((name symbol :offset 4)
|
||||
(next stack-frame :offset 8) ;; which way does this point?
|
||||
)
|
||||
:size-assert #xc
|
||||
:method-count-assert 9
|
||||
:flag-assert #x90000000c
|
||||
)
|
||||
|
||||
;; a "catch" frame is a frame that can be "thrown" to.
|
||||
;; the "throw" is a nonlocal control flow back to the state before the "catch" block.
|
||||
(deftype catch-frame (stack-frame)
|
||||
((sp int32 :offset-assert 12)
|
||||
(ra int32 :offset-assert 16)
|
||||
; (freg float 6 :offset-assert 20)
|
||||
; (rreg uint128 8 :offset-assert 48)
|
||||
;; In OpenGOAL, we swap a rreg for 4 more fregs.
|
||||
(freg float 10 :offset-assert 20) ;; only use 8
|
||||
(rreg uint128 7) ;; only use 5
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #xb0
|
||||
:flag-assert #x9000000b0
|
||||
(:methods
|
||||
(new (symbol type symbol function (pointer uint64)) object 0)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype protect-frame (stack-frame)
|
||||
((exit (function none) :offset-assert 12) ;; guessed by decompiler
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type (function none)) protect-frame)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
:flag-assert #x900000010
|
||||
)
|
||||
|
||||
|
||||
(deftype handle (uint64)
|
||||
((process (pointer process) :offset 0)
|
||||
(pid int32 :offset 32)
|
||||
(u64 uint64 :offset 0)
|
||||
)
|
||||
:flag-assert #x900000008
|
||||
)
|
||||
|
||||
(deftype state (protect-frame)
|
||||
((code function :offset-assert 16) ;; guessed by decompiler
|
||||
(trans (function none) :offset-assert 20) ;; guessed by decompiler
|
||||
(post function :offset-assert 24) ;; guessed by decompiler
|
||||
(enter function :offset-assert 28) ;; guessed by decompiler
|
||||
(event (function process int symbol event-message-block object) :offset-assert 32) ;; guessed by decompiler
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type symbol function
|
||||
(function none)
|
||||
function
|
||||
(function none)
|
||||
(function process int symbol event-message-block object)) _type_ 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x24
|
||||
:flag-assert #x900000024
|
||||
)
|
||||
|
||||
(deftype event-message-block (structure)
|
||||
((to-handle handle)
|
||||
(to (pointer process) :offset 0) ;; overlays process field of handle
|
||||
(form-handle handle :offset-assert 8)
|
||||
(from (pointer process) :offset 8)
|
||||
(param uint64 6)
|
||||
(message symbol)
|
||||
(num-params int32)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x48
|
||||
:flag-assert #x900000048
|
||||
;; Failed to read fields.
|
||||
)
|
||||
|
||||
|
||||
|
||||
(deftype event-message-block-array (inline-array-class)
|
||||
((data event-message-block :inline :dynamic :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 10
|
||||
:size-assert #x10
|
||||
:flag-assert #xa00000010
|
||||
(:methods
|
||||
(send-all! (_type_) none 9)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(deftype process (process-tree)
|
||||
((pool dead-pool)
|
||||
(status symbol :offset-assert 40)
|
||||
(pid int32)
|
||||
(main-thread cpu-thread :offset-assert 48)
|
||||
(top-thread cpu-thread :offset-assert 52)
|
||||
(entity entity-actor :offset-assert 56)
|
||||
(level level :offset-assert 60)
|
||||
(state state :offset-assert 64)
|
||||
(next-state state :offset-assert 68)
|
||||
(trans-hook function :offset-assert 72)
|
||||
(post-hook function :offset-assert 76)
|
||||
(event-hook (function process int symbol event-message-block object) :offset-assert 80)
|
||||
(allocated-length int32 :offset-assert 84)
|
||||
(pad-unknown-0 uint32 2) ;; had to rename this unfortunately, there is a type that uses this same name "vehicle"
|
||||
(heap-base pointer :offset-assert 96)
|
||||
(heap-top pointer :offset-assert 100)
|
||||
(heap-cur pointer :offset-assert 104)
|
||||
(stack-frame-top stack-frame :offset-assert 108)
|
||||
(connection-list connectable :inline :offset-assert 112)
|
||||
(stack uint8 :dynamic :offset-assert 128 :score -1)
|
||||
)
|
||||
(:methods
|
||||
(new (symbol type string int) _type_ 0)
|
||||
)
|
||||
(:states
|
||||
dead-state
|
||||
empty-state)
|
||||
:size-assert #x80
|
||||
:method-count-assert 14
|
||||
:no-runtime-type ;; already defined by kscheme. Don't do it again.
|
||||
)
|
||||
|
||||
(deftype sql-result (basic)
|
||||
((len int32 :offset-assert 4)
|
||||
(allocated-length uint32 :offset-assert 8)
|
||||
(error symbol :offset-assert 12)
|
||||
(data string :dynamic :offset-assert 16) ;; are these actually symbols, or are they strings (in the GOAL code they are treated as strings atleast)
|
||||
)
|
||||
(:methods (new (symbol type uint) _type_ 0))
|
||||
:method-count-assert 9
|
||||
:size-assert #x10
|
||||
)
|
||||
|
||||
(define-extern *sql-result* sql-result)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; gkernel ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-extern *kernel-version* binteger)
|
||||
(define-extern *irx-version* binteger)
|
||||
(define-extern *kernel-boot-mode* symbol)
|
||||
(define-extern *kernel-boot-level* symbol)
|
||||
(define-extern *deci-count* int)
|
||||
(define-extern *last-loado-length* int)
|
||||
(define-extern *last-loado-global-usage* int)
|
||||
(define-extern *last-loado-debug-usage* int)
|
||||
(define-extern *kernel-packages* pair)
|
||||
(define-extern load-package (function string kheap pair))
|
||||
(define-extern unload-package (function string pair))
|
||||
(define-extern *kernel-context* kernel-context)
|
||||
(define-extern *dram-stack* (pointer uint8))
|
||||
(define-extern *null-kernel-context* kernel-context)
|
||||
(define-extern remove-exit (function none :behavior process))
|
||||
(define-extern stream<-process-mask (function object process-mask process-mask))
|
||||
(define-extern *master-mode* symbol)
|
||||
(define-extern *pause-lock* symbol)
|
||||
(define-extern inspect-process-heap (function process symbol))
|
||||
(define-extern return-from-thread (function none))
|
||||
(define-extern return-from-thread-dead (function none))
|
||||
(define-extern reset-and-call (function thread function object))
|
||||
(define-extern method-state (function type basic state))
|
||||
(define-extern *global-search-name* basic)
|
||||
(define-extern *global-search-count* int)
|
||||
(define-extern process-by-name (function string process-tree process))
|
||||
(define-extern process-not-name (function string process-tree process))
|
||||
(define-extern process-count (function process-tree int))
|
||||
(define-extern kill-by-name (function string process-tree symbol))
|
||||
(define-extern kill-by-type (function type process-tree symbol))
|
||||
(define-extern kill-not-name (function string process-tree symbol))
|
||||
(define-extern kill-not-type (function type process-tree symbol))
|
||||
(define-extern iterate-process-tree (function process-tree (function object object) kernel-context object))
|
||||
(define-extern execute-process-tree (function process-tree (function object object) kernel-context object))
|
||||
(define-extern search-process-tree (function process-tree (function process-tree object) process-tree))
|
||||
(define-extern kernel-dispatcher (function object))
|
||||
(define-extern sync-dispatcher (function object))
|
||||
(define-extern inspect-process-tree (function process-tree int int symbol process-tree))
|
||||
(define-extern throw-dispatch (function catch-frame object none))
|
||||
(define-extern throw (function symbol object int))
|
||||
(define-extern previous-brother (function process-tree object))
|
||||
(define-extern change-parent (function process-tree process-tree process-tree))
|
||||
(define-extern change-brother (function process-tree process-tree object))
|
||||
(define-extern change-to-last-brother (function process-tree process-tree))
|
||||
(define-extern run-function-in-process (function process function object object object object object object object))
|
||||
(define-extern set-to-run-bootstrap (function none))
|
||||
(define-extern set-to-run (function cpu-thread function object object object object object object pointer))
|
||||
(define-extern entity-deactivate-handler (function process entity-actor none))
|
||||
(define-extern *listener-process* process)
|
||||
(define-extern *null-process* process)
|
||||
(define-extern *vis-boot* symbol)
|
||||
(define-extern *kernel-clock* clock)
|
||||
(define-extern *16k-dead-pool* dead-pool)
|
||||
(define-extern *8k-dead-pool* dead-pool)
|
||||
(define-extern *4k-dead-pool* dead-pool)
|
||||
(define-extern *target-dead-pool* dead-pool)
|
||||
(define-extern *camera-dead-pool* dead-pool)
|
||||
(define-extern *camera-master-dead-pool* dead-pool)
|
||||
(define-extern *debug-dead-pool* dead-pool-heap)
|
||||
(define-extern *nk-dead-pool* dead-pool-heap)
|
||||
(define-extern *default-dead-pool* dead-pool)
|
||||
(define-extern *pickup-dead-pool* dead-pool)
|
||||
(define-extern *city-dead-pool* dead-pool-heap)
|
||||
(define-extern *dead-pool-list* pair)
|
||||
(define-extern *active-pool* process-tree)
|
||||
(define-extern *display-pool* process-tree) ;; process-tree
|
||||
(define-extern *camera-pool* process-tree) ;; process-tree
|
||||
(define-extern *target-pool* process-tree) ;; process-tree
|
||||
(define-extern *entity-pool* process-tree) ;; process-tree
|
||||
(define-extern *mid-pool* process-tree)
|
||||
(define-extern *pusher-pool* process-tree)
|
||||
(define-extern *bg-pool* process-tree)
|
||||
(define-extern *default-pool* process-tree) ;; process-tree
|
@ -8,7 +8,7 @@
|
||||
// if you want to filter to only some object names.
|
||||
// it will make the decompiler much faster.
|
||||
"allowed_objects": [],
|
||||
"banned_objects": [],
|
||||
"banned_objects": ["script", "ragdoll-edit", "gun-states", "manipulator", "hfrag", "hfrag-vu1", "ff-squad-control"],
|
||||
|
||||
////////////////////////////
|
||||
// CODE ANALYSIS OPTIONS
|
||||
@ -19,9 +19,9 @@
|
||||
"disassemble_code": true,
|
||||
|
||||
// Run the decompiler
|
||||
"decompile_code": false,
|
||||
"decompile_code": true,
|
||||
|
||||
"find_functions": false,
|
||||
"find_functions": true,
|
||||
|
||||
////////////////////////////
|
||||
// DATA ANALYSIS OPTIONS
|
||||
@ -39,9 +39,11 @@
|
||||
// unpack game count to assets folder
|
||||
"process_game_count": false,
|
||||
// write goal imports for art groups
|
||||
"process_art_groups": false,
|
||||
"process_art_groups": true,
|
||||
// write out a json file containing the art info mapping, run this with all objects allowed
|
||||
"dump_art_group_info": false,
|
||||
"dump_art_group_info": true,
|
||||
// write out a json file containing the joint node mapping, run this with all objects allowed
|
||||
"dump_joint_geo_info": false,
|
||||
|
||||
///////////////////////////
|
||||
// WEIRD OPTIONS
|
||||
@ -79,16 +81,18 @@
|
||||
// CONFIG FILES
|
||||
////////////////////////////
|
||||
|
||||
"type_casts_file": "decompiler/config/jak3/type_casts.jsonc",
|
||||
"anonymous_function_types_file": "decompiler/config/jak3/anonymous_function_types.jsonc",
|
||||
"var_names_file": "decompiler/config/jak3/var_names.jsonc",
|
||||
"label_types_file": "decompiler/config/jak3/label_types.jsonc",
|
||||
"stack_structures_file": "decompiler/config/jak3/stack_structures.jsonc",
|
||||
"hacks_file": "decompiler/config/jak3/hacks.jsonc",
|
||||
"inputs_file": "decompiler/config/jak3/inputs.jsonc",
|
||||
"art_info_file": "decompiler/config/jak3/art_info.jsonc",
|
||||
"import_deps_file": "decompiler/config/jak3/import_deps.jsonc",
|
||||
"type_casts_file": "decompiler/config/jak3/ntsc_v1/type_casts.jsonc",
|
||||
"anonymous_function_types_file": "decompiler/config/jak3/ntsc_v1/anonymous_function_types.jsonc",
|
||||
"var_names_file": "decompiler/config/jak3/ntsc_v1/var_names.jsonc",
|
||||
"label_types_file": "decompiler/config/jak3/ntsc_v1/label_types.jsonc",
|
||||
"stack_structures_file": "decompiler/config/jak3/ntsc_v1/stack_structures.jsonc",
|
||||
"hacks_file": "decompiler/config/jak3/ntsc_v1/hacks.jsonc",
|
||||
"inputs_file": "decompiler/config/jak3/ntsc_v1/inputs.jsonc",
|
||||
"art_info_file": "decompiler/config/jak3/ntsc_v1/art_info.jsonc",
|
||||
"import_deps_file": "decompiler/config/jak3/ntsc_v1/import_deps.jsonc",
|
||||
"all_types_file": "decompiler/config/jak3/all-types.gc",
|
||||
"art_group_dump_file": "decompiler/config/jak3/ntsc_v1/art-group-info.min.json",
|
||||
"joint_node_dump_file": "decompiler/config/jak3/ntsc_v1/joint-node-info.min.json",
|
||||
|
||||
// optional: a predetermined object file name map from a file.
|
||||
// this will make decompilation naming consistent even if you only run on some objects.
|
||||
|
1
decompiler/config/jak3/ntsc_v1/art-group-info.min.json
Normal file
1
decompiler/config/jak3/ntsc_v1/art-group-info.min.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
@ -1,4 +1,6 @@
|
||||
{
|
||||
"files": {},
|
||||
"functions": {}
|
||||
"functions": {},
|
||||
"type_remap": {},
|
||||
"joint_node_hacks": {}
|
||||
}
|
||||
|
@ -3,51 +3,761 @@
|
||||
// HACKS and ASM FUNCTIONS
|
||||
////////////////////////////
|
||||
|
||||
"types_with_bad_inspect_methods": [],
|
||||
"types_with_bad_inspect_methods": [
|
||||
"game-task-event",
|
||||
"game-task-control",
|
||||
"predator-edge",
|
||||
"manipy"
|
||||
],
|
||||
|
||||
"no_type_analysis_functions_by_name": [],
|
||||
|
||||
// this limits the number of cases in a cond. The first argument is the name of the function.
|
||||
// the second argument is the name of the first condition in the cond. Use print_cfg to find it out.
|
||||
// The third argument is the number of cases. If you set it too small it may fail to build the CFG.
|
||||
"cond_with_else_max_lengths": [],
|
||||
"cond_with_else_max_lengths": [
|
||||
["(method 20 res-lump)", "b0", 2],
|
||||
["(method 11 res-lump)", "b0", 1],
|
||||
["(method 12 res-lump)", "b0", 1]
|
||||
],
|
||||
|
||||
// if a cond with an else case is being used a value in a place where it looks wrong
|
||||
// you can add the function name to this list and it will more aggressively reject this rewrite.
|
||||
"aggressively_reject_cond_to_value_rewrite": [],
|
||||
"aggressively_reject_cond_to_value_rewrite": [
|
||||
"(method 10 res-lump)",
|
||||
"(method 11 res-lump)",
|
||||
"(method 12 res-lump)"
|
||||
],
|
||||
|
||||
// this provides a hint to the decompiler that these functions will have a lot of inline assembly.
|
||||
// currently it just leaves pcpyld as an asm op.
|
||||
"hint_inline_assembly_functions": [],
|
||||
|
||||
"asm_functions_by_name": [],
|
||||
"asm_functions_by_name": [
|
||||
// checking boxed type is different now - these make the cfg stuff sad
|
||||
"name=",
|
||||
"(method 77 grenadier)",
|
||||
// until loop without nop:
|
||||
"target-history-print",
|
||||
"display-list-control",
|
||||
"anim-test-anim-list-handler",
|
||||
"anim-test-sequence-list-handler",
|
||||
"anim-tester-get-playing-item",
|
||||
"start-pilot-recorder",
|
||||
"(anon-function 10 pilot-recorder)",
|
||||
"(anon-function 10 sig-recorder)",
|
||||
// actual asm
|
||||
"quad-copy!",
|
||||
"return-from-thread",
|
||||
"return-from-thread-dead",
|
||||
"reset-and-call",
|
||||
"(method 10 cpu-thread)",
|
||||
"(method 11 cpu-thread)",
|
||||
"(method 0 catch-frame)",
|
||||
"throw-dispatch",
|
||||
"throw",
|
||||
"run-function-in-process",
|
||||
"set-to-run-bootstrap",
|
||||
"return-from-exception",
|
||||
"exp",
|
||||
"(method 17 bounding-box)",
|
||||
"(method 9 bounding-box)",
|
||||
"(method 9 matrix)",
|
||||
"quaternion->matrix-2",
|
||||
"sin-rad",
|
||||
"cos-rad",
|
||||
"atan-series-rad",
|
||||
"sign-float",
|
||||
"dma-count-until-done",
|
||||
"(method 11 collide-mesh-cache)",
|
||||
"cpu-delay",
|
||||
"qword-read-time",
|
||||
"dma-test-func",
|
||||
"move-test-func",
|
||||
|
||||
"symlink2",
|
||||
"blerc-a-fragment",
|
||||
"blerc-execute",
|
||||
"foreground-check-longest-edge-asm",
|
||||
"generic-light-proc",
|
||||
"shadow-add-single-edges",
|
||||
"shadow-add-facing-single-tris",
|
||||
"shadow-add-double-tris",
|
||||
"shadow-add-double-edges",
|
||||
"(method 17 collide-edge-work)",
|
||||
"(method 10 collide-cache-prim)",
|
||||
"(method 17 collide-cache)",
|
||||
"(method 16 ocean)",
|
||||
|
||||
// unknown instructions
|
||||
"debug-line-clip?",
|
||||
// logand with #f arg
|
||||
"bugfix?",
|
||||
// CFG failed
|
||||
"draw-inline-array-instance-shrub",
|
||||
|
||||
"(method 9 editable-region)", // condition branch assert hit
|
||||
"test-to-from-spr",
|
||||
"test-from-spr",
|
||||
"test-to-spr",
|
||||
"test-seq-read",
|
||||
"test-worst-read",
|
||||
"test-seq-write",
|
||||
"test-worst-write",
|
||||
// texture
|
||||
"adgif-shader<-texture!",
|
||||
|
||||
// jak 3
|
||||
"borrow-city-expansion",
|
||||
"(method 26 level-group)",
|
||||
"(anon-function 65 temple-obs)",
|
||||
"(method 33 task-manager-nest-cocoons)",
|
||||
"(method 33 rub-tower)",
|
||||
"(method 261 crimson-guard)",
|
||||
"(anon-function 25 volcanox-obs)"
|
||||
],
|
||||
|
||||
// these functions use pairs and the decompiler
|
||||
// will be less picky about types related to pairs.
|
||||
"pair_functions_by_name": [],
|
||||
"pair_functions_by_name": [
|
||||
"ref",
|
||||
"(method 4 pair)",
|
||||
"last",
|
||||
"member",
|
||||
"nmember",
|
||||
"assoc",
|
||||
"assoce",
|
||||
"nassoc",
|
||||
"nassoce",
|
||||
"append!",
|
||||
"delete!",
|
||||
"delete-car!",
|
||||
"insert-cons!",
|
||||
"sort",
|
||||
"unload-package",
|
||||
"display-loop-main",
|
||||
"lookup-level-info",
|
||||
"(method 24 level-group)",
|
||||
"(method 19 level-group)",
|
||||
// script
|
||||
"command-get-time",
|
||||
"command-get-param",
|
||||
"command-get-quoted-param",
|
||||
"command-get-entity",
|
||||
"(method 9 script-context)",
|
||||
"(anon-function 6 script)",
|
||||
"(anon-function 49 script)",
|
||||
"(anon-function 52 script)",
|
||||
"(anon-function 72 script)",
|
||||
"(anon-function 73 script)",
|
||||
"(anon-function 74 script)",
|
||||
"(anon-function 75 script)",
|
||||
"(anon-function 76 script)",
|
||||
"(anon-function 80 script)",
|
||||
"(method 11 script-context)",
|
||||
"(method 10 script-context)",
|
||||
"command-get-trans",
|
||||
"key-assoc",
|
||||
"(anon-function 0 script)",
|
||||
// default-menu
|
||||
"dm-scene-load-pick-func",
|
||||
"debug-menu-make-continue-sub-menu",
|
||||
"debug-menu-make-from-template",
|
||||
"debug-menu-context-make-default-menus",
|
||||
"debug-menu-make-task-menu",
|
||||
"(method 19 gui-control)",
|
||||
// menu
|
||||
"debug-menu-rebuild",
|
||||
"debug-menu-find-from-template",
|
||||
"debug-menu-render",
|
||||
"debug-menu-context-select-next-or-prev-item",
|
||||
"debug-menu-context-select-new-item",
|
||||
"debug-menu-send-msg",
|
||||
// airlock
|
||||
"(method 24 com-airlock)",
|
||||
"(method 19 gui-control)",
|
||||
"(method 28 editable)",
|
||||
"execute-select",
|
||||
"(method 29 editable)",
|
||||
"(method 25 editable)",
|
||||
// game-info
|
||||
"(method 20 game-info)",
|
||||
"print-continues",
|
||||
// task-control
|
||||
"(anon-function 55 task-control)",
|
||||
"(method 17 load-state)",
|
||||
"(method 12 level)",
|
||||
"bg",
|
||||
"update-sound-banks",
|
||||
"entity-remap-names",
|
||||
"(method 8 process-tree)",
|
||||
"(post play-anim scene-player)",
|
||||
"(method 25 scene-player)",
|
||||
"(method 25 scene-player)",
|
||||
"scene-player-init",
|
||||
"next-continue",
|
||||
"(method 25 warp-gate)",
|
||||
"(code use warp-gate)",
|
||||
"cspace-inspect-tree",
|
||||
"(method 11 mtn-step-plat-rocks-a)",
|
||||
"(method 11 mtn-step-plat-rocks-b)",
|
||||
"(method 11 mtn-step-plat-rocks-c)",
|
||||
"(method 22 fort-floor-spike-b)",
|
||||
"prototypes-game-visible-set!",
|
||||
"(method 22 fort-floor-spike-a)",
|
||||
"(method 22 fort-floor-spike-b)",
|
||||
"(method 22 fort-floor-spike-c)",
|
||||
"(method 11 sew-catwalk)",
|
||||
"(method 11 mtn-aval-rocks)",
|
||||
"(method 11 gar-curtain)"
|
||||
],
|
||||
|
||||
// If format is used with the wrong number of arguments,
|
||||
// it will often mess up the decompilation, as the decompiler assumes
|
||||
// that they used the correct number. This will override the decompiler's
|
||||
// automatic detection.
|
||||
"bad_format_strings": {},
|
||||
"bad_format_strings": {
|
||||
"~170h~5d~220h~5d~280h~5,,2f": 3,
|
||||
"~338h~5d~388h~5d~448h~5,,2f": 3,
|
||||
"~30Htf: ~8D~134Hpr: ~8D~252Hsh: ~8D~370Hhd: ~8D~%": 4,
|
||||
"~30Hal: ~8D~131Hwa: ~8D~252Hsp: ~8D~370Hwp: ~8D~%": 4,
|
||||
"ERROR: <asg> ~A in spool anim loop for ~A ~D, but not loaded.~": 3,
|
||||
// TODO - these should be automatic
|
||||
" tfrag ~192H~5DK ~280Htfragment~456H~5DK~%": 2,
|
||||
" tie-proto ~192H~5DK ~280Hsky~456H~5DK~%": 2,
|
||||
" tie-instance ~192H~5DK ~280Htie-fragment~456H~5DK~%": 2,
|
||||
" shrub-proto ~192H~5DK ~280Htie-scissor~456H~5DK~%": 2,
|
||||
" shrub-instance ~192H~5DK ~280Hshrubbery~456H~5DK~%": 2,
|
||||
" collision ~192H~5DK ~280Htie-generic~456H~5DK~%": 2,
|
||||
" pris-anim ~192H~5DK ~280Hpris-generic~456H~5DK~%": 2,
|
||||
" textures ~192H~5DK ~280Htextures~456H~5DK~%": 2,
|
||||
" misc ~192H~5DK ~280Hsprite~456H~5DK~%": 2,
|
||||
" entity ~192H~5DK~%": 1,
|
||||
" pris-geo ~192H~5DK ~280Hpris-fragment~456H~5DK~%": 2,
|
||||
"~33L~S~32L ~S": 2,
|
||||
"~32L~S ~33L~S~1L": 2,
|
||||
"~35L~S~33L ~S": 2,
|
||||
"~1L~S~35L ~S": 2,
|
||||
"~35L~S ~1L~S~1L": 2,
|
||||
"~33L~S~35L ~S": 2,
|
||||
"~33L~C~34L~S~33L~C": 3,
|
||||
"~35L~S ~33L~S~1L": 2,
|
||||
"~33L~S ~35L~S~1L": 2,
|
||||
"~33L~C": 1
|
||||
},
|
||||
|
||||
"blocks_ending_in_asm_branch": {},
|
||||
"blocks_ending_in_asm_branch": {
|
||||
"closest-pt-in-triangle": [17],
|
||||
// this one is all asm branches
|
||||
"circle-circle-xz-intersect": [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
|
||||
],
|
||||
"load-game-text-info": [15, 16, 17, 19, 20, 21],
|
||||
|
||||
"find-knot-span": [0, 1, 2, 3, 5, 6, 7, 8, 9],
|
||||
|
||||
"curve-evaluate!": [0, 2, 5, 6, 7, 8, 9],
|
||||
|
||||
"display-loop-main": [127, 130, 133, 136],
|
||||
|
||||
"real-main-draw-hook": [114, 115, 116, 118],
|
||||
|
||||
"sprite-draw-distorters": [4, 5],
|
||||
"draw-drawable-tree-instance-shrub": [5, 7, 9, 11],
|
||||
|
||||
"add-debug-box-with-transform": [0, 3],
|
||||
"add-debug-line-sphere": [0],
|
||||
|
||||
"(method 12 perf-stat)": [0],
|
||||
"(method 11 perf-stat)": [0],
|
||||
"bsp-camera-asm": [1, 2, 3, 4, 6, 7],
|
||||
"(method 9 texture-page-dir)": [5, 6],
|
||||
"level-remap-texture": [2, 3, 4, 5, 6],
|
||||
|
||||
"(method 27 nav-mesh)": [1, 2],
|
||||
"(method 31 nav-mesh)": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
|
||||
"(method 46 nav-mesh)": [2, 3],
|
||||
"(method 32 nav-mesh)": [1, 2],
|
||||
"(method 33 nav-mesh)": [1, 2],
|
||||
"(method 42 nav-mesh)": [1, 2, 3, 7],
|
||||
"point-poly-distance-min": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
||||
"(method 34 nav-mesh)": [1, 2, 3, 7],
|
||||
"(method 35 nav-mesh)": [2, 4],
|
||||
"draw-actor-marks": [8],
|
||||
"find-nearest-entity": [7, 9, 10, 11, 12, 13, 14],
|
||||
"start-perf-stat-collection": [26],
|
||||
"end-perf-stat-collection": [0],
|
||||
"upload-vis-bits": [2, 6, 3, 0],
|
||||
"set-background-regs!": [4, 3],
|
||||
"draw-drawable-tree-instance-tie": [21, 23, 31, 33],
|
||||
"command-get-process": [43],
|
||||
"unpack-comp-rle": [1, 3, 5, 6],
|
||||
"(method 16 level)": [0, 1, 5, 13, 14, 15],
|
||||
"unpack-comp-huf": [2, 4, 5, 6, 7, 8, 9],
|
||||
"unpack-comp-lzo": [
|
||||
0,
|
||||
1,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25,
|
||||
26,
|
||||
27,
|
||||
28,
|
||||
29,
|
||||
30,
|
||||
31,
|
||||
32,
|
||||
33,
|
||||
34,
|
||||
35, // branch fwd 39
|
||||
39, // branch fwd no delay
|
||||
43, // goto 18
|
||||
45 // goto 6
|
||||
],
|
||||
"(method 27 conveyor)": [5, 14, 22],
|
||||
"(method 44 nav-graph)": [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 14, 15, 16, 17, 18, 22, 24, 25, 26, 27, 30, 31,
|
||||
32, 33, 34, 35, 36
|
||||
],
|
||||
"(method 11 sparticle-launch-control)": [
|
||||
18, 24, 25, 28, 29, 32, 33, 34, 36, 41, 55, 58, 93, 95
|
||||
],
|
||||
|
||||
"(method 22 gui-control)": [
|
||||
10, // goto L63 (B39)
|
||||
16, // goto L58 (B27)
|
||||
26, // goto L62 (B)
|
||||
27, // goto L62
|
||||
28, // goto L61
|
||||
35, // goto L62
|
||||
36, // goto L62
|
||||
38, // goto L99
|
||||
42, // goto L89
|
||||
50, // goto L84
|
||||
108, // goto L86
|
||||
110, // goto L86
|
||||
116, // goto L99
|
||||
117, // goto L91
|
||||
120
|
||||
],
|
||||
|
||||
"(anon-function 11 game-save)": [0, 3, 4, 5],
|
||||
"update-actor-hash": [0, 2, 4],
|
||||
"(code target-death)": [111, 140],
|
||||
"(method 13 collide-cache)": [7, 9],
|
||||
"(method 11 collide-mesh)": [2, 4],
|
||||
"(method 12 collide-mesh-cache)": [0, 1, 2, 3, 4, 5],
|
||||
"(method 10 collide-mesh)": [2],
|
||||
"(method 42 collide-shape)": [0, 1, 2, 3, 4, 7],
|
||||
"(method 18 collide-shape-prim-mesh)": [2, 3, 4, 5, 6, 7],
|
||||
"(method 18 collide-shape-prim-sphere)": [2, 3, 4],
|
||||
"(method 15 collide-shape-prim-sphere)": [1, 2, 3, 4, 5, 6],
|
||||
"(method 16 collide-shape-prim-sphere)": [0, 1, 2, 3, 4],
|
||||
"(method 36 collide-shape)": [8, 9],
|
||||
"(method 45 collide-shape)": [33],
|
||||
"(method 40 collide-shape)": [
|
||||
0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
|
||||
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
|
||||
],
|
||||
"(method 12 collide-shape-prim-group)": [1, 2, 3, 4, 5, 6],
|
||||
"(method 13 collide-shape-prim)": [1, 2, 3, 4, 5, 6],
|
||||
"(method 12 collide-shape-prim-sphere)": [
|
||||
1, 2, 3, 4, 5, 8, 10, 11, 13, 14, 15
|
||||
],
|
||||
"(method 12 collide-shape-prim-mesh)": [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16
|
||||
],
|
||||
"(method 24 grid-hash)": [39, 35, 22, 15],
|
||||
"(method 12 flow-control)": [11, 12, 13, 14, 15, 18, 20, 22, 29],
|
||||
"(method 19 process-drawable)": [0, 2, 3, 7, 10, 11, 30],
|
||||
"find-offending-process-focusable": [16, 19],
|
||||
|
||||
"target-standard-event-handler": [
|
||||
5, // fwd L31/7
|
||||
6, // to 152
|
||||
7, // fwd L38
|
||||
20, // to 152
|
||||
21, // fwd L39
|
||||
22, // to 152
|
||||
23, // to L40
|
||||
24, // to 152
|
||||
25, // to L45
|
||||
43, // to l152
|
||||
44, // to 46
|
||||
45, // to l152
|
||||
|
||||
46, // to l114
|
||||
|
||||
190, // to l152
|
||||
191, // to 121
|
||||
210,
|
||||
211,
|
||||
212,
|
||||
213,
|
||||
214,
|
||||
|
||||
224,
|
||||
225,
|
||||
226,
|
||||
227,
|
||||
232,
|
||||
233,
|
||||
234,
|
||||
235,
|
||||
236,
|
||||
237,
|
||||
238,
|
||||
239,
|
||||
240,
|
||||
241,
|
||||
242,
|
||||
|
||||
255,
|
||||
256,
|
||||
|
||||
269,
|
||||
270,
|
||||
285,
|
||||
286,
|
||||
287,
|
||||
288,
|
||||
289,
|
||||
290
|
||||
],
|
||||
"bones-mtx-calc-execute": [19, 7],
|
||||
"foreground-draw": [0, 1, 126],
|
||||
"dma-add-process-drawable": [0, 136],
|
||||
"(anon-function 3 ruins-obs)": [14, 22],
|
||||
"(anon-function 0 target-death)": [
|
||||
50, // goto 52
|
||||
51, // goto L65
|
||||
63, // goto L47
|
||||
73, // goto L25
|
||||
78, // goto L46
|
||||
84, // goto L42
|
||||
95, // goto next
|
||||
96, // goto L36
|
||||
115, // goto L55
|
||||
121,
|
||||
131
|
||||
],
|
||||
"(anon-function 4 gun-states)": [94, 96, 98],
|
||||
"target-board-handler": [13, 14, 18],
|
||||
"find-closest-circle-ray-intersection": [0, 4, 15, 16, 17, 18],
|
||||
"(method 18 nav-control)": [
|
||||
11, // L283
|
||||
12, // L300
|
||||
19, // L295
|
||||
20, // L293
|
||||
31, // weird jump back
|
||||
34 // weird jump no delay slot
|
||||
],
|
||||
|
||||
"(method 19 nav-control)": [9, 10],
|
||||
"(method 19 nav-mesh)": [7],
|
||||
"(method 18 nav-mesh)": [9],
|
||||
"(method 40 nav-state)": [1, 2],
|
||||
"(method 45 nav-mesh)": [5, 6],
|
||||
"(method 43 nav-mesh)": [0, 1, 2, 12, 13, 14, 15, 16, 17, 18, 19, 20],
|
||||
"(anon-function 45 gungame-obs)": [0, 1, 6, 9, 14, 18, 21, 22, 30], // TODO - probably not the best
|
||||
"(method 142 grenadier)": [0, 1, 3],
|
||||
"(anon-function 34 predator)": [24],
|
||||
"(anon-function 57 crimson-guard-level)": [22],
|
||||
"(method 48 rigid-body-object)": [0, 1, 2, 3, 4, 5],
|
||||
"(method 15 rigid-body)": [0, 1, 2, 5],
|
||||
"(method 63 collide-shape-moving)": [
|
||||
0, 1, 2, 3, 4, 5, 6, 10, 12, 13, 14, 28, 38, 39, 40, 44
|
||||
],
|
||||
"string-word-wrap": [1, 2, 6],
|
||||
"(method 37 vehicle)": [0, 1, 10, 11, 12, 13, 15, 16],
|
||||
"(method 123 vehicle)": [
|
||||
0, 1, 2, 3, 4, 7, 8, 9, 10, 17, 19, 20, 23, 26, 30, 31, 32, 33, 34
|
||||
],
|
||||
"(method 122 vehicle)": [0, 1, 10, 11, 17, 18, 19, 20, 21, 22, 24, 25],
|
||||
"(method 48 vehicle)": [
|
||||
0, 1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 16, 17, 23, 24, 29, 30, 31
|
||||
],
|
||||
"(method 11 vehicle-hud-requests)": [0, 6, 7, 10, 11, 12],
|
||||
"(method 17 traffic-manager)": [
|
||||
0, 4, 7, 17, 23, 25, 26, 27, 28, 39, 42, 43, 44
|
||||
],
|
||||
"(anon-function 12 vehicle-states)": [0, 1, 2, 3],
|
||||
"(method 45 traffic-engine)": [5, 8],
|
||||
"(method 15 city-level-info)": [0, 1, 2, 6, 7, 9, 11, 13],
|
||||
"(method 59 traffic-engine)": [5, 6, 7, 8, 9, 10],
|
||||
"(method 10 traffic-suppressor)": [0, 1, 2, 4],
|
||||
"(method 18 traffic-tracker)": [2, 3, 5, 6, 7, 8],
|
||||
"(method 181 gator)": [
|
||||
2, 3, 7, 10, 11, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 30
|
||||
],
|
||||
"(method 10 simple-sprite-system)": [0],
|
||||
"target-pilot-post": [0, 2, 4, 13, 16, 22, 27, 41],
|
||||
"(anon-function 0 ruins-obs)": [
|
||||
0, 5, 7, 12, 13, 15, 17, 23, 24, 33, 42, 45, 46, 53, 58
|
||||
],
|
||||
"(anon-function 1 ruins-obs)": [
|
||||
1, 2, 4, 6, 7, 14, 17, 19, 22, 24, 26, 27, 29, 31, 33, 35
|
||||
],
|
||||
"(anon-function 2 ruins-obs)": [7, 28, 37, 50, 51, 61, 62, 71],
|
||||
"(anon-function 62 sig0-course)": [0, 1, 5, 6],
|
||||
"(method 67 collide-shape-moving)": [0, 1, 2, 3, 11, 12, 13],
|
||||
"(anon-function 12 juicer)": [29, 30],
|
||||
"(anon-function 0 atoll-obs)": [11, 19, 20],
|
||||
"(method 74 spydroid)": [12], // stack spill delay slot
|
||||
"(anon-function 16 kid-states)": [4, 5],
|
||||
"(anon-function 23 kid-states)": [4, 5],
|
||||
"(anon-function 16 kor-states)": [4, 5],
|
||||
"(anon-function 23 kor-states)": [4, 5],
|
||||
"(method 18 mysql-nav-graph)": [0, 1, 2, 3, 4, 7, 8, 9, 14, 16],
|
||||
"(anon-function 2 rigid-body-queue)": [0, 1, 2, 3],
|
||||
"(method 15 rigid-body-queue)": [5, 6, 7, 8, 9, 10, 11],
|
||||
"(method 13 rigid-body-queue)": [5, 6, 7, 8, 9, 10, 11],
|
||||
"(method 11 rigid-body-queue)": [0, 5, 6, 7, 8, 9, 10, 11, 17, 18, 25],
|
||||
"(method 10 rigid-body-queue)": [0, 9, 10, 16, 24, 25, 26, 35, 36, 48],
|
||||
"(method 18 vehicle-controller)": [0, 1, 74, 75],
|
||||
"(method 15 vehicle-controller)": [0, 3, 5, 6, 7, 10],
|
||||
"(anon-function 41 guard)": [9],
|
||||
"(anon-function 10 metalhead-predator)": [24, 25],
|
||||
"(anon-function 10 errol-chal)": [6],
|
||||
"choose-next-branch-no-exit-level": [0, 6, 8, 12, 13, 16, 18, 26],
|
||||
"(anon-function 39 kidesc-states)": [4, 5],
|
||||
"(anon-function 56 hal2-course)": [4, 5],
|
||||
"(anon-function 58 hal2-course)": [74],
|
||||
"(method 142 gun-buoy)": [0, 2],
|
||||
"generic-merc-execute-all": [7, 15]
|
||||
},
|
||||
|
||||
// Sometimes the game might use format strings that are fetched dynamically,
|
||||
// for example using the game text lookup method
|
||||
// Add information about those format instructions here.
|
||||
// e.g. "function-name":[[op, argc], [op, argc], ...]
|
||||
// where "op" is the op number for the call to format.
|
||||
"dynamic_format_arg_counts": {},
|
||||
"dynamic_format_arg_counts": {
|
||||
"(method 10 menu-loading-option)": [[118, 1]],
|
||||
"(method 10 menu-insufficient-space-option)": [
|
||||
[63, 1],
|
||||
[103, 1]
|
||||
],
|
||||
"(method 10 menu-secrets-insufficient-space-option)": [[55, 1]],
|
||||
"(method 10 menu-card-removed-option)": [[48, 1]],
|
||||
"(method 10 menu-format-card-option)": [[49, 1]],
|
||||
"(method 10 menu-create-game-option)": [[49, 1]],
|
||||
"(method 10 menu-error-auto-saving-option)": [[72, 1]],
|
||||
"(method 10 menu-error-loading-option)": [
|
||||
[64, 1],
|
||||
[99, 1]
|
||||
],
|
||||
"(method 10 menu-insert-card-option)": [[48, 1]],
|
||||
"(method 16 fail-mission)": [
|
||||
[68, 1],
|
||||
[101, 1],
|
||||
[130, 1]
|
||||
],
|
||||
"auto-save-post": [[158, 1]],
|
||||
"(method 30 training-manager)": [[53, 0]],
|
||||
"(trans course training-manager)": [
|
||||
[54, 0],
|
||||
[89, 0],
|
||||
[124, 0],
|
||||
[155, 0],
|
||||
[195, 0],
|
||||
[230, 0],
|
||||
[261, 0],
|
||||
[307, 0],
|
||||
[338, 0],
|
||||
[374, 0],
|
||||
[409, 0],
|
||||
[444, 0],
|
||||
[479, 0],
|
||||
[510, 0]
|
||||
],
|
||||
"(method 17 hud-goal)": [[71, 0]],
|
||||
"(method 15 hud-miss)": [[44, 0]],
|
||||
"(method 28 hoverboard-training-manager)": [[53, 0]],
|
||||
"(method 29 hoverboard-training-manager)": [
|
||||
[48, 0],
|
||||
[83, 0],
|
||||
[118, 0],
|
||||
[153, 0],
|
||||
[184, 0],
|
||||
[224, 0],
|
||||
[259, 0],
|
||||
[294, 0],
|
||||
[325, 0],
|
||||
[365, 0],
|
||||
[400, 0],
|
||||
[431, 0],
|
||||
[477, 0],
|
||||
[508, 0]
|
||||
],
|
||||
"(trans menu burning-bush)": [
|
||||
[294, 0],
|
||||
[378, 0],
|
||||
[406, 0],
|
||||
[434, 0],
|
||||
[462, 0],
|
||||
[490, 0],
|
||||
[518, 0],
|
||||
[350, 0]
|
||||
],
|
||||
"(trans idle burning-bush)": [[171, 0]],
|
||||
"(anon-function 11 oracle-training)": [[79, 0]],
|
||||
"(anon-function 4 oracle-training)": [[79, 0]],
|
||||
"(anon-function 0 oracle-training)": [[79, 0]],
|
||||
"(anon-function 7 oracle-training)": [[79, 0]],
|
||||
"(method 27 sig-recorder)": [[93, 0]],
|
||||
"(method 15 hud-race-final-stats)": [[158, 1]],
|
||||
"(method 24 race-manager)": [[67, 1]],
|
||||
"(method 25 race-manager)": [
|
||||
[67, 1],
|
||||
[96, 1]
|
||||
]
|
||||
},
|
||||
|
||||
"mips2c_functions_by_name": [],
|
||||
"mips2c_functions_by_name": [
|
||||
"collide-do-primitives",
|
||||
"moving-sphere-triangle-intersect",
|
||||
"calc-animation-from-spr",
|
||||
"draw-string-asm",
|
||||
"draw-string",
|
||||
"get-string-length",
|
||||
"adgif-shader<-texture-with-update!",
|
||||
"init-boundary-regs",
|
||||
"draw-boundary-polygon",
|
||||
"render-boundary-quad",
|
||||
"render-boundary-tri",
|
||||
"clip-polygon-against-negative-hyperplane",
|
||||
"clip-polygon-against-positive-hyperplane",
|
||||
"sp-init-fields!",
|
||||
"particle-adgif",
|
||||
"sp-launch-particles-var",
|
||||
"sparticle-motion-blur",
|
||||
"sp-process-block-2d",
|
||||
"sp-process-block-3d",
|
||||
"set-tex-offset",
|
||||
"draw-large-polygon",
|
||||
"render-sky-quad",
|
||||
"render-sky-tri",
|
||||
"(method 16 sky-work)",
|
||||
"(method 17 sky-work)",
|
||||
"(method 32 sky-work)",
|
||||
"(method 33 sky-work)",
|
||||
// "(method 28 sky-work)",
|
||||
"(method 29 sky-work)",
|
||||
"(method 30 sky-work)",
|
||||
"(method 11 collide-hash)",
|
||||
"(method 12 collide-hash)",
|
||||
"fill-bg-using-box-new",
|
||||
"fill-bg-using-line-sphere-new",
|
||||
"(method 12 collide-mesh)",
|
||||
"(method 11 collide-mesh)",
|
||||
"(method 14 collide-mesh)",
|
||||
"(method 15 collide-mesh)",
|
||||
"(method 10 collide-edge-hold-list)",
|
||||
"(method 19 collide-edge-work)",
|
||||
"(method 9 edge-grab-info)",
|
||||
"(method 16 collide-edge-work)",
|
||||
"(method 17 collide-edge-work)",
|
||||
"(method 18 collide-edge-work)",
|
||||
"draw-large-polygon-ocean",
|
||||
"render-ocean-quad",
|
||||
"init-ocean-far-regs",
|
||||
"(method 14 ocean)",
|
||||
"(method 15 ocean)",
|
||||
"(method 16 ocean)",
|
||||
"(method 18 grid-hash)",
|
||||
"(method 19 grid-hash)",
|
||||
"(method 20 grid-hash)",
|
||||
"(method 22 grid-hash)",
|
||||
"(method 28 sphere-hash)",
|
||||
"(method 33 sphere-hash)",
|
||||
"(method 29 sphere-hash)",
|
||||
"(method 30 sphere-hash)",
|
||||
"(method 31 sphere-hash)",
|
||||
"(method 32 sphere-hash)",
|
||||
"(method 33 spatial-hash)",
|
||||
"(method 39 spatial-hash)",
|
||||
"(method 36 spatial-hash)",
|
||||
"(method 37 spatial-hash)",
|
||||
"(method 35 spatial-hash)",
|
||||
"(method 10 collide-shape-prim-mesh)",
|
||||
"(method 10 collide-shape-prim-sphere)",
|
||||
"(method 10 collide-shape-prim-group)",
|
||||
"(method 11 collide-shape-prim-mesh)",
|
||||
"(method 11 collide-shape-prim-sphere)",
|
||||
"(method 11 collide-shape-prim-group)",
|
||||
"(method 9 collide-cache-prim)",
|
||||
"(method 10 collide-cache-prim)",
|
||||
"(method 17 collide-cache)",
|
||||
"(method 9 collide-puss-work)",
|
||||
"(method 10 collide-puss-work)",
|
||||
"bones-mtx-calc",
|
||||
"foreground-check-longest-edge-asm",
|
||||
"foreground-merc",
|
||||
"add-light-sphere-to-light-group",
|
||||
"light-hash-add-items",
|
||||
"light-hash-count-items",
|
||||
"light-hash-get-bucket-index",
|
||||
// nav-mesh / nav-control related
|
||||
// TODO - it would be nice to eventually figure out the asm blocks for the majority of these
|
||||
"nav-state-patch-pointers",
|
||||
"(method 20 nav-engine)",
|
||||
// "find-closest-circle-ray-intersection",
|
||||
// "(method 18 nav-control)",
|
||||
"nav-dma-send-to-spr-no-flush",
|
||||
"nav-dma-send-from-spr-no-flush",
|
||||
"(method 17 nav-engine)",
|
||||
"(method 18 nav-engine)",
|
||||
"(method 21 nav-engine)",
|
||||
"(method 39 nav-state)",
|
||||
"setup-blerc-chains-for-one-fragment",
|
||||
"blerc-execute",
|
||||
"ripple-create-wave-table",
|
||||
"ripple-execute-init",
|
||||
"ripple-apply-wave-table",
|
||||
"ripple-matrix-scale",
|
||||
"(method 53 squid)",
|
||||
"init-vortex-regs",
|
||||
"render-vortex-quad",
|
||||
"draw-large-polygon-vortex",
|
||||
"foreground-generic-merc",
|
||||
"generic-merc-init-asm",
|
||||
"mercneric-convert",
|
||||
"high-speed-reject",
|
||||
"generic-translucent",
|
||||
"generic-merc-query",
|
||||
"generic-merc-death",
|
||||
"generic-merc-execute-asm",
|
||||
"generic-merc-do-chain",
|
||||
"generic-light-proc",
|
||||
"generic-envmap-proc",
|
||||
"generic-prepare-dma-double",
|
||||
"generic-prepare-dma-single",
|
||||
"generic-warp-source-proc",
|
||||
"generic-warp-dest-proc",
|
||||
"generic-warp-dest",
|
||||
"generic-warp-envmap-dest",
|
||||
"generic-no-light-proc"
|
||||
|
||||
],
|
||||
|
||||
"mips2c_jump_table_functions": {},
|
||||
|
||||
// there are some missing textures. I don't know what the game actually does here.
|
||||
// the format for entries is [level, tpage, index]
|
||||
"missing_textures": [],
|
||||
"missing_textures": [["vinroom", 0, 0]],
|
||||
|
||||
// some object files have garbage pad data at the end which makes the decompiler
|
||||
// assume they must be different files, such as the art group for orb-cache-top.
|
||||
|
@ -10,281 +10,281 @@
|
||||
"dgo_names":[
|
||||
//"CGO/ART.CGO",
|
||||
"CGO/KERNEL.CGO",
|
||||
"CGO/ENGINE.CGO",
|
||||
// "CGO/ENGINE.CGO",
|
||||
"CGO/GAME.CGO",
|
||||
"CGO/COMMON.CGO"
|
||||
//"DGO/LJKDMPK.DGO",
|
||||
//"DGO/LBBSDRP1.DGO",
|
||||
//"DGO/LTNJXHIP.DGO",
|
||||
//"DGO/MIC.DGO",
|
||||
//"DGO/OASISCST.DGO",
|
||||
//"DGO/CTYPEPA.DGO",
|
||||
//"DGO/LPRENME.DGO",
|
||||
//"DGO/LFREEOUT.DGO",
|
||||
//"DGO/LGUNNORM.DGO",
|
||||
//"DGO/LTOWA.DGO",
|
||||
//"DGO/TEMA.DGO",
|
||||
//"DGO/CTA.DGO",
|
||||
//"DGO/LPRECC.DGO",
|
||||
//"DGO/LJKDXVIN.DGO",
|
||||
//"DGO/CTYPEPC.DGO",
|
||||
//"DGO/SEA.DGO",
|
||||
//"DGO/COMBE.DGO",
|
||||
//"DGO/CTYPESA.DGO",
|
||||
//"DGO/LBLOWCST.DGO",
|
||||
//"DGO/WSD.DGO",
|
||||
//"DGO/LBBRING3.DGO",
|
||||
//"DGO/LCTYPATK.DGO",
|
||||
//"DGO/WCB.DGO",
|
||||
//"DGO/DESRESC.DGO",
|
||||
//"DGO/LBBRING4.DGO",
|
||||
//"DGO/GRIDCST.DGO",
|
||||
//"DGO/RAILX.DGO",
|
||||
//"DGO/SEJ.DGO",
|
||||
//"DGO/LJAKC.DGO",
|
||||
//"DGO/CTB.DGO",
|
||||
//"DGO/CTYCARC.DGO",
|
||||
//"DGO/LMECH.DGO",
|
||||
//"DGO/LBBSDRP2.DGO",
|
||||
//"DGO/NSA.DGO",
|
||||
//"DGO/LBBTCHA3.DGO",
|
||||
//"DGO/GUNGAME2.DGO",
|
||||
//"DGO/CTC.DGO",
|
||||
//"DGO/LVINCST.DGO",
|
||||
//"DGO/COMBX.DGO",
|
||||
//"DGO/DESH.DGO",
|
||||
//"DGO/DESRACE2.DGO",
|
||||
//"DGO/RAILD.DGO",
|
||||
//"DGO/FACC.DGO",
|
||||
//"DGO/CTYPESC.DGO",
|
||||
//"DGO/LWASBBV.DGO",
|
||||
//"DGO/TOWB.DGO",
|
||||
//"DGO/HGA.DGO",
|
||||
//"DGO/SEH.DGO",
|
||||
//"DGO/MHCTYCST.DGO",
|
||||
//"DGO/GUNGAME1.DGO",
|
||||
//"DGO/INTROCST.DGO",
|
||||
//"DGO/DESJUMP.DGO",
|
||||
//"DGO/SEM.DGO",
|
||||
//"DGO/SEI.DGO",
|
||||
//"DGO/DESG.DGO",
|
||||
//"DGO/DESW.DGO",
|
||||
//"DGO/LOUTRO3.DGO",
|
||||
//"DGO/LDAMKLEV.DGO",
|
||||
//"DGO/DESERROL.DGO",
|
||||
//"DGO/RAILB2.DGO",
|
||||
//"DGO/LERROL.DGO",
|
||||
//"DGO/IPF.DGO",
|
||||
//"DGO/RAILB.DGO",
|
||||
//"DGO/LCTYHIJK.DGO",
|
||||
//"DGO/CTYPEPB.DGO",
|
||||
//"DGO/PRECB.DGO",
|
||||
//"DGO/LFORM.DGO",
|
||||
//"DGO/WASLEAPR.DGO",
|
||||
//"DGO/LKEIRA.DGO",
|
||||
//"DGO/LJAK.DGO",
|
||||
//"DGO/SLUMBSET.DGO",
|
||||
//"DGO/FACD.DGO",
|
||||
//"DGO/LWASSIG.DGO",
|
||||
//"DGO/LBIPED.DGO",
|
||||
//"DGO/DESD.DGO",
|
||||
//"DGO/CFB.DGO",
|
||||
//"DGO/FREECAST.DGO",
|
||||
//"DGO/SEG.DGO",
|
||||
//"DGO/FACTORYA.DGO",
|
||||
//"DGO/LPATK.DGO",
|
||||
//"DGO/FRSTX.DGO",
|
||||
//"DGO/SEB.DGO",
|
||||
//"DGO/DESBCST.DGO",
|
||||
//"DGO/DESE.DGO",
|
||||
//"DGO/DESOASIS.DGO",
|
||||
//"DGO/CTYCARA.DGO",
|
||||
//"DGO/LSIGKLV.DGO",
|
||||
//"DGO/CIB.DGO",
|
||||
//"DGO/LBBRING2.DGO",
|
||||
//"DGO/LTNFXHIP.DGO",
|
||||
//"DGO/MIA.DGO",
|
||||
//"DGO/MHCB.DGO",
|
||||
//"DGO/LNSTOBC.DGO",
|
||||
//"DGO/COMBD.DGO",
|
||||
//"DGO/RBCT.DGO",
|
||||
//"DGO/LTORNJNX.DGO",
|
||||
//"DGO/DESBATTL.DGO",
|
||||
//"DGO/SEK.DGO",
|
||||
//"DGO/LSNKWHLS.DGO",
|
||||
//"DGO/LMHCB.DGO",
|
||||
//"DGO/LBOMBBOT.DGO",
|
||||
//"DGO/OUTCAST3.DGO",
|
||||
//"DGO/LBLOWTMH.DGO",
|
||||
//"DGO/TEMD.DGO",
|
||||
//"DGO/LTOWCITY.DGO",
|
||||
//"DGO/OUTROCST.DGO",
|
||||
//"DGO/WASCAST.DGO",
|
||||
//"DGO/LFACRM2.DGO",
|
||||
//"DGO/WASPGAME.DGO",
|
||||
//"DGO/RAILE.DGO",
|
||||
//"DGO/CTYPESB.DGO",
|
||||
//"DGO/DESBOSS1.DGO",
|
||||
//"DGO/FREEHQ.DGO",
|
||||
//"DGO/LTORN.DGO",
|
||||
//"DGO/TOWERA.DGO",
|
||||
//"DGO/LSAMOS.DGO",
|
||||
//"DGO/LFORP.DGO",
|
||||
//"DGO/CFA.DGO",
|
||||
//"DGO/LJINX.DGO",
|
||||
//"DGO/SEO.DGO",
|
||||
//"DGO/PRECA.DGO",
|
||||
//"DGO/TOWERC.DGO",
|
||||
//"DGO/WCA.DGO",
|
||||
//"DGO/SEC.DGO",
|
||||
//"DGO/DESF.DGO",
|
||||
//"DGO/SEL.DGO",
|
||||
//"DGO/LCTYDEST.DGO",
|
||||
//"DGO/LTORNSAM.DGO",
|
||||
//"DGO/MUSEUM3B.DGO",
|
||||
//"DGO/SEE.DGO",
|
||||
//"DGO/DESHUNT.DGO",
|
||||
//"DGO/RAILA.DGO",
|
||||
//"DGO/TITLE.DGO",
|
||||
//"DGO/RUBC.DGO",
|
||||
//"DGO/DESB.DGO",
|
||||
//"DGO/LFACCAR.DGO",
|
||||
//"DGO/LNSTOA.DGO",
|
||||
//"DGO/MUSEUM3.DGO",
|
||||
//"DGO/ONINTENT.DGO",
|
||||
//"DGO/STA.DGO",
|
||||
//"DGO/WASSTADA.DGO",
|
||||
//"DGO/POWERGD.DGO",
|
||||
//"DGO/LKLEEVER.DGO",
|
||||
//"DGO/FACB.DGO",
|
||||
//"DGO/LCTYASS.DGO",
|
||||
//"DGO/MHCA.DGO",
|
||||
//"DGO/LTOWB.DGO",
|
||||
//"DGO/LNSTCST.DGO",
|
||||
//"DGO/DESRESCG.DGO",
|
||||
//"DGO/INTPALRF.DGO",
|
||||
//"DGO/LMHCA.DGO",
|
||||
//"DGO/TOWERCST.DGO",
|
||||
//"DGO/RAILF.DGO",
|
||||
//"DGO/CIA.DGO",
|
||||
//"DGO/CTYCARKG.DGO",
|
||||
//"DGO/WASCHASE.DGO",
|
||||
//"DGO/LFACO.DGO",
|
||||
//"DGO/WIN.DGO",
|
||||
//"DGO/TEMPLEE.DGO",
|
||||
//"DGO/LBBSPIRT.DGO",
|
||||
//"DGO/MUSEUM2.DGO",
|
||||
//"DGO/INTTITLE.DGO",
|
||||
//"DGO/STAA.DGO",
|
||||
//"DGO/MUSEUM4B.DGO",
|
||||
//"DGO/PRECD.DGO",
|
||||
//"DGO/SEF.DGO",
|
||||
//"DGO/CTYCARB.DGO",
|
||||
//"DGO/WASDEFEN.DGO",
|
||||
//"DGO/LBLOWTKG.DGO",
|
||||
//"DGO/DESA.DGO",
|
||||
//"DGO/COMBB.DGO",
|
||||
//"DGO/WASSTADC.DGO",
|
||||
//"DGO/DESC.DGO",
|
||||
//"DGO/LDAMPECK.DGO",
|
||||
//"DGO/LJAKSIG.DGO",
|
||||
//"DGO/HALFPIPE.DGO",
|
||||
//"DGO/DESRACE1.DGO",
|
||||
//"DGO/SEN.DGO",
|
||||
//"DGO/TEMP.DGO",
|
||||
//"DGO/SED.DGO",
|
||||
//"DGO/LFACB.DGO",
|
||||
//"DGO/LCTYSNPR.DGO",
|
||||
//"DGO/LBBSPID.DGO",
|
||||
//"DGO/FRSTA.DGO",
|
||||
//"DGO/LBBRING5.DGO",
|
||||
//"DGO/LBBSPRT3.DGO",
|
||||
//"DGO/HHG.DGO",
|
||||
//"DGO/LBBSPRT2.DGO",
|
||||
//"DGO/CGB.DGO",
|
||||
//"DGO/LDMPCKGN.DGO",
|
||||
//"DGO/LSEEMWCA.DGO",
|
||||
//"DGO/HGB.DGO",
|
||||
//"DGO/LONINSIM.DGO",
|
||||
//"DGO/RUBA.DGO",
|
||||
//"DGO/DESRALLY.DGO",
|
||||
//"DGO/WWD.DGO",
|
||||
//"DGO/STB.DGO",
|
||||
//"DGO/MIB.DGO",
|
||||
//"DGO/LCTYBLOW.DGO",
|
||||
//"DGO/LWSTDPCK.DGO",
|
||||
//"DGO/MUSEUM.DGO",
|
||||
//"DGO/LJAKCKLV.DGO",
|
||||
//"DGO/LBBRING1.DGO",
|
||||
//"DGO/MUSEUM4.DGO",
|
||||
//"DGO/LFACRM1.DGO",
|
||||
//"DGO/LJKCDMKL.DGO",
|
||||
//"DGO/LDAMSIG.DGO",
|
||||
//"DGO/DESTRACK.DGO",
|
||||
//"DGO/GGA.DGO",
|
||||
//"DGO/RAILC.DGO",
|
||||
//"DGO/LBBTCHA2.DGO",
|
||||
//"DGO/DESINTER.DGO",
|
||||
//"DGO/NSB.DGO",
|
||||
//"DGO/LOUTRO.DGO",
|
||||
//"DGO/VIN.DGO",
|
||||
//"DGO/LDESGCST.DGO",
|
||||
//"DGO/WARPCAST.DGO",
|
||||
//"DGO/LBBRING6.DGO",
|
||||
//"DGO/FRSTB.DGO",
|
||||
//"DGO/TEMC.DGO",
|
||||
//"DGO/COMBC.DGO",
|
||||
//"DGO/LTRTWHLS.DGO",
|
||||
//"DGO/PRECC.DGO",
|
||||
//"DGO/DESCHASE.DGO",
|
||||
//"DGO/CITYCAST.DGO",
|
||||
//"DGO/CPO.DGO",
|
||||
//"DGO/LFACCITY.DGO",
|
||||
//"DGO/RAILCST.DGO",
|
||||
//"DGO/LJNDKLEV.DGO",
|
||||
//"DGO/CWI.DGO",
|
||||
//"DGO/MINEE.DGO",
|
||||
//"DGO/LFORRING.DGO",
|
||||
//"DGO/LASHELIN.DGO",
|
||||
//"DGO/LJAKKLEV.DGO",
|
||||
//"DGO/LCTYPALT.DGO",
|
||||
//"DGO/LNSTOBB.DGO",
|
||||
//"DGO/LJKFEET.DGO",
|
||||
//"DGO/DST.DGO",
|
||||
//"DGO/LBBTCHA1.DGO",
|
||||
//"DGO/LGUNRNC.DGO",
|
||||
//"DGO/COMBN.DGO",
|
||||
//"DGO/DESRESCC.DGO",
|
||||
//"DGO/LSIGJAKC.DGO",
|
||||
//"DGO/DESLIZ.DGO",
|
||||
//"DGO/WASPALA.DGO",
|
||||
//"DGO/LJAKNDAX.DGO",
|
||||
//"DGO/WASSEEM.DGO",
|
||||
//"DGO/WASALL.DGO",
|
||||
//"DGO/WCASEEM.DGO",
|
||||
//"DGO/LSIG.DGO",
|
||||
//"DGO/LFACTORY.DGO",
|
||||
//"DGO/LWLANDM.DGO",
|
||||
//"DGO/LPTRL.DGO",
|
||||
//"DGO/MINED.DGO",
|
||||
//"DGO/LDAMPKSM.DGO",
|
||||
//"DGO/RUBB.DGO",
|
||||
//"DGO/LCITYSML.DGO",
|
||||
//"DGO/RUBA2.DGO",
|
||||
//"DGO/LOUTRO2.DGO",
|
||||
//"DGO/VOCX.DGO",
|
||||
//"DGO/TEMX.DGO",
|
||||
//"DGO/ARENACST.DGO",
|
||||
//"DGO/TEMB.DGO",
|
||||
//"DGO/COMBA.DGO",
|
||||
//"DGO/LBBSDRP3.DGO",
|
||||
//"DGO/LPATKCS.DGO",
|
||||
//"DGO/VOCA.DGO",
|
||||
//"DGO/WASSTADB.DGO",
|
||||
//"DGO/LDAX.DGO",
|
||||
//"DGO/LCTYPROT.DGO",
|
||||
//"DGO/DESHOVER.DGO",
|
||||
//"DGO/DESBOSS2.DGO"
|
||||
// "CGO/COMMON.CGO",
|
||||
"DGO/LJKDMPK.DGO",
|
||||
"DGO/LBBSDRP1.DGO",
|
||||
"DGO/LTNJXHIP.DGO",
|
||||
"DGO/MIC.DGO",
|
||||
"DGO/OASISCST.DGO",
|
||||
"DGO/CTYPEPA.DGO",
|
||||
"DGO/LPRENME.DGO",
|
||||
"DGO/LFREEOUT.DGO",
|
||||
"DGO/LGUNNORM.DGO",
|
||||
"DGO/LTOWA.DGO",
|
||||
"DGO/TEMA.DGO",
|
||||
"DGO/CTA.DGO",
|
||||
"DGO/LPRECC.DGO",
|
||||
"DGO/LJKDXVIN.DGO",
|
||||
"DGO/CTYPEPC.DGO",
|
||||
"DGO/SEA.DGO",
|
||||
"DGO/COMBE.DGO",
|
||||
"DGO/CTYPESA.DGO",
|
||||
"DGO/LBLOWCST.DGO",
|
||||
"DGO/WSD.DGO",
|
||||
"DGO/LBBRING3.DGO",
|
||||
"DGO/LCTYPATK.DGO",
|
||||
"DGO/WCB.DGO",
|
||||
"DGO/DESRESC.DGO",
|
||||
"DGO/LBBRING4.DGO",
|
||||
"DGO/GRIDCST.DGO",
|
||||
"DGO/RAILX.DGO",
|
||||
"DGO/SEJ.DGO",
|
||||
"DGO/LJAKC.DGO",
|
||||
"DGO/CTB.DGO",
|
||||
"DGO/CTYCARC.DGO",
|
||||
"DGO/LMECH.DGO",
|
||||
"DGO/LBBSDRP2.DGO",
|
||||
"DGO/NSA.DGO",
|
||||
"DGO/LBBTCHA3.DGO",
|
||||
"DGO/GUNGAME2.DGO",
|
||||
"DGO/CTC.DGO",
|
||||
"DGO/LVINCST.DGO",
|
||||
"DGO/COMBX.DGO",
|
||||
"DGO/DESH.DGO",
|
||||
"DGO/DESRACE2.DGO",
|
||||
"DGO/RAILD.DGO",
|
||||
"DGO/FACC.DGO",
|
||||
"DGO/CTYPESC.DGO",
|
||||
"DGO/LWASBBV.DGO",
|
||||
"DGO/TOWB.DGO",
|
||||
"DGO/HGA.DGO",
|
||||
"DGO/SEH.DGO",
|
||||
"DGO/MHCTYCST.DGO",
|
||||
"DGO/GUNGAME1.DGO",
|
||||
"DGO/INTROCST.DGO",
|
||||
"DGO/DESJUMP.DGO",
|
||||
"DGO/SEM.DGO",
|
||||
"DGO/SEI.DGO",
|
||||
"DGO/DESG.DGO",
|
||||
"DGO/DESW.DGO",
|
||||
"DGO/LOUTRO3.DGO",
|
||||
"DGO/LDAMKLEV.DGO",
|
||||
"DGO/DESERROL.DGO",
|
||||
"DGO/RAILB2.DGO",
|
||||
"DGO/LERROL.DGO",
|
||||
"DGO/IPF.DGO",
|
||||
"DGO/RAILB.DGO",
|
||||
"DGO/LCTYHIJK.DGO",
|
||||
"DGO/CTYPEPB.DGO",
|
||||
"DGO/PRECB.DGO",
|
||||
"DGO/LFORM.DGO",
|
||||
"DGO/WASLEAPR.DGO",
|
||||
"DGO/LKEIRA.DGO",
|
||||
"DGO/LJAK.DGO",
|
||||
"DGO/SLUMBSET.DGO",
|
||||
"DGO/FACD.DGO",
|
||||
"DGO/LWASSIG.DGO",
|
||||
"DGO/LBIPED.DGO",
|
||||
"DGO/DESD.DGO",
|
||||
"DGO/CFB.DGO",
|
||||
"DGO/FREECAST.DGO",
|
||||
"DGO/SEG.DGO",
|
||||
"DGO/FACTORYA.DGO",
|
||||
"DGO/LPATK.DGO",
|
||||
"DGO/FRSTX.DGO",
|
||||
"DGO/SEB.DGO",
|
||||
"DGO/DESBCST.DGO",
|
||||
"DGO/DESE.DGO",
|
||||
"DGO/DESOASIS.DGO",
|
||||
"DGO/CTYCARA.DGO",
|
||||
"DGO/LSIGKLV.DGO",
|
||||
"DGO/CIB.DGO",
|
||||
"DGO/LBBRING2.DGO",
|
||||
"DGO/LTNFXHIP.DGO",
|
||||
"DGO/MIA.DGO",
|
||||
"DGO/MHCB.DGO",
|
||||
"DGO/LNSTOBC.DGO",
|
||||
"DGO/COMBD.DGO",
|
||||
"DGO/RBCT.DGO",
|
||||
"DGO/LTORNJNX.DGO",
|
||||
"DGO/DESBATTL.DGO",
|
||||
"DGO/SEK.DGO",
|
||||
"DGO/LSNKWHLS.DGO",
|
||||
"DGO/LMHCB.DGO",
|
||||
"DGO/LBOMBBOT.DGO",
|
||||
"DGO/OUTCAST3.DGO",
|
||||
"DGO/LBLOWTMH.DGO",
|
||||
"DGO/TEMD.DGO",
|
||||
"DGO/LTOWCITY.DGO",
|
||||
"DGO/OUTROCST.DGO",
|
||||
"DGO/WASCAST.DGO",
|
||||
"DGO/LFACRM2.DGO",
|
||||
"DGO/WASPGAME.DGO",
|
||||
"DGO/RAILE.DGO",
|
||||
"DGO/CTYPESB.DGO",
|
||||
"DGO/DESBOSS1.DGO",
|
||||
"DGO/FREEHQ.DGO",
|
||||
"DGO/LTORN.DGO",
|
||||
"DGO/TOWERA.DGO",
|
||||
"DGO/LSAMOS.DGO",
|
||||
"DGO/LFORP.DGO",
|
||||
"DGO/CFA.DGO",
|
||||
"DGO/LJINX.DGO",
|
||||
"DGO/SEO.DGO",
|
||||
"DGO/PRECA.DGO",
|
||||
"DGO/TOWERC.DGO",
|
||||
"DGO/WCA.DGO",
|
||||
"DGO/SEC.DGO",
|
||||
"DGO/DESF.DGO",
|
||||
"DGO/SEL.DGO",
|
||||
"DGO/LCTYDEST.DGO",
|
||||
"DGO/LTORNSAM.DGO",
|
||||
"DGO/MUSEUM3B.DGO",
|
||||
"DGO/SEE.DGO",
|
||||
"DGO/DESHUNT.DGO",
|
||||
"DGO/RAILA.DGO",
|
||||
"DGO/TITLE.DGO",
|
||||
"DGO/RUBC.DGO",
|
||||
"DGO/DESB.DGO",
|
||||
"DGO/LFACCAR.DGO",
|
||||
"DGO/LNSTOA.DGO",
|
||||
"DGO/MUSEUM3.DGO",
|
||||
"DGO/ONINTENT.DGO",
|
||||
"DGO/STA.DGO",
|
||||
"DGO/WASSTADA.DGO",
|
||||
"DGO/POWERGD.DGO",
|
||||
"DGO/LKLEEVER.DGO",
|
||||
"DGO/FACB.DGO",
|
||||
"DGO/LCTYASS.DGO",
|
||||
"DGO/MHCA.DGO",
|
||||
"DGO/LTOWB.DGO",
|
||||
"DGO/LNSTCST.DGO",
|
||||
"DGO/DESRESCG.DGO",
|
||||
"DGO/INTPALRF.DGO",
|
||||
"DGO/LMHCA.DGO",
|
||||
"DGO/TOWERCST.DGO",
|
||||
"DGO/RAILF.DGO",
|
||||
"DGO/CIA.DGO",
|
||||
"DGO/CTYCARKG.DGO",
|
||||
"DGO/WASCHASE.DGO",
|
||||
"DGO/LFACO.DGO",
|
||||
"DGO/WIN.DGO",
|
||||
"DGO/TEMPLEE.DGO",
|
||||
"DGO/LBBSPIRT.DGO",
|
||||
"DGO/MUSEUM2.DGO",
|
||||
"DGO/INTTITLE.DGO",
|
||||
"DGO/STAA.DGO",
|
||||
"DGO/MUSEUM4B.DGO",
|
||||
"DGO/PRECD.DGO",
|
||||
"DGO/SEF.DGO",
|
||||
"DGO/CTYCARB.DGO",
|
||||
"DGO/WASDEFEN.DGO",
|
||||
"DGO/LBLOWTKG.DGO",
|
||||
"DGO/DESA.DGO",
|
||||
"DGO/COMBB.DGO",
|
||||
"DGO/WASSTADC.DGO",
|
||||
"DGO/DESC.DGO",
|
||||
"DGO/LDAMPECK.DGO",
|
||||
"DGO/LJAKSIG.DGO",
|
||||
"DGO/HALFPIPE.DGO",
|
||||
"DGO/DESRACE1.DGO",
|
||||
"DGO/SEN.DGO",
|
||||
"DGO/TEMP.DGO",
|
||||
"DGO/SED.DGO",
|
||||
"DGO/LFACB.DGO",
|
||||
"DGO/LCTYSNPR.DGO",
|
||||
"DGO/LBBSPID.DGO",
|
||||
"DGO/FRSTA.DGO",
|
||||
"DGO/LBBRING5.DGO",
|
||||
"DGO/LBBSPRT3.DGO",
|
||||
"DGO/HHG.DGO",
|
||||
"DGO/LBBSPRT2.DGO",
|
||||
"DGO/CGB.DGO",
|
||||
"DGO/LDMPCKGN.DGO",
|
||||
"DGO/LSEEMWCA.DGO",
|
||||
"DGO/HGB.DGO",
|
||||
"DGO/LONINSIM.DGO",
|
||||
"DGO/RUBA.DGO",
|
||||
"DGO/DESRALLY.DGO",
|
||||
"DGO/WWD.DGO",
|
||||
"DGO/STB.DGO",
|
||||
"DGO/MIB.DGO",
|
||||
"DGO/LCTYBLOW.DGO",
|
||||
"DGO/LWSTDPCK.DGO",
|
||||
"DGO/MUSEUM.DGO",
|
||||
"DGO/LJAKCKLV.DGO",
|
||||
"DGO/LBBRING1.DGO",
|
||||
"DGO/MUSEUM4.DGO",
|
||||
"DGO/LFACRM1.DGO",
|
||||
"DGO/LJKCDMKL.DGO",
|
||||
"DGO/LDAMSIG.DGO",
|
||||
"DGO/DESTRACK.DGO",
|
||||
"DGO/GGA.DGO",
|
||||
"DGO/RAILC.DGO",
|
||||
"DGO/LBBTCHA2.DGO",
|
||||
"DGO/DESINTER.DGO",
|
||||
"DGO/NSB.DGO",
|
||||
"DGO/LOUTRO.DGO",
|
||||
"DGO/VIN.DGO",
|
||||
"DGO/LDESGCST.DGO",
|
||||
"DGO/WARPCAST.DGO",
|
||||
"DGO/LBBRING6.DGO",
|
||||
"DGO/FRSTB.DGO",
|
||||
"DGO/TEMC.DGO",
|
||||
"DGO/COMBC.DGO",
|
||||
"DGO/LTRTWHLS.DGO",
|
||||
"DGO/PRECC.DGO",
|
||||
"DGO/DESCHASE.DGO",
|
||||
"DGO/CITYCAST.DGO",
|
||||
"DGO/CPO.DGO",
|
||||
"DGO/LFACCITY.DGO",
|
||||
"DGO/RAILCST.DGO",
|
||||
"DGO/LJNDKLEV.DGO",
|
||||
"DGO/CWI.DGO",
|
||||
"DGO/MINEE.DGO",
|
||||
"DGO/LFORRING.DGO",
|
||||
"DGO/LASHELIN.DGO",
|
||||
"DGO/LJAKKLEV.DGO",
|
||||
"DGO/LCTYPALT.DGO",
|
||||
"DGO/LNSTOBB.DGO",
|
||||
"DGO/LJKFEET.DGO",
|
||||
"DGO/DST.DGO",
|
||||
"DGO/LBBTCHA1.DGO",
|
||||
"DGO/LGUNRNC.DGO",
|
||||
"DGO/COMBN.DGO",
|
||||
"DGO/DESRESCC.DGO",
|
||||
"DGO/LSIGJAKC.DGO",
|
||||
"DGO/DESLIZ.DGO",
|
||||
"DGO/WASPALA.DGO",
|
||||
"DGO/LJAKNDAX.DGO",
|
||||
"DGO/WASSEEM.DGO",
|
||||
"DGO/WASALL.DGO",
|
||||
"DGO/WCASEEM.DGO",
|
||||
"DGO/LSIG.DGO",
|
||||
"DGO/LFACTORY.DGO",
|
||||
"DGO/LWLANDM.DGO",
|
||||
"DGO/LPTRL.DGO",
|
||||
"DGO/MINED.DGO",
|
||||
"DGO/LDAMPKSM.DGO",
|
||||
"DGO/RUBB.DGO",
|
||||
"DGO/LCITYSML.DGO",
|
||||
"DGO/RUBA2.DGO",
|
||||
"DGO/LOUTRO2.DGO",
|
||||
"DGO/VOCX.DGO",
|
||||
"DGO/TEMX.DGO",
|
||||
"DGO/ARENACST.DGO",
|
||||
"DGO/TEMB.DGO",
|
||||
"DGO/COMBA.DGO",
|
||||
"DGO/LBBSDRP3.DGO",
|
||||
"DGO/LPATKCS.DGO",
|
||||
"DGO/VOCA.DGO",
|
||||
"DGO/WASSTADB.DGO",
|
||||
"DGO/LDAX.DGO",
|
||||
"DGO/LCTYPROT.DGO",
|
||||
"DGO/DESHOVER.DGO",
|
||||
"DGO/DESBOSS2.DGO"
|
||||
],
|
||||
|
||||
// some objects are part of STR files (streaming data).
|
||||
|
1
decompiler/config/jak3/ntsc_v1/joint-node-info.min.json
Normal file
1
decompiler/config/jak3/ntsc_v1/joint-node-info.min.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
@ -160,6 +160,11 @@ void DecompilerTypeSystem::add_type_parent(const std::string& child, const std::
|
||||
}
|
||||
|
||||
std::string DecompilerTypeSystem::lookup_parent_from_inspects(const std::string& child) const {
|
||||
if (child == "process-tree")
|
||||
return "basic";
|
||||
if (child == "process")
|
||||
return "process-tree";
|
||||
|
||||
auto kv_tp = type_parents.find(child);
|
||||
if (kv_tp != type_parents.end()) {
|
||||
return kv_tp->second;
|
||||
@ -169,6 +174,15 @@ std::string DecompilerTypeSystem::lookup_parent_from_inspects(const std::string&
|
||||
}
|
||||
|
||||
bool DecompilerTypeSystem::lookup_flags(const std::string& type, u64* dest) const {
|
||||
if (type == "process-tree") {
|
||||
*dest = ((u64)0xe << 32) + (0 << 16) + 0x24;
|
||||
return true;
|
||||
}
|
||||
if (type == "process") {
|
||||
*dest = ((u64)0xe << 32) + (0 << 16) + 0x80;
|
||||
return true;
|
||||
}
|
||||
|
||||
auto kv = type_flags.find(type);
|
||||
if (kv != type_flags.end()) {
|
||||
*dest = kv->second;
|
||||
|
2764
goal_src/jak3/build/all_objs.json
Normal file
2764
goal_src/jak3/build/all_objs.json
Normal file
File diff suppressed because it is too large
Load Diff
6
scripts/shell/decomp3.sh
Executable file
6
scripts/shell/decomp3.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Directory of this script
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
"${DIR}"/../../build/decompiler/decompiler "${DIR}"/../../decompiler/config/jak3/jak3_config.jsonc "${DIR}"/../../iso_data/ "${DIR}"/../../decompiler_out --version ntsc_v1
|
Loading…
Reference in New Issue
Block a user