diff --git a/src/engine/fox_display.c b/src/engine/fox_display.c index 97d24fee..51efb9cd 100644 --- a/src/engine/fox_display.c +++ b/src/engine/fox_display.c @@ -1782,7 +1782,7 @@ void Display_Update(void) { #endif // @port: @event: Call DisplayPreUpdateEvent - EventSystem_CallEvent(DisplayPreUpdateEvent, NULL); + CALL_EVENT(DisplayPreUpdateEvent); Matrix_Push(&gGfxMatrix); if ((gCurrentLevel == LEVEL_AQUAS) && (gPlayer[0].state == PLAYERSTATE_ACTIVE)) { @@ -2016,5 +2016,5 @@ void Display_Update(void) { Matrix_Pop(&gGfxMatrix); // @port: @event: Call DisplayPostUpdateEvent - EventSystem_CallEvent(DisplayPostUpdateEvent, NULL); + CALL_EVENT(DisplayPostUpdateEvent); } diff --git a/src/engine/fox_game.c b/src/engine/fox_game.c index b9f14276..c8871eb7 100644 --- a/src/engine/fox_game.c +++ b/src/engine/fox_game.c @@ -348,7 +348,7 @@ void Game_Update(void) { u8 soundMode; // @port: @event: Call GamePreUpdateEvent - EventSystem_CallEvent(GamePreUpdateEvent, NULL); + CALL_EVENT(GamePreUpdateEvent); Game_SetGameState(); if (gGameStandby) { @@ -606,7 +606,7 @@ void Game_Update(void) { Audio_dummy_80016A50(); // @port: @event: Call GamePostUpdateEvent - EventSystem_CallEvent(GamePostUpdateEvent, NULL); + CALL_EVENT(GamePostUpdateEvent); } } diff --git a/src/engine/fox_hud.c b/src/engine/fox_hud.c index 3196171b..98fea7e4 100644 --- a/src/engine/fox_hud.c +++ b/src/engine/fox_hud.c @@ -2,6 +2,7 @@ #include "fox_hud.h" #include "prevent_bss_reordering.h" #include "port/interpolation/FrameInterpolation.h" +#include "port/hooks/Events.h" Vec3f D_801616A0; Vec3f D_801616B0; @@ -3612,27 +3613,40 @@ void HUD_VS_Radar(void) { } void HUD_SinglePlayer(void) { - if (gPlayState != PLAY_PAUSE) { - HUD_Radar(); + CALL_CANCELLABLE_EVENT(DrawRadarHUDEvent){ + if (gPlayState != PLAY_PAUSE) { + HUD_Radar(); + } } RCP_SetupDL_36(); if ((gLevelMode != LEVELMODE_TURRET) && (D_hud_80161708 != 0)) { - HUD_BoostGauge_Draw(246.0f, 28.0f); - HUD_BombCounter_Draw(250.0f, 38.0f); - } - - HUD_IncomingMsg(); - - if (D_hud_80161708 != 0) { - HUD_Shield_GoldRings_Score(24.0f, 30.0f); - if (gCurrentLevel != LEVEL_TRAINING) { - HUD_LivesCount2_Draw(248.0f, 11.0f, gLifeCount[gPlayerNum]); + CALL_CANCELLABLE_EVENT(DrawBoostGaugeHUDEvent) { + HUD_BoostGauge_Draw(246.0f, 28.0f); + } + CALL_CANCELLABLE_EVENT(DrawBombCounterHUDEvent) { + HUD_BombCounter_Draw(250.0f, 38.0f); } } - if (gCurrentLevel == LEVEL_TRAINING) { - Training_RingPassCount_Draw(); + CALL_CANCELLABLE_EVENT(DrawIncomingMsgHUDEvent) { + HUD_IncomingMsg(); + } + + if (D_hud_80161708 != 0) { + CALL_CANCELLABLE_EVENT(DrawGoldRingsHUDEvent) { + HUD_Shield_GoldRings_Score(24.0f, 30.0f); + } + CALL_CANCELLABLE_EVENT(DrawLivesCounterHUDEvent) { + if (gCurrentLevel != LEVEL_TRAINING) { + HUD_LivesCount2_Draw(248.0f, 11.0f, gLifeCount[gPlayerNum]); + } + } + } + CALL_CANCELLABLE_EVENT(DrawTrainingRingPassCountHUDEvent) { + if (gCurrentLevel == LEVEL_TRAINING) { + Training_RingPassCount_Draw(); + } } } diff --git a/src/port/hooks/impl/EventSystem.cpp b/src/port/hooks/impl/EventSystem.cpp index 71eaffb5..3418b6ef 100644 --- a/src/port/hooks/impl/EventSystem.cpp +++ b/src/port/hooks/impl/EventSystem.cpp @@ -4,8 +4,16 @@ EventSystem* EventSystem::Instance = new EventSystem(); +EventID EventSystem::RegisterEvent() { + return this->mInternalEventID++; +} + ListenerID EventSystem::RegisterListener(EventID id, EventCallback callback, EventPriority priority) { - auto& listeners = this->mEventListeners[(uint8_t)((id >> 16) & 0xFF)][(uint16_t)(id & 0xFFFF)]; + if(id == -1) { + throw std::runtime_error("Trying to register listener for unregistered event"); + } + + auto& listeners = this->mEventListeners[id]; if(std::find_if(listeners.begin(), listeners.end(), [callback](EventListener listener) { return listener.function == callback; @@ -24,23 +32,23 @@ ListenerID EventSystem::RegisterListener(EventID id, EventCallback callback, Eve } void EventSystem::UnregisterListener(EventID id, ListenerID listenerId) { - auto& listeners = this->mEventListeners[(uint8_t)((id >> 16) & 0xFF)][(uint16_t)(id & 0xFFFF)]; + auto& listeners = this->mEventListeners[id]; listeners.erase(listeners.begin() + listenerId); } void EventSystem::CallEvent(EventID id, IEvent* event) { - auto& listeners = this->mEventListeners[(uint8_t)((id >> 16) & 0xFF)][(uint16_t)(id & 0xFFFF)]; - - if (listeners.empty()) { - return; - } + auto& listeners = this->mEventListeners[id]; for (auto& listener : listeners) { listener.function(event); } } +extern "C" EventID EventSystem_RegisterEvent() { + return EventSystem::Instance->RegisterEvent(); +} + extern "C" size_t EventSystem_RegisterListener(EventID id, EventCallback callback, EventPriority priority) { return EventSystem::Instance->RegisterListener(id, callback, priority); } diff --git a/src/port/hooks/impl/EventSystem.h b/src/port/hooks/impl/EventSystem.h index 32a32a26..8bf65732 100644 --- a/src/port/hooks/impl/EventSystem.h +++ b/src/port/hooks/impl/EventSystem.h @@ -4,15 +4,9 @@ #include #include -typedef uint16_t EventID; -typedef uint16_t NamespaceID; +typedef uint32_t EventID; typedef uint32_t ListenerID; -typedef enum { - EVENT_TYPE_PRE, - EVENT_TYPE_POST -} EventType; - typedef enum { EVENT_PRIORITY_LOW, EVENT_PRIORITY_NORMAL, @@ -30,18 +24,21 @@ typedef struct { EventCallback function; } EventListener; -// Namespace ID Type -// 00000000XXXXXXXX 000000000000000 0 -#define EVENT_ID(namespace_, id_, type_) ((((uint32_t)(namespace_) & 0xFFFF) << 16) | (((uint32_t)(id_) & 0x7FFF) << 1) | ((uint32_t)(type_) & 0x1)) +#ifdef INIT_EVENT_IDS +#define DECLARE_EVENT(eventName) \ + uint32_t eventName##ID = -1; +#else +#define DECLARE_EVENT(eventName) \ + extern uint32_t eventName##ID; +#endif -#define INTERNAL_EVENT_ID(id, type) EVENT_ID(0, id, type) -#define DEFINE_EVENT(id, eventName, type, ...) \ +#define DEFINE_EVENT(eventName, ...) \ typedef struct { \ IEvent event; \ __VA_ARGS__ \ } eventName; \ \ - static uint32_t eventName##ID = INTERNAL_EVENT_ID(id, type); + DECLARE_EVENT(eventName) #define CALL_EVENT(eventType, ...) \ eventType eventType##_ = { {false}, __VA_ARGS__ }; \ @@ -52,6 +49,12 @@ typedef struct { EventSystem_CallEvent(eventType##ID, &eventType##_); \ if (!eventType##_.event.cancelled) +#define REGISTER_EVENT(eventType) \ + eventType##ID = EventSystem_RegisterEvent(); + +#define REGISTER_LISTENER(eventType, callback, priority) \ + EventSystem_RegisterListener(eventType##ID, callback, priority); + #ifdef __cplusplus #include #include @@ -60,13 +63,16 @@ typedef struct { class EventSystem { public: static EventSystem* Instance; + EventID RegisterEvent(); ListenerID RegisterListener(EventID id, EventCallback callback, EventPriority priority = EVENT_PRIORITY_NORMAL); void UnregisterListener(EventID ev, ListenerID id); void CallEvent(EventID id, IEvent* event); private: - std::unordered_map>> mEventListeners; + std::unordered_map> mEventListeners; + EventID mInternalEventID = 0; }; #else +extern EventID EventSystem_RegisterEvent(); extern ListenerID EventSystem_RegisterListener(EventID id, EventCallback callback, EventPriority priority); extern void EventSystem_UnregisterListener(EventID ev, ListenerID id); extern void EventSystem_CallEvent(EventID id, void* event); diff --git a/src/port/hooks/list/EngineEvent.h b/src/port/hooks/list/EngineEvent.h index a16ba6f4..dc3f72f5 100644 --- a/src/port/hooks/list/EngineEvent.h +++ b/src/port/hooks/list/EngineEvent.h @@ -2,8 +2,19 @@ #include "port/hooks/impl/EventSystem.h" -#define DisplayPreUpdateEvent INTERNAL_EVENT_ID(1, EVENT_TYPE_PRE) -#define DisplayPostUpdateEvent INTERNAL_EVENT_ID(1, EVENT_TYPE_POST) +DEFINE_EVENT(DisplayPreUpdateEvent); +DEFINE_EVENT(DisplayPostUpdateEvent); -#define GamePreUpdateEvent INTERNAL_EVENT_ID(2, EVENT_TYPE_PRE) -#define GamePostUpdateEvent INTERNAL_EVENT_ID(2, EVENT_TYPE_POST) \ No newline at end of file +DEFINE_EVENT(GamePreUpdateEvent); +DEFINE_EVENT(GamePostUpdateEvent); + +DEFINE_EVENT(DrawRadarHUDEvent); +DEFINE_EVENT(DrawBoostGaugeHUDEvent); +DEFINE_EVENT(DrawBombCounterHUDEvent); +DEFINE_EVENT(DrawIncomingMsgHUDEvent); +DEFINE_EVENT(DrawGoldRingsHUDEvent); +DEFINE_EVENT(DrawLivesCounterHUDEvent); +DEFINE_EVENT(DrawTrainingRingPassCountHUDEvent); + +DEFINE_EVENT(DrawGlobalHUDPreEvent); +DEFINE_EVENT(DrawGlobalHUDPostEvent); \ No newline at end of file diff --git a/src/port/hooks/list/ItemEvent.h b/src/port/hooks/list/ItemEvent.h index 70e89a14..bf9739ef 100644 --- a/src/port/hooks/list/ItemEvent.h +++ b/src/port/hooks/list/ItemEvent.h @@ -4,6 +4,6 @@ #include "sf64object.h" #include "port/hooks/impl/EventSystem.h" -DEFINE_EVENT(3, ItemDropEvent, EVENT_TYPE_PRE, +DEFINE_EVENT(ItemDropEvent, Item* item; ); \ No newline at end of file diff --git a/src/port/mods/PortEnhancements.c b/src/port/mods/PortEnhancements.c index 04f0f5e8..fad4a327 100644 --- a/src/port/mods/PortEnhancements.c +++ b/src/port/mods/PortEnhancements.c @@ -1,9 +1,11 @@ #include "PortEnhancements.h" -#include "port/hooks/Events.h" #include "global.h" #include "hit64.h" #include "mods.h" +#define INIT_EVENT_IDS +#include "port/hooks/Events.h" + void OnDisplayUpdatePre(IEvent* event) { #if DEBUG_BOSS_KILLER == 1 KillBoss(); @@ -157,8 +159,26 @@ void OnGameUpdatePost(IEvent* event) { void PortEnhancements_Init() { // Register event listeners - EventSystem_RegisterListener(DisplayPreUpdateEvent, OnDisplayUpdatePre, EVENT_PRIORITY_NORMAL); - EventSystem_RegisterListener(GamePostUpdateEvent, OnGameUpdatePost, EVENT_PRIORITY_NORMAL); + REGISTER_EVENT(DisplayPreUpdateEvent); + REGISTER_EVENT(DisplayPostUpdateEvent); + + REGISTER_EVENT(GamePreUpdateEvent); + REGISTER_EVENT(GamePostUpdateEvent); + + REGISTER_EVENT(DrawRadarHUDEvent); + REGISTER_EVENT(DrawBoostGaugeHUDEvent); + REGISTER_EVENT(DrawBombCounterHUDEvent); + REGISTER_EVENT(DrawIncomingMsgHUDEvent); + REGISTER_EVENT(DrawGoldRingsHUDEvent); + REGISTER_EVENT(DrawLivesCounterHUDEvent); + REGISTER_EVENT(DrawTrainingRingPassCountHUDEvent); + REGISTER_EVENT(DrawGlobalHUDPreEvent); + REGISTER_EVENT(DrawGlobalHUDPostEvent); + + REGISTER_EVENT(ItemDropEvent); + + REGISTER_LISTENER(DisplayPreUpdateEvent, OnDisplayUpdatePre, EVENT_PRIORITY_NORMAL); + REGISTER_LISTENER(GamePostUpdateEvent, OnGameUpdatePost, EVENT_PRIORITY_NORMAL); } void PortEnhancements_Exit() {