Skip to content

Commit 0f992c9

Browse files
d3nd3cursoragent
andcommitted
Release v7.1: simplify cl_maxfps freeze sync, loading network UI
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 210d56a commit 0f992c9

22 files changed

Lines changed: 96 additions & 385 deletions

CHANGELOG.md

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

3+
## v7.1
4+
5+
### cl_maxfps singleplayer — simplify freeze sync
6+
7+
- **Removed SV/CL throttle pairing** (`Qcommon_Frame` Pre + `SV_Frame` override) and **ExitLevel** / **GameDllLoaded** lifecycle hooks — freeze-flag sync alone fixes the post-cinematic black screen.
8+
- **Kept:** `CL_Frame` NOP patch, sofplus `sp_Sys_Mil` detour, **CinematicFreeze** mirror to exe, **M_PushMenu** Pre clear when game freeze is already off.
9+
- **README:** Documents root cause — throttled `CL_Frame` lets `intermission` run at `Qcommon_Frame` top `Cbuf_Execute` while exe `cinematicfreeze` is still set.
10+
11+
### Internal menus — loading screen & HTTP maps
12+
13+
- **Vanilla `loading.rmf`** for all local loads; custom Buddy loading UI only during **MP connect** or **HTTP maps** download.
14+
- **`loading_network.rmf`:** conditional map/download status panel in loading header via `_sofbuddy_loading_network` (`cninclude` on vanilla loading).
15+
- **`SCR_BeginLoadingPlaque`:** skip redundant second plaque push during HTTP precache (avoids killmenu flash / client instability before spawn); `killmenu` only on custom loading path.
16+
317
## v7.0
418

519
### Scaled UI — per-font glyph snap & XP alignment fixes

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.0
1+
7.1

build/generated_detours.cpp

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,6 @@ namespace detour_drawTeamIcons {
213213
tdrawTeamIcons odrawTeamIcons = nullptr;
214214
}
215215

216-
namespace detour_SV_Frame {
217-
tSV_Frame oSV_Frame = nullptr;
218-
}
219-
220216
namespace detour_M_PushMenu {
221217
tM_PushMenu oM_PushMenu = nullptr;
222218
}
@@ -225,10 +221,6 @@ namespace detour_CinematicFreeze {
225221
tCinematicFreeze oCinematicFreeze = nullptr;
226222
}
227223

228-
namespace detour_ExitLevel {
229-
tExitLevel oExitLevel = nullptr;
230-
}
231-
232224
namespace detour_Sys_Milliseconds {
233225
tSys_Milliseconds oSys_Milliseconds = nullptr;
234226
}
@@ -692,17 +684,6 @@ namespace detour_drawTeamIcons {
692684
}
693685
}
694686

695-
namespace detour_SV_Frame {
696-
ManagerType& GetManager() {
697-
static ManagerType* instance = nullptr;
698-
if (!instance) {
699-
static char storage[sizeof(ManagerType)];
700-
instance = new(storage) ManagerType();
701-
}
702-
return *instance;
703-
}
704-
}
705-
706687
namespace detour_M_PushMenu {
707688
ManagerType& GetManager() {
708689
static ManagerType* instance = nullptr;
@@ -725,17 +706,6 @@ namespace detour_CinematicFreeze {
725706
}
726707
}
727708

728-
namespace detour_ExitLevel {
729-
ManagerType& GetManager() {
730-
static ManagerType* instance = nullptr;
731-
if (!instance) {
732-
static char storage[sizeof(ManagerType)];
733-
instance = new(storage) ManagerType();
734-
}
735-
return *instance;
736-
}
737-
}
738-
739709
namespace detour_Sys_Milliseconds {
740710
ManagerType& GetManager() {
741711
static ManagerType* instance = nullptr;
@@ -947,17 +917,6 @@ namespace detour_CinematicFreeze {
947917
}
948918
}
949919

950-
namespace detour_ExitLevel {
951-
void __cdecl hkExitLevel() {
952-
ManagerType& mgr = GetManager();
953-
if (mgr.GetPreCallbackCount() > 0) mgr.DispatchPre();
954-
if (oExitLevel) {
955-
oExitLevel();
956-
}
957-
if (mgr.GetPostCallbackCount() > 0) mgr.DispatchPost();
958-
}
959-
}
960-
961920
// Override hooks (hooks.json override: true)
962921
// Note: Override hooks with custom_detour: true are manually installed at runtime and not generated here
963922
namespace detour_CL_Precache_f {
@@ -1098,12 +1057,6 @@ namespace detour_SCR_ExecuteLayoutString {
10981057
}
10991058
}
11001059

1101-
namespace detour_SV_Frame {
1102-
void __cdecl hkSV_Frame(int msec) {
1103-
::mfps_sv_frame_override(msec, oSV_Frame);
1104-
}
1105-
}
1106-
11071060
namespace detour_Sys_GetGameApi {
11081061
void* __cdecl hkSys_GetGameApi(void* imports) {
11091062
return ::sys_getgameapi_override_callback(imports, oSys_GetGameApi);

build/generated_detours.h

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,33 +1082,6 @@ namespace {
10821082
static AutoDetour_drawTeamIcons g_AutoDetour_drawTeamIcons;
10831083
}
10841084

1085-
namespace detour_SV_Frame {
1086-
using tSV_Frame = void(__cdecl*)(int msec);
1087-
extern tSV_Frame oSV_Frame;
1088-
using ManagerType = TypedSharedHookManager<void, int>;
1089-
ManagerType& GetManager();
1090-
1091-
void __cdecl hkSV_Frame(int msec);
1092-
}
1093-
1094-
namespace {
1095-
struct AutoDetour_SV_Frame {
1096-
AutoDetour_SV_Frame() {
1097-
using namespace detour_SV_Frame;
1098-
if (!GetDetourSystem().IsDetourRegistered("SV_Frame")) {
1099-
GetDetourSystem().RegisterDetour(
1100-
reinterpret_cast<void*>(0x0005F5B0),
1101-
reinterpret_cast<void*>(detour_SV_Frame::hkSV_Frame),
1102-
reinterpret_cast<void**>(&detour_SV_Frame::oSV_Frame),
1103-
"SV_Frame",
1104-
DetourModule::SofExe,
1105-
static_cast<size_t>(0));
1106-
}
1107-
}
1108-
};
1109-
static AutoDetour_SV_Frame g_AutoDetour_SV_Frame;
1110-
}
1111-
11121085
namespace detour_M_PushMenu {
11131086
using tM_PushMenu = void(__cdecl*)(char const* menu_file, char const* parentFrame, bool lock_input);
11141087
extern tM_PushMenu oM_PushMenu;
@@ -1163,33 +1136,6 @@ namespace {
11631136
static AutoDetour_CinematicFreeze g_AutoDetour_CinematicFreeze;
11641137
}
11651138

1166-
namespace detour_ExitLevel {
1167-
using tExitLevel = void(__cdecl*)();
1168-
extern tExitLevel oExitLevel;
1169-
using ManagerType = TypedSharedHookManager<void>;
1170-
ManagerType& GetManager();
1171-
1172-
void __cdecl hkExitLevel();
1173-
}
1174-
1175-
namespace {
1176-
struct AutoDetour_ExitLevel {
1177-
AutoDetour_ExitLevel() {
1178-
using namespace detour_ExitLevel;
1179-
if (!GetDetourSystem().IsDetourRegistered("ExitLevel")) {
1180-
GetDetourSystem().RegisterDetour(
1181-
reinterpret_cast<void*>(0xAE0A0),
1182-
reinterpret_cast<void*>(detour_ExitLevel::hkExitLevel),
1183-
reinterpret_cast<void**>(&detour_ExitLevel::oExitLevel),
1184-
"ExitLevel",
1185-
DetourModule::GameDll,
1186-
static_cast<size_t>(0));
1187-
}
1188-
}
1189-
};
1190-
static AutoDetour_ExitLevel g_AutoDetour_ExitLevel;
1191-
}
1192-
11931139
namespace detour_Sys_Milliseconds {
11941140
using tSys_Milliseconds = int(__cdecl*)();
11951141
extern tSys_Milliseconds oSys_Milliseconds;

build/generated_registrations.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
extern qboolean cbuf_addlatecommands_override_callback(detour_Cbuf_AddLateCommands::tCbuf_AddLateCommands original);
1111
extern void cinematicfreeze_callback(bool bEnable);
1212
extern void cl_maxfps_EarlyStartup();
13-
extern void cl_maxfps_GameDllLoaded(void* game_export);
14-
extern void cl_maxfps_ShutdownGameProgs();
1513
extern void cl_precache_http_maps_override_callback(detour_CL_Precache_f::tCL_Precache_f original);
1614
extern void console_protection_EarlyStartup();
1715
extern LRESULT dispatchmessagea_override_callback(const MSG* msg, detour_DispatchMessageA::tDispatchMessageA original);
@@ -60,10 +58,7 @@ extern void lightblend_PostCvarInit();
6058
extern void lightblend_RefDllLoaded(char const* name);
6159
extern void mediaTimers_EarlyStartup();
6260
extern void mediaTimers_PostCvarInit();
63-
extern void mfps_ExitLevel_post();
6461
extern void mfps_M_PushMenu_pre(char const*& menu_file, char const*& parentFrame, bool& lock_input);
65-
extern void mfps_qcommon_frame_pre(int& msec);
66-
extern void mfps_sv_frame_override(int msec, detour_SV_Frame::tSV_Frame original);
6762
extern void new_system_bug_EarlyStartup();
6863
extern void r_blendlightmaps_post_callback();
6964
extern void r_blendlightmaps_pre_callback();
@@ -89,12 +84,6 @@ inline void RegisterAllFeatureHooks() {
8984
SharedHookManager::Instance().RegisterCallback(
9085
"EarlyStartup", "cl_maxfps_singleplayer", "cl_maxfps_EarlyStartup",
9186
[]() { cl_maxfps_EarlyStartup(); }, 70, SharedHookPhase::Post);
92-
SharedHookManager::Instance().RegisterCallback<void*>(
93-
"GameDllLoaded", "cl_maxfps_singleplayer", "cl_maxfps_GameDllLoaded",
94-
std::function<void(void*)>([](void* game_export) { cl_maxfps_GameDllLoaded(game_export); }), 50, SharedHookPhase::Post);
95-
SharedHookManager::Instance().RegisterCallback(
96-
"SV_ShutdownGameProgs", "cl_maxfps_singleplayer", "cl_maxfps_ShutdownGameProgs",
97-
[]() { cl_maxfps_ShutdownGameProgs(); }, 90, SharedHookPhase::Pre);
9887
SharedHookManager::Instance().RegisterCallback(
9988
"EarlyStartup", "console_protection", "console_protection_EarlyStartup",
10089
[]() { console_protection_EarlyStartup(); }, 80, SharedHookPhase::Post);
@@ -152,10 +141,6 @@ inline void RegisterAllFeatureHooks() {
152141
SharedHookManager::Instance().RegisterCallback(
153142
"PostCvarInit", "internal_menus", "internal_menus_PostCvarInit",
154143
[]() { internal_menus_PostCvarInit(); }, 70, SharedHookPhase::Post);
155-
detour_Qcommon_Frame::GetManager().RegisterPreCallback(
156-
"cl_maxfps_singleplayer", "mfps_qcommon_frame_pre",
157-
[](int& msec) { mfps_qcommon_frame_pre(msec); },
158-
75);
159144
{
160145
auto& mgr = detour_CinematicFreeze::GetManager();
161146
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] CinematicFreeze manager at 0x%p\n", &mgr);
@@ -169,15 +154,6 @@ inline void RegisterAllFeatureHooks() {
169154
"cl_maxfps_singleplayer", "mfps_M_PushMenu_pre",
170155
[](char const*& menu_file, char const*& parentFrame, bool& lock_input) { mfps_M_PushMenu_pre(menu_file, parentFrame, lock_input); },
171156
85);
172-
{
173-
auto& mgr = detour_ExitLevel::GetManager();
174-
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] ExitLevel manager at 0x%p\n", &mgr);
175-
mgr.RegisterPostCallback(
176-
"cl_maxfps_singleplayer", "mfps_ExitLevel_post",
177-
[]() { mfps_ExitLevel_post(); },
178-
100);
179-
PrintOut(PRINT_LOG, "[RegisterAllFeatureHooks] ExitLevel post callbacks: %zu\n", mgr.GetPostCallbackCount());
180-
}
181157
detour_GL_BuildPolygonFromSurface::GetManager().RegisterPreCallback(
182158
"hd_textures", "gl_buildpolygonfromsurface_pre_callback",
183159
[](void*& msurface_s) { gl_buildpolygonfromsurface_pre_callback(msurface_s); },

compile_commands.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@
7979
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
8080
"file": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy/src/features/cl_maxfps_singleplayer/hooks/cinematicfreeze.cpp"
8181
},
82+
{
83+
"command": "i686-w64-mingw32-g++-posix -c -Ihdr -Isrc -Ibuild/release -MMD -MP -o obj/release/features/cl_maxfps_singleplayer/hooks/m_pushmenu_pre.o src/features/cl_maxfps_singleplayer/hooks/m_pushmenu_pre.cpp -D_WIN32_WINNT=0x0501 -std=c++14 -O3 -fno-omit-frame-pointer -DNDEBUG",
84+
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
85+
"file": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy/src/features/cl_maxfps_singleplayer/hooks/m_pushmenu_pre.cpp"
86+
},
8287
{
8388
"command": "i686-w64-mingw32-g++-posix -c -Ihdr -Isrc -Ibuild/release -MMD -MP -o obj/release/features/cl_maxfps_singleplayer/hooks/sp_sys_mil.o src/features/cl_maxfps_singleplayer/hooks/sp_sys_mil.cpp -D_WIN32_WINNT=0x0501 -std=c++14 -O3 -fno-omit-frame-pointer -DNDEBUG",
8489
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
@@ -219,6 +224,11 @@
219224
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
220225
"file": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy/src/features/internal_menus/hooks/m_pushmenu_pre.cpp"
221226
},
227+
{
228+
"command": "i686-w64-mingw32-g++-posix -c -Ihdr -Isrc -Ibuild/release -MMD -MP -o obj/release/features/internal_menus/hooks/qcommon_frame_post.o src/features/internal_menus/hooks/qcommon_frame_post.cpp -D_WIN32_WINNT=0x0501 -std=c++14 -O3 -fno-omit-frame-pointer -DNDEBUG",
229+
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
230+
"file": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy/src/features/internal_menus/hooks/qcommon_frame_post.cpp"
231+
},
222232
{
223233
"command": "i686-w64-mingw32-g++-posix -c -Ihdr -Isrc -Ibuild/release -MMD -MP -o obj/release/features/internal_menus/hooks/scr_beginloadingplaque_post.o src/features/internal_menus/hooks/scr_beginloadingplaque_post.cpp -D_WIN32_WINNT=0x0501 -std=c++14 -O3 -fno-omit-frame-pointer -DNDEBUG",
224234
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
@@ -509,6 +519,16 @@
509519
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
510520
"file": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy/src/features/scaled_ui_base/hooks/vid_checkchanges.cpp"
511521
},
522+
{
523+
"command": "i686-w64-mingw32-g++-posix -c -Ihdr -Isrc -Ibuild/release -MMD -MP -o obj/release/features/scaled_ui_base/ref_gl_state.o src/features/scaled_ui_base/ref_gl_state.cpp -D_WIN32_WINNT=0x0501 -std=c++14 -O3 -fno-omit-frame-pointer -DNDEBUG",
524+
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
525+
"file": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy/src/features/scaled_ui_base/ref_gl_state.cpp"
526+
},
527+
{
528+
"command": "i686-w64-mingw32-g++-posix -c -Ihdr -Isrc -Ibuild/release -MMD -MP -o obj/release/features/scaled_ui_base/scale_round.o src/features/scaled_ui_base/scale_round.cpp -D_WIN32_WINNT=0x0501 -std=c++14 -O3 -fno-omit-frame-pointer -DNDEBUG",
529+
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",
530+
"file": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy/src/features/scaled_ui_base/scale_round.cpp"
531+
},
512532
{
513533
"command": "i686-w64-mingw32-g++-posix -c -Ihdr -Isrc -Ibuild/release -MMD -MP -o obj/release/features/scaled_ui_base/sui_cvars.o src/features/scaled_ui_base/sui_cvars.cpp -D_WIN32_WINNT=0x0501 -std=c++14 -O3 -fno-omit-frame-pointer -DNDEBUG",
514534
"directory": "/home/dinda/git-projects/d3nd3/public/sof/sof_buddy",

detours.yaml

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -830,16 +830,6 @@ functions:
830830
- type: int
831831
name: msec
832832

833-
- name: SV_Frame
834-
module: SofExe
835-
identifier: "0x0005F5B0"
836-
return_type: void
837-
calling_convention: __cdecl
838-
detour_len: 0
839-
params:
840-
- type: int
841-
name: msec
842-
843833
- name: M_PushMenu
844834
module: SofExe
845835
identifier: "0x200C7630"
@@ -864,14 +854,6 @@ functions:
864854
- type: bool
865855
name: bEnable
866856

867-
- name: ExitLevel
868-
module: GameDll
869-
identifier: "0xAE0A0"
870-
return_type: void
871-
calling_convention: __cdecl
872-
detour_len: 0
873-
params: []
874-
875857
- name: Sys_Milliseconds
876858
module: SofExe
877859
identifier: "0x00055930"

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 "7.0"
10+
#define SOFBUDDY_VERSION "7.1"

0 commit comments

Comments
 (0)