summaryrefslogtreecommitdiffstats
path: root/src/studio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/studio.cpp')
-rw-r--r--src/studio.cpp94
1 files changed, 57 insertions, 37 deletions
diff --git a/src/studio.cpp b/src/studio.cpp
index b428a26..803b6b2 100644
--- a/src/studio.cpp
+++ b/src/studio.cpp
@@ -197,25 +197,25 @@ using ForceOverrideFn = void (*)(void *, void *, int);
197void *g_modelrender = nullptr; 197void *g_modelrender = nullptr;
198ModelExecFn g_orig_model_exec = nullptr; 198ModelExecFn g_orig_model_exec = nullptr;
199ForceOverrideFn g_force_override = nullptr; 199ForceOverrideFn g_force_override = nullptr;
200void *g_style_mats[6] = {}; 200void *g_style_mats[7] = {};
201 201
202void *viewmodel_material(); 202void *viewmodel_material();
203 203
204const char *chams_material_name(int idx) { 204const char *chams_material_name(int idx) {
205 switch (idx) { 205 switch (idx) {
206 case 1: return "debug/debugwireframe"; 206 case 1: return "debug/debugwireframe";
207 case 2: return "vgui/white_additive"; 207 case 2:
208 case 3: return "debug/debugtranslucentsinglecolor"; 208 case 3:
209 case 4: return "debug/debugtranslucentvertexcolor"; 209 case 4:
210 case 5: return "debug/debugmrmfullbright2"; 210 case 5:
211 case 6: return "debug/debugtranslucentsinglecolor";
211 default: return "vgui/white"; // models/debug/debugwhite is EP2-only 212 default: return "vgui/white"; // models/debug/debugwhite is EP2-only
212 } 213 }
213} 214}
214 215
215void *chams_material() { 216void *style_material(int idx) {
216 int idx = g_chams_mat_index;
217 if (idx < 0) idx = 0; 217 if (idx < 0) idx = 0;
218 if (idx > 5) idx = 5; 218 if (idx > 6) idx = 6;
219 if (g_style_mats[idx]) 219 if (g_style_mats[idx])
220 return g_style_mats[idx]; 220 return g_style_mats[idx];
221 if (g_style_mats[3]) 221 if (g_style_mats[3])
@@ -223,8 +223,7 @@ void *chams_material() {
223 return viewmodel_material(); 223 return viewmodel_material();
224} 224}
225 225
226// Viewmodels need a model shader; the VGUI white materials used by some 226// Viewmodels need a model shader; vgui materials do not draw skinned models.
227// styles do not draw skinned models and make the hands/weapon disappear.
228void *viewmodel_material() { 227void *viewmodel_material() {
229 if (g_style_mats[3]) 228 if (g_style_mats[3])
230 return g_style_mats[3]; 229 return g_style_mats[3];
@@ -249,13 +248,15 @@ void chams_color(void *mat, float r, float g, float b) {
249 vfunc<ColorFn>(mat, 28)(mat, r, g, b); 248 vfunc<ColorFn>(mat, 28)(mat, r, g, b);
250} 249}
251 250
252void chams_apply(void *mat, bool ignorez, int style, bool force_white) { 251void chams_apply(void *mat, bool ignorez, int style, bool force_white,
252 const int *rgb) {
253 using FlagFn = void (*)(void *, int, bool); 253 using FlagFn = void (*)(void *, int, bool);
254 float r = force_white ? 1.0f : (float)g_chams_rgb[0] / 255.0f; 254 float r = force_white ? 1.0f : (float)rgb[0] / 255.0f;
255 float g = force_white ? 1.0f : (float)g_chams_rgb[1] / 255.0f; 255 float g = force_white ? 1.0f : (float)rgb[1] / 255.0f;
256 float b = force_white ? 1.0f : (float)g_chams_rgb[2] / 255.0f; 256 float b = force_white ? 1.0f : (float)rgb[2] / 255.0f;
257 chams_color(mat, r, g, b); 257 chams_color(mat, r, g, b);
258 // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright. 258 // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright,
259 // 6 Glow outline (solid base; the wireframe overlay is a second draw).
259 vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez); 260 vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez);
260 vfunc<FlagFn>(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1); 261 vfunc<FlagFn>(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1);
261 vfunc<FlagFn>(mat, 29)(mat, 1 << 7 /* ADDITIVE */, style == 2); 262 vfunc<FlagFn>(mat, 29)(mat, 1 << 7 /* ADDITIVE */, style == 2);
@@ -282,31 +283,50 @@ void hkdModelExecute(void *self, const void *state, const void *info,
282 // ModelRenderInfo_t::entity_index is at 0x30 on 32-bit. 283 // ModelRenderInfo_t::entity_index is at 0x30 on 32-bit.
283 int idx = *(const int *)((const char *)info + 0x30); 284 int idx = *(const int *)((const char *)info + 0x30);
284 if (idx > 0 && idx <= 8192) { 285 if (idx > 0 && idx <= 8192) {
285 bool is_npc = esp_is_npc_index(idx);
286 bool is_vm = g_chams_viewmodel && esp_is_viewmodel_index(idx); 286 bool is_vm = g_chams_viewmodel && esp_is_viewmodel_index(idx);
287 if (is_npc || is_vm) { 287 ChamsGroup *grp = nullptr;
288 int style = g_chams_mat_index; 288 if (!is_vm) {
289 if (style < 0) style = 0; 289 int rel = esp_npc_relation(idx);
290 if (style > 5) style = 5; 290 if (rel >= 0)
291 // VGUI materials do not draw skinned models: use the solid model 291 grp = rel == 0 ? &g_chams_hostile
292 // shader for the viewmodel with the same flags (flat/additive). 292 : rel == 1 ? &g_chams_neutral : &g_chams_friendly;
293 bool vgui_style = (style == 0 || style == 2); 293 }
294 void *mat = (is_vm && vgui_style) ? viewmodel_material() 294 if (is_vm || grp) {
295 : chams_material(); 295 auto draw_pass = [&](int style, const int *rgb,
296 if (!mat) 296 bool ignorez) -> bool {
297 mat = viewmodel_material(); 297 if (style < 0) style = 0;
298 if (mat) { 298 if (style > 6) style = 6;
299 void *mat = style_material(style);
300 if (!mat)
301 return false;
299 bool white = style == 4; 302 bool white = style == 4;
300 if (g_chams_walls && !is_vm) { 303 chams_apply(mat, ignorez, style, white, rgb);
301 chams_apply(mat, true, style, white); 304 g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */);
302 g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */);
303 g_orig_model_exec(self, state, info, bone);
304 }
305 chams_apply(mat, false, style, white);
306 g_force_override(self, mat, 0);
307 g_orig_model_exec(self, state, info, bone); 305 g_orig_model_exec(self, state, info, bone);
308 g_force_override(self, nullptr, 0); 306 if (style == 6) {
307 // Solid base plus a wireframe contour pass for depth.
308 void *wire = g_style_mats[1];
309 if (wire && wire != mat) {
310 chams_apply(wire, ignorez, 1, false, rgb);
311 g_force_override(self, wire, 0);
312 g_orig_model_exec(self, state, info, bone);
313 chams_reset(wire);
314 }
315 }
309 chams_reset(mat); 316 chams_reset(mat);
317 return true;
318 };
319 bool did = false;
320 if (is_vm) {
321 did = draw_pass(g_chams_vm_mat, g_chams_vm_rgb, false);
322 } else {
323 if (grp->inv_on)
324 did |= draw_pass(grp->inv_mat, grp->inv_rgb, true);
325 if (grp->vis_on)
326 did |= draw_pass(grp->vis_mat, grp->vis_rgb, false);
327 }
328 if (did) {
329 g_force_override(self, nullptr, 0);
310 return; 330 return;
311 } 331 }
312 } 332 }
@@ -337,7 +357,7 @@ void chams_preload() {
337 void *probe = world_find_material("vgui/white"); 357 void *probe = world_find_material("vgui/white");
338 logf("chams: probe vgui/white = %p", probe); 358 logf("chams: probe vgui/white = %p", probe);
339 } 359 }
340 for (int i = 0; i < 6; i++) { 360 for (int i = 0; i < 7; i++) {
341 if (g_style_mats[i]) 361 if (g_style_mats[i])
342 continue; 362 continue;
343 void *m = world_find_material(chams_material_name(i)); 363 void *m = world_find_material(chams_material_name(i));