diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-06 16:19:25 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-06 16:19:25 +0100 |
| commit | 9f0724dcd25a06c5674d30d045dc485a341253b1 (patch) | |
| tree | e7587dd03c0b164113d3b879b18d81fccf332c05 /src/studio.cpp | |
| parent | Chams: leave engine-forced material passes alone (diff) | |
| download | hl2h-9f0724dcd25a06c5674d30d045dc485a341253b1.tar.gz hl2h-9f0724dcd25a06c5674d30d045dc485a341253b1.zip | |
Hooks: central vtable install with restore support
Move vtable patching into hooks.cpp: one call clones the table, validates every
slot, records the originals and installs the clone. Installs happen from the
setup, game and paint threads, so the bookkeeping is mutex-protected.
Client, CInput, IVModelRender, IStudioRender and ISurface all use it, and
hooks_restore_all() can now put every interface back (previously impossible).
Diffstat (limited to '')
| -rw-r--r-- | src/studio.cpp | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/src/studio.cpp b/src/studio.cpp index 8b0a710..275bfba 100644 --- a/src/studio.cpp +++ b/src/studio.cpp | |||
| @@ -597,15 +597,17 @@ void chams_init() { | |||
| 597 | (void *)g_force_override, (void *)g_orig_model_exec); | 597 | (void *)g_force_override, (void *)g_orig_model_exec); |
| 598 | return; | 598 | return; |
| 599 | } | 599 | } |
| 600 | void **nvt = vtable_clone(g_iface.modelrender, 32); | 600 | VtablePatch patches[] = { |
| 601 | if (!nvt) { | 601 | {1, (void *)&hkdForceOverride, |
| 602 | logf("chams: vtable clone failed"); | 602 | reinterpret_cast<void **>(&g_real_force_override)}, // track forced passes |
| 603 | {19, (void *)&hkdModelExecute, | ||
| 604 | reinterpret_cast<void **>(&g_orig_model_exec)}, | ||
| 605 | }; | ||
| 606 | if (!hooks_install_vtable(g_iface.modelrender, 32, patches, 2)) { | ||
| 607 | logf("chams: vtable patch failed"); | ||
| 603 | return; | 608 | return; |
| 604 | } | 609 | } |
| 605 | nvt[1] = (void *)&hkdForceOverride; // track engine-forced passes | ||
| 606 | nvt[19] = (void *)&hkdModelExecute; | ||
| 607 | g_modelrender = g_iface.modelrender; | 610 | g_modelrender = g_iface.modelrender; |
| 608 | *(void ***)g_modelrender = nvt; | ||
| 609 | logf("chams: IVModelRender %p hooked (draw=%p override=%p)", g_modelrender, | 611 | logf("chams: IVModelRender %p hooked (draw=%p override=%p)", g_modelrender, |
| 610 | (void *)g_orig_model_exec, (void *)g_force_override); | 612 | (void *)g_orig_model_exec, (void *)g_force_override); |
| 611 | } | 613 | } |
| @@ -641,24 +643,22 @@ void studio_props_init() { | |||
| 641 | logf("studio: interface has no vtable"); | 643 | logf("studio: interface has no vtable"); |
| 642 | return; | 644 | return; |
| 643 | } | 645 | } |
| 644 | void **vt = vtable_clone(sr, 49); | 646 | VtablePatch patches[] = { |
| 645 | if (!vt) { | 647 | {27, (void *)&hook_set_color, |
| 646 | logf("studio: vtable clone failed"); | 648 | reinterpret_cast<void **>(&g_orig_set_color)}, |
| 649 | {28, (void *)&hook_set_alpha, | ||
| 650 | reinterpret_cast<void **>(&g_orig_set_alpha)}, | ||
| 651 | {29, (void *)&hook_draw_model, | ||
| 652 | reinterpret_cast<void **>(&g_orig_draw_model)}, | ||
| 653 | {30, (void *)&hook_draw_static_prop, | ||
| 654 | reinterpret_cast<void **>(&g_orig_draw_static)}, | ||
| 655 | {46, (void *)&hook_draw_array, | ||
| 656 | reinterpret_cast<void **>(&g_orig_draw_array)}, | ||
| 657 | }; | ||
| 658 | if (!hooks_install_vtable(sr, 49, patches, 5)) { | ||
| 659 | logf("studio: vtable patch failed"); | ||
| 647 | return; | 660 | return; |
| 648 | } | 661 | } |
| 649 | |||
| 650 | g_orig_set_color = (SetColorFn)vt[27]; | ||
| 651 | g_orig_set_alpha = (SetAlphaFn)vt[28]; | ||
| 652 | g_orig_draw_model = (DrawModelFn)vt[29]; | ||
| 653 | g_orig_draw_static = (DrawStaticFn)vt[30]; | ||
| 654 | g_orig_draw_array = (DrawArrayFn)vt[46]; | ||
| 655 | vt[27] = (void *)&hook_set_color; | ||
| 656 | vt[28] = (void *)&hook_set_alpha; | ||
| 657 | vt[29] = (void *)&hook_draw_model; | ||
| 658 | vt[30] = (void *)&hook_draw_static_prop; | ||
| 659 | vt[46] = (void *)&hook_draw_array; | ||
| 660 | |||
| 661 | *(void ***)sr = vt; | ||
| 662 | g_installed = true; | 662 | g_installed = true; |
| 663 | logf("studio: IStudioRender %p hooked (color=%p draw=%p static=%p " | 663 | logf("studio: IStudioRender %p hooked (color=%p draw=%p static=%p " |
| 664 | "array=%p)", sr, (void *)g_orig_set_color, (void *)g_orig_draw_model, | 664 | "array=%p)", sr, (void *)g_orig_set_color, (void *)g_orig_draw_model, |
