From 4aeee4956155bc49b26baee02ad7297c75bbc35a Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Tue, 18 Feb 2025 08:54:37 +0000 Subject: [PATCH] object_patches: fix rail booster sounds overlapping at HFR (#427) --- UnleashedRecomp/patches/object_patches.cpp | 37 ++++++++++++++++++++-- UnleashedRecompLib/config/SWA.toml | 5 +++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/UnleashedRecomp/patches/object_patches.cpp b/UnleashedRecomp/patches/object_patches.cpp index 45e2822..11c0883 100644 --- a/UnleashedRecomp/patches/object_patches.cpp +++ b/UnleashedRecomp/patches/object_patches.cpp @@ -70,10 +70,9 @@ void ObjBigBarrelSetPositionMidAsmHook(PPCRegister& r3, PPCRegister& r4) } } +// SWA::CExBullet::AddCallback // Tornado Defense bullet particles are colored by the button prompt, which differs on PlayStation 3. // Luckily, the PS3 particles are left in the files, and they get spawned by name when a bullet gets created. - -// SWA::CExBullet::AddCallback PPC_FUNC_IMPL(__imp__sub_82B14CC0); PPC_FUNC(sub_82B14CC0) { @@ -99,3 +98,37 @@ PPC_FUNC(sub_82B14CC0) __imp__sub_82B14CC0(ctx, base); } + +// CObjGrindDashPanel is particularly egregious when it comes to overlapping sounds at HFR +// due to the character proxy sending the hit message multiple times in a frame. This is a +// quick workaround to limit the message process function to occur at a 30 FPS time step. +static constexpr size_t OBJ_GRIND_DASH_PANEL_SIZE = 0x160; + +void ObjGrindDashPanelAllocMidAsmHook(PPCRegister& r3) +{ + r3.u32 += sizeof(std::chrono::steady_clock::time_point); +} + +// SWA::CObjGrindDashPanel::CObjGrindDashPanel +PPC_FUNC_IMPL(__imp__sub_82614228); +PPC_FUNC(sub_82614228) +{ + new (base + ctx.r3.u32 + OBJ_GRIND_DASH_PANEL_SIZE) std::chrono::steady_clock::time_point(); + __imp__sub_82614228(ctx, base); +} + +// SWA::CObjGrindDashPanel::MsgHitEventCollision::Impl +PPC_FUNC_IMPL(__imp__sub_826145D8); +PPC_FUNC(sub_826145D8) +{ + auto pLastHitTime = (std::chrono::steady_clock::time_point*)g_memory.Translate(ctx.r3.u32 + OBJ_GRIND_DASH_PANEL_SIZE); + auto now = std::chrono::steady_clock::now(); + auto deltaTime = std::min(std::chrono::duration(now - *pLastHitTime).count(), 1.0 / 15.0); + + *pLastHitTime = now; + + if (deltaTime < 1.0 / 30.0) + return; + + __imp__sub_826145D8(ctx, base); +} diff --git a/UnleashedRecompLib/config/SWA.toml b/UnleashedRecompLib/config/SWA.toml index de0e981..0b0ed1a 100644 --- a/UnleashedRecompLib/config/SWA.toml +++ b/UnleashedRecompLib/config/SWA.toml @@ -1086,3 +1086,8 @@ registers = ["r4"] name = "AnimationDataMakeMidAsmHook" address = 0x82BB38E4 registers = ["r31", "r29", "r28"] + +[[midasm_hook]] +name = "ObjGrindDashPanelAllocMidAsmHook" +address = 0x82614948 +registers = ["r3"]