Skip to content

Commit 0a0431e

Browse files
committed
Release v5.1: raw mouse menu cursor, drain-on-GetCursorPos, registration refactor, pump cap
1 parent 2154efb commit 0a0431e

14 files changed

Lines changed: 278 additions & 146 deletions

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## v5.1
4+
5+
- Raw mouse: hook `IN_MenuMouse` (SofExe `0x4A420`) with Pre/Post callbacks; while inside it, `GetCursorPos` uses the real API so menu cursor motion matches the OS (avoids synthetic cursor lag on connect / low FPS). `detours.yaml` uses `cvar_t*` parameters; `hooks.json` registers Pre/Post; new `in_menumouse.cpp` tracks scope with a depth counter.
6+
- Raw mouse: fold pending mickeys at read time — `GetCursorPos` calls `raw_mouse_drain_pending_raw_for_cursor()` (shared `GetRawInputBuffer` drain with bounded multi-batch emptying) so the virtual cursor stays fresh without waiting on the next pump boundary.
7+
- Raw mouse: `Sys_SendKeyEvents` only resets deltas (`consume_deltas`); raw queue draining is no longer done there — only the `GetCursorPos` path drains (plus lazy registration when not yet registered). Removed `raw_processed_this_frame` / `raw_mouse_on_peek_returned_no_message`; `raw_mouse_process_raw_mouse()` forwards to the same drain helper.
8+
- Raw mouse: registration cleanup — `RawMouseDropRegistration()`, single `RawMouseCommitRawInputRegistration()` for Win32 register + validation; `raw_mouse_ensure_registered` fast-paths when already registered for the same root (skips heavy window resolution on common `DispatchMessageA` calls). Dropped public `raw_mouse_register_input` (only `ensure_registered` needed it).
9+
- Raw mouse: message pump default `MAX_MSG_PER_FRAME` set to **10** with a short comment on the vanilla full-drain vs capped tradeoff.
10+
311
## v5.0
412

513
- Raw mouse: message pump no longer removes `WM_INPUT` from the queue (avoids high-frequency peel cost on high-poll mice). Uses filtered `PeekMessage` bands around `WM_INPUT` when it blocks the head; otherwise `GetMessage` for strict FIFO. When both low-ID and high-ID candidates exist, orders by `MSG.time` with high-band tie-break for mouse/client messages. Raises per-pump cap to 10 dispatched messages; updates `sys_msg_time` and centralizes quit/dispatch in `DispatchOneMsg`.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.0
1+
5.1

build/generated_detours.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ namespace detour_Sys_SendKeyEvents {
153153
tSys_SendKeyEvents oSys_SendKeyEvents = nullptr;
154154
}
155155

156+
namespace detour_IN_MenuMouse {
157+
tIN_MenuMouse oIN_MenuMouse = nullptr;
158+
}
159+
156160
namespace detour_GetCursorPos {
157161
tGetCursorPos oGetCursorPos = nullptr;
158162
}
@@ -568,6 +572,17 @@ namespace detour_Sys_SendKeyEvents {
568572
}
569573
}
570574

575+
namespace detour_IN_MenuMouse {
576+
ManagerType& GetManager() {
577+
static ManagerType* instance = nullptr;
578+
if (!instance) {
579+
static char storage[sizeof(ManagerType)];
580+
instance = new(storage) ManagerType();
581+
}
582+
return *instance;
583+
}
584+
}
585+
571586
namespace detour_GetCursorPos {
572587
ManagerType& GetManager() {
573588
static ManagerType* instance = nullptr;
@@ -735,6 +750,17 @@ namespace detour_CinematicFreeze {
735750
}
736751
}
737752

753+
namespace detour_IN_MenuMouse {
754+
void __cdecl hkIN_MenuMouse(cvar_t* cvar1, cvar_t* cvar2) {
755+
ManagerType& mgr = GetManager();
756+
if (mgr.GetPreCallbackCount() > 0) mgr.DispatchPre(cvar1, cvar2);
757+
if (oIN_MenuMouse) {
758+
oIN_MenuMouse(cvar1, cvar2);
759+
}
760+
if (mgr.GetPostCallbackCount() > 0) mgr.DispatchPost(cvar1, cvar2);
761+
}
762+
}
763+
738764
// Override hooks (hooks.json override: true)
739765
// Note: Override hooks with custom_detour: true are manually installed at runtime and not generated here
740766
namespace detour_CL_Precache_f {

build/generated_detours.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,33 @@ namespace {
10061006
static AutoDetour_Sys_SendKeyEvents g_AutoDetour_Sys_SendKeyEvents;
10071007
}
10081008

1009+
namespace detour_IN_MenuMouse {
1010+
using tIN_MenuMouse = void(__cdecl*)(cvar_t* cvar1, cvar_t* cvar2);
1011+
extern tIN_MenuMouse oIN_MenuMouse;
1012+
using ManagerType = TypedSharedHookManager<void, cvar_t*, cvar_t*>;
1013+
ManagerType& GetManager();
1014+
1015+
void __cdecl hkIN_MenuMouse(cvar_t* cvar1, cvar_t* cvar2);
1016+
}
1017+
1018+
namespace {
1019+
struct AutoDetour_IN_MenuMouse {
1020+
AutoDetour_IN_MenuMouse() {
1021+
using namespace detour_IN_MenuMouse;
1022+
if (!GetDetourSystem().IsDetourRegistered("IN_MenuMouse")) {
1023+
GetDetourSystem().RegisterDetour(
1024+
reinterpret_cast<void*>(0x0004A420),
1025+
reinterpret_cast<void*>(detour_IN_MenuMouse::hkIN_MenuMouse),
1026+
reinterpret_cast<void**>(&detour_IN_MenuMouse::oIN_MenuMouse),
1027+
"IN_MenuMouse",
1028+
DetourModule::SofExe,
1029+
static_cast<size_t>(0));
1030+
}
1031+
}
1032+
};
1033+
static AutoDetour_IN_MenuMouse g_AutoDetour_IN_MenuMouse;
1034+
}
1035+
10091036
namespace detour_GetCursorPos {
10101037
using tGetCursorPos = BOOL(__stdcall*)(LPPOINT lpPoint);
10111038
extern tGetCursorPos oGetCursorPos;

build/generated_registrations.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ extern void r_blendlightmaps_post_callback();
5656
extern void r_blendlightmaps_pre_callback();
5757
extern void raw_mouse_EarlyStartup();
5858
extern void raw_mouse_RefDllLoaded(char const* name);
59+
extern void raw_mouse_in_menumouse_post(cvar_t* cvar1, cvar_t* cvar2);
60+
extern void raw_mouse_in_menumouse_pre(cvar_t*& cvar1, cvar_t*& cvar2);
5961
extern void scaledCon_EarlyStartup();
6062
extern void scaledHud_RefDllLoaded(char const* name);
6163
extern void scaledUIBase_RefDllLoaded(char const* name);
@@ -159,6 +161,19 @@ inline void RegisterAllFeatureHooks() {
159161
100);
160162
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] R_BlendLightmaps post callbacks: %zu\n", mgr.GetPostCallbackCount());
161163
}
164+
detour_IN_MenuMouse::GetManager().RegisterPreCallback(
165+
"raw_mouse", "raw_mouse_in_menumouse_pre",
166+
[](cvar_t*& cvar1, cvar_t*& cvar2) { raw_mouse_in_menumouse_pre(cvar1, cvar2); },
167+
0);
168+
{
169+
auto& mgr = detour_IN_MenuMouse::GetManager();
170+
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MenuMouse manager at 0x%p\n", &mgr);
171+
mgr.RegisterPostCallback(
172+
"raw_mouse", "raw_mouse_in_menumouse_post",
173+
[](cvar_t* cvar1, cvar_t* cvar2) { raw_mouse_in_menumouse_post(cvar1, cvar2); },
174+
0);
175+
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MenuMouse post callbacks: %zu\n", mgr.GetPostCallbackCount());
176+
}
162177
detour_GL_FindImage::GetManager().RegisterPostCallback(
163178
"scaled_ui_base", "gl_findimage_post_callback",
164179
[](void* result, char* filename, int imagetype, char mimap, char allowPicmip) { return gl_findimage_post_callback(result, filename, imagetype, mimap, allowPicmip); },

detours.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,9 @@ functions:
438438
calling_convention: __cdecl
439439
detour_len: 0
440440
params:
441-
- type: void*
441+
- type: cvar_t*
442442
name: cvar1
443-
- type: void*
443+
- type: cvar_t*
444444
name: cvar2
445445

446446
- name: GetCursorPos

hdr/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
Increment version using: ./increment_version.sh
88
*/
99

10-
#define SOFBUDDY_VERSION "5.0"
10+
#define SOFBUDDY_VERSION "5.1"

src/features/raw_mouse/hooks/getcursorpos.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ BOOL getcursorpos_override_callback(
1616
return original(lpPoint);
1717
}
1818

19+
if (raw_mouse_in_menumouse_scope()) {
20+
SOFBUDDY_ASSERT(original != nullptr);
21+
return original(lpPoint);
22+
}
23+
24+
raw_mouse_drain_pending_raw_for_cursor();
25+
1926
if (!lpPoint) {
2027
SetLastError(ERROR_INVALID_PARAMETER);
2128
return FALSE;

src/features/raw_mouse/hooks/hooks.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
[
2+
{
3+
"function": "IN_MenuMouse",
4+
"callback": "raw_mouse_in_menumouse_pre",
5+
"phase": "Pre",
6+
"priority": 0
7+
},
8+
{
9+
"function": "IN_MenuMouse",
10+
"callback": "raw_mouse_in_menumouse_post",
11+
"phase": "Post",
12+
"priority": 0
13+
},
214
{
315
"function": "GetCursorPos",
416
"callback": "getcursorpos_override_callback",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "feature_config.h"
2+
3+
#if FEATURE_RAW_MOUSE
4+
5+
#include "sof_compat.h"
6+
7+
static int raw_mouse_in_menumouse_depth = 0;
8+
9+
bool raw_mouse_in_menumouse_scope() { return raw_mouse_in_menumouse_depth > 0; }
10+
11+
void raw_mouse_in_menumouse_pre(cvar_t*& cvar1, cvar_t*& cvar2) {
12+
(void)cvar1;
13+
(void)cvar2;
14+
++raw_mouse_in_menumouse_depth;
15+
}
16+
17+
void raw_mouse_in_menumouse_post(cvar_t* cvar1, cvar_t* cvar2) {
18+
(void)cvar1;
19+
(void)cvar2;
20+
if (raw_mouse_in_menumouse_depth > 0)
21+
--raw_mouse_in_menumouse_depth;
22+
}
23+
24+
#endif

0 commit comments

Comments
 (0)