diff --git a/librecomp/include/librecomp/overlays.hpp b/librecomp/include/librecomp/overlays.hpp index e08e4d5..8defccc 100644 --- a/librecomp/include/librecomp/overlays.hpp +++ b/librecomp/include/librecomp/overlays.hpp @@ -24,12 +24,15 @@ namespace recomp { void register_patches(const char* patch_data, size_t patch_size, SectionTableEntry* code_sections, size_t num_sections); void register_base_exports(const FunctionExport* exports); + void register_base_events(char const* const* event_names); void read_patch_data(uint8_t* rdram, gpr patch_data_address); void init_overlays(); const std::unordered_map& get_vrom_to_section_map(); recomp_func_t* get_func_by_section_ram(uint32_t section_rom, uint32_t function_vram); recomp_func_t* get_base_export(const std::string& export_name); + size_t get_base_event_index(const std::string& event_name); + size_t num_base_events(); } }; diff --git a/librecomp/src/mod_events.cpp b/librecomp/src/mod_events.cpp index 67ed418..538dad4 100644 --- a/librecomp/src/mod_events.cpp +++ b/librecomp/src/mod_events.cpp @@ -1,5 +1,6 @@ #include #include "librecomp/mods.hpp" +#include "librecomp/overlays.hpp" #include "ultramodern/error_handling.hpp" template @@ -10,6 +11,11 @@ overloaded(Ts...) -> overloaded; // Vector of callbacks for each registered event. std::vector> event_callbacks{}; +extern "C" { + // This can stay at 0 since the base events are always first in the list. + uint32_t builtin_base_event_index = 0; +} + extern "C" void recomp_trigger_event(uint8_t* rdram, recomp_context* ctx, uint32_t event_index) { // Sanity check the event index. if (event_index >= event_callbacks.size()) { diff --git a/librecomp/src/mods.cpp b/librecomp/src/mods.cpp index 6692d68..d117e4c 100644 --- a/librecomp/src/mods.cpp +++ b/librecomp/src/mods.cpp @@ -320,6 +320,7 @@ size_t recomp::mods::ModContext::num_opened_mods() { std::vector recomp::mods::ModContext::load_mods(uint8_t* rdram, int32_t load_address, uint32_t& ram_used) { std::vector ret{}; ram_used = 0; + num_events = recomp::overlays::num_base_events(); if (!patched_funcs.empty()) { printf("Mods already loaded!\n"); @@ -564,8 +565,10 @@ recomp::mods::ModLoadError recomp::mods::ModContext::resolve_dependencies(recomp bool did_find_event = false; if (dependency.mod_id == N64Recomp::DependencyBaseRecomp) { - error_param = "Base recomp events not supported yet"; - return ModLoadError::InvalidCallbackEvent; + event_index = recomp::overlays::get_base_event_index(dependency_event.event_name); + if (event_index != (size_t)-1) { + did_find_event = true; + } } else if (dependency.mod_id == N64Recomp::DependencySelf) { did_find_event = mod.get_global_event_index(dependency_event.event_name, event_index); @@ -637,5 +640,5 @@ void recomp::mods::ModContext::unload_mods() { patched_funcs.clear(); loaded_mods_by_id.clear(); recomp::mods::reset_events(); - num_events = 0; + num_events = recomp::overlays::num_base_events(); } diff --git a/librecomp/src/overlays.cpp b/librecomp/src/overlays.cpp index 9e606ef..b0d15ec 100644 --- a/librecomp/src/overlays.cpp +++ b/librecomp/src/overlays.cpp @@ -36,6 +36,7 @@ static std::unordered_map code_sections_by_rom{}; static std::vector loaded_sections{}; static std::unordered_map func_map{}; static std::unordered_map base_exports{}; +static std::unordered_map base_events; extern "C" { int32_t* section_addresses = nullptr; @@ -85,6 +86,24 @@ recomp_func_t* recomp::overlays::get_base_export(const std::string& export_name) return it->second; } +void recomp::overlays::register_base_events(char const* const* event_names) { + for (size_t event_index = 0; event_names[event_index] != nullptr; event_index++) { + base_events.emplace(event_names[event_index], event_index); + } +} + +size_t recomp::overlays::get_base_event_index(const std::string& event_name) { + auto it = base_events.find(event_name); + if (it == base_events.end()) { + return (size_t)-1; + } + return it->second; +} + +size_t recomp::overlays::num_base_events() { + return base_events.size(); +} + const std::unordered_map& recomp::overlays::get_vrom_to_section_map() { return code_sections_by_rom; }