Initial commit - resize works

This commit is contained in:
Jade Macho 2024-02-14 00:05:07 +01:00
commit 056953c26e
Signed by: 0x0ade
GPG Key ID: E1960710FE4FBEEF
12 changed files with 526 additions and 0 deletions

52
CustomResolution/Cmd.cs Normal file
View File

@ -0,0 +1,52 @@
using Dalamud.Game.Command;
using Dalamud.Plugin.Services;
using System;
namespace CustomResolution;
public abstract class Cmd : IDisposable
{
private ICommandManager? _commandManager;
private string? _commandString;
public abstract string Name { get; }
public string FullName => _commandString ?? $"/{Name}";
public abstract string HelpMessage { get; }
public void Register(ICommandManager commandManager)
{
if (_commandManager is not null)
{
Dispose();
}
_commandManager = commandManager;
_commandString = FullName;
commandManager.AddHandler(FullName, new CommandInfo(Handle)
{
HelpMessage = HelpMessage
});
}
public abstract void Run(string arguments);
public void Dispose()
{
_commandManager?.RemoveHandler(FullName);
_commandManager = null;
GC.SuppressFinalize(this);
}
private void Handle(string command, string arguments)
{
if (command != _commandString)
{
return;
}
Run(arguments);
}
}

View File

@ -0,0 +1,43 @@
using Dalamud.Configuration;
using Dalamud.Plugin;
using System;
namespace CustomResolution;
[Serializable]
public class Configuration : IPluginConfiguration
{
public int Version { get; set; } = 0;
public bool IsScale = true;
public float Scale = 1f;
public uint Width = 1024;
public uint Height = 1024;
[NonSerialized]
private DalamudPluginInterface? pluginInterface;
internal void Initialize(DalamudPluginInterface pluginInterface)
{
this.pluginInterface = pluginInterface;
}
public void Save()
{
pluginInterface!.SavePluginConfig(this);
}
}
public enum CullingMode
{
None,
OnlyInFront,
OnlyInView
}
public enum DutyMode
{
Always,
OutsideContent,
InContent
}

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Authors>0x0ade</Authors>
<Company></Company>
<Version>0.1.0.0</Version>
<Description></Description>
<Copyright></Copyright>
<PackageProjectUrl></PackageProjectUrl>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<Platforms>x64</Platforms>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProduceReferenceAssembly>false</ProduceReferenceAssembly>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
<PropertyGroup>
<DalamudLibPath>$(appdata)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="2.1.12" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.49-beta">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<Reference Include="FFXIVClientStructs">
<HintPath>$(DalamudLibPath)FFXIVClientStructs.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>$(DalamudLibPath)Newtonsoft.Json.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Dalamud">
<HintPath>$(DalamudLibPath)Dalamud.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="ImGui.NET">
<HintPath>$(DalamudLibPath)ImGui.NET.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="ImGuiScene">
<HintPath>$(DalamudLibPath)ImGuiScene.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Lumina">
<HintPath>$(DalamudLibPath)Lumina.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="Lumina.Excel">
<HintPath>$(DalamudLibPath)Lumina.Excel.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Cmds\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,11 @@
{
"Name": "CustomResolution",
"InternalName": "CustomResolution2782",
"Author": "0x0ade",
"ApplicableVersion": "any",
"DalamudApiLevel": 9,
"Punchline": "Enforces a custom resolution for the game, similar to NVIDIA DSR.",
"Description": "Basic plugin that allows you to specify a custom resolution.",
"Tags": [ "dsr", "resolution", "dpi", "scale", "scaling" ],
"RepoUrl": "https://gitea.0x0a.de/0x0ade/DP-CustomResolution"
}

View File

@ -0,0 +1 @@
GetClientRect

View File

@ -0,0 +1,13 @@
namespace CustomResolution;
public sealed class OpenSettingsCmd : Cmd
{
public override string Name => "cres";
public override string HelpMessage => "Open the CustomResolution Settings";
public override void Run(string arguments)
{
Service.PluginUI.SettingsVisible = !Service.PluginUI.SettingsVisible;
}
}

125
CustomResolution/Plugin.cs Normal file
View File

@ -0,0 +1,125 @@
using Dalamud.IoC;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Win32;
using Windows.Win32.Foundation;
namespace CustomResolution;
public sealed unsafe class Plugin : IDalamudPlugin
{
private readonly List<Cmd> _cmds;
private bool _unloading = false;
private int _tickCount = 0;
public Plugin([RequiredVersion("1.0")] DalamudPluginInterface pluginInterface)
{
pluginInterface.Create<Service>();
Service.Plugin = this;
Service.Config = Service.PluginInterface.GetPluginConfig() as Configuration ?? new();
Service.Config.Initialize(Service.PluginInterface);
Service.PluginUI = new();
_cmds = typeof(Plugin).Assembly.GetTypes()
.Where(t => !t.IsAbstract && typeof(Cmd).IsAssignableFrom(t))
.Select(t => (Cmd) Activator.CreateInstance(t)!)
.ToList();
foreach (Cmd cmd in _cmds)
{
cmd.Register(Service.CommandManager);
}
Service.Framework.Update += OnFrameworkUpdate;
}
public string Name => "CustomResolution";
public uint CurrentWidth { get; private set; }
public uint CurrentHeight { get; private set; }
public uint CurrentWindowWidth { get; private set; }
public uint CurrentWindowHeight { get; private set; }
public void Dispose()
{
_tickCount = 0;
_unloading = true;
Service.Framework.Update -= OnFrameworkUpdate;
Service.Framework.RunOnFrameworkThread(Update);
foreach (Cmd cmd in _cmds)
{
cmd.Dispose();
}
Service.PluginUI.Dispose();
Service.Plugin = null!;
}
public void Update()
{
var dev = Device.Instance();
var width = dev->Width;
var height = dev->Height;
PInvoke.GetClientRect((HWND) (IntPtr) dev->hWnd, out var rect);
if (Service.Config.IsScale || _unloading)
{
var scale = _unloading ? 1f : Service.Config.Scale;
width = (uint) Math.Round(rect.Width * scale);
height = (uint) Math.Round(rect.Height * scale);
}
else
{
width = Service.Config.Width;
height = Service.Config.Height;
}
if (width != dev->Width || height != dev->Height)
{
if (width < 256)
{
width = 256;
}
if (height < 256)
{
height = 256;
}
dev->NewWidth = width;
dev->NewHeight = height;
dev->RequestResolutionChange = 1;
}
CurrentWidth = width;
CurrentHeight = height;
CurrentWindowWidth = (uint) rect.Width;
CurrentWindowHeight = (uint) rect.Height;
}
private void OnFrameworkUpdate(IFramework framework)
{
if (_tickCount++ >= 10)
{
_tickCount = 0;
Update();
}
_tickCount++;
}
}

View File

@ -0,0 +1,46 @@
using CustomResolution.Windows;
using Dalamud.Interface.Windowing;
using System;
namespace CustomResolution;
public sealed class PluginUI : IDisposable
{
private ConfigWindow _configWindow;
internal PluginUI()
{
Service.PluginInterface.UiBuilder.Draw += Draw;
Service.PluginInterface.UiBuilder.OpenConfigUi += ShowConfigWindow;
WindowSystem.AddWindow(_configWindow = new ConfigWindow());
}
public WindowSystem WindowSystem { get; } = new("CustomResolution");
public bool SettingsVisible
{
get => _configWindow.IsOpen;
set => _configWindow.IsOpen = value;
}
public void Dispose()
{
WindowSystem.RemoveAllWindows();
_configWindow.Dispose();
Service.PluginInterface.UiBuilder.Draw -= Draw;
Service.PluginInterface.UiBuilder.OpenConfigUi -= ShowConfigWindow;
}
public void Draw()
{
WindowSystem.Draw();
}
private void ShowConfigWindow()
{
}
}

View File

@ -0,0 +1,32 @@
using Dalamud.IoC;
using Dalamud.Plugin;
using System;
using Dalamud.Plugin.Services;
namespace CustomResolution;
public sealed class Service
{
public static Plugin Plugin { get; internal set; } = null!;
public static Configuration Config { get; internal set; } = null!;
public static PluginUI PluginUI { get; internal set; } = null!;
[PluginService]
public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService]
public static ICommandManager CommandManager { get; private set; } = null!;
[PluginService]
public static IFramework Framework { get; private set; } = null!;
[PluginService]
public static IClientState ClientState { get; private set; } = null!;
[PluginService]
public static IPluginLog PluginLog { get; private set; } = null!;
public static Func<string, object?>? GetPluginInstance { get; private set; }
}

View File

@ -0,0 +1,83 @@
using Dalamud.Interface.Windowing;
using ImGuiNET;
using System;
using System.Numerics;
namespace CustomResolution.Windows;
public class ConfigWindow : Window, IDisposable
{
private int[] _displayCurrentWH = new int[2];
private int[] _displayCurrentWindowWH = new int[2];
private bool _configIsScale;
private float _configScale;
private int[] _configWH = new int[2];
public ConfigWindow() : base(
"CustomResolution",
ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoScrollbar |
ImGuiWindowFlags.NoScrollWithMouse)
{
Size = new Vector2(430, 160);
SizeCondition = ImGuiCond.Always;
UpdateFromConfig();
}
public void Dispose() {
}
public void UpdateFromConfig()
{
var config = Service.Config;
_configIsScale = config.IsScale;
_configScale = config.Scale;
_configWH[0] = (int) config.Width;
_configWH[1] = (int) config.Height;
}
public void UpdateToConfig()
{
var config = Service.Config;
config.IsScale = _configIsScale;
config.Scale = _configScale;
config.Width = (uint) _configWH[0];
config.Height = (uint) _configWH[1];
config.Save();
}
public override void Draw()
{
var plugin = Service.Plugin;
_displayCurrentWH[0] = (int) plugin.CurrentWidth;
_displayCurrentWH[1] = (int) plugin.CurrentHeight;
_displayCurrentWindowWH[0] = (int) plugin.CurrentWindowWidth;
_displayCurrentWindowWH[1] = (int) plugin.CurrentWindowHeight;
ImGui.BeginDisabled();
ImGui.InputInt2("Current window size", ref _displayCurrentWindowWH[0]);
ImGui.InputInt2("Current render size", ref _displayCurrentWH[0]);
ImGui.EndDisabled();
ImGui.Checkbox("Use scale", ref _configIsScale);
if (_configIsScale)
{
ImGui.InputFloat("Scale", ref _configScale, 0.01f, 0.1f);
}
else
{
ImGui.InputInt2("Size in pixels", ref _configWH[0]);
}
if (ImGui.Button("Save and apply"))
{
UpdateToConfig();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,54 @@
{
"version": 1,
"dependencies": {
"net7.0-windows7.0": {
"DalamudPackager": {
"type": "Direct",
"requested": "[2.1.12, )",
"resolved": "2.1.12",
"contentHash": "Sc0PVxvgg4NQjcI8n10/VfUQBAS4O+Fw2pZrAqBdRMbthYGeogzu5+xmIGCGmsEZ/ukMOBuAqiNiB5qA3MRalg=="
},
"Microsoft.Windows.CsWin32": {
"type": "Direct",
"requested": "[0.3.49-beta, )",
"resolved": "0.3.49-beta",
"contentHash": "/iAXplVDKESFyLz/MShuVYVx62YFvFePpq3qrzREl8KScQqG6Z2kV7r9UJTjQS1g+hfy3V+e4m1x9lsu24YNSg==",
"dependencies": {
"Microsoft.Windows.SDK.Win32Docs": "0.1.42-alpha",
"Microsoft.Windows.SDK.Win32Metadata": "55.0.45-preview",
"Microsoft.Windows.WDK.Win32Metadata": "0.9.9-experimental",
"System.Memory": "4.5.5",
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"Microsoft.Windows.SDK.Win32Docs": {
"type": "Transitive",
"resolved": "0.1.42-alpha",
"contentHash": "Z/9po23gUA9aoukirh2ItMU2ZS9++Js9Gdds9fu5yuMojDrmArvY2y+tq9985tR3cxFxpZO1O35Wjfo0khj5HA=="
},
"Microsoft.Windows.SDK.Win32Metadata": {
"type": "Transitive",
"resolved": "55.0.45-preview",
"contentHash": "2i1kVIk8rMuMCYtoeYeWbmCRLqNgb63Berac3Gv+J/pjp0oucopasKgLQNslryhsgBl4xex9ENhJX2MXEW5vdA=="
},
"Microsoft.Windows.WDK.Win32Metadata": {
"type": "Transitive",
"resolved": "0.9.9-experimental",
"contentHash": "cncPlxLqR25mFOuvpxZPgXgJqRmXyV5eTULj/9w8AQvO/c1xJDEapohRsWkYaia7hCR/EwEzBHr7RU9u93T03w==",
"dependencies": {
"Microsoft.Windows.SDK.Win32Metadata": "55.0.45-preview"
}
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.5",
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
}
}
}
}