diff options
Diffstat (limited to '')
| -rw-r--r-- | src/studio.cpp | 94 |
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); | |||
| 197 | void *g_modelrender = nullptr; | 197 | void *g_modelrender = nullptr; |
| 198 | ModelExecFn g_orig_model_exec = nullptr; | 198 | ModelExecFn g_orig_model_exec = nullptr; |
| 199 | ForceOverrideFn g_force_override = nullptr; | 199 | ForceOverrideFn g_force_override = nullptr; |
| 200 | void *g_style_mats[6] = {}; | 200 | void *g_style_mats[7] = {}; |
| 201 | 201 | ||
| 202 | void *viewmodel_material(); | 202 | void *viewmodel_material(); |
| 203 | 203 | ||
| 204 | const char *chams_material_name(int idx) { | 204 | const 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 | ||
| 215 | void *chams_material() { | 216 | void *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. | ||
| 228 | void *viewmodel_material() { | 227 | void *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 | ||
| 252 | void chams_apply(void *mat, bool ignorez, int style, bool force_white) { | 251 | void 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)); |
