summaryrefslogtreecommitdiffstats
path: root/src/world.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-11-04 18:15:18 +0100
committersalmonik <salmonik@tuta.io>2026-11-04 18:15:18 +0100
commit83b36aaaf146325af2d93dfbaf21eccba91a5d74 (patch)
tree2f6cd5a1d38231df4a6650e223681863f651e1df /src/world.cpp
parentChams: material styles and viewmodel support (diff)
downloadhl2h-83b36aaaf146325af2d93dfbaf21eccba91a5d74.tar.gz
hl2h-83b36aaaf146325af2d93dfbaf21eccba91a5d74.zip
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.
Diffstat (limited to 'src/world.cpp')
-rw-r--r--src/world.cpp73
1 files changed, 41 insertions, 32 deletions
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) {
1015 using GetFn = void *(*)(void *, unsigned short); 1015 using GetFn = void *(*)(void *, unsigned short);
1016 using CountFn = int (*)(void *); 1016 using CountFn = int (*)(void *);
1017 using NameFn = const char *(*)(void *); 1017 using NameFn = const char *(*)(void *);
1018 using FindFn = void *(*)(void *, const char *, const char *, bool,
1019 const char *);
1018 FirstFn first = (FirstFn)vfunc<FirstFn>(ms, 73); 1020 FirstFn first = (FirstFn)vfunc<FirstFn>(ms, 73);
1019 NextFn next = (NextFn)vfunc<NextFn>(ms, 74); 1021 NextFn next = (NextFn)vfunc<NextFn>(ms, 74);
1020 InvalidFn invalid = (InvalidFn)vfunc<InvalidFn>(ms, 75); 1022 InvalidFn invalid = (InvalidFn)vfunc<InvalidFn>(ms, 75);
1021 GetFn get = (GetFn)vfunc<GetFn>(ms, 76); 1023 GetFn get = (GetFn)vfunc<GetFn>(ms, 76);
1022 CountFn count = (CountFn)vfunc<CountFn>(ms, 77); 1024 CountFn count = (CountFn)vfunc<CountFn>(ms, 77);
1023 const char *candidates[] = {name, 1025 static const char *groups[] = {"Model textures", "Other textures", nullptr};
1024 "models/debug/debugwhite2", 1026
1025 "models/debug/debugwhite3", 1027 auto walk = [&](const char *want) -> void * {
1026 "vgui/white", 1028 int total = count ? count(ms) : 0;
1027 "debug/debugtranslucentsinglecolor", 1029 if (total <= 0 || total >= 200000)
1028 "debug/debugwireframevertexcolorignorez", 1030 return nullptr;
1029 nullptr};
1030 int total = count ? count(ms) : 0;
1031 if (total > 0 && total < 200000) {
1032 unsigned short h = first(ms); 1031 unsigned short h = first(ms);
1033 unsigned short inv = invalid(ms); 1032 unsigned short inv = invalid(ms);
1034 for (int i = 0; i < total && h != inv; i++) { 1033 for (int i = 0; i < total && h != inv; i++) {
@@ -1036,38 +1035,48 @@ void *world_find_material(const char *name) {
1036 if (mat) { 1035 if (mat) {
1037 NameFn mat_name = (NameFn)vfunc<NameFn>(mat, 0); 1036 NameFn mat_name = (NameFn)vfunc<NameFn>(mat, 0);
1038 const char *n = mat_name(mat); 1037 const char *n = mat_name(mat);
1039 if (n) { 1038 if (n && strcmp(n, want) == 0)
1040 for (int c = 0; candidates[c]; c++) 1039 return mat;
1041 if (strcmp(n, candidates[c]) == 0) {
1042 logf("chams: material %s = %p", n, mat);
1043 return mat;
1044 }
1045 }
1046 } 1040 }
1047 h = next(ms, h); 1041 h = next(ms, h);
1048 } 1042 }
1049 } 1043 return nullptr;
1050 // Not resident yet: let the material system load it. 1044 };
1051 using FindFn = void *(*)(void *, const char *, const char *, bool, 1045 auto find = [&](const char *want) -> void * {
1052 const char *);
1053 static const char *groups[] = {"Model textures", "Other textures", nullptr};
1054 for (int c = 0; candidates[c]; c++) {
1055 for (int g = 0; groups[g]; g++) { 1046 for (int g = 0; groups[g]; g++) {
1056 void *mat = vfunc<FindFn>(ms, 71)(ms, candidates[c], groups[g], false, 1047 void *mat = vfunc<FindFn>(ms, 71)(ms, want, groups[g], false, nullptr);
1057 nullptr);
1058 if (!mat) 1048 if (!mat)
1059 continue; 1049 continue;
1060 NameFn mat_name = (NameFn)vfunc<NameFn>(mat, 0); 1050 NameFn mat_name = (NameFn)vfunc<NameFn>(mat, 0);
1061 const char *n = mat_name(mat); 1051 const char *n = mat_name(mat);
1062 if (!n) 1052 if (n && strcmp(n, want) == 0)
1063 continue; 1053 return mat;
1064 for (int k = 0; candidates[k]; k++) { 1054 }
1065 if (strcmp(n, candidates[k]) == 0) { 1055 return nullptr;
1066 logf("chams: material %s = %p (FindMaterial)", n, mat); 1056 };
1067 return mat; 1057
1068 } 1058 // First the exact style requested (resident or loaded on demand), then only
1069 } 1059 // the basic white fallbacks. Returning vgui/white before trying the exact
1060 // name made every style look identical.
1061 void *mat = walk(name);
1062 if (!mat)
1063 mat = find(name);
1064 if (mat) {
1065 logf("chams: material %s = %p", name, mat);
1066 return mat;
1067 }
1068 static const char *fallbacks[] = {"models/debug/debugwhite", "vgui/white",
1069 nullptr};
1070 for (int i = 0; fallbacks[i]; i++) {
1071 mat = walk(fallbacks[i]);
1072 if (!mat)
1073 mat = find(fallbacks[i]);
1074 if (mat) {
1075 logf("chams: material %s (fallback for %s) = %p", fallbacks[i], name,
1076 mat);
1077 return mat;
1070 } 1078 }
1071 } 1079 }
1080 logf("chams: material %s not found", name);
1072 return nullptr; 1081 return nullptr;
1073} 1082}