From 83b36aaaf146325af2d93dfbaf21eccba91a5d74 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 18:15:18 +0100 Subject: Chams: exact material styles, GUI dropdown, viewmodel hookup - world_find_material now tries the exact requested style first (resident, then FindMaterial) before falling back to debugwhite/vgui white. The old candidate scan returned vgui/white for every style, so all materials looked flat. - Add a real CK_DROPDOWN control (overlay list, outside-click close, config save) and use it for the Chams material selector. - Chams viewmodel toggle included in config/UI. --- src/world.cpp | 73 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 32 deletions(-) (limited to 'src/world.cpp') diff --git a/src/world.cpp b/src/world.cpp index 897ad0a..a2e65cc 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1015,20 +1015,19 @@ void *world_find_material(const char *name) { using GetFn = void *(*)(void *, unsigned short); using CountFn = int (*)(void *); using NameFn = const char *(*)(void *); + using FindFn = void *(*)(void *, const char *, const char *, bool, + const char *); FirstFn first = (FirstFn)vfunc(ms, 73); NextFn next = (NextFn)vfunc(ms, 74); InvalidFn invalid = (InvalidFn)vfunc(ms, 75); GetFn get = (GetFn)vfunc(ms, 76); CountFn count = (CountFn)vfunc(ms, 77); - const char *candidates[] = {name, - "models/debug/debugwhite2", - "models/debug/debugwhite3", - "vgui/white", - "debug/debugtranslucentsinglecolor", - "debug/debugwireframevertexcolorignorez", - nullptr}; - int total = count ? count(ms) : 0; - if (total > 0 && total < 200000) { + static const char *groups[] = {"Model textures", "Other textures", nullptr}; + + auto walk = [&](const char *want) -> void * { + int total = count ? count(ms) : 0; + if (total <= 0 || total >= 200000) + return nullptr; unsigned short h = first(ms); unsigned short inv = invalid(ms); for (int i = 0; i < total && h != inv; i++) { @@ -1036,38 +1035,48 @@ void *world_find_material(const char *name) { if (mat) { NameFn mat_name = (NameFn)vfunc(mat, 0); const char *n = mat_name(mat); - if (n) { - for (int c = 0; candidates[c]; c++) - if (strcmp(n, candidates[c]) == 0) { - logf("chams: material %s = %p", n, mat); - return mat; - } - } + if (n && strcmp(n, want) == 0) + return mat; } h = next(ms, h); } - } - // Not resident yet: let the material system load it. - using FindFn = void *(*)(void *, const char *, const char *, bool, - const char *); - static const char *groups[] = {"Model textures", "Other textures", nullptr}; - for (int c = 0; candidates[c]; c++) { + return nullptr; + }; + auto find = [&](const char *want) -> void * { for (int g = 0; groups[g]; g++) { - void *mat = vfunc(ms, 71)(ms, candidates[c], groups[g], false, - nullptr); + void *mat = vfunc(ms, 71)(ms, want, groups[g], false, nullptr); if (!mat) continue; NameFn mat_name = (NameFn)vfunc(mat, 0); const char *n = mat_name(mat); - if (!n) - continue; - for (int k = 0; candidates[k]; k++) { - if (strcmp(n, candidates[k]) == 0) { - logf("chams: material %s = %p (FindMaterial)", n, mat); - return mat; - } - } + if (n && strcmp(n, want) == 0) + return mat; + } + return nullptr; + }; + + // First the exact style requested (resident or loaded on demand), then only + // the basic white fallbacks. Returning vgui/white before trying the exact + // name made every style look identical. + void *mat = walk(name); + if (!mat) + mat = find(name); + if (mat) { + logf("chams: material %s = %p", name, mat); + return mat; + } + static const char *fallbacks[] = {"models/debug/debugwhite", "vgui/white", + nullptr}; + for (int i = 0; fallbacks[i]; i++) { + mat = walk(fallbacks[i]); + if (!mat) + mat = find(fallbacks[i]); + if (mat) { + logf("chams: material %s (fallback for %s) = %p", fallbacks[i], name, + mat); + return mat; } } + logf("chams: material %s not found", name); return nullptr; } -- cgit v1.2.3