diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-04 22:09:14 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-04 22:09:14 +0100 |
| commit | 0cbcbfc14997eff39e0c76acf30c48b851ed1f62 (patch) | |
| tree | 19a5b0996bdf9e096f79e9636ebb48b57e10e643 /src/modules.cpp | |
| parent | Chams: real additive material, addref cached materials (diff) | |
| download | hl2h-0cbcbfc14997eff39e0c76acf30c48b851ed1f62.tar.gz hl2h-0cbcbfc14997eff39e0c76acf30c48b851ed1f62.zip | |
Chams: working alpha via RenderView blend and a custom VMT
Testing on :99 showed the material $alpha path is a dead end: UnlitGeneric
takes translucency from the base texture/vertex alpha, and the debug materials
have neither. Follow Amalgam: apply alpha with IVRenderView::SetBlend
(VEngineRenderView014 slot 4) around the model draw, saving/restoring it.
To have something translucent to blend, write a tiny UnlitGeneric VMT with
$model 1 + $translucent 1 + a white base texture to
<game>/<mod>/materials/hl2hake/translucent.vmt (plus a custom/ copy). It is
written by a preload constructor so it exists before the material system scans
its search paths, then loaded once with FindMaterial. Styles 0/3/4/6 use it
when the colour alpha is below 255.
Also:
- Visible wireframe + through-wall: fill the visible silhouette first so the
through-wall pass cannot show in the wireframe gaps, then draw a brightened
contour. Style 6 is now "Solid + contour" (recolour + visible edges).
- find_modules builds local snapshots and publishes them under a mutex; the
setup thread and the server retry could reset the shared vectors live and
crash at startup.
Verified on :99: Solid + alpha 64 renders a see-through viewmodel, Solid +
contour shows a blue fill with bright blue contours, Additive is a translucent
coloured glow and Fullbright is a white additive glow.
Diffstat (limited to '')
| -rw-r--r-- | src/modules.cpp | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/modules.cpp b/src/modules.cpp index b832694..7a82028 100644 --- a/src/modules.cpp +++ b/src/modules.cpp | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | // modules.cpp — /proc/self/maps parsing and module discovery | 1 | // modules.cpp — /proc/self/maps parsing and module discovery |
| 2 | #include "hl2h.h" | 2 | #include "hl2h.h" |
| 3 | #include <elf.h> | 3 | #include <elf.h> |
| 4 | #include <mutex> | ||
| 4 | #include <vector> | 5 | #include <vector> |
| 5 | 6 | ||
| 7 | static std::mutex g_modules_mutex; | ||
| 8 | |||
| 6 | static bool basename_is(const char *path, const char *base) { | 9 | static bool basename_is(const char *path, const char *base) { |
| 7 | size_t pl = strlen(path), bl = strlen(base); | 10 | size_t pl = strlen(path), bl = strlen(base); |
| 8 | if (pl < bl || strcmp(path + pl - bl, base) != 0) | 11 | if (pl < bl || strcmp(path + pl - bl, base) != 0) |
| @@ -11,9 +14,7 @@ static bool basename_is(const char *path, const char *base) { | |||
| 11 | } | 14 | } |
| 12 | 15 | ||
| 13 | void find_modules() { | 16 | void find_modules() { |
| 14 | g_client = Module(); | 17 | Module client, engine, server; |
| 15 | g_engine = Module(); | ||
| 16 | g_server = Module(); | ||
| 17 | FILE *f = fopen("/proc/self/maps", "r"); | 18 | FILE *f = fopen("/proc/self/maps", "r"); |
| 18 | if (!f) | 19 | if (!f) |
| 19 | return; | 20 | return; |
| @@ -41,19 +42,19 @@ void find_modules() { | |||
| 41 | memcpy(clean, path, pl); | 42 | memcpy(clean, path, pl); |
| 42 | clean[pl] = 0; | 43 | clean[pl] = 0; |
| 43 | if (basename_is(clean, "client.so")) | 44 | if (basename_is(clean, "client.so")) |
| 44 | m = &g_client; | 45 | m = &client; |
| 45 | else if (basename_is(clean, "engine.so")) | 46 | else if (basename_is(clean, "engine.so")) |
| 46 | m = &g_engine; | 47 | m = &engine; |
| 47 | else if (basename_is(clean, "server.so")) | 48 | else if (basename_is(clean, "server.so")) |
| 48 | m = &g_server; | 49 | m = &server; |
| 49 | } else { | 50 | } else { |
| 50 | // anon: absorb only as .bss tail after a file-backed range | 51 | // anon: absorb only as .bss tail after a file-backed range |
| 51 | if (g_client.valid() && g_client.ranges.back().file && | 52 | if (client.valid() && client.ranges.back().file && |
| 52 | lo == g_client.ranges.back().hi && hi - lo <= 0x1000000) | 53 | lo == client.ranges.back().hi && hi - lo <= 0x1000000) |
| 53 | m = &g_client; | 54 | m = &client; |
| 54 | else if (g_engine.valid() && g_engine.ranges.back().file && | 55 | else if (engine.valid() && engine.ranges.back().file && |
| 55 | lo == g_engine.ranges.back().hi && hi - lo <= 0x1000000) | 56 | lo == engine.ranges.back().hi && hi - lo <= 0x1000000) |
| 56 | m = &g_engine; | 57 | m = &engine; |
| 57 | } | 58 | } |
| 58 | if (!m) | 59 | if (!m) |
| 59 | continue; | 60 | continue; |
| @@ -71,6 +72,16 @@ void find_modules() { | |||
| 71 | } | 72 | } |
| 72 | } | 73 | } |
| 73 | fclose(f); | 74 | fclose(f); |
| 75 | // setup_thread and resolve_server_netvars can both call this; the old code | ||
| 76 | // reset the shared Module globals and reallocated their vectors live, which | ||
| 77 | // crashed under the startup thread. Publish complete snapshots instead. | ||
| 78 | std::lock_guard<std::mutex> lock(g_modules_mutex); | ||
| 79 | if (client.valid()) | ||
| 80 | g_client = std::move(client); | ||
| 81 | if (engine.valid()) | ||
| 82 | g_engine = std::move(engine); | ||
| 83 | if (server.valid()) | ||
| 84 | g_server = std::move(server); | ||
| 74 | } | 85 | } |
| 75 | 86 | ||
| 76 | // --------------------------------------------------------------------------- | 87 | // --------------------------------------------------------------------------- |
