Files
psopeeps-newserv/src/FunctionCompiler.hh
T
2025-05-26 14:11:38 -07:00

98 lines
3.3 KiB
C++

#pragma once
#include <inttypes.h>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "Menu.hh"
// TODO: Support x86 and SH4 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 {
UNKNOWN = 0,
POWERPC, // GC
X86, // PC, XB, BB
SH4, // Dreamcast
};
Architecture arch;
std::string code;
std::vector<uint16_t> relocation_deltas;
std::unordered_map<std::string, uint32_t> label_offsets;
uint32_t entrypoint_offset_offset;
std::string source_path; // Path to source file from newserv root
std::string short_name; // Based on filename
std::string long_name; // From .meta name directive
std::string description; // From .meta description directive
uint8_t index; // 0 = unused (not registered in index_to_function)
uint32_t menu_item_id;
bool hide_from_patches_menu;
uint32_t specific_version;
bool is_big_endian() const;
template <bool BE>
std::string generate_client_command_t(
const std::unordered_map<std::string, uint32_t>& label_writes,
const void* suffix_data = nullptr,
size_t suffix_size = 0,
uint32_t override_relocations_offset = 0) const;
std::string generate_client_command(
const std::unordered_map<std::string, uint32_t>& label_writes = {},
const void* suffix_data = nullptr,
size_t suffix_size = 0,
uint32_t override_relocations_offset = 0) const;
};
const char* name_for_architecture(CompiledFunctionCode::Architecture arch);
std::shared_ptr<CompiledFunctionCode> 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<std::string, std::shared_ptr<CompiledFunctionCode>> name_to_function;
std::unordered_map<uint8_t, std::shared_ptr<CompiledFunctionCode>> index_to_function;
std::unordered_map<uint64_t, std::shared_ptr<CompiledFunctionCode>> menu_item_id_and_specific_version_to_patch_function;
// Key here is e.g. "PATCHNAME-SPECIFICVERSION", with the latter in hex
std::map<std::string, std::shared_ptr<CompiledFunctionCode>> name_and_specific_version_to_patch_function;
std::shared_ptr<const Menu> patch_switches_menu(uint32_t specific_version, const std::unordered_set<std::string>& auto_patches_enabled) const;
bool patch_menu_empty(uint32_t specific_version) const;
std::shared_ptr<const CompiledFunctionCode> get_patch(const std::string& name, uint32_t specific_version) const;
};
struct DOLFileIndex {
struct File {
uint32_t menu_item_id;
std::string name;
std::string data;
bool is_compressed;
};
std::vector<std::shared_ptr<File>> item_id_to_file;
std::unordered_map<std::string, std::shared_ptr<File>> name_to_file;
std::shared_ptr<const Menu> menu;
DOLFileIndex() = default;
explicit DOLFileIndex(const std::string& directory);
inline bool empty() const {
return this->name_to_file.empty() && this->item_id_to_file.empty();
}
};
uint32_t specific_version_for_gc_header_checksum(uint32_t header_checksum);