Share PeSigScanner and use in RenderTargetHdrEnabler because of ReShade.

This commit is contained in:
Ottermandias 2025-01-11 17:59:44 +01:00
parent 7f52777fd4
commit 6ea38eac0a
5 changed files with 28 additions and 25 deletions

View file

@ -7,6 +7,7 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using FFXIVClientStructs.FFXIV.Client.Graphics.Render; using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
using OtterGui.Services; using OtterGui.Services;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Services; using Penumbra.Services;
namespace Penumbra.Interop.Hooks.PostProcessing; namespace Penumbra.Interop.Hooks.PostProcessing;
@ -31,19 +32,23 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable
public TextureReportRecord[]? TextureReport { get; private set; } public TextureReportRecord[]? TextureReport { get; private set; }
[Signature(Sigs.RenderTargetManagerInitialize, DetourName = nameof(RenderTargetManagerInitializeDetour))] private readonly Hook<RenderTargetManagerInitializeFunc>? _renderTargetManagerInitialize;
private readonly Hook<RenderTargetManagerInitializeFunc> _renderTargetManagerInitialize = null!; private readonly Hook<CreateTexture2DFunc>? _createTexture2D;
[Signature(Sigs.DeviceCreateTexture2D, DetourName = nameof(CreateTexture2DDetour))]
private readonly Hook<CreateTexture2DFunc> _createTexture2D = null!;
public RenderTargetHdrEnabler(IGameInteropProvider interop, Configuration config, IDalamudPluginInterface pi, public RenderTargetHdrEnabler(IGameInteropProvider interop, Configuration config, IDalamudPluginInterface pi,
DalamudConfigService dalamudConfig) DalamudConfigService dalamudConfig, PeSigScanner peScanner)
{ {
_config = config; _config = config;
interop.InitializeFromAttributes(this); if (peScanner.TryScanText(Sigs.RenderTargetManagerInitialize, out var initializeAddress)
if (config.HdrRenderTargets && !HookOverrides.Instance.PostProcessing.RenderTargetManagerInitialize) && peScanner.TryScanText(Sigs.DeviceCreateTexture2D, out var createAddress))
_renderTargetManagerInitialize.Enable(); {
_renderTargetManagerInitialize =
interop.HookFromAddress<RenderTargetManagerInitializeFunc>(initializeAddress, RenderTargetManagerInitializeDetour);
_createTexture2D = interop.HookFromAddress<CreateTexture2DFunc>(createAddress, CreateTexture2DDetour);
if (config.HdrRenderTargets && !HookOverrides.Instance.PostProcessing.RenderTargetManagerInitialize)
_renderTargetManagerInitialize.Enable();
}
_share = pi.GetOrCreateData("Penumbra.RenderTargetHDR.V1", () => _share = pi.GetOrCreateData("Penumbra.RenderTargetHDR.V1", () =>
{ {
@ -87,19 +92,19 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable
private void Dispose(bool _) private void Dispose(bool _)
{ {
_createTexture2D.Dispose(); _createTexture2D?.Dispose();
_renderTargetManagerInitialize.Dispose(); _renderTargetManagerInitialize?.Dispose();
} }
private nint RenderTargetManagerInitializeDetour(RenderTargetManager* @this) private nint RenderTargetManagerInitializeDetour(RenderTargetManager* @this)
{ {
_createTexture2D.Enable(); _createTexture2D!.Enable();
_share.Item5[0] = true; _share.Item5[0] = true;
_textureIndices.Value = new TextureIndices(0, 0); _textureIndices.Value = new TextureIndices(0, 0);
_textures.Value = _config.DebugMode ? [] : null; _textures.Value = _config.DebugMode ? [] : null;
try try
{ {
return _renderTargetManagerInitialize.Original(@this); return _renderTargetManagerInitialize!.Original(@this);
} }
finally finally
{ {
@ -133,7 +138,7 @@ public unsafe class RenderTargetHdrEnabler : IService, IDisposable
_textureIndices.Value = indices; _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) if (_textures.IsValueCreated)
_textures.Value?.Add((nint)texture, (indices.CreationOrder - 1, originalTextureFormat)); _textures.Value?.Add((nint)texture, (indices.CreationOrder - 1, originalTextureFormat));
return texture; return texture;

View file

@ -2,9 +2,9 @@
namespace Penumbra.Interop.Hooks.ResourceLoading; 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() public void Enable()
{ {

View file

@ -7,21 +7,20 @@ using Swan;
namespace Penumbra.Interop.Hooks.ResourceLoading; 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); public unsafe delegate int PapResourceHandlerPrototype(void* self, byte* path, int length);
private readonly PeSigScanner _scanner = new();
private readonly Dictionary<nint, AsmHook> _hooks = []; private readonly Dictionary<nint, AsmHook> _hooks = [];
private readonly Dictionary<(nint, Register, ulong), nint> _nativeAllocPaths = []; private readonly Dictionary<(nint, Register, ulong), nint> _nativeAllocPaths = [];
private readonly List<nint> _nativeAllocCaves = []; private readonly List<nint> _nativeAllocCaves = [];
public void Rewrite(string sig, string name) 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."); 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(); var hookPoints = ScanPapHookPoints(funcInstructions).ToList();
foreach (var hookPoint in hookPoints) foreach (var hookPoint in hookPoints)
@ -165,8 +164,6 @@ public sealed class PapRewriter(PapRewriter.PapResourceHandlerPrototype papResou
public void Dispose() public void Dispose()
{ {
_scanner.Dispose();
foreach (var hook in _hooks.Values) foreach (var hook in _hooks.Values)
{ {
hook.Disable(); hook.Disable();

View file

@ -1,12 +1,13 @@
using System.IO.MemoryMappedFiles; using System.IO.MemoryMappedFiles;
using Iced.Intel; using Iced.Intel;
using OtterGui.Services;
using PeNet; using PeNet;
using Decoder = Iced.Intel.Decoder; using Decoder = Iced.Intel.Decoder;
namespace Penumbra.Interop.Hooks.ResourceLoading; 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 // 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 MemoryMappedFile _file;
private readonly MemoryMappedViewAccessor _textSection; private readonly MemoryMappedViewAccessor _textSection;

View file

@ -22,7 +22,7 @@ public unsafe class ResourceLoader : IDisposable, IService
private ResolveData _resolvedData = ResolveData.Invalid; private ResolveData _resolvedData = ResolveData.Invalid;
public event Action<Utf8GamePath, FullPath?, ResolveData>? PapRequested; public event Action<Utf8GamePath, FullPath?, ResolveData>? 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; _resources = resources;
_fileReadService = fileReadService; _fileReadService = fileReadService;
@ -35,7 +35,7 @@ public unsafe class ResourceLoader : IDisposable, IService
_resources.ResourceHandleDecRef += DecRefProtection; _resources.ResourceHandleDecRef += DecRefProtection;
_fileReadService.ReadSqPack += ReadSqPackDetour; _fileReadService.ReadSqPack += ReadSqPackDetour;
_papHandler = new PapHandler(PapResourceHandler); _papHandler = new PapHandler(sigScanner, PapResourceHandler);
_papHandler.Enable(); _papHandler.Enable();
} }