Skip to content

Commit 4ab03b6

Browse files
committed
Release v4.5: raw mouse modes 0/1/2, Wine/PH3 path, internal menu RMF renames
1 parent 0c7723c commit 4ab03b6

59 files changed

Lines changed: 578 additions & 317 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

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

3+
## v4.5
4+
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.
6+
- 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).
7+
- Docs: README menu.png hero image; raw_mouse and internal_menus README updates. Update-from-zip scripts (Windows/Linux) refinements.
8+
39
## v4.4
410

511
- Raw mouse: reworked raw input pipeline to buffer and drain high-Hz `WM_INPUT` via `GetRawInputBuffer`, skip zero-delta packets, and keep the game's original mouse cvars/flow intact while sourcing movement from hardware deltas instead of OS cursor position.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
- **`F12`** (or **`bind <key> sofbuddy_menu sof_buddy`**) — **Open the SoF Buddy menu. Use this. It’s the main entry point for all settings, updater, and profiles.**
107107
- `sofbuddy_list_features` — Print compiled features (and whether they are on/off).
108108
- `sofbuddy_menu <name>` — Open an embedded internal menu page (examples: `loading`, `sof_buddy`).
109-
- `sofbuddy_menu <menu>/<page>` — Open a specific embedded page (e.g. `sofbuddy_menu sof_buddy/sb_perf`).
109+
- `sofbuddy_menu <menu>/<page>` — Open a specific embedded page (e.g. `sofbuddy_menu sof_buddy/cpu`).
110110
- `sofbuddy_apply_menu_hotkey` — Re-apply bind from `_sofbuddy_menu_hotkey` (default `F12`).
111111
- `sofbuddy_apply_profile_comp` — Apply competitive/low-visual profile preset.
112112
- `sofbuddy_apply_profile_visual` — Apply visual/high-fidelity profile preset.

VERSION

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

build/generated_detours.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,14 @@ namespace detour_DispatchMessageA {
165165
tDispatchMessageA oDispatchMessageA = nullptr;
166166
}
167167

168+
namespace detour_PeekMessageA {
169+
tPeekMessageA oPeekMessageA = nullptr;
170+
}
171+
172+
namespace detour_GetMessageA {
173+
tGetMessageA oGetMessageA = nullptr;
174+
}
175+
168176
namespace detour_GL_BuildPolygonFromSurface {
169177
ManagerType& GetManager() {
170178
static ManagerType* instance = nullptr;
@@ -605,6 +613,28 @@ namespace detour_DispatchMessageA {
605613
}
606614
}
607615

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+
608638
namespace detour_GL_BuildPolygonFromSurface {
609639
void __cdecl hkGL_BuildPolygonFromSurface(void* msurface_s) {
610640
ManagerType& mgr = GetManager();
@@ -858,6 +888,18 @@ namespace detour_GetCursorPos {
858888
}
859889
}
860890

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+
861903
namespace detour_R_DrawFont {
862904
void __cdecl hkR_DrawFont(int screenX, int screenY, char* text, int colorPalette, char* font, bool rememberLastColor) {
863905
::hkR_DrawFont(screenX, screenY, text, colorPalette, font, rememberLastColor, oR_DrawFont);

build/generated_detours.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,3 +1097,67 @@ namespace {
10971097
static AutoDetour_DispatchMessageA g_AutoDetour_DispatchMessageA;
10981098
}
10991099

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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ 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);
1920
extern void gl_buildpolygonfromsurface_pre_callback(void*& msurface_s);
2021
extern void* gl_findimage_post_callback(void* result, char* filename, int imagetype, char mimap, char allowPicmip);
2122
extern void hd_textures_RefDllLoaded(char const* name);
@@ -42,7 +43,9 @@ extern void http_maps_qcommon_frame_post_callback(int msec);
4243
extern void http_maps_qcommon_frame_pre_callback(int& msec);
4344
extern void http_maps_reconnect_f_pre_callback();
4445
extern void in_menumouse_callback(void* cvar1, void* cvar2);
46+
extern void in_menumouse_pre_callback(void*& cvar1, void*& cvar2);
4547
extern void in_mousemove_callback(void* cmd);
48+
extern void in_mousemove_pre_callback(void*& cmd);
4649
extern void internal_menus_EarlyStartup();
4750
extern void internal_menus_M_PushMenu_post(char const* menu_file, char const* parentFrame, bool lock_input);
4851
extern void internal_menus_M_PushMenu_pre(char const*& menu_file, char const*& parentFrame, bool& lock_input);
@@ -54,6 +57,7 @@ extern void lightblend_RefDllLoaded(char const* name);
5457
extern void mediaTimers_EarlyStartup();
5558
extern void mediaTimers_PostCvarInit();
5659
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);
5761
extern void r_blendlightmaps_post_callback();
5862
extern void r_blendlightmaps_pre_callback();
5963
extern void raw_mouse_EarlyStartup();
@@ -160,6 +164,10 @@ inline void RegisterAllFeatureHooks() {
160164
100);
161165
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] R_BlendLightmaps post callbacks: %zu\n", mgr.GetPostCallbackCount());
162166
}
167+
detour_IN_MouseMove::GetManager().RegisterPreCallback(
168+
"raw_mouse", "in_mousemove_pre_callback",
169+
[](void*& cmd) { in_mousemove_pre_callback(cmd); },
170+
100);
163171
{
164172
auto& mgr = detour_IN_MouseMove::GetManager();
165173
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MouseMove manager at 0x%p\n", &mgr);
@@ -169,6 +177,10 @@ inline void RegisterAllFeatureHooks() {
169177
100);
170178
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MouseMove post callbacks: %zu\n", mgr.GetPostCallbackCount());
171179
}
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);
172184
{
173185
auto& mgr = detour_IN_MenuMouse::GetManager();
174186
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] IN_MenuMouse manager at 0x%p\n", &mgr);

detours.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,37 @@ functions:
454454
params:
455455
- type: const MSG*
456456
name: msg
457+
458+
- name: PeekMessageA
459+
module: Unknown
460+
identifier: "PeekMessageA"
461+
return_type: BOOL
462+
calling_convention: __stdcall
463+
detour_len: 0
464+
params:
465+
- type: LPMSG
466+
name: lpMsg
467+
- type: HWND
468+
name: hWnd
469+
- type: UINT
470+
name: wMsgFilterMin
471+
- type: UINT
472+
name: wMsgFilterMax
473+
- type: UINT
474+
name: wRemoveMsg
475+
476+
- name: GetMessageA
477+
module: Unknown
478+
identifier: "GetMessageA"
479+
return_type: BOOL
480+
calling_convention: __stdcall
481+
detour_len: 0
482+
params:
483+
- type: LPMSG
484+
name: lpMsg
485+
- type: HWND
486+
name: hWnd
487+
- type: UINT
488+
name: wMsgFilterMin
489+
- type: UINT
490+
name: wMsgFilterMax

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 "4.4"
10+
#define SOFBUDDY_VERSION "4.5"

rsrc/lin_scripts/update_from_zip.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ else
5151
echo "Warning: could not delete ${ZIP_PATH}"
5252
fi
5353
echo
54-
echo "Searching for old configuration to prune..."
55-
find "${ROOT_DIR}" -type f -name "sofbuddy.cfg" -print -delete 2>/dev/null || true
54+
read -r -p "Start with fresh settings? [Y/n]: " ans
55+
if [[ ! "${ans,,}" =~ ^n(o)?$ ]]; then
56+
echo "Searching for old configuration to prune..."
57+
find "${ROOT_DIR}" -type f -name "sofbuddy.cfg" -print -delete 2>/dev/null || true
58+
fi
5659
echo
5760
echo "You can now launch SoF normally."

rsrc/win_scripts/update_from_zip.cmd

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,15 @@ if /i "!EXTRACT_METHOD!"=="vbscript" (
7777
)
7878
)
7979
echo.
80-
echo Searching for old configuration to prune...
81-
for /r "%ROOT_DIR%" %%F in (sofbuddy.cfg) do (
82-
if exist "%%F" (
83-
echo Removing: %%F
84-
del /f /q "%%F" >nul 2>&1
80+
set "FRESH=Y"
81+
set /p "FRESH=Start with fresh settings? [Y/n]: "
82+
if /i not "!FRESH!"=="n" (
83+
echo Searching for old configuration to prune...
84+
for /r "%ROOT_DIR%" %%F in (sofbuddy.cfg) do (
85+
if exist "%%F" (
86+
echo Removing: %%F
87+
del /f /q "%%F" >nul 2>&1
88+
)
8589
)
8690
)
8791
echo.

0 commit comments

Comments
 (0)