summaryrefslogtreecommitdiffstats
path: root/src/studio.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-04 18:43:28 +0100
committersalmonik <salmonik@tuta.io>2026-11-04 18:43:28 +0100
commitd7201a987ba6cc56fda3d3ea69275307385f7c3e (patch)
tree54d5247ac75adc3b9241c323dbc0ca5db5d35c96 /src/studio.cpp
parentChams: style flags on the resident debug material (diff)
downloadhl2h-d7201a987ba6cc56fda3d3ea69275307385f7c3e.tar.gz
hl2h-d7201a987ba6cc56fda3d3ea69275307385f7c3e.zip
Chams: preload style materials outside the model draw
FindMaterial inside DrawModelExecute did not load the style VMTs, so every style fell back to the solid material. Preload the six style materials from outer_draw (throttled) and have the render hook use the cached pointers only. world_find_material now returns only the exact requested material; the caller falls back to the solid style. Add a vgui/white probe and per-style preload logs.
Diffstat (limited to 'src/studio.cpp')
-rw-r--r--src/studio.cpp65
1 files changed, 50 insertions, 15 deletions
diff --git a/src/studio.cpp b/src/studio.cpp
index 1ca8ad7..44d1bb4 100644
--- a/src/studio.cpp
+++ b/src/studio.cpp
@@ -19,6 +19,7 @@
19#include <cstdio> 19#include <cstdio>
20#include <cstring> 20#include <cstring>
21#include <dlfcn.h> 21#include <dlfcn.h>
22#include <time.h>
22 23
23namespace { 24namespace {
24 25
@@ -196,34 +197,37 @@ using ForceOverrideFn = void (*)(void *, void *, int);
196void *g_modelrender = nullptr; 197void *g_modelrender = nullptr;
197ModelExecFn g_orig_model_exec = nullptr; 198ModelExecFn g_orig_model_exec = nullptr;
198ForceOverrideFn g_force_override = nullptr; 199ForceOverrideFn g_force_override = nullptr;
199void *g_chams_mat = nullptr; 200void *g_style_mats[6] = {};
200int g_chams_mat_idx = -1; 201
202void *viewmodel_material();
201 203
202const char *chams_material_name(int idx) { 204const char *chams_material_name(int idx) {
203 (void)idx; 205 switch (idx) {
204 // Only this debug material is reliably resident in the base game; the other 206 case 1: return "debug/debugwireframe";
205 // debug VMTs are not loaded and FindMaterial does not make them available. 207 case 2: return "debug/additivevertexcolorvertexalpha";
206 // Visual styles are applied as material flags instead. 208 case 3: return "debug/debugtranslucentsinglecolor";
207 return "debug/debugtranslucentsinglecolor"; 209 case 4: return "debug/debugtranslucentvertexcolor";
210 case 5: return "debug/debugmrmfullbright2";
211 default: return "models/debug/debugwhite";
212 }
208} 213}
209 214
210void *chams_material() { 215void *chams_material() {
211 int idx = g_chams_mat_index; 216 int idx = g_chams_mat_index;
212 if (idx < 0) idx = 0; 217 if (idx < 0) idx = 0;
213 if (idx > 5) idx = 5; 218 if (idx > 5) idx = 5;
214 if (g_chams_mat && g_chams_mat_idx == idx) 219 if (g_style_mats[idx])
215 return g_chams_mat; 220 return g_style_mats[idx];
216 g_chams_mat = world_find_material(chams_material_name(idx)); 221 if (g_style_mats[3])
217 if (!g_chams_mat) 222 return g_style_mats[3];
218 g_chams_mat = world_find_material("debug/debugtranslucentsinglecolor"); 223 return viewmodel_material();
219 g_chams_mat_idx = idx;
220 logf("chams: style %d -> %p", idx, g_chams_mat);
221 return g_chams_mat;
222} 224}
223 225
224// Viewmodels need a model shader; the VGUI white materials used by some 226// Viewmodels need a model shader; the VGUI white materials used by some
225// styles do not draw skinned models and make the hands/weapon disappear. 227// styles do not draw skinned models and make the hands/weapon disappear.
226void *viewmodel_material() { 228void *viewmodel_material() {
229 if (g_style_mats[3])
230 return g_style_mats[3];
227 static void *mat = nullptr; 231 static void *mat = nullptr;
228 if (!mat) 232 if (!mat)
229 mat = world_find_material("debug/debugtranslucentsinglecolor"); 233 mat = world_find_material("debug/debugtranslucentsinglecolor");
@@ -307,6 +311,37 @@ void hkdModelExecute(void *self, const void *state, const void *info,
307 311
308} // namespace 312} // namespace
309 313
314static double chams_now() {
315 timespec ts;
316 clock_gettime(CLOCK_MONOTONIC, &ts);
317 return (double)ts.tv_sec + (double)ts.tv_nsec * 1e-9;
318}
319
320// Called from outer_draw (outside the model draw) so FindMaterial can load
321// the style VMTs. The render hook only reads the cached pointers.
322void chams_preload() {
323 static double last = 0.0;
324 static bool probed = false;
325 double now = chams_now();
326 if (now - last < 1.5)
327 return;
328 last = now;
329 if (!probed) {
330 probed = true;
331 void *probe = world_find_material("vgui/white");
332 logf("chams: probe vgui/white = %p", probe);
333 }
334 for (int i = 0; i < 6; i++) {
335 if (g_style_mats[i])
336 continue;
337 void *m = world_find_material(chams_material_name(i));
338 if (m) {
339 g_style_mats[i] = m;
340 logf("chams: preloaded style %d %s = %p", i, chams_material_name(i), m);
341 }
342 }
343}
344
310void chams_init() { 345void chams_init() {
311 if (g_modelrender || !g_iface.modelrender) { 346 if (g_modelrender || !g_iface.modelrender) {
312 if (!g_iface.modelrender) 347 if (!g_iface.modelrender)