mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Merge pull request #328 from fitzchivalrik/feature/ControllerNavigation
This commit is contained in:
commit
2a79ac58e0
11 changed files with 642 additions and 3 deletions
|
|
@ -122,6 +122,11 @@ namespace Dalamud.Configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsDisableViewport { get; set; } = true;
|
public bool IsDisableViewport { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether or not navigation via a gamepad should be globally enabled in ImGui.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsGamepadNavigationEnabled { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load a configuration from the provided path.
|
/// Load a configuration from the provided path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,11 @@ namespace Dalamud.Game.ClientState
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public KeyState KeyState;
|
public KeyState KeyState;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides access to the button state of gamepad buttons in game.
|
||||||
|
/// </summary>
|
||||||
|
public GamepadState GamepadState;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides access to client conditions/player state. Allows you to check if a player is in a duty, mounted, etc.
|
/// Provides access to client conditions/player state. Allows you to check if a player is in a duty, mounted, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -131,6 +136,8 @@ namespace Dalamud.Game.ClientState
|
||||||
|
|
||||||
this.KeyState = new KeyState(Address, scanner.Module.BaseAddress);
|
this.KeyState = new KeyState(Address, scanner.Module.BaseAddress);
|
||||||
|
|
||||||
|
this.GamepadState = new GamepadState(this.Address);
|
||||||
|
|
||||||
this.Condition = new Condition( Address );
|
this.Condition = new Condition( Address );
|
||||||
|
|
||||||
this.Targets = new Targets(dalamud, Address);
|
this.Targets = new Targets(dalamud, Address);
|
||||||
|
|
@ -150,6 +157,7 @@ namespace Dalamud.Game.ClientState
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Enable() {
|
public void Enable() {
|
||||||
|
this.GamepadState.Enable();
|
||||||
this.PartyList.Enable();
|
this.PartyList.Enable();
|
||||||
this.setupTerritoryTypeHook.Enable();
|
this.setupTerritoryTypeHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
@ -158,6 +166,7 @@ namespace Dalamud.Game.ClientState
|
||||||
this.PartyList.Dispose();
|
this.PartyList.Dispose();
|
||||||
this.setupTerritoryTypeHook.Dispose();
|
this.setupTerritoryTypeHook.Dispose();
|
||||||
this.Actors.Dispose();
|
this.Actors.Dispose();
|
||||||
|
this.GamepadState.Dispose();
|
||||||
|
|
||||||
this.dalamud.Framework.OnUpdateEvent -= FrameworkOnOnUpdateEvent;
|
this.dalamud.Framework.OnUpdateEvent -= FrameworkOnOnUpdateEvent;
|
||||||
this.dalamud.NetworkHandlers.CfPop += NetworkHandlersOnCfPop;
|
this.dalamud.NetworkHandlers.CfPop += NetworkHandlersOnCfPop;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,14 @@ namespace Dalamud.Game.ClientState
|
||||||
public IntPtr SetupTerritoryType { get; private set; }
|
public IntPtr SetupTerritoryType { get; private set; }
|
||||||
//public IntPtr SomeActorTableAccess { get; private set; }
|
//public IntPtr SomeActorTableAccess { get; private set; }
|
||||||
//public IntPtr PartyListUpdate { get; private set; }
|
//public IntPtr PartyListUpdate { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Game function which polls the gamepads for data.
|
||||||
|
///
|
||||||
|
/// Called every frame, even when `Enable Gamepad` is off in the settings.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr GamepadPoll { get; private set; }
|
||||||
|
|
||||||
public IntPtr ConditionFlags { get; private set; }
|
public IntPtr ConditionFlags { get; private set; }
|
||||||
|
|
||||||
protected override void Setup64Bit(SigScanner sig) {
|
protected override void Setup64Bit(SigScanner sig) {
|
||||||
|
|
@ -38,6 +45,8 @@ namespace Dalamud.Game.ClientState
|
||||||
ConditionFlags = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? BA ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01 48 83 C4 30");
|
ConditionFlags = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? BA ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01 48 83 C4 30");
|
||||||
|
|
||||||
TargetManager = sig.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? FF 50 ?? 48 85 DB", 3);
|
TargetManager = sig.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? FF 50 ?? 48 85 DB", 3);
|
||||||
|
|
||||||
|
this.GamepadPoll = sig.ScanText("40 ?? 57 41 ?? 48 81 EC ?? ?? ?? ?? 44 0F ?? ?? ?? ?? ?? ?? ?? 48 8B");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
96
Dalamud/Game/ClientState/GamepadButtons.cs
Normal file
96
Dalamud/Game/ClientState/GamepadButtons.cs
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Bitmask of the Button ushort used by the game.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum GamepadButtons : ushort
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No buttons pressed.
|
||||||
|
/// </summary>
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Digipad up.
|
||||||
|
/// </summary>
|
||||||
|
DpadUp = 0x0001,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Digipad down.
|
||||||
|
/// </summary>
|
||||||
|
DpadDown = 0x0002,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Digipad left.
|
||||||
|
/// </summary>
|
||||||
|
DpadLeft = 0x0004,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Digipad right.
|
||||||
|
/// </summary>
|
||||||
|
DpadRight = 0x0008,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// North action button. Triangle on PS, Y on Xbox.
|
||||||
|
/// </summary>
|
||||||
|
North = 0x0010,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// South action button. Cross on PS, A on Xbox.
|
||||||
|
/// </summary>
|
||||||
|
South = 0x0020,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// West action button. Square on PS, X on Xbos.
|
||||||
|
/// </summary>
|
||||||
|
West = 0x0040,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// East action button. Circle on PS, B on Xbox.
|
||||||
|
/// </summary>
|
||||||
|
East = 0x0080,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// First button on left shoulder side.
|
||||||
|
/// </summary>
|
||||||
|
L1 = 0x0100,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Second button on left shoulder side. Analog input lost in this bitmask.
|
||||||
|
/// </summary>
|
||||||
|
L2 = 0x0200,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Press on left analogue stick.
|
||||||
|
/// </summary>
|
||||||
|
L3 = 0x0400,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// First button on right shoulder.
|
||||||
|
/// </summary>
|
||||||
|
R1 = 0x0800,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Second button on right shoulder. Analog input lost in this bitmask.
|
||||||
|
/// </summary>
|
||||||
|
R2 = 0x1000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Press on right analogue stick.
|
||||||
|
/// </summary>
|
||||||
|
R3 = 0x2000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Button on the right inner side of the controller. Options on PS, Start on Xbox.
|
||||||
|
/// </summary>
|
||||||
|
Start = 0x8000,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Button on the left inner side of the controller. ??? on PS, Back on Xbox.
|
||||||
|
/// </summary>
|
||||||
|
Select = 0x4000,
|
||||||
|
}
|
||||||
|
}
|
||||||
270
Dalamud/Game/ClientState/GamepadState.cs
Normal file
270
Dalamud/Game/ClientState/GamepadState.cs
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Structs;
|
||||||
|
using Dalamud.Hooking;
|
||||||
|
using ImGuiNET;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Exposes the game gamepad state to dalamud.
|
||||||
|
///
|
||||||
|
/// Will block game's gamepad input if <see cref="ImGuiConfigFlags.NavEnableGamepad"/> is set.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class GamepadState
|
||||||
|
{
|
||||||
|
private readonly Hook<ControllerPoll> gamepadPoll;
|
||||||
|
|
||||||
|
private bool isDisposed;
|
||||||
|
|
||||||
|
private int leftStickX;
|
||||||
|
private int leftStickY;
|
||||||
|
private int rightStickX;
|
||||||
|
private int rightStickY;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GamepadState" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="resolver">Resolver knowing the pointer to the GamepadPoll function.</param>
|
||||||
|
public GamepadState(ClientStateAddressResolver resolver)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Log.Verbose("GamepadPoll address {GamepadPoll}", resolver.GamepadPoll);
|
||||||
|
#endif
|
||||||
|
this.gamepadPoll = new Hook<ControllerPoll>(
|
||||||
|
resolver.GamepadPoll,
|
||||||
|
(ControllerPoll)this.GamepadPollDetour);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes an instance of the <see cref="GamepadState" /> class.
|
||||||
|
/// </summary>
|
||||||
|
~GamepadState()
|
||||||
|
{
|
||||||
|
this.Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate int ControllerPoll(IntPtr controllerInput);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the pointer to the current instance of the GamepadInput struct.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr GamepadInput { get; private set; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the left analogue stick in the left direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float LeftStickLeft => this.leftStickX < 0 ? -this.leftStickX / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the left analogue stick in the right direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float LeftStickRight => this.leftStickX > 0 ? this.leftStickX / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the left analogue stick in the up direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float LeftStickUp => this.leftStickY > 0 ? this.leftStickY / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the left analogue stick in the down direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float LeftStickDown => this.leftStickY < 0 ? -this.leftStickY / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the right analogue stick in the left direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float RightStickLeft => this.rightStickX < 0 ? -this.rightStickX / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the right analogue stick in the right direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float RightStickRight => this.rightStickX > 0 ? this.rightStickX / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the right analogue stick in the up direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float RightStickUp => this.rightStickY > 0 ? this.rightStickY / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of the right analogue stick in the down direction between 0 (not tilted) and 1 (max tilt).
|
||||||
|
/// </summary>
|
||||||
|
public float RightStickDown => this.rightStickY < 0 ? -this.rightStickY / 100f : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets buttons pressed bitmask, set once when the button is pressed. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
///
|
||||||
|
/// Exposed internally for Debug Data window.
|
||||||
|
/// </summary>
|
||||||
|
internal ushort ButtonsPressed { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets raw button bitmask, set the whole time while a button is held. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
///
|
||||||
|
/// Exposed internally for Debug Data window.
|
||||||
|
/// </summary>
|
||||||
|
internal ushort ButtonsRaw { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets button released bitmask, set once right after the button is not hold anymore. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
///
|
||||||
|
/// Exposed internally for Debug Data window.
|
||||||
|
/// </summary>
|
||||||
|
internal ushort ButtonsReleased { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets button repeat bitmask, emits the held button input in fixed intervals. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
///
|
||||||
|
/// Exposed internally for Debug Data window.
|
||||||
|
/// </summary>
|
||||||
|
internal ushort ButtonsRepeat { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether detour should block gamepad input for game.
|
||||||
|
///
|
||||||
|
/// Ideally, we would use
|
||||||
|
/// (ImGui.GetIO().ConfigFlags & ImGuiConfigFlags.NavEnableGamepad) > 0
|
||||||
|
/// but this has a race condition during load with the detour which sets up ImGui
|
||||||
|
/// and throws if our detour gets called before the other.
|
||||||
|
/// </summary>
|
||||||
|
internal bool NavEnableGamepad { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether <paramref name="button"/> has been pressed.
|
||||||
|
///
|
||||||
|
/// Only true on first frame of the press.
|
||||||
|
/// If ImGuiConfigFlags.NavEnableGamepad is set, this is unreliable.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="button">The button to check for.</param>
|
||||||
|
/// <returns>1 if pressed, 0 otherwise.</returns>
|
||||||
|
public float Pressed(GamepadButtons button) => (this.ButtonsPressed & (ushort)button) > 0 ? 1 : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether <paramref name="button"/> is being pressed.
|
||||||
|
///
|
||||||
|
/// True in intervals if button is held down.
|
||||||
|
/// If ImGuiConfigFlags.NavEnableGamepad is set, this is unreliable.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="button">The button to check for.</param>
|
||||||
|
/// <returns>1 if still pressed during interval, 0 otherwise or in between intervals.</returns>
|
||||||
|
public float Repeat(GamepadButtons button) => (this.ButtonsRepeat & (ushort)button) > 0 ? 1 : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether <paramref name="button"/> has been released.
|
||||||
|
///
|
||||||
|
/// Only true the frame after release.
|
||||||
|
/// If ImGuiConfigFlags.NavEnableGamepad is set, this is unreliable.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="button">The button to check for.</param>
|
||||||
|
/// <returns>1 if released, 0 otherwise.</returns>
|
||||||
|
public float Released(GamepadButtons button) => (this.ButtonsReleased & (ushort)button) > 0 ? 1 : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the raw state of <paramref name="button"/>.
|
||||||
|
///
|
||||||
|
/// Is set the entire time a button is pressed down.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="button">The button to check for.</param>
|
||||||
|
/// <returns>1 the whole time button is pressed, 0 otherwise.</returns>
|
||||||
|
public float Raw(GamepadButtons button) => (this.ButtonsRaw & (ushort)button) > 0 ? 1 : 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the hook of the GamepadPoll function.
|
||||||
|
/// </summary>
|
||||||
|
public void Enable()
|
||||||
|
{
|
||||||
|
this.gamepadPoll.Enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes this instance, alongside its hooks.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GamepadPollDetour(IntPtr gamepadInput)
|
||||||
|
{
|
||||||
|
var original = this.gamepadPoll.Original(gamepadInput);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
this.GamepadInput = gamepadInput;
|
||||||
|
#endif
|
||||||
|
var input = (GamepadInput*)gamepadInput;
|
||||||
|
this.leftStickX = input->LeftStickX;
|
||||||
|
this.leftStickY = input->LeftStickY;
|
||||||
|
this.rightStickX = input->RightStickX;
|
||||||
|
this.rightStickY = input->RightStickY;
|
||||||
|
this.ButtonsRaw = input->ButtonsRaw;
|
||||||
|
this.ButtonsPressed = input->ButtonsPressed;
|
||||||
|
this.ButtonsReleased = input->ButtonsReleased;
|
||||||
|
this.ButtonsRepeat = input->ButtonsRepeat;
|
||||||
|
|
||||||
|
if (this.NavEnableGamepad)
|
||||||
|
{
|
||||||
|
input->LeftStickX = 0;
|
||||||
|
input->LeftStickY = 0;
|
||||||
|
input->RightStickX = 0;
|
||||||
|
input->RightStickY = 0;
|
||||||
|
|
||||||
|
// NOTE (Chiv) Zeroing `ButtonsRaw` destroys `ButtonPressed`, `ButtonReleased`
|
||||||
|
// and `ButtonRepeat` as the game uses the RAW input to determine those (apparently).
|
||||||
|
// It does block, however, all input to the game.
|
||||||
|
// Leaving `ButtonsRaw` as it is and only zeroing the other leaves e.g. long-hold L2/R2
|
||||||
|
// and the digipad (in some situations, but thankfully not in menus) functional.
|
||||||
|
// We can either:
|
||||||
|
// (a) Explicitly only set L2/R2/Digipad to 0 (and destroy their `ButtonPressed` field) => Needs to be documented, or
|
||||||
|
// (b) ignore it as so far it seems only a 'visual' error
|
||||||
|
// (L2/R2 being held down activates CrossHotBar but activating an ability is impossible because of the others blocked input,
|
||||||
|
// Digipad is ignored in menus but without any menu's one still switches target or party members, but cannot interact with them
|
||||||
|
// because of the other blocked input)
|
||||||
|
// `ButtonPressed` is pretty useful but its hella confusing to the user, so we do (a) and advise plugins do not rely on
|
||||||
|
// `ButtonPressed` while ImGuiConfigFlags.NavEnableGamepad is set.
|
||||||
|
// This is debatable.
|
||||||
|
// ImGui itself does not care either way as it uses the Raw values and does its own state handling.
|
||||||
|
const ushort deletionMask = (ushort)(~GamepadButtons.L2
|
||||||
|
& ~GamepadButtons.R2
|
||||||
|
& ~GamepadButtons.DpadDown
|
||||||
|
& ~GamepadButtons.DpadLeft
|
||||||
|
& ~GamepadButtons.DpadUp
|
||||||
|
& ~GamepadButtons.DpadRight);
|
||||||
|
input->ButtonsRaw &= deletionMask;
|
||||||
|
input->ButtonsPressed = 0;
|
||||||
|
input->ButtonsReleased = 0;
|
||||||
|
input->ButtonsRepeat = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE (Chiv) Not so sure about the return value, does not seem to matter if we return the
|
||||||
|
// original, zero or do the work adjusting the bits.
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e, $"Gamepad Poll detour critical error! Gamepad navigation will not work!");
|
||||||
|
|
||||||
|
// NOTE (Chiv) Explicitly deactivate on error
|
||||||
|
ImGui.GetIO().ConfigFlags &= ~ImGuiConfigFlags.NavEnableGamepad;
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (this.isDisposed) return;
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
this.gamepadPoll?.Disable();
|
||||||
|
this.gamepadPoll?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isDisposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
Dalamud/Game/ClientState/Structs/GamepadInput.cs
Normal file
64
Dalamud/Game/ClientState/Structs/GamepadInput.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Structs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Struct which gets populated by polling the gamepads.
|
||||||
|
///
|
||||||
|
/// Has an array of gamepads, among many other things (here not mapped).
|
||||||
|
/// All we really care about is the final data which the game uses to determine input.
|
||||||
|
///
|
||||||
|
/// The size is definitely bigger than only the following fields but I do not know how big.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public struct GamepadInput
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Left analogue stick's horizontal value, -99 for left, 99 for right.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0x88)]
|
||||||
|
public int LeftStickX;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Left analogue stick's vertical value, -99 for down, 99 for up.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0x8C)]
|
||||||
|
public int LeftStickY;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Right analogue stick's horizontal value, -99 for left, 99 for right.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0x90)]
|
||||||
|
public int RightStickX;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Right analogue stick's vertical value, -99 for down, 99 for up.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0x94)]
|
||||||
|
public int RightStickY;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raw input, set the whole time while a button is held. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0x98)]
|
||||||
|
public ushort ButtonsRaw; // bitfield
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Button pressed, set once when the button is pressed. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0x9C)]
|
||||||
|
public ushort ButtonsPressed; // bitfield
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Button released input, set once right after the button is not hold anymore. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0xA0)]
|
||||||
|
public ushort ButtonsReleased; // bitfield
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repeatedly emits the held button input in fixed intervals. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(0xA4)]
|
||||||
|
public ushort ButtonsRepeat; // bitfield
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ namespace Dalamud.Interface
|
||||||
private string[] dataKinds = new[]
|
private string[] dataKinds = new[]
|
||||||
{
|
{
|
||||||
"ServerOpCode", "Address", "Actor Table", "Font Test", "Party List", "Plugin IPC", "Condition",
|
"ServerOpCode", "Address", "Actor Table", "Font Test", "Party List", "Plugin IPC", "Condition",
|
||||||
"Gauge", "Command", "Addon", "Addon Inspector", "StartInfo", "Target", "Toast", "ImGui", "Tex",
|
"Gauge", "Command", "Addon", "Addon Inspector", "StartInfo", "Target", "Toast", "ImGui", "Tex", "Gamepad",
|
||||||
};
|
};
|
||||||
|
|
||||||
private bool drawActors = false;
|
private bool drawActors = false;
|
||||||
|
|
@ -391,6 +391,60 @@ namespace Dalamud.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Gamepad
|
||||||
|
case 16:
|
||||||
|
Action<string, uint, Func<GamepadButtons, float>> helper = (text, mask, resolve) =>
|
||||||
|
{
|
||||||
|
ImGui.Text($"{text} {mask:X4}");
|
||||||
|
ImGui.Text($"DPadLeft {resolve(GamepadButtons.DpadLeft)} " +
|
||||||
|
$"DPadUp {resolve(GamepadButtons.DpadUp)} " +
|
||||||
|
$"DPadRight {resolve(GamepadButtons.DpadRight)} " +
|
||||||
|
$"DPadDown {resolve(GamepadButtons.DpadDown)} ");
|
||||||
|
ImGui.Text($"West {resolve(GamepadButtons.West)} " +
|
||||||
|
$"North {resolve(GamepadButtons.North)} " +
|
||||||
|
$"East {resolve(GamepadButtons.East)} " +
|
||||||
|
$"South {resolve(GamepadButtons.South)} ");
|
||||||
|
ImGui.Text($"L1 {resolve(GamepadButtons.L1)} " +
|
||||||
|
$"L2 {resolve(GamepadButtons.L2)} " +
|
||||||
|
$"R1 {resolve(GamepadButtons.R1)} " +
|
||||||
|
$"R2 {resolve(GamepadButtons.R2)} ");
|
||||||
|
ImGui.Text($"Select {resolve(GamepadButtons.Select)} " +
|
||||||
|
$"Start {resolve(GamepadButtons.Start)} " +
|
||||||
|
$"L3 {resolve(GamepadButtons.L3)} " +
|
||||||
|
$"R3 {resolve(GamepadButtons.R3)} ");
|
||||||
|
};
|
||||||
|
#if DEBUG
|
||||||
|
ImGui.Text($"GamepadInput {this.dalamud.ClientState.GamepadState.GamepadInput.ToString("X")}");
|
||||||
|
if (ImGui.IsItemHovered()) ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
|
||||||
|
if (ImGui.IsItemClicked()) ImGui.SetClipboardText($"{this.dalamud.ClientState.GamepadState.GamepadInput.ToString("X")}");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
helper(
|
||||||
|
"Buttons Raw",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsRaw,
|
||||||
|
this.dalamud.ClientState.GamepadState.Raw);
|
||||||
|
helper(
|
||||||
|
"Buttons Pressed",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsPressed,
|
||||||
|
this.dalamud.ClientState.GamepadState.Pressed);
|
||||||
|
helper(
|
||||||
|
"Buttons Repeat",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsRepeat,
|
||||||
|
this.dalamud.ClientState.GamepadState.Repeat);
|
||||||
|
helper(
|
||||||
|
"Buttons Released",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsReleased,
|
||||||
|
this.dalamud.ClientState.GamepadState.Released);
|
||||||
|
ImGui.Text($"LeftStickLeft {this.dalamud.ClientState.GamepadState.LeftStickLeft:0.00} " +
|
||||||
|
$"LeftStickUp {this.dalamud.ClientState.GamepadState.LeftStickUp:0.00} " +
|
||||||
|
$"LeftStickRight {this.dalamud.ClientState.GamepadState.LeftStickRight:0.00} " +
|
||||||
|
$"LeftStickDown {this.dalamud.ClientState.GamepadState.LeftStickDown:0.00} ");
|
||||||
|
ImGui.Text($"RightStickLeft {this.dalamud.ClientState.GamepadState.RightStickLeft:0.00} " +
|
||||||
|
$"RightStickUp {this.dalamud.ClientState.GamepadState.RightStickUp:0.00} " +
|
||||||
|
$"RightStickRight {this.dalamud.ClientState.GamepadState.RightStickRight:0.00} " +
|
||||||
|
$"RightStickDown {this.dalamud.ClientState.GamepadState.RightStickDown:0.00} ");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ namespace Dalamud.Interface
|
||||||
private readonly ComponentDemoWindow componentDemoWindow;
|
private readonly ComponentDemoWindow componentDemoWindow;
|
||||||
private readonly ColorDemoWindow colorDemoWindow;
|
private readonly ColorDemoWindow colorDemoWindow;
|
||||||
private readonly ScratchpadWindow scratchpadWindow;
|
private readonly ScratchpadWindow scratchpadWindow;
|
||||||
|
private readonly GamepadModeNotifierWindow gamepadModeNotifierWindow;
|
||||||
|
|
||||||
private readonly WindowSystem windowSystem = new WindowSystem("DalamudCore");
|
private readonly WindowSystem windowSystem = new WindowSystem("DalamudCore");
|
||||||
|
|
||||||
|
|
@ -116,6 +117,9 @@ namespace Dalamud.Interface
|
||||||
};
|
};
|
||||||
this.windowSystem.AddWindow(this.scratchpadWindow);
|
this.windowSystem.AddWindow(this.scratchpadWindow);
|
||||||
|
|
||||||
|
this.gamepadModeNotifierWindow = new GamepadModeNotifierWindow();
|
||||||
|
this.windowSystem.AddWindow(this.gamepadModeNotifierWindow);
|
||||||
|
|
||||||
Log.Information("[DUI] Windows added");
|
Log.Information("[DUI] Windows added");
|
||||||
|
|
||||||
if (dalamud.Configuration.LogOpenAtStartup)
|
if (dalamud.Configuration.LogOpenAtStartup)
|
||||||
|
|
@ -553,5 +557,13 @@ namespace Dalamud.Interface
|
||||||
{
|
{
|
||||||
this.scratchpadWindow.IsOpen ^= true;
|
this.scratchpadWindow.IsOpen ^= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggle the gamepad notifier window window.
|
||||||
|
/// </summary>
|
||||||
|
internal void ToggleGamePadNotifierWindow()
|
||||||
|
{
|
||||||
|
this.gamepadModeNotifierWindow.IsOpen ^= true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Dalamud.Interface
|
||||||
{
|
{
|
||||||
this.dalamud = dalamud;
|
this.dalamud = dalamud;
|
||||||
|
|
||||||
this.Size = new Vector2(740, 500);
|
this.Size = new Vector2(740, 550);
|
||||||
this.SizeCondition = ImGuiCond.FirstUseEver;
|
this.SizeCondition = ImGuiCond.FirstUseEver;
|
||||||
|
|
||||||
this.dalamudMessagesChatType = this.dalamud.Configuration.GeneralChatType;
|
this.dalamudMessagesChatType = this.dalamud.Configuration.GeneralChatType;
|
||||||
|
|
@ -38,6 +38,7 @@ namespace Dalamud.Interface
|
||||||
|
|
||||||
this.doDocking = this.dalamud.Configuration.IsDocking;
|
this.doDocking = this.dalamud.Configuration.IsDocking;
|
||||||
this.doViewport = !this.dalamud.Configuration.IsDisableViewport;
|
this.doViewport = !this.dalamud.Configuration.IsDisableViewport;
|
||||||
|
this.doGamepad = this.dalamud.Configuration.IsGamepadNavigationEnabled;
|
||||||
|
|
||||||
this.doPluginTest = this.dalamud.Configuration.DoPluginTest;
|
this.doPluginTest = this.dalamud.Configuration.DoPluginTest;
|
||||||
this.thirdRepoList = this.dalamud.Configuration.ThirdRepoList.Select(x => x.Clone()).ToList();
|
this.thirdRepoList = this.dalamud.Configuration.ThirdRepoList.Select(x => x.Clone()).ToList();
|
||||||
|
|
@ -133,6 +134,7 @@ namespace Dalamud.Interface
|
||||||
private bool doToggleUiHideDuringGpose;
|
private bool doToggleUiHideDuringGpose;
|
||||||
private bool doDocking;
|
private bool doDocking;
|
||||||
private bool doViewport;
|
private bool doViewport;
|
||||||
|
private bool doGamepad;
|
||||||
private List<ThirdRepoSetting> thirdRepoList;
|
private List<ThirdRepoSetting> thirdRepoList;
|
||||||
|
|
||||||
private bool printPluginsWelcomeMsg;
|
private bool printPluginsWelcomeMsg;
|
||||||
|
|
@ -228,6 +230,9 @@ namespace Dalamud.Interface
|
||||||
ImGui.Checkbox(Loc.Localize("DalamudSettingToggleDocking", "Enable window docking"), ref this.doDocking);
|
ImGui.Checkbox(Loc.Localize("DalamudSettingToggleDocking", "Enable window docking"), ref this.doDocking);
|
||||||
ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingToggleDockingHint", "This will allow you to fuse and tab plugin windows."));
|
ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingToggleDockingHint", "This will allow you to fuse and tab plugin windows."));
|
||||||
|
|
||||||
|
ImGui.Checkbox(Loc.Localize("DalamudSettingToggleGamepadNavigation", "Enable navigation of ImGui windows via gamepad."), ref this.doGamepad);
|
||||||
|
ImGui.TextColored(this.hintTextColor, Loc.Localize("DalamudSettingToggleGamepadNavigationHint", "This will allow you to toggle between game and ImGui navigation via L1+L3.\nToggle the PluginInstaller window via R3 if ImGui navigation is enabled."));
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,6 +383,7 @@ namespace Dalamud.Interface
|
||||||
this.dalamud.Configuration.ToggleUiHideDuringGpose = this.doToggleUiHideDuringGpose;
|
this.dalamud.Configuration.ToggleUiHideDuringGpose = this.doToggleUiHideDuringGpose;
|
||||||
|
|
||||||
this.dalamud.Configuration.IsDocking = this.doDocking;
|
this.dalamud.Configuration.IsDocking = this.doDocking;
|
||||||
|
this.dalamud.Configuration.IsGamepadNavigationEnabled = this.doGamepad;
|
||||||
|
|
||||||
// This is applied every frame in InterfaceManager::CheckViewportState()
|
// This is applied every frame in InterfaceManager::CheckViewportState()
|
||||||
this.dalamud.Configuration.IsDisableViewport = !this.doViewport;
|
this.dalamud.Configuration.IsDisableViewport = !this.doViewport;
|
||||||
|
|
@ -392,6 +398,18 @@ namespace Dalamud.Interface
|
||||||
ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.DockingEnable;
|
ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.DockingEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE (Chiv) Toggle gamepad navigation via setting
|
||||||
|
if (!this.dalamud.Configuration.IsGamepadNavigationEnabled)
|
||||||
|
{
|
||||||
|
ImGui.GetIO().BackendFlags &= ~ImGuiBackendFlags.HasGamepad;
|
||||||
|
ImGui.GetIO().ConfigFlags &= ~ImGuiConfigFlags.NavEnableSetMousePos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.GetIO().BackendFlags |= ImGuiBackendFlags.HasGamepad;
|
||||||
|
ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.NavEnableSetMousePos;
|
||||||
|
}
|
||||||
|
|
||||||
this.dalamud.Configuration.DoPluginTest = this.doPluginTest;
|
this.dalamud.Configuration.DoPluginTest = this.doPluginTest;
|
||||||
this.dalamud.Configuration.ThirdRepoList = this.thirdRepoList.Select(x => x.Clone()).ToList();
|
this.dalamud.Configuration.ThirdRepoList = this.thirdRepoList.Select(x => x.Clone()).ToList();
|
||||||
|
|
||||||
|
|
|
||||||
47
Dalamud/Interface/GamepadModeNotifierWindow.cs
Normal file
47
Dalamud/Interface/GamepadModeNotifierWindow.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
using CheapLoc;
|
||||||
|
using Dalamud.Interface.Windowing;
|
||||||
|
using ImGuiNET;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class responsible for drawing a notifier on screen that gamepad mode is active.
|
||||||
|
/// </summary>
|
||||||
|
internal class GamepadModeNotifierWindow : Window
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GamepadModeNotifierWindow"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public GamepadModeNotifierWindow()
|
||||||
|
: base(
|
||||||
|
"###DalamudGamepadModeNotifier",
|
||||||
|
ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoMouseInputs
|
||||||
|
| ImGuiWindowFlags.NoFocusOnAppearing | ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.NoNav
|
||||||
|
| ImGuiWindowFlags.NoInputs | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoSavedSettings,
|
||||||
|
true)
|
||||||
|
{
|
||||||
|
this.Size = Vector2.Zero;
|
||||||
|
this.SizeCondition = ImGuiCond.Always;
|
||||||
|
this.IsOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draws a light grey-ish, main-viewport-big filled rect in the background draw list alongside a text indicating gamepad mode.
|
||||||
|
/// </summary>
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
var drawList = ImGui.GetBackgroundDrawList();
|
||||||
|
drawList.PushClipRectFullScreen();
|
||||||
|
drawList.AddRectFilled(Vector2.Zero, ImGuiHelpers.MainViewport.Size, 0x661A1A1A);
|
||||||
|
drawList.AddText(
|
||||||
|
Vector2.One,
|
||||||
|
0xFFFFFFFF,
|
||||||
|
Loc.Localize(
|
||||||
|
"DalamudGamepadModeNotifierText",
|
||||||
|
"Gamepad mode is ON. Press R1+L3 to deactivate, press R3 to toggle PluginInstaller."));
|
||||||
|
drawList.PopClipRect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.Internal.DXGI;
|
using Dalamud.Game.Internal.DXGI;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using EasyHook;
|
using EasyHook;
|
||||||
|
|
@ -291,6 +292,21 @@ namespace Dalamud.Interface
|
||||||
ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.DockingEnable;
|
ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.DockingEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE (Chiv) Toggle gamepad navigation via setting
|
||||||
|
if (!this.dalamud.Configuration.IsGamepadNavigationEnabled)
|
||||||
|
{
|
||||||
|
ImGui.GetIO().BackendFlags &= ~ImGuiBackendFlags.HasGamepad;
|
||||||
|
ImGui.GetIO().ConfigFlags &= ~ImGuiConfigFlags.NavEnableSetMousePos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.GetIO().BackendFlags |= ImGuiBackendFlags.HasGamepad;
|
||||||
|
ImGui.GetIO().ConfigFlags |= ImGuiConfigFlags.NavEnableSetMousePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE (Chiv) Explicitly deactivate on dalamud boot
|
||||||
|
ImGui.GetIO().ConfigFlags &= ~ImGuiConfigFlags.NavEnableGamepad;
|
||||||
|
|
||||||
ImGuiHelpers.MainViewport = ImGui.GetMainViewport();
|
ImGuiHelpers.MainViewport = ImGui.GetMainViewport();
|
||||||
|
|
||||||
Log.Information("[IM] Scene & ImGui setup OK!");
|
Log.Information("[IM] Scene & ImGui setup OK!");
|
||||||
|
|
@ -461,6 +477,45 @@ namespace Dalamud.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: mouse state?
|
// TODO: mouse state?
|
||||||
|
|
||||||
|
var gamepadEnabled = (ImGui.GetIO().BackendFlags & ImGuiBackendFlags.HasGamepad) > 0;
|
||||||
|
|
||||||
|
// NOTE (Chiv) Activate ImGui navigation via L1+L3 press
|
||||||
|
// (mimicking how mouse navigation is activated via L1+R3 press in game).
|
||||||
|
if (gamepadEnabled
|
||||||
|
&& this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.L1) > 0
|
||||||
|
&& this.dalamud.ClientState.GamepadState.Pressed(GamepadButtons.L3) > 0)
|
||||||
|
{
|
||||||
|
ImGui.GetIO().ConfigFlags ^= ImGuiConfigFlags.NavEnableGamepad;
|
||||||
|
this.dalamud.ClientState.GamepadState.NavEnableGamepad ^= true;
|
||||||
|
this.dalamud.DalamudUi.ToggleGamePadNotifierWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gamepadEnabled
|
||||||
|
&& (ImGui.GetIO().ConfigFlags & ImGuiConfigFlags.NavEnableGamepad) > 0)
|
||||||
|
{
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Activate] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.South);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Cancel] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.East);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Input] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.North);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Menu] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.West);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.DpadLeft] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.DpadLeft);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.DpadRight] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.DpadRight);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.DpadUp] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.DpadUp);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.DpadDown] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.DpadDown);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.LStickLeft] = this.dalamud.ClientState.GamepadState.LeftStickLeft;
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.LStickRight] = this.dalamud.ClientState.GamepadState.LeftStickRight;
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.LStickUp] = this.dalamud.ClientState.GamepadState.LeftStickUp;
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.LStickDown] = this.dalamud.ClientState.GamepadState.LeftStickDown;
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.FocusPrev] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.L1);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.FocusNext] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.R1);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.TweakSlow] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.L2);
|
||||||
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.TweakFast] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.R2);
|
||||||
|
|
||||||
|
if (this.dalamud.ClientState.GamepadState.Pressed(GamepadButtons.R3) > 0)
|
||||||
|
{
|
||||||
|
this.dalamud.DalamudUi.TogglePluginInstaller();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Display()
|
private void Display()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue