write code

This commit is contained in:
Soreepeong 2024-07-25 21:07:49 +09:00
parent ef64a67d10
commit d8861ec7da
6 changed files with 46 additions and 46 deletions

View file

@ -444,7 +444,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
public bool WindowIsImmersive { get; set; } = false; public bool WindowIsImmersive { get; set; } = false;
/// <summary>Gets or sets the mode specifying how to handle ReShade.</summary> /// <summary>Gets or sets the mode specifying how to handle ReShade.</summary>
public ReShadeHandlingMode ReShadeHandlingMode { get; set; } = ReShadeHandlingMode.ReShadeAddon; public ReShadeHandlingMode ReShadeHandlingMode { get; set; } = ReShadeHandlingMode.Default;
/// <summary>Gets or sets the swap chain hook mode.</summary> /// <summary>Gets or sets the swap chain hook mode.</summary>
public SwapChainHelper.HookMode SwapChainHookMode { get; set; } = SwapChainHelper.HookMode.ByteCode; public SwapChainHelper.HookMode SwapChainHookMode { get; set; } = SwapChainHelper.HookMode.ByteCode;

View file

@ -46,6 +46,14 @@ internal unsafe partial class InterfaceManager
this.RenderDalamudDraw(activeScene); this.RenderDalamudDraw(activeScene);
} }
private void ReShadeAddonInterfaceOnReShadeOverlay(ref ReShadeAddonInterface.ApiObject runtime)
{
var swapChainNative = runtime.GetNative<IDXGISwapChain>();
if (this.RenderDalamudCheckAndInitialize(swapChainNative, 0) is { } activeScene)
this.RenderDalamudDraw(activeScene);
}
private int AsReShadeAddonDxgiSwapChainResizeBuffersDetour( private int AsReShadeAddonDxgiSwapChainResizeBuffersDetour(
IDXGISwapChain* swapChain, IDXGISwapChain* swapChain,
uint bufferCount, uint bufferCount,

View file

@ -878,6 +878,7 @@ internal partial class InterfaceManager : IInternalDisposableService
switch (this.dalamudConfiguration.ReShadeHandlingMode) switch (this.dalamudConfiguration.ReShadeHandlingMode)
{ {
// This is the only mode honored when SwapChainHookMode is set to VTable. // This is the only mode honored when SwapChainHookMode is set to VTable.
case ReShadeHandlingMode.Default:
case ReShadeHandlingMode.UnwrapReShade when ReShadeAddonInterface.ReShadeModule is not null: case ReShadeHandlingMode.UnwrapReShade when ReShadeAddonInterface.ReShadeModule is not null:
if (SwapChainHelper.UnwrapReShade()) if (SwapChainHelper.UnwrapReShade())
Log.Information("Unwrapped ReShade"); Log.Information("Unwrapped ReShade");
@ -896,7 +897,8 @@ internal partial class InterfaceManager : IInternalDisposableService
break; break;
// Register Dalamud as a ReShade addon. // Register Dalamud as a ReShade addon.
case ReShadeHandlingMode.ReShadeAddon: case ReShadeHandlingMode.ReShadeAddonPresent:
case ReShadeHandlingMode.ReShadeAddonReShadeOverlay:
if (!ReShadeAddonInterface.TryRegisterAddon(out this.reShadeAddonInterface)) if (!ReShadeAddonInterface.TryRegisterAddon(out this.reShadeAddonInterface))
{ {
Log.Warning("Could not register as ReShade addon"); Log.Warning("Could not register as ReShade addon");
@ -906,13 +908,15 @@ internal partial class InterfaceManager : IInternalDisposableService
Log.Information("Registered as a ReShade addon"); Log.Information("Registered as a ReShade addon");
this.reShadeAddonInterface.InitSwapChain += this.ReShadeAddonInterfaceOnInitSwapChain; this.reShadeAddonInterface.InitSwapChain += this.ReShadeAddonInterfaceOnInitSwapChain;
this.reShadeAddonInterface.DestroySwapChain += this.ReShadeAddonInterfaceOnDestroySwapChain; this.reShadeAddonInterface.DestroySwapChain += this.ReShadeAddonInterfaceOnDestroySwapChain;
this.reShadeAddonInterface.Present += this.ReShadeAddonInterfaceOnPresent; if (this.dalamudConfiguration.ReShadeHandlingMode == ReShadeHandlingMode.ReShadeAddonPresent)
this.reShadeAddonInterface.Present += this.ReShadeAddonInterfaceOnPresent;
else
this.reShadeAddonInterface.ReShadeOverlay += this.ReShadeAddonInterfaceOnReShadeOverlay;
dxgiSwapChainResizeBuffersDelegate = this.AsReShadeAddonDxgiSwapChainResizeBuffersDetour; dxgiSwapChainResizeBuffersDelegate = this.AsReShadeAddonDxgiSwapChainResizeBuffersDetour;
break; break;
// Hook ReShade's DXGISwapChain::on_present. This is the legacy and the default option. // Hook ReShade's DXGISwapChain::on_present. This is the legacy and the default option.
case ReShadeHandlingMode.Default:
case ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent: case ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent:
pfnReShadeDxgiSwapChainPresent = ReShadeAddonInterface.FindReShadeDxgiSwapChainOnPresent(); pfnReShadeDxgiSwapChainPresent = ReShadeAddonInterface.FindReShadeDxgiSwapChainOnPresent();

View file

@ -22,6 +22,7 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
private readonly Hook<GetModuleHandleExWDelegate> addonModuleResolverHook; private readonly Hook<GetModuleHandleExWDelegate> addonModuleResolverHook;
private readonly DelegateStorage<UnsafePresentDelegate> presentDelegate; private readonly DelegateStorage<UnsafePresentDelegate> presentDelegate;
private readonly DelegateStorage<ReShadeOverlayDelegate> reShadeOverlayDelegate;
private readonly DelegateStorage<ReShadeInitSwapChain> initSwapChainDelegate; private readonly DelegateStorage<ReShadeInitSwapChain> initSwapChainDelegate;
private readonly DelegateStorage<ReShadeDestroySwapChain> destroySwapChainDelegate; private readonly DelegateStorage<ReShadeDestroySwapChain> destroySwapChainDelegate;
@ -61,6 +62,9 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
pSourceRect is null ? default : new(pSourceRect, 1), pSourceRect is null ? default : new(pSourceRect, 1),
pDestRect is null ? default : new(pDestRect, 1), pDestRect is null ? default : new(pDestRect, 1),
new(pDirtyRects, (int)dirtyRectCount)))); new(pDirtyRects, (int)dirtyRectCount))));
Exports.ReShadeRegisterEvent(
AddonEvent.ReShadeOverlay,
this.reShadeOverlayDelegate = new((ref ApiObject rt) => this.ReShadeOverlay?.Invoke(ref rt)));
Exports.ReShadeRegisterEvent( Exports.ReShadeRegisterEvent(
AddonEvent.InitSwapChain, AddonEvent.InitSwapChain,
this.initSwapChainDelegate = new((ref ApiObject rt) => this.InitSwapChain?.Invoke(ref rt))); this.initSwapChainDelegate = new((ref ApiObject rt) => this.InitSwapChain?.Invoke(ref rt)));
@ -104,6 +108,10 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
ReadOnlySpan<RECT> destRect, ReadOnlySpan<RECT> destRect,
ReadOnlySpan<RECT> dirtyRects); ReadOnlySpan<RECT> dirtyRects);
/// <summary>Delegate for <see cref="ReShadeAddonInterface.AddonEvent.ReShadeOverlay"/>.</summary>
/// <param name="effectRuntime">Reference to the ReShade runtime.</param>
public delegate void ReShadeOverlayDelegate(ref ApiObject effectRuntime);
/// <summary>Delegate for <see cref="ReShadeAddonInterface.AddonEvent.InitSwapChain"/>.</summary> /// <summary>Delegate for <see cref="ReShadeAddonInterface.AddonEvent.InitSwapChain"/>.</summary>
/// <param name="swapChain">Reference to the ReShade SwapChain wrapper.</param> /// <param name="swapChain">Reference to the ReShade SwapChain wrapper.</param>
public delegate void ReShadeInitSwapChain(ref ApiObject swapChain); public delegate void ReShadeInitSwapChain(ref ApiObject swapChain);
@ -132,6 +140,9 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
/// <summary>Called on <see cref="ReShadeAddonInterface.AddonEvent.Present"/>.</summary> /// <summary>Called on <see cref="ReShadeAddonInterface.AddonEvent.Present"/>.</summary>
public event PresentDelegate? Present; public event PresentDelegate? Present;
/// <summary>Called on <see cref="ReShadeAddonInterface.AddonEvent.ReShadeOverlay"/>.</summary>
public event ReShadeOverlayDelegate? ReShadeOverlay;
/// <summary>Called on <see cref="ReShadeAddonInterface.AddonEvent.InitSwapChain"/>.</summary> /// <summary>Called on <see cref="ReShadeAddonInterface.AddonEvent.InitSwapChain"/>.</summary>
public event ReShadeInitSwapChain? InitSwapChain; public event ReShadeInitSwapChain? InitSwapChain;
@ -181,7 +192,8 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
return this.addonModuleResolverHook.Original(dwFlags, lpModuleName, phModule); return this.addonModuleResolverHook.Original(dwFlags, lpModuleName, phModule);
if (lpModuleName == this.initSwapChainDelegate || if (lpModuleName == this.initSwapChainDelegate ||
lpModuleName == this.destroySwapChainDelegate || lpModuleName == this.destroySwapChainDelegate ||
lpModuleName == this.presentDelegate) lpModuleName == this.presentDelegate ||
lpModuleName == this.reShadeOverlayDelegate)
{ {
*phModule = this.hDalamudModule; *phModule = this.hDalamudModule;
return BOOL.TRUE; return BOOL.TRUE;

View file

@ -9,8 +9,13 @@ internal enum ReShadeHandlingMode
/// <summary>Unwrap ReShade from the swap chain obtained from the game.</summary> /// <summary>Unwrap ReShade from the swap chain obtained from the game.</summary>
UnwrapReShade, UnwrapReShade,
/// <summary>Register as a ReShade addon, and draw on reshade_overlay event.</summary> /// <summary>Register as a ReShade addon, and draw on <see cref="ReShadeAddonInterface.AddonEvent.Present"/> event.
ReShadeAddon, /// </summary>
ReShadeAddonPresent,
/// <summary>Register as a ReShade addon, and draw on <see cref="ReShadeAddonInterface.AddonEvent.ReShadeOverlay"/>
/// event. </summary>
ReShadeAddonReShadeOverlay,
/// <summary>Hook <c>DXGISwapChain::on_present(UINT flags, const DXGI_PRESENT_PARAMETERS *params)</c> in /// <summary>Hook <c>DXGISwapChain::on_present(UINT flags, const DXGI_PRESENT_PARAMETERS *params)</c> in
/// <c>dxgi_swapchain.cpp</c>.</summary> /// <c>dxgi_swapchain.cpp</c>.</summary>

View file

@ -79,50 +79,21 @@ public class SettingsTabExperimental : SettingsTab
"You may try different options to work around problems you may encounter.\nRestart is required for changes to take effect."), "You may try different options to work around problems you may encounter.\nRestart is required for changes to take effect."),
c => c.ReShadeHandlingMode, c => c.ReShadeHandlingMode,
(v, c) => c.ReShadeHandlingMode = v, (v, c) => c.ReShadeHandlingMode = v,
fallbackValue: ReShadeHandlingMode.ReShadeAddon, fallbackValue: ReShadeHandlingMode.Default,
warning: static rshm => warning: static rshm =>
rshm is ReShadeHandlingMode.UnwrapReShade or ReShadeHandlingMode.None rshm is ReShadeHandlingMode.UnwrapReShade or ReShadeHandlingMode.None ||
Service<DalamudConfiguration>.Get().SwapChainHookMode == SwapChainHelper.HookMode.ByteCode
? null ? null
: Loc.Localize( : "Current option will be ignored and no special ReShade handling will be done, because SwapChain vtable hook mode is set.")
"DalamudSettingsReShadeHandlingModeIgnoredVTableHookMode",
"Current option will be ignored and no special ReShade handling will be done, because SwapChain vtable hook mode is set."))
{ {
FriendlyEnumNameGetter = x => x switch FriendlyEnumNameGetter = x => x switch
{ {
ReShadeHandlingMode.Default => Loc.Localize( ReShadeHandlingMode.Default => "Default",
"DalamudSettingsReShadeHandlingModeDefault", ReShadeHandlingMode.UnwrapReShade => "Unwrap",
"Default"), ReShadeHandlingMode.ReShadeAddonPresent => "ReShade Addon (present)",
ReShadeHandlingMode.UnwrapReShade => Loc.Localize( ReShadeHandlingMode.ReShadeAddonReShadeOverlay => "ReShade Addon (reshade_overlay)",
"DalamudSettingsReShadeHandlingModeUnwrapReShade", ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent => "Hook ReShade::DXGISwapChain::OnPresent",
"Unwrap ReShade"), ReShadeHandlingMode.None => "Do not handle",
ReShadeHandlingMode.ReShadeAddon => Loc.Localize(
"DalamudSettingsReShadeHandlingModeReShadeAddon",
"ReShade addon"),
ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent => Loc.Localize(
"DalamudSettingsReShadeHandlingModeHookReShadeDxgiSwapChainOnPresent",
"Hook ReShade DXGISwapChain::OnPresent"),
ReShadeHandlingMode.None => Loc.Localize(
"DalamudSettingsReShadeHandlingModeNone",
"Do not handle"),
_ => "<invalid>",
},
FriendlyEnumDescriptionGetter = x => x switch
{
ReShadeHandlingMode.Default => Loc.Localize(
"DalamudSettingsReShadeHandlingModeDefaultDescription",
"Dalamud will use the developer-recommend settings. If nothing's wrong, keeping this option is recommended."),
ReShadeHandlingMode.UnwrapReShade => Loc.Localize(
"DalamudSettingsReShadeHandlingModeUnwrapReShadeDescription",
"Dalamud will exclude itself from all ReShade handling. Multi-monitor windows should work fine with this mode, but it may not be supported and crash in future ReShade versions."),
ReShadeHandlingMode.ReShadeAddon => Loc.Localize(
"DalamudSettingsReShadeHandlingModeReShadeAddonDescription",
"Dalamud will register itself as a ReShade addon. Multi-monitor window option will require reloading ReShade every time a new window is opened, or even may not work at all."),
ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent => Loc.Localize(
"DalamudSettingsReShadeHandlingModeHookReShadeDxgiSwapChainOnPresentDescription",
"Dalamud will use an unsupported method of detouring an internal ReShade function. Multi-monitor window option will require reloading ReShade every time a new window is opened, or even may not work at all."),
ReShadeHandlingMode.None => Loc.Localize(
"DalamudSettingsReShadeHandlingModeNoneDescription",
"No special handling will be done for ReShade. Dalamud will be under the effect of ReShade postprocessing."),
_ => "<invalid>", _ => "<invalid>",
}, },
}, },