diff --git a/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs b/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs index 41c4dab1..653d9c1a 100644 --- a/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs +++ b/Penumbra/Interop/Hooks/PostProcessing/RenderTargetHdrEnabler.cs @@ -7,6 +7,7 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; using FFXIVClientStructs.FFXIV.Client.Graphics.Render; using OtterGui.Services; using Penumbra.GameData; +using Penumbra.Interop.Hooks.ResourceLoading; using Penumbra.Services; namespace Penumbra.Interop.Hooks.PostProcessing; @@ -31,19 +32,23 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable public TextureReportRecord[]? TextureReport { get; private set; } - [Signature(Sigs.RenderTargetManagerInitialize, DetourName = nameof(RenderTargetManagerInitializeDetour))] - private readonly Hook _renderTargetManagerInitialize = null!; - - [Signature(Sigs.DeviceCreateTexture2D, DetourName = nameof(CreateTexture2DDetour))] - private readonly Hook _createTexture2D = null!; + private readonly Hook? _renderTargetManagerInitialize; + private readonly Hook? _createTexture2D; public RenderTargetHdrEnabler(IGameInteropProvider interop, Configuration config, IDalamudPluginInterface pi, - DalamudConfigService dalamudConfig) + DalamudConfigService dalamudConfig, PeSigScanner peScanner) { _config = config; - interop.InitializeFromAttributes(this); - if (config.HdrRenderTargets && !HookOverrides.Instance.PostProcessing.RenderTargetManagerInitialize) - _renderTargetManagerInitialize.Enable(); + if (peScanner.TryScanText(Sigs.RenderTargetManagerInitialize, out var initializeAddress) + && peScanner.TryScanText(Sigs.DeviceCreateTexture2D, out var createAddress)) + { + _renderTargetManagerInitialize = + interop.HookFromAddress(initializeAddress, RenderTargetManagerInitializeDetour); + _createTexture2D = interop.HookFromAddress(createAddress, CreateTexture2DDetour); + + if (config.HdrRenderTargets && !HookOverrides.Instance.PostProcessing.RenderTargetManagerInitialize) + _renderTargetManagerInitialize.Enable(); + } _share = pi.GetOrCreateData("Penumbra.RenderTargetHDR.V1", () => { @@ -87,19 +92,19 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable private void Dispose(bool _) { - _createTexture2D.Dispose(); - _renderTargetManagerInitialize.Dispose(); + _createTexture2D?.Dispose(); + _renderTargetManagerInitialize?.Dispose(); } private nint RenderTargetManagerInitializeDetour(RenderTargetManager* @this) { - _createTexture2D.Enable(); + _createTexture2D!.Enable(); _share.Item5[0] = true; _textureIndices.Value = new TextureIndices(0, 0); _textures.Value = _config.DebugMode ? [] : null; try { - return _renderTargetManagerInitialize.Original(@this); + return _renderTargetManagerInitialize!.Original(@this); } finally { @@ -133,7 +138,7 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable _textureIndices.Value = indices; } - var texture = _createTexture2D.Original(@this, size, mipLevel, textureFormat, flags, unk); + var texture = _createTexture2D!.Original(@this, size, mipLevel, textureFormat, flags, unk); if (_textures.IsValueCreated) _textures.Value?.Add((nint)texture, (indices.CreationOrder - 1, originalTextureFormat)); return texture; diff --git a/Penumbra/Interop/Hooks/ResourceLoading/PapHandler.cs b/Penumbra/Interop/Hooks/ResourceLoading/PapHandler.cs index 5ba8c975..35ee86dc 100644 --- a/Penumbra/Interop/Hooks/ResourceLoading/PapHandler.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/PapHandler.cs @@ -2,9 +2,9 @@ namespace Penumbra.Interop.Hooks.ResourceLoading; -public sealed class PapHandler(PapRewriter.PapResourceHandlerPrototype papResourceHandler) : IDisposable +public sealed class PapHandler(PeSigScanner sigScanner, PapRewriter.PapResourceHandlerPrototype papResourceHandler) : IDisposable { - private readonly PapRewriter _papRewriter = new(papResourceHandler); + private readonly PapRewriter _papRewriter = new(sigScanner, papResourceHandler); public void Enable() { diff --git a/Penumbra/Interop/Hooks/ResourceLoading/PapRewriter.cs b/Penumbra/Interop/Hooks/ResourceLoading/PapRewriter.cs index 2fb1623d..5fdec816 100644 --- a/Penumbra/Interop/Hooks/ResourceLoading/PapRewriter.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/PapRewriter.cs @@ -7,21 +7,20 @@ using Swan; namespace Penumbra.Interop.Hooks.ResourceLoading; -public sealed class PapRewriter(PapRewriter.PapResourceHandlerPrototype papResourceHandler) : IDisposable +public sealed class PapRewriter(PeSigScanner sigScanner, PapRewriter.PapResourceHandlerPrototype papResourceHandler) : IDisposable { public unsafe delegate int PapResourceHandlerPrototype(void* self, byte* path, int length); - private readonly PeSigScanner _scanner = new(); private readonly Dictionary _hooks = []; private readonly Dictionary<(nint, Register, ulong), nint> _nativeAllocPaths = []; private readonly List _nativeAllocCaves = []; public void Rewrite(string sig, string name) { - if (!_scanner.TryScanText(sig, out var address)) + if (!sigScanner.TryScanText(sig, out var address)) throw new Exception($"Signature for {name} [{sig}] could not be found."); - var funcInstructions = _scanner.GetFunctionInstructions(address).ToArray(); + var funcInstructions = sigScanner.GetFunctionInstructions(address).ToArray(); var hookPoints = ScanPapHookPoints(funcInstructions).ToList(); foreach (var hookPoint in hookPoints) @@ -165,8 +164,6 @@ public sealed class PapRewriter(PapRewriter.PapResourceHandlerPrototype papResou public void Dispose() { - _scanner.Dispose(); - foreach (var hook in _hooks.Values) { hook.Disable(); diff --git a/Penumbra/Interop/Hooks/ResourceLoading/PeSigScanner.cs b/Penumbra/Interop/Hooks/ResourceLoading/PeSigScanner.cs index 4be0da00..620f3160 100644 --- a/Penumbra/Interop/Hooks/ResourceLoading/PeSigScanner.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/PeSigScanner.cs @@ -1,12 +1,13 @@ using System.IO.MemoryMappedFiles; using Iced.Intel; +using OtterGui.Services; using PeNet; using Decoder = Iced.Intel.Decoder; namespace Penumbra.Interop.Hooks.ResourceLoading; // A good chunk of this was blatantly stolen from Dalamud's SigScanner 'cause Winter could not be faffed, Winter will definitely not rewrite it later -public unsafe class PeSigScanner : IDisposable +public unsafe class PeSigScanner : IDisposable, IService { private readonly MemoryMappedFile _file; private readonly MemoryMappedViewAccessor _textSection; diff --git a/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs b/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs index 47f96d98..ad9c41e6 100644 --- a/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs +++ b/Penumbra/Interop/Hooks/ResourceLoading/ResourceLoader.cs @@ -22,7 +22,7 @@ public unsafe class ResourceLoader : IDisposable, IService private ResolveData _resolvedData = ResolveData.Invalid; public event Action? PapRequested; - public ResourceLoader(ResourceService resources, FileReadService fileReadService, RsfService rsfService, Configuration config) + public ResourceLoader(ResourceService resources, FileReadService fileReadService, RsfService rsfService, Configuration config, PeSigScanner sigScanner) { _resources = resources; _fileReadService = fileReadService; @@ -35,7 +35,7 @@ public unsafe class ResourceLoader : IDisposable, IService _resources.ResourceHandleDecRef += DecRefProtection; _fileReadService.ReadSqPack += ReadSqPackDetour; - _papHandler = new PapHandler(PapResourceHandler); + _papHandler = new PapHandler(sigScanner, PapResourceHandler); _papHandler.Enable(); }