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;
/// <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>
public SwapChainHelper.HookMode SwapChainHookMode { get; set; } = SwapChainHelper.HookMode.ByteCode;

View file

@ -46,6 +46,14 @@ internal unsafe partial class InterfaceManager
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(
IDXGISwapChain* swapChain,
uint bufferCount,

View file

@ -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();

View file

@ -22,6 +22,7 @@ internal sealed unsafe partial class ReShadeAddonInterface : IDisposable
private readonly Hook<GetModuleHandleExWDelegate> addonModuleResolverHook;
private readonly DelegateStorage<UnsafePresentDelegate> presentDelegate;
private readonly DelegateStorage<ReShadeOverlayDelegate> reShadeOverlayDelegate;
private readonly DelegateStorage<ReShadeInitSwapChain> initSwapChainDelegate;
private readonly DelegateStorage<ReShadeDestroySwapChain> 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<RECT> destRect,
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>
/// <param name="swapChain">Reference to the ReShade SwapChain wrapper.</param>
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>
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>
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;

View file

@ -9,8 +9,13 @@ internal enum ReShadeHandlingMode
/// <summary>Unwrap ReShade from the swap chain obtained from the game.</summary>
UnwrapReShade,
/// <summary>Register as a ReShade addon, and draw on reshade_overlay event.</summary>
ReShadeAddon,
/// <summary>Register as a ReShade addon, and draw on <see cref="ReShadeAddonInterface.AddonEvent.Present"/> event.
/// </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
/// <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."),
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<DalamudConfiguration>.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"),
_ => "<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."),
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",
_ => "<invalid>",
},
},