diff --git a/CustomResolution2782/ConfigurationEnums.cs b/CustomResolution2782/ConfigurationEnums.cs
index 68b11b0..e6a96b1 100644
--- a/CustomResolution2782/ConfigurationEnums.cs
+++ b/CustomResolution2782/ConfigurationEnums.cs
@@ -117,16 +117,27 @@ public static class MinSizeModeExt
public enum ResolutionScalingMode
{
- Fast = 0,
- FSR = 1,
- DLSS = 2
+ Point = 0,
+ Linear = 1,
+ FSR = 2,
+ DLSS = 3
}
public static class ResolutionScalingModeExt
{
+ public static byte ToXIV(this ResolutionScalingMode mode) => mode switch
+ {
+ ResolutionScalingMode.Point => 0,
+ ResolutionScalingMode.Linear => 0,
+ ResolutionScalingMode.FSR => 1,
+ ResolutionScalingMode.DLSS => 2,
+ _ => 0
+ };
+
public static string ToHumanNameString(this ResolutionScalingMode mode) => mode switch
{
- ResolutionScalingMode.Fast => "Fast Pixelation",
+ ResolutionScalingMode.Point => "Pixelated",
+ ResolutionScalingMode.Linear => "Blurry Pixelated",
ResolutionScalingMode.FSR => "AMD FSR",
ResolutionScalingMode.DLSS => "NVIDIA DLSS",
_ => mode.ToString(),
@@ -134,7 +145,8 @@ public static class ResolutionScalingModeExt
public static string? ToHumanInfoString(this ResolutionScalingMode mode) => mode switch
{
- ResolutionScalingMode.Fast => "Lowest quality option which results in blurry pixelation.",
+ ResolutionScalingMode.Point => "Low quality option which results in pixelation.",
+ ResolutionScalingMode.Linear => "Low quality option which results in blurry pixelation.",
ResolutionScalingMode.FSR => "Upscaling which works on any GPU for low performance overhead.",
ResolutionScalingMode.DLSS => "DLSS in FFXIV is buggy, even without any plugins.",
_ => null
diff --git a/CustomResolution2782/CustomResolution2782.csproj b/CustomResolution2782/CustomResolution2782.csproj
index d3de3a4..0abb272 100644
--- a/CustomResolution2782/CustomResolution2782.csproj
+++ b/CustomResolution2782/CustomResolution2782.csproj
@@ -19,6 +19,7 @@
false
true
CustomResolution
+ true
@@ -30,7 +31,6 @@
-
$(DalamudLibPath)FFXIVClientStructs.dll
false
@@ -71,9 +71,11 @@
$(DalamudLibPath)SharpDX.Mathematics.dll
false
-
+
+ $(DalamudLibPath)TerraFX.Interop.Windows.dll
+ false
+
-
diff --git a/CustomResolution2782/DisplaySizeState.cs b/CustomResolution2782/DisplaySizeState.cs
index a16a048..e1bd7d5 100644
--- a/CustomResolution2782/DisplaySizeState.cs
+++ b/CustomResolution2782/DisplaySizeState.cs
@@ -6,6 +6,7 @@ using FloppyUtils;
using System;
using System.Runtime.InteropServices;
using System.Text;
+using TerraFX.Interop.DirectX;
using TerraFX.Interop.Windows;
using static TerraFX.Interop.Windows.Windows;
@@ -421,13 +422,14 @@ public unsafe struct DeviceEx
public ref uint NewHeight => ref _.NewHeight;
// C# doesn't let us use ptr types as generic arguments, oh well.
+ public readonly ID3D11DeviceContext* D3D11DeviceContext => (ID3D11DeviceContext*) _.D3D11DeviceContext;
public readonly ImmediateContextEx* ImmediateContext => (ImmediateContextEx*) _.ImmediateContext;
}
// ImmediateContextEx in FFXIVClientStructs is a bare minimum.
// https://github.com/aers/FFXIVClientStructs/blob/ef5e9a5997671fb2c9a72cb9d57d841855f62085/FFXIVClientStructs/FFXIV/Client/Graphics/Kernel/ImmediateContext.cs
[StructLayout(LayoutKind.Explicit)]
-public struct ImmediateContextEx
+public unsafe struct ImmediateContextEx
{
[FieldOffset(0)]
public ImmediateContext _;
diff --git a/CustomResolution2782/GameSizeState.cs b/CustomResolution2782/GameSizeState.cs
index 04afe9c..440300e 100644
--- a/CustomResolution2782/GameSizeState.cs
+++ b/CustomResolution2782/GameSizeState.cs
@@ -4,10 +4,13 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FloppyUtils;
+using SharpDX;
using System;
using System.Runtime.InteropServices;
using System.Text;
-using TerraFX.Interop.Windows;
+using TerraFX.Interop.DirectX;
+using Device = FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Device;
+using SDX11 = SharpDX.Direct3D11;
namespace CustomResolution;
@@ -17,17 +20,42 @@ public unsafe class GameSizeState : IDisposable
private Hook _rtmApplyScalingHook;
private Hook _rtmDestroyAfterResizeHook;
private Hook _rtmRegenAfterResizeHook;
- private Hook _icdx11ProcessCommandsHook;
+ private Hook _immediateProcessCommandsHook;
private Hook _ddx11PostTickHook;
private Hook _taskRenderGraphicsRenderHook;
+ private Hook _prepareTextureHook;
+ private Hook _immediatePreparePSHook;
+ private Hook _immediatePrepareCSHook;
+ private Hook _createTexture2DHook;
+ private Hook _drawHook;
+
+ private SDX11.DeviceContext _d3dctx;
+ private SDX11.Device _d3ddev;
+ private SDX11.SamplerState _samplerMips;
+ private SDX11.SamplerState _samplerPoint;
private bool _wasEnabled = false;
private object _renderLock = new();
private ForceUpdateRTMState _forceUpdateRTM = ForceUpdateRTMState._0_Idle;
+ private uint _gameplayDrawCount = 0;
+ private GameplayDrawState _gameplayDrawState = GameplayDrawState.None;
+
public GameSizeState()
{
+ var dev = (DeviceEx*) Device.Instance();
+ _d3dctx = CppObject.FromPointer((nint) dev->D3D11DeviceContext);
+ _d3ddev = _d3dctx.Device;
+
+ var samplerDesc = SDX11.SamplerStateDescription.Default();
+ samplerDesc.Filter = SDX11.Filter.MinMagMipLinear;
+ _samplerMips = new(_d3ddev, samplerDesc);
+ samplerDesc.Filter = SDX11.Filter.MinMagMipPoint;
+ samplerDesc.MinimumLod = 0;
+ samplerDesc.MaximumLod = 0;
+ _samplerPoint = new(_d3ddev, samplerDesc);
+
/* Writes DynamicResolutionTargetHeight to size[1] near the end,
* but if in (gpose || main menu), only scale < 1??
*/
@@ -37,8 +65,6 @@ public unsafe class GameSizeState : IDisposable
);
_rtmApplyScalingHook.Enable();
- var dev = (DeviceEx*) Device.Instance();
-
/* Device.RequestResolutionChange and other triggers run some callbacks, namely
* (at the time of 7.2) 0x40 for RTM destruction and 0x48 for RTM reconstruction,
* registered in RTM init and run in PostTick.
@@ -70,11 +96,11 @@ public unsafe class GameSizeState : IDisposable
* with some other race conditions regarding the fields we modify.
* Let's wrap it in a C# lock and call it a day...
*/
- _icdx11ProcessCommandsHook = Service.GameInteropProvider.HookFromAddress(
+ _immediateProcessCommandsHook = Service.GameInteropProvider.HookFromAddress(
Service.SigScanner.ScanText("48 89 5C 24 10 48 89 6C 24 18 56 57 41 56 48 83 EC 30 48 8B 01 41 8B F0 48 8B EA"),
- ICDX11ProcessCommandsDetour
+ ImmediateProcessCommandsDetour
);
- _icdx11ProcessCommandsHook.Enable();
+ _immediateProcessCommandsHook.Enable();
_ddx11PostTickHook = Service.GameInteropProvider.HookFromAddress(
Service.SigScanner.ScanText("48 89 5C 24 10 48 89 6C 24 18 48 89 74 24 20 57 41 54 41 55 41 56 41 57 B8 30 43 00 00 ?? ?? ?? ?? ?? 48 2B E0 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? 00 00 8B 15"),
@@ -100,6 +126,43 @@ public unsafe class GameSizeState : IDisposable
TaskRenderGraphicsRenderDetour
);
_taskRenderGraphicsRenderHook.Enable();
+
+ /* Texture preparation used in a lot of places, but most notable for
+ * writing to the mip level count of the gameplay texture and also updating the D3D11 ptrs.
+ */
+ _prepareTextureHook = Service.GameInteropProvider.HookFromAddress(
+ Service.SigScanner.ScanText("40 53 48 83 EC 20 48 8B 02 48 8B D9 48 89 41 38 48 8B 02 48 89 41 40"),
+ PrepareTextureDetour
+ );
+ _prepareTextureHook.Enable();
+
+ /* The shader resource view of GameplayTexture gets read by these two.
+ */
+ _immediatePreparePSHook = Service.GameInteropProvider.HookFromAddress(
+ Service.SigScanner.ScanText("48 8B C4 4C 89 40 18 48 89 48 08 53 56 48 83 EC 68 44 8B 5A 44 48 8D B1 E8 03 00 00 4C 89 68 D8"),
+ ImmediatePreparePSDetour
+ );
+ _immediatePreparePSHook.Enable();
+ _immediatePrepareCSHook = Service.GameInteropProvider.HookFromAddress(
+ Service.SigScanner.ScanText("48 8B C4 4C 89 40 18 48 89 48 08 53 56 48 83 EC 68 44 8B 5A 44 48 8D B1 E8 13 00 00 4C 89 68 D8"),
+ ImmediatePrepareCSDetour
+ );
+ _immediatePrepareCSHook.Enable();
+
+ /* And because all that isn't bad enough:
+ * Hook ID3D11Device funcs based on their vtable indices, to allow mipmap generation,
+ * and to allow changing the sampler state before drawing.
+ */
+ _createTexture2DHook = Service.GameInteropProvider.HookFromAddress(
+ ((ID3D11Device*) _d3ddev.NativePointer)->lpVtbl[5],
+ CreateTexture2DDetour
+ );
+ _createTexture2DHook.Enable();
+ _drawHook = Service.GameInteropProvider.HookFromAddress(
+ ((ID3D11DeviceContext*) _d3dctx.NativePointer)->lpVtbl[13],
+ DrawDetour
+ );
+ _drawHook.Enable();
}
public bool ConfigDynRezo { get; private set; }
@@ -121,7 +184,7 @@ public unsafe class GameSizeState : IDisposable
private delegate void RTMRegenAfterResize();
// [UnmanagedFunctionPointer(CallingConvention.FastCall)]
- private delegate void ICDX11ProcessCommands(ImmediateContext* ctx, RenderCommandBufferGroup* cmds, uint count);
+ private delegate void ImmediateProcessCommands(ImmediateContext* ctx, RenderCommandBufferGroup* cmds, uint count);
// [UnmanagedFunctionPointer(CallingConvention.FastCall)]
private delegate void DDX11PostTick(DeviceEx* dev);
@@ -129,14 +192,35 @@ public unsafe class GameSizeState : IDisposable
// [UnmanagedFunctionPointer(CallingConvention.FastCall)]
private delegate void TaskRenderGraphicsRender();
+ // [UnmanagedFunctionPointer(CallingConvention.FastCall)]
+ private delegate ulong PrepareTexture(Texture* tex, uint* size, byte mips, uint format);
+
+ // [UnmanagedFunctionPointer(CallingConvention.FastCall)]
+ private delegate void ImmediatePreparePS(ImmediateContextEx* im, PixelShader* ps, ImmediateBlitResource* data);
+
+ // [UnmanagedFunctionPointer(CallingConvention.FastCall)]
+ private delegate void ImmediatePrepareCS(ImmediateContextEx* im, Shader* cs, ImmediateBlitResource* data);
+
+ private delegate int CreateTexture2D(ID3D11Device* d3ddev, D3D11_TEXTURE2D_DESC* desc, D3D11_SUBRESOURCE_DATA* initialData, ID3D11Texture2D** tex);
+
+ private delegate void Draw(ID3D11DeviceContext* d3dctx, uint vertexCount, uint startVertexPosition);
+
public void Dispose()
{
_rtmApplyScalingHook.Dispose();
_rtmDestroyAfterResizeHook.Dispose();
_rtmRegenAfterResizeHook.Dispose();
- _icdx11ProcessCommandsHook.Dispose();
+ _immediateProcessCommandsHook.Dispose();
_ddx11PostTickHook.Dispose();
_taskRenderGraphicsRenderHook.Dispose();
+ _prepareTextureHook.Dispose();
+ _immediatePreparePSHook.Dispose();
+ _immediatePrepareCSHook.Dispose();
+ _createTexture2DHook.Dispose();
+ _drawHook.Dispose();
+ _samplerPoint.Dispose();
+ _samplerMips.Dispose();
+ _d3ddev.Dispose();
Service.Framework.RunOnFrameworkThread(Update);
}
@@ -159,7 +243,7 @@ public unsafe class GameSizeState : IDisposable
{
_dbg.Append(@$"RTMApplyScaling 0x{(_rtmApplyScalingHook.IsDisposed ? null : _rtmApplyScalingHook.Address):X16}
RTMRegenAfterResize 0x{(_rtmRegenAfterResizeHook.IsDisposed ? null : _rtmRegenAfterResizeHook.Address):X16}
-ICDX11ProcessCommands 0x{(_icdx11ProcessCommandsHook.IsDisposed ? null : _icdx11ProcessCommandsHook.Address):X16}
+ImmediateProcessCommands 0x{(_immediateProcessCommandsHook.IsDisposed ? null : _immediateProcessCommandsHook.Address):X16}
DR !{gfx->DynamicRezoEnable} +{gfx->DynamicRezoEnableBeyond1} _{gfx->DynamicRezoEnableCutScene} ?{gfx->DynamicRezoEnableUnkx47} ?{gfx->DynamicRezoEnableUnkx48}
GR x{gfx->GraphicsRezoScale} ?{gfx->GraphicsRezoUnk1} _{gfx->GraphicsRezoUpscaleType} ?{gfx->GraphicsRezoUnk2}
DEV 0x{(long) (nint) dev:X16}
@@ -181,7 +265,7 @@ RR {dev->RequestRender} 0x{(long) dev->ImmediateContext->IfNonZeroSkipPostTickPr
gfx->DynamicRezoEnable = (byte) (ConfigDynRezo || enabled ? 1 : 0);
if (enabled)
{
- gfx->GraphicsRezoUpscaleType = (byte) (cfg.Scale <= 1f ? Service.Config._.ResolutionScalingMode : ResolutionScalingMode.Fast);
+ gfx->GraphicsRezoUpscaleType = cfg.Scale <= 1f ? Service.Config._.ResolutionScalingMode.ToXIV() : ResolutionScalingMode.Linear.ToXIV();
rtm->DynamicResolutionMinimumHeight = rtm->DynamicResolutionMaximumHeight;
}
else
@@ -194,9 +278,8 @@ RR {dev->RequestRender} 0x{(long) dev->ImmediateContext->IfNonZeroSkipPostTickPr
var scale = MathF.Max(1f, enabled ? cfg.Scale : 1f);
GetScaledWidthHeight(dev->Width, dev->Height, scale, out var widthS, out var heightS);
- // TODO: Figure out a more consistent way to get to the currently allocated size.
// Check if the backing RTs are the expected size.
- var tex = rtm->_.Unk20[0].Value;
+ var tex = rtm->GameplayTexture;
if (tex->AllocatedWidth != widthS || tex->AllocatedHeight != heightS)
{
if (!unloading)
@@ -295,7 +378,7 @@ RR {dev->RequestRender} 0x{(long) dev->ImmediateContext->IfNonZeroSkipPostTickPr
Service.PluginLog.Debug($"Destroying RTM resources");
byte rv = _rtmDestroyAfterResizeHook.OriginalDisposeSafe();
- Service.PluginLog.Debug($"After: 0x{(long) (nint) rtm->_.Unk20[0].Value->D3D11Texture2D:X16}");
+ Service.PluginLog.Debug($"After: {rv} 0x{(long) (nint) rtm->GameplayTexture->D3D11Texture2D:X16}");
return rv;
}
@@ -314,14 +397,16 @@ RR {dev->RequestRender} 0x{(long) dev->ImmediateContext->IfNonZeroSkipPostTickPr
using var scale = new ScaleState();
Service.PluginLog.Debug($"Regenerating RTM resources: {dev->Width} x {dev->Height}");
_rtmRegenAfterResizeHook.OriginalDisposeSafe();
- Service.PluginLog.Debug($"After: 0x{(long) (nint) rtm->_.Unk20[0].Value->D3D11Texture2D:X16}");
+ Service.PluginLog.Debug($"After: 0x{(long) (nint) rtm->GameplayTexture->D3D11Texture2D:X16}");
}
- private void ICDX11ProcessCommandsDetour(ImmediateContext* ctx, RenderCommandBufferGroup* cmds, uint count)
+ private void ImmediateProcessCommandsDetour(ImmediateContext* ctx, RenderCommandBufferGroup* cmds, uint count)
{
+ _gameplayDrawCount = 0;
+
lock (_renderLock)
{
- _icdx11ProcessCommandsHook.OriginalDisposeSafe(ctx, cmds, count);
+ _immediateProcessCommandsHook.OriginalDisposeSafe(ctx, cmds, count);
}
}
@@ -346,6 +431,112 @@ RR {dev->RequestRender} 0x{(long) dev->ImmediateContext->IfNonZeroSkipPostTickPr
}
}
+ private ulong PrepareTextureDetour(Texture* tex, uint* size, byte mips, uint format)
+ {
+ var rtm = (RenderTargetManagerEx*) RenderTargetManager.Instance();
+ if (tex != rtm->GameplayTexture)
+ {
+ return _prepareTextureHook.OriginalDisposeSafe(tex, size, mips, format);
+ }
+
+ ref var cfg = ref Service.Config._;
+
+ if (!Service.Plugin.Unloading && cfg.Game.IsEnabled && cfg.Game.Scale > 2f)
+ {
+ mips = (byte) MathF.Ceiling(MathF.Log2(cfg.Game.Scale));
+ }
+
+ Service.PluginLog.Debug($"Preparing gameplay texture 0x{(long) (nint) tex:X16} with {mips} mips, currently 0x{(long) (nint) tex->D3D11Texture2D:X16}");
+ var rv = _prepareTextureHook.OriginalDisposeSafe(tex, size, mips, format);
+ Service.PluginLog.Debug($"After: 0x{rv:X16} 0x{(long) (nint) tex->D3D11Texture2D:X16} 0x{(long) (nint) tex->D3D11ShaderResourceView:X16}");
+ return rv;
+ }
+
+ private void ImmediatePreparePSDetour(ImmediateContextEx* im, PixelShader* ps, ImmediateBlitResource* data)
+ {
+ var rtm = (RenderTargetManagerEx*) RenderTargetManager.Instance();
+ var tex = rtm->GameplayTexture;
+ if (ps->Shader.SamplerCount >= 1 && data[0].Texture == tex)
+ {
+ _gameplayDrawCount++;
+
+ var gfx = (GraphicsConfigEx*) GraphicsConfig.Instance();
+ if ((gfx->GraphicsRezoUpscaleType == (byte) ResolutionScalingMode.FSR && gfx->GraphicsRezoScale < 1f) ||
+ gfx->GraphicsRezoUpscaleType == (byte) ResolutionScalingMode.DLSS)
+ {
+ // IF you think this is useful to you, maybe check out the feature-minishader branch.
+ // _drawIsGameplay = _gameplayDrawCount == 1;
+ }
+ else if (_gameplayDrawCount == 3)
+ {
+ if (Service.Config._.ResolutionScalingMode == ResolutionScalingMode.Point)
+ {
+ _gameplayDrawState = GameplayDrawState.ForcePoint;
+ }
+ else if (tex->MipLevel != 1)
+ {
+ _gameplayDrawState = GameplayDrawState.ForceMips;
+ }
+ }
+ }
+
+ _immediatePreparePSHook.OriginalDisposeSafe(im, ps, data);
+ }
+
+ private void ImmediatePrepareCSDetour(ImmediateContextEx* im, Shader* cs, ImmediateBlitResource* data)
+ {
+ var rtm = (RenderTargetManagerEx*) RenderTargetManager.Instance();
+ if (((PixelShader*) cs)->Shader.SamplerCount >= 1 && data[0].Texture == rtm->GameplayTexture)
+ {
+ _gameplayDrawCount++;
+ }
+
+ _immediatePrepareCSHook.OriginalDisposeSafe(im, cs, data);
+ }
+
+ private int CreateTexture2DDetour(ID3D11Device* d3ddev, D3D11_TEXTURE2D_DESC* desc, D3D11_SUBRESOURCE_DATA* initialData, ID3D11Texture2D** tex)
+ {
+ var rtm = (RenderTargetManagerEx*) RenderTargetManager.Instance();
+ if (tex != &rtm->GameplayTexture->D3D11Texture2D)
+ {
+ return _createTexture2DHook.OriginalDisposeSafe(d3ddev, desc, initialData, tex);
+ }
+
+ if (rtm->GameplayTexture->MipLevel != 1)
+ {
+ desc->MiscFlags |= (uint) D3D11_RESOURCE_MISC_FLAG.D3D11_RESOURCE_MISC_GENERATE_MIPS;
+ }
+
+ return _createTexture2DHook.OriginalDisposeSafe(d3ddev, desc, initialData, tex);
+ }
+
+ private void DrawDetour(ID3D11DeviceContext* d3dctx, uint vertexCount, uint startVertexPosition)
+ {
+ if (_gameplayDrawState == GameplayDrawState.None)
+ {
+ _drawHook.OriginalDisposeSafe(d3dctx, vertexCount, startVertexPosition);
+ return;
+ }
+
+ var state = _gameplayDrawState;
+ _gameplayDrawState = GameplayDrawState.None;
+
+ var rtm = (RenderTargetManagerEx*) RenderTargetManager.Instance();
+
+ switch (state)
+ {
+ case GameplayDrawState.ForceMips:
+ _d3dctx.PixelShader.SetSampler(0, _samplerMips);
+ _d3dctx.GenerateMips(CppObject.FromPointer((nint) rtm->GameplayTexture->D3D11ShaderResourceView));
+ break;
+ case GameplayDrawState.ForcePoint:
+ _d3dctx.PixelShader.SetSampler(0, _samplerPoint);
+ break;
+ }
+
+ _drawHook.OriginalDisposeSafe(d3dctx, vertexCount, startVertexPosition);
+ }
+
private enum ForceUpdateRTMState
{
_0_Idle,
@@ -353,6 +544,13 @@ RR {dev->RequestRender} 0x{(long) dev->ImmediateContext->IfNonZeroSkipPostTickPr
_2_ToScale
}
+ private enum GameplayDrawState
+ {
+ None,
+ ForceMips,
+ ForcePoint
+ }
+
private struct ScaleState : IDisposable
{
public uint Width;
@@ -406,6 +604,18 @@ public unsafe struct RenderTargetManagerEx
[FieldOffset(0)]
public RenderTargetManager _;
+ // Gets blitted FROM after actual gameplay texture. Actual purpose unknown.
+ [FieldOffset(0x68)]
+ public Texture* GameplayTextureUnk1;
+
+ // Gets blitted TO after actual gameplay texture, using Unk1. Actual purpose unknown.
+ [FieldOffset(0x100)]
+ public Texture* GameplayTextureUnk2;
+
+ // Gets blitted to backbuffer.
+ [FieldOffset(0x258)]
+ public Texture* GameplayTexture;
+
[FieldOffset(0x428)]
public uint Resolution_Width;
[FieldOffset(0x428 + 0x4)]
@@ -431,3 +641,21 @@ public unsafe struct RenderTargetManagerEx
[FieldOffset(0x70C + 4 * 4)]
public float GraphicsRezoScaleUnk2;
}
+
+[StructLayout(LayoutKind.Explicit, Size = 0x18)]
+public unsafe struct ImmediateBlitResource
+{
+ // D3D11ShaderResourceView must be at 0x58 + (GlobalIndex % 3) * 8
+ // Smells like something swapchain-adjacent, but have yet to analyze anything with != null.
+ [FieldOffset(0x0)]
+ public nint Unkx0;
+
+ [FieldOffset(0x8)]
+ public Texture* Texture;
+
+ [FieldOffset(0x10)]
+ public uint Unkx10;
+
+ [FieldOffset(0x14)]
+ public uint Unkx14;
+}
diff --git a/CustomResolution2782/Plugin.cs b/CustomResolution2782/Plugin.cs
index 62893ca..22e0ee8 100644
--- a/CustomResolution2782/Plugin.cs
+++ b/CustomResolution2782/Plugin.cs
@@ -2,7 +2,6 @@
using Dalamud.Game.Config;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
-using FFXIVClientStructs.FFXIV.Client.System.Framework;
using ImGuiNET;
using System;
using System.Collections.Generic;
diff --git a/CustomResolution2782/Windows/ConfigWindow.cs b/CustomResolution2782/Windows/ConfigWindow.cs
index ab251ac..a249a0a 100644
--- a/CustomResolution2782/Windows/ConfigWindow.cs
+++ b/CustomResolution2782/Windows/ConfigWindow.cs
@@ -154,16 +154,7 @@ Changed via /gres");
DrawSizeTabShared(ref _.Game, "Game", scaleOnly: true);
- using (_.Game.Scale > 2f ? ImRaii.PushColor(ImGuiCol.Border, 0xff00ffff) : null)
- {
- ImGui.InputFloat("Scale", ref _.Game.Scale, 0.01f, 0.1f, "%.3f", ImGuiInputTextFlags.None);
- }
-
- if (_.Game.Scale > 2f && ImGui.IsItemHovered())
- {
- ImGui.SetTooltip(@"Scaling larger than 2x currently doesn't improve antialiasing!
-This is still being worked on before the v1.0 release.");
- }
+ ImGui.InputFloat("Scale", ref _.Game.Scale, 0.01f, 0.1f, "%.3f", ImGuiInputTextFlags.None);
if (ImGui.BeginCombo("Graphics Upscaling", _.ResolutionScalingMode.ToHumanNameString()))
{
diff --git a/CustomResolution2782/packages.lock.json b/CustomResolution2782/packages.lock.json
index 6b40e5f..57051b7 100644
--- a/CustomResolution2782/packages.lock.json
+++ b/CustomResolution2782/packages.lock.json
@@ -8,27 +8,6 @@
"resolved": "12.0.0",
"contentHash": "J5TJLV3f16T/E2H2P17ClWjtfEBPpq3yxvqW46eN36JCm6wR+EaoaYkqG9Rm5sHqs3/nK/vKjWWyvEs/jhKoXw=="
},
- "SharpDX.D3DCompiler": {
- "type": "Direct",
- "requested": "[4.2.0, )",
- "resolved": "4.2.0",
- "contentHash": "Rnsd6Ilp127xbXqhTit8WKFQUrXwWxqVGpglyWDNkIBCk0tWXNQEjrJpsl0KAObzyZaa33+EXAikLVt5fnd3GA==",
- "dependencies": {
- "NETStandard.Library": "1.6.1",
- "SharpDX": "4.2.0"
- }
- },
- "SharpDX.Direct2D1": {
- "type": "Direct",
- "requested": "[4.2.0, )",
- "resolved": "4.2.0",
- "contentHash": "Qs8LzDMaQf1u3KB8ArHu9pDv6itZ++QXs99a/bVAG+nKr0Hx5NG4mcN5vsfE0mVR2TkeHfeUm4PksRah6VUPtA==",
- "dependencies": {
- "NETStandard.Library": "1.6.1",
- "SharpDX": "4.2.0",
- "SharpDX.DXGI": "4.2.0"
- }
- },
"SharpDX.Direct3D11": {
"type": "Direct",
"requested": "[4.2.0, )",
@@ -40,12 +19,6 @@
"SharpDX.DXGI": "4.2.0"
}
},
- "TerraFX.Interop.Windows": {
- "type": "Direct",
- "requested": "[10.0.22621.2, )",
- "resolved": "10.0.22621.2",
- "contentHash": "lORoYCoURS33Vi7PDvubRugLF2+l5v3rX2oVEqNhpBLjs3aZpqapRvTHPKVwsC+dGrsGuqJ/3yXuxVUb0vl3vg=="
- },
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
"resolved": "1.1.0",
diff --git a/README.md b/README.md
index a723a3f..d0be9e4 100644
--- a/README.md
+++ b/README.md
@@ -23,15 +23,6 @@ everything where it was while still allowing you to switch between game scaling
is that this does NOT affect the screenshot resolution.
-I'm scaling by 3x or higher, but I'm still getting jagged edges!
-The plugin currently only gives FFXIV a fake resolution to work with internally, but it doesn't ensure that the
-extra pixels land on your screen. When scaling the display resolution, those will still be used for in-game or ReShade screenshots though.
-
-Windows should perform basic filtering with 2x scaling (it might not work on some graphics cards?), and I haven't
-heard back from anyone using this on Linux yet. But an universal fix for this is possible - it just requires more
-time than I have on my hands right now.
-
-
I'm using DLSS, and my game looks pixelated / is small!
DLSS in FFXIV is bugged. No, I'm not joking: even without any plugins or mods loaded, it can glitch out when
simply resizing the window (most notably by rapidly pressing WinKey + Down and WinKey + Up).