jak-project/decompiler/config.h

202 lines
6.9 KiB
C
Raw Permalink Normal View History

#pragma once
#include <optional>
2020-08-22 23:30:17 -04:00
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "common/common_types.h"
#include "common/util/FileUtil.h"
#include "common/versions/versions.h"
#include "decompiler/Disasm/Register.h"
#include "decompiler/data/TextureDB.h"
#include "decompiler/data/game_text.h"
#include "third-party/json.hpp"
namespace decompiler {
struct RegisterTypeCast {
int atomic_op_idx = -1;
Register reg;
std::string type_name;
};
2020-08-22 23:30:17 -04:00
struct StackTypeCast {
int stack_offset = -1;
std::string type_name;
};
struct LabelConfigInfo {
// if the label is a "value" type, it will be loaded directly into a register.
// in all cases, this is a constant, either a 64-bit integer or a float.
// For example:
// ld v1, L346(fp)
// lwc1 f0, L345(fp)
// lw a0, L41(fp)
// if the label is not a value type, it's a reference type, and the GOAL variable is a pointer.
bool is_value = false;
// the type of the resulting GOAL variable.
std::string type_name;
// if the type is a (pointer x) or (inline-array x), the size must be specified here.
// For a boxed array (array x), the size will be figured out automatically
std::optional<int> array_size;
};
struct LocalVarOverride {
std::string name;
// this may be left out, indicating that the variable should use the type determined
// by the type analysis pass.
std::optional<std::string> type;
};
/*!
* Information about a structure on the stack.
*/
struct StackStructureHint {
std::string element_type; // type of the thing stored
// todo - is boxed array on the stack supported?
enum class ContainerType {
NONE, // just store the plain thing.
ARRAY, // for refs, array of refs. For values, array of values.
INLINE_ARRAY // for refs, array of values, for values, invalid
} container_type = ContainerType::NONE;
int container_size = -1; // if container other than NONE, the number of elements.
int stack_offset = 0; // where it's located on the stack (relative to sp after prologue)
};
struct CondWithElseLengthHack {
std::unordered_map<std::string, int> max_length_by_start_block;
};
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;
std::unordered_map<std::string, CondWithElseLengthHack> cond_with_else_len_by_func_name;
std::unordered_set<std::string> reject_cond_to_value;
std::unordered_map<std::string, std::unordered_set<int>> blocks_ending_in_asm_branch_by_func_name;
std::unordered_map<std::string, std::vector<std::vector<int>>>
format_ops_with_dynamic_string_by_func_name;
std::unordered_set<std::string> mips2c_functions_by_name;
std::unordered_map<std::string, std::vector<int>> mips2c_jump_table_functions;
std::unordered_map<std::string, std::vector<std::pair<int, int>>> missing_textures_by_level;
};
struct ObjectPatchInfo {
u32 crc;
std::string target_file;
std::string patch_file;
};
2020-08-22 23:30:17 -04:00
struct Config {
GameVersion game_version = GameVersion::Jak1;
2020-08-22 23:30:17 -04:00
std::vector<std::string> dgo_names;
std::vector<std::string> object_file_names;
std::vector<std::string> str_file_names;
std::vector<std::string> str_texture_file_names;
std::vector<std::string> str_art_file_names;
std::vector<std::string> streamed_audio_file_names;
std::string obj_file_name_map_file;
std::string all_types_file;
2021-05-11 19:19:23 -04:00
bool disassemble_code = false;
bool decompile_code = false;
g/j1: Cleanup all main issues in the formatter and format all of `goal_src/jak1` (#3535) This PR does two main things: 1. Work through the main low-hanging fruit issues in the formatter keeping it from feeling mature and usable 2. Iterate and prove that point by formatting all of the Jak 1 code base. **This has removed around 100K lines in total.** - The decompiler will now format it's results for jak 1 to keep things from drifting back to where they were. This is controlled by a new config flag `format_code`. How am I confident this hasn't broken anything?: - I compiled the entire project and stored it's `out/jak1/obj` files separately - I then recompiled the project after formatting and wrote a script that md5's each file and compares it (`compare-compilation-outputs.py` - The results (eventually) were the same: ![Screenshot 2024-05-25 132900](https://github.com/open-goal/jak-project/assets/13153231/015e6f20-8d19-49b7-9951-97fa88ddc6c2) > This proves that the only difference before and after is non-critical whitespace for all code/macros that is actually in use. I'm still aware of improvements that could be made to the formatter, as well as general optimization of it's performance. But in general these are for rare or non-critical situations in my opinion and I'll work through them before doing Jak 2. The vast majority looks great and is working properly at this point. Those known issues are the following if you are curious: ![image](https://github.com/open-goal/jak-project/assets/13153231/0edfaba1-6d36-40f5-ab23-0642209867c4)
2024-06-05 22:17:31 -04:00
bool format_code = false;
2020-08-22 23:30:17 -04:00
bool write_scripts = false;
2021-05-11 19:19:23 -04:00
bool disassemble_data = false;
bool process_tpages = false;
bool write_tpage_imports = false;
bool process_game_text = false;
bool process_game_count = false;
bool process_art_groups = false;
bool process_subtitle_text = false;
bool process_subtitle_images = false;
bool dump_art_group_info = false;
bool dump_joint_geo_info = false;
bool dump_tex_info = false;
bool rip_levels = false;
bool extract_collision = false;
bool find_functions = false;
bool read_spools = false;
bool ignore_var_name_casts = false;
2021-05-11 19:19:23 -04:00
bool write_hex_near_instructions = false;
bool hexdump_code = false;
bool hexdump_data = false;
bool dump_objs = false;
bool print_cfgs = false;
2021-05-11 19:19:23 -04:00
bool generate_symbol_definition_map = false;
bool generate_all_types = false;
std::optional<std::string> old_all_types_file;
bool is_pal = false;
bool write_patches = false;
bool apply_patches = false;
std::string game_name;
std::string expected_elf_name;
GameTextVersion text_version = GameTextVersion::JAK1_V1;
std::unordered_set<std::string> allowed_objects;
std::unordered_set<std::string> banned_objects;
std::unordered_set<std::string> merged_objects;
std::unordered_map<std::string, std::unordered_map<int, std::vector<RegisterTypeCast>>>
register_type_casts_by_function_by_atomic_op_idx;
std::unordered_map<std::string, std::unordered_map<int, StackTypeCast>>
stack_type_casts_by_function_by_stack_offset;
std::unordered_map<std::string, std::unordered_map<int, std::string>>
anon_function_types_by_obj_by_id;
std::unordered_map<std::string, std::vector<std::string>> function_arg_names;
std::unordered_map<std::string, std::unordered_map<std::string, LocalVarOverride>>
function_var_overrides;
std::unordered_map<std::string, std::unordered_map<std::string, LabelConfigInfo>> label_types;
std::unordered_map<std::string, std::vector<StackStructureHint>>
stack_structure_hints_by_function;
std::unordered_map<std::string, ObjectPatchInfo> object_patches;
std::unordered_map<std::string, int> bad_format_strings;
std::unordered_set<std::string> animated_textures;
std::unordered_set<int> common_tpages;
std::vector<std::string> levels_to_extract;
bool levels_extract;
bool save_texture_pngs = false;
bool rip_streamed_audio = false;
DecompileHacks hacks;
std::unordered_map<std::string, std::string> art_group_type_remap;
std::unordered_map<std::string, std::unordered_map<std::string, std::string>>
art_group_file_override;
std::unordered_map<std::string, std::unordered_map<int, std::string>> art_group_info_dump;
std::unordered_map<std::string, std::unordered_map<int, std::string>> jg_info_dump;
std::unordered_map<u32, TexInfo> texture_info_dump;
std::unordered_map<std::string, std::string> joint_node_hacks;
decomp3: more engine stuff, detect non-virtual state inheritance (#3377) - `speech` - `ambient` - `water-h` - `vol-h` - `generic-obs` - `carry-h` - `pilot-h` - `board-h` - `gun-h` - `flut-h` - `indax-h` - `lightjak-h` - `darkjak-h` - `target-util` - `history` - `collide-reaction-target` - `logic-target` - `sidekick` - `projectile` - `voicebox` - `ragdoll-edit` - most of `ragdoll` (not added to gsrc yet) - `curves` - `find-nearest` - `lightjak-wings` - `target-handler` - `target-anim` - `target` - `target2` - `target-swim` - `target-lightjak` - `target-invisible` - `target-death` - `target-gun` - `gun-util` - `board-util` - `target-board` - `board-states` - `mech-h` - `vol` - `vent` - `viewer` - `gem-pool` - `collectables` - `crates` - `secrets-menu` Additionally: - Detection of non-virtual state inheritance - Added a config file that allows overriding the process stack size set by `stack-size-set!` calls - Fix for integer multiplication with `r0` - Fixed detection for the following macros: - `static-attack-info` - `defpart` and `defpartgroup` (probably still needs adjustments, uses Jak 2 implementation at the moment) - `sound-play` (Jak 3 seems to always call `sound-play-by-name` with a `sound-group` of 0, so the macro has been temporarily defaulted to use that) One somewhat significant change made here that should be noted is that the return type of `process::init-from-entity!` was changed to `object`. I've been thinking about this for a while, since it looks a bit nicer without the `(none)` at the end and I have recently encountered init methods that early return `0`.
2024-03-03 15:15:27 -05:00
std::unordered_map<std::string, int> process_stack_size_overrides;
std::unordered_map<std::string, std::vector<std::string>> import_deps_by_file;
bool rip_collision = false;
2020-08-22 23:30:17 -04:00
};
Config read_config_file(const fs::path& path_to_config_file,
const std::string& config_game_version,
const std::string& override_json = "{}");
void from_json(const nlohmann::json& j, TexInfo& info);
void to_json(nlohmann::json& j, const TexInfo& info);
} // namespace decompiler