From 304441c71997ee61e618146f4d4302c6d2b952ad Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 27 Oct 2026 18:21:13 +0100 Subject: GUI: Insert-only close, freeze mouse look at the source Feedback pass: - Insert now toggles the GUI; the old text tree moved to F1. - Remove the title-bar X. Insert is the only close path; Esc only cancels bind capture. - Discard accumulated mouse deltas in CInput::CreateMove before the game can apply them (CInput::ClearStates), so the camera no longer moves for a frame and snaps back. Also skip ExtraMouseSample and zero relative mouse state while the GUI is open. - Strip attack/use/impulse/weapon selection from the command while open; keep jump, duck and walk. Skip combat command edits (spread seed) too. - Widen System page buttons so "Reload config" and "Reset defaults" fit. - Update CONTEXT/ADR for the Insert-only close behavior. --- src/cinput.cpp | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'src/cinput.cpp') diff --git a/src/cinput.cpp b/src/cinput.cpp index a75cc4f..ad7face 100644 --- a/src/cinput.cpp +++ b/src/cinput.cpp @@ -85,12 +85,42 @@ void fix_verified_crc(int seq, uint32_t crc) { using InputCreateMoveFn = void (*)(void *, int, float, bool); static InputCreateMoveFn oInputCreateMove = nullptr; +using InputExtraMouseFn = void (*)(void *, float, bool); +static InputExtraMouseFn oInputExtraMouseSample = nullptr; + +// ExtraMouseSample runs AdjustAngles at render-frame rate, between movement +// commands. While the GUI is open it must not touch the view; movement still +// comes through CreateMove. +static void hkdInputExtraMouseSample(void *self, float frametime, bool active) { + if (gui_is_open()) + return; + if (oInputExtraMouseSample) + oInputExtraMouseSample(self, frametime, active); +} + +void input_clear_mouse_states() { + if (!g_input) + return; + // CInput::ClearStates (IInput slot 20): zeros both the software mouse + // accumulator and the engine raw-input accumulator. + using Fn = void (*)(void *); + vfunc((void *)g_input, 20)((void *)g_input); +} static void hkdInputCreateMove(void *self, int seq, float frametime, bool active) { + // Mouse deltas are accumulated between ticks. With the custom GUI open we + // must discard them before CInput::CreateMove applies mouse look, otherwise + // the view moves for one frame and snaps back when do_move freezes it. + if (gui_is_open()) + input_clear_mouse_states(); if (oInputCreateMove) oInputCreateMove(self, seq, frametime, active); + // No combat features may modify the command while the GUI is open. + if (gui_is_open()) + return; + CUserCmd *cmd = get_usercmd(seq); if (!cmd) return; @@ -125,8 +155,14 @@ static bool install_input_hook() { memcpy(nvt, vt, N * sizeof(void *)); oInputCreateMove = (InputCreateMoveFn)vt[3]; nvt[3] = (void *)&hkdInputCreateMove; + if (N > 4) { + oInputExtraMouseSample = (InputExtraMouseFn)vt[4]; + nvt[4] = (void *)&hkdInputExtraMouseSample; + } VTABLE((void *)g_input) = nvt; - logf("CInput CreateMove hooked: slot 3 orig=%p", (void *)oInputCreateMove); + logf("CInput CreateMove hooked: slot 3 orig=%p; ExtraMouseSample slot 4 " + "orig=%p", + (void *)oInputCreateMove, (void *)oInputExtraMouseSample); return true; } -- cgit v1.2.3