From dcaa7e725d02131363ea303d3ea233a900fcb41b Mon Sep 17 00:00:00 2001 From: Isaac0-dev <62234577+Isaac0-dev@users.noreply.github.com> Date: Fri, 18 Apr 2025 10:28:15 +1000 Subject: [PATCH] fix resetting display lists (#752) --- data/dynos_mgr_gfx.cpp | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/data/dynos_mgr_gfx.cpp b/data/dynos_mgr_gfx.cpp index d8e0d68d9..9ba84c5a8 100644 --- a/data/dynos_mgr_gfx.cpp +++ b/data/dynos_mgr_gfx.cpp @@ -5,11 +5,17 @@ extern "C" { #include "pc/lua/utils/smlua_gfx_utils.h" } +struct MapNode { + void *duplicate; + size_t size; + Gfx *gfxCopy; +}; + static ModData sModDisplayLists; static ModData sModVertexBuffers; // Maps read-only Gfx and Vtx buffers to their writable duplicates -static std::map> sRomToRamGfxVtxMap; +static std::map sRomToRamGfxVtxMap; static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) { if (!aVtx) { return NULL; } @@ -17,7 +23,7 @@ static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) { // Return duplicate if it already exists auto it = sRomToRamGfxVtxMap.find(aVtx); if (it != sRomToRamGfxVtxMap.end()) { - return (Vtx *) it->second.first; + return (Vtx *) it->second.duplicate; } // Duplicate vertex buffer and return the copy @@ -25,7 +31,7 @@ static Vtx *DynOS_Vtx_Duplicate(Vtx *aVtx, u32 vtxCount, bool shouldDuplicate) { size_t vtxSize = vtxCount * sizeof(Vtx); Vtx *vtxDuplicate = vtx_allocate_internal(vtxCount); memcpy(vtxDuplicate, aVtx, vtxSize); - sRomToRamGfxVtxMap[aVtx] = { (void *) vtxDuplicate, vtxSize }; + sRomToRamGfxVtxMap[aVtx] = { (void *) vtxDuplicate, vtxSize, NULL }; return vtxDuplicate; } @@ -38,7 +44,7 @@ static Gfx *DynOS_Gfx_Duplicate(Gfx *aGfx, bool shouldDuplicate) { // Return duplicate if it already exists auto it = sRomToRamGfxVtxMap.find(aGfx); if (it != sRomToRamGfxVtxMap.end()) { - return (Gfx *) it->second.first; + return (Gfx *) it->second.duplicate; } // Check if it's vanilla @@ -50,10 +56,8 @@ static Gfx *DynOS_Gfx_Duplicate(Gfx *aGfx, bool shouldDuplicate) { Gfx *gfxDuplicate = aGfx; u32 gfxLength = shouldDuplicate ? gfx_get_length_no_sentinel(aGfx) : gfx_get_length(aGfx); if (shouldDuplicate) { - size_t gfxSize = gfxLength * sizeof(Gfx); gfxDuplicate = gfx_allocate_internal(gfxLength); - memcpy(gfxDuplicate, aGfx, gfxSize); - sRomToRamGfxVtxMap[aGfx] = { (void *) gfxDuplicate, gfxSize }; + memcpy(gfxDuplicate, aGfx, gfxLength * sizeof(Gfx)); } // Look for other display lists or vertices @@ -73,6 +77,15 @@ static Gfx *DynOS_Gfx_Duplicate(Gfx *aGfx, bool shouldDuplicate) { } } + // Create a second duplicate for resetting the + // display list later, and then store it in the map + if (shouldDuplicate) { + size_t gfxSize = gfxLength * sizeof(Gfx); + Gfx *gfxCopy = (Gfx *) malloc(gfxSize); + memcpy(gfxCopy, gfxDuplicate, gfxSize); + sRomToRamGfxVtxMap[aGfx] = { (void *) gfxDuplicate, gfxSize, gfxCopy }; + } + return gfxDuplicate; } @@ -127,8 +140,8 @@ Gfx *DynOS_Gfx_Get(const char *aName, u32 *outLength) { it = sRomToRamGfxVtxMap.find(gfxVanilla); } - *outLength = it->second.second / sizeof(Gfx); - return (Gfx *) it->second.first; + *outLength = it->second.size / sizeof(Gfx); + return (Gfx *) it->second.duplicate; } return NULL; @@ -221,9 +234,9 @@ void DynOS_Gfx_ModShutdown() { // Restore vanilla display lists for (auto &it : sRomToRamGfxVtxMap) { - const void *original = it.first; - void *duplicate = it.second.first; - size_t size = it.second.second; + const void *original = it.second.gfxCopy ? it.second.gfxCopy : it.first; + void *duplicate = it.second.duplicate; + size_t size = it.second.size; memcpy(duplicate, original, size); } }