mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
[decompiler] Clean up config more (#458)
* remove global config * fix dir
This commit is contained in:
parent
d7d563814f
commit
0599d144f8
|
@ -727,7 +727,8 @@ int detect(int idx, Function& function, LinkedObjectFile& file, TypeInspectorRes
|
|||
TypeInspectorResult inspect_inspect_method(Function& inspect,
|
||||
const std::string& type_name,
|
||||
DecompilerTypeSystem& dts,
|
||||
LinkedObjectFile& file) {
|
||||
LinkedObjectFile& file,
|
||||
bool skip_fields) {
|
||||
TypeInspectorResult result;
|
||||
TypeFlags flags;
|
||||
flags.flag = 0;
|
||||
|
@ -740,9 +741,8 @@ TypeInspectorResult inspect_inspect_method(Function& inspect,
|
|||
result.type_heap_base = flags.heap_base;
|
||||
assert(flags.pad == 0);
|
||||
|
||||
auto& bad_set = get_config().bad_inspect_types;
|
||||
int idx = get_start_idx(inspect, file, &result, result.parent_type_name);
|
||||
if (idx == 0 || bad_set.find(type_name) != bad_set.end()) {
|
||||
if (idx == 0 || skip_fields) {
|
||||
// printf("was weird: %s\n", result.warnings.c_str());
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -35,5 +35,6 @@ struct TypeInspectorResult {
|
|||
TypeInspectorResult inspect_inspect_method(Function& inspect,
|
||||
const std::string& type_name,
|
||||
DecompilerTypeSystem& dts,
|
||||
LinkedObjectFile& file);
|
||||
LinkedObjectFile& file,
|
||||
bool skip_fields);
|
||||
} // namespace decompiler
|
|
@ -680,8 +680,7 @@ std::string LinkedObjectFile::print_asm_function_disassembly(const std::string&
|
|||
/*!
|
||||
* Print disassembled functions and data segments.
|
||||
*/
|
||||
std::string LinkedObjectFile::print_disassembly() {
|
||||
bool write_hex = get_config().write_hex_near_instructions;
|
||||
std::string LinkedObjectFile::print_disassembly(bool write_hex) {
|
||||
std::string result;
|
||||
|
||||
assert(segments <= 3);
|
||||
|
|
|
@ -51,7 +51,7 @@ class LinkedObjectFile {
|
|||
void disassemble_functions();
|
||||
void process_fp_relative_links();
|
||||
std::string print_scripts();
|
||||
std::string print_disassembly();
|
||||
std::string print_disassembly(bool write_hex);
|
||||
bool has_any_functions();
|
||||
void append_word_to_string(std::string& dest, const LinkedWord& word) const;
|
||||
std::string print_function_disassembly(Function& func,
|
||||
|
|
|
@ -609,7 +609,8 @@ static void link_v5(LinkedObjectFile& f,
|
|||
static void link_v3(LinkedObjectFile& f,
|
||||
const std::vector<uint8_t>& data,
|
||||
const std::string& name,
|
||||
DecompilerTypeSystem& dts) {
|
||||
DecompilerTypeSystem& dts,
|
||||
int game_version) {
|
||||
auto header = (const LinkHeaderV3*)(&data.at(0));
|
||||
assert(name == header->name);
|
||||
assert(header->segments == 3);
|
||||
|
@ -656,11 +657,11 @@ static void link_v3(LinkedObjectFile& f,
|
|||
// HACK!
|
||||
// why is this a thing?
|
||||
// HACK!
|
||||
if (get_config().game_version == 1 && name == "level-h" && seg_id == 0) {
|
||||
if (game_version == 1 && name == "level-h" && seg_id == 0) {
|
||||
segment_size++;
|
||||
}
|
||||
|
||||
if (get_config().game_version == 2) {
|
||||
if (game_version == 2) {
|
||||
bool adjusted = false;
|
||||
while (segment_size % 4) {
|
||||
segment_size++;
|
||||
|
@ -800,14 +801,15 @@ static void link_v3(LinkedObjectFile& f,
|
|||
*/
|
||||
LinkedObjectFile to_linked_object_file(const std::vector<uint8_t>& data,
|
||||
const std::string& name,
|
||||
DecompilerTypeSystem& dts) {
|
||||
DecompilerTypeSystem& dts,
|
||||
int game_version) {
|
||||
LinkedObjectFile result;
|
||||
const auto* header = (const LinkHeaderCommon*)&data.at(0);
|
||||
|
||||
// use appropriate linker
|
||||
if (header->version == 3) {
|
||||
assert(header->type_tag == 0);
|
||||
link_v3(result, data, name, dts);
|
||||
link_v3(result, data, name, dts, game_version);
|
||||
} else if (header->version == 4 || header->version == 2) {
|
||||
assert(header->type_tag == 0xffffffff);
|
||||
link_v2_or_v4(result, data, name, dts);
|
||||
|
|
|
@ -6,16 +6,12 @@
|
|||
* This implements a decoder for the GOAL linking format.
|
||||
*/
|
||||
|
||||
#ifndef NEXT_LINKEDOBJECTFILECREATION_H
|
||||
#define NEXT_LINKEDOBJECTFILECREATION_H
|
||||
|
||||
#include "LinkedObjectFile.h"
|
||||
|
||||
namespace decompiler {
|
||||
class DecompilerTypeSystem;
|
||||
LinkedObjectFile to_linked_object_file(const std::vector<uint8_t>& data,
|
||||
const std::string& name,
|
||||
DecompilerTypeSystem& dts);
|
||||
DecompilerTypeSystem& dts,
|
||||
int game_version);
|
||||
} // namespace decompiler
|
||||
|
||||
#endif // NEXT_LINKEDOBJECTFILECREATION_H
|
||||
|
|
|
@ -110,7 +110,8 @@ ObjectFileData& ObjectFileDB::lookup_record(const ObjectFileRecord& rec) {
|
|||
ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos,
|
||||
const std::string& obj_file_name_map_file,
|
||||
const std::vector<std::string>& object_files,
|
||||
const std::vector<std::string>& str_files) {
|
||||
const std::vector<std::string>& str_files,
|
||||
const Config& config) {
|
||||
Timer timer;
|
||||
|
||||
lg::info("-Loading types...");
|
||||
|
@ -128,14 +129,14 @@ ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos,
|
|||
|
||||
lg::info("-Loading {} DGOs...", _dgos.size());
|
||||
for (auto& dgo : _dgos) {
|
||||
get_objs_from_dgo(dgo);
|
||||
get_objs_from_dgo(dgo, config);
|
||||
}
|
||||
|
||||
lg::info("-Loading {} plain object files...", object_files.size());
|
||||
for (auto& obj : object_files) {
|
||||
auto data = file_util::read_binary_file(obj);
|
||||
auto name = obj_filename_to_name(obj);
|
||||
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO");
|
||||
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO", config);
|
||||
}
|
||||
|
||||
lg::info("-Loading {} streaming object files...", str_files.size());
|
||||
|
@ -149,7 +150,7 @@ ObjectFileDB::ObjectFileDB(const std::vector<std::string>& _dgos,
|
|||
// append the chunk ID to the full name
|
||||
std::string name = obj_name + fmt::format("+{}", i);
|
||||
auto& data = reader.get_chunk(i);
|
||||
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO");
|
||||
add_obj_from_dgo(name, name, data.data(), data.size(), "NO-XGO", config);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,7 +191,7 @@ constexpr int MAX_CHUNK_SIZE = 0x8000;
|
|||
/*!
|
||||
* Load the objects stored in the given DGO into the ObjectFileDB
|
||||
*/
|
||||
void ObjectFileDB::get_objs_from_dgo(const std::string& filename) {
|
||||
void ObjectFileDB::get_objs_from_dgo(const std::string& filename, const Config& config) {
|
||||
auto dgo_data = file_util::read_binary_file(filename);
|
||||
stats.total_dgo_bytes += dgo_data.size();
|
||||
|
||||
|
@ -221,7 +222,8 @@ void ObjectFileDB::get_objs_from_dgo(const std::string& filename) {
|
|||
|
||||
auto name = get_object_file_name(obj_header.name, reader.here(), obj_header.object_count);
|
||||
|
||||
add_obj_from_dgo(name, obj_header.name, reader.here(), obj_header.object_count, dgo_base_name);
|
||||
add_obj_from_dgo(name, obj_header.name, reader.here(), obj_header.object_count, dgo_base_name,
|
||||
config);
|
||||
reader.ffwd(obj_header.object_count);
|
||||
}
|
||||
|
||||
|
@ -236,8 +238,8 @@ void ObjectFileDB::add_obj_from_dgo(const std::string& obj_name,
|
|||
const std::string& name_in_dgo,
|
||||
const uint8_t* obj_data,
|
||||
uint32_t obj_size,
|
||||
const std::string& dgo_name) {
|
||||
const auto& config = get_config();
|
||||
const std::string& dgo_name,
|
||||
const Config& config) {
|
||||
if (!config.allowed_objects.empty()) {
|
||||
if (config.allowed_objects.find(obj_name) == config.allowed_objects.end()) {
|
||||
return;
|
||||
|
@ -390,14 +392,14 @@ std::string ObjectFileDB::generate_obj_listing() {
|
|||
/*!
|
||||
* Process all of the linking data of all objects.
|
||||
*/
|
||||
void ObjectFileDB::process_link_data() {
|
||||
void ObjectFileDB::process_link_data(const Config& config) {
|
||||
lg::info("Processing Link Data...");
|
||||
Timer process_link_timer;
|
||||
|
||||
LinkedObjectFile::Stats combined_stats;
|
||||
|
||||
for_each_obj([&](ObjectFileData& obj) {
|
||||
obj.linked_data = to_linked_object_file(obj.data, obj.record.name, dts);
|
||||
obj.linked_data = to_linked_object_file(obj.data, obj.record.name, dts, config.game_version);
|
||||
combined_stats.add(obj.linked_data.stats);
|
||||
});
|
||||
|
||||
|
@ -454,7 +456,8 @@ void ObjectFileDB::write_object_file_words(const std::string& output_dir,
|
|||
*/
|
||||
void ObjectFileDB::write_disassembly(const std::string& output_dir,
|
||||
bool disassemble_data,
|
||||
bool disassemble_code) {
|
||||
bool disassemble_code,
|
||||
bool print_hex) {
|
||||
lg::info("- Writing functions...");
|
||||
Timer timer;
|
||||
uint32_t total_bytes = 0, total_files = 0;
|
||||
|
@ -463,7 +466,7 @@ void ObjectFileDB::write_disassembly(const std::string& output_dir,
|
|||
|
||||
for_each_obj([&](ObjectFileData& obj) {
|
||||
if ((obj.obj_version == 3 && disassemble_code) || (obj.obj_version != 3 && disassemble_data)) {
|
||||
auto file_text = obj.linked_data.print_disassembly();
|
||||
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 = file_util::combine_path(output_dir, obj.to_unique_name() + ".asm");
|
||||
|
||||
|
@ -488,7 +491,7 @@ void ObjectFileDB::write_disassembly(const std::string& output_dir,
|
|||
/*!
|
||||
* Find code/data zones, identify functions, and disassemble
|
||||
*/
|
||||
void ObjectFileDB::find_code() {
|
||||
void ObjectFileDB::find_code(const Config& config) {
|
||||
lg::info("Finding code in object files...");
|
||||
LinkedObjectFile::Stats combined_stats;
|
||||
Timer timer;
|
||||
|
@ -499,7 +502,7 @@ void ObjectFileDB::find_code() {
|
|||
obj.linked_data.find_functions();
|
||||
obj.linked_data.disassemble_functions();
|
||||
|
||||
if (get_config().game_version == 1 || obj.to_unique_name() != "effect-control-v0") {
|
||||
if (config.game_version == 1 || obj.to_unique_name() != "effect-control-v0") {
|
||||
obj.linked_data.process_fp_relative_links();
|
||||
} else {
|
||||
lg::warn("Skipping process_fp_relative_links in {}", obj.to_unique_name().c_str());
|
||||
|
@ -619,12 +622,11 @@ std::string ObjectFileDB::process_game_count_file() {
|
|||
/*!
|
||||
* This is the main decompiler routine which runs after we've identified functions.
|
||||
*/
|
||||
void ObjectFileDB::analyze_functions_ir1() {
|
||||
void ObjectFileDB::analyze_functions_ir1(const Config& config) {
|
||||
lg::info("- Analyzing Functions...");
|
||||
Timer timer;
|
||||
|
||||
int total_functions = 0;
|
||||
const auto& config = get_config();
|
||||
|
||||
// Step 1 - analyze the "top level" or "login" code for each object file.
|
||||
// this will give us type definitions, method definitions, and function definitions...
|
||||
|
@ -665,7 +667,8 @@ void ObjectFileDB::analyze_functions_ir1() {
|
|||
|
||||
unique_names.insert(name);
|
||||
|
||||
if (config.asm_functions_by_name.find(name) != config.asm_functions_by_name.end()) {
|
||||
if (config.hacks.asm_functions_by_name.find(name) !=
|
||||
config.hacks.asm_functions_by_name.end()) {
|
||||
func.warnings.info("Flagged as asm by config");
|
||||
func.suspected_asm = true;
|
||||
}
|
||||
|
@ -735,7 +738,10 @@ void ObjectFileDB::analyze_functions_ir1() {
|
|||
|
||||
// if we got an inspect method, inspect it.
|
||||
if (func.is_inspect_method) {
|
||||
auto result = inspect_inspect_method(func, func.method_of_type, dts, data.linked_data);
|
||||
auto result = inspect_inspect_method(
|
||||
func, func.method_of_type, dts, data.linked_data,
|
||||
config.hacks.types_with_bad_inspect_methods.find(func.method_of_type) !=
|
||||
config.hacks.types_with_bad_inspect_methods.end());
|
||||
all_type_defs += ";; " + data.to_unique_name() + "\n";
|
||||
all_type_defs += result.print_as_deftype() + "\n";
|
||||
}
|
||||
|
|
|
@ -49,32 +49,34 @@ class ObjectFileDB {
|
|||
ObjectFileDB(const std::vector<std::string>& _dgos,
|
||||
const std::string& obj_file_name_map_file,
|
||||
const std::vector<std::string>& object_files,
|
||||
const std::vector<std::string>& str_files);
|
||||
const std::vector<std::string>& str_files,
|
||||
const Config& config);
|
||||
std::string generate_dgo_listing();
|
||||
std::string generate_obj_listing();
|
||||
void process_link_data();
|
||||
void process_link_data(const Config& config);
|
||||
void process_labels();
|
||||
void find_code();
|
||||
void find_code(const Config& config);
|
||||
void find_and_write_scripts(const std::string& output_dir);
|
||||
void dump_raw_objects(const std::string& output_dir);
|
||||
|
||||
void write_object_file_words(const std::string& output_dir, bool dump_data, bool dump_code);
|
||||
void write_disassembly(const std::string& output_dir,
|
||||
bool disassemble_data,
|
||||
bool disassemble_code);
|
||||
bool disassemble_code,
|
||||
bool print_hex);
|
||||
|
||||
void analyze_functions_ir1();
|
||||
void analyze_functions_ir2(const std::string& output_dir);
|
||||
void ir2_top_level_pass();
|
||||
void analyze_functions_ir1(const Config& config);
|
||||
void analyze_functions_ir2(const std::string& output_dir, const Config& config);
|
||||
void ir2_top_level_pass(const Config& config);
|
||||
void ir2_stack_spill_slot_pass();
|
||||
void ir2_basic_block_pass();
|
||||
void ir2_atomic_op_pass();
|
||||
void ir2_type_analysis_pass();
|
||||
void ir2_atomic_op_pass(const Config& config);
|
||||
void ir2_type_analysis_pass(const Config& config);
|
||||
void ir2_register_usage_pass();
|
||||
void ir2_variable_pass();
|
||||
void ir2_cfg_build_pass();
|
||||
void ir2_store_current_forms();
|
||||
void ir2_build_expressions();
|
||||
void ir2_build_expressions(const Config& config);
|
||||
void ir2_insert_lets();
|
||||
void ir2_rewrite_inline_asm_instructions();
|
||||
void ir2_insert_anonymous_functions();
|
||||
|
@ -94,16 +96,18 @@ class ObjectFileDB {
|
|||
|
||||
bool lookup_function_type(const FunctionName& name,
|
||||
const std::string& obj_name,
|
||||
const Config& config,
|
||||
TypeSpec* result);
|
||||
|
||||
public:
|
||||
void load_map_file(const std::string& map_data);
|
||||
void get_objs_from_dgo(const std::string& filename);
|
||||
void get_objs_from_dgo(const std::string& filename, const Config& config);
|
||||
void add_obj_from_dgo(const std::string& obj_name,
|
||||
const std::string& name_in_dgo,
|
||||
const uint8_t* obj_data,
|
||||
uint32_t obj_size,
|
||||
const std::string& dgo_name);
|
||||
const std::string& dgo_name,
|
||||
const Config& config);
|
||||
|
||||
/*!
|
||||
* Apply f to all ObjectFileData's. Does it in the right order.
|
||||
|
|
|
@ -29,18 +29,18 @@ namespace decompiler {
|
|||
* At this point, we assume that the files are loaded and we've run find_code to locate all
|
||||
* functions, but nothing else.
|
||||
*/
|
||||
void ObjectFileDB::analyze_functions_ir2(const std::string& output_dir) {
|
||||
void ObjectFileDB::analyze_functions_ir2(const std::string& output_dir, const Config& config) {
|
||||
lg::info("Using IR2 analysis...");
|
||||
lg::info("Processing top-level functions...");
|
||||
ir2_top_level_pass();
|
||||
ir2_top_level_pass(config);
|
||||
lg::info("Processing basic blocks and control flow graph...");
|
||||
ir2_basic_block_pass();
|
||||
lg::info("Finding stack spills...");
|
||||
ir2_stack_spill_slot_pass();
|
||||
lg::info("Converting to atomic ops...");
|
||||
ir2_atomic_op_pass();
|
||||
ir2_atomic_op_pass(config);
|
||||
lg::info("Running type analysis...");
|
||||
ir2_type_analysis_pass();
|
||||
ir2_type_analysis_pass(config);
|
||||
lg::info("Register usage analysis...");
|
||||
ir2_register_usage_pass();
|
||||
lg::info("Variable analysis...");
|
||||
|
@ -51,7 +51,7 @@ void ObjectFileDB::analyze_functions_ir2(const std::string& output_dir) {
|
|||
lg::info("Storing temporary form result...");
|
||||
ir2_store_current_forms();
|
||||
lg::info("Expression building...");
|
||||
ir2_build_expressions();
|
||||
ir2_build_expressions(config);
|
||||
lg::info("Re-writing inline asm instructions...");
|
||||
ir2_rewrite_inline_asm_instructions();
|
||||
|
||||
|
@ -74,7 +74,7 @@ void ObjectFileDB::analyze_functions_ir2(const std::string& output_dir) {
|
|||
* - Find method definitions
|
||||
* - Warn for non-unique function names.
|
||||
*/
|
||||
void ObjectFileDB::ir2_top_level_pass() {
|
||||
void ObjectFileDB::ir2_top_level_pass(const Config& config) {
|
||||
Timer timer;
|
||||
int total_functions = 0;
|
||||
int total_named_global_functions = 0;
|
||||
|
@ -134,8 +134,8 @@ void ObjectFileDB::ir2_top_level_pass() {
|
|||
|
||||
unique_names.insert(name);
|
||||
|
||||
if (get_config().asm_functions_by_name.find(name) !=
|
||||
get_config().asm_functions_by_name.end()) {
|
||||
if (config.hacks.asm_functions_by_name.find(name) !=
|
||||
config.hacks.asm_functions_by_name.end()) {
|
||||
func.warnings.info("Flagged as asm by config");
|
||||
func.suspected_asm = true;
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ void ObjectFileDB::ir2_stack_spill_slot_pass() {
|
|||
* Conversion of MIPS instructions into AtomicOps. The AtomicOps represent what we
|
||||
* think are IR of the original GOAL compiler.
|
||||
*/
|
||||
void ObjectFileDB::ir2_atomic_op_pass() {
|
||||
void ObjectFileDB::ir2_atomic_op_pass(const Config& config) {
|
||||
Timer timer;
|
||||
int total_functions = 0;
|
||||
int attempted = 0;
|
||||
|
@ -266,8 +266,8 @@ void ObjectFileDB::ir2_atomic_op_pass() {
|
|||
attempted++;
|
||||
try {
|
||||
bool inline_asm =
|
||||
get_config().hint_inline_assembly_functions.find(func.guessed_name.to_string()) !=
|
||||
get_config().hint_inline_assembly_functions.end();
|
||||
config.hacks.hint_inline_assembly_functions.find(func.guessed_name.to_string()) !=
|
||||
config.hacks.hint_inline_assembly_functions.end();
|
||||
auto ops = convert_function_to_atomic_ops(func, data.linked_data.labels, func.warnings,
|
||||
inline_asm);
|
||||
func.ir2.atomic_ops = std::make_shared<FunctionAtomicOps>(std::move(ops));
|
||||
|
@ -288,13 +288,23 @@ void ObjectFileDB::ir2_atomic_op_pass() {
|
|||
100.f * attempted / total_functions, 100.f * successful / attempted);
|
||||
}
|
||||
|
||||
template <typename Key, typename Value>
|
||||
Value try_lookup(const std::unordered_map<Key, Value>& map, const Key& key) {
|
||||
auto lookup = map.find(key);
|
||||
if (lookup == map.end()) {
|
||||
return Value();
|
||||
} else {
|
||||
return lookup->second;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Analyze registers and determine the type in each register at each instruction.
|
||||
* - Figure out the type of each function, from configs.
|
||||
* - Propagate types.
|
||||
* - NOTE: this will update register info usage more accurately for functions.
|
||||
*/
|
||||
void ObjectFileDB::ir2_type_analysis_pass() {
|
||||
void ObjectFileDB::ir2_type_analysis_pass(const Config& config) {
|
||||
Timer timer;
|
||||
int total_functions = 0;
|
||||
int non_asm_functions = 0;
|
||||
|
@ -307,21 +317,21 @@ void ObjectFileDB::ir2_type_analysis_pass() {
|
|||
if (!func.suspected_asm) {
|
||||
non_asm_functions++;
|
||||
TypeSpec ts;
|
||||
if (lookup_function_type(func.guessed_name, data.to_unique_name(), &ts) &&
|
||||
if (lookup_function_type(func.guessed_name, data.to_unique_name(), config, &ts) &&
|
||||
func.ir2.atomic_ops_succeeded) {
|
||||
func.type = ts;
|
||||
attempted_functions++;
|
||||
// try type analysis here.
|
||||
auto func_name = func.guessed_name.to_string();
|
||||
auto casts = get_config().type_casts_by_function_by_atomic_op_idx[func_name];
|
||||
auto label_types = get_config().label_types[data.to_unique_name()];
|
||||
auto casts = try_lookup(config.type_casts_by_function_by_atomic_op_idx, func_name);
|
||||
auto label_types = try_lookup(config.label_types, data.to_unique_name());
|
||||
func.ir2.env.set_type_casts(casts);
|
||||
func.ir2.env.set_label_types(label_types);
|
||||
if (get_config().pair_functions_by_name.find(func_name) !=
|
||||
get_config().pair_functions_by_name.end()) {
|
||||
if (config.hacks.pair_functions_by_name.find(func_name) !=
|
||||
config.hacks.pair_functions_by_name.end()) {
|
||||
func.ir2.env.set_sloppy_pair_typing();
|
||||
}
|
||||
func.ir2.env.set_stack_var_hints(get_config().stack_var_hints_by_function[func_name]);
|
||||
func.ir2.env.set_stack_var_hints(try_lookup(config.stack_var_hints_by_function, func_name));
|
||||
if (run_type_analysis_ir2(ts, dts, func)) {
|
||||
successful_functions++;
|
||||
func.ir2.env.types_succeeded = true;
|
||||
|
@ -436,7 +446,7 @@ void ObjectFileDB::ir2_store_current_forms() {
|
|||
lg::info("Stored debug forms for {} functions in {:.2f} ms\n", total, timer.getMs());
|
||||
}
|
||||
|
||||
void ObjectFileDB::ir2_build_expressions() {
|
||||
void ObjectFileDB::ir2_build_expressions(const Config& config) {
|
||||
Timer timer;
|
||||
int total = 0;
|
||||
int attempted = 0;
|
||||
|
@ -449,13 +459,13 @@ void ObjectFileDB::ir2_build_expressions() {
|
|||
func.ir2.env.types_succeeded) {
|
||||
attempted++;
|
||||
auto name = func.guessed_name.to_string();
|
||||
auto arg_config = get_config().function_arg_names.find(name);
|
||||
auto var_config = get_config().function_var_overrides.find(name);
|
||||
auto arg_config = config.function_arg_names.find(name);
|
||||
auto var_config = config.function_var_overrides.find(name);
|
||||
if (convert_to_expressions(func.ir2.top_form, *func.ir2.form_pool, func,
|
||||
arg_config != get_config().function_arg_names.end()
|
||||
arg_config != config.function_arg_names.end()
|
||||
? arg_config->second
|
||||
: std::vector<std::string>{},
|
||||
var_config != get_config().function_var_overrides.end()
|
||||
var_config != config.function_var_overrides.end()
|
||||
? var_config->second
|
||||
: std::unordered_map<std::string, LocalVarOverride>{},
|
||||
dts)) {
|
||||
|
@ -826,12 +836,11 @@ std::string ObjectFileDB::ir2_function_to_string(ObjectFileData& data, Function&
|
|||
*/
|
||||
bool ObjectFileDB::lookup_function_type(const FunctionName& name,
|
||||
const std::string& obj_name,
|
||||
const Config& config,
|
||||
TypeSpec* result) {
|
||||
auto& cfg = get_config();
|
||||
|
||||
// don't return function types that are explictly flagged as bad in config.
|
||||
if (cfg.no_type_analysis_functions_by_name.find(name.to_string()) !=
|
||||
cfg.no_type_analysis_functions_by_name.end()) {
|
||||
if (config.hacks.no_type_analysis_functions_by_name.find(name.to_string()) !=
|
||||
config.hacks.no_type_analysis_functions_by_name.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -867,7 +876,7 @@ bool ObjectFileDB::lookup_function_type(const FunctionName& name,
|
|||
return true;
|
||||
} else if (name.kind == FunctionName::FunctionKind::UNIDENTIFIED) {
|
||||
// try looking up the object
|
||||
const auto& map = get_config().anon_function_types_by_obj_by_id;
|
||||
const auto& map = config.anon_function_types_by_obj_by_id;
|
||||
auto obj_kv = map.find(obj_name);
|
||||
if (obj_kv != map.end()) {
|
||||
auto func_kv = obj_kv->second.find(name.get_anon_id());
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
#include "decompiler/util/config_parsers.h"
|
||||
|
||||
namespace decompiler {
|
||||
Config gConfig;
|
||||
|
||||
Config& get_config() {
|
||||
return gConfig;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/*!
|
||||
|
@ -25,60 +20,39 @@ nlohmann::json read_json_file_from_config(const nlohmann::json& cfg, const std::
|
|||
} // namespace
|
||||
|
||||
/*!
|
||||
* Parse the main config file and set the global decompiler configuration.
|
||||
* Parse the main config file and return decompiler config.
|
||||
*/
|
||||
void set_config(const std::string& path_to_config_file) {
|
||||
Config read_config_file(const std::string& path_to_config_file) {
|
||||
Config config;
|
||||
auto config_str = file_util::read_text_file(path_to_config_file);
|
||||
auto cfg = parse_commented_json(config_str);
|
||||
|
||||
gConfig.game_version = cfg.at("game_version").get<int>();
|
||||
gConfig.dgo_names = cfg.at("dgo_names").get<std::vector<std::string>>();
|
||||
gConfig.object_file_names = cfg.at("object_file_names").get<std::vector<std::string>>();
|
||||
gConfig.str_file_names = cfg.at("str_file_names").get<std::vector<std::string>>();
|
||||
config.game_version = cfg.at("game_version").get<int>();
|
||||
|
||||
auto inputs_json = read_json_file_from_config(cfg, "inputs_file");
|
||||
config.dgo_names = inputs_json.at("dgo_names").get<std::vector<std::string>>();
|
||||
config.object_file_names = inputs_json.at("object_file_names").get<std::vector<std::string>>();
|
||||
config.str_file_names = inputs_json.at("str_file_names").get<std::vector<std::string>>();
|
||||
|
||||
if (cfg.contains("obj_file_name_map_file")) {
|
||||
gConfig.obj_file_name_map_file = cfg.at("obj_file_name_map_file").get<std::string>();
|
||||
}
|
||||
gConfig.disassemble_code = cfg.at("disassemble_code").get<bool>();
|
||||
gConfig.decompile_code = cfg.at("decompile_code").get<bool>();
|
||||
gConfig.regenerate_all_types = cfg.at("regenerate_all_types").get<bool>();
|
||||
gConfig.write_hex_near_instructions = cfg.at("write_hex_near_instructions").get<bool>();
|
||||
gConfig.write_scripts = cfg.at("write_scripts").get<bool>();
|
||||
gConfig.disassemble_data = cfg.at("disassemble_data").get<bool>();
|
||||
gConfig.process_tpages = cfg.at("process_tpages").get<bool>();
|
||||
gConfig.process_game_text = cfg.at("process_game_text").get<bool>();
|
||||
gConfig.process_game_count = cfg.at("process_game_count").get<bool>();
|
||||
gConfig.hexdump_code = cfg.at("hexdump_code").get<bool>();
|
||||
gConfig.hexdump_data = cfg.at("hexdump_data").get<bool>();
|
||||
gConfig.dump_objs = cfg.at("dump_objs").get<bool>();
|
||||
gConfig.hint_inline_assembly_functions =
|
||||
cfg.at("inline_asm_hint").get<std::unordered_set<std::string>>();
|
||||
|
||||
std::vector<std::string> asm_functions_by_name =
|
||||
cfg.at("asm_functions_by_name").get<std::vector<std::string>>();
|
||||
for (const auto& x : asm_functions_by_name) {
|
||||
gConfig.asm_functions_by_name.insert(x);
|
||||
}
|
||||
|
||||
std::vector<std::string> pair_functions_by_name =
|
||||
cfg.at("pair_functions_by_name").get<std::vector<std::string>>();
|
||||
for (const auto& x : pair_functions_by_name) {
|
||||
gConfig.pair_functions_by_name.insert(x);
|
||||
}
|
||||
|
||||
std::vector<std::string> no_type_analysis_functions_by_name =
|
||||
cfg.at("no_type_analysis_functions_by_name").get<std::vector<std::string>>();
|
||||
for (const auto& x : no_type_analysis_functions_by_name) {
|
||||
gConfig.no_type_analysis_functions_by_name.insert(x);
|
||||
}
|
||||
|
||||
auto bad_inspect = cfg.at("types_with_bad_inspect_methods").get<std::vector<std::string>>();
|
||||
for (const auto& x : bad_inspect) {
|
||||
gConfig.bad_inspect_types.insert(x);
|
||||
config.obj_file_name_map_file = cfg.at("obj_file_name_map_file").get<std::string>();
|
||||
}
|
||||
config.disassemble_code = cfg.at("disassemble_code").get<bool>();
|
||||
config.decompile_code = cfg.at("decompile_code").get<bool>();
|
||||
config.regenerate_all_types = cfg.at("regenerate_all_types").get<bool>();
|
||||
config.write_hex_near_instructions = cfg.at("write_hex_near_instructions").get<bool>();
|
||||
config.write_scripts = cfg.at("write_scripts").get<bool>();
|
||||
config.disassemble_data = cfg.at("disassemble_data").get<bool>();
|
||||
config.process_tpages = cfg.at("process_tpages").get<bool>();
|
||||
config.process_game_text = cfg.at("process_game_text").get<bool>();
|
||||
config.process_game_count = cfg.at("process_game_count").get<bool>();
|
||||
config.hexdump_code = cfg.at("hexdump_code").get<bool>();
|
||||
config.hexdump_data = cfg.at("hexdump_data").get<bool>();
|
||||
config.dump_objs = cfg.at("dump_objs").get<bool>();
|
||||
|
||||
auto allowed = cfg.at("allowed_objects").get<std::vector<std::string>>();
|
||||
for (const auto& x : allowed) {
|
||||
gConfig.allowed_objects.insert(x);
|
||||
config.allowed_objects.insert(x);
|
||||
}
|
||||
|
||||
auto type_casts_json = read_json_file_from_config(cfg, "type_casts_file");
|
||||
|
@ -92,7 +66,7 @@ void set_config(const std::string& path_to_config_file) {
|
|||
type_cast.atomic_op_idx = idx;
|
||||
type_cast.reg = Register(cast.at(1));
|
||||
type_cast.type_name = cast.at(2).get<std::string>();
|
||||
gConfig.type_casts_by_function_by_atomic_op_idx[function_name][idx].push_back(type_cast);
|
||||
config.type_casts_by_function_by_atomic_op_idx[function_name][idx].push_back(type_cast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +78,7 @@ void set_config(const std::string& path_to_config_file) {
|
|||
for (auto& anon_type : anon_types) {
|
||||
auto id = anon_type.at(0).get<int>();
|
||||
const auto& type_name = anon_type.at(1).get<std::string>();
|
||||
gConfig.anon_function_types_by_obj_by_id[obj_file_name][id] = type_name;
|
||||
config.anon_function_types_by_obj_by_id[obj_file_name][id] = type_name;
|
||||
}
|
||||
}
|
||||
auto var_names_json = read_json_file_from_config(cfg, "var_names_file");
|
||||
|
@ -113,7 +87,7 @@ void set_config(const std::string& path_to_config_file) {
|
|||
auto arg = kv.value().find("args");
|
||||
if (arg != kv.value().end()) {
|
||||
for (auto& x : arg.value()) {
|
||||
gConfig.function_arg_names[function_name].push_back(x);
|
||||
config.function_arg_names[function_name].push_back(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +103,7 @@ void set_config(const std::string& path_to_config_file) {
|
|||
} else {
|
||||
throw std::runtime_error("Invalid function var override.");
|
||||
}
|
||||
gConfig.function_var_overrides[function_name][vkv.first] = override;
|
||||
config.function_var_overrides[function_name][vkv.first] = override;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +116,7 @@ void set_config(const std::string& path_to_config_file) {
|
|||
const auto& name = x.at(0).get<std::string>();
|
||||
const auto& type_name = x.at(1).get<std::string>();
|
||||
bool is_const = x.at(2).get<bool>();
|
||||
auto& config_entry = gConfig.label_types[obj_name][name];
|
||||
auto& config_entry = config.label_types[obj_name][name];
|
||||
config_entry = {type_name, is_const, {}};
|
||||
if (x.size() > 3) {
|
||||
config_entry.array_size = x.at(3).get<int>();
|
||||
|
@ -154,8 +128,21 @@ void set_config(const std::string& path_to_config_file) {
|
|||
for (auto& kv : stack_vars_json.items()) {
|
||||
auto& func_name = kv.key();
|
||||
auto& stack_vars = kv.value();
|
||||
gConfig.stack_var_hints_by_function[func_name] = parse_stack_var_hints(stack_vars);
|
||||
config.stack_var_hints_by_function[func_name] = parse_stack_var_hints(stack_vars);
|
||||
}
|
||||
|
||||
auto hacks_json = read_json_file_from_config(cfg, "hacks_file");
|
||||
config.hacks.hint_inline_assembly_functions =
|
||||
hacks_json.at("hint_inline_assembly_functions").get<std::unordered_set<std::string>>();
|
||||
config.hacks.asm_functions_by_name =
|
||||
hacks_json.at("asm_functions_by_name").get<std::unordered_set<std::string>>();
|
||||
config.hacks.pair_functions_by_name =
|
||||
hacks_json.at("pair_functions_by_name").get<std::unordered_set<std::string>>();
|
||||
config.hacks.no_type_analysis_functions_by_name =
|
||||
hacks_json.at("no_type_analysis_functions_by_name").get<std::unordered_set<std::string>>();
|
||||
config.hacks.types_with_bad_inspect_methods =
|
||||
hacks_json.at("types_with_bad_inspect_methods").get<std::unordered_set<std::string>>();
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace decompiler
|
|
@ -42,12 +42,20 @@ struct StackVariableHint {
|
|||
int stack_offset = 0; // where it's located on the stack (relative to sp after prologue)
|
||||
};
|
||||
|
||||
struct DecompileHacks {
|
||||
std::unordered_set<std::string> types_with_bad_inspect_methods;
|
||||
std::unordered_set<std::string> no_type_analysis_functions_by_name;
|
||||
std::unordered_set<std::string> hint_inline_assembly_functions;
|
||||
std::unordered_set<std::string> asm_functions_by_name;
|
||||
std::unordered_set<std::string> pair_functions_by_name;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
int game_version = -1;
|
||||
std::vector<std::string> dgo_names;
|
||||
std::vector<std::string> object_file_names;
|
||||
std::vector<std::string> str_file_names;
|
||||
std::unordered_set<std::string> bad_inspect_types;
|
||||
|
||||
std::string obj_file_name_map_file;
|
||||
|
||||
bool disassemble_code = false;
|
||||
|
@ -64,9 +72,6 @@ struct Config {
|
|||
bool hexdump_data = false;
|
||||
bool dump_objs = false;
|
||||
|
||||
std::unordered_set<std::string> asm_functions_by_name;
|
||||
std::unordered_set<std::string> pair_functions_by_name;
|
||||
std::unordered_set<std::string> no_type_analysis_functions_by_name;
|
||||
std::unordered_set<std::string> allowed_objects;
|
||||
std::unordered_map<std::string, std::unordered_map<int, std::vector<TypeCast>>>
|
||||
type_casts_by_function_by_atomic_op_idx;
|
||||
|
@ -78,10 +83,9 @@ struct Config {
|
|||
std::unordered_map<std::string, std::unordered_map<std::string, LabelType>> label_types;
|
||||
std::unordered_map<std::string, std::vector<StackVariableHint>> stack_var_hints_by_function;
|
||||
|
||||
std::unordered_set<std::string> hint_inline_assembly_functions;
|
||||
DecompileHacks hacks;
|
||||
};
|
||||
|
||||
Config& get_config();
|
||||
void set_config(const std::string& path_to_config_file);
|
||||
Config read_config_file(const std::string& path_to_config_file);
|
||||
|
||||
} // namespace decompiler
|
||||
|
|
|
@ -1,68 +1,9 @@
|
|||
|
||||
|
||||
{
|
||||
"game_version":1,
|
||||
"game_version": 1,
|
||||
|
||||
|
||||
//////////////////////
|
||||
// INPUT FILES
|
||||
//////////////////////
|
||||
|
||||
// input is GOAL object files, possibly in containers.
|
||||
// most objects are part of CGO/DGO files (both go in dgo_names). This includes levels and the engine
|
||||
// the DGOs will be processed in this order. Usually it's best to have KERNEL, ENGINE, then the levels when
|
||||
// you want to run on the entire game.
|
||||
"dgo_names":["CGO/KERNEL.CGO","CGO/ENGINE.CGO", "CGO/GAME.CGO",
|
||||
"CGO/ART.CGO", "DGO/BEA.DGO", "DGO/CIT.DGO", "CGO/COMMON.CGO", "DGO/DAR.DGO", "DGO/DEM.DGO",
|
||||
"DGO/FIN.DGO", "DGO/INT.DGO", "DGO/JUB.DGO", "DGO/JUN.DGO", "CGO/JUNGLE.CGO", "CGO/L1.CGO", "DGO/FIC.DGO",
|
||||
"DGO/LAV.DGO", "DGO/MAI.DGO", "CGO/MAINCAVE.CGO", "DGO/MIS.DGO", "DGO/OGR.DGO", "CGO/RACERP.CGO", "DGO/ROB.DGO", "DGO/ROL.DGO",
|
||||
"DGO/SNO.DGO", "DGO/SUB.DGO", "DGO/SUN.DGO", "CGO/SUNKEN.CGO", "DGO/SWA.DGO", "DGO/TIT.DGO", "DGO/TRA.DGO", "DGO/VI1.DGO",
|
||||
"DGO/VI2.DGO", "DGO/VI3.DGO", "CGO/VILLAGEP.CGO", "CGO/WATER-AN.CGO"
|
||||
],
|
||||
|
||||
// some objects are part of STR files (streaming data). In Jak 1 this is just animations
|
||||
"str_file_names":["STR/BAFCELL.STR", "STR/SWTE4.STR", "STR/SWTE3.STR", "STR/SWTE2.STR", "STR/SWTE1.STR",
|
||||
"STR/SNRBSBFC.STR", "STR/SNRBIPFC.STR", "STR/SNRBICFC.STR", "STR/ORR3.STR", "STR/ORR2.STR", "STR/MICANNON.STR",
|
||||
"STR/BECANNON.STR", "STR/SWTS4.STR", "STR/SWTS3.STR", "STR/SWTS2.STR", "STR/SW4.STR", "STR/SW3.STR", "STR/SW2.STR",
|
||||
"STR/SWTS1.STR", "STR/ORREYE.STR", "STR/ORLEYE.STR", "STR/SW1.STR", "STR/MAGFCELL.STR", "STR/GNFCELL.STR",
|
||||
"STR/ORRE3.STR","STR/ORRE2.STR","STR/ORRE1.STR","STR/ORR1.STR","STR/ORLE3.STR","STR/ORLE2.STR","STR/ORI3.STR",
|
||||
"STR/ORI2.STR","STR/DE0202.STR","STR/RARSANIM.STR","STR/RARANIM.STR","STR/EIFISH.STR","STR/ORLE1.STR",
|
||||
"STR/SWTEF4.STR","STR/SWTEF3.STR","STR/SWTEF2.STR","STR/SWTEF1.STR","STR/ORI1.STR","STR/EIICE.STR","STR/EIA3.STR",
|
||||
"STR/DE0191.STR","STR/DE0186.STR","STR/DE0187.STR","STR/EIA4.STR","STR/EIPOLE.STR","STR/RARASECO.STR",
|
||||
"STR/RARA2.STR","STR/DE0184.STR","STR/DE0181.STR","STR/PESEXT.STR","STR/DE0195.STR","STR/EIA2.STR","STR/FIR1.STR",
|
||||
"STR/DE0182.STR","STR/BIR1.STR","STR/HAPOPEN.STR","STR/EITUBE.STR","STR/SCR1.STR","STR/DE0197.STR",
|
||||
"STR/DE0193.STR","STR/EIA1.STR","STR/FAR2.STR","STR/FAR1.STR","STR/DE0199.STR","STR/GERMONEY.STR",
|
||||
"STR/BIRESOLU.STR","STR/GARMONEY.STR","STR/BIADVENT.STR","STR/FUCRV1.STR","STR/BIREJECT.STR","STR/WAR1.STR",
|
||||
"STR/BIACCEPT.STR","STR/SA3R1DEC.STR","STR/ASR1GENE.STR","STR/FIREJECT.STR","STR/GARRACE.STR","STR/GEZMONEY.STR",
|
||||
"STR/LRFALLIN.STR","STR/EXR2.STR","STR/GERMOLES.STR","STR/FUCVICTO.STR","STR/MIR1ORBS.STR","STR/SA3R1RAM.STR",
|
||||
"STR/AS2R1FLU.STR","STR/FUCV2.STR","STR/MIR1GNAW.STR","STR/GAZMONEY.STR","STR/AS3REMIN.STR","STR/SIHISA.STR",
|
||||
"STR/FIACCEPT.STR","STR/FIWECO.STR","STR/FARESOLU.STR","STR/ASR1RBIK.STR","STR/MARDONAT.STR","STR/GAZRACE.STR",
|
||||
"STR/FUCFV1.STR","STR/FUCV5.STR","STR/SABR1CDU.STR","STR/FLLINTRO.STR","STR/SAR1ECOR.STR","STR/AS2R1ROB.STR",
|
||||
"STR/MIR2ORBS.STR","STR/MARBEAMS.STR","STR/LOI2.STR","STR/SAR1GENE.STR","STR/BILR1.STR","STR/AS2R1ROO.STR",
|
||||
"STR/ASR1BESW.STR","STR/LOLOOP.STR","STR/FAINTROD.STR","STR/GEZMOLES.STR","STR/V1IN.STR","STR/FUCV4.STR",
|
||||
"STR/SAIECORO.STR","STR/MIR1SWIT.STR","STR/LOINTRO.STR","STR/SAR2GENE.STR","STR/MUVICTOR.STR","STR/SAR1MCAN.STR",
|
||||
"STR/FUCV7.STR","STR/MIZ1ORBS.STR","STR/FUCV8.STR","STR/BILR2.STR","STR/FUCV6.STR","STR/FUCV3.STR",
|
||||
"STR/PLLBLOWU.STR","STR/PLBMAIN.STR","STR/WARESOLU.STR","STR/EIRACER.STR","STR/MAZDONAT.STR","STR/MAZBEAMS.STR",
|
||||
"STR/MIISWITC.STR","STR/FIBRTVIL.STR","STR/FIBRTMIS.STR","STR/SABR1PAR.STR","STR/NDINTRO.STR","STR/GORDOWN.STR",
|
||||
"STR/GORUP.STR","STR/SA3IRAMS.STR","STR/YERESOLU.STR","STR/EIFLUT.STR","STR/GRSDSACR.STR","STR/EXR1.STR",
|
||||
"STR/SCRESOLU.STR","STR/FIRESOLU.STR","STR/SIHITEST.STR","STR/GAI1.STR","STR/EXRESOLU.STR","STR/MIZ2ORBS.STR",
|
||||
"STR/ASIRBIKE.STR","STR/GRSOBBEC.STR","STR/BIINTROD.STR","STR/GRSOBBNC.STR","STR/AS2IROBB.STR","STR/GRSOBFIN.STR",
|
||||
"STR/RERESOLU.STR","STR/BLRESOLU.STR","STR/SABIPARM.STR","STR/EVMEND.STR","STR/AS2RESOL.STR","STR/SAIMCANN.STR",
|
||||
"STR/MIIGNAWE.STR","STR/GRSOBBA.STR","STR/GRSINTRO.STR","STR/SAISE.STR","STR/SA3IDECO.STR","STR/ASFRESOL.STR",
|
||||
"STR/EXINTROD.STR","STR/BILINTRO.STR","STR/FIINTROD.STR","STR/MAINTROD.STR","STR/SCINTROD.STR","STR/AS2IFLUT.STR",
|
||||
"STR/ASLERESO.STR","STR/ASLSRESO.STR","STR/AS2IROOM.STR","STR/GRSRESOL.STR","STR/SABICDUS.STR","STR/SIHISB.STR",
|
||||
"STR/ASIBESWI.STR","STR/BILBRESO.STR","STR/FIBRT1AL.STR","STR/AS2INTRO.STR","STR/GEINTROD.STR","STR/SAISD1.STR",
|
||||
"STR/SAISA.STR","STR/SIHISC.STR","STR/MIIORBS.STR","STR/WAINTROD.STR","STR/SAISD2.STR","STR/GRSOPREB.STR",
|
||||
"STR/GRSOBBB.STR","STR/SA3INTRO.STR"
|
||||
],
|
||||
|
||||
// some objects are directly stored as files on the DVD. This is just text files.
|
||||
"object_file_names":["TEXT/0COMMON.TXT", "TEXT/1COMMON.TXT", "TEXT/2COMMON.TXT", "TEXT/3COMMON.TXT", "TEXT/4COMMON.TXT",
|
||||
"TEXT/5COMMON.TXT", "TEXT/6COMMON.TXT"],
|
||||
|
||||
// if you want to filter to only some object names.
|
||||
// it will make the decompiler much faster.
|
||||
"allowed_objects":[],
|
||||
"allowed_objects": [],
|
||||
|
||||
////////////////////////////
|
||||
// CODE ANALYSIS OPTIONS
|
||||
|
@ -70,10 +11,10 @@
|
|||
|
||||
// set to true to generate plain .asm files with MIPS disassembly, with no fancy decompilation.
|
||||
// this is fast and should succeed 100% of the time.
|
||||
"disassemble_code":false,
|
||||
"disassemble_code": false,
|
||||
|
||||
// Run the decompiler
|
||||
"decompile_code":true,
|
||||
"decompile_code": true,
|
||||
|
||||
////////////////////////////
|
||||
// DATA ANALYSIS OPTIONS
|
||||
|
@ -82,14 +23,14 @@
|
|||
// set to true to generate plain .asm files for data files.
|
||||
// this will display most data as hex, but will add labels/references/type pointers/strings
|
||||
// this generates a huge amount of output if you run it on the entire game.
|
||||
"disassemble_data":false,
|
||||
"disassemble_data": false,
|
||||
|
||||
// unpack textures to assets folder
|
||||
"process_tpages":true,
|
||||
"process_tpages": true,
|
||||
// unpack game text to assets folder
|
||||
"process_game_text":true,
|
||||
"process_game_text": true,
|
||||
// unpack game count to assets folder
|
||||
"process_game_count":true,
|
||||
"process_game_count": true,
|
||||
|
||||
///////////////////////////
|
||||
// WEIRD OPTIONS
|
||||
|
@ -98,464 +39,33 @@
|
|||
// these options are used rarely and should usually be left at false
|
||||
|
||||
// output a file type_defs.gc which is used the types part of all-types.gc
|
||||
"regenerate_all_types":false,
|
||||
"regenerate_all_types": false,
|
||||
|
||||
// debug option for instruction decoder
|
||||
"write_hex_near_instructions":false,
|
||||
"write_hex_near_instructions": false,
|
||||
|
||||
// experimental tool to extract linked lists used for region scripting in Jak 2 and Jak 3.
|
||||
"write_scripts":false,
|
||||
"write_scripts": false,
|
||||
|
||||
// hex dump of code/data files.
|
||||
"hexdump_code":false,
|
||||
"hexdump_data":false,
|
||||
"hexdump_code": false,
|
||||
"hexdump_data": false,
|
||||
// dump raw obj files
|
||||
"dump_objs":false,
|
||||
"dump_objs": false,
|
||||
|
||||
|
||||
////////////////////////////
|
||||
// CONFIG FILES
|
||||
////////////////////////////
|
||||
|
||||
"type_casts_file":"decompiler/config/jak1_ntsc_black_label/type_casts.jsonc",
|
||||
"anonymous_function_types_file":"decompiler/config/jak1_ntsc_black_label/anonymous_function_types.jsonc",
|
||||
"var_names_file":"decompiler/config/jak1_ntsc_black_label/var_names.jsonc",
|
||||
"label_types_file":"decompiler/config/jak1_ntsc_black_label/label_types.jsonc",
|
||||
"stack_vars_file":"decompiler/config/jak1_ntsc_black_label/stack_vars.jsonc",
|
||||
"type_casts_file": "decompiler/config/jak1_ntsc_black_label/type_casts.jsonc",
|
||||
"anonymous_function_types_file": "decompiler/config/jak1_ntsc_black_label/anonymous_function_types.jsonc",
|
||||
"var_names_file": "decompiler/config/jak1_ntsc_black_label/var_names.jsonc",
|
||||
"label_types_file": "decompiler/config/jak1_ntsc_black_label/label_types.jsonc",
|
||||
"stack_vars_file": "decompiler/config/jak1_ntsc_black_label/stack_vars.jsonc",
|
||||
"hacks_file": "decompiler/config/jak1_ntsc_black_label/hacks.jsonc",
|
||||
"inputs_file": "decompiler/config/jak1_ntsc_black_label/inputs.jsonc",
|
||||
|
||||
// optional: a predetermined object file name map from a file.
|
||||
// this will make decompilation naming consistent even if you only run on some objects.
|
||||
"obj_file_name_map_file":"goal_src/build/all_objs.json",
|
||||
|
||||
|
||||
////////////////////////////
|
||||
// HACKS and ASM FUNCTIONS
|
||||
////////////////////////////
|
||||
|
||||
"types_with_bad_inspect_methods":[
|
||||
"engine",
|
||||
"bsp-header",
|
||||
"joint-anim-matrix",
|
||||
"part-tracker"],
|
||||
|
||||
"no_type_analysis_functions_by_name":[],
|
||||
|
||||
// this provides a hint to the decompiler that these functions will have a lot of inline assembly.
|
||||
"inline_asm_hint":["matrix-transpose!"],
|
||||
|
||||
"asm_functions_by_name":[
|
||||
// gcommon
|
||||
"quad-copy!",
|
||||
|
||||
// gkernel
|
||||
"(method 11 cpu-thread)",
|
||||
"throw",
|
||||
"return-from-thread",
|
||||
"return-from-thread-dead",
|
||||
"reset-and-call",
|
||||
"(method 10 cpu-thread)",
|
||||
"(method 0 catch-frame)",
|
||||
"throw-dispatch",
|
||||
"set-to-run-bootstrap",
|
||||
"run-function-in-process", // not asm, but it uses the stack.
|
||||
|
||||
// pskernel
|
||||
"return-from-exception", // F: eret
|
||||
"kernel-read-function", // F: delay slot tricks
|
||||
"kernel-write-function", // F: delay slot tricks
|
||||
"kernel-copy-function",
|
||||
"kernel-check-hardwired-addresses",
|
||||
|
||||
// math
|
||||
"rand-uint31-gen",
|
||||
|
||||
// bounding box
|
||||
"(method 9 bounding-box)", // F: asm branching
|
||||
"(method 14 bounding-box)",
|
||||
|
||||
// matrix
|
||||
"(method 9 matrix)", // F: asm branching
|
||||
"matrix-axis-sin-cos!", // F: asm branching
|
||||
"matrix-axis-sin-cos-vu!",
|
||||
|
||||
// geometry
|
||||
"curve-evaluate!", // BUG: cfg fails, suspected weird gotos
|
||||
"circle-circle-xz-intersect", // F: asm branching
|
||||
"closest-pt-in-triangle", // F: asm branching
|
||||
"find-knot-span", // ??
|
||||
"vector-segment-distance-point!",
|
||||
|
||||
// trigonometry
|
||||
"exp", // BUG: cfg is wrong.
|
||||
"atan0", // P: manual use of stack
|
||||
"sincos!", // P: manual use of stack
|
||||
"sincos-rad!",
|
||||
|
||||
// dma-h
|
||||
"dma-count-until-done", // F: asm branching
|
||||
"dma-sync-with-count", // F: asm branching
|
||||
"dma-send-no-scratch", // F: asm branching
|
||||
"dma-sync-fast",
|
||||
|
||||
// dma
|
||||
"symlink3", // F: asm branching
|
||||
"symlink2", // F: asm branching
|
||||
"dma-sync-hang",
|
||||
|
||||
// display
|
||||
"vblank-handler", // F: weird asm for interrupt handler
|
||||
"vif1-handler", // F: weird asm for interrupt handler
|
||||
"vif1-handler-debug",
|
||||
|
||||
// vector
|
||||
"vector=", // asm branching
|
||||
|
||||
// texture
|
||||
"adgif-shader<-texture-with-update!", // F: asm branching
|
||||
"(method 9 texture-page-dir)",
|
||||
|
||||
// collide-mesh-h
|
||||
"(method 11 collide-mesh-cache)",
|
||||
|
||||
// actor-link-h (BUG)
|
||||
"(method 21 actor-link-info)", // BUG: sc cfg / cfg-ir bug
|
||||
"(method 20 actor-link-info)",
|
||||
|
||||
// collide-func
|
||||
"moving-sphere-triangle-intersect", // P: weird branching
|
||||
"collide-do-primitives", // P: asm branching
|
||||
"ray-triangle-intersect", // F: asm branching
|
||||
"ray-cylinder-intersect", // F: asm branching
|
||||
"raw-ray-sphere-intersect",
|
||||
|
||||
// joint
|
||||
"calc-animation-from-spr", // F: asm branching
|
||||
"decompress-frame-data-pair-to-accumulator", // P: asm calling
|
||||
"decompress-frame-data-to-accumulator", // P: asm calling
|
||||
"decompress-fixed-data-to-accumulator", // P: asm calling
|
||||
"normalize-frame-quaternions", // F: asm branching, return
|
||||
"clear-frame-accumulator", // F: asm branching
|
||||
"cspace<-parented-transformq-joint!",
|
||||
|
||||
// bsp
|
||||
"level-remap-texture", // BUG: probably missing branch case?
|
||||
"bsp-camera-asm", // F: asm branching
|
||||
"sprite-draw-distorters",
|
||||
|
||||
// merc-blend-shape
|
||||
"setup-blerc-chains-for-one-fragment", // F: asm branching
|
||||
"blerc-execute", // F: asm branching
|
||||
"merc-dma-chain-to-spr", // F: asm branching
|
||||
"blerc-a-fragment",
|
||||
|
||||
// ripple
|
||||
"ripple-matrix-scale",
|
||||
"ripple-apply-wave-table",
|
||||
"ripple-create-wave-table",
|
||||
"ripple-execute-init",
|
||||
|
||||
// bones
|
||||
"draw-bones-hud",
|
||||
"draw-bones",
|
||||
"draw-bones-check-longest-edge-asm",
|
||||
"draw-bones-merc",
|
||||
"bones-mtx-calc-execute",
|
||||
"bones-mtx-calc",
|
||||
"texscroll-execute",
|
||||
|
||||
// generic-effect
|
||||
"generic-debug-light-proc",
|
||||
"generic-none-dma-wait",
|
||||
"generic-copy-vtx-dclr-dtex",
|
||||
"generic-light",
|
||||
"generic-envmap-only-proc",
|
||||
"generic-no-light",
|
||||
"generic-no-light+envmap",
|
||||
"generic-no-light-dproc",
|
||||
"generic-no-light-dproc-only",
|
||||
"generic-no-light-proc",
|
||||
"generic-interp-dproc",
|
||||
"generic-envmap-dproc",
|
||||
"generic-prepare-dma-single",
|
||||
"generic-prepare-dma-double",
|
||||
"generic-envmap-proc",
|
||||
"generic-light-proc",
|
||||
"generic-dma-from-spr",
|
||||
"upload-vu0-program",
|
||||
|
||||
// generic-merc
|
||||
"generic-merc-execute-all",
|
||||
"generic-merc-execute-asm",
|
||||
"high-speed-reject",
|
||||
"mercneric-convert",
|
||||
"mercneric-bittable-asm",
|
||||
"mercneric-shader-asm",
|
||||
"mercneric-matrix-asm",
|
||||
"generic-merc-init-asm",
|
||||
|
||||
// generic-tie
|
||||
"generic-tie-convert",
|
||||
"generic-tie-convert-proc",
|
||||
"generic-tie-upload-next",
|
||||
"generic-tie-decompress",
|
||||
"generic-tie-dma-to-spad-sync",
|
||||
|
||||
// shadow-cpu
|
||||
"shadow-execute",
|
||||
"shadow-add-double-edges",
|
||||
"shadow-add-double-tris",
|
||||
"shadow-add-single-edges",
|
||||
"shadow-add-facing-single-tris",
|
||||
"shadow-add-verts",
|
||||
"shadow-find-double-edges",
|
||||
"shadow-find-facing-double-tris",
|
||||
"shadow-find-single-edges",
|
||||
"shadow-find-facing-single-tris",
|
||||
"shadow-scissor-top",
|
||||
"shadow-scissor-edges",
|
||||
"shadow-calc-dual-verts",
|
||||
|
||||
// font
|
||||
"get-string-length",
|
||||
"draw-string",
|
||||
|
||||
// decomp
|
||||
"(method 16 level)", // BUG: cfg fails
|
||||
"unpack-comp-huf",
|
||||
"unpack-comp-rle",
|
||||
|
||||
// background
|
||||
"upload-vis-bits",
|
||||
"background-upload-vu0",
|
||||
|
||||
// draw-node
|
||||
"draw-node-cull",
|
||||
|
||||
// shrubbery
|
||||
"test-func",
|
||||
"draw-inline-array-instance-shrub",
|
||||
|
||||
// tfrag
|
||||
"stats-tfrag-asm",
|
||||
"draw-inline-array-tfrag-near",
|
||||
"draw-inline-array-tfrag",
|
||||
|
||||
// tie-methods
|
||||
"draw-inline-array-prototype-tie-near-asm",
|
||||
"draw-inline-array-prototype-tie-asm",
|
||||
"draw-inline-array-prototype-tie-generic-asm",
|
||||
"draw-inline-array-instance-tie",
|
||||
|
||||
// sparticle-launcher
|
||||
"(method 11 sparticle-launch-control)", // BUG: cfg ir
|
||||
"sp-launch-particles-var",
|
||||
"particle-adgif",
|
||||
"sp-init-fields!",
|
||||
|
||||
// sparticle
|
||||
"memcpy",
|
||||
"sp-process-block-3d",
|
||||
"sp-process-block-2d",
|
||||
"sp-get-particle",
|
||||
|
||||
// loader BUG
|
||||
"(method 10 external-art-buffer)",
|
||||
|
||||
// game-info BUG
|
||||
"(method 11 fact-info-target)",
|
||||
|
||||
// game-save BUG
|
||||
"(anon-function 5 game-save)", // BUG:
|
||||
"(anon-function 6 game-save)", // BUG:
|
||||
"(anon-function 7 game-save)", // BUG:
|
||||
"(anon-function 8 game-save)", // BUG:
|
||||
"(anon-function 9 game-save)", // BUG:
|
||||
"(anon-function 10 game-save)",
|
||||
|
||||
// mood BUG
|
||||
"update-mood-lava", // BUG:
|
||||
"update-mood-lightning",
|
||||
|
||||
// time-of-day
|
||||
"time-of-day-interp-colors-scratch",
|
||||
"time-of-day-interp-colors",
|
||||
|
||||
// sky-tng
|
||||
"clip-polygon-against-negative-hyperplane",
|
||||
"clip-polygon-against-positive-hyperplane",
|
||||
"draw-large-polygon",
|
||||
|
||||
// load-boundary
|
||||
"render-boundary-tri",
|
||||
"render-boundary-quad",
|
||||
"draw-boundary-polygon",
|
||||
|
||||
// level BUG
|
||||
"level-update-after-load",
|
||||
|
||||
// text BUG
|
||||
"load-game-text-info",
|
||||
|
||||
// collide-probe
|
||||
"collide-probe-instance-tie",
|
||||
"collide-probe-node",
|
||||
|
||||
// collide-mesh
|
||||
"(method 10 collide-mesh)",
|
||||
"(method 13 collide-mesh)",
|
||||
"(method 9 collide-mesh-cache)",
|
||||
"(method 15 collide-mesh)",
|
||||
"(method 14 collide-mesh)",
|
||||
"(method 11 collide-mesh)",
|
||||
"(method 12 collide-mesh)",
|
||||
|
||||
// collide-edge-grab
|
||||
"(method 13 collide-edge-work)",
|
||||
"(method 17 collide-edge-work)",
|
||||
"(method 15 collide-edge-work)",
|
||||
"(method 16 collide-edge-work)",
|
||||
"(method 9 edge-grab-info)", // maybe bug
|
||||
"(method 18 collide-edge-work)",
|
||||
"(method 10 collide-edge-hold-list)",
|
||||
|
||||
// collide-shape
|
||||
"(method 15 collide-shape-prim-mesh)", // BUG:
|
||||
"(method 15 collide-shape-prim-sphere)", // BUG:
|
||||
"(method 16 collide-shape-prim)",
|
||||
"(method 15 collide-shape-prim-group)",
|
||||
"(method 40 collide-shape)",
|
||||
"(method 45 collide-shape)",
|
||||
"(method 28 collide-shape-prim-mesh)", // BUG:
|
||||
"(method 29 collide-shape-prim-group)",
|
||||
"(method 20 collide-shape-prim-group)",
|
||||
"(method 19 collide-shape-prim-sphere)",
|
||||
"(method 18 collide-shape-prim-sphere)",
|
||||
"(method 23 collide-shape-prim-sphere)",
|
||||
"(method 23 collide-shape-prim-mesh)", // BUG: maybe
|
||||
"(method 24 collide-shape-prim)",
|
||||
"(method 23 collide-shape-prim-group)",
|
||||
"(method 42 collide-shape)",
|
||||
|
||||
// collide-shape-rider
|
||||
"(method 35 collide-shape)",
|
||||
|
||||
// cam-master BUG
|
||||
"master-is-hopeful-better?",
|
||||
|
||||
// cam-layout BUG
|
||||
"cam-layout-save-cam-trans",
|
||||
|
||||
// process-drawable BUG
|
||||
"cspace-inspect-tree", // BUG:
|
||||
"process-drawable-birth-fuel-cell", // BUG:
|
||||
"(method 19 process-drawable)",
|
||||
|
||||
// ambient
|
||||
"ambient-inspect",
|
||||
|
||||
// generic-obs BUG
|
||||
"camera-change-to",
|
||||
|
||||
// target BUG
|
||||
"target-falling-anim-trans",
|
||||
|
||||
// target2 BUG
|
||||
"(anon-function 33 target2)", // BUG:
|
||||
"(anon-function 67 target2)", // BUG:
|
||||
"look-for-points-of-interest",
|
||||
|
||||
// menu BUG
|
||||
"debug-menu-item-var-render",
|
||||
|
||||
// drawable-tree
|
||||
"(method 16 drawable-tree)",
|
||||
|
||||
// collide-cache
|
||||
"(method 10 collide-puss-work)",
|
||||
"(method 9 collide-puss-work)",
|
||||
"(method 19 collide-cache)",
|
||||
"(method 10 collide-cache-prim)",
|
||||
"(method 9 collide-cache-prim)",
|
||||
"(method 30 collide-cache)",
|
||||
"(method 13 collide-shape-prim-group)",
|
||||
"(method 13 collide-shape-prim-sphere)",
|
||||
"(method 13 collide-shape-prim-mesh)",
|
||||
"(method 14 collide-shape-prim-group)",
|
||||
"(method 14 collide-shape-prim-sphere)",
|
||||
"(method 14 collide-shape-prim-mesh)",
|
||||
"(method 12 collide-shape-prim-group)", // BUG: maybe
|
||||
"(method 12 collide-shape-prim-sphere)",
|
||||
"(method 12 collide-shape-prim-mesh)",
|
||||
"(method 29 collide-cache)",
|
||||
"(method 27 collide-cache)",
|
||||
"(method 14 collide-cache)",
|
||||
"(method 28 collide-cache)",
|
||||
"(method 26 collide-cache)",
|
||||
"(method 21 collide-cache)",
|
||||
"(method 32 collide-cache)",
|
||||
|
||||
// memory-usage BUG
|
||||
"(method 14 level)",
|
||||
|
||||
// navigate BUG
|
||||
"(method 32 nav-control)",
|
||||
|
||||
// collectables BUG
|
||||
"birth-pickup-at-point",
|
||||
"add-blue-motion",
|
||||
|
||||
// ocean
|
||||
"draw-large-polygon-ocean",
|
||||
|
||||
// ocean-vu0
|
||||
"ocean-generate-verts",
|
||||
"ocean-interp-wave",
|
||||
|
||||
// anim-tester BUG
|
||||
"anim-tester-add-newobj",
|
||||
|
||||
// nav-enemy BUG
|
||||
"(anon-function 28 nav-enemy)",
|
||||
|
||||
// orb-cache BUG
|
||||
"(method 27 orb-cache-top)",
|
||||
|
||||
// ropebridge BUG
|
||||
"(method 27 ropebridge)",
|
||||
|
||||
// all unchecked.and in level DGO code
|
||||
"(anon-function 11 robotboss)",
|
||||
"(anon-function 18 robotboss)",
|
||||
"(anon-function 49 robotboss)",
|
||||
"(anon-function 21 plant-boss)",
|
||||
"(anon-function 10 ice-cube)",
|
||||
"(anon-function 15 ice-cube)",
|
||||
"(anon-function 45 lavatube-energy)",
|
||||
"(anon-function 5 game-save)",
|
||||
"(anon-function 6 game-save)",
|
||||
"(anon-function 7 game-save)",
|
||||
"(anon-function 8 game-save)",
|
||||
"(anon-function 9 game-save)",
|
||||
"(anon-function 10 game-save)",
|
||||
"(anon-function 28 nav-enemy)",
|
||||
"mistycannon-find-best-solution",
|
||||
"target-flut-falling-anim-trans",
|
||||
"kermit-check-to-hit-player?",
|
||||
"(anon-function 6 title-obs)",
|
||||
"(anon-function 36 mistycannon)",
|
||||
"(anon-function 5 battlecontroller)",
|
||||
"(anon-function 43 maincave-obs)",
|
||||
"(anon-function 2 target-tube)",
|
||||
"(anon-function 5 orbit-plat)",
|
||||
"(anon-function 2 ogreboss)",
|
||||
|
||||
// not enough type info to decompile these
|
||||
// (these are NOT actually asm functions)
|
||||
"(method 15 sync-info)", // NEED *res-static-buf*
|
||||
"(method 15 sync-info-eased)", // NEED *res-static-buf*
|
||||
"(method 15 sync-info-paused)" // NEED *res-static-buf*
|
||||
],
|
||||
|
||||
"pair_functions_by_name":["ref", "last", "member", "nmember", "assoc", "assoce", "append!", "delete!", "delete-car!",
|
||||
"insert-cons!", "sort", "unload-package", "(method 4 pair)", "nassoc", "nassoce", "lookup-level-info", "(method 21 level-group)"]
|
||||
}
|
||||
"obj_file_name_map_file": "goal_src/build/all_objs.json"
|
||||
}
|
||||
|
|
450
decompiler/config/jak1_ntsc_black_label/hacks.jsonc
Normal file
450
decompiler/config/jak1_ntsc_black_label/hacks.jsonc
Normal file
|
@ -0,0 +1,450 @@
|
|||
{
|
||||
////////////////////////////
|
||||
// HACKS and ASM FUNCTIONS
|
||||
////////////////////////////
|
||||
|
||||
"types_with_bad_inspect_methods": [
|
||||
"engine",
|
||||
"bsp-header",
|
||||
"joint-anim-matrix",
|
||||
"part-tracker"
|
||||
],
|
||||
|
||||
"no_type_analysis_functions_by_name": [],
|
||||
|
||||
// this provides a hint to the decompiler that these functions will have a lot of inline assembly.
|
||||
"hint_inline_assembly_functions": ["matrix-transpose!"],
|
||||
|
||||
"asm_functions_by_name": [
|
||||
// gcommon
|
||||
"quad-copy!",
|
||||
|
||||
// gkernel
|
||||
"(method 11 cpu-thread)",
|
||||
"throw",
|
||||
"return-from-thread",
|
||||
"return-from-thread-dead",
|
||||
"reset-and-call",
|
||||
"(method 10 cpu-thread)",
|
||||
"(method 0 catch-frame)",
|
||||
"throw-dispatch",
|
||||
"set-to-run-bootstrap",
|
||||
"run-function-in-process", // not asm, but it uses the stack.
|
||||
|
||||
// pskernel
|
||||
"return-from-exception", // F: eret
|
||||
"kernel-read-function", // F: delay slot tricks
|
||||
"kernel-write-function", // F: delay slot tricks
|
||||
"kernel-copy-function",
|
||||
"kernel-check-hardwired-addresses",
|
||||
|
||||
// math
|
||||
"rand-uint31-gen",
|
||||
|
||||
// bounding box
|
||||
"(method 9 bounding-box)", // F: asm branching
|
||||
"(method 14 bounding-box)",
|
||||
|
||||
// matrix
|
||||
"(method 9 matrix)", // F: asm branching
|
||||
"matrix-axis-sin-cos!", // F: asm branching
|
||||
"matrix-axis-sin-cos-vu!",
|
||||
|
||||
// geometry
|
||||
"curve-evaluate!", // BUG: cfg fails, suspected weird gotos
|
||||
"circle-circle-xz-intersect", // F: asm branching
|
||||
"closest-pt-in-triangle", // F: asm branching
|
||||
"find-knot-span", // ??
|
||||
"vector-segment-distance-point!",
|
||||
|
||||
// trigonometry
|
||||
"exp", // BUG: cfg is wrong.
|
||||
"atan0", // P: manual use of stack
|
||||
"sincos!", // P: manual use of stack
|
||||
"sincos-rad!",
|
||||
|
||||
// dma-h
|
||||
"dma-count-until-done", // F: asm branching
|
||||
"dma-sync-with-count", // F: asm branching
|
||||
"dma-send-no-scratch", // F: asm branching
|
||||
"dma-sync-fast",
|
||||
|
||||
// dma
|
||||
"symlink3", // F: asm branching
|
||||
"symlink2", // F: asm branching
|
||||
"dma-sync-hang",
|
||||
|
||||
// display
|
||||
"vblank-handler", // F: weird asm for interrupt handler
|
||||
"vif1-handler", // F: weird asm for interrupt handler
|
||||
"vif1-handler-debug",
|
||||
|
||||
// vector
|
||||
"vector=", // asm branching
|
||||
|
||||
// texture
|
||||
"adgif-shader<-texture-with-update!", // F: asm branching
|
||||
"(method 9 texture-page-dir)",
|
||||
|
||||
// collide-mesh-h
|
||||
"(method 11 collide-mesh-cache)",
|
||||
|
||||
// actor-link-h (BUG)
|
||||
"(method 21 actor-link-info)", // BUG: sc cfg / cfg-ir bug
|
||||
"(method 20 actor-link-info)",
|
||||
|
||||
// collide-func
|
||||
"moving-sphere-triangle-intersect", // P: weird branching
|
||||
"collide-do-primitives", // P: asm branching
|
||||
"ray-triangle-intersect", // F: asm branching
|
||||
"ray-cylinder-intersect", // F: asm branching
|
||||
"raw-ray-sphere-intersect",
|
||||
|
||||
// joint
|
||||
"calc-animation-from-spr", // F: asm branching
|
||||
"decompress-frame-data-pair-to-accumulator", // P: asm calling
|
||||
"decompress-frame-data-to-accumulator", // P: asm calling
|
||||
"decompress-fixed-data-to-accumulator", // P: asm calling
|
||||
"normalize-frame-quaternions", // F: asm branching, return
|
||||
"clear-frame-accumulator", // F: asm branching
|
||||
"cspace<-parented-transformq-joint!",
|
||||
|
||||
// bsp
|
||||
"level-remap-texture", // BUG: probably missing branch case?
|
||||
"bsp-camera-asm", // F: asm branching
|
||||
"sprite-draw-distorters",
|
||||
|
||||
// merc-blend-shape
|
||||
"setup-blerc-chains-for-one-fragment", // F: asm branching
|
||||
"blerc-execute", // F: asm branching
|
||||
"merc-dma-chain-to-spr", // F: asm branching
|
||||
"blerc-a-fragment",
|
||||
|
||||
// ripple
|
||||
"ripple-matrix-scale",
|
||||
"ripple-apply-wave-table",
|
||||
"ripple-create-wave-table",
|
||||
"ripple-execute-init",
|
||||
|
||||
// bones
|
||||
"draw-bones-hud",
|
||||
"draw-bones",
|
||||
"draw-bones-check-longest-edge-asm",
|
||||
"draw-bones-merc",
|
||||
"bones-mtx-calc-execute",
|
||||
"bones-mtx-calc",
|
||||
"texscroll-execute",
|
||||
|
||||
// generic-effect
|
||||
"generic-debug-light-proc",
|
||||
"generic-none-dma-wait",
|
||||
"generic-copy-vtx-dclr-dtex",
|
||||
"generic-light",
|
||||
"generic-envmap-only-proc",
|
||||
"generic-no-light",
|
||||
"generic-no-light+envmap",
|
||||
"generic-no-light-dproc",
|
||||
"generic-no-light-dproc-only",
|
||||
"generic-no-light-proc",
|
||||
"generic-interp-dproc",
|
||||
"generic-envmap-dproc",
|
||||
"generic-prepare-dma-single",
|
||||
"generic-prepare-dma-double",
|
||||
"generic-envmap-proc",
|
||||
"generic-light-proc",
|
||||
"generic-dma-from-spr",
|
||||
"upload-vu0-program",
|
||||
|
||||
// generic-merc
|
||||
"generic-merc-execute-all",
|
||||
"generic-merc-execute-asm",
|
||||
"high-speed-reject",
|
||||
"mercneric-convert",
|
||||
"mercneric-bittable-asm",
|
||||
"mercneric-shader-asm",
|
||||
"mercneric-matrix-asm",
|
||||
"generic-merc-init-asm",
|
||||
|
||||
// generic-tie
|
||||
"generic-tie-convert",
|
||||
"generic-tie-convert-proc",
|
||||
"generic-tie-upload-next",
|
||||
"generic-tie-decompress",
|
||||
"generic-tie-dma-to-spad-sync",
|
||||
|
||||
// shadow-cpu
|
||||
"shadow-execute",
|
||||
"shadow-add-double-edges",
|
||||
"shadow-add-double-tris",
|
||||
"shadow-add-single-edges",
|
||||
"shadow-add-facing-single-tris",
|
||||
"shadow-add-verts",
|
||||
"shadow-find-double-edges",
|
||||
"shadow-find-facing-double-tris",
|
||||
"shadow-find-single-edges",
|
||||
"shadow-find-facing-single-tris",
|
||||
"shadow-scissor-top",
|
||||
"shadow-scissor-edges",
|
||||
"shadow-calc-dual-verts",
|
||||
|
||||
// font
|
||||
"get-string-length",
|
||||
"draw-string",
|
||||
|
||||
// decomp
|
||||
"(method 16 level)", // BUG: cfg fails
|
||||
"unpack-comp-huf",
|
||||
"unpack-comp-rle",
|
||||
|
||||
// background
|
||||
"upload-vis-bits",
|
||||
"background-upload-vu0",
|
||||
|
||||
// draw-node
|
||||
"draw-node-cull",
|
||||
|
||||
// shrubbery
|
||||
"test-func",
|
||||
"draw-inline-array-instance-shrub",
|
||||
|
||||
// tfrag
|
||||
"stats-tfrag-asm",
|
||||
"draw-inline-array-tfrag-near",
|
||||
"draw-inline-array-tfrag",
|
||||
|
||||
// tie-methods
|
||||
"draw-inline-array-prototype-tie-near-asm",
|
||||
"draw-inline-array-prototype-tie-asm",
|
||||
"draw-inline-array-prototype-tie-generic-asm",
|
||||
"draw-inline-array-instance-tie",
|
||||
|
||||
// sparticle-launcher
|
||||
"(method 11 sparticle-launch-control)", // BUG: cfg ir
|
||||
"sp-launch-particles-var",
|
||||
"particle-adgif",
|
||||
"sp-init-fields!",
|
||||
|
||||
// sparticle
|
||||
"memcpy",
|
||||
"sp-process-block-3d",
|
||||
"sp-process-block-2d",
|
||||
"sp-get-particle",
|
||||
|
||||
// loader BUG
|
||||
"(method 10 external-art-buffer)",
|
||||
|
||||
// game-info BUG
|
||||
"(method 11 fact-info-target)",
|
||||
|
||||
// game-save BUG
|
||||
"(anon-function 5 game-save)", // BUG:
|
||||
"(anon-function 6 game-save)", // BUG:
|
||||
"(anon-function 7 game-save)", // BUG:
|
||||
"(anon-function 8 game-save)", // BUG:
|
||||
"(anon-function 9 game-save)", // BUG:
|
||||
"(anon-function 10 game-save)",
|
||||
|
||||
// mood BUG
|
||||
"update-mood-lava", // BUG:
|
||||
"update-mood-lightning",
|
||||
|
||||
// time-of-day
|
||||
"time-of-day-interp-colors-scratch",
|
||||
"time-of-day-interp-colors",
|
||||
|
||||
// sky-tng
|
||||
"clip-polygon-against-negative-hyperplane",
|
||||
"clip-polygon-against-positive-hyperplane",
|
||||
"draw-large-polygon",
|
||||
|
||||
// load-boundary
|
||||
"render-boundary-tri",
|
||||
"render-boundary-quad",
|
||||
"draw-boundary-polygon",
|
||||
|
||||
// level BUG
|
||||
"level-update-after-load",
|
||||
|
||||
// text BUG
|
||||
"load-game-text-info",
|
||||
|
||||
// collide-probe
|
||||
"collide-probe-instance-tie",
|
||||
"collide-probe-node",
|
||||
|
||||
// collide-mesh
|
||||
"(method 10 collide-mesh)",
|
||||
"(method 13 collide-mesh)",
|
||||
"(method 9 collide-mesh-cache)",
|
||||
"(method 15 collide-mesh)",
|
||||
"(method 14 collide-mesh)",
|
||||
"(method 11 collide-mesh)",
|
||||
"(method 12 collide-mesh)",
|
||||
|
||||
// collide-edge-grab
|
||||
"(method 13 collide-edge-work)",
|
||||
"(method 17 collide-edge-work)",
|
||||
"(method 15 collide-edge-work)",
|
||||
"(method 16 collide-edge-work)",
|
||||
"(method 9 edge-grab-info)", // maybe bug
|
||||
"(method 18 collide-edge-work)",
|
||||
"(method 10 collide-edge-hold-list)",
|
||||
|
||||
// collide-shape
|
||||
"(method 15 collide-shape-prim-mesh)", // BUG:
|
||||
"(method 15 collide-shape-prim-sphere)", // BUG:
|
||||
"(method 16 collide-shape-prim)",
|
||||
"(method 15 collide-shape-prim-group)",
|
||||
"(method 40 collide-shape)",
|
||||
"(method 45 collide-shape)",
|
||||
"(method 28 collide-shape-prim-mesh)", // BUG:
|
||||
"(method 29 collide-shape-prim-group)",
|
||||
"(method 20 collide-shape-prim-group)",
|
||||
"(method 19 collide-shape-prim-sphere)",
|
||||
"(method 18 collide-shape-prim-sphere)",
|
||||
"(method 23 collide-shape-prim-sphere)",
|
||||
"(method 23 collide-shape-prim-mesh)", // BUG: maybe
|
||||
"(method 24 collide-shape-prim)",
|
||||
"(method 23 collide-shape-prim-group)",
|
||||
"(method 42 collide-shape)",
|
||||
|
||||
// collide-shape-rider
|
||||
"(method 35 collide-shape)",
|
||||
|
||||
// cam-master BUG
|
||||
"master-is-hopeful-better?",
|
||||
|
||||
// cam-layout BUG
|
||||
"cam-layout-save-cam-trans",
|
||||
|
||||
// process-drawable BUG
|
||||
"cspace-inspect-tree", // BUG:
|
||||
"process-drawable-birth-fuel-cell", // BUG:
|
||||
"(method 19 process-drawable)",
|
||||
|
||||
// ambient
|
||||
"ambient-inspect",
|
||||
|
||||
// generic-obs BUG
|
||||
"camera-change-to",
|
||||
|
||||
// target BUG
|
||||
"target-falling-anim-trans",
|
||||
|
||||
// target2 BUG
|
||||
"(anon-function 33 target2)", // BUG:
|
||||
"(anon-function 67 target2)", // BUG:
|
||||
"look-for-points-of-interest",
|
||||
|
||||
// menu BUG
|
||||
"debug-menu-item-var-render",
|
||||
|
||||
// drawable-tree
|
||||
"(method 16 drawable-tree)",
|
||||
|
||||
// collide-cache
|
||||
"(method 10 collide-puss-work)",
|
||||
"(method 9 collide-puss-work)",
|
||||
"(method 19 collide-cache)",
|
||||
"(method 10 collide-cache-prim)",
|
||||
"(method 9 collide-cache-prim)",
|
||||
"(method 30 collide-cache)",
|
||||
"(method 13 collide-shape-prim-group)",
|
||||
"(method 13 collide-shape-prim-sphere)",
|
||||
"(method 13 collide-shape-prim-mesh)",
|
||||
"(method 14 collide-shape-prim-group)",
|
||||
"(method 14 collide-shape-prim-sphere)",
|
||||
"(method 14 collide-shape-prim-mesh)",
|
||||
"(method 12 collide-shape-prim-group)", // BUG: maybe
|
||||
"(method 12 collide-shape-prim-sphere)",
|
||||
"(method 12 collide-shape-prim-mesh)",
|
||||
"(method 29 collide-cache)",
|
||||
"(method 27 collide-cache)",
|
||||
"(method 14 collide-cache)",
|
||||
"(method 28 collide-cache)",
|
||||
"(method 26 collide-cache)",
|
||||
"(method 21 collide-cache)",
|
||||
"(method 32 collide-cache)",
|
||||
|
||||
// memory-usage BUG
|
||||
"(method 14 level)",
|
||||
|
||||
// navigate BUG
|
||||
"(method 32 nav-control)",
|
||||
|
||||
// collectables BUG
|
||||
"birth-pickup-at-point",
|
||||
"add-blue-motion",
|
||||
|
||||
// ocean
|
||||
"draw-large-polygon-ocean",
|
||||
|
||||
// ocean-vu0
|
||||
"ocean-generate-verts",
|
||||
"ocean-interp-wave",
|
||||
|
||||
// anim-tester BUG
|
||||
"anim-tester-add-newobj",
|
||||
|
||||
// nav-enemy BUG
|
||||
"(anon-function 28 nav-enemy)",
|
||||
|
||||
// orb-cache BUG
|
||||
"(method 27 orb-cache-top)",
|
||||
|
||||
// ropebridge BUG
|
||||
"(method 27 ropebridge)",
|
||||
|
||||
// all unchecked.and in level DGO code
|
||||
"(anon-function 11 robotboss)",
|
||||
"(anon-function 18 robotboss)",
|
||||
"(anon-function 49 robotboss)",
|
||||
"(anon-function 21 plant-boss)",
|
||||
"(anon-function 10 ice-cube)",
|
||||
"(anon-function 15 ice-cube)",
|
||||
"(anon-function 45 lavatube-energy)",
|
||||
"(anon-function 5 game-save)",
|
||||
"(anon-function 6 game-save)",
|
||||
"(anon-function 7 game-save)",
|
||||
"(anon-function 8 game-save)",
|
||||
"(anon-function 9 game-save)",
|
||||
"(anon-function 10 game-save)",
|
||||
"(anon-function 28 nav-enemy)",
|
||||
"mistycannon-find-best-solution",
|
||||
"target-flut-falling-anim-trans",
|
||||
"kermit-check-to-hit-player?",
|
||||
"(anon-function 6 title-obs)",
|
||||
"(anon-function 36 mistycannon)",
|
||||
"(anon-function 5 battlecontroller)",
|
||||
"(anon-function 43 maincave-obs)",
|
||||
"(anon-function 2 target-tube)",
|
||||
"(anon-function 5 orbit-plat)",
|
||||
"(anon-function 2 ogreboss)",
|
||||
|
||||
// not enough type info to decompile these
|
||||
// (these are NOT actually asm functions)
|
||||
"(method 15 sync-info)", // NEED *res-static-buf*
|
||||
"(method 15 sync-info-eased)", // NEED *res-static-buf*
|
||||
"(method 15 sync-info-paused)" // NEED *res-static-buf*
|
||||
],
|
||||
|
||||
"pair_functions_by_name": [
|
||||
"ref",
|
||||
"last",
|
||||
"member",
|
||||
"nmember",
|
||||
"assoc",
|
||||
"assoce",
|
||||
"append!",
|
||||
"delete!",
|
||||
"delete-car!",
|
||||
"insert-cons!",
|
||||
"sort",
|
||||
"unload-package",
|
||||
"(method 4 pair)",
|
||||
"nassoc",
|
||||
"nassoce",
|
||||
"lookup-level-info",
|
||||
"(method 21 level-group)"
|
||||
]
|
||||
}
|
260
decompiler/config/jak1_ntsc_black_label/inputs.jsonc
Normal file
260
decompiler/config/jak1_ntsc_black_label/inputs.jsonc
Normal file
|
@ -0,0 +1,260 @@
|
|||
{
|
||||
//////////////////////
|
||||
// INPUT FILES
|
||||
//////////////////////
|
||||
|
||||
// input is GOAL object files, possibly in containers.
|
||||
// most objects are part of CGO/DGO files (both go in dgo_names). This includes levels and the engine
|
||||
// the DGOs will be processed in this order. Usually it's best to have KERNEL, ENGINE, then the levels when
|
||||
// you want to run on the entire game.
|
||||
"dgo_names": [
|
||||
"CGO/KERNEL.CGO",
|
||||
"CGO/ENGINE.CGO",
|
||||
"CGO/GAME.CGO",
|
||||
"CGO/ART.CGO",
|
||||
"DGO/BEA.DGO",
|
||||
"DGO/CIT.DGO",
|
||||
"CGO/COMMON.CGO",
|
||||
"DGO/DAR.DGO",
|
||||
"DGO/DEM.DGO",
|
||||
"DGO/FIN.DGO",
|
||||
"DGO/INT.DGO",
|
||||
"DGO/JUB.DGO",
|
||||
"DGO/JUN.DGO",
|
||||
"CGO/JUNGLE.CGO",
|
||||
"CGO/L1.CGO",
|
||||
"DGO/FIC.DGO",
|
||||
"DGO/LAV.DGO",
|
||||
"DGO/MAI.DGO",
|
||||
"CGO/MAINCAVE.CGO",
|
||||
"DGO/MIS.DGO",
|
||||
"DGO/OGR.DGO",
|
||||
"CGO/RACERP.CGO",
|
||||
"DGO/ROB.DGO",
|
||||
"DGO/ROL.DGO",
|
||||
"DGO/SNO.DGO",
|
||||
"DGO/SUB.DGO",
|
||||
"DGO/SUN.DGO",
|
||||
"CGO/SUNKEN.CGO",
|
||||
"DGO/SWA.DGO",
|
||||
"DGO/TIT.DGO",
|
||||
"DGO/TRA.DGO",
|
||||
"DGO/VI1.DGO",
|
||||
"DGO/VI2.DGO",
|
||||
"DGO/VI3.DGO",
|
||||
"CGO/VILLAGEP.CGO",
|
||||
"CGO/WATER-AN.CGO"
|
||||
],
|
||||
|
||||
// some objects are part of STR files (streaming data). In Jak 1 this is just animations
|
||||
"str_file_names": [
|
||||
"STR/BAFCELL.STR",
|
||||
"STR/SWTE4.STR",
|
||||
"STR/SWTE3.STR",
|
||||
"STR/SWTE2.STR",
|
||||
"STR/SWTE1.STR",
|
||||
"STR/SNRBSBFC.STR",
|
||||
"STR/SNRBIPFC.STR",
|
||||
"STR/SNRBICFC.STR",
|
||||
"STR/ORR3.STR",
|
||||
"STR/ORR2.STR",
|
||||
"STR/MICANNON.STR",
|
||||
"STR/BECANNON.STR",
|
||||
"STR/SWTS4.STR",
|
||||
"STR/SWTS3.STR",
|
||||
"STR/SWTS2.STR",
|
||||
"STR/SW4.STR",
|
||||
"STR/SW3.STR",
|
||||
"STR/SW2.STR",
|
||||
"STR/SWTS1.STR",
|
||||
"STR/ORREYE.STR",
|
||||
"STR/ORLEYE.STR",
|
||||
"STR/SW1.STR",
|
||||
"STR/MAGFCELL.STR",
|
||||
"STR/GNFCELL.STR",
|
||||
"STR/ORRE3.STR",
|
||||
"STR/ORRE2.STR",
|
||||
"STR/ORRE1.STR",
|
||||
"STR/ORR1.STR",
|
||||
"STR/ORLE3.STR",
|
||||
"STR/ORLE2.STR",
|
||||
"STR/ORI3.STR",
|
||||
"STR/ORI2.STR",
|
||||
"STR/DE0202.STR",
|
||||
"STR/RARSANIM.STR",
|
||||
"STR/RARANIM.STR",
|
||||
"STR/EIFISH.STR",
|
||||
"STR/ORLE1.STR",
|
||||
"STR/SWTEF4.STR",
|
||||
"STR/SWTEF3.STR",
|
||||
"STR/SWTEF2.STR",
|
||||
"STR/SWTEF1.STR",
|
||||
"STR/ORI1.STR",
|
||||
"STR/EIICE.STR",
|
||||
"STR/EIA3.STR",
|
||||
"STR/DE0191.STR",
|
||||
"STR/DE0186.STR",
|
||||
"STR/DE0187.STR",
|
||||
"STR/EIA4.STR",
|
||||
"STR/EIPOLE.STR",
|
||||
"STR/RARASECO.STR",
|
||||
"STR/RARA2.STR",
|
||||
"STR/DE0184.STR",
|
||||
"STR/DE0181.STR",
|
||||
"STR/PESEXT.STR",
|
||||
"STR/DE0195.STR",
|
||||
"STR/EIA2.STR",
|
||||
"STR/FIR1.STR",
|
||||
"STR/DE0182.STR",
|
||||
"STR/BIR1.STR",
|
||||
"STR/HAPOPEN.STR",
|
||||
"STR/EITUBE.STR",
|
||||
"STR/SCR1.STR",
|
||||
"STR/DE0197.STR",
|
||||
"STR/DE0193.STR",
|
||||
"STR/EIA1.STR",
|
||||
"STR/FAR2.STR",
|
||||
"STR/FAR1.STR",
|
||||
"STR/DE0199.STR",
|
||||
"STR/GERMONEY.STR",
|
||||
"STR/BIRESOLU.STR",
|
||||
"STR/GARMONEY.STR",
|
||||
"STR/BIADVENT.STR",
|
||||
"STR/FUCRV1.STR",
|
||||
"STR/BIREJECT.STR",
|
||||
"STR/WAR1.STR",
|
||||
"STR/BIACCEPT.STR",
|
||||
"STR/SA3R1DEC.STR",
|
||||
"STR/ASR1GENE.STR",
|
||||
"STR/FIREJECT.STR",
|
||||
"STR/GARRACE.STR",
|
||||
"STR/GEZMONEY.STR",
|
||||
"STR/LRFALLIN.STR",
|
||||
"STR/EXR2.STR",
|
||||
"STR/GERMOLES.STR",
|
||||
"STR/FUCVICTO.STR",
|
||||
"STR/MIR1ORBS.STR",
|
||||
"STR/SA3R1RAM.STR",
|
||||
"STR/AS2R1FLU.STR",
|
||||
"STR/FUCV2.STR",
|
||||
"STR/MIR1GNAW.STR",
|
||||
"STR/GAZMONEY.STR",
|
||||
"STR/AS3REMIN.STR",
|
||||
"STR/SIHISA.STR",
|
||||
"STR/FIACCEPT.STR",
|
||||
"STR/FIWECO.STR",
|
||||
"STR/FARESOLU.STR",
|
||||
"STR/ASR1RBIK.STR",
|
||||
"STR/MARDONAT.STR",
|
||||
"STR/GAZRACE.STR",
|
||||
"STR/FUCFV1.STR",
|
||||
"STR/FUCV5.STR",
|
||||
"STR/SABR1CDU.STR",
|
||||
"STR/FLLINTRO.STR",
|
||||
"STR/SAR1ECOR.STR",
|
||||
"STR/AS2R1ROB.STR",
|
||||
"STR/MIR2ORBS.STR",
|
||||
"STR/MARBEAMS.STR",
|
||||
"STR/LOI2.STR",
|
||||
"STR/SAR1GENE.STR",
|
||||
"STR/BILR1.STR",
|
||||
"STR/AS2R1ROO.STR",
|
||||
"STR/ASR1BESW.STR",
|
||||
"STR/LOLOOP.STR",
|
||||
"STR/FAINTROD.STR",
|
||||
"STR/GEZMOLES.STR",
|
||||
"STR/V1IN.STR",
|
||||
"STR/FUCV4.STR",
|
||||
"STR/SAIECORO.STR",
|
||||
"STR/MIR1SWIT.STR",
|
||||
"STR/LOINTRO.STR",
|
||||
"STR/SAR2GENE.STR",
|
||||
"STR/MUVICTOR.STR",
|
||||
"STR/SAR1MCAN.STR",
|
||||
"STR/FUCV7.STR",
|
||||
"STR/MIZ1ORBS.STR",
|
||||
"STR/FUCV8.STR",
|
||||
"STR/BILR2.STR",
|
||||
"STR/FUCV6.STR",
|
||||
"STR/FUCV3.STR",
|
||||
"STR/PLLBLOWU.STR",
|
||||
"STR/PLBMAIN.STR",
|
||||
"STR/WARESOLU.STR",
|
||||
"STR/EIRACER.STR",
|
||||
"STR/MAZDONAT.STR",
|
||||
"STR/MAZBEAMS.STR",
|
||||
"STR/MIISWITC.STR",
|
||||
"STR/FIBRTVIL.STR",
|
||||
"STR/FIBRTMIS.STR",
|
||||
"STR/SABR1PAR.STR",
|
||||
"STR/NDINTRO.STR",
|
||||
"STR/GORDOWN.STR",
|
||||
"STR/GORUP.STR",
|
||||
"STR/SA3IRAMS.STR",
|
||||
"STR/YERESOLU.STR",
|
||||
"STR/EIFLUT.STR",
|
||||
"STR/GRSDSACR.STR",
|
||||
"STR/EXR1.STR",
|
||||
"STR/SCRESOLU.STR",
|
||||
"STR/FIRESOLU.STR",
|
||||
"STR/SIHITEST.STR",
|
||||
"STR/GAI1.STR",
|
||||
"STR/EXRESOLU.STR",
|
||||
"STR/MIZ2ORBS.STR",
|
||||
"STR/ASIRBIKE.STR",
|
||||
"STR/GRSOBBEC.STR",
|
||||
"STR/BIINTROD.STR",
|
||||
"STR/GRSOBBNC.STR",
|
||||
"STR/AS2IROBB.STR",
|
||||
"STR/GRSOBFIN.STR",
|
||||
"STR/RERESOLU.STR",
|
||||
"STR/BLRESOLU.STR",
|
||||
"STR/SABIPARM.STR",
|
||||
"STR/EVMEND.STR",
|
||||
"STR/AS2RESOL.STR",
|
||||
"STR/SAIMCANN.STR",
|
||||
"STR/MIIGNAWE.STR",
|
||||
"STR/GRSOBBA.STR",
|
||||
"STR/GRSINTRO.STR",
|
||||
"STR/SAISE.STR",
|
||||
"STR/SA3IDECO.STR",
|
||||
"STR/ASFRESOL.STR",
|
||||
"STR/EXINTROD.STR",
|
||||
"STR/BILINTRO.STR",
|
||||
"STR/FIINTROD.STR",
|
||||
"STR/MAINTROD.STR",
|
||||
"STR/SCINTROD.STR",
|
||||
"STR/AS2IFLUT.STR",
|
||||
"STR/ASLERESO.STR",
|
||||
"STR/ASLSRESO.STR",
|
||||
"STR/AS2IROOM.STR",
|
||||
"STR/GRSRESOL.STR",
|
||||
"STR/SABICDUS.STR",
|
||||
"STR/SIHISB.STR",
|
||||
"STR/ASIBESWI.STR",
|
||||
"STR/BILBRESO.STR",
|
||||
"STR/FIBRT1AL.STR",
|
||||
"STR/AS2INTRO.STR",
|
||||
"STR/GEINTROD.STR",
|
||||
"STR/SAISD1.STR",
|
||||
"STR/SAISA.STR",
|
||||
"STR/SIHISC.STR",
|
||||
"STR/MIIORBS.STR",
|
||||
"STR/WAINTROD.STR",
|
||||
"STR/SAISD2.STR",
|
||||
"STR/GRSOPREB.STR",
|
||||
"STR/GRSOBBB.STR",
|
||||
"STR/SA3INTRO.STR"
|
||||
],
|
||||
|
||||
// some objects are directly stored as files on the DVD. This is just text files.
|
||||
"object_file_names": [
|
||||
"TEXT/0COMMON.TXT",
|
||||
"TEXT/1COMMON.TXT",
|
||||
"TEXT/2COMMON.TXT",
|
||||
"TEXT/3COMMON.TXT",
|
||||
"TEXT/4COMMON.TXT",
|
||||
"TEXT/5COMMON.TXT",
|
||||
"TEXT/6COMMON.TXT"
|
||||
]
|
||||
}
|
|
@ -25,20 +25,20 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
// collect all files to process
|
||||
set_config(argv[1]);
|
||||
auto config = read_config_file(argv[1]);
|
||||
std::string in_folder = argv[2];
|
||||
std::string out_folder = argv[3];
|
||||
|
||||
std::vector<std::string> dgos, objs, strs;
|
||||
for (const auto& dgo_name : get_config().dgo_names) {
|
||||
for (const auto& dgo_name : config.dgo_names) {
|
||||
dgos.push_back(file_util::combine_path(in_folder, dgo_name));
|
||||
}
|
||||
|
||||
for (const auto& obj_name : get_config().object_file_names) {
|
||||
for (const auto& obj_name : config.object_file_names) {
|
||||
objs.push_back(file_util::combine_path(in_folder, obj_name));
|
||||
}
|
||||
|
||||
for (const auto& str_name : get_config().str_file_names) {
|
||||
for (const auto& str_name : config.str_file_names) {
|
||||
strs.push_back(file_util::combine_path(in_folder, str_name));
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
// build file database
|
||||
lg::info("Setting up object file DB...");
|
||||
ObjectFileDB db(dgos, get_config().obj_file_name_map_file, objs, strs);
|
||||
ObjectFileDB db(dgos, config.obj_file_name_map_file, objs, strs, config);
|
||||
|
||||
// write out DGO file info
|
||||
file_util::write_text_file(file_util::combine_path(out_folder, "dgo.txt"),
|
||||
|
@ -56,57 +56,58 @@ int main(int argc, char** argv) {
|
|||
db.generate_obj_listing());
|
||||
|
||||
// dump raw objs
|
||||
if (get_config().dump_objs) {
|
||||
if (config.dump_objs) {
|
||||
auto path = file_util::combine_path(out_folder, "raw_obj");
|
||||
file_util::create_dir_if_needed(path);
|
||||
db.dump_raw_objects(path);
|
||||
}
|
||||
|
||||
// process files (required for all analysis)
|
||||
db.process_link_data();
|
||||
db.find_code();
|
||||
db.process_link_data(config);
|
||||
db.find_code(config);
|
||||
db.process_labels();
|
||||
|
||||
// print disassembly
|
||||
if (get_config().disassemble_code || get_config().disassemble_data) {
|
||||
db.write_disassembly(out_folder, get_config().disassemble_data, get_config().disassemble_code);
|
||||
if (config.disassemble_code || config.disassemble_data) {
|
||||
db.write_disassembly(out_folder, config.disassemble_data, config.disassemble_code,
|
||||
config.write_hex_near_instructions);
|
||||
}
|
||||
|
||||
// regenerate all-types if needed
|
||||
if (get_config().regenerate_all_types) {
|
||||
db.analyze_functions_ir1();
|
||||
if (config.regenerate_all_types) {
|
||||
db.analyze_functions_ir1(config);
|
||||
file_util::write_text_file(file_util::combine_path(out_folder, "type_defs.gc"),
|
||||
db.all_type_defs);
|
||||
}
|
||||
|
||||
// main decompile.
|
||||
if (get_config().decompile_code) {
|
||||
db.analyze_functions_ir2(out_folder);
|
||||
if (config.decompile_code) {
|
||||
db.analyze_functions_ir2(out_folder, config);
|
||||
}
|
||||
|
||||
// write out all symbols TODO - organize by file
|
||||
file_util::write_text_file(file_util::combine_path(out_folder, "all-syms.gc"),
|
||||
db.dts.dump_symbol_types());
|
||||
|
||||
if (get_config().hexdump_code || get_config().hexdump_data) {
|
||||
db.write_object_file_words(out_folder, get_config().hexdump_data, get_config().hexdump_code);
|
||||
if (config.hexdump_code || config.hexdump_data) {
|
||||
db.write_object_file_words(out_folder, config.hexdump_data, config.hexdump_code);
|
||||
}
|
||||
|
||||
// data stuff
|
||||
if (get_config().write_scripts) {
|
||||
if (config.write_scripts) {
|
||||
db.find_and_write_scripts(out_folder);
|
||||
}
|
||||
|
||||
if (get_config().process_game_text) {
|
||||
if (config.process_game_text) {
|
||||
auto result = db.process_game_text_files();
|
||||
file_util::write_text_file(file_util::get_file_path({"assets", "game_text.txt"}), result);
|
||||
}
|
||||
|
||||
if (get_config().process_tpages) {
|
||||
if (config.process_tpages) {
|
||||
db.process_tpages();
|
||||
}
|
||||
|
||||
if (get_config().process_game_count) {
|
||||
if (config.process_game_count) {
|
||||
auto result = db.process_game_count_file();
|
||||
file_util::write_text_file(file_util::get_file_path({"assets", "game_count.txt"}), result);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ echo "======================================="
|
|||
echo ""
|
||||
echo " ================= Cloning..."
|
||||
|
||||
cd ../..
|
||||
ISO_DATA_PATH=${1}
|
||||
BRANCH_NAME=${2:-master}
|
||||
# Provide a default location to bind the ISO_DATA_PATH
|
||||
|
@ -42,19 +41,22 @@ make -j
|
|||
echo " ================ Running unit tests..."
|
||||
../test.sh
|
||||
|
||||
echo " ================ Running offline decompiler tests..."
|
||||
./offline-test
|
||||
|
||||
echo " ================ Decompiling..."
|
||||
../decomp.sh
|
||||
../scripts/shell/decomp.sh
|
||||
|
||||
echo " ================ Building assets..."
|
||||
../gc.sh -cmd \(build-data\)
|
||||
../scripts/shell/gc.sh -cmd \(build-data\)
|
||||
|
||||
echo " ================ Checking assets..."
|
||||
../check.sh
|
||||
../scripts/shell/check.sh
|
||||
|
||||
echo " ================ Building game..."
|
||||
../gc.sh -cmd \(build-game\)
|
||||
../scripts/shell/gc.sh -cmd \(build-game\)
|
||||
|
||||
echo " ================ Booting game..."
|
||||
../boot_game.sh
|
||||
../scripts/shell/boot_game.sh
|
||||
|
||||
echo "Offline test has completed successfully!"
|
||||
|
|
|
@ -206,18 +206,19 @@ int main(int argc, char** argv) {
|
|||
class OfflineDecompilation : public ::testing::Test {
|
||||
protected:
|
||||
static std::unique_ptr<decompiler::ObjectFileDB> db;
|
||||
static std::unique_ptr<decompiler::Config> config;
|
||||
static void SetUpTestCase() {
|
||||
// global setup
|
||||
file_util::init_crc();
|
||||
decompiler::init_opcode_info();
|
||||
decompiler::set_config(
|
||||
file_util::get_file_path({"decompiler", "config", "jak1_ntsc_black_label.jsonc"}));
|
||||
config = std::make_unique<decompiler::Config>(decompiler::read_config_file(
|
||||
file_util::get_file_path({"decompiler", "config", "jak1_ntsc_black_label.jsonc"})));
|
||||
|
||||
std::unordered_set<std::string> object_files;
|
||||
for (auto& p : g_object_files_to_decompile_or_ref_check) {
|
||||
object_files.insert(p.first);
|
||||
}
|
||||
decompiler::get_config().allowed_objects = object_files;
|
||||
config->allowed_objects = object_files;
|
||||
|
||||
std::vector<std::string> dgos = {"CGO/KERNEL.CGO", "CGO/ENGINE.CGO"};
|
||||
std::vector<std::string> dgo_paths;
|
||||
|
@ -231,23 +232,27 @@ class OfflineDecompilation : public ::testing::Test {
|
|||
}
|
||||
}
|
||||
|
||||
db = std::make_unique<decompiler::ObjectFileDB>(
|
||||
dgo_paths, decompiler::get_config().obj_file_name_map_file, std::vector<std::string>{},
|
||||
std::vector<std::string>{});
|
||||
db = std::make_unique<decompiler::ObjectFileDB>(dgo_paths, config->obj_file_name_map_file,
|
||||
std::vector<std::string>{},
|
||||
std::vector<std::string>{}, *config);
|
||||
|
||||
// basic processing to find functions/data/disassembly
|
||||
db->process_link_data();
|
||||
db->find_code();
|
||||
db->process_link_data(*config);
|
||||
db->find_code(*config);
|
||||
db->process_labels();
|
||||
|
||||
// fancy decompilation.
|
||||
db->analyze_functions_ir2({});
|
||||
db->analyze_functions_ir2({}, *config);
|
||||
}
|
||||
|
||||
static void TearDownTestCase() { db.reset(); }
|
||||
static void TearDownTestCase() {
|
||||
db.reset();
|
||||
config.reset();
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<decompiler::ObjectFileDB> OfflineDecompilation::db;
|
||||
std::unique_ptr<decompiler::Config> OfflineDecompilation::config;
|
||||
|
||||
/*!
|
||||
* Check that the most basic disassembly into files/functions/instructions has succeeded.
|
||||
|
@ -263,7 +268,7 @@ TEST_F(OfflineDecompilation, CheckBasicDecode) {
|
|||
EXPECT_EQ(stats.n_fp_reg_use, stats.n_fp_reg_use_resolved);
|
||||
});
|
||||
|
||||
EXPECT_EQ(obj_count, decompiler::get_config().allowed_objects.size());
|
||||
EXPECT_EQ(obj_count, config->allowed_objects.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -302,7 +307,7 @@ TEST_F(OfflineDecompilation, FunctionDetect) {
|
|||
});
|
||||
|
||||
// one login per object file
|
||||
EXPECT_EQ(decompiler::get_config().allowed_objects.size(), login_count);
|
||||
EXPECT_EQ(config->allowed_objects.size(), login_count);
|
||||
|
||||
// not many lambdas.
|
||||
EXPECT_TRUE(unknown_count < 10);
|
||||
|
|
Loading…
Reference in a new issue