Add support for creating events in patches

This commit is contained in:
Mr-Wiseguy 2024-08-31 22:04:24 -04:00
parent 11c50bf349
commit 073bd0e4c2
4 changed files with 34 additions and 3 deletions

View file

@ -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<uint32_t, uint16_t>& 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();
}
};

View file

@ -1,5 +1,6 @@
#include <vector>
#include "librecomp/mods.hpp"
#include "librecomp/overlays.hpp"
#include "ultramodern/error_handling.hpp"
template<class... Ts>
@ -10,6 +11,11 @@ overloaded(Ts...) -> overloaded<Ts...>;
// Vector of callbacks for each registered event.
std::vector<std::vector<recomp::mods::GenericFunction>> 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()) {

View file

@ -320,6 +320,7 @@ size_t recomp::mods::ModContext::num_opened_mods() {
std::vector<recomp::mods::ModLoadErrorDetails> recomp::mods::ModContext::load_mods(uint8_t* rdram, int32_t load_address, uint32_t& ram_used) {
std::vector<recomp::mods::ModLoadErrorDetails> 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();
}

View file

@ -36,6 +36,7 @@ static std::unordered_map<uint32_t, uint16_t> code_sections_by_rom{};
static std::vector<LoadedSection> loaded_sections{};
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, size_t> 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<uint32_t, uint16_t>& recomp::overlays::get_vrom_to_section_map() {
return code_sections_by_rom;
}