summaryrefslogtreecommitdiffstats
path: root/src/hl2h.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-03 22:22:08 +0100
committersalmonik <salmonik@tuta.io>2026-11-03 22:22:08 +0100
commit4b7dd1ca76ff0f97d53038ac9a11165f2fc68528 (patch)
treed30473e54ecbb18f14e54e7cf678e7e7dc1a2a52 /src/hl2h.cpp
parentVischeck: only glass materials are glass; log font/glass diagnostics (diff)
downloadhl2h-4b7dd1ca76ff0f97d53038ac9a11165f2fc68528.tar.gz
hl2h-4b7dd1ca76ff0f97d53038ac9a11165f2fc68528.zip
World: add Fullbright visual feature
- New Visuals card with the usual Active + Bind; default off. Unbound+Active is always-on, a bind makes it hold-to-brighten. - Resolve VEngineCvar004 and set mat_fullbright 1/0 through FindVar (slot 12) and ConVar::SetValue(int) (slot 11), bypassing the console cheat gate. Fall back to ClientCmd if the cvar interface is unavailable. - Reapply after map loads/respawns and persist [fullbright] active/bind. - Log on/off; show an error toast if the cvar cannot be applied.
Diffstat (limited to '')
-rw-r--r--src/hl2h.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/hl2h.cpp b/src/hl2h.cpp
index f95f6ed..ebb9b14 100644
--- a/src/hl2h.cpp
+++ b/src/hl2h.cpp
@@ -123,6 +123,42 @@ float getfov(const QAngle &my_view, const QAngle &aim_ang) {
123 123
124static int g_modified_logged = 0; 124static int g_modified_logged = 0;
125 125
126// VEngineCvar004 / ICvar vtable: IAppSystem has 5 slots, then
127// AllocateDLLIdentifier, RegisterConCommand, UnregisterConCommand,
128// UnregisterConCommands, GetCommandLineValue, FindCommandBase,
129// FindCommandBase const, FindVar -> slot 12.
130// ConCommandBase has two dtor slots, then IsCommand, IsFlagSet, AddFlags,
131// GetName, GetHelpText, IsRegistered, GetDLLIdentifier; ConVar then adds
132// SetValue(const char*), SetValue(float), SetValue(int) -> slot 11.
133bool cvar_set_int(const char *name, int value) {
134 if (!name)
135 return false;
136 if (g_iface.cvar) {
137 using FindVarFn = void *(*)(void *, const char *);
138 void *var = vfunc<FindVarFn>(g_iface.cvar, 12)(g_iface.cvar, name);
139 if (var) {
140 using GetNameFn = const char *(*)(void *);
141 const char *got = vfunc<GetNameFn>(var, 5)(var);
142 if (got && strcmp(got, name) == 0) {
143 using SetIntFn = void (*)(void *, int);
144 vfunc<SetIntFn>(var, 11)(var, value);
145 return true;
146 }
147 }
148 }
149 // Fallback for an engine that does not expose VEngineCvar004: ClientCmd
150 // slot 7. Cheat-protected cvars may still be rejected.
151 if (g_iface.engine) {
152 char cmd[96];
153 snprintf(cmd, sizeof(cmd), "%s %d", name, value);
154 using CmdFn = void (*)(void *, const char *);
155 vfunc<CmdFn>(g_iface.engine, 7)(g_iface.engine, cmd);
156 logd("cvar: fallback command '%s'", cmd);
157 return true;
158 }
159 return false;
160}
161
126void note_modified(const CUserCmd *cmd, int flags, const float *vel) { 162void note_modified(const CUserCmd *cmd, int flags, const float *vel) {
127 // recompute usercmd CRC after modification 163 // recompute usercmd CRC after modification
128 fix_verified_crc(cmd->command_number, usercmd_checksum(cmd)); 164 fix_verified_crc(cmd->command_number, usercmd_checksum(cmd));
@@ -563,6 +599,7 @@ static void do_move(int seq, float frametime) {
563 bones_clear(); 599 bones_clear();
564 aimbot_reset_lock(); 600 aimbot_reset_lock();
565 silentaim_reset_lock(); 601 silentaim_reset_lock();
602 fullbright_invalidate();
566 } 603 }
567 604
568 if (feature_active(FEAT_SPREAD)) { 605 if (feature_active(FEAT_SPREAD)) {
@@ -908,10 +945,36 @@ static void *setup_thread(void *) {
908 g_iface.engineserver = ef("VEngineServer021", nullptr); 945 g_iface.engineserver = ef("VEngineServer021", nullptr);
909 g_iface.debugoverlay = ef("VDebugOverlay003", nullptr); 946 g_iface.debugoverlay = ef("VDebugOverlay003", nullptr);
910 g_iface.enginetrace = ef("EngineTraceClient003", nullptr); 947 g_iface.enginetrace = ef("EngineTraceClient003", nullptr);
948 static const char *cvar_names[] = {"VEngineCvar004", "VEngineCvar007",
949 "VEngineCvar003", "IVEngineCvar004",
950 nullptr};
951 for (int i = 0; cvar_names[i] && !g_iface.cvar; i++) {
952 g_iface.cvar = ef(cvar_names[i], nullptr);
953 if (!g_iface.cvar)
954 g_iface.cvar = cf(cvar_names[i], nullptr);
955 }
956 if (!g_iface.cvar) {
957 size_t slash = g_engine.path.find_last_of('/');
958 if (slash != std::string::npos) {
959 std::string path =
960 g_engine.path.substr(0, slash + 1) + "libvstdlib.so";
961 void *h = dlopen(path.c_str(), RTLD_NOLOAD | RTLD_LAZY | RTLD_GLOBAL);
962 if (!h)
963 h = dlopen(path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
964 if (h) {
965 auto vf = (CreateInterfaceFn)dlsym(h, "CreateInterface");
966 if (vf) {
967 for (int i = 0; cvar_names[i] && !g_iface.cvar; i++)
968 g_iface.cvar = vf(cvar_names[i], nullptr);
969 }
970 }
971 }
972 }
911 logf("modelinfo: %p (VModelInfoClient006)", g_iface.modelinfo); 973 logf("modelinfo: %p (VModelInfoClient006)", g_iface.modelinfo);
912 logf("engineserver: %p (VEngineServer021), debugoverlay: %p, " 974 logf("engineserver: %p (VEngineServer021), debugoverlay: %p, "
913 "enginetrace: %p (EngineTraceClient003)", 975 "enginetrace: %p (EngineTraceClient003)",
914 g_iface.engineserver, g_iface.debugoverlay, g_iface.enginetrace); 976 g_iface.engineserver, g_iface.debugoverlay, g_iface.enginetrace);
977 logf("cvar: %p (VEngineCvar004)", g_iface.cvar);
915 978
916 resolve_netvars(); 979 resolve_netvars();
917 if (!g_net.ok()) 980 if (!g_net.ok())