extractor: cleanup, support unicode properly, and add multi-game support (#1609)

* extractor: refactor and cleanup for multi-game support

* deps: switch to `ghc::filesystem` as it is utf-8 everywhere by default

* extractor: finally working with unicode

* unicode: fix unicode cli args on windows in all `main` functions
This commit is contained in:
Tyler Wilding
2022-07-05 20:38:13 -04:00
committed by GitHub
parent ac1e620161
commit 6446389263
70 changed files with 7010 additions and 765 deletions
+11 -12
View File
@@ -113,10 +113,10 @@ const ObjectFileData& ObjectFileDB::lookup_record(const ObjectFileRecord& rec) c
/*!
* Build an object file DB for the given list of DGOs.
*/
ObjectFileDB::ObjectFileDB(const std::vector<std::filesystem::path>& _dgos,
const std::filesystem::path& obj_file_name_map_file,
const std::vector<std::filesystem::path>& object_files,
const std::vector<std::filesystem::path>& str_files,
ObjectFileDB::ObjectFileDB(const std::vector<fs::path>& _dgos,
const fs::path& obj_file_name_map_file,
const std::vector<fs::path>& object_files,
const std::vector<fs::path>& str_files,
const Config& config) {
Timer timer;
@@ -258,7 +258,7 @@ void ObjectFileDB::load_map_file(const std::string& map_data) {
/*!
* Load the objects stored in the given DGO into the ObjectFileDB
*/
void ObjectFileDB::get_objs_from_dgo(const std::filesystem::path& filename, const Config& config) {
void ObjectFileDB::get_objs_from_dgo(const fs::path& filename, const Config& config) {
auto dgo_data = file_util::read_binary_file(filename);
stats.total_dgo_bytes += dgo_data.size();
@@ -516,7 +516,7 @@ void ObjectFileDB::process_labels() {
/*!
* Dump object files and their linking data to text files for debugging
*/
void ObjectFileDB::write_object_file_words(const std::filesystem::path& output_dir,
void ObjectFileDB::write_object_file_words(const fs::path& output_dir,
bool dump_data,
bool dump_code) {
lg::info("- Writing object file dumps (code? {} data? {})...", dump_code, dump_data);
@@ -545,7 +545,7 @@ void ObjectFileDB::write_object_file_words(const std::filesystem::path& output_d
/*!
* Dump disassembly for object files containing code. Data zones will also be dumped.
*/
void ObjectFileDB::write_disassembly(const std::filesystem::path& output_dir,
void ObjectFileDB::write_disassembly(const fs::path& output_dir,
bool disassemble_data,
bool disassemble_code,
bool print_hex) {
@@ -623,7 +623,7 @@ void ObjectFileDB::find_code(const Config& config) {
* Finds and writes all scripts into a file named all_scripts.lisp.
* Doesn't change any state in ObjectFileDB.
*/
void ObjectFileDB::find_and_write_scripts(const std::filesystem::path& output_dir) {
void ObjectFileDB::find_and_write_scripts(const fs::path& output_dir) {
lg::info("- Finding scripts in object files...");
Timer timer;
std::string all_scripts;
@@ -645,8 +645,7 @@ void ObjectFileDB::find_and_write_scripts(const std::filesystem::path& output_di
lg::info(" Total {:.3f} ms\n", timer.getMs());
}
std::string ObjectFileDB::process_tpages(TextureDB& tex_db,
const std::filesystem::path& output_path) {
std::string ObjectFileDB::process_tpages(TextureDB& tex_db, const fs::path& output_path) {
lg::info("- Finding textures in tpages...");
std::string tpage_string = "tpage-";
int total = 0, success = 0;
@@ -796,7 +795,7 @@ void ObjectFileDB::extract_art_info() {
/*!
* Write out the art group information.
*/
void ObjectFileDB::dump_art_info(const std::filesystem::path& output_dir) {
void ObjectFileDB::dump_art_info(const fs::path& output_dir) {
lg::info("Writing art group info...");
Timer timer;
@@ -820,7 +819,7 @@ void ObjectFileDB::dump_art_info(const std::filesystem::path& output_dir) {
lg::info("Written art group info: in {:.2f} ms\n", timer.getMs());
}
void ObjectFileDB::dump_raw_objects(const std::filesystem::path& output_dir) {
void ObjectFileDB::dump_raw_objects(const fs::path& output_dir) {
for_each_obj([&](ObjectFileData& data) {
auto dest = output_dir / data.to_unique_name();
if (data.obj_version != 3) {
+15 -16
View File
@@ -15,6 +15,7 @@
#include "common/common_types.h"
#include "common/util/Assert.h"
#include "common/util/FileUtil.h"
#include "decompiler/analysis/symbol_def_map.h"
#include "decompiler/data/TextureDB.h"
@@ -144,30 +145,28 @@ struct LetRewriteStats {
class ObjectFileDB {
public:
ObjectFileDB(const std::vector<std::filesystem::path>& _dgos,
const std::filesystem::path& obj_file_name_map_file,
const std::vector<std::filesystem::path>& object_files,
const std::vector<std::filesystem::path>& str_files,
ObjectFileDB(const std::vector<fs::path>& _dgos,
const fs::path& obj_file_name_map_file,
const std::vector<fs::path>& object_files,
const std::vector<fs::path>& str_files,
const Config& config);
std::string generate_dgo_listing();
std::string generate_obj_listing(const std::unordered_set<std::string>& merged_objs);
void process_link_data(const Config& config);
void process_labels();
void find_code(const Config& config);
void find_and_write_scripts(const std::filesystem::path& output_dir);
void find_and_write_scripts(const fs::path& output_dir);
void extract_art_info();
void dump_art_info(const std::filesystem::path& output_dir);
void dump_raw_objects(const std::filesystem::path& output_dir);
void write_object_file_words(const std::filesystem::path& output_dir,
bool dump_data,
bool dump_code);
void write_disassembly(const std::filesystem::path& output_dir,
void dump_art_info(const fs::path& output_dir);
void dump_raw_objects(const fs::path& output_dir);
void write_object_file_words(const fs::path& output_dir, bool dump_data, bool dump_code);
void write_disassembly(const fs::path& output_dir,
bool disassemble_data,
bool disassemble_code,
bool print_hex);
void analyze_functions_ir2(
const std::filesystem::path& output_dir,
const fs::path& output_dir,
const Config& config,
const std::unordered_set<std::string>& skip_functions,
const std::unordered_map<std::string, std::unordered_set<std::string>>& skip_states = {});
@@ -185,7 +184,7 @@ class ObjectFileDB {
void ir2_rewrite_inline_asm_instructions(int seg, ObjectFileData& data);
void ir2_insert_anonymous_functions(int seg, ObjectFileData& data);
void ir2_symbol_definition_map(ObjectFileData& data);
void ir2_write_results(const std::filesystem::path& output_dir,
void ir2_write_results(const fs::path& output_dir,
const Config& config,
const std::vector<std::string>& imports,
ObjectFileData& data);
@@ -193,7 +192,7 @@ class ObjectFileDB {
void ir2_do_segment_analysis_phase2(int seg, const Config& config, ObjectFileData& data);
void ir2_setup_labels(const Config& config, ObjectFileData& data);
void ir2_run_mips2c(const Config& config, ObjectFileData& data);
void ir2_analyze_all_types(const std::filesystem::path& output_file,
void ir2_analyze_all_types(const fs::path& output_file,
const std::optional<std::string>& previous_game_types,
const std::unordered_set<std::string>& bad_types);
std::string ir2_to_file(ObjectFileData& data, const Config& config);
@@ -202,7 +201,7 @@ class ObjectFileDB {
const std::vector<std::string>& imports,
const std::unordered_set<std::string>& skip_functions);
std::string process_tpages(TextureDB& tex_db, const std::filesystem::path& output_path);
std::string process_tpages(TextureDB& tex_db, const fs::path& output_path);
std::string process_game_count_file();
std::string process_game_text_files(const Config& cfg);
@@ -216,7 +215,7 @@ class ObjectFileDB {
public:
void load_map_file(const std::string& map_data);
void get_objs_from_dgo(const std::filesystem::path& filename, const Config& config);
void get_objs_from_dgo(const fs::path& 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,
+3 -3
View File
@@ -38,7 +38,7 @@ namespace decompiler {
* functions, but nothing else.
*/
void ObjectFileDB::analyze_functions_ir2(
const std::filesystem::path& output_dir,
const fs::path& output_dir,
const Config& config,
const std::unordered_set<std::string>& skip_functions,
const std::unordered_map<std::string, std::unordered_set<std::string>>& skip_states) {
@@ -300,7 +300,7 @@ void ObjectFileDB::ir2_top_level_pass(const Config& config) {
lg::info("{:4d} logins {:.2f}%\n", total_top_levels, 100.f * total_top_levels / total_functions);
}
void ObjectFileDB::ir2_analyze_all_types(const std::filesystem::path& output_file,
void ObjectFileDB::ir2_analyze_all_types(const fs::path& output_file,
const std::optional<std::string>& previous_game_types,
const std::unordered_set<std::string>& bad_types) {
struct PerObject {
@@ -690,7 +690,7 @@ void ObjectFileDB::ir2_insert_anonymous_functions(int seg, ObjectFileData& data)
});
}
void ObjectFileDB::ir2_write_results(const std::filesystem::path& output_dir,
void ObjectFileDB::ir2_write_results(const fs::path& output_dir,
const Config& config,
const std::vector<std::string>& imports,
ObjectFileData& obj) {