Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZAPD features to support OOT multiversion assets #322

Merged
merged 4 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions ZAPD/Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class Globals
fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath;
TextureType texType;
CsFloatType floatType = CsFloatType::FloatOnly;
int64_t baseAddress = -1;
int64_t startOffset = -1;
int64_t endOffset = -1;
ZGame game;
GameConfig cfg;
bool verboseUnaccounted = false;
Expand Down
27 changes: 27 additions & 0 deletions ZAPD/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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[]);

Expand Down Expand Up @@ -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++)
Expand Down Expand Up @@ -429,6 +435,27 @@ void Arg_CsFloatMode([[maybe_unused]] int& i, [[maybe_unused]] char* argv[])
}
}

uint32_t ParseU32Hex(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 = ParseU32Hex(argv[++i]);
}

void Arg_StartOffset(int& i, char* argv[])
{
Globals::Instance->startOffset = ParseU32Hex(argv[++i]);
}

void Arg_EndOffset(int& i, char* argv[])
{
Globals::Instance->endOffset = ParseU32Hex(argv[++i]);
}

int HandleExtract(ZFileMode fileMode, ExporterSet* exporterSet)
{
bool procFileModeSuccess = false;
Expand Down
18 changes: 18 additions & 0 deletions ZAPD/ZFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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<uint8_t>(rawData.begin() + Globals::Instance->startOffset,
rawData.begin() + Globals::Instance->endOffset);

if (reader->Attribute("RangeEnd") == nullptr)
rangeEnd = rawData.size();
Expand Down Expand Up @@ -585,6 +591,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<std::string> parts = StringHelper::Split(includePath, "/");
parts.erase(parts.begin(), parts.begin() + 2);
includePath = StringHelper::Join(parts, "/");
}

Declaration* decl = GetDeclaration(address);
if (decl == nullptr)
Expand Down Expand Up @@ -621,6 +633,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<std::string> parts = StringHelper::Split(includePath, "/");
parts.erase(parts.begin(), parts.begin() + 2);
includePath = StringHelper::Join(parts, "/");
}

Declaration* decl = GetDeclaration(address);
if (decl == nullptr)
Expand Down
15 changes: 15 additions & 0 deletions ZAPDUtils/Utils/StringHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ class StringHelper
return result;
}

static std::string Join(const std::vector<std::string> 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;
Expand Down
Loading