diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
index d5f1299fd..45b49cc8a 100644
--- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs
+++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs
@@ -444,7 +444,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
public bool WindowIsImmersive { get; set; } = false;
/// Gets or sets the mode specifying how to handle ReShade.
- public ReShadeHandlingMode ReShadeHandlingMode { get; set; } = ReShadeHandlingMode.ReShadeAddon;
+ public ReShadeHandlingMode ReShadeHandlingMode { get; set; } = ReShadeHandlingMode.Default;
/// Gets or sets the swap chain hook mode.
public SwapChainHelper.HookMode SwapChainHookMode { get; set; } = SwapChainHelper.HookMode.ByteCode;
diff --git a/Dalamud/Interface/Internal/InterfaceManager.AsReShadeAddon.cs b/Dalamud/Interface/Internal/InterfaceManager.AsReShadeAddon.cs
index c5131d3a0..73c0a4d15 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.AsReShadeAddon.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.AsReShadeAddon.cs
@@ -46,6 +46,14 @@ internal unsafe partial class InterfaceManager
this.RenderDalamudDraw(activeScene);
}
+ private void ReShadeAddonInterfaceOnReShadeOverlay(ref ReShadeAddonInterface.ApiObject runtime)
+ {
+ var swapChainNative = runtime.GetNative();
+
+ if (this.RenderDalamudCheckAndInitialize(swapChainNative, 0) is { } activeScene)
+ this.RenderDalamudDraw(activeScene);
+ }
+
private int AsReShadeAddonDxgiSwapChainResizeBuffersDetour(
IDXGISwapChain* swapChain,
uint bufferCount,
diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs
index 10703ad8d..313d0ae94 100644
--- a/Dalamud/Interface/Internal/InterfaceManager.cs
+++ b/Dalamud/Interface/Internal/InterfaceManager.cs
@@ -878,6 +878,7 @@ internal partial class InterfaceManager : IInternalDisposableService
switch (this.dalamudConfiguration.ReShadeHandlingMode)
{
// This is the only mode honored when SwapChainHookMode is set to VTable.
+ case ReShadeHandlingMode.Default:
case ReShadeHandlingMode.UnwrapReShade when ReShadeAddonInterface.ReShadeModule is not null:
if (SwapChainHelper.UnwrapReShade())
Log.Information("Unwrapped ReShade");
@@ -896,7 +897,8 @@ internal partial class InterfaceManager : IInternalDisposableService
break;
// Register Dalamud as a ReShade addon.
- case ReShadeHandlingMode.ReShadeAddon:
+ case ReShadeHandlingMode.ReShadeAddonPresent:
+ case ReShadeHandlingMode.ReShadeAddonReShadeOverlay:
if (!ReShadeAddonInterface.TryRegisterAddon(out this.reShadeAddonInterface))
{
Log.Warning("Could not register as ReShade addon");
@@ -906,13 +908,15 @@ internal partial class InterfaceManager : IInternalDisposableService
Log.Information("Registered as a ReShade addon");
this.reShadeAddonInterface.InitSwapChain += this.ReShadeAddonInterfaceOnInitSwapChain;
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;
break;
// Hook ReShade's DXGISwapChain::on_present. This is the legacy and the default option.
- case ReShadeHandlingMode.Default:
case ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent:
pfnReShadeDxgiSwapChainPresent = ReShadeAddonInterface.FindReShadeDxgiSwapChainOnPresent();
diff --git a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.cs b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.cs
index cb4c04afa..9062a6a1b 100644
--- a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.cs
+++ b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeAddonInterface.cs
@@ -22,6 +22,7 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
private readonly Hook addonModuleResolverHook;
private readonly DelegateStorage presentDelegate;
+ private readonly DelegateStorage reShadeOverlayDelegate;
private readonly DelegateStorage initSwapChainDelegate;
private readonly DelegateStorage destroySwapChainDelegate;
@@ -61,6 +62,9 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
pSourceRect is null ? default : new(pSourceRect, 1),
pDestRect is null ? default : new(pDestRect, 1),
new(pDirtyRects, (int)dirtyRectCount))));
+ Exports.ReShadeRegisterEvent(
+ AddonEvent.ReShadeOverlay,
+ this.reShadeOverlayDelegate = new((ref ApiObject rt) => this.ReShadeOverlay?.Invoke(ref rt)));
Exports.ReShadeRegisterEvent(
AddonEvent.InitSwapChain,
this.initSwapChainDelegate = new((ref ApiObject rt) => this.InitSwapChain?.Invoke(ref rt)));
@@ -104,6 +108,10 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
ReadOnlySpan destRect,
ReadOnlySpan dirtyRects);
+ /// Delegate for .
+ /// Reference to the ReShade runtime.
+ public delegate void ReShadeOverlayDelegate(ref ApiObject effectRuntime);
+
/// Delegate for .
/// Reference to the ReShade SwapChain wrapper.
public delegate void ReShadeInitSwapChain(ref ApiObject swapChain);
@@ -132,6 +140,9 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
/// Called on .
public event PresentDelegate? Present;
+ /// Called on .
+ public event ReShadeOverlayDelegate? ReShadeOverlay;
+
/// Called on .
public event ReShadeInitSwapChain? InitSwapChain;
@@ -181,7 +192,8 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
return this.addonModuleResolverHook.Original(dwFlags, lpModuleName, phModule);
if (lpModuleName == this.initSwapChainDelegate ||
lpModuleName == this.destroySwapChainDelegate ||
- lpModuleName == this.presentDelegate)
+ lpModuleName == this.presentDelegate ||
+ lpModuleName == this.reShadeOverlayDelegate)
{
*phModule = this.hDalamudModule;
return BOOL.TRUE;
diff --git a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeHandlingMode.cs b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeHandlingMode.cs
index 6ffba3878..b02fd630d 100644
--- a/Dalamud/Interface/Internal/ReShadeHandling/ReShadeHandlingMode.cs
+++ b/Dalamud/Interface/Internal/ReShadeHandling/ReShadeHandlingMode.cs
@@ -9,8 +9,13 @@ internal enum ReShadeHandlingMode
/// Unwrap ReShade from the swap chain obtained from the game.
UnwrapReShade,
- /// Register as a ReShade addon, and draw on reshade_overlay event.
- ReShadeAddon,
+ /// Register as a ReShade addon, and draw on event.
+ ///
+ ReShadeAddonPresent,
+
+ /// Register as a ReShade addon, and draw on
+ /// event.
+ ReShadeAddonReShadeOverlay,
/// Hook DXGISwapChain::on_present(UINT flags, const DXGI_PRESENT_PARAMETERS *params) in
/// dxgi_swapchain.cpp.
diff --git a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs
index 6da89004b..d3298f61a 100644
--- a/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs
+++ b/Dalamud/Interface/Internal/Windows/Settings/Tabs/SettingsTabExperimental.cs
@@ -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."),
c => c.ReShadeHandlingMode,
(v, c) => c.ReShadeHandlingMode = v,
- fallbackValue: ReShadeHandlingMode.ReShadeAddon,
+ fallbackValue: ReShadeHandlingMode.Default,
warning: static rshm =>
- rshm is ReShadeHandlingMode.UnwrapReShade or ReShadeHandlingMode.None
+ rshm is ReShadeHandlingMode.UnwrapReShade or ReShadeHandlingMode.None ||
+ Service.Get().SwapChainHookMode == SwapChainHelper.HookMode.ByteCode
? null
- : Loc.Localize(
- "DalamudSettingsReShadeHandlingModeIgnoredVTableHookMode",
- "Current option will be ignored and no special ReShade handling will be done, because SwapChain vtable hook mode is set."))
+ : "Current option will be ignored and no special ReShade handling will be done, because SwapChain vtable hook mode is set.")
{
FriendlyEnumNameGetter = x => x switch
{
- ReShadeHandlingMode.Default => Loc.Localize(
- "DalamudSettingsReShadeHandlingModeDefault",
- "Default"),
- ReShadeHandlingMode.UnwrapReShade => Loc.Localize(
- "DalamudSettingsReShadeHandlingModeUnwrapReShade",
- "Unwrap ReShade"),
- ReShadeHandlingMode.ReShadeAddon => Loc.Localize(
- "DalamudSettingsReShadeHandlingModeReShadeAddon",
- "ReShade addon"),
- ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent => Loc.Localize(
- "DalamudSettingsReShadeHandlingModeHookReShadeDxgiSwapChainOnPresent",
- "Hook ReShade DXGISwapChain::OnPresent"),
- ReShadeHandlingMode.None => Loc.Localize(
- "DalamudSettingsReShadeHandlingModeNone",
- "Do not handle"),
- _ => "",
- },
- 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."),
+ ReShadeHandlingMode.Default => "Default",
+ ReShadeHandlingMode.UnwrapReShade => "Unwrap",
+ ReShadeHandlingMode.ReShadeAddonPresent => "ReShade Addon (present)",
+ ReShadeHandlingMode.ReShadeAddonReShadeOverlay => "ReShade Addon (reshade_overlay)",
+ ReShadeHandlingMode.HookReShadeDxgiSwapChainOnPresent => "Hook ReShade::DXGISwapChain::OnPresent",
+ ReShadeHandlingMode.None => "Do not handle",
_ => "",
},
},