Added new extract mode to ZAPD and optimized OTR gen time

This commit is contained in:
Jack Walker 2022-03-30 18:35:16 -04:00
commit 7d94209d36
14 changed files with 239 additions and 64 deletions

View file

@ -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 = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str());
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, 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(); MemoryStream* dlStream = new MemoryStream();
BinaryWriter dlWriter = BinaryWriter(dlStream); BinaryWriter dlWriter = BinaryWriter(dlStream);
@ -382,7 +382,10 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
//otrArchive->RemoveFile(fName); //otrArchive->RemoveFile(fName);
#endif #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()); //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 = StringHelper::Sprintf("%s\\%s", GetParentFolderName(res).c_str(), dListDecl2->varName.c_str());
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, 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(); MemoryStream* dlStream = new MemoryStream();
BinaryWriter dlWriter = BinaryWriter(dlStream); BinaryWriter dlWriter = BinaryWriter(dlStream);
Save(dList->otherDLists[i], outPath, &dlWriter); 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 else
@ -793,7 +799,6 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
addr -= dList->parent->baseAddress; addr -= dList->parent->baseAddress;
auto segOffset = GETSEGOFFSET(addr); auto segOffset = GETSEGOFFSET(addr);
//uint32_t seg = data & 0xFFFFFFFF;
Declaration* vtxDecl = dList->parent->GetDeclarationRanged(segOffset); Declaration* vtxDecl = dList->parent->GetDeclarationRanged(segOffset);
//std::string vtxName = ""; //std::string vtxName = "";
//bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, dList->parent, "", 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; word0 = hash >> 32;
word1 = hash & 0xFFFFFFFF; 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()); //printf("Exporting VTX Data %s\n", fName.c_str());
// Write vertices to file // 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(); auto end = std::chrono::steady_clock::now();
size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

View file

@ -25,6 +25,7 @@ std::string otrFileName = "oot.otr";
std::shared_ptr<Ship::Archive> otrArchive; std::shared_ptr<Ship::Archive> otrArchive;
BinaryWriter* fileWriter; BinaryWriter* fileWriter;
std::chrono::steady_clock::time_point fileStart, resStart; std::chrono::steady_clock::time_point fileStart, resStart;
std::map<std::string, std::vector<char>> files;
void InitVersionInfo(); void InitVersionInfo();
@ -39,6 +40,8 @@ static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileM
{ {
fileMode = (ZFileMode)ExporterFileMode::BuildOTR; fileMode = (ZFileMode)ExporterFileMode::BuildOTR;
printf("BOTR: Generating OTR Archive...\n");
if (File::Exists(otrFileName)) if (File::Exists(otrFileName))
otrArchive = std::shared_ptr<Ship::Archive>(new Ship::Archive(otrFileName, true)); otrArchive = std::shared_ptr<Ship::Archive>(new Ship::Archive(otrFileName, true));
else 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) static void ExporterParseArgs(int argc, char* argv[], int& i)
{ {
std::string arg = argv[i]; std::string arg = argv[i];
@ -85,6 +113,7 @@ static void ExporterFileBegin(ZFile* file)
static void ExporterFileEnd(ZFile* file) static void ExporterFileEnd(ZFile* file)
{ {
int bp = 0;
} }
static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer) static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
@ -124,7 +153,10 @@ static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
else else
fName = StringHelper::Sprintf("%s\\%s", oName.c_str(), rName.c_str()); 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(); auto end = std::chrono::steady_clock::now();
@ -155,6 +187,8 @@ static void ImportExporters()
exporterSet->beginXMLFunc = ExporterXMLBegin; exporterSet->beginXMLFunc = ExporterXMLBegin;
exporterSet->endXMLFunc = ExporterXMLEnd; exporterSet->endXMLFunc = ExporterXMLEnd;
exporterSet->resSaveFunc = ExporterResourceEnd; exporterSet->resSaveFunc = ExporterResourceEnd;
exporterSet->endProgramFunc = ExporterProgramEnd;
exporterSet->exporters[ZResourceType::Background] = new OTRExporter_Background(); exporterSet->exporters[ZResourceType::Background] = new OTRExporter_Background();
exporterSet->exporters[ZResourceType::Texture] = new OTRExporter_Texture(); exporterSet->exporters[ZResourceType::Texture] = new OTRExporter_Texture();
exporterSet->exporters[ZResourceType::Room] = new OTRExporter_Room(); exporterSet->exporters[ZResourceType::Room] = new OTRExporter_Room();

View file

@ -3,3 +3,4 @@
#include <Archive.h> #include <Archive.h>
extern std::shared_ptr<Ship::Archive> otrArchive; extern std::shared_ptr<Ship::Archive> otrArchive;
extern std::map<std::string, std::vector<char>> files;

View file

@ -453,7 +453,10 @@ void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWrite
OTRExporter_Cutscene cs; OTRExporter_Cutscene cs;
cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter); 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); //std::string fName = OTRExporter_DisplayList::GetPathToRes(res, vtxDecl->varName);
//otrArchive->AddFile(fName, (uintptr_t)csStream->ToVector().data(), csWriter.GetBaseAddress()); //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; OTRExporter_Path pathExp;
pathExp.Save(&cmdSetPathways->pathwayList, outPath, &pathWriter); 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()); //otrArchive->AddFile(path, (uintptr_t)pathStream->ToVector().data(), pathWriter.GetBaseAddress());

View file

@ -76,6 +76,15 @@ void ExtractRom() {
if (result.error == NULLSTR) { if (result.error == NULLSTR) {
if (MoonUtils::exists("oot.otr")) MoonUtils::rm("oot.otr"); if (MoonUtils::exists("oot.otr")) MoonUtils::rm("oot.otr");
if (MoonUtils::exists("Extract")) MoonUtils::rm("Extract"); 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); startWorker(version);
extracting = true; extracting = true;
} }

View file

@ -14,6 +14,7 @@
#endif #endif
namespace Util = MoonUtils; namespace Util = MoonUtils;
static bool oldExtractMode = false;
static int maxResources = 0; static int maxResources = 0;
static int extractedResources = 0; static int extractedResources = 0;
bool buildingOtr = false; bool buildingOtr = false;
@ -36,19 +37,16 @@ std::string GetXMLVersion(RomVersion version)
} }
void BuildOTR(const std::string output) { void BuildOTR(const std::string output) {
Util::copy("tmp/baserom/Audiobank", "Extract/Audiobank"); if (oldExtractMode)
Util::copy("tmp/baserom/Audioseq", "Extract/Audioseq"); {
Util::copy("tmp/baserom/Audiotable", "Extract/Audiotable"); std::string execStr = Util::format("assets/extractor/%s", isWindows() ? "ZAPD.exe" : "ZAPD.out") + " botr -se OTR";
Util::copy("tmp/baserom/version", "Extract/version"); ProcessResult result = NativeFS->LaunchProcess(execStr);
if (result.exitCode != 0) {
Util::copy("assets/game/", "Extract/assets/"); std::cout << "\nError when building the OTR file with error code: " << result.exitCode << " !" << std::endl;
std::cout << "Aborting...\n" << std::endl;
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!"); setCurrentStep("Done!");
if (output == ".") return; if (output == ".") return;
@ -85,38 +83,62 @@ void startWorker(RomVersion version) {
Util::write("tmp/baserom/version", (char*)&version.crc, sizeof(version.crc)); Util::write("tmp/baserom/version", (char*)&version.crc, sizeof(version.crc));
std::vector<std::string> files;
Util::dirscan(path, files);
std::vector<std::string> xmlFiles;
const int num_threads = std::thread::hardware_concurrency(); if (oldExtractMode)
ctpl::thread_pool pool(num_threads / 2); {
for(auto &file : files) { std::vector<std::string> files;
if (file.find(".xml") != std::string::npos) xmlFiles.push_back(file); Util::dirscan(path, files);
} std::vector<std::string> xmlFiles;
for (auto& file : xmlFiles) { const int num_threads = std::thread::hardware_concurrency();
if(single_thread) { ctpl::thread_pool pool(num_threads / 2);
ExtractFunc(file, version); for (auto& file : files) {
} else { if (file.find(".xml") != std::string::npos) xmlFiles.push_back(file);
pool.push([file, version](int) {
ExtractFunc(file, version);
});
} }
}
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) { void updateWorker(const std::string& output) {
if (maxResources > 0 && !buildingOtr && extractedResources >= maxResources) { if (maxResources > 0 && !buildingOtr && (extractedResources >= maxResources || !oldExtractMode))
{
setCurrentStep("Building OTR..."); setCurrentStep("Building OTR...");
if (skipFrames < 3) { if (skipFrames < 3) {
skipFrames++; skipFrames++;
return; return;
} }
buildingOtr = true; buildingOtr = true;
if (single_thread){
if (single_thread || !oldExtractMode){
BuildOTR(output); BuildOTR(output);
return; return;
} }

View file

@ -36,6 +36,7 @@ public:
ExporterSetFuncVoid3 beginXMLFunc = nullptr; ExporterSetFuncVoid3 beginXMLFunc = nullptr;
ExporterSetFuncVoid3 endXMLFunc = nullptr; ExporterSetFuncVoid3 endXMLFunc = nullptr;
ExporterSetResSave resSaveFunc = nullptr; ExporterSetResSave resSaveFunc = nullptr;
ExporterSetFuncVoid3 endProgramFunc = nullptr;
}; };
class Globals class Globals

View file

@ -240,6 +240,8 @@ int main(int argc, char* argv[])
fileMode = ZFileMode::BuildBlob; fileMode = ZFileMode::BuildBlob;
else if (buildMode == "e") else if (buildMode == "e")
fileMode = ZFileMode::Extract; fileMode = ZFileMode::Extract;
else if (buildMode == "ed")
fileMode = ZFileMode::ExtractDirectory;
else if (exporterSet != nullptr && exporterSet->parseFileModeFunc != nullptr) else if (exporterSet != nullptr && exporterSet->parseFileModeFunc != nullptr)
exporterSet->parseFileModeFunc(buildMode, fileMode); exporterSet->parseFileModeFunc(buildMode, fileMode);
@ -249,6 +251,8 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
Globals::Instance->fileMode = fileMode;
// We've parsed through our commands once. If an exporter exists, it's been set by now. // 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. // 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 // TODO: switch
if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile || fileMode == ZFileMode::ExtractDirectory)
{ {
bool procFileModeSuccess = false; bool procFileModeSuccess = false;
if (exporterSet != nullptr && exporterSet->processFileModeFunc != nullptr) if (exporterSet != nullptr && exporterSet->processFileModeFunc != nullptr)
procFileModeSuccess = exporterSet->processFileModeFunc(fileMode); procFileModeSuccess = exporterSet->processFileModeFunc(fileMode);
if (!procFileModeSuccess) if (!procFileModeSuccess)
{ {
bool parseSuccessful; if (fileMode == ZFileMode::ExtractDirectory)
for (auto& extFile : Globals::Instance->cfg.externalFiles)
{ {
fs::path externalXmlFilePath = std::vector<std::string> fileList =
Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath; 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", printf("(%i / %i): %s\n", (i+1), fileList.size(), fileList[i].c_str());
externalXmlFilePath.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, auto end = std::chrono::steady_clock::now();
extFile.outPath, ZFileMode::ExternalFile); auto diff =
std::chrono::duration_cast<std::chrono::seconds>(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) if (!parseSuccessful)
return 1; return 1;
} }
parseSuccessful = Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath,
Globals::Instance->outputPath, fileMode);
if (!parseSuccessful)
return 1;
} }
} }
else if (fileMode == ZFileMode::BuildTexture) else if (fileMode == ZFileMode::BuildTexture)
@ -326,6 +398,9 @@ int main(int argc, char* argv[])
overlay->GetSourceOutputCode("")); overlay->GetSourceOutputCode(""));
} }
if (exporterSet != nullptr && exporterSet->endProgramFunc != nullptr)
exporterSet->endProgramFunc();
delete g; delete g;
return 0; return 0;
} }

View file

@ -150,8 +150,11 @@ std::string ZBackground::GetExternalExtension() const
void ZBackground::Save(const fs::path& outFolder) void ZBackground::Save(const fs::path& outFolder)
{ {
fs::path filepath = outFolder / (outName + "." + GetExternalExtension()); if (!Globals::Instance->otrMode)
File::WriteAllBytes(filepath.string(), data); {
fs::path filepath = outFolder / (outName + "." + GetExternalExtension());
File::WriteAllBytes(filepath.string(), data);
}
} }
std::string ZBackground::GetBodySourceCode() const std::string ZBackground::GetBodySourceCode() const

View file

@ -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())) 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); 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); nRes->ExtractFromXML(child, rawDataIndex);
switch (nRes->GetResourceType()) switch (nRes->GetResourceType())
@ -813,7 +813,8 @@ void ZFile::GenerateSourceHeaderFiles()
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
printf("Writing H file: %s\n", headerFilename.c_str()); 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 std::string ZFile::GetHeaderInclude() const
@ -1190,6 +1191,9 @@ void ZFile::HandleUnaccountedData()
uint32_t lastSize = 0; uint32_t lastSize = 0;
std::vector<offset_t> declsAddresses; std::vector<offset_t> declsAddresses;
if (Globals::Instance->otrMode)
return;
for (const auto& item : declarations) for (const auto& item : declarations)
{ {
declsAddresses.push_back(item.first); declsAddresses.push_back(item.first);

View file

@ -16,6 +16,7 @@ enum class ZFileMode
BuildBackground, BuildBackground,
Extract, Extract,
ExternalFile, ExternalFile,
ExtractDirectory,
Invalid, Invalid,
Custom = 1000, // Used for exporter file modes Custom = 1000, // Used for exporter file modes
}; };

View file

@ -218,6 +218,9 @@ size_t ZLimb::GetRawDataSize() const
std::string ZLimb::GetBodySourceCode() const std::string ZLimb::GetBodySourceCode() const
{ {
if (Globals::Instance->otrMode)
return "";
std::string dListStr; std::string dListStr;
std::string dListStr2; std::string dListStr2;
Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr); Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr);

View file

@ -3,6 +3,7 @@
#include "Utils/BitConverter.h" #include "Utils/BitConverter.h"
#include "Utils/StringHelper.h" #include "Utils/StringHelper.h"
#include "ZFile.h" #include "ZFile.h"
#include <Globals.h>
REGISTER_ZFILENODE(PlayerAnimationData, ZPlayerAnimationData); REGISTER_ZFILENODE(PlayerAnimationData, ZPlayerAnimationData);
@ -54,6 +55,9 @@ std::string ZPlayerAnimationData::GetBodySourceCode() const
{ {
std::string declaration = ""; std::string declaration = "";
if (Globals::Instance->otrMode)
return "";
size_t index = 0; size_t index = 0;
for (const auto& entry : limbRotData) for (const auto& entry : limbRotData)
{ {

View file

@ -138,6 +138,10 @@ void ElfMsg_CallNaviCylinder(ElfMsg* this, GlobalContext* globalCtx) {
Player* player = GET_PLAYER(globalCtx); Player* player = GET_PLAYER(globalCtx);
EnElf* navi = (EnElf*)player->naviActor; 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) && 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) && (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))) { ((player->actor.world.pos.y - this->actor.world.pos.y) < (100.0f * this->actor.scale.y))) {