From 7096f8303d2bd2e9b23e3de79b0d94249777c7de Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Sun, 19 Nov 2023 20:54:39 -0500 Subject: [PATCH 1/2] fix alt backgrounds not always loading --- soh/soh/OTRGlobals.cpp | 21 +++++++++++++++++++++ soh/soh/OTRGlobals.h | 2 ++ soh/src/code/z_room.c | 7 +++++++ 3 files changed, 30 insertions(+) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index ad57d1ca5d2..2e2271a02a6 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1415,6 +1415,14 @@ extern "C" void ResourceMgr_DirtyDirectory(const char* resName) { LUS::Context::GetInstance()->GetResourceManager()->DirtyDirectory(resName); } +extern "C" void ResourceMgr_UnloadResource(const char* resName) { + std::string path = resName; + if (path.substr(0, 7) == "__OTR__") { + path = path.substr(7); + } + auto res = LUS::Context::GetInstance()->GetResourceManager()->UnloadResource(path); +} + // OTRTODO: There is probably a more elegant way to go about this... // Kenix: This is definitely leaking memory when it's called. extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) { @@ -1441,6 +1449,19 @@ extern "C" uint8_t ResourceMgr_FileExists(const char* filePath) { return ExtensionCache.contains(path); } +extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) { + std::string path = filePath; + if (path.substr(0, 7) == "__OTR__") { + path = path.substr(7); + } + + if (path.substr(0, 4) != "alt/") { + path = "alt/" + path; + } + + return ExtensionCache.contains(path); +} + extern "C" void ResourceMgr_LoadFile(const char* resName) { LUS::Context::GetInstance()->GetResourceManager()->LoadResource(resName); } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index e00cfecd508..d5753fd6997 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -86,8 +86,10 @@ uint32_t ResourceMgr_GetGameVersion(int index); uint32_t ResourceMgr_GetGamePlatform(int index); uint32_t ResourceMgr_GetGameRegion(int index); void ResourceMgr_LoadDirectory(const char* resName); +void ResourceMgr_UnloadResource(const char* resName); char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize); uint8_t ResourceMgr_FileExists(const char* resName); +uint8_t ResourceMgr_FileAltExists(const char* resName); char* GetResourceDataByNameHandlingMQ(const char* path); void ResourceMgr_LoadFile(const char* resName); char* ResourceMgr_LoadFileFromDisk(const char* filePath); diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c index ccbc93d0ded..05041240535 100644 --- a/soh/src/code/z_room.c +++ b/soh/src/code/z_room.c @@ -277,6 +277,13 @@ void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 h bg->b.imagePal = 0; bg->b.imageFlip = CVarGetInteger("gMirroredWorld", 0) ? G_BG_FLAG_FLIPS : 0; + // When an alt resource exists for the background, we need to unload the original asset + // to clear the cache so the alt asset will be loaded instead + // OTRTODO: If Alt loading over original cache is fixed, this block can most likely be removed + if (CVarGetInteger("gAltAssets", 0) && ResourceMgr_FileAltExists((char*) source)) { + ResourceMgr_UnloadResource((char*) source); + } + if (ResourceMgr_ResourceIsBackground((char*) source)) { char* blob = (char*) ResourceGetDataByName((char *) source); swapAndConvertJPEG(blob); From 08b9d5a5f3c35f03fbe853a93eff22602a19669d Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Mon, 20 Nov 2023 15:08:08 -0500 Subject: [PATCH 2/2] include gfx lookup with the original unload --- soh/soh/OTRGlobals.cpp | 13 +++++++++++++ soh/soh/OTRGlobals.h | 1 + soh/src/code/z_room.c | 6 ++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 2e2271a02a6..76e8ebe2211 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1462,6 +1462,14 @@ extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) { return ExtensionCache.contains(path); } +// Unloads a resource if an alternate version exists when alt assets are enabled +// The resource is only removed from the internal cache to prevent it from used in the next resource lookup +extern "C" void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName) { + if (CVarGetInteger("gAltAssets", 0) && ResourceMgr_FileAltExists((char*) resName)) { + ResourceMgr_UnloadResource((char*) resName); + } +} + extern "C" void ResourceMgr_LoadFile(const char* resName) { LUS::Context::GetInstance()->GetResourceManager()->LoadResource(resName); } @@ -1586,6 +1594,11 @@ extern "C" void ResourceMgr_PushCurrentDirectory(char* path) extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path) { + // When an alt resource exists for the DL, we need to unload the original asset + // to clear the cache so the alt asset will be loaded instead + // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed + ResourceMgr_UnloadOriginalWhenAltExists(path); + auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); return (Gfx*)&res->Instructions[0]; } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index d5753fd6997..ab8c4d5d1d9 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -90,6 +90,7 @@ void ResourceMgr_UnloadResource(const char* resName); char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize); uint8_t ResourceMgr_FileExists(const char* resName); uint8_t ResourceMgr_FileAltExists(const char* resName); +void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName); char* GetResourceDataByNameHandlingMQ(const char* path); void ResourceMgr_LoadFile(const char* resName); char* ResourceMgr_LoadFileFromDisk(const char* filePath); diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c index 05041240535..772978f0988 100644 --- a/soh/src/code/z_room.c +++ b/soh/src/code/z_room.c @@ -279,10 +279,8 @@ void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 h // When an alt resource exists for the background, we need to unload the original asset // to clear the cache so the alt asset will be loaded instead - // OTRTODO: If Alt loading over original cache is fixed, this block can most likely be removed - if (CVarGetInteger("gAltAssets", 0) && ResourceMgr_FileAltExists((char*) source)) { - ResourceMgr_UnloadResource((char*) source); - } + // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed + ResourceMgr_UnloadOriginalWhenAltExists((char*) source); if (ResourceMgr_ResourceIsBackground((char*) source)) { char* blob = (char*) ResourceGetDataByName((char *) source);