summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/studio.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/src/studio.cpp b/src/studio.cpp
index 69a2e07..8b0a710 100644
--- a/src/studio.cpp
+++ b/src/studio.cpp
@@ -212,6 +212,20 @@ ModelExecFn g_orig_model_exec = nullptr;
212ForceOverrideFn g_force_override = nullptr; 212ForceOverrideFn g_force_override = nullptr;
213void *g_style_mats[8] = {}; 213void *g_style_mats[8] = {};
214 214
215// The engine forces a material for special passes (shadow depth, reflections)
216// and clears it again. Without tracking that, the chams pass could not tell
217// "no override" from "engine override in progress": it hijacked the shadow pass
218// with chams materials and then cleared the engine's override for every model
219// drawn afterwards.
220static ForceOverrideFn g_real_force_override = nullptr;
221static void *g_current_override = nullptr;
222
223static void hkdForceOverride(void *self, void *mat, int type) {
224 g_current_override = mat;
225 if (g_real_force_override)
226 g_real_force_override(self, mat, type);
227}
228
215const char *chams_material_name(int idx) { 229const char *chams_material_name(int idx) {
216 switch (idx) { 230 switch (idx) {
217 case 1: return "debug/debugwireframe"; 231 case 1: return "debug/debugwireframe";
@@ -330,6 +344,12 @@ void hkdModelExecute(void *self, const void *state, const void *info,
330 g_orig_model_exec(self, state, info, bone); 344 g_orig_model_exec(self, state, info, bone);
331 return; 345 return;
332 } 346 }
347 // Shadow-depth/reflection passes arrive with a material already forced. Let
348 // them draw normally instead of substituting chams.
349 if (g_current_override) {
350 g_orig_model_exec(self, state, info, bone);
351 return;
352 }
333 if (feature_active(FEAT_CHAMS) && info && g_force_override) { 353 if (feature_active(FEAT_CHAMS) && info && g_force_override) {
334 // ModelRenderInfo_t::entity_index is at 0x30 on 32-bit. 354 // ModelRenderInfo_t::entity_index is at 0x30 on 32-bit.
335 int idx = *(const int *)((const char *)info + 0x30); 355 int idx = *(const int *)((const char *)info + 0x30);
@@ -568,7 +588,8 @@ void chams_init() {
568 logf("chams: model render has no vtable"); 588 logf("chams: model render has no vtable");
569 return; 589 return;
570 } 590 }
571 g_force_override = (ForceOverrideFn)vt[1]; 591 g_real_force_override = (ForceOverrideFn)vt[1];
592 g_force_override = g_real_force_override;
572 g_orig_model_exec = (ModelExecFn)vt[19]; 593 g_orig_model_exec = (ModelExecFn)vt[19];
573 if (!mod_engine().contains((uintptr_t)g_force_override) || 594 if (!mod_engine().contains((uintptr_t)g_force_override) ||
574 !mod_engine().contains((uintptr_t)g_orig_model_exec)) { 595 !mod_engine().contains((uintptr_t)g_orig_model_exec)) {
@@ -581,6 +602,7 @@ void chams_init() {
581 logf("chams: vtable clone failed"); 602 logf("chams: vtable clone failed");
582 return; 603 return;
583 } 604 }
605 nvt[1] = (void *)&hkdForceOverride; // track engine-forced passes
584 nvt[19] = (void *)&hkdModelExecute; 606 nvt[19] = (void *)&hkdModelExecute;
585 g_modelrender = g_iface.modelrender; 607 g_modelrender = g_iface.modelrender;
586 *(void ***)g_modelrender = nvt; 608 *(void ***)g_modelrender = nvt;