From 109345e94d6c6de1354349ed5b14cc50a991a2bf Mon Sep 17 00:00:00 2001
From: David Chavez <david@dcvz.io>
Date: Wed, 1 Mar 2023 10:18:26 +0100
Subject: [PATCH] [Resources] Properly encode soh textures and remove raw load
 (#2548)

---
 OTRExporter/OTRExporter/Main.cpp              | 21 ++++++++++++++-----
 OTRExporter/OTRExporter/TextureExporter.cpp   |  7 ++++---
 soh/soh/OTRGlobals.cpp                        | 20 ------------------
 soh/soh/OTRGlobals.h                          |  1 -
 soh/src/code/z_parameter.c                    |  2 +-
 soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 20 +++++++++---------
 .../ovl_file_choose/z_file_choose.c           | 16 +++++++-------
 7 files changed, 39 insertions(+), 48 deletions(-)

diff --git a/OTRExporter/OTRExporter/Main.cpp b/OTRExporter/OTRExporter/Main.cpp
index e95c36f1f..206ea7171 100644
--- a/OTRExporter/OTRExporter/Main.cpp
+++ b/OTRExporter/OTRExporter/Main.cpp
@@ -1,4 +1,5 @@
 #include "Main.h"
+#include "Exporter.h"
 #include "BackgroundExporter.h"
 #include "TextureExporter.h"
 #include "RoomExporter.h"
@@ -120,13 +121,23 @@ static void ExporterProgramEnd()
 				splitPath.pop_back();
 				std::string afterPath = std::accumulate(splitPath.begin(), splitPath.end(), std::string(""));
 				if (extension == "png" && (format == "rgba32" || format == "rgb5a1" || format == "i4" || format == "i8" || format == "ia4" || format == "ia8" || format == "ia16" || format == "ci4" || format == "ci8")) {
+					ZTexture tex(nullptr);
 					Globals::Instance->buildRawTexture = true;
-					Globals::Instance->BuildAssetTexture(item, ZTexture::GetTextureTypeFromString(format), afterPath);
-					Globals::Instance->buildRawTexture = false;
-
-					auto fileData = File::ReadAllBytes(afterPath);
+					tex.FromPNG(item, ZTexture::GetTextureTypeFromString(format));
 					printf("otrArchive->AddFile(%s)\n", StringHelper::Split(afterPath, "Extract/")[1].c_str());
-					otrArchive->AddFile(StringHelper::Split(afterPath, "Extract/")[1], (uintptr_t)fileData.data(), fileData.size());
+
+					auto exporter = new OTRExporter_Texture();
+					MemoryStream* stream = new MemoryStream();
+					BinaryWriter writer(stream);
+
+ 					exporter->Save(&tex, "", &writer);
+
+ 					std::string src = tex.GetBodySourceCode();
+ 					writer.Write((char*) src.c_str(), src.size());
+
+ 					std::vector<char> fileData = stream->ToVector();
+ 					otrArchive->AddFile(StringHelper::Split(afterPath, "Extract/assets/")[1], (uintptr_t)fileData.data(), fileData.size());
+					continue;
 				}
 			}
 
diff --git a/OTRExporter/OTRExporter/TextureExporter.cpp b/OTRExporter/OTRExporter/TextureExporter.cpp
index 69d00b6f3..fae445cf8 100644
--- a/OTRExporter/OTRExporter/TextureExporter.cpp
+++ b/OTRExporter/OTRExporter/TextureExporter.cpp
@@ -17,9 +17,10 @@ void OTRExporter_Texture::Save(ZResource* res, const fs::path& outPath, BinaryWr
 
 	writer->Write((uint32_t)tex->GetRawDataSize());
 
-	auto data = tex->parent->GetRawData();
-
-	writer->Write((char*)data.data() + tex->GetRawDataIndex(), tex->GetRawDataSize());
+	if (tex->parent != nullptr) {
+ 		auto data = tex->parent->GetRawData();
+ 		writer->Write((char*)data.data() + tex->GetRawDataIndex(), tex->GetRawDataSize());
+ 	}
 
 	auto end = std::chrono::steady_clock::now();
 	size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index 5528bfba1..7dd6ddcfd 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -894,26 +894,6 @@ extern "C" char* GetResourceDataByNameHandlingMQ(const char* path) {
     return (char*)res->GetPointer();
 }
 
-extern "C" char* ResourceMgr_LoadFileRaw(const char* resName) {
-    // TODO: This should not exist. Anywhere we are loading textures with this function should be Resources instead.
-    // We are not currently packing our otr archive with certain textures as resources with otr headers.
-    static std::unordered_map<std::string, std::shared_ptr<Ship::OtrFile>> cachedRawFiles;
-
-    auto cacheFind = cachedRawFiles.find(resName);
-    if (cacheFind != cachedRawFiles.end()) {
-        return cacheFind->second->Buffer.data();
-    }
-    
-    auto file = OTRGlobals::Instance->context->GetResourceManager()->LoadFile(resName);
-    cachedRawFiles[resName] = file;
-
-    if (file == nullptr) {
-        return nullptr;
-    }
-
-    return file->Buffer.data();
-}
-
 extern "C" char* ResourceMgr_LoadFileFromDisk(const char* filePath) {
     FILE* file = fopen(filePath, "r");
     fseek(file, 0, SEEK_END);
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index d6a8182bf..f79b232e0 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -97,7 +97,6 @@ float OTRGetDimensionFromLeftEdge(float v);
 float OTRGetDimensionFromRightEdge(float v);
 int16_t OTRGetRectDimensionFromLeftEdge(float v);
 int16_t OTRGetRectDimensionFromRightEdge(float v);
-char* ResourceMgr_LoadFileRaw(const char* resName);
 bool AudioPlayer_Init(void);
 int AudioPlayer_Buffered(void);
 int AudioPlayer_GetDesiredBuffered(void);
diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c
index c5bbb38ca..df8e40869 100644
--- a/soh/src/code/z_parameter.c
+++ b/soh/src/code/z_parameter.c
@@ -5321,7 +5321,7 @@ void Interface_Draw(PlayState* play) {
 
             gDPSetPrimColor(OVERLAY_DISP++, 0, 0, dPadColor.r, dPadColor.g, dPadColor.b, dpadAlpha);
             if (fullUi) {
-                gDPLoadTextureBlock(OVERLAY_DISP++, ResourceMgr_LoadFileRaw("assets/textures/parameter_static/gDPad"),
+                gDPLoadTextureBlock(OVERLAY_DISP++, GetResourceDataByName("__OTR__textures/parameter_static/gDPad", false),
                                     G_IM_FMT_IA, G_IM_SIZ_16b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP,
                                     G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
                 gSPWideTextureRectangle(OVERLAY_DISP++, DpadPosX << 2, DpadPosY << 2,
diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c
index 79426dc76..e3e485698 100644
--- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c
+++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c
@@ -752,16 +752,16 @@ void EnBox_UpdateSizeAndTexture(EnBox* this, PlayState* play) {
 void EnBox_CreateExtraChestTextures() {
     if (hasCreatedRandoChestTextures) return;
     Gfx gTreasureChestChestTextures[] = {
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gSkullTreasureChestFrontTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gSkullTreasureChestSideAndTopTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gGoldTreasureChestFrontTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gGoldTreasureChestSideAndTopTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gKeyTreasureChestFrontTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gKeyTreasureChestSideAndTopTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gChristmasRedTreasureChestFrontTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gChristmasRedTreasureChestSideAndTopTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gChristmasGreenTreasureChestFrontTex")),
-        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, ResourceMgr_LoadFileRaw("assets/objects/object_box/gChristmasGreenTreasureChestSideAndTopTex")),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gSkullTreasureChestFrontTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gSkullTreasureChestSideAndTopTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gGoldTreasureChestFrontTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gGoldTreasureChestSideAndTopTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gKeyTreasureChestFrontTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gKeyTreasureChestSideAndTopTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gChristmasRedTreasureChestFrontTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gChristmasRedTreasureChestSideAndTopTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gChristmasGreenTreasureChestFrontTex", false)),
+        gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, GetResourceDataByName("__OTR__objects/object_box/gChristmasGreenTreasureChestSideAndTopTex", false)),
     };
 
     Gfx* frontCmd = ResourceMgr_LoadGfxByName(gTreasureChestChestFrontDL);
diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
index 613f16261..2823311e1 100644
--- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
+++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
@@ -55,7 +55,7 @@ void FileChoose_DrawRawImageRGBA32(GraphicsContext* gfxCtx, s16 centerX, s16 cen
 
     OPEN_DISPS(gfxCtx);
 
-    source = ResourceMgr_LoadFileRaw(source);
+    source = GetResourceDataByName(source, false);
 
     curTexture = source;
     rectLeft = centerX - (width / 2);
@@ -1448,11 +1448,11 @@ const char* FileChoose_GetQuestChooseTitleTexName(Language lang) {
     switch (lang) {
         case LANGUAGE_ENG:
         default:
-            return "assets/textures/title_static/gFileSelPleaseChooseAQuestENGTex";
+            return "__OTR__textures/title_static/gFileSelPleaseChooseAQuestENGTex";
         case LANGUAGE_FRA:
-            return "assets/textures/title_static/gFileSelPleaseChooseAQuestFRATex";
+            return "__OTR__textures/title_static/gFileSelPleaseChooseAQuestFRATex";
         case LANGUAGE_GER:
-            return "assets/textures/title_static/gFileSelPleaseChooseAQuestGERTex";
+            return "__OTR__textures/title_static/gFileSelPleaseChooseAQuestGERTex";
     }
 }
 
@@ -1471,7 +1471,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
     char* tex = (this->configMode == CM_QUEST_MENU || this->configMode == CM_ROTATE_TO_NAME_ENTRY || 
         this->configMode == CM_START_QUEST_MENU || this->configMode == CM_QUEST_TO_MAIN ||
         this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU)
-                  ? ResourceMgr_LoadFileRaw(FileChoose_GetQuestChooseTitleTexName(gSaveContext.language))
+                  ? GetResourceDataByName(FileChoose_GetQuestChooseTitleTexName(gSaveContext.language), false)
                   : sTitleLabels[gSaveContext.language][this->titleLabel];
 
     OPEN_DISPS(this->state.gfxCtx);
@@ -1541,7 +1541,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
                 FileChoose_DrawTextureI8(this->state.gfxCtx, gTitleTheLegendOfTextTex, 72, 8, 156, 108, 72, 8, 1024, 1024);
                 FileChoose_DrawTextureI8(this->state.gfxCtx, gTitleOcarinaOfTimeTMTextTex, 96, 8, 154, 163, 96, 8, 1024, 1024);
                 FileChoose_DrawImageRGBA32(this->state.gfxCtx, 160, 135, ResourceMgr_GameHasOriginal() ? gTitleZeldaShieldLogoTex : gTitleZeldaShieldLogoMQTex, 160, 160);
-                FileChoose_DrawRawImageRGBA32(this->state.gfxCtx, 182, 180, "assets/objects/object_mag/gTitleRandomizerSubtitleTex", 128, 32);
+                FileChoose_DrawRawImageRGBA32(this->state.gfxCtx, 182, 180, "__OTR__objects/object_mag/gTitleRandomizerSubtitleTex", 128, 32);
                 break;
         }
     } else if (this->configMode != CM_ROTATE_TO_NAME_ENTRY) {
@@ -1617,7 +1617,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
                                     this->nameAlpha[i]);
                 }
                 gDPLoadTextureBlock(POLY_OPA_DISP++,
-                                    ResourceMgr_LoadFileRaw("assets/textures/title_static/gFileSelRANDButtonTex"),
+                                    GetResourceDataByName("__OTR__textures/title_static/gFileSelRANDButtonTex", false),
                                     G_IM_FMT_IA, G_IM_SIZ_16b, 44, 16, 0, G_TX_NOMIRROR | G_TX_WRAP,
                                     G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
                 gSP1Quadrangle(POLY_OPA_DISP++, 8, 10, 11, 9, 0);
@@ -1634,7 +1634,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
                                     this->nameAlpha[i]);
                 }
                 gDPLoadTextureBlock(POLY_OPA_DISP++,
-                                    ResourceMgr_LoadFileRaw("assets/textures/title_static/gFileSelMQButtonTex"),
+                                    GetResourceDataByName("__OTR__textures/title_static/gFileSelMQButtonTex", false),
                                     G_IM_FMT_IA, G_IM_SIZ_16b, 44, 16, 0, G_TX_NOMIRROR | G_TX_WRAP,
                                     G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
                 gSP1Quadrangle(POLY_OPA_DISP++, 8, 10, 11, 9, 0);