Skip to content

Commit c960a62

Browse files
committed
Release v4.6: raw mouse message-pump flow, media timers TimeGetTime
1 parent 4ab03b6 commit c960a62

24 files changed

Lines changed: 340 additions & 613 deletions

CHANGELOG.md

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

3+
## v4.6
4+
5+
- Raw mouse: message-pump–based flow. Replaced engine-frame hooks (IN_MouseMove, IN_MenuMouse, PeekMessageA, GetMessageA) with Sys_SendKeyEvents replacement and dedicated capped two-range pump so WM_INPUT is never peeked or delivered. One GetRawInputBuffer per frame in Sys_SendKeyEvents path; DispatchMessageA only handles window events (registration/clip). Virtual cursor via GetCursorPos/SetCursorPos. WOW64: buffer size×8 and RAWMOUSE at offset 24. Single cvar 0=off, non-zero=on. README updated.
6+
- Media timers: Sys_SendKeyEvents call site (exe 0x65D5E) now uses my_TimeGetTime (QPC) instead of my_Sys_Milliseconds for consistent frame timing.
7+
38
## v4.5
49

5-
- Raw mouse: `_sofbuddy_rawmouse` is now a mode switch (0=off, 1=4.4-style, 2=PH3-style). Mode 1 dispatches WM_INPUT and processes in DispatchMessageA; on Wine we skip raw_mouse_poll() there to avoid double-count. Mode 2 uses two-range PeekMessageA so the message loop does not run when only WM_INPUT is queued; on Windows we use GetRawInputBuffer only in IN_MouseMove/IN_MenuMouse PRE (PH3-style); on Wine we drain WM_INPUT in PRE then poll. PeekMessageA/GetMessageA override hooks and raw_mouse_drain_wm_input() added; README documents modes and relation to PH3.
10+
- Raw mouse: reimplemented with single setting (0=off, non-zero=on). PH3-style only: two-range PeekMessageA so WM_INPUT is never seen; GetMessageA swallows WM_INPUT (no GetRawInputData); one GetRawInputBuffer per frame in IN_MouseMove/IN_MenuMouse Pre; DispatchMessageA returns 0 for WM_INPUT. No per-message processing or drain-from-handle.
611
- Internal menus: SoF Buddy RMF assets renamed from sb_* to shorter names (e.g. sb_perf → cpu, sb_input → input, sb_http → network, sb_tweaks_perf → profiles, sb_scaling → ui_scale).
712
- Docs: README menu.png hero image; raw_mouse and internal_menus README updates. Update-from-zip scripts (Windows/Linux) refinements.
813

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.5
1+
4.6

build/generated_detours.cpp

Lines changed: 9 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ namespace detour_R_BlendLightmaps {
1313
tR_BlendLightmaps oR_BlendLightmaps = nullptr;
1414
}
1515

16-
namespace detour_IN_MouseMove {
17-
tIN_MouseMove oIN_MouseMove = nullptr;
18-
}
19-
2016
namespace detour_VID_CheckChanges {
2117
tVID_CheckChanges oVID_CheckChanges = nullptr;
2218
}
@@ -153,8 +149,8 @@ namespace detour_Sys_GetGameApi {
153149
tSys_GetGameApi oSys_GetGameApi = nullptr;
154150
}
155151

156-
namespace detour_IN_MenuMouse {
157-
tIN_MenuMouse oIN_MenuMouse = nullptr;
152+
namespace detour_Sys_SendKeyEvents {
153+
tSys_SendKeyEvents oSys_SendKeyEvents = nullptr;
158154
}
159155

160156
namespace detour_GetCursorPos {
@@ -165,14 +161,6 @@ namespace detour_DispatchMessageA {
165161
tDispatchMessageA oDispatchMessageA = nullptr;
166162
}
167163

168-
namespace detour_PeekMessageA {
169-
tPeekMessageA oPeekMessageA = nullptr;
170-
}
171-
172-
namespace detour_GetMessageA {
173-
tGetMessageA oGetMessageA = nullptr;
174-
}
175-
176164
namespace detour_GL_BuildPolygonFromSurface {
177165
ManagerType& GetManager() {
178166
static ManagerType* instance = nullptr;
@@ -195,17 +183,6 @@ namespace detour_R_BlendLightmaps {
195183
}
196184
}
197185

198-
namespace detour_IN_MouseMove {
199-
ManagerType& GetManager() {
200-
static ManagerType* instance = nullptr;
201-
if (!instance) {
202-
static char storage[sizeof(ManagerType)];
203-
instance = new(storage) ManagerType();
204-
}
205-
return *instance;
206-
}
207-
}
208-
209186
namespace detour_VID_CheckChanges {
210187
ManagerType& GetManager() {
211188
static ManagerType* instance = nullptr;
@@ -580,7 +557,7 @@ namespace detour_Sys_GetGameApi {
580557
}
581558
}
582559

583-
namespace detour_IN_MenuMouse {
560+
namespace detour_Sys_SendKeyEvents {
584561
ManagerType& GetManager() {
585562
static ManagerType* instance = nullptr;
586563
if (!instance) {
@@ -613,28 +590,6 @@ namespace detour_DispatchMessageA {
613590
}
614591
}
615592

616-
namespace detour_PeekMessageA {
617-
ManagerType& GetManager() {
618-
static ManagerType* instance = nullptr;
619-
if (!instance) {
620-
static char storage[sizeof(ManagerType)];
621-
instance = new(storage) ManagerType();
622-
}
623-
return *instance;
624-
}
625-
}
626-
627-
namespace detour_GetMessageA {
628-
ManagerType& GetManager() {
629-
static ManagerType* instance = nullptr;
630-
if (!instance) {
631-
static char storage[sizeof(ManagerType)];
632-
instance = new(storage) ManagerType();
633-
}
634-
return *instance;
635-
}
636-
}
637-
638593
namespace detour_GL_BuildPolygonFromSurface {
639594
void __cdecl hkGL_BuildPolygonFromSurface(void* msurface_s) {
640595
ManagerType& mgr = GetManager();
@@ -657,17 +612,6 @@ namespace detour_R_BlendLightmaps {
657612
}
658613
}
659614

660-
namespace detour_IN_MouseMove {
661-
void __cdecl hkIN_MouseMove(void* cmd) {
662-
ManagerType& mgr = GetManager();
663-
if (mgr.GetPreCallbackCount() > 0) mgr.DispatchPre(cmd);
664-
if (oIN_MouseMove) {
665-
oIN_MouseMove(cmd);
666-
}
667-
if (mgr.GetPostCallbackCount() > 0) mgr.DispatchPost(cmd);
668-
}
669-
}
670-
671615
namespace detour_VID_CheckChanges {
672616
void __cdecl hkVID_CheckChanges() {
673617
ManagerType& mgr = GetManager();
@@ -791,17 +735,6 @@ namespace detour_CinematicFreeze {
791735
}
792736
}
793737

794-
namespace detour_IN_MenuMouse {
795-
void __cdecl hkIN_MenuMouse(void* cvar1, void* cvar2) {
796-
ManagerType& mgr = GetManager();
797-
if (mgr.GetPreCallbackCount() > 0) mgr.DispatchPre(cvar1, cvar2);
798-
if (oIN_MenuMouse) {
799-
oIN_MenuMouse(cvar1, cvar2);
800-
}
801-
if (mgr.GetPostCallbackCount() > 0) mgr.DispatchPost(cvar1, cvar2);
802-
}
803-
}
804-
805738
// Override hooks (hooks.json override: true)
806739
// Note: Override hooks with custom_detour: true are manually installed at runtime and not generated here
807740
namespace detour_CL_Precache_f {
@@ -888,18 +821,6 @@ namespace detour_GetCursorPos {
888821
}
889822
}
890823

891-
namespace detour_GetMessageA {
892-
BOOL __stdcall hkGetMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) {
893-
return ::getmessagea_override_callback(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, oGetMessageA);
894-
}
895-
}
896-
897-
namespace detour_PeekMessageA {
898-
BOOL __stdcall hkPeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) {
899-
return ::peekmessagea_override_callback(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg, oPeekMessageA);
900-
}
901-
}
902-
903824
namespace detour_R_DrawFont {
904825
void __cdecl hkR_DrawFont(int screenX, int screenY, char* text, int colorPalette, char* font, bool rememberLastColor) {
905826
::hkR_DrawFont(screenX, screenY, text, colorPalette, font, rememberLastColor, oR_DrawFont);
@@ -936,6 +857,12 @@ namespace detour_Sys_Milliseconds {
936857
}
937858
}
938859

860+
namespace detour_Sys_SendKeyEvents {
861+
void __cdecl hkSys_SendKeyEvents() {
862+
::sys_sendkeyevents_override_callback(oSys_SendKeyEvents);
863+
}
864+
}
865+
939866
namespace detour_VID_LoadRefresh {
940867
qboolean __cdecl hkVID_LoadRefresh(char const* name) {
941868
return ::vid_loadrefresh_override_callback(name, oVID_LoadRefresh);

build/generated_detours.h

Lines changed: 15 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,6 @@ namespace {
6161
static AutoDetour_R_BlendLightmaps g_AutoDetour_R_BlendLightmaps;
6262
}
6363

64-
namespace detour_IN_MouseMove {
65-
using tIN_MouseMove = void(__cdecl*)(void* cmd);
66-
extern tIN_MouseMove oIN_MouseMove;
67-
using ManagerType = TypedSharedHookManager<void, void*>;
68-
ManagerType& GetManager();
69-
70-
void __cdecl hkIN_MouseMove(void* cmd);
71-
}
72-
73-
namespace {
74-
struct AutoDetour_IN_MouseMove {
75-
AutoDetour_IN_MouseMove() {
76-
using namespace detour_IN_MouseMove;
77-
if (!GetDetourSystem().IsDetourRegistered("IN_MouseMove")) {
78-
GetDetourSystem().RegisterDetour(
79-
reinterpret_cast<void*>(0x0004A1F0),
80-
reinterpret_cast<void*>(detour_IN_MouseMove::hkIN_MouseMove),
81-
reinterpret_cast<void**>(&detour_IN_MouseMove::oIN_MouseMove),
82-
"IN_MouseMove",
83-
DetourModule::SofExe,
84-
static_cast<size_t>(0));
85-
}
86-
}
87-
};
88-
static AutoDetour_IN_MouseMove g_AutoDetour_IN_MouseMove;
89-
}
90-
9164
namespace detour_VID_CheckChanges {
9265
using tVID_CheckChanges = void(__cdecl*)();
9366
extern tVID_CheckChanges oVID_CheckChanges;
@@ -1006,31 +979,31 @@ namespace {
1006979
static AutoDetour_Sys_GetGameApi g_AutoDetour_Sys_GetGameApi;
1007980
}
1008981

1009-
namespace detour_IN_MenuMouse {
1010-
using tIN_MenuMouse = void(__cdecl*)(void* cvar1, void* cvar2);
1011-
extern tIN_MenuMouse oIN_MenuMouse;
1012-
using ManagerType = TypedSharedHookManager<void, void*, void*>;
982+
namespace detour_Sys_SendKeyEvents {
983+
using tSys_SendKeyEvents = void(__cdecl*)();
984+
extern tSys_SendKeyEvents oSys_SendKeyEvents;
985+
using ManagerType = TypedSharedHookManager<void>;
1013986
ManagerType& GetManager();
1014987

1015-
void __cdecl hkIN_MenuMouse(void* cvar1, void* cvar2);
988+
void __cdecl hkSys_SendKeyEvents();
1016989
}
1017990

1018991
namespace {
1019-
struct AutoDetour_IN_MenuMouse {
1020-
AutoDetour_IN_MenuMouse() {
1021-
using namespace detour_IN_MenuMouse;
1022-
if (!GetDetourSystem().IsDetourRegistered("IN_MenuMouse")) {
992+
struct AutoDetour_Sys_SendKeyEvents {
993+
AutoDetour_Sys_SendKeyEvents() {
994+
using namespace detour_Sys_SendKeyEvents;
995+
if (!GetDetourSystem().IsDetourRegistered("Sys_SendKeyEvents")) {
1023996
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",
997+
reinterpret_cast<void*>(0x00065CF0),
998+
reinterpret_cast<void*>(detour_Sys_SendKeyEvents::hkSys_SendKeyEvents),
999+
reinterpret_cast<void**>(&detour_Sys_SendKeyEvents::oSys_SendKeyEvents),
1000+
"Sys_SendKeyEvents",
10281001
DetourModule::SofExe,
1029-
static_cast<size_t>(0));
1002+
static_cast<size_t>(5));
10301003
}
10311004
}
10321005
};
1033-
static AutoDetour_IN_MenuMouse g_AutoDetour_IN_MenuMouse;
1006+
static AutoDetour_Sys_SendKeyEvents g_AutoDetour_Sys_SendKeyEvents;
10341007
}
10351008

10361009
namespace detour_GetCursorPos {
@@ -1097,67 +1070,3 @@ namespace {
10971070
static AutoDetour_DispatchMessageA g_AutoDetour_DispatchMessageA;
10981071
}
10991072

1100-
namespace detour_PeekMessageA {
1101-
using tPeekMessageA = BOOL(__stdcall*)(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg);
1102-
extern tPeekMessageA oPeekMessageA;
1103-
using ManagerType = TypedSharedHookManager<BOOL, LPMSG, HWND, UINT, UINT, UINT>;
1104-
ManagerType& GetManager();
1105-
1106-
BOOL __stdcall hkPeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg);
1107-
}
1108-
1109-
namespace {
1110-
struct AutoDetour_PeekMessageA {
1111-
AutoDetour_PeekMessageA() {
1112-
using namespace detour_PeekMessageA;
1113-
if (!GetDetourSystem().IsDetourRegistered("PeekMessageA")) {
1114-
void* addr_PeekMessageA = nullptr;
1115-
{
1116-
HMODULE hMod = GetModuleHandleA("user32.dll");
1117-
if (hMod) addr_PeekMessageA = reinterpret_cast<void*>(GetProcAddress(hMod, "PeekMessageA"));
1118-
}
1119-
GetDetourSystem().RegisterDetour(
1120-
addr_PeekMessageA,
1121-
reinterpret_cast<void*>(detour_PeekMessageA::hkPeekMessageA),
1122-
reinterpret_cast<void**>(&detour_PeekMessageA::oPeekMessageA),
1123-
"PeekMessageA",
1124-
DetourModule::Unknown,
1125-
static_cast<size_t>(0));
1126-
}
1127-
}
1128-
};
1129-
static AutoDetour_PeekMessageA g_AutoDetour_PeekMessageA;
1130-
}
1131-
1132-
namespace detour_GetMessageA {
1133-
using tGetMessageA = BOOL(__stdcall*)(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
1134-
extern tGetMessageA oGetMessageA;
1135-
using ManagerType = TypedSharedHookManager<BOOL, LPMSG, HWND, UINT, UINT>;
1136-
ManagerType& GetManager();
1137-
1138-
BOOL __stdcall hkGetMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
1139-
}
1140-
1141-
namespace {
1142-
struct AutoDetour_GetMessageA {
1143-
AutoDetour_GetMessageA() {
1144-
using namespace detour_GetMessageA;
1145-
if (!GetDetourSystem().IsDetourRegistered("GetMessageA")) {
1146-
void* addr_GetMessageA = nullptr;
1147-
{
1148-
HMODULE hMod = GetModuleHandleA("user32.dll");
1149-
if (hMod) addr_GetMessageA = reinterpret_cast<void*>(GetProcAddress(hMod, "GetMessageA"));
1150-
}
1151-
GetDetourSystem().RegisterDetour(
1152-
addr_GetMessageA,
1153-
reinterpret_cast<void*>(detour_GetMessageA::hkGetMessageA),
1154-
reinterpret_cast<void**>(&detour_GetMessageA::oGetMessageA),
1155-
"GetMessageA",
1156-
DetourModule::Unknown,
1157-
static_cast<size_t>(0));
1158-
}
1159-
}
1160-
};
1161-
static AutoDetour_GetMessageA g_AutoDetour_GetMessageA;
1162-
}
1163-

build/generated_registrations.h

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ extern LRESULT dispatchmessagea_override_callback(const MSG* msg, detour_Dispatc
1616
extern void drawteamicons_pre_callback(float*& targetPlayerOrigin, char*& playerName, char*& imageNameTeamIcon, int& redOrBlue);
1717
extern void fs_initfilesystem_override_callback(detour_FS_InitFilesystem::tFS_InitFilesystem original);
1818
extern BOOL getcursorpos_override_callback(LPPOINT lpPoint, detour_GetCursorPos::tGetCursorPos original);
19-
extern BOOL getmessagea_override_callback(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, detour_GetMessageA::tGetMessageA original);
2019
extern void gl_buildpolygonfromsurface_pre_callback(void*& msurface_s);
2120
extern void* gl_findimage_post_callback(void* result, char* filename, int imagetype, char mimap, char allowPicmip);
2221
extern void hd_textures_RefDllLoaded(char const* name);
@@ -42,10 +41,6 @@ extern void http_maps_cl_parseconfigstring_pre_callback();
4241
extern void http_maps_qcommon_frame_post_callback(int msec);
4342
extern void http_maps_qcommon_frame_pre_callback(int& msec);
4443
extern void http_maps_reconnect_f_pre_callback();
45-
extern void in_menumouse_callback(void* cvar1, void* cvar2);
46-
extern void in_menumouse_pre_callback(void*& cvar1, void*& cvar2);
47-
extern void in_mousemove_callback(void* cmd);
48-
extern void in_mousemove_pre_callback(void*& cmd);
4944
extern void internal_menus_EarlyStartup();
5045
extern void internal_menus_M_PushMenu_post(char const* menu_file, char const* parentFrame, bool lock_input);
5146
extern void internal_menus_M_PushMenu_pre(char const*& menu_file, char const*& parentFrame, bool& lock_input);
@@ -57,7 +52,6 @@ extern void lightblend_RefDllLoaded(char const* name);
5752
extern void mediaTimers_EarlyStartup();
5853
extern void mediaTimers_PostCvarInit();
5954
extern void new_system_bug_EarlyStartup();
60-
extern BOOL peekmessagea_override_callback(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg, detour_PeekMessageA::tPeekMessageA original);
6155
extern void r_blendlightmaps_post_callback();
6256
extern void r_blendlightmaps_pre_callback();
6357
extern void raw_mouse_EarlyStartup();
@@ -70,6 +64,7 @@ extern void sofbuddy_cfg_cl_shutdown_post_callback();
7064
extern void sv_shutdowngameprogs_callback();
7165
extern void* sys_getgameapi_override_callback(void* imports, detour_Sys_GetGameApi::tSys_GetGameApi original);
7266
extern int sys_milliseconds_override_callback(detour_Sys_Milliseconds::tSys_Milliseconds original);
67+
extern void sys_sendkeyevents_override_callback(detour_Sys_SendKeyEvents::tSys_SendKeyEvents original);
7368
extern void teamicons_offset_RefDllLoaded(char const* name);
7469
extern void texturemapping_PostCvarInit();
7570
extern void vid_checkchanges_post();
@@ -164,32 +159,6 @@ inline void RegisterAllFeatureHooks() {
164159
100);
165160
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] R_BlendLightmaps post callbacks: %zu\n", mgr.GetPostCallbackCount());
166161
}
167-
detour_IN_MouseMove::GetManager().RegisterPreCallback(
168-
"raw_mouse", "in_mousemove_pre_callback",
169-
[](void*& cmd) { in_mousemove_pre_callback(cmd); },
170-
100);
171-
{
172-
auto& mgr = detour_IN_MouseMove::GetManager();
173-
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MouseMove manager at 0x%p\n", &mgr);
174-
mgr.RegisterPostCallback(
175-
"raw_mouse", "in_mousemove_callback",
176-
[](void* cmd) { in_mousemove_callback(cmd); },
177-
100);
178-
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MouseMove post callbacks: %zu\n", mgr.GetPostCallbackCount());
179-
}
180-
detour_IN_MenuMouse::GetManager().RegisterPreCallback(
181-
"raw_mouse", "in_menumouse_pre_callback",
182-
[](void*& cvar1, void*& cvar2) { in_menumouse_pre_callback(cvar1, cvar2); },
183-
100);
184-
{
185-
auto& mgr = detour_IN_MenuMouse::GetManager();
186-
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MenuMouse manager at 0x%p\n", &mgr);
187-
mgr.RegisterPostCallback(
188-
"raw_mouse", "in_menumouse_callback",
189-
[](void* cvar1, void* cvar2) { in_menumouse_callback(cvar1, cvar2); },
190-
100);
191-
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MenuMouse post callbacks: %zu\n", mgr.GetPostCallbackCount());
192-
}
193162
detour_GL_FindImage::GetManager().RegisterPostCallback(
194163
"scaled_ui_base", "gl_findimage_post_callback",
195164
[](void* result, char* filename, int imagetype, char mimap, char allowPicmip) { return gl_findimage_post_callback(result, filename, imagetype, mimap, allowPicmip); },

0 commit comments

Comments
 (0)