summaryrefslogtreecommitdiffstats
path: root/src/world.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/world.cpp')
-rw-r--r--src/world.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/world.cpp b/src/world.cpp
index 2fa1fc4..ab0c134 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -999,3 +999,50 @@ void skybox_update() {
999 g_sky_retry_at = now + 1.0; 999 g_sky_retry_at = now + 1.0;
1000 } 1000 }
1001} 1001}
1002
1003// Find a loaded material by its full name (e.g. "models/debug/debugwhite").
1004// Used by chams; walks the material list like the tint code and falls back to
1005// FindMaterial if the material is not currently resident.
1006void *world_find_material(const char *name) {
1007 if (!name || !*name)
1008 return nullptr;
1009 void *ms = material_system();
1010 if (!ms)
1011 return nullptr;
1012 using FirstFn = unsigned short (*)(void *);
1013 using NextFn = unsigned short (*)(void *, unsigned short);
1014 using InvalidFn = unsigned short (*)(void *);
1015 using GetFn = void *(*)(void *, unsigned short);
1016 using CountFn = int (*)(void *);
1017 using NameFn = const char *(*)(void *);
1018 FirstFn first = (FirstFn)vfunc<FirstFn>(ms, 73);
1019 NextFn next = (NextFn)vfunc<NextFn>(ms, 74);
1020 InvalidFn invalid = (InvalidFn)vfunc<InvalidFn>(ms, 75);
1021 GetFn get = (GetFn)vfunc<GetFn>(ms, 76);
1022 CountFn count = (CountFn)vfunc<CountFn>(ms, 77);
1023 int total = count ? count(ms) : 0;
1024 if (total > 0 && total < 200000) {
1025 unsigned short h = first(ms);
1026 unsigned short inv = invalid(ms);
1027 for (int i = 0; i < total && h != inv; i++) {
1028 void *mat = get(ms, h);
1029 if (mat) {
1030 NameFn mat_name = (NameFn)vfunc<NameFn>(mat, 0);
1031 const char *n = mat_name(mat);
1032 if (n && strcmp(n, name) == 0)
1033 return mat;
1034 }
1035 h = next(ms, h);
1036 }
1037 }
1038 // Not resident yet: let the material system load it. FindMaterial is slot
1039 // 71 (IsMaterialLoaded is 72, FirstMaterial 73).
1040 using FindFn = void *(*)(void *, const char *, const char *, bool,
1041 const char *);
1042 void *mat = vfunc<FindFn>(ms, 71)(ms, name, "Model textures", false, nullptr);
1043 if (!mat)
1044 return nullptr;
1045 NameFn mat_name = (NameFn)vfunc<NameFn>(mat, 0);
1046 const char *n = mat_name(mat);
1047 return (n && strcmp(n, name) == 0) ? mat : nullptr;
1048}