mirror of
https://github.com/N64Recomp/N64ModernRuntime.git
synced 2025-10-30 08:02:29 +00:00
Implement extended function exports that pass the caller mod's index as an extra argument
This commit is contained in:
parent
e814ad6f83
commit
e6d1ed5dd6
5 changed files with 30 additions and 4 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8781eb44acbf55cb6a109d2aa5529aadb95a419d
|
Subproject commit 2af6f2d161f755ca68f8baeb4dc5b69ef58a862c
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
namespace N64Recomp {
|
namespace N64Recomp {
|
||||||
class Context;
|
class Context;
|
||||||
struct LiveGeneratorOutput;
|
struct LiveGeneratorOutput;
|
||||||
|
class ShimFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace recomp {
|
namespace recomp {
|
||||||
|
|
@ -348,7 +349,7 @@ namespace recomp {
|
||||||
void check_dependencies(ModHandle& mod, std::vector<std::pair<ModLoadError, std::string>>& errors);
|
void check_dependencies(ModHandle& mod, std::vector<std::pair<ModLoadError, std::string>>& errors);
|
||||||
CodeModLoadError init_mod_code(uint8_t* rdram, const std::unordered_map<uint32_t, uint16_t>& section_vrom_map, ModHandle& mod, int32_t load_address, bool hooks_available, uint32_t& ram_used, std::string& error_param);
|
CodeModLoadError init_mod_code(uint8_t* rdram, const std::unordered_map<uint32_t, uint16_t>& section_vrom_map, ModHandle& mod, int32_t load_address, bool hooks_available, uint32_t& ram_used, std::string& error_param);
|
||||||
CodeModLoadError load_mod_code(uint8_t* rdram, ModHandle& mod, uint32_t base_event_index, std::string& error_param);
|
CodeModLoadError load_mod_code(uint8_t* rdram, ModHandle& mod, uint32_t base_event_index, std::string& error_param);
|
||||||
CodeModLoadError resolve_code_dependencies(ModHandle& mod, const std::unordered_map<recomp_func_t*, recomp::overlays::BasePatchedFunction>& base_patched_funcs, std::string& error_param);
|
CodeModLoadError resolve_code_dependencies(ModHandle& mod, size_t mod_index, const std::unordered_map<recomp_func_t*, recomp::overlays::BasePatchedFunction>& base_patched_funcs, std::string& error_param);
|
||||||
void add_opened_mod(ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& detected_content_types, std::vector<char>&& thumbnail);
|
void add_opened_mod(ModManifest&& manifest, ConfigStorage&& config_storage, std::vector<size_t>&& game_indices, std::vector<ModContentTypeId>&& detected_content_types, std::vector<char>&& thumbnail);
|
||||||
void close_mods();
|
void close_mods();
|
||||||
std::vector<ModLoadErrorDetails> regenerate_with_hooks(
|
std::vector<ModLoadErrorDetails> regenerate_with_hooks(
|
||||||
|
|
@ -388,6 +389,8 @@ namespace recomp {
|
||||||
// Tracks which hook slots have already been processed. Used to regenerate vanilla functions as needed
|
// Tracks which hook slots have already been processed. Used to regenerate vanilla functions as needed
|
||||||
// to add hooks to any functions that weren't already replaced by a mod.
|
// to add hooks to any functions that weren't already replaced by a mod.
|
||||||
std::vector<bool> processed_hook_slots;
|
std::vector<bool> processed_hook_slots;
|
||||||
|
// Generated shim functions to use for implementing shim exports.
|
||||||
|
std::vector<std::unique_ptr<N64Recomp::ShimFunction>> shim_functions;
|
||||||
ConfigSchema empty_schema;
|
ConfigSchema empty_schema;
|
||||||
std::vector<char> empty_bytes;
|
std::vector<char> empty_bytes;
|
||||||
size_t num_events = 0;
|
size_t num_events = 0;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ namespace recomp {
|
||||||
|
|
||||||
void register_patches(const char* patch_data, size_t patch_size, SectionTableEntry* code_sections, size_t num_sections);
|
void register_patches(const char* patch_data, size_t patch_size, SectionTableEntry* code_sections, size_t num_sections);
|
||||||
void register_base_export(const std::string& name, recomp_func_t* func);
|
void register_base_export(const std::string& name, recomp_func_t* func);
|
||||||
|
void register_ext_base_export(const std::string& name, recomp_func_ext_t* func);
|
||||||
void register_base_exports(const FunctionExport* exports);
|
void register_base_exports(const FunctionExport* exports);
|
||||||
void register_base_events(char const* const* event_names);
|
void register_base_events(char const* const* event_names);
|
||||||
void register_manual_patch_symbols(const ManualPatchSymbol* manual_patch_symbols);
|
void register_manual_patch_symbols(const ManualPatchSymbol* manual_patch_symbols);
|
||||||
|
|
@ -38,6 +39,7 @@ namespace recomp {
|
||||||
bool get_func_entry_by_section_index_function_offset(uint16_t code_section_index, uint32_t function_offset, FuncEntry& func_out);
|
bool get_func_entry_by_section_index_function_offset(uint16_t code_section_index, uint32_t function_offset, FuncEntry& func_out);
|
||||||
recomp_func_t* get_func_by_section_index_function_offset(uint16_t code_section_index, uint32_t function_offset);
|
recomp_func_t* get_func_by_section_index_function_offset(uint16_t code_section_index, uint32_t function_offset);
|
||||||
recomp_func_t* get_base_export(const std::string& export_name);
|
recomp_func_t* get_base_export(const std::string& export_name);
|
||||||
|
recomp_func_ext_t* get_ext_base_export(const std::string& export_name);
|
||||||
size_t get_base_event_index(const std::string& event_name);
|
size_t get_base_event_index(const std::string& event_name);
|
||||||
size_t num_base_events();
|
size_t num_base_events();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1520,7 +1520,7 @@ std::vector<recomp::mods::ModLoadErrorDetails> recomp::mods::ModContext::load_mo
|
||||||
for (size_t mod_index : loaded_code_mods) {
|
for (size_t mod_index : loaded_code_mods) {
|
||||||
auto& mod = opened_mods[mod_index];
|
auto& mod = opened_mods[mod_index];
|
||||||
std::string cur_error_param;
|
std::string cur_error_param;
|
||||||
CodeModLoadError cur_error = resolve_code_dependencies(mod, base_patched_funcs, cur_error_param);
|
CodeModLoadError cur_error = resolve_code_dependencies(mod, mod_index, base_patched_funcs, cur_error_param);
|
||||||
if (cur_error != CodeModLoadError::Good) {
|
if (cur_error != CodeModLoadError::Good) {
|
||||||
if (cur_error_param.empty()) {
|
if (cur_error_param.empty()) {
|
||||||
ret.emplace_back(mod.manifest.mod_id, ModLoadError::FailedToLoadCode, error_to_string(cur_error));
|
ret.emplace_back(mod.manifest.mod_id, ModLoadError::FailedToLoadCode, error_to_string(cur_error));
|
||||||
|
|
@ -2172,7 +2172,7 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::load_mod_code(uint8_t*
|
||||||
return CodeModLoadError::Good;
|
return CodeModLoadError::Good;
|
||||||
}
|
}
|
||||||
|
|
||||||
recomp::mods::CodeModLoadError recomp::mods::ModContext::resolve_code_dependencies(recomp::mods::ModHandle& mod, const std::unordered_map<recomp_func_t*, overlays::BasePatchedFunction>& base_patched_funcs, std::string& error_param) {
|
recomp::mods::CodeModLoadError recomp::mods::ModContext::resolve_code_dependencies(recomp::mods::ModHandle& mod, size_t mod_index, const std::unordered_map<recomp_func_t*, overlays::BasePatchedFunction>& base_patched_funcs, std::string& error_param) {
|
||||||
// Reference symbols.
|
// Reference symbols.
|
||||||
std::string reference_syms_error_param{};
|
std::string reference_syms_error_param{};
|
||||||
CodeModLoadError reference_syms_error = mod.code_handle->populate_reference_symbols(*mod.recompiler_context, reference_syms_error_param);
|
CodeModLoadError reference_syms_error = mod.code_handle->populate_reference_symbols(*mod.recompiler_context, reference_syms_error_param);
|
||||||
|
|
@ -2201,6 +2201,13 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::resolve_code_dependenci
|
||||||
if (dependency_id == N64Recomp::DependencyBaseRecomp) {
|
if (dependency_id == N64Recomp::DependencyBaseRecomp) {
|
||||||
recomp_func_t* func_ptr = recomp::overlays::get_base_export(imported_func.base.name);
|
recomp_func_t* func_ptr = recomp::overlays::get_base_export(imported_func.base.name);
|
||||||
did_find_func = func_ptr != nullptr;
|
did_find_func = func_ptr != nullptr;
|
||||||
|
if (!did_find_func) {
|
||||||
|
recomp_func_ext_t* func_ext_ptr = recomp::overlays::get_ext_base_export(imported_func.base.name);
|
||||||
|
did_find_func = func_ext_ptr != nullptr;
|
||||||
|
if (did_find_func) {
|
||||||
|
func_ptr = shim_functions.emplace_back(std::make_unique<N64Recomp::ShimFunction>(func_ext_ptr, mod_index)).get()->get_func();
|
||||||
|
}
|
||||||
|
}
|
||||||
func_handle = func_ptr;
|
func_handle = func_ptr;
|
||||||
}
|
}
|
||||||
else if (dependency_id == N64Recomp::DependencySelf) {
|
else if (dependency_id == N64Recomp::DependencySelf) {
|
||||||
|
|
@ -2343,6 +2350,7 @@ void recomp::mods::ModContext::unload_mods() {
|
||||||
loaded_mods_by_id.clear();
|
loaded_mods_by_id.clear();
|
||||||
hook_slots.clear();
|
hook_slots.clear();
|
||||||
processed_hook_slots.clear();
|
processed_hook_slots.clear();
|
||||||
|
shim_functions.clear();
|
||||||
recomp::mods::reset_events();
|
recomp::mods::reset_events();
|
||||||
recomp::mods::reset_hooks();
|
recomp::mods::reset_hooks();
|
||||||
num_events = recomp::overlays::num_base_events();
|
num_events = recomp::overlays::num_base_events();
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ static std::unordered_map<uint32_t, uint16_t> patch_code_sections_by_rom{};
|
||||||
static std::vector<LoadedSection> loaded_sections{};
|
static std::vector<LoadedSection> loaded_sections{};
|
||||||
static std::unordered_map<int32_t, recomp_func_t*> func_map{};
|
static std::unordered_map<int32_t, recomp_func_t*> func_map{};
|
||||||
static std::unordered_map<std::string, recomp_func_t*> base_exports{};
|
static std::unordered_map<std::string, recomp_func_t*> base_exports{};
|
||||||
|
static std::unordered_map<std::string, recomp_func_ext_t*> ext_base_exports{};
|
||||||
static std::unordered_map<std::string, size_t> base_events;
|
static std::unordered_map<std::string, size_t> base_events;
|
||||||
static std::unordered_map<uint32_t, recomp_func_t*> manual_patch_symbols_by_vram;
|
static std::unordered_map<uint32_t, recomp_func_t*> manual_patch_symbols_by_vram;
|
||||||
|
|
||||||
|
|
@ -67,6 +68,10 @@ void recomp::overlays::register_base_export(const std::string& name, recomp_func
|
||||||
base_exports.emplace(name, func);
|
base_exports.emplace(name, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void recomp::overlays::register_ext_base_export(const std::string& name, recomp_func_ext_t* func) {
|
||||||
|
ext_base_exports.emplace(name, func);
|
||||||
|
}
|
||||||
|
|
||||||
void recomp::overlays::register_base_exports(const FunctionExport* export_list) {
|
void recomp::overlays::register_base_exports(const FunctionExport* export_list) {
|
||||||
std::unordered_map<uint32_t, recomp_func_t*> patch_func_vram_map{};
|
std::unordered_map<uint32_t, recomp_func_t*> patch_func_vram_map{};
|
||||||
|
|
||||||
|
|
@ -98,6 +103,14 @@ recomp_func_t* recomp::overlays::get_base_export(const std::string& export_name)
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recomp_func_ext_t* recomp::overlays::get_ext_base_export(const std::string& export_name) {
|
||||||
|
auto it = ext_base_exports.find(export_name);
|
||||||
|
if (it == ext_base_exports.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
void recomp::overlays::register_base_events(char const* const* event_names) {
|
void recomp::overlays::register_base_events(char const* const* event_names) {
|
||||||
for (size_t event_index = 0; event_names[event_index] != nullptr; event_index++) {
|
for (size_t event_index = 0; event_names[event_index] != nullptr; event_index++) {
|
||||||
base_events.emplace(event_names[event_index], event_index);
|
base_events.emplace(event_names[event_index], event_index);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue