D235: wire videoResetTextureCache into per-stage reset (stale GL texture cache); D311: arm speed-poison choke-point probes

D235 (wrong textures after dying/restarting a level) -- mechanism found
+ fix (M-193). M-108's refutation of the game-side CI-cache theory stands,
but the port has its own TextureCacheMap (port/fast3d/gfx_pc.cpp) keyed by
(source address, palette addrs, fmt, siz, size_bytes, palette_hash) with NO
content check. Stage-texture source addresses live in MEMPOOL_STAGE, which
the per-stage while(!done) block in boss.c resets on every transition
(death/restart included). After the reset, entries keyed into that arena are
stale; if the texpool places a different image at an address that held
another one in the previous run of the level, the lookup hits and returns
the old pixels -- 'wrong textures' only on the reload path, never on a cold
boot. The N64 has no such cache (RSP re-reads DRAM every frame), so this is
a pure port-side defect: videoResetTextureCache() (port/src/video.c) existed
with zero callers and is now called in that block after memaReset
(#ifdef PORT). Re-uploads are pixel-identical; cost is one-time during the
loading screen. GE_D235=1 logs the purged entry count per transition
(cold boot = 0, death/restart > 0) as mechanism evidence; new
gfx_texture_cache_count() accessor backs it. Full 21-level golden sweep:
21/21 PASS (pixel-identical). Live death/restart confirmation is a playtest
item.

D311 (upstream poison source, M-194): every write of model->speed funnels
through modelSetAnimSpeed (startframe<=0 path) or modelSetAnimation2 -- both
now log 'D311: ... ANOMALY' when the incoming value or the resident speed is
non-finite/|v|>1e4 (#ifdef PORT, unconditional-on-fire like the D156
guards; silent in healthy play). The line captures in/resident/startframe/
oldspeed/newspeed/timespeed + model ptr so the next Caverns occurrence pins
the injecting call. Static pass: sub_GAME_7F06FE90 callers all pass
arg2=16.0f (denominator safe); the old->new lerp only circulates values;
bheadAdjustAnimation is the one path where a live player-velocity
corruption reaches model->speed.
This commit is contained in:
James Dansereau committed 2026-09-20 23:46:43 -04:00
1 parent 8d3bd5732a
commit bb508e5ce4
6 files changed
+67 -3

No files matched your search

+5
View File
@@ -563,6 +563,11 @@ void gfx_texture_cache_clear() {
memset(rendering_state.textures, 0, sizeof(rendering_state.textures));
}
/* D235: entry count for the stage-transition probe (boss.c). */
extern "C" int gfx_texture_cache_count(void) {
return (int)gfx_texture_cache.map.size();
}
static bool gfx_texture_cache_lookup(int i, const TextureCacheKey& key) {
TextureCacheMap::iterator it = gfx_texture_cache.map.find(key);
TextureCacheNode** n = &rendering_state.textures[i];