diff --git a/Rebound/Plugin.cs b/Rebound/Plugin.cs index cb8d171..31e02c9 100644 --- a/Rebound/Plugin.cs +++ b/Rebound/Plugin.cs @@ -4,8 +4,10 @@ using Dalamud.IoC; using Dalamud.Plugin; using Dalamud.Plugin.Services; +using Dalamud.Utility.Signatures; using FFXIVClientStructs.FFXIV.Client.Graphics.Physics; using static FFXIVClientStructs.FFXIV.Client.Graphics.Physics.BonePhysicsUpdater; +using FFXIVClientStructs.FFXIV.Client.System.Framework; namespace Rebound; @@ -13,6 +15,9 @@ public sealed class Plugin : IDalamudPlugin { private readonly Hook? boneSimulatorUpdateHook = null!; + [Signature("F3 0F 10 89 ?? ?? ?? ?? 4C 8B C2", DetourName = nameof(TaskHook))] + private readonly Hook? taskHook = null!; + #if DEBUG /// If the fix should be enabled, it's only toggleable here for debug purposes public bool EnableFix = true; @@ -38,7 +43,7 @@ public Plugin() startTick = DateTime.Now.Ticks; boneSimulatorUpdateHook?.Enable(); - Framework.Update += Update; + taskHook?.Enable(); #if DEBUG DebugWindow = new DebugWindow(this); @@ -51,9 +56,6 @@ public Plugin() #endif } - [PluginService] - internal static IFramework Framework { get; private set; } = null!; - [PluginService] internal static IGameInteropProvider Hooking { get; private set; } = null!; @@ -74,7 +76,7 @@ public Plugin() public void Dispose() { boneSimulatorUpdateHook?.Dispose(); - Framework.Update -= Update; + taskHook?.Dispose(); #if DEBUG WindowSystem.RemoveAllWindows(); @@ -82,13 +84,25 @@ public void Dispose() #endif } - // Called every frame. - public void Update(IFramework _) + /// Our new bone simulator update function. + /// Called for each BoneSimulator, so possibly multiple times every frame. Should be kept very simple for performance reasons. + private unsafe void BoneUpdate(BonePhysicsUpdater* self, UpdateBoneSimulatorJobData* data) + { + if (!ExecutePhysics) + { + return; + } + + boneSimulatorUpdateHook!.Original(self, data); + } + + private unsafe void TaskHook(Framework* self, void* a2) { #if DEBUG if (!EnableFix) { ExecutePhysics = true; + taskHook!.Original(self, a2); return; } #endif @@ -97,6 +111,7 @@ public void Update(IFramework _) if (PluginInterface.UiBuilder.CutsceneActive) { ExecutePhysics = true; + taskHook!.Original(self, a2); return; } @@ -118,20 +133,16 @@ public void Update(IFramework _) RanPhysics = true; ExecutePhysics = true; } - } - /// Our new bone simulator update function. - /// Called for each BoneSimulator, so possibly multiple times every frame. Should be kept very simple for performance reasons. - private unsafe void BoneUpdate(BonePhysicsUpdater* self, UpdateBoneSimulatorJobData* data) - { - if (!ExecutePhysics) - { - return; - } - - boneSimulatorUpdateHook!.Original(self, data); + var oldDeltaTime = self->FrameDeltaTime; + self->FrameDeltaTime = 1.0f / (float)TargetFps; // Unsure if this helps at all, but just in case. + taskHook!.Original(self, a2); + self->FrameDeltaTime = oldDeltaTime; } + /// The detour function signature + private unsafe delegate void TaskHookDelegate(Framework* self, void* a2); + #if DEBUG private void DrawUi() => WindowSystem.Draw(); #endif