From 364afcaf2f63dc523cfbe444b6ec7452f83c50c6 Mon Sep 17 00:00:00 2001 From: cadmic Date: Fri, 21 Jun 2024 12:26:45 -0700 Subject: [PATCH 1/4] Add ZAPD hack to deal with extracted/VERSION/ in include paths --- ZAPD/ZFile.cpp | 12 ++++++++++++ ZAPDUtils/Utils/StringHelper.h | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/ZAPD/ZFile.cpp b/ZAPD/ZFile.cpp index 0b2a4d631..656ef6aa6 100644 --- a/ZAPD/ZFile.cpp +++ b/ZAPD/ZFile.cpp @@ -585,6 +585,12 @@ Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& in includePath = "assets/" + StringHelper::Split(includePath, "assets/extracted/")[1]; if (StringHelper::StartsWith(includePath, "assets/custom/")) includePath = "assets/" + StringHelper::Split(includePath, "assets/custom/")[1]; + // Hack for OOT: don't prefix include paths with extracted/VERSION/ + if (StringHelper::StartsWith(includePath, "extracted/")) { + std::vector parts = StringHelper::Split(includePath, "/"); + parts.erase(parts.begin(), parts.begin() + 2); + includePath = StringHelper::Join(parts, "/"); + } Declaration* decl = GetDeclaration(address); if (decl == nullptr) @@ -621,6 +627,12 @@ Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& in includePath = "assets/" + StringHelper::Split(includePath, "assets/extracted/")[1]; if (StringHelper::StartsWith(includePath, "assets/custom/")) includePath = "assets/" + StringHelper::Split(includePath, "assets/custom/")[1]; + // Hack for OOT: don't prefix include paths with extracted/VERSION/ + if (StringHelper::StartsWith(includePath, "extracted/")) { + std::vector parts = StringHelper::Split(includePath, "/"); + parts.erase(parts.begin(), parts.begin() + 2); + includePath = StringHelper::Join(parts, "/"); + } Declaration* decl = GetDeclaration(address); if (decl == nullptr) diff --git a/ZAPDUtils/Utils/StringHelper.h b/ZAPDUtils/Utils/StringHelper.h index c4e012eb0..942d0bcc9 100644 --- a/ZAPDUtils/Utils/StringHelper.h +++ b/ZAPDUtils/Utils/StringHelper.h @@ -30,6 +30,21 @@ class StringHelper return result; } + static std::string Join(const std::vector parts, const std::string& delimiter) + { + std::string result; + + for (size_t i = 0; i < parts.size(); i++) + { + result += parts[i]; + + if (i != parts.size() - 1) + result += delimiter; + } + + return result; + } + static std::string Strip(std::string s, const std::string& delimiter) { size_t pos = 0; From afce9b25e567cf422d88165ac176df9b5ee3300d Mon Sep 17 00:00:00 2001 From: cadmic Date: Fri, 21 Jun 2024 12:27:09 -0700 Subject: [PATCH 2/4] Add ZAPD flags to override virtual address / start offset / end offset --- README.md | 3 +++ ZAPD/Globals.h | 3 +++ ZAPD/Main.cpp | 21 +++++++++++++++++++++ ZAPD/ZFile.cpp | 6 ++++++ 4 files changed, 33 insertions(+) diff --git a/README.md b/README.md index c7a9c2848..5006f8d4b 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,9 @@ ZAPD also accepts the following list of extra parameters: - `both`: `CS_FLOAT(0x42280000, 42.0f)` - `hex-commented-left`: `/* 42.0f */ 0x42280000` - `hex-commented-right`: `0x42280000 /* 42.0f */` +- `--base-address ADDRESS`: Override base virtual address for input files. +- `--start-offset OFFSET`: Override start offset for input files. +- `--end-offset OFFSET`: Override end offset for input files. - `-W...`: warning flags, see below Additionally, you can pass the flag `--version` to see the current ZAPD version. If that flag is passed, ZAPD will ignore any other parameter passed. diff --git a/ZAPD/Globals.h b/ZAPD/Globals.h index 6f603e7a5..21d58c091 100644 --- a/ZAPD/Globals.h +++ b/ZAPD/Globals.h @@ -41,6 +41,9 @@ class Globals fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath; TextureType texType; CsFloatType floatType = CsFloatType::FloatOnly; + int baseAddress = -1; + int startOffset = -1; + int endOffset = -1; ZGame game; GameConfig cfg; bool verboseUnaccounted = false; diff --git a/ZAPD/Main.cpp b/ZAPD/Main.cpp index 75529119a..271ebbc03 100644 --- a/ZAPD/Main.cpp +++ b/ZAPD/Main.cpp @@ -37,6 +37,9 @@ void Arg_EnableGCCCompat(int& i, char* argv[]); void Arg_ForceStatic(int& i, char* argv[]); void Arg_ForceUnaccountedStatic(int& i, char* argv[]); void Arg_CsFloatMode(int& i, char* argv[]); +void Arg_BaseAddress(int& i, char* argv[]); +void Arg_StartOffset(int& i, char* argv[]); +void Arg_EndOffset(int& i, char* argv[]); int main(int argc, char* argv[]); @@ -254,6 +257,9 @@ void ParseArgs(int& argc, char* argv[]) {"-us", &Arg_ForceUnaccountedStatic}, {"--unaccounted-static", &Arg_ForceUnaccountedStatic}, {"--cs-float", &Arg_CsFloatMode}, + {"--base-address", &Arg_BaseAddress}, + {"--start-offset", &Arg_StartOffset}, + {"--end-offset", &Arg_EndOffset}, }; for (int32_t i = 2; i < argc; i++) @@ -429,6 +435,21 @@ void Arg_CsFloatMode([[maybe_unused]] int& i, [[maybe_unused]] char* argv[]) } } +void Arg_BaseAddress(int& i, char* argv[]) +{ + Globals::Instance->baseAddress = std::stoul(argv[++i], nullptr, 16); +} + +void Arg_StartOffset(int& i, char* argv[]) +{ + Globals::Instance->startOffset = std::stoul(argv[++i], nullptr, 16); +} + +void Arg_EndOffset(int& i, char* argv[]) +{ + Globals::Instance->endOffset = std::stoul(argv[++i], nullptr, 16); +} + int HandleExtract(ZFileMode fileMode, ExporterSet* exporterSet) { bool procFileModeSuccess = false; diff --git a/ZAPD/ZFile.cpp b/ZAPD/ZFile.cpp index 656ef6aa6..db2d251a5 100644 --- a/ZAPD/ZFile.cpp +++ b/ZAPD/ZFile.cpp @@ -120,6 +120,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) if (reader->Attribute("BaseAddress") != nullptr) baseAddress = StringHelper::StrToL(reader->Attribute("BaseAddress"), 16); + if (mode == ZFileMode::Extract && Globals::Instance->baseAddress != -1) + baseAddress = Globals::Instance->baseAddress; + if (reader->Attribute("RangeStart") != nullptr) rangeStart = StringHelper::StrToL(reader->Attribute("RangeStart"), 16); @@ -197,6 +200,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) } rawData = File::ReadAllBytes((basePath / name).string()); + if (mode == ZFileMode::Extract && Globals::Instance->startOffset != -1 && Globals::Instance->endOffset != -1) + rawData = std::vector(rawData.begin() + Globals::Instance->startOffset, + rawData.begin() + Globals::Instance->endOffset); if (reader->Attribute("RangeEnd") == nullptr) rangeEnd = rawData.size(); From 175a31f575f253f06c1a25a0ebaa32189ceb08cd Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Fri, 21 Jun 2024 15:42:58 -0700 Subject: [PATCH 3/4] make zapd addresses globals int64_t so they can store uint32_t addresses and -1 --- ZAPD/Globals.h | 6 +++--- ZAPD/Main.cpp | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ZAPD/Globals.h b/ZAPD/Globals.h index 21d58c091..2cc9c2d4d 100644 --- a/ZAPD/Globals.h +++ b/ZAPD/Globals.h @@ -41,9 +41,9 @@ class Globals fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath; TextureType texType; CsFloatType floatType = CsFloatType::FloatOnly; - int baseAddress = -1; - int startOffset = -1; - int endOffset = -1; + int64_t baseAddress = -1; + int64_t startOffset = -1; + int64_t endOffset = -1; ZGame game; GameConfig cfg; bool verboseUnaccounted = false; diff --git a/ZAPD/Main.cpp b/ZAPD/Main.cpp index 271ebbc03..3d91f2e04 100644 --- a/ZAPD/Main.cpp +++ b/ZAPD/Main.cpp @@ -435,19 +435,25 @@ void Arg_CsFloatMode([[maybe_unused]] int& i, [[maybe_unused]] char* argv[]) } } +uint32_t parse_u32_hex(char* str) +{ + static_assert(sizeof(uint32_t) <= sizeof(unsigned long)); + return (uint32_t)std::stoul(str, nullptr, 16); +} + void Arg_BaseAddress(int& i, char* argv[]) { - Globals::Instance->baseAddress = std::stoul(argv[++i], nullptr, 16); + Globals::Instance->baseAddress = parse_u32_hex(argv[++i]); } void Arg_StartOffset(int& i, char* argv[]) { - Globals::Instance->startOffset = std::stoul(argv[++i], nullptr, 16); + Globals::Instance->startOffset = parse_u32_hex(argv[++i]); } void Arg_EndOffset(int& i, char* argv[]) { - Globals::Instance->endOffset = std::stoul(argv[++i], nullptr, 16); + Globals::Instance->endOffset = parse_u32_hex(argv[++i]); } int HandleExtract(ZFileMode fileMode, ExporterSet* exporterSet) From f046260edecad8ad2592ec96b43b5548a77103e8 Mon Sep 17 00:00:00 2001 From: cadmic Date: Fri, 21 Jun 2024 19:22:49 -0700 Subject: [PATCH 4/4] Use CamelCase --- ZAPD/Main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ZAPD/Main.cpp b/ZAPD/Main.cpp index 3d91f2e04..19d10d7d9 100644 --- a/ZAPD/Main.cpp +++ b/ZAPD/Main.cpp @@ -435,7 +435,7 @@ void Arg_CsFloatMode([[maybe_unused]] int& i, [[maybe_unused]] char* argv[]) } } -uint32_t parse_u32_hex(char* str) +uint32_t ParseU32Hex(char* str) { static_assert(sizeof(uint32_t) <= sizeof(unsigned long)); return (uint32_t)std::stoul(str, nullptr, 16); @@ -443,17 +443,17 @@ uint32_t parse_u32_hex(char* str) void Arg_BaseAddress(int& i, char* argv[]) { - Globals::Instance->baseAddress = parse_u32_hex(argv[++i]); + Globals::Instance->baseAddress = ParseU32Hex(argv[++i]); } void Arg_StartOffset(int& i, char* argv[]) { - Globals::Instance->startOffset = parse_u32_hex(argv[++i]); + Globals::Instance->startOffset = ParseU32Hex(argv[++i]); } void Arg_EndOffset(int& i, char* argv[]) { - Globals::Instance->endOffset = parse_u32_hex(argv[++i]); + Globals::Instance->endOffset = ParseU32Hex(argv[++i]); } int HandleExtract(ZFileMode fileMode, ExporterSet* exporterSet)