From a83d3c80d3c555490e7545a191a2c09dd74ca13d Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 12:52:03 +0100 Subject: Props: forward DrawModel's modelOrigin argument DrawModel takes (this, results, info, boneToWorld, flexWeights, flexDelayedWeights, const Vector &modelOrigin, flags). The hook dropped modelOrigin, so flags landed in its slot and the real flags were read from caller stack garbage. studiorender.so 0x83ad0 reads 0x20(%ebp) as the modelOrigin pointer and 0x24(%ebp) as the flags; passing both restores the engine's normal draw. This is the cause of the intermittent (~50%) checkerboard/error-material props: the draw was being issued with a garbage flag word. --- src/studio.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/studio.cpp b/src/studio.cpp index 485b4fb..2d6c826 100644 --- a/src/studio.cpp +++ b/src/studio.cpp @@ -25,8 +25,12 @@ namespace { using SetColorFn = void (*)(void *, const float *); using SetAlphaFn = void (*)(void *, float); using DrawStaticFn = void (*)(void *, void *, void *, int); +// DrawModel takes (this, results, info, boneToWorld, flexWeights, +// flexDelayedWeights, modelOrigin, flags). The modelOrigin argument is a +// `const Vector &`, so it arrives as a pointer; omitting it shifts flags into +// modelOrigin and leaves flags as caller stack garbage. using DrawModelFn = void (*)(void *, void *, void *, void *, void *, void *, - int); + const void *, int); using DrawArrayFn = void (*)(void *, void *, int, void *, int, int); SetColorFn g_orig_set_color = nullptr; @@ -107,16 +111,25 @@ void hook_set_alpha(void *self, float alpha) { void hook_draw_model(void *self, void *results, void *info, void *bone, - void *flex, void *flex_delayed, int flags) { + void *flex, void *flex_delayed, const void *model_origin, + int flags) { const char *model = info_model_name(info); bool prop = prop_tint_on() && is_prop_model(model); + static int prop_logs = 0; + if (prop && prop_logs < 12) { + prop_logs++; + void *client = info ? *(void **)((uintptr_t)info + 24) : nullptr; + logf("studio: prop draw model=\"%s\" client=%p origin=%p flags=%d", + model ? model : "?", client, model_origin, flags); + } if (prop) { float c[4]; prop_color(c); g_orig_set_color(self, c); g_prop_depth++; } - g_orig_draw_model(self, results, info, bone, flex, flex_delayed, flags); + g_orig_draw_model(self, results, info, bone, flex, flex_delayed, + model_origin, flags); if (prop) g_prop_depth--; } -- cgit v1.2.3