Files
jak-project/decompiler/config.h
T
Jordan 76e4bcb8bc [decompiler] Extracting Sound Effects and Music (#4401)
This PR adds the ability to extract sound effects to .wav files for each
of the four games, and music to .wav files for Jak1 and Jak2.

Basically what I have done is create a "fake player" which works the
same as the player from Player.cpp except we just take the raw audio
samples that would be sent to cubeb and then write them to wave files.

I shamelessly stole @Hat-Kid's code for flavas, for parsing the sound
effect names and for finding where the sound banks start for Jak 1 lol.
2026-09-16 19:29:11 -04:00

207 lines
7.1 KiB
C++

#pragma once
#include <optional>
#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;
};
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;
};
struct Config {
GameVersion game_version = GameVersion::Jak1;
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;
bool disassemble_code = false;
bool dump_function_metadata = false;
bool decompile_code = false;
bool format_code = false;
bool write_scripts = false;
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 process_part_group_table = false;
bool dump_art_group_info = false;
bool dump_joint_geo_info = false;
bool dump_tex_info = false;
bool dump_part_group_table = false;
bool rip_levels = false;
bool extract_collision = false;
bool find_functions = false;
bool read_spools = false;
bool ignore_var_name_casts = false;
bool write_hex_near_instructions = false;
bool hexdump_code = false;
bool hexdump_data = false;
bool dump_objs = false;
bool print_cfgs = false;
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;
bool rip_music = 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;
std::unordered_map<std::string, int> process_stack_size_overrides;
std::unordered_map<u32, std::string> part_group_table;
std::unordered_map<std::string, std::vector<std::string>> import_deps_by_file;
bool rip_collision = false;
};
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