diff --git a/codxe.vcxproj b/codxe.vcxproj index b0c7e4e..1010ddd 100644 --- a/codxe.vcxproj +++ b/codxe.vcxproj @@ -90,6 +90,7 @@ + diff --git a/src/game/iw3/mp/components/cg.cpp b/src/game/iw3/mp/components/cg.cpp index 41cd697..9a292a7 100644 --- a/src/game/iw3/mp/components/cg.cpp +++ b/src/game/iw3/mp/components/cg.cpp @@ -108,14 +108,6 @@ void Menus_OpenByName_Hook(UiContext *dc, const char *menuName) Menus_OpenByName_Detour.GetOriginal()(dc, menuName); } -Detour CG_Init_Detour; - -void CG_Init_Hook(int localClientNum, int serverMessageNum, int serverCommandSequence, int clientNum) -{ - CG_Init_Detour.GetOriginal()(localClientNum, serverMessageNum, serverCommandSequence, clientNum); - cj_tas::On_CG_Init(); -} - cg::cg() { Menus_OpenByName_Detour = Detour(Menus_OpenByName, Menus_OpenByName_Hook); @@ -143,9 +135,6 @@ cg::cg() UI_SafeTranslateString_Detour = Detour(UI_SafeTranslateString, UI_SafeTranslateString_Hook); UI_SafeTranslateString_Detour.Install(); - CG_Init_Detour = Detour(CG_Init, CG_Init_Hook); - CG_Init_Detour.Install(); - cg_scoreboardLabel_Score = Dvar_RegisterString("cg_scoreboardLabel_Score", "", DVAR_FLAG_NONE, "Override label for 'Score' column on scoreboard"); @@ -166,7 +155,6 @@ cg::~cg() UI_SafeTranslateString_Detour.Remove(); BG_CalculateWeaponPosition_IdleAngles_Detour.Remove(); BG_CalculateView_IdleAngles_Detour.Remove(); - CG_Init_Detour.Remove(); } } // namespace mp } // namespace iw3 diff --git a/src/game/iw3/mp/components/cj_tas.cpp b/src/game/iw3/mp/components/cj_tas.cpp index f002125..e754597 100644 --- a/src/game/iw3/mp/components/cj_tas.cpp +++ b/src/game/iw3/mp/components/cj_tas.cpp @@ -1,4 +1,5 @@ #include "pch.h" +#include "events.h" #include "cj_tas.h" #define ANGLE2SHORT(x) ((int)((x) * 65536 / 360) & 65535) @@ -35,12 +36,6 @@ dvar_s *cj_tas_playback_ignore_weapon = nullptr; unsigned int rpg_mp_index = 0; -void cj_tas::On_CG_Init() -{ - // Weapon indexes change every game - rpg_mp_index = BG_FindWeaponIndexForName("rpg_mp"); -} - void Cmd_Startrecord_f() { if (is_recording) @@ -372,6 +367,15 @@ void CL_CreateNewCommands_Hook(int localClientNum) } } +const float colorWhiteRGBA[4] = {1.0f, 1.0f, 1.0f, 1.0f}; +void CG_DrawTAS() +{ + static Font_s *bigDevFont = R_RegisterFont("fonts/bigDevFont"); + const float x = 10.f * scrPlaceFullUnsafe.scaleVirtualToFull[0]; + const float y = 30.f; + R_AddCmdDrawText("TAS", 5, bigDevFont, x, y, 1.0, 1.0, 0.0, colorWhiteRGBA, 0); +} + cj_tas::cj_tas() { CL_CreateNewCommands_Detour = Detour(CL_CreateNewCommands, CL_CreateNewCommands_Hook); @@ -399,6 +403,22 @@ cj_tas::cj_tas() cj_tas_rpg_lookdown_yaw = Dvar_RegisterInt("cj_tas_rpg_lookdown_yaw", 0, -180, 180, 0, "RPG lookdown yaw angle"); cj_tas_rpg_lookdown_pitch = Dvar_RegisterInt("cj_tas_rpg_lookdown_pitch", 70, -70, 70, 0, "RPG lookdown pitch angle"); + + Events::OnCG_DrawActive( + []() + { + if (cj_tas::TAS_Enabled()) + { + CG_DrawTAS(); + } + }); + + Events::OnCG_Init( + []() + { + // Weapon indexes change every game + rpg_mp_index = BG_FindWeaponIndexForName("rpg_mp"); + }); } cj_tas::~cj_tas() diff --git a/src/game/iw3/mp/components/clipmap.cpp b/src/game/iw3/mp/components/clipmap.cpp index 041f226..d6d1787 100644 --- a/src/game/iw3/mp/components/clipmap.cpp +++ b/src/game/iw3/mp/components/clipmap.cpp @@ -1,4 +1,5 @@ #include "pch.h" +#include "events.h" #include "clipmap.h" namespace iw3 @@ -123,6 +124,8 @@ clipmap::clipmap() CM_LoadMap_Detour = Detour(CM_LoadMap, CM_LoadMap_Hook); CM_LoadMap_Detour.Install(); + + Events::OnCG_DrawActive(clipmap::HandleBrushCollisionChange); } clipmap::~clipmap() diff --git a/src/game/iw3/mp/components/events.cpp b/src/game/iw3/mp/components/events.cpp new file mode 100644 index 0000000..104bbbf --- /dev/null +++ b/src/game/iw3/mp/components/events.cpp @@ -0,0 +1,65 @@ +#include "pch.h" +#include "events.h" + +namespace iw3 +{ +namespace mp +{ + +std::vector> Events::cg_drawactive_callbacks; + +void Events::CG_DrawActive_Hook(int localClientNum) +{ + // Call original function first + CG_DrawActive_Detour.GetOriginal()(localClientNum); + + for (auto it = cg_drawactive_callbacks.begin(); it != cg_drawactive_callbacks.end(); ++it) + { + (*it)(); + } +} + +void Events::OnCG_DrawActive(const std::function &callback) +{ + cg_drawactive_callbacks.emplace_back(callback); +} + +Detour Events::CG_DrawActive_Detour; + +std::vector> Events::cg_init_callbacks; + +void Events::CG_Init_Hook(int localClientNum, int serverMessageNum, int serverCommandSequence, int clientNum) +{ + // Call original function first + CG_Init_Detour.GetOriginal()(localClientNum, serverMessageNum, serverCommandSequence, clientNum); + + for (auto it = cg_init_callbacks.begin(); it != cg_init_callbacks.end(); ++it) + { + (*it)(); + } +} + +void Events::OnCG_Init(const std::function &callback) +{ + cg_init_callbacks.emplace_back(callback); +} + +Detour Events::CG_Init_Detour; + +Events::Events() +{ + CG_DrawActive_Detour = Detour(CG_DrawActive, CG_DrawActive_Hook); + CG_DrawActive_Detour.Install(); + + CG_Init_Detour = Detour(CG_Init, CG_Init_Hook); + CG_Init_Detour.Install(); +} + +Events::~Events() +{ + CG_DrawActive_Detour.Remove(); + CG_Init_Detour.Remove(); +} + +} // namespace mp +} // namespace iw3 diff --git a/src/game/iw3/mp/components/events.h b/src/game/iw3/mp/components/events.h new file mode 100644 index 0000000..9cafd90 --- /dev/null +++ b/src/game/iw3/mp/components/events.h @@ -0,0 +1,34 @@ +#pragma once + +#include "pch.h" + +namespace iw3 +{ +namespace mp +{ + +class Events : public Module +{ + public: + Events(); + ~Events(); + + const char *get_name() override + { + return "Events"; + }; + + static void OnCG_DrawActive(const std::function &callback); + static void OnCG_Init(const std::function &callback); + + private: + static std::vector> cg_drawactive_callbacks; + static Detour CG_DrawActive_Detour; + static void CG_DrawActive_Hook(int localClientNum); + + static std::vector> cg_init_callbacks; + static Detour CG_Init_Detour; + static void CG_Init_Hook(int localClientNum, int serverMessageNum, int serverCommandSequence, int clientNum); +}; +} // namespace mp +} // namespace iw3 \ No newline at end of file diff --git a/src/game/iw3/mp/main.cpp b/src/game/iw3/mp/main.cpp index e0d05ba..e07aa5b 100644 --- a/src/game/iw3/mp/main.cpp +++ b/src/game/iw3/mp/main.cpp @@ -1,9 +1,9 @@ #include "pch.h" -#include "main.h" #include "components/cg.h" #include "components/cj_tas.h" #include "components/clipmap.h" #include "components/cmds.h" +#include "components/events.h" #include "components/g_scr_main.h" #include "components/gsc_client_fields.h" #include "components/gsc_functions.h" @@ -14,6 +14,7 @@ #include "components/scr_parser.h" #include "components/sv_bots.h" #include "common/config.h" +#include "main.h" // Structure to hold data for the active keyboard request struct KeyboardRequest @@ -279,14 +280,6 @@ void DrawFixedFPS() R_AddCmdDrawText(buff, 16, font, x, y, 1.0, 1.0, 0.0, colorWhiteRGBA, 0); } -void CG_DrawTAS() -{ - static Font_s *bigDevFont = R_RegisterFont("fonts/bigDevFont"); - const float x = 10.f * scrPlaceFullUnsafe.scaleVirtualToFull[0]; - const float y = 30.f; - R_AddCmdDrawText("TAS", 5, bigDevFont, x, y, 1.0, 1.0, 0.0, colorWhiteRGBA, 0); -} - dvar_s *cg_draw_player_info = nullptr; void CG_DrawPlayerInfo() @@ -311,34 +304,6 @@ void CG_DrawPlayerInfo() R_AddCmdDrawText(buff, 256, consoleFont, x, y, 1.0, 1.0, 0.0, colorWhiteRGBA, 0); } -Detour CG_DrawActive_Detour; - -void CG_DrawActive_Hook(int localClientNum) -{ - static dvar_s *pm_fixed_fps_enable = Dvar_FindMalleableVar("pm_fixed_fps_enable"); - - CheckKeyboardCompletion(); - - if (pm_fixed_fps_enable->current.enabled) - { - DrawFixedFPS(); - } - - if (cj_tas::TAS_Enabled()) - { - CG_DrawTAS(); - } - - if (cg_draw_player_info->current.enabled) - { - CG_DrawPlayerInfo(); - } - - clipmap::HandleBrushCollisionChange(); - - CG_DrawActive_Detour.GetOriginal()(localClientNum); -} - Detour UI_Refresh_Detour; void UI_Refresh_Hook(int localClientNum) @@ -408,7 +373,9 @@ IW3_MP_Plugin::IW3_MP_Plugin() DisableFastfileAuth(); + // Special modules need to be registered first RegisterModule(new Config()); + RegisterModule(new Events()); RegisterModule(new cg()); RegisterModule(new cj_tas()); @@ -427,9 +394,6 @@ IW3_MP_Plugin::IW3_MP_Plugin() UI_Refresh_Detour = Detour(UI_Refresh, UI_Refresh_Hook); UI_Refresh_Detour.Install(); - CG_DrawActive_Detour = Detour(CG_DrawActive, CG_DrawActive_Hook); - CG_DrawActive_Detour.Install(); - CL_GamepadButtonEvent_Detour = Detour(CL_GamepadButtonEvent, CL_GamepadButtonEvent_Hook); CL_GamepadButtonEvent_Detour.Install(); @@ -446,13 +410,30 @@ IW3_MP_Plugin::IW3_MP_Plugin() cg_draw_player_info = Dvar_RegisterBool("cg_draw_player_info", false, 0, "Draw player info (origin, viewangles, speed) on screen"); + + Events::OnCG_DrawActive( + []() + { + CheckKeyboardCompletion(); + + static dvar_s *pm_fixed_fps_enable = Dvar_FindMalleableVar("pm_fixed_fps_enable"); + + if (pm_fixed_fps_enable->current.enabled) + { + DrawFixedFPS(); + } + + if (cg_draw_player_info->current.enabled) + { + CG_DrawPlayerInfo(); + } + }); } IW3_MP_Plugin::~IW3_MP_Plugin() { DbgPrint("Shutting down MP\n"); - CG_DrawActive_Detour.Remove(); CL_GamepadButtonEvent_Detour.Remove(); Load_MapEntsPtr_Detour.Remove(); diff --git a/src/game/iw3/mp/symbols.h b/src/game/iw3/mp/symbols.h index 0f91c70..e42e4aa 100644 --- a/src/game/iw3/mp/symbols.h +++ b/src/game/iw3/mp/symbols.h @@ -15,7 +15,9 @@ static auto Cbuf_AddText = reinterpret_cast(0x8223AAE8); -static auto CG_DrawActive = reinterpret_cast(0x8231E6E0); +typedef void (*CG_DrawActive_t)(int localClientNum); +static CG_DrawActive_t CG_DrawActive = reinterpret_cast(0x8231E6E0); + static auto CG_GameMessage = reinterpret_cast(0x8230AAF0); static auto CG_GetPredictedPlayerState = reinterpret_cast(0x82309120); static auto CG_RegisterGraphics = reinterpret_cast(0x8230D858); @@ -201,9 +203,8 @@ static auto CL_GetPredictedOriginForServerTime = int *bobCycle, int *movementDir)>(0x822CAA38); static auto CL_SetStance = reinterpret_cast(0x822D92A0); -static auto CG_Init = - reinterpret_cast( - 0x8230DEA0); +typedef void (*CG_Init_t)(int localClientNum, int serverMessageNum, int serverCommandSequence, int clientNum); +static CG_Init_t CG_Init = reinterpret_cast(0x8230DEA0); static auto Hunk_AllocateTempMemoryHighInternal = reinterpret_cast(0x821D7328); static auto Scr_AddSourceBuffer =