From 5f9f395d91c4dee2e2e625c1be23a52ae35b5fb3 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Thu, 14 Aug 2025 09:57:27 +0100 Subject: [PATCH] Use dynamic physics update rate above 120 FPS --- MarathonRecomp/CMakeLists.txt | 1 + MarathonRecomp/api/Marathon.h | 3 +++ MarathonRecomp/api/Sonicteam/GameImp.h | 9 +++++++++ MarathonRecomp/api/Sonicteam/GameImp.inl | 8 ++++++++ .../api/Sonicteam/SoX/Physics/Havok/WorldHavok.h | 14 ++++++++++++++ MarathonRecomp/api/Sonicteam/SoX/Physics/World.h | 9 +++++++++ MarathonRecomp/api/Sonicteam/SoX/RefCountObject.h | 11 +++++++++++ MarathonRecomp/patches/fps_patches.cpp | 14 ++++++++++++++ 8 files changed, 69 insertions(+) create mode 100644 MarathonRecomp/api/Sonicteam/GameImp.inl create mode 100644 MarathonRecomp/api/Sonicteam/SoX/Physics/Havok/WorldHavok.h create mode 100644 MarathonRecomp/api/Sonicteam/SoX/Physics/World.h create mode 100644 MarathonRecomp/api/Sonicteam/SoX/RefCountObject.h create mode 100644 MarathonRecomp/patches/fps_patches.cpp diff --git a/MarathonRecomp/CMakeLists.txt b/MarathonRecomp/CMakeLists.txt index 76e2586fe..1f53add8b 100644 --- a/MarathonRecomp/CMakeLists.txt +++ b/MarathonRecomp/CMakeLists.txt @@ -138,6 +138,7 @@ set(MARATHON_RECOMP_PATCHES_CXX_SOURCES "patches/aspect_ratio_patches.cpp" "patches/audio_patches.cpp" "patches/camera_patches.cpp" + "patches/fps_patches.cpp" "patches/frontend_listener.cpp" "patches/misc_patches.cpp" "patches/player_patches.cpp" diff --git a/MarathonRecomp/api/Marathon.h b/MarathonRecomp/api/Marathon.h index ec5ec14c8..49b8141f8 100644 --- a/MarathonRecomp/api/Marathon.h +++ b/MarathonRecomp/api/Marathon.h @@ -56,6 +56,9 @@ #include "Sonicteam/SoX/Engine/Task.h" #include "Sonicteam/SoX/MessageReceiver.h" #include "Sonicteam/SoX/Object.h" +#include "Sonicteam/SoX/Physics/Havok/WorldHavok.h" +#include "Sonicteam/SoX/Physics/World.h" +#include "Sonicteam/SoX/RefCountObject.h" #include "Sonicteam/System/CreateStatic.h" #include "Sonicteam/System/Singleton.h" #include "Sonicteam/TitleTask.h" diff --git a/MarathonRecomp/api/Sonicteam/GameImp.h b/MarathonRecomp/api/Sonicteam/GameImp.h index 2dc4855a1..dde0e1224 100644 --- a/MarathonRecomp/api/Sonicteam/GameImp.h +++ b/MarathonRecomp/api/Sonicteam/GameImp.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace Sonicteam { @@ -29,5 +30,13 @@ namespace Sonicteam MARATHON_INSERT_PADDING(0xE3C); PlayerData m_PlayerData[4]; + MARATHON_INSERT_PADDING(0xA4C); + xpointer m_pPhysicsWorld; + xpointer m_pMyCollisionFilter; + + template + inline T* GetPhysicsWorld(); }; } + +#include diff --git a/MarathonRecomp/api/Sonicteam/GameImp.inl b/MarathonRecomp/api/Sonicteam/GameImp.inl new file mode 100644 index 000000000..ed1de103f --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/GameImp.inl @@ -0,0 +1,8 @@ +namespace Sonicteam +{ + template + inline T* GameImp::GetPhysicsWorld() + { + return (T*)m_pPhysicsWorld.get(); + } +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Physics/Havok/WorldHavok.h b/MarathonRecomp/api/Sonicteam/SoX/Physics/Havok/WorldHavok.h new file mode 100644 index 000000000..8415b9c7d --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Physics/Havok/WorldHavok.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +namespace Sonicteam::SoX::Physics::Havok +{ + class WorldHavok : public World + { + public: + MARATHON_INSERT_PADDING(0x18); + bool m_IsDynamicUpdateRate; + }; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/Physics/World.h b/MarathonRecomp/api/Sonicteam/SoX/Physics/World.h new file mode 100644 index 000000000..7e786fd12 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/Physics/World.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace Sonicteam::SoX::Physics +{ + class World : public RefCountObject {}; +} diff --git a/MarathonRecomp/api/Sonicteam/SoX/RefCountObject.h b/MarathonRecomp/api/Sonicteam/SoX/RefCountObject.h new file mode 100644 index 000000000..4f006d9b7 --- /dev/null +++ b/MarathonRecomp/api/Sonicteam/SoX/RefCountObject.h @@ -0,0 +1,11 @@ +#pragma once + +namespace Sonicteam::SoX +{ + class RefCountObject + { + public: + xpointer m_pVftable; + be m_ReferenceCount; + }; +} diff --git a/MarathonRecomp/patches/fps_patches.cpp b/MarathonRecomp/patches/fps_patches.cpp new file mode 100644 index 000000000..5067635d3 --- /dev/null +++ b/MarathonRecomp/patches/fps_patches.cpp @@ -0,0 +1,14 @@ +#include +#include + +// Sonicteam::SoX::Physics::Havok::WorldHavok::Update +PPC_FUNC_IMPL(__imp__sub_82587AA8); +PPC_FUNC(sub_82587AA8) +{ + auto pPhysicsWorld = (Sonicteam::SoX::Physics::Havok::WorldHavok*)(base + ctx.r3.u32); + + // Use dynamic update rate if the FPS exceeds the fixed rate. + pPhysicsWorld->m_IsDynamicUpdateRate = Config::FPS > 120; + + __imp__sub_82587AA8(ctx, base); +}