Input keybinds: hold ` for free mouse, use alt + delete to toggle free mouse
All checks were successful
Build / Compute Version (push) Successful in 6s
Build / Build Nuget package (NuGet) (push) Successful in 53s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 58s
Build / Build Nuget package (SharedCringe) (push) Successful in 1m2s
Build / Build Nuget package (CringePlugins) (push) Successful in 1m19s
Build / Build Launcher (push) Successful in 1m49s

This commit is contained in:
2025-05-17 18:08:44 -04:00
parent bd626f7a2b
commit 662aef1247
3 changed files with 114 additions and 19 deletions

View File

@@ -11,23 +11,27 @@ using ImGuiNET;
using SharpDX.Direct3D11;
using static ImGuiNET.ImGui;
using VRage;
using Sandbox.Graphics.GUI;
namespace CringeLauncher;
internal class ImGuiHandler : IDisposable
{
private DeviceContext? _deviceContext;
private int _blockKeysCounter;
private static nint _wndproc;
public bool BlockMouse { get; private set; }
public bool BlockKeys { get; private set; }
public bool BlockKeys => _blockKeysCounter > 0;
public bool DrawMouse { get; private set; }
internal bool MouseToggle { get; set; }
internal bool MouseKey { get; set; }
public static ImGuiHandler? Instance;
public static RenderTargetView? Rtv;
private readonly IRootRenderComponent _renderHandler = new RenderHandler();
private static bool _init;
@@ -36,16 +40,16 @@ internal class ImGuiHandler : IDisposable
_deviceContext = deviceContext;
CreateContext();
var io = GetIO();
var path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CringeLauncher", "imgui.ini");
io.NativePtr->IniFilename = AnsiStringMarshaller.ConvertToUnmanaged(path);
io.ConfigWindowsMoveFromTitleBarOnly = true;
io.ConfigFlags |= ImGuiConfigFlags.DockingEnable | ImGuiConfigFlags.ViewportsEnable;
ImGui_ImplWin32_Init(windowHandle);
ImGui_ImplDX11_Init(device.NativePointer, deviceContext.NativePointer);
_init = true;
@@ -58,7 +62,7 @@ internal class ImGuiHandler : IDisposable
unsafe
{
delegate* unmanaged[Stdcall]<HWND, int, nint, nint, int> wndProcHook = &WndProcHook;
PInvoke.SetWindowLongPtr(windowHandle, WINDOW_LONG_PTR_INDEX.GWL_WNDPROC, (nint)wndProcHook);
}
}
@@ -67,33 +71,69 @@ internal class ImGuiHandler : IDisposable
{
if (Rtv is null)
return;
ImGui_ImplDX11_NewFrame();
ImGui_ImplWin32_NewFrame();
NewFrame();
var io = GetIO();
BlockMouse = io.WantCaptureMouse;
BlockKeys = io.WantTextInput;
DrawMouse = io.MouseDrawCursor;
if (io.WantTextInput)
_blockKeysCounter = 10; //WantTextInput can be false briefly after pressing enter in a textbox
else
_blockKeysCounter--;
DrawMouse = io.MouseDrawCursor || MouseToggle || MouseKey;
var focusedScreen = MyScreenManager.GetScreenWithFocus(); //migrated logic from MyDX9Gui.Draw
if (DrawMouse || focusedScreen?.GetDrawMouseCursor() == true || (MyScreenManager.InputToNonFocusedScreens && MyScreenManager.GetScreensCount() > 1))
{
MyGuiSandbox.SetMouseCursorVisibility(true, false);
}
else if (focusedScreen != null)
{
MyGuiSandbox.SetMouseCursorVisibility(focusedScreen.GetDrawMouseCursor());
}
_renderHandler.OnFrame();
Render();
_deviceContext!.ClearState();
_deviceContext.OutputMerger.SetRenderTargets(Rtv);
ImGui_ImplDX11_RenderDrawData(GetDrawData());
UpdatePlatformWindows();
RenderPlatformWindowsDefault();
}
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvStdcall)])]
private static unsafe int WndProcHook(HWND hWnd, int msg, nint wParam, nint lParam)
{
//special handling for the mouse free key
if (msg is 0x0100 or 0x104 && (int)wParam == 0xC0 && Instance != null)
{
Instance.MouseKey = true;
return 0;
}
if (msg is 0x0101 or 0x105 && (int)wParam == 0xC0 && Instance != null)
{
Instance.MouseKey = false;
return 0;
}
if (msg == 0x102 && (char)(int)wParam == '`')
return 0;
//ignore input if mouse is hidden
if (MyVRage.Platform?.Input?.ShowCursor == false && Instance?.DrawMouse != true)
if (Instance?.BlockKeys != true && MyVRage.Platform?.Input?.ShowCursor == false && Instance?.DrawMouse != true)
return CallWindowProc(_wndproc, hWnd, msg, wParam, lParam);
var hookResult = ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam);
@@ -101,11 +141,11 @@ internal class ImGuiHandler : IDisposable
if (hookResult != 0)
return hookResult;
var io = GetIO();
if (!_init)
return CallWindowProc(_wndproc, hWnd, msg, wParam, lParam);
var io = GetIO();
var blockMessage = (msg is >= 256 and <= 265 && io.WantTextInput)
|| (msg is >= 512 and <= 526 && io.WantCaptureMouse);

View File

@@ -1,5 +1,9 @@
using HarmonyLib;
using Sandbox.Engine.Platform.VideoMode;
using Sandbox.Game.World;
using Sandbox.Graphics;
using Sandbox.Graphics.GUI;
using System.Reflection.Emit;
using VRage;
using VRage.Input;
using VRage.Input.Keyboard;
@@ -25,6 +29,45 @@ internal static class InputPatch
}
}
[HarmonyPrefix, HarmonyPatch(typeof(MyVRageInput), nameof(MyVRageInput.GetMouseXForGamePlayF))]
private static bool GetMouseXForGamePlayFPrefix(ref float __result)
{
if (ImGuiHandler.Instance?.DrawMouse == true)
{
__result = 0;
return false;
}
return true;
}
[HarmonyPrefix, HarmonyPatch(typeof(MyVRageInput), nameof(MyVRageInput.GetMouseYForGamePlayF))]
private static bool GetMouseYForGamePlayFPrefix(ref float __result)
{
if (ImGuiHandler.Instance?.DrawMouse == true)
{
__result = 0;
return false;
}
return true;
}
[HarmonyTranspiler, HarmonyPatch(typeof(MyDX9Gui), nameof(MyDX9Gui.Draw))]
private static List<CodeInstruction> Dx9GuiDrawTranspiler(IEnumerable<CodeInstruction> instructions)
{
var list = instructions.ToList();
var method = AccessTools.Method(typeof(MyVideoSettingsManager), nameof(MyVideoSettingsManager.IsHardwareCursorUsed));
var index = list.FindIndex(b => b.Calls(method));
list[index].opcode = OpCodes.Ret;
list[index].operand = null;
list.RemoveRange(index + 1, list.Count - index - 1);
return list;
}
[HarmonyPrefix, HarmonyPatch(typeof(MyGuiLocalizedKeyboardState), nameof(MyGuiLocalizedKeyboardState.GetCurrentState))]
private static bool GetKeyboardStatePrefix(ref MyKeyboardState __result)
{
@@ -46,4 +89,16 @@ internal static class InputPatch
}
return true;
}
[HarmonyPostfix, HarmonyPatch(typeof(MySession), nameof(MySession.HandleInput))]
private static void HandleInputPostfix()
{
if (ImGuiHandler.Instance == null || MyInput.Static == null)
return;
if (MyInput.Static.IsAnyAltKeyPressed() && MyInput.Static.IsNewKeyPressed(MyKeys.Delete))
{
ImGuiHandler.Instance.MouseToggle = !ImGuiHandler.Instance.MouseToggle;
}
}
}

View File

@@ -6,7 +6,7 @@ using VRage;
namespace CringeLauncher.Patches;
[HarmonyPatch(typeof(CustomRootWriter), "Init")]
public class XmlRootWriterPatch
public static class XmlRootWriterPatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{