feat: add automatic UI hiding to GameGui, UiBuilder

This commit is contained in:
goat 2020-08-14 02:51:55 +02:00
parent b7e36fb2e6
commit 5f9efaaea0
5 changed files with 52 additions and 5 deletions

View file

@ -378,6 +378,9 @@ namespace Dalamud {
} }
} }
if (this.Framework.Gui.GameUiHidden)
return;
if (this.isImguiDrawLogWindow) if (this.isImguiDrawLogWindow)
{ {
this.isImguiDrawLogWindow = this.logWindow != null && this.logWindow.Draw(); this.isImguiDrawLogWindow = this.logWindow != null && this.logWindow.Draw();

View file

@ -44,6 +44,17 @@ namespace Dalamud.Game.Internal.Gui {
float *camPos, float *clipPos, float rayDistance, float *worldPos, int *unknown); float *camPos, float *clipPos, float rayDistance, float *worldPos, int *unknown);
private readonly ScreenToWorldNativeDelegate screenToWorldNative; private readonly ScreenToWorldNativeDelegate screenToWorldNative;
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate IntPtr ToggleUiHideDelegate(IntPtr thisPtr, byte unknownByte);
private readonly Hook<ToggleUiHideDelegate> toggleUiHideHook;
public bool GameUiHidden { get; private set; }
/// <summary>
/// Event which is fired when the game UI hiding is toggled.
/// </summary>
public event EventHandler<bool> OnUiHideToggled;
/// <summary> /// <summary>
/// The item ID that is currently hovered by the player. 0 when no item is hovered. /// The item ID that is currently hovered by the player. 0 when no item is hovered.
/// If > 1.000.000, subtract 1.000.000 and treat it as HQ /// If > 1.000.000, subtract 1.000.000 and treat it as HQ
@ -90,6 +101,8 @@ namespace Dalamud.Game.Internal.Gui {
this.screenToWorldNative = this.screenToWorldNative =
Marshal.GetDelegateForFunctionPointer<ScreenToWorldNativeDelegate>(Address.ScreenToWorld); Marshal.GetDelegateForFunctionPointer<ScreenToWorldNativeDelegate>(Address.ScreenToWorld);
this.toggleUiHideHook = new Hook<ToggleUiHideDelegate>(Address.ToggleUiHide, new ToggleUiHideDelegate(ToggleUiHideDetour), this);
} }
private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) { private IntPtr HandleSetGlobalBgmDetour(UInt16 bgmKey, byte a2, UInt32 a3, UInt32 a4, UInt32 a5, byte a6) {
@ -279,6 +292,20 @@ namespace Dalamud.Game.Internal.Gui {
return isSuccess; return isSuccess;
} }
private IntPtr ToggleUiHideDetour(IntPtr thisPtr, byte unknownByte) {
GameUiHidden = !GameUiHidden;
try {
OnUiHideToggled?.Invoke(this, GameUiHidden);
} catch (Exception ex) {
Log.Error(ex, "Error on OnUiHideToggled event dispatch");
}
Log.Debug("UiHide toggled: {0}", GameUiHidden);
return this.toggleUiHideHook.Original(thisPtr, unknownByte);
}
public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0); public void SetBgm(ushort bgmKey) => this.setGlobalBgmHook.Original(bgmKey, 0, 0, 0, 0, 0);
public void Enable() { public void Enable() {
@ -286,6 +313,7 @@ namespace Dalamud.Game.Internal.Gui {
this.setGlobalBgmHook.Enable(); this.setGlobalBgmHook.Enable();
this.handleItemHoverHook.Enable(); this.handleItemHoverHook.Enable();
this.handleItemOutHook.Enable(); this.handleItemOutHook.Enable();
this.toggleUiHideHook.Enable();
} }
public void Dispose() { public void Dispose() {
@ -293,6 +321,7 @@ namespace Dalamud.Game.Internal.Gui {
this.setGlobalBgmHook.Dispose(); this.setGlobalBgmHook.Dispose();
this.handleItemHoverHook.Dispose(); this.handleItemHoverHook.Dispose();
this.handleItemOutHook.Dispose(); this.handleItemOutHook.Dispose();
this.toggleUiHideHook.Dispose();
} }
} }
} }

View file

@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using Serilog; using Serilog;
namespace Dalamud.Game.Internal.Gui { namespace Dalamud.Game.Internal.Gui {
public sealed class GameGuiAddressResolver : BaseAddressResolver { internal sealed class GameGuiAddressResolver : BaseAddressResolver {
public IntPtr BaseAddress { get; private set; } public IntPtr BaseAddress { get; private set; }
public IntPtr ChatManager { get; private set; } public IntPtr ChatManager { get; private set; }
@ -14,6 +14,7 @@ namespace Dalamud.Game.Internal.Gui {
public IntPtr GetUIObject { get; private set; } public IntPtr GetUIObject { get; private set; }
public IntPtr GetMatrixSingleton { get; private set; } public IntPtr GetMatrixSingleton { get; private set; }
public IntPtr ScreenToWorld { get; private set; } public IntPtr ScreenToWorld { get; private set; }
public IntPtr ToggleUiHide { get; set; }
public GameGuiAddressResolver(IntPtr baseAddress) { public GameGuiAddressResolver(IntPtr baseAddress) {
BaseAddress = baseAddress; BaseAddress = baseAddress;
@ -35,6 +36,7 @@ namespace Dalamud.Game.Internal.Gui {
GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9"); GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9");
GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??"); GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1"); ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
ToggleUiHide = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 0F B6 B9 ?? ?? ?? ?? B8 ?? ?? ?? ??");
} }
} }
} }

View file

@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dalamud.Game.Internal.Gui;
using ImGuiNET; using ImGuiNET;
using ImGuiScene; using ImGuiScene;
using Serilog; using Serilog;
using SharpDX.Direct3D11;
namespace Dalamud.Interface namespace Dalamud.Interface
{ {
@ -31,8 +33,14 @@ namespace Dalamud.Interface
/// </summary> /// </summary>
public event RawDX11Scene.BuildUIDelegate OnBuildUi; public event RawDX11Scene.BuildUIDelegate OnBuildUi;
/// <summary>
/// Choose if this plugin should hide its UI automatically when the whole game hides its UI.
/// </summary>
public bool DisableAutomaticUiHide { get; set; } = false;
private readonly InterfaceManager interfaceManager; private readonly InterfaceManager interfaceManager;
#if DEBUG private readonly GameGui gameGui;
#if DEBUG
internal static bool DoStats { get; set; } = true; internal static bool DoStats { get; set; } = true;
#else #else
internal static bool DoStats { get; set; } = false; internal static bool DoStats { get; set; } = false;
@ -47,10 +55,11 @@ namespace Dalamud.Interface
/// </summary> /// </summary>
/// <param name="interfaceManager">The interface manager to register on.</param> /// <param name="interfaceManager">The interface manager to register on.</param>
/// <param name="namespaceName">The plugin namespace.</param> /// <param name="namespaceName">The plugin namespace.</param>
internal UiBuilder(InterfaceManager interfaceManager, string namespaceName) { internal UiBuilder(InterfaceManager interfaceManager, GameGui gameGui, string namespaceName) {
this.namespaceName = namespaceName; this.namespaceName = namespaceName;
this.interfaceManager = interfaceManager; this.interfaceManager = interfaceManager;
this.gameGui = gameGui;
this.interfaceManager.OnDraw += OnDraw; this.interfaceManager.OnDraw += OnDraw;
this.stopwatch = new System.Diagnostics.Stopwatch(); this.stopwatch = new System.Diagnostics.Stopwatch();
} }
@ -118,6 +127,10 @@ namespace Dalamud.Interface
private bool hasErrorWindow; private bool hasErrorWindow;
private void OnDraw() { private void OnDraw() {
if (this.gameGui.GameUiHidden && !DisableAutomaticUiHide)
return;
ImGui.PushID(this.namespaceName); ImGui.PushID(this.namespaceName);
if (DoStats) { if (DoStats) {
this.stopwatch.Restart(); this.stopwatch.Restart();

View file

@ -75,7 +75,7 @@ namespace Dalamud.Plugin
this.CommandManager = dalamud.CommandManager; this.CommandManager = dalamud.CommandManager;
this.Framework = dalamud.Framework; this.Framework = dalamud.Framework;
this.ClientState = dalamud.ClientState; this.ClientState = dalamud.ClientState;
this.UiBuilder = new UiBuilder(dalamud.InterfaceManager, pluginName); this.UiBuilder = new UiBuilder(dalamud.InterfaceManager, dalamud.Framework.Gui, pluginName);
this.TargetModuleScanner = dalamud.SigScanner; this.TargetModuleScanner = dalamud.SigScanner;
this.Data = dalamud.Data; this.Data = dalamud.Data;
this.SeStringManager = dalamud.SeStringManager; this.SeStringManager = dalamud.SeStringManager;