From dd7439227948fc5c1f6c1b37afff0b0ea395e23c Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Sun, 20 Oct 2024 02:54:49 +0100 Subject: [PATCH] Implemented Unleash gauge hooks - Implements "Unleash Cancel" to allow cancelling Unleash after activating it. - Implements out of control fixes to prevent the gauge from draining when the player cannot utilise it. --- UnleashedRecomp/api/SWA.h | 1 + .../Player/Character/EvilSonic/EvilSonic.h | 14 ++++++ .../Character/EvilSonic/EvilSonicContext.h | 2 + UnleashedRecomp/config.cpp | 1 + UnleashedRecomp/config.h | 1 + UnleashedRecomp/game.cpp | 49 +++++++++++++++++++ UnleashedRecomp/kernel/heap.h | 3 +- UnleashedRecomp/res/config.toml | 1 + UnleashedRecompLib/config/SWA.toml | 7 ++- 9 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h diff --git a/UnleashedRecomp/api/SWA.h b/UnleashedRecomp/api/SWA.h index cf04961..a544cf7 100644 --- a/UnleashedRecomp/api/SWA.h +++ b/UnleashedRecomp/api/SWA.h @@ -1,6 +1,7 @@ #pragma once #include "SWA/Camera/Camera.h" +#include "SWA/Player/Character/EvilSonic/EvilSonic.h" #include "SWA/Player/Character/EvilSonic/EvilSonicContext.h" #include "SWA/System/ApplicationDocument.h" #include "SWA/System/GameDocument.h" diff --git a/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h new file mode 100644 index 0000000..d6b510e --- /dev/null +++ b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonic.h @@ -0,0 +1,14 @@ +#pragma once + +#include "SWA.inl" +#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h" + +namespace SWA::Player +{ + class CEvilSonic + { + public: + SWA_INSERT_PADDING(0xC4); + xpointer m_spContext; + }; +} diff --git a/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonicContext.h b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonicContext.h index cd7cce5..ebc786d 100644 --- a/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonicContext.h +++ b/UnleashedRecomp/api/SWA/Player/Character/EvilSonic/EvilSonicContext.h @@ -11,5 +11,7 @@ namespace SWA::Player be m_DarkGaiaEnergy; SWA_INSERT_PADDING(0x138); be m_AnimationID; + SWA_INSERT_PADDING(0x104); + be m_OutOfControlCount; }; } diff --git a/UnleashedRecomp/config.cpp b/UnleashedRecomp/config.cpp index a765501..1c6da53 100644 --- a/UnleashedRecomp/config.cpp +++ b/UnleashedRecomp/config.cpp @@ -9,6 +9,7 @@ void Config::Load() TOML_READ_ENUM(ELanguage, Language); TOML_READ_ENUM(EScoreBehaviour, ScoreBehaviour); TOML_READ_BOOLEAN(Hints); + TOML_READ_BOOLEAN(UnleashOutOfControlDrain); TOML_READ_BOOLEAN(WerehogHubTransformVideo); } TOML_END_SECTION(); diff --git a/UnleashedRecomp/config.h b/UnleashedRecomp/config.h index 04f7cfd..63d59e2 100644 --- a/UnleashedRecomp/config.h +++ b/UnleashedRecomp/config.h @@ -50,6 +50,7 @@ public: inline static ELanguage Language = ELanguage_English; inline static EScoreBehaviour ScoreBehaviour = EScoreBehaviour_CheckpointReset; inline static bool Hints = true; + inline static bool UnleashOutOfControlDrain = true; inline static bool WerehogHubTransformVideo = true; // Controls diff --git a/UnleashedRecomp/game.cpp b/UnleashedRecomp/game.cpp index c96d975..54654d1 100644 --- a/UnleashedRecomp/game.cpp +++ b/UnleashedRecomp/game.cpp @@ -8,6 +8,10 @@ const char* m_pStageID; uint32_t m_lastCheckpointScore = 0; +float m_lastDarkGaiaEnergy = 0.0f; + +bool m_isUnleashCancelled = false; + #pragma region Aspect Ratio Hooks bool CameraAspectRatioMidAsmHook(PPCRegister& r31) @@ -145,6 +149,51 @@ PPC_FUNC(sub_824DCF38) #pragma endregion +#pragma region Player Hooks + +// Dark Gaia energy change hook. +PPC_FUNC_IMPL(__imp__sub_823AF7A8); +PPC_FUNC(sub_823AF7A8) +{ + auto pEvilSonicContext = (SWA::Player::CEvilSonicContext*)g_memory.Translate(ctx.r3.u32); + + m_lastDarkGaiaEnergy = pEvilSonicContext->m_DarkGaiaEnergy; + + // Don't drain energy if out of control. + if (!Config::UnleashOutOfControlDrain && pEvilSonicContext->m_OutOfControlCount && ctx.f1.f64 < 0.0) + return; + + __imp__sub_823AF7A8(ctx, base); + + if (!Config::UnleashCancel) + return; + + auto pInputState = SWA::CInputState::GetInstance(); + + // Don't allow cancelling Unleash if the intro anim is still playing. + if (!pInputState || pEvilSonicContext->m_AnimationID == 39) + return; + + if (pInputState->GetPadState().IsTapped(SWA::eKeyState_RightBumper)) + { + pEvilSonicContext->m_DarkGaiaEnergy = 0.0f; + m_isUnleashCancelled = true; + } +} + +void PostUnleashMidAsmHook(PPCRegister& r30) +{ + if (m_isUnleashCancelled) + { + if (auto pEvilSonicContext = (SWA::Player::CEvilSonicContext*)g_memory.Translate(r30.u32)) + pEvilSonicContext->m_DarkGaiaEnergy = m_lastDarkGaiaEnergy; + + m_isUnleashCancelled = false; + } +} + +#pragma endregion + #pragma region Miscellaneous Hooks bool DisableHintsMidAsmHook() diff --git a/UnleashedRecomp/kernel/heap.h b/UnleashedRecomp/kernel/heap.h index 26f8066..90da8e6 100644 --- a/UnleashedRecomp/kernel/heap.h +++ b/UnleashedRecomp/kernel/heap.h @@ -1,5 +1,6 @@ #pragma once -#include "Mutex.h" + +#include "mutex.h" #include struct Heap diff --git a/UnleashedRecomp/res/config.toml b/UnleashedRecomp/res/config.toml index 931c34b..55a30c4 100644 --- a/UnleashedRecomp/res/config.toml +++ b/UnleashedRecomp/res/config.toml @@ -4,6 +4,7 @@ Language = 1 # The language displayed by the game. ScoreBehaviour = 0 # Determines how the score behaves when restarting at a checkpoint. # Reset to zero = 0; Reset to last checkpoint score = 1. Hints = true # Determines whether to spawn hint rings and volumes. +UnleashOutOfControlDrain = true # Determines whether to drain Dark Gaia energy whilst the player cannot move. WerehogHubTransformVideo = true # Determines whether to play the transition video for switching time of day in the hub areas. # Setting this to false will instead play a generic transition without artificial loading times. diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index 470a4a3..d56c799 100644 --- a/UnleashedRecompLib/config/SWA.toml +++ b/UnleashedRecompLib/config/SWA.toml @@ -192,4 +192,9 @@ registers = ["f1"] [[midasm_hook]] name = "GetStageIDMidAsmHook" address = 0x82528198 -registers = ["r5"] \ No newline at end of file +registers = ["r5"] + +[[midasm_hook]] +name = "PostUnleashMidAsmHook" +address = 0x823C6788 +registers = ["r30"] \ No newline at end of file