1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-10 08:50:23 +00:00

git subrepo pull --force tools/ZAPD (#1049)

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "a3363333d"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "a3363333d"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
fig02 2021-12-03 15:57:05 -05:00 committed by GitHub
parent 5e9d24fca4
commit 68899c2e33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1311 additions and 569 deletions

View file

@ -13,6 +13,7 @@
#include "Utils/MemoryStream.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZAnimation.h"
#include "ZArray.h"
#include "ZBackground.h"
@ -73,19 +74,13 @@ ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBas
ZFile::~ZFile()
{
for (ZResource* res : resources)
{
delete res;
}
for (auto d : declarations)
{
delete d.second;
}
for (auto sym : symbolResources)
{
delete sym.second;
}
}
void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
@ -114,8 +109,11 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
else if (std::string_view(gameStr) == "OOT")
Globals::Instance->game = ZGame::OOT_RETAIL;
else
throw std::runtime_error(
StringHelper::Sprintf("Error: Game type %s not supported.", gameStr));
{
std::string errorHeader =
StringHelper::Sprintf("'Game' type '%s' is not supported.", gameStr);
HANDLE_ERROR_PROCESS(WarningType::InvalidAttributeValue, errorHeader, "");
}
}
if (reader->Attribute("BaseAddress") != nullptr)
@ -128,16 +126,22 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
rangeEnd = StringHelper::StrToL(reader->Attribute("RangeEnd"), 16);
if (rangeStart > rangeEnd)
throw std::runtime_error("Error: RangeStart must be before than RangeEnd.");
HANDLE_ERROR_PROCESS(
WarningType::Always,
StringHelper::Sprintf("'RangeStart' 0x%06X must be before 'RangeEnd' 0x%06X",
rangeStart, rangeEnd),
"");
const char* segmentXml = reader->Attribute("Segment");
if (segmentXml != nullptr)
{
if (!StringHelper::HasOnlyDigits(segmentXml))
{
throw std::runtime_error(StringHelper::Sprintf(
"error: Invalid segment value '%s': must be a decimal between 0 and 15 inclusive",
segmentXml));
HANDLE_ERROR_PROCESS(WarningType::Always,
StringHelper::Sprintf("error: Invalid segment value '%s': must be "
"a decimal between 0 and 15 inclusive",
segmentXml),
"");
}
segment = StringHelper::StrToL(segmentXml, 10);
@ -146,16 +150,19 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
if (segment == 128)
{
#ifdef DEPRECATION_ON
fprintf(stderr, "warning: segment 128 is deprecated.\n\tRemove "
"'Segment=\"128\"' from the xml to use virtual addresses\n");
HANDLE_WARNING_PROCESS(
WarningType::Always, "warning: segment 128 is deprecated.",
"Remove 'Segment=\"128\"' from the xml to use virtual addresses\n");
#endif
}
else
{
throw std::runtime_error(
HANDLE_ERROR_PROCESS(
WarningType::Always,
StringHelper::Sprintf("error: invalid segment value '%s': must be a decimal "
"number between 0 and 15 inclusive",
segmentXml));
segmentXml),
"");
}
}
}
@ -176,18 +183,16 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile)
{
if (!File::Exists((basePath / name).string()))
throw std::runtime_error(
StringHelper::Sprintf("Error! File %s does not exist.", (basePath / name).c_str()));
{
std::string errorHeader = StringHelper::Sprintf("binary file '%s' does not exist.",
(basePath / name).c_str());
HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, "");
}
rawData = File::ReadAllBytes((basePath / name).string());
/*
* TODO: In OoT repo ovl_Boss_Sst has a wrong RangeEnd (0xAD40 instead of 0xAD70),
* so uncommenting the following produces wrong behavior.
* If somebody fixes that in OoT repo, uncomment this. I'm too tired of fixing XMLs.
*/
// if (reader->Attribute("RangeEnd") == nullptr)
// rangeEnd = rawData.size();
if (reader->Attribute("RangeEnd") == nullptr)
rangeEnd = rawData.size();
}
std::unordered_set<std::string> nameSet;
@ -211,20 +216,17 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
if (offsetSet.find(offsetXml) != offsetSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Offset' attribute: %s \n",
name.c_str(), offsetXml));
std::string errorHeader =
StringHelper::Sprintf("repeated 'Offset' attribute: %s", offsetXml);
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
offsetSet.insert(offsetXml);
}
else if (Globals::Instance->warnNoOffset)
else
{
fprintf(stderr, "Warning No offset specified for: %s", nameXml);
}
else if (Globals::Instance->errorNoOffset)
{
throw std::runtime_error(
StringHelper::Sprintf("Error no offset specified for %s", nameXml));
HANDLE_WARNING_RESOURCE(WarningType::MissingOffsets, this, nullptr, rawDataIndex,
StringHelper::Sprintf("no offset specified for %s.", nameXml),
"");
}
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
@ -234,9 +236,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
{
if (outNameSet.find(outNameXml) != outNameSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'OutName' attribute: %s \n",
name.c_str(), outNameXml));
std::string errorHeader =
StringHelper::Sprintf("repeated 'OutName' attribute: %s", outNameXml);
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
outNameSet.insert(outNameXml);
}
@ -244,9 +246,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
{
if (nameSet.find(nameXml) != nameSet.end())
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Name' attribute: %s \n",
name.c_str(), nameXml));
std::string errorHeader =
StringHelper::Sprintf("repeated 'Name' attribute: %s", nameXml);
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
nameSet.insert(nameXml);
}
@ -279,16 +281,14 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
}
else if (std::string_view(child->Name()) == "File")
{
throw std::runtime_error(StringHelper::Sprintf(
"ZFile::ParseXML: Error in '%s'.\n\t Can't declare a File inside a File.\n",
name.c_str()));
std::string errorHeader = "Can't declare a <File> inside a <File>";
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
else
{
throw std::runtime_error(
StringHelper::Sprintf("ZFile::ParseXML: Error in '%s'.\n\t Unknown element found "
"inside a File element: '%s'.\n",
name.c_str(), nodeName.c_str()));
std::string errorHeader = StringHelper::Sprintf(
"Unknown element found inside a <File> element: %s", nodeName.c_str());
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
}
}
@ -307,7 +307,7 @@ void ZFile::BuildSourceFile()
return;
if (!Directory::Exists(outputPath))
Directory::CreateDirectory(outputPath);
Directory::CreateDirectory(outputPath.string());
GenerateSourceFiles();
}
@ -317,6 +317,11 @@ std::string ZFile::GetName() const
return name;
}
std::string ZFile::GetOutName() const
{
return outName.string();
}
ZFileMode ZFile::GetMode() const
{
return mode;
@ -338,10 +343,10 @@ void ZFile::ExtractResources()
return;
if (!Directory::Exists(outputPath))
Directory::CreateDirectory(outputPath);
Directory::CreateDirectory(outputPath.string());
if (!Directory::Exists(GetSourceOutputFolderPath()))
Directory::CreateDirectory(GetSourceOutputFolderPath());
Directory::CreateDirectory(GetSourceOutputFolderPath().string());
for (size_t i = 0; i < resources.size(); i++)
resources[i]->ParseRawDataLate();
@ -351,8 +356,8 @@ void ZFile::ExtractResources()
if (Globals::Instance->genSourceFile)
GenerateSourceFiles();
MemoryStream* memStream = new MemoryStream();
BinaryWriter writer = BinaryWriter(memStream);
auto memStreamFile = std::shared_ptr<MemoryStream>(new MemoryStream());
BinaryWriter writerFile = BinaryWriter(memStreamFile);
ExporterSet* exporterSet = Globals::Instance->GetExporterSet();
@ -361,6 +366,9 @@ void ZFile::ExtractResources()
for (ZResource* res : resources)
{
auto memStreamRes = std::shared_ptr<MemoryStream>(new MemoryStream());
BinaryWriter writerRes = BinaryWriter(memStreamRes);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
printf("Saving resource %s\n", res->GetName().c_str());
@ -369,18 +377,24 @@ void ZFile::ExtractResources()
// Check if we have an exporter "registered" for this resource type
ZResourceExporter* exporter = Globals::Instance->GetExporter(res->GetResourceType());
if (exporter != nullptr)
exporter->Save(res, Globals::Instance->outputPath.string(), &writer);
{
//exporter->Save(res, Globals::Instance->outputPath.string(), &writerFile);
exporter->Save(res, Globals::Instance->outputPath.string(), &writerRes);
}
if (exporterSet != nullptr && exporterSet->resSaveFunc != nullptr)
exporterSet->resSaveFunc(res, writerRes);
}
if (memStream->GetLength() > 0)
if (memStreamFile->GetLength() > 0)
{
File::WriteAllBytes(StringHelper::Sprintf("%s%s.bin",
Globals::Instance->outputPath.string().c_str(),
GetName().c_str()),
memStream->ToVector());
memStreamFile->ToVector());
}
writer.Close();
writerFile.Close();
if (exporterSet != nullptr && exporterSet->endFileFunc != nullptr)
exporterSet->endFileFunc(this);
@ -1070,8 +1084,6 @@ std::string ZFile::ProcessDeclarations()
}
}
output += "\n";
return output;
}
@ -1234,11 +1246,12 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr,
{
Declaration* currentDecl = declarations.at(currentAddress);
fprintf(stderr,
"WARNING: Intersection detected from 0x%06X:0x%06X (%s), conflicts with "
"0x%06X (%s)\n",
lastAddr, lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress,
currentDecl->varName.c_str());
std::string intersectionInfo = StringHelper::Sprintf(
"Resource from 0x%06X:0x%06X (%s) conflicts with 0x%06X (%s).", lastAddr,
lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress,
currentDecl->varName.c_str());
HANDLE_WARNING_RESOURCE(WarningType::Intersection, this, nullptr, currentAddress,
"intersection detected", intersectionInfo);
}
}
@ -1309,25 +1322,17 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr,
diff, src);
decl->isUnaccounted = true;
if (Globals::Instance->warnUnaccounted)
if (nonZeroUnaccounted)
{
if (nonZeroUnaccounted)
{
fprintf(stderr,
"Warning in file: %s (%s)\n"
"\t A non-zero unaccounted block was found at offset '0x%06X'.\n"
"\t Block size: '0x%X'.\n",
xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff);
}
else if (diff >= 16)
{
fprintf(stderr,
"Warning in file: %s (%s)\n"
"\t A big (size>=0x10) zero-only unaccounted block was found "
"at offset '0x%06X'.\n"
"\t Block size: '0x%X'.\n",
xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff);
}
HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress,
"a non-zero unaccounted block was found",
StringHelper::Sprintf("Block size: '0x%X'", diff));
}
else if (diff >= 16)
{
HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress,
"a big (size>=0x10) zero-only unaccounted block was found",
StringHelper::Sprintf("Block size: '0x%X'", diff));
}
}
}