From 7d94209d36a19396d05bda5e145f1f035926a3aa Mon Sep 17 00:00:00 2001 From: Jack Walker <7463599+Jack-Walker@users.noreply.github.com> Date: Wed, 30 Mar 2022 18:35:16 -0400 Subject: [PATCH] Added new extract mode to ZAPD and optimized OTR gen time --- .../OTRExporter/DisplayListExporter.cpp | 22 ++-- OTRExporter/OTRExporter/Main.cpp | 36 +++++- OTRExporter/OTRExporter/Main.h | 3 +- OTRExporter/OTRExporter/RoomExporter.cpp | 12 +- OTRGui/src/game/game.cpp | 9 ++ OTRGui/src/impl/extractor/extractor.cpp | 84 +++++++++----- ZAPDTR/ZAPD/Globals.h | 1 + ZAPDTR/ZAPD/Main.cpp | 107 +++++++++++++++--- ZAPDTR/ZAPD/ZBackground.cpp | 7 +- ZAPDTR/ZAPD/ZFile.cpp | 10 +- ZAPDTR/ZAPD/ZFile.h | 1 + ZAPDTR/ZAPD/ZLimb.cpp | 3 + ZAPDTR/ZAPD/ZPlayerAnimationData.cpp | 4 + .../overlays/actors/ovl_Elf_Msg/z_elf_msg.c | 4 + 14 files changed, 239 insertions(+), 64 deletions(-) diff --git a/OTRExporter/OTRExporter/DisplayListExporter.cpp b/OTRExporter/OTRExporter/DisplayListExporter.cpp index 4d4f067b1..f0824550e 100644 --- a/OTRExporter/OTRExporter/DisplayListExporter.cpp +++ b/OTRExporter/OTRExporter/DisplayListExporter.cpp @@ -370,7 +370,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina //std::string fName = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str()); std::string fName = OTRExporter_DisplayList::GetPathToRes(res, dListDecl2->varName.c_str()); - if (!File::Exists("Extract\\" + fName)) + if (files.find(fName) == files.end() && !File::Exists("Extract\\" + fName)) { MemoryStream* dlStream = new MemoryStream(); BinaryWriter dlWriter = BinaryWriter(dlStream); @@ -382,7 +382,10 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina //otrArchive->RemoveFile(fName); #endif - File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector()); + if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) + File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector()); + else + files[fName] = dlStream->ToVector(); //otrArchive->AddFile(fName, (uintptr_t)dlStream->ToVector().data(), dlWriter.GetBaseAddress()); } @@ -464,14 +467,17 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina //std::string fName = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str()); std::string fName = OTRExporter_DisplayList::GetPathToRes(res, dListDecl2->varName.c_str()); - if (!File::Exists("Extract\\" + fName)) + if (files.find(fName) == files.end() && !File::Exists("Extract\\" + fName)) { MemoryStream* dlStream = new MemoryStream(); BinaryWriter dlWriter = BinaryWriter(dlStream); Save(dList->otherDLists[i], outPath, &dlWriter); - File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector()); + if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) + File::WriteAllBytes("Extract\\" + fName, dlStream->ToVector()); + else + files[fName] = dlStream->ToVector(); } } else @@ -793,7 +799,6 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina addr -= dList->parent->baseAddress; auto segOffset = GETSEGOFFSET(addr); - //uint32_t seg = data & 0xFFFFFFFF; Declaration* vtxDecl = dList->parent->GetDeclarationRanged(segOffset); //std::string vtxName = ""; //bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, dList->parent, "", vtxName); @@ -822,7 +827,7 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina word0 = hash >> 32; word1 = hash & 0xFFFFFFFF; - if (!File::Exists("Extract\\" + fName)) + if (files.find(fName) == files.end() && !File::Exists("Extract\\" + fName)) { //printf("Exporting VTX Data %s\n", fName.c_str()); // Write vertices to file @@ -878,7 +883,10 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina } } - File::WriteAllBytes("Extract\\" + fName, vtxStream->ToVector()); + if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) + File::WriteAllBytes("Extract\\" + fName, vtxStream->ToVector()); + else + files[fName] = vtxStream->ToVector(); auto end = std::chrono::steady_clock::now(); size_t diff = std::chrono::duration_cast(end - start).count(); diff --git a/OTRExporter/OTRExporter/Main.cpp b/OTRExporter/OTRExporter/Main.cpp index 24a156fe9..e62ed5ef4 100644 --- a/OTRExporter/OTRExporter/Main.cpp +++ b/OTRExporter/OTRExporter/Main.cpp @@ -25,6 +25,7 @@ std::string otrFileName = "oot.otr"; std::shared_ptr otrArchive; BinaryWriter* fileWriter; std::chrono::steady_clock::time_point fileStart, resStart; +std::map> files; void InitVersionInfo(); @@ -39,6 +40,8 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM { fileMode = (ZFileMode)ExporterFileMode::BuildOTR; + printf("BOTR: Generating OTR Archive...\n"); + if (File::Exists(otrFileName)) otrArchive = std::shared_ptr(new Ship::Archive(otrFileName, true)); else @@ -54,6 +57,31 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM } } +static void ExporterProgramEnd() +{ + if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory) + { + printf("Generating OTR Archive...\n"); + otrArchive = Ship::Archive::CreateArchive(otrFileName, 65536 / 2); + + for (auto item : files) + { + auto fileData = item.second; + otrArchive->AddFile(item.first, (uintptr_t)fileData.data(), fileData.size()); + } + + // Add any additional files that need to be manually copied... + auto lst = Directory::ListFiles("Extract"); + + for (auto item : lst) + { + auto fileData = File::ReadAllBytes(item); + otrArchive->AddFile(StringHelper::Split(item, "Extract\\")[1], (uintptr_t)fileData.data(), fileData.size()); + } + } +} + + static void ExporterParseArgs(int argc, char* argv[], int& i) { std::string arg = argv[i]; @@ -85,6 +113,7 @@ static void ExporterFileBegin(ZFile* file) static void ExporterFileEnd(ZFile* file) { + int bp = 0; } static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer) @@ -124,7 +153,10 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer) else fName = StringHelper::Sprintf("%s\\%s", oName.c_str(), rName.c_str()); - File::WriteAllBytes("Extract\\" + fName, strem->ToVector()); + if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory) + files[fName] = strem->ToVector(); + else + File::WriteAllBytes("Extract\\" + fName, strem->ToVector()); } auto end = std::chrono::steady_clock::now(); @@ -155,6 +187,8 @@ static void ImportExporters() exporterSet->beginXMLFunc = ExporterXMLBegin; exporterSet->endXMLFunc = ExporterXMLEnd; exporterSet->resSaveFunc = ExporterResourceEnd; + exporterSet->endProgramFunc = ExporterProgramEnd; + exporterSet->exporters[ZResourceType::Background] = new OTRExporter_Background(); exporterSet->exporters[ZResourceType::Texture] = new OTRExporter_Texture(); exporterSet->exporters[ZResourceType::Room] = new OTRExporter_Room(); diff --git a/OTRExporter/OTRExporter/Main.h b/OTRExporter/OTRExporter/Main.h index a29e21859..af4ada763 100644 --- a/OTRExporter/OTRExporter/Main.h +++ b/OTRExporter/OTRExporter/Main.h @@ -2,4 +2,5 @@ #include -extern std::shared_ptr otrArchive; \ No newline at end of file +extern std::shared_ptr otrArchive; +extern std::map> files; \ No newline at end of file diff --git a/OTRExporter/OTRExporter/RoomExporter.cpp b/OTRExporter/OTRExporter/RoomExporter.cpp index 622901aff..1890711d9 100644 --- a/OTRExporter/OTRExporter/RoomExporter.cpp +++ b/OTRExporter/OTRExporter/RoomExporter.cpp @@ -452,8 +452,11 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite BinaryWriter csWriter = BinaryWriter(csStream); OTRExporter_Cutscene cs; cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter); - - File::WriteAllBytes("Extract\\" + fName, csStream->ToVector()); + + if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) + File::WriteAllBytes("Extract\\" + fName, csStream->ToVector()); + else + files[fName] = csStream->ToVector(); //std::string fName = OTRExporter_DisplayList::GetPathToRes(res, vtxDecl->varName); //otrArchive->AddFile(fName, (uintptr_t)csStream->ToVector().data(), csWriter.GetBaseAddress()); @@ -477,7 +480,10 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite OTRExporter_Path pathExp; pathExp.Save(&cmdSetPathways->pathwayList, outPath, &pathWriter); - File::WriteAllBytes("Extract\\" + path, pathStream->ToVector()); + if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) + File::WriteAllBytes("Extract\\" + path, pathStream->ToVector()); + else + files[path] = pathStream->ToVector(); //otrArchive->AddFile(path, (uintptr_t)pathStream->ToVector().data(), pathWriter.GetBaseAddress()); diff --git a/OTRGui/src/game/game.cpp b/OTRGui/src/game/game.cpp index 68f2bd122..964e86d0a 100644 --- a/OTRGui/src/game/game.cpp +++ b/OTRGui/src/game/game.cpp @@ -76,6 +76,15 @@ void ExtractRom() { if (result.error == NULLSTR) { if (MoonUtils::exists("oot.otr")) MoonUtils::rm("oot.otr"); if (MoonUtils::exists("Extract")) MoonUtils::rm("Extract"); + + MoonUtils::mkdir("Extract"); + MoonUtils::copy("tmp/baserom/Audiobank", "Extract/Audiobank"); + MoonUtils::copy("tmp/baserom/Audioseq", "Extract/Audioseq"); + MoonUtils::copy("tmp/baserom/Audiotable", "Extract/Audiotable"); + MoonUtils::copy("tmp/baserom/version", "Extract/version"); + + MoonUtils::copy("assets/game/", "Extract/assets/"); + startWorker(version); extracting = true; } diff --git a/OTRGui/src/impl/extractor/extractor.cpp b/OTRGui/src/impl/extractor/extractor.cpp index e7fd8a756..859948459 100644 --- a/OTRGui/src/impl/extractor/extractor.cpp +++ b/OTRGui/src/impl/extractor/extractor.cpp @@ -14,6 +14,7 @@ #endif namespace Util = MoonUtils; +static bool oldExtractMode = false; static int maxResources = 0; static int extractedResources = 0; bool buildingOtr = false; @@ -36,19 +37,16 @@ std::string GetXMLVersion(RomVersion version) } void BuildOTR(const std::string output) { - Util::copy("tmp/baserom/Audiobank", "Extract/Audiobank"); - Util::copy("tmp/baserom/Audioseq", "Extract/Audioseq"); - Util::copy("tmp/baserom/Audiotable", "Extract/Audiotable"); - Util::copy("tmp/baserom/version", "Extract/version"); - - Util::copy("assets/game/", "Extract/assets/"); - - std::string execStr = Util::format("assets/extractor/%s", isWindows() ? "ZAPD.exe" : "ZAPD.out") + " botr -se OTR"; - ProcessResult result = NativeFS->LaunchProcess(execStr); - if(result.exitCode != 0) { - std::cout << "\nError when building the OTR file with error code: " << result.exitCode << " !" << std::endl; - std::cout << "Aborting...\n" << std::endl; + if (oldExtractMode) + { + std::string execStr = Util::format("assets/extractor/%s", isWindows() ? "ZAPD.exe" : "ZAPD.out") + " botr -se OTR"; + ProcessResult result = NativeFS->LaunchProcess(execStr); + if (result.exitCode != 0) { + std::cout << "\nError when building the OTR file with error code: " << result.exitCode << " !" << std::endl; + std::cout << "Aborting...\n" << std::endl; + } } + setCurrentStep("Done!"); if (output == ".") return; @@ -85,38 +83,62 @@ void startWorker(RomVersion version) { Util::write("tmp/baserom/version", (char*)&version.crc, sizeof(version.crc)); - std::vector files; - Util::dirscan(path, files); - std::vector xmlFiles; - const int num_threads = std::thread::hardware_concurrency(); - ctpl::thread_pool pool(num_threads / 2); - for(auto &file : files) { - if (file.find(".xml") != std::string::npos) xmlFiles.push_back(file); - } + if (oldExtractMode) + { + std::vector files; + Util::dirscan(path, files); + std::vector xmlFiles; - for (auto& file : xmlFiles) { - if(single_thread) { - ExtractFunc(file, version); - } else { - pool.push([file, version](int) { - ExtractFunc(file, version); - }); + const int num_threads = std::thread::hardware_concurrency(); + ctpl::thread_pool pool(num_threads / 2); + for (auto& file : files) { + if (file.find(".xml") != std::string::npos) xmlFiles.push_back(file); } - } - maxResources = xmlFiles.size(); + for (auto& file : xmlFiles) { + if (single_thread) { + ExtractFunc(file, version); + } + else { + pool.push([file, version](int) { + ExtractFunc(file, version); + }); + } + } + + maxResources = xmlFiles.size(); + } + else + { + std::string execStr = Util::format("assets/extractor/%s", isWindows() ? "ZAPD.exe" : "ZAPD.out"); + std::string args = Util::format(" ed -eh -i %s -b tmp/baserom/ -o %s -osf %s -gsf 1 -rconf assets/extractor/Config_%s.xml -se OTR %s", path.c_str(), path + "../", path + "../", GetXMLVersion(version).c_str(), ""); + ProcessResult result = NativeFS->LaunchProcess(execStr + args); + + if (result.exitCode != 0) { + std::cout << "\nError when extracting the ROM with error code: " << result.exitCode << " !" << std::endl; + std::cout << "Aborting...\n" << std::endl; + } + else + { + printf("All done?\n"); + } + + maxResources = 1; + } } void updateWorker(const std::string& output) { - if (maxResources > 0 && !buildingOtr && extractedResources >= maxResources) { + if (maxResources > 0 && !buildingOtr && (extractedResources >= maxResources || !oldExtractMode)) + { setCurrentStep("Building OTR..."); if (skipFrames < 3) { skipFrames++; return; } buildingOtr = true; - if (single_thread){ + + if (single_thread || !oldExtractMode){ BuildOTR(output); return; } diff --git a/ZAPDTR/ZAPD/Globals.h b/ZAPDTR/ZAPD/Globals.h index 140de1f24..3231b2cc9 100644 --- a/ZAPDTR/ZAPD/Globals.h +++ b/ZAPDTR/ZAPD/Globals.h @@ -36,6 +36,7 @@ public: ExporterSetFuncVoid3 beginXMLFunc = nullptr; ExporterSetFuncVoid3 endXMLFunc = nullptr; ExporterSetResSave resSaveFunc = nullptr; + ExporterSetFuncVoid3 endProgramFunc = nullptr; }; class Globals diff --git a/ZAPDTR/ZAPD/Main.cpp b/ZAPDTR/ZAPD/Main.cpp index 440f6d504..68c3693ab 100644 --- a/ZAPDTR/ZAPD/Main.cpp +++ b/ZAPDTR/ZAPD/Main.cpp @@ -240,6 +240,8 @@ int main(int argc, char* argv[]) fileMode = ZFileMode::BuildBlob; else if (buildMode == "e") fileMode = ZFileMode::Extract; + else if (buildMode == "ed") + fileMode = ZFileMode::ExtractDirectory; else if (exporterSet != nullptr && exporterSet->parseFileModeFunc != nullptr) exporterSet->parseFileModeFunc(buildMode, fileMode); @@ -249,6 +251,8 @@ int main(int argc, char* argv[]) return 1; } + Globals::Instance->fileMode = fileMode; + // We've parsed through our commands once. If an exporter exists, it's been set by now. // Now we'll parse through them again but pass them on to our exporter if one is available. @@ -267,39 +271,107 @@ int main(int argc, char* argv[]) } // TODO: switch - if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) + if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile || fileMode == ZFileMode::ExtractDirectory) { bool procFileModeSuccess = false; if (exporterSet != nullptr && exporterSet->processFileModeFunc != nullptr) procFileModeSuccess = exporterSet->processFileModeFunc(fileMode); + if (!procFileModeSuccess) { - bool parseSuccessful; - - for (auto& extFile : Globals::Instance->cfg.externalFiles) + if (fileMode == ZFileMode::ExtractDirectory) { - fs::path externalXmlFilePath = - Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath; + std::vector fileList = + Directory::ListFiles(Globals::Instance->inputPath.string()); - if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + bool parseSuccessful; + + + auto start = std::chrono::steady_clock::now(); + + for (int i = 0; i < fileList.size(); i++) { - printf("Parsing external file from config: '%s'\n", - externalXmlFilePath.c_str()); + printf("(%i / %i): %s\n", (i+1), fileList.size(), fileList[i].c_str()); + + for (auto& extFile : Globals::Instance->cfg.externalFiles) + { + fs::path externalXmlFilePath = + Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath; + + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + { + printf("Parsing external file from config: '%s'\n", + externalXmlFilePath.c_str()); + } + + parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath, + extFile.outPath, ZFileMode::ExternalFile); + + if (!parseSuccessful) + return 1; + } + + parseSuccessful = Parse(fileList[i], Globals::Instance->baseRomPath, + Globals::Instance->outputPath, fileMode); + + if (!parseSuccessful) + return 1; + + /*for (auto file : Globals::Instance->files) + delete file;*/ + + for (int i = Globals::Instance->cfg.externalFiles.size(); i < Globals::Instance->files.size(); i++) + { + //if (!Globals::Instance->files[i]->isExternalFile) + { + delete Globals::Instance->files[i]; + Globals::Instance->files.erase(Globals::Instance->files.begin() + i); + i--; + } + } + + //Globals::Instance->files.clear(); + Globals::Instance->externalFiles.clear(); + Globals::Instance->segments.clear(); + Globals::Instance->cfg.segmentRefFiles.clear(); } - parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath, - extFile.outPath, ZFileMode::ExternalFile); + auto end = std::chrono::steady_clock::now(); + auto diff = + std::chrono::duration_cast(end - start).count(); + printf("Generated OTR File Data in %i seconds\n", diff); + } + else + { + bool parseSuccessful; + + for (auto& extFile : Globals::Instance->cfg.externalFiles) + { + fs::path externalXmlFilePath = + Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath; + + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + { + printf("Parsing external file from config: '%s'\n", + externalXmlFilePath.c_str()); + } + + parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath, + extFile.outPath, ZFileMode::ExternalFile); + + if (!parseSuccessful) + return 1; + } + + parseSuccessful = + Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath, + Globals::Instance->outputPath, fileMode); if (!parseSuccessful) return 1; } - - parseSuccessful = Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath, - Globals::Instance->outputPath, fileMode); - if (!parseSuccessful) - return 1; } } else if (fileMode == ZFileMode::BuildTexture) @@ -326,6 +398,9 @@ int main(int argc, char* argv[]) overlay->GetSourceOutputCode("")); } + if (exporterSet != nullptr && exporterSet->endProgramFunc != nullptr) + exporterSet->endProgramFunc(); + delete g; return 0; } diff --git a/ZAPDTR/ZAPD/ZBackground.cpp b/ZAPDTR/ZAPD/ZBackground.cpp index 0ed1eb747..94efe06e9 100644 --- a/ZAPDTR/ZAPD/ZBackground.cpp +++ b/ZAPDTR/ZAPD/ZBackground.cpp @@ -150,8 +150,11 @@ std::string ZBackground::GetExternalExtension() const void ZBackground::Save(const fs::path& outFolder) { - fs::path filepath = outFolder / (outName + "." + GetExternalExtension()); - File::WriteAllBytes(filepath.string(), data); + if (!Globals::Instance->otrMode) + { + fs::path filepath = outFolder / (outName + "." + GetExternalExtension()); + File::WriteAllBytes(filepath.string(), data); + } } std::string ZBackground::GetBodySourceCode() const diff --git a/ZAPDTR/ZAPD/ZFile.cpp b/ZAPDTR/ZAPD/ZFile.cpp index 13ab961f8..f008e2174 100644 --- a/ZAPDTR/ZAPD/ZFile.cpp +++ b/ZAPDTR/ZAPD/ZFile.cpp @@ -181,7 +181,7 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) } } - if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile) + if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile || mode == ZFileMode::ExtractDirectory) { if (!File::Exists((basePath / name).string())) { @@ -260,7 +260,7 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) { ZResource* nRes = nodeMap[nodeName](this); - if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile) + if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile || mode == ZFileMode::ExtractDirectory) nRes->ExtractFromXML(child, rawDataIndex); switch (nRes->GetResourceType()) @@ -813,7 +813,8 @@ void ZFile::GenerateSourceHeaderFiles() if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) printf("Writing H file: %s\n", headerFilename.c_str()); - File::WriteAllText(headerFilename, formatter.GetOutput()); + if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory) + File::WriteAllText(headerFilename, formatter.GetOutput()); } std::string ZFile::GetHeaderInclude() const @@ -1190,6 +1191,9 @@ void ZFile::HandleUnaccountedData() uint32_t lastSize = 0; std::vector declsAddresses; + if (Globals::Instance->otrMode) + return; + for (const auto& item : declarations) { declsAddresses.push_back(item.first); diff --git a/ZAPDTR/ZAPD/ZFile.h b/ZAPDTR/ZAPD/ZFile.h index ac4062d5b..787dd0148 100644 --- a/ZAPDTR/ZAPD/ZFile.h +++ b/ZAPDTR/ZAPD/ZFile.h @@ -16,6 +16,7 @@ enum class ZFileMode BuildBackground, Extract, ExternalFile, + ExtractDirectory, Invalid, Custom = 1000, // Used for exporter file modes }; diff --git a/ZAPDTR/ZAPD/ZLimb.cpp b/ZAPDTR/ZAPD/ZLimb.cpp index 330fbaf7c..774fc7150 100644 --- a/ZAPDTR/ZAPD/ZLimb.cpp +++ b/ZAPDTR/ZAPD/ZLimb.cpp @@ -218,6 +218,9 @@ size_t ZLimb::GetRawDataSize() const std::string ZLimb::GetBodySourceCode() const { + if (Globals::Instance->otrMode) + return ""; + std::string dListStr; std::string dListStr2; Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr); diff --git a/ZAPDTR/ZAPD/ZPlayerAnimationData.cpp b/ZAPDTR/ZAPD/ZPlayerAnimationData.cpp index a96604fda..ab633c129 100644 --- a/ZAPDTR/ZAPD/ZPlayerAnimationData.cpp +++ b/ZAPDTR/ZAPD/ZPlayerAnimationData.cpp @@ -3,6 +3,7 @@ #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" +#include REGISTER_ZFILENODE(PlayerAnimationData, ZPlayerAnimationData); @@ -54,6 +55,9 @@ std::string ZPlayerAnimationData::GetBodySourceCode() const { std::string declaration = ""; + if (Globals::Instance->otrMode) + return ""; + size_t index = 0; for (const auto& entry : limbRotData) { diff --git a/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c b/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c index e730b746a..5e0a780fd 100644 --- a/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c +++ b/soh/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c @@ -138,6 +138,10 @@ void ElfMsg_CallNaviCylinder(ElfMsg* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); EnElf* navi = (EnElf*)player->naviActor; + // This fixes a crash when using a grotto exit when you never properly entered + if (navi == NULL) + return; + if (ElfMsg_WithinXZDistance(&player->actor.world.pos, &this->actor.world.pos, this->actor.scale.x * 100.0f) && (this->actor.world.pos.y <= player->actor.world.pos.y) && ((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y))) {