#pragma once #include #include #include #include #include #include #include "Menu.hh" bool function_compiler_available(); // TODO: Support x86 function calls in the future. Currently we only support // PPC32 because I haven't written an appropriate x86 assembler yet. struct CompiledFunctionCode { enum class Architecture { POWERPC = 0, X86, }; Architecture arch; std::string code; std::vector relocation_deltas; std::unordered_map label_offsets; uint32_t entrypoint_offset_offset; std::string name; uint32_t index; // 0 = unused (not registered in index_to_function) uint32_t menu_item_id; bool is_big_endian() const; template std::string generate_client_command_t( const std::unordered_map& label_writes, const std::string& suffix) const; std::string generate_client_command( const std::unordered_map& label_writes = {}, const std::string& suffix = "") const; }; const char* name_for_architecture(CompiledFunctionCode::Architecture arch); std::shared_ptr compile_function_code( CompiledFunctionCode::Architecture arch, const std::string& directory, const std::string& name, const std::string& text); struct FunctionCodeIndex { FunctionCodeIndex() = default; explicit FunctionCodeIndex(const std::string& directory); std::unordered_map> name_to_function; std::unordered_map> index_to_function; std::unordered_map> menu_item_id_to_patch_function; std::map> name_to_patch_function; std::vector patch_menu() const; inline bool patch_menu_empty() const { return this->name_to_patch_function.empty(); } }; struct DOLFileIndex { struct DOLFile { uint32_t menu_item_id; std::string name; std::string data; }; std::vector> item_id_to_file; std::map> name_to_file; DOLFileIndex() = default; explicit DOLFileIndex(const std::string& directory); std::vector menu() const; inline bool empty() const { return this->name_to_file.empty() && this->item_id_to_file.empty(); } };