From 998eee9c618775bd00b60b42d2a9390aa65844c5 Mon Sep 17 00:00:00 2001 From: Jonaeru Date: Fri, 1 May 2026 21:28:41 +0900 Subject: [PATCH] Fix menu character and weapon texture corruption --- port/fast3d/gfx_api.h | 1 + port/fast3d/gfx_pc.cpp | 23 +++++++++++++++++++++++ port/include/video.h | 1 + port/src/video.c | 5 +++++ src/game/menu.c | 8 ++++++++ 5 files changed, 38 insertions(+) diff --git a/port/fast3d/gfx_api.h b/port/fast3d/gfx_api.h index 6a0bc3f43..327aa835e 100644 --- a/port/fast3d/gfx_api.h +++ b/port/fast3d/gfx_api.h @@ -48,6 +48,7 @@ void gfx_set_texture_filter(enum FilteringMode mode); void gfx_set_mipmap_filter(enum MipmapFilteringMode mode); void gfx_texture_cache_clear(void); void gfx_texture_cache_delete(const uint8_t *orig_addr); +void gfx_texture_cache_delete_range(const uint8_t *start, const uint8_t *end); int gfx_create_framebuffer(uint32_t width, uint32_t height, int upscale, int autoresize); void gfx_resize_framebuffer(int fb, uint32_t width, uint32_t height, int upscale, int autoresize); void gfx_set_framebuffer(int fb, float noise_scale) ; diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 269bd72b4..e0f66734d 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -585,6 +585,29 @@ void gfx_texture_cache_delete(const uint8_t* orig_addr) { } } +void gfx_texture_cache_delete_range(const uint8_t* start, const uint8_t* end) { + gfx_flush(); + + for (int i = 0; i < 2; ++i) { + if (rendering_state.textures[i] + && rendering_state.textures[i]->first.texture_addr >= start + && rendering_state.textures[i]->first.texture_addr < end) { + rdp.textures_changed[i] = true; + rendering_state.textures[i] = nullptr; + } + } + + for (auto it = gfx_texture_cache.map.begin(); it != gfx_texture_cache.map.end(); ) { + if (it->first.texture_addr >= start && it->first.texture_addr < end) { + gfx_texture_cache.lru.erase(it->second.lru_location); + gfx_texture_cache.free_texture_ids.push_back(it->second.texture_id); + it = gfx_texture_cache.map.erase(it); + } else { + ++it; + } + } +} + static void import_texture_rgba16(int tile, const LoadedTexture& loaded_texture, bool gen_mipmaps) { const uint8_t* addr = loaded_texture.addr; const uint32_t size_bytes = loaded_texture.size_bytes; diff --git a/port/include/video.h b/port/include/video.h index d0a81a29d..c9bb97f92 100644 --- a/port/include/video.h +++ b/port/include/video.h @@ -74,6 +74,7 @@ s32 videoFramebuffersSupported(void); void videoResetTextureCache(void); void videoFreeCachedTexture(const void *texptr); +void videoFreeCachedTextures(const void *start, const void *end); void videoShutdown(void); diff --git a/port/src/video.c b/port/src/video.c index 63ad78293..3f1247d0c 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -530,6 +530,11 @@ void videoFreeCachedTexture(const void *texptr) gfx_texture_cache_delete(texptr); } +void videoFreeCachedTextures(const void *start, const void *end) +{ + gfx_texture_cache_delete_range(start, end); +} + void videoShutdown(void) { free(vidModes); diff --git a/src/game/menu.c b/src/game/menu.c index c9f4cca3a..5e0699f1d 100644 --- a/src/game/menu.c +++ b/src/game/menu.c @@ -1928,6 +1928,10 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) totalfilelen += 0x4000; #endif +#ifndef PLATFORM_N64 + videoFreeCachedTextures(menumodel->allocstart, menumodel->allocstart + menumodel->alloclen); +#endif + texInitPool(&texpool, menumodel->allocstart + totalfilelen, menumodel->alloclen - totalfilelen); menumodel->headnum = headnum; @@ -1960,6 +1964,10 @@ Gfx *menuRenderModel(Gfx *gdl, struct menumodel *menumodel, s32 modeltype) totalfilelen = ALIGN64(fileGetInflatedSize(menumodel->newparams, LOADTYPE_MODEL)) + 0x4000; if (1); +#ifndef PLATFORM_N64 + videoFreeCachedTextures(menumodel->allocstart, menumodel->allocstart + menumodel->alloclen); +#endif + texInitPool(&texpool, &menumodel->allocstart[(u32)totalfilelen], menumodel->alloclen - totalfilelen); menumodel->headnum = -1;