From 745af556ca19868486eae95135f967e34a370585 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Fri, 27 Dec 2024 16:11:32 -0600 Subject: [PATCH] Hook system PoC --- src/engine/fox_beam.c | 6 ++++ src/port/Engine.cpp | 16 +++++----- src/port/hooks/Events.h | 3 ++ src/port/hooks/impl/EventSystem.cpp | 29 ++++++++++++++++++ src/port/hooks/impl/EventSystem.h | 44 +++++++++++++++++++++++++++ src/port/hooks/list/PlayerShotEvent.h | 10 ++++++ 6 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 src/port/hooks/Events.h create mode 100644 src/port/hooks/impl/EventSystem.cpp create mode 100644 src/port/hooks/impl/EventSystem.h create mode 100644 src/port/hooks/list/PlayerShotEvent.h diff --git a/src/engine/fox_beam.c b/src/engine/fox_beam.c index d6751bcc..4f1a9af0 100644 --- a/src/engine/fox_beam.c +++ b/src/engine/fox_beam.c @@ -1,9 +1,11 @@ +#include #include "global.h" #include "assets/ast_landmaster.h" #include "assets/ast_aquas.h" #include "assets/ast_great_fox.h" #include "assets/ast_versus.h" #include "port/interpolation/FrameInterpolation.h" +#include "port/hooks/Events.h" Vec3f sShotViewPos; @@ -661,6 +663,10 @@ void PlayerShot_ApplyDamageToActor(PlayerShot* shot, Actor* actor, s32 hitIndex) Vec3f sp44 = { 0.0f, 0.0f, -100.0f }; Vec3f sp38; + PlayerShotEvent* event = malloc(sizeof(PlayerShotEvent)); + EventSystem_CallEvent(EVENT_PLAYER_SHOT, event); + free(event); + actor->dmgType = DMG_BEAM; actor->dmgPart = hitIndex - 1; actor->timer_0C2 = 2; diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 27ff1065..2acdd9f9 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -37,20 +37,16 @@ #include #include "audio/GameAudio.h" #include "port/patches/DisplayListPatch.h" -// #include "sf64audio_provisional.h" + +#include "port/hooks/impl/EventSystem.h" +#include "port/hooks/Events.h" #include -#include #include -#include #include namespace fs = std::filesystem; -// extern "C" AudioBufferParameters gAudioBufferParams; - -#include - extern "C" { float gInterpolationStep = 0.0f; #include @@ -192,6 +188,12 @@ void GameEngine::Create() { #if defined(__SWITCH__) || defined(__WIIU__) CVarRegisterInteger("gControlNav", 1); // always enable controller nav on switch/wii u #endif + + EventSystem::Instance->RegisterListener(EVENT_PLAYER_SHOT, EVENT_PRIORITY_NORMAL, [](IEvent* event) { + auto pse = (PlayerShotEvent*) event; + SPDLOG_INFO("Player shot event fired for actor {}", pse->actorId); + }); + } void GameEngine::Destroy() { diff --git a/src/port/hooks/Events.h b/src/port/hooks/Events.h new file mode 100644 index 00000000..9c56592c --- /dev/null +++ b/src/port/hooks/Events.h @@ -0,0 +1,3 @@ +#pragma once + +#include "list/PlayerShotEvent.h" diff --git a/src/port/hooks/impl/EventSystem.cpp b/src/port/hooks/impl/EventSystem.cpp new file mode 100644 index 00000000..5aa74bc0 --- /dev/null +++ b/src/port/hooks/impl/EventSystem.cpp @@ -0,0 +1,29 @@ +#include "EventSystem.h" + +EventSystem* EventSystem::Instance = new EventSystem(); + +size_t EventSystem::RegisterListener(EventID id, EventPriority priority, EventCallback callback) { + if (std::find(this->mEventListeners[id].begin(), this->mEventListeners[id].end(), callback) != this->mEventListeners[id].end()) { + throw std::runtime_error("Listener already registered"); + } + + this->mEventListeners[id].push_back(callback); +} + +void EventSystem::CallEvent(EventID id, IEvent* event) { + if (this->mEventListeners[id].empty()) { + return; + } + + for (auto& callback : this->mEventListeners[id]) { + callback(event); + } +} + +extern "C" size_t EventSystem_RegisterListener(EventID id, EventPriority priority, EventCallback callback) { + return EventSystem::Instance->RegisterListener(id, priority, callback); +} + +extern "C" void EventSystem_CallEvent(EventID id, void* event) { + EventSystem::Instance->CallEvent(id, static_cast(event)); +} \ No newline at end of file diff --git a/src/port/hooks/impl/EventSystem.h b/src/port/hooks/impl/EventSystem.h new file mode 100644 index 00000000..3e6cf29b --- /dev/null +++ b/src/port/hooks/impl/EventSystem.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +typedef uint16_t EventID; + +typedef enum EventType { + EVENT_TYPE_PRE, + EVENT_TYPE_NORMAL, + EVENT_TYPE_POST, +} EventType; + +typedef enum EventPriority { + EVENT_PRIORITY_LOW, + EVENT_PRIORITY_NORMAL, + EVENT_PRIORITY_HIGH, +} EventPriority; + +typedef struct IEvent { + bool cancelled; +} IEvent; + +typedef void (*EventCallback)(IEvent*); + +// ID Type +// 00000000000000 00 +#define EVENT_ID(id, type) ((id << 2) | type) + +#ifdef __cplusplus +#include +#include + +class EventSystem { +public: + static EventSystem* Instance; + size_t RegisterListener(EventID id, EventPriority priority, EventCallback callback); + void CallEvent(EventID id, IEvent* event); +private: + std::array, 0xFFFF> mEventListeners; +}; +#else +extern size_t EventSystem_RegisterListener(EventID id, EventPriority priority, EventCallback callback); +extern void EventSystem_CallEvent(EventID id, void* event); +#endif \ No newline at end of file diff --git a/src/port/hooks/list/PlayerShotEvent.h b/src/port/hooks/list/PlayerShotEvent.h new file mode 100644 index 00000000..8a495861 --- /dev/null +++ b/src/port/hooks/list/PlayerShotEvent.h @@ -0,0 +1,10 @@ +#pragma once + +#include "port/hooks/impl/EventSystem.h" + +typedef struct { + IEvent event; + int actorId; +} PlayerShotEvent; + +#define EVENT_PLAYER_SHOT EVENT_ID(1, EVENT_TYPE_NORMAL) \ No newline at end of file