Skip to content

Commit

Permalink
Check XML resource attributes (#126)
Browse files Browse the repository at this point in the history
* register attibutes

* fix array problems

* cutscene problems

* Set inner

* fix merge

* ups

* Run format

* small cleaning

* A small blob cleanup

* Simplify the logic a bit

* ups

* Fix merge problem

* Fix merge issues

* Fix merge issues

* fix merge-produced type

* Fix merge issues

* run format and update easteregg

* register ZPath attributes

* dumb problems

* How dumb can I be?

* future proof change

* empty commit

* Check if Width and Height attributes of ZTexture has only decimal digits
  • Loading branch information
AngheloAlf authored May 27, 2021
1 parent 769f570 commit 4410b55
Show file tree
Hide file tree
Showing 38 changed files with 447 additions and 381 deletions.
2 changes: 1 addition & 1 deletion ZAPD/HighLevel/HLAnimationIntermediette.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ HLAnimationIntermediette* HLAnimationIntermediette::FromZAnimation(ZAnimation* z

ZAnimation* HLAnimationIntermediette::ToZAnimation()
{
ZAnimation* zAnim = new ZAnimation(nullptr);
ZAnimation* zAnim = new ZNormalAnimation(nullptr);

return zAnim;
}
Expand Down
17 changes: 12 additions & 5 deletions ZAPD/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@

#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#include <csignal>
#include <cstdlib>
#include <cxxabi.h> // for __cxa_demangle
#include <dlfcn.h> // for dladdr
#include <execinfo.h>
#include <time.h>
#include <unistd.h>
#endif

Expand All @@ -35,6 +37,7 @@ void BuildAssetModelIntermediette(const fs::path& outPath);
void BuildAssetAnimationIntermediette(const fs::path& animPath, const fs::path& outPath);

#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
void ErrorHandler(int sig)
{
void* array[4096];
Expand All @@ -44,11 +47,15 @@ void ErrorHandler(int sig)

fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig);

fprintf(stderr, "\n\t\tYou've met with a terrible fate, haven't you?\n\n");
/**
* Other possible options:
* - SEA BEARS FOAM. SLEEP BEARS DREAMS. \n BOTH END IN THE SAME WAY: CRASSSH!
*/
const char* crashEasterEgg[] = {
"\tYou've met with a terrible fate, haven't you?",
"\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!",
};

srand(time(nullptr));
auto easterIndex = rand() % ARRAY_COUNT(crashEasterEgg);

fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]);

fprintf(stderr, "Traceback:\n");
for (size_t i = 1; i < size; i++)
Expand Down
6 changes: 6 additions & 0 deletions ZAPD/StringHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdarg.h>
#include <string>
#include <vector>
#include <algorithm>

class StringHelper
{
Expand Down Expand Up @@ -99,4 +100,9 @@ class StringHelper
}

static std::string BoolStr(bool b) { return b ? "true" : "false"; }

static bool HasOnlyDigits(const std::string &str)
{
return std::all_of(str.begin(), str.end(), ::isdigit);
}
};
41 changes: 9 additions & 32 deletions ZAPD/ZAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ void ZAnimation::Save(const fs::path& outFolder)
}
}

void ZAnimation::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
}

std::string ZAnimation::GetSourceOutputCode(const std::string& prefix)
{
return "";
Expand Down Expand Up @@ -120,16 +115,6 @@ std::string ZNormalAnimation::GetSourceTypeName() const
return "AnimationHeader";
}

void ZNormalAnimation::ExtractFromXML(tinyxml2::XMLElement* reader,
const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex)
{
rawData = std::move(nRawData);
rawDataIndex = nRawDataIndex;
ParseXML(reader);
ParseRawData();
}

void ZNormalAnimation::ParseRawData()
{
ZAnimation::ParseRawData();
Expand Down Expand Up @@ -196,16 +181,6 @@ std::string ZLinkAnimation::GetSourceTypeName() const
return "LinkAnimationHeader";
}

void ZLinkAnimation::ExtractFromXML(tinyxml2::XMLElement* reader,
const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex)
{
rawData = std::move(nRawData);
rawDataIndex = nRawDataIndex;
ParseXML(reader);
ParseRawData();
}

void ZLinkAnimation::ParseRawData()
{
ZAnimation::ParseRawData();
Expand Down Expand Up @@ -251,6 +226,7 @@ std::string TransformData::GetSourceTypeName()

ZCurveAnimation::ZCurveAnimation(ZFile* nParent) : ZAnimation(nParent)
{
RegisterOptionalAttribute("SkelOffset");
}

ZCurveAnimation::~ZCurveAnimation()
Expand All @@ -262,15 +238,16 @@ void ZCurveAnimation::ParseXML(tinyxml2::XMLElement* reader)
{
ZAnimation::ParseXML(reader);

const char* skelOffsetXml = reader->Attribute("SkelOffset");
if (skelOffsetXml == nullptr)
std::string skelOffsetXml = registeredAttributes.at("SkelOffset").value;
if (skelOffsetXml == "")
{
throw std::runtime_error(StringHelper::Sprintf(
"ZCurveAnimation::ParseXML: Fatal error in '%s'. Missing 'SkelOffset' attribute in "
"ZCurveAnimation. You need to provide the offset of the curve skeleton.",
name.c_str()));
throw std::runtime_error(
StringHelper::Sprintf("ZCurveAnimation::ParseXML: Fatal error in '%s'.\n"
"\t Missing 'SkelOffset' attribute in ZCurveAnimation.\n"
"\t You need to provide the offset of the curve skeleton.",
name.c_str()));
}
skelOffset = std::strtoul(skelOffsetXml, nullptr, 0);
skelOffset = StringHelper::StrToL(skelOffsetXml, 0);
}

void ZCurveAnimation::ParseRawData()
Expand Down
7 changes: 0 additions & 7 deletions ZAPD/ZAnimation.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class ZAnimation : public ZResource
protected:
void ParseRawData() override;
void Save(const fs::path& outFolder) override;
void ParseXML(tinyxml2::XMLElement* reader) override;
};

class ZNormalAnimation : public ZAnimation
Expand All @@ -52,9 +51,6 @@ class ZNormalAnimation : public ZAnimation
size_t GetRawDataSize() const override;
std::string GetSourceTypeName() const override;

void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex) override;

protected:
virtual void ParseRawData() override;
};
Expand All @@ -70,9 +66,6 @@ class ZLinkAnimation : public ZAnimation
size_t GetRawDataSize() const override;
std::string GetSourceTypeName() const override;

void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex) override;

protected:
virtual void ParseRawData() override;
};
Expand Down
70 changes: 39 additions & 31 deletions ZAPD/ZArray.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "ZArray.h"
#include <cassert>
#include "Globals.h"
#include "StringHelper.h"
#include "ZFile.h"
Expand All @@ -8,71 +9,78 @@ REGISTER_ZFILENODE(Array, ZArray);
ZArray::ZArray(ZFile* nParent) : ZResource(nParent)
{
canHaveInner = true;
RegisterRequiredAttribute("Count");
}

ZArray::~ZArray()
{
delete testFile;
for (auto res : resList)
delete res;
}

void ZArray::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);

arrayCnt = reader->IntAttribute("Count", 0);
testFile = new ZFile(ZFileMode::Extract, reader, Globals::Instance->baseRomPath, "",
parent->GetName(), "ZArray subfile", true);
}

// TODO: This is a bit hacky, but until we refactor how ZFile parses the XML, it'll have to do.
std::string ZArray::GetSourceOutputCode(const std::string& prefix)
{
std::string output = "";
arrayCnt = StringHelper::StrToL(registeredAttributes.at("Count").value, 0);
// TODO: do a better check.
assert(arrayCnt > 0);

if (testFile->resources.size() <= 0)
tinyxml2::XMLElement* child = reader->FirstChildElement();
if (child == nullptr)
throw std::runtime_error(
StringHelper::Sprintf("Error! Array needs at least one sub-element.\n"));

ZResource* res = testFile->resources[0];
size_t resSize = res->GetRawDataSize();
childName = child->Name();

if (!res->DoesSupportArray())
auto nodeMap = ZFile::GetNodeMap();
size_t childIndex = rawDataIndex;
for (size_t i = 0; i < arrayCnt; i++)
{
throw std::runtime_error(StringHelper::Sprintf(
"Error! Resource %s does not support being wrapped in an array!\n",
res->GetName().c_str()));
ZResource* res = nodeMap->at(childName)(parent);
if (!res->DoesSupportArray())
{
throw std::runtime_error(StringHelper::Sprintf(
"Error! Resource %s does not support being wrapped in an array!\n",
childName.c_str()));
}
res->parent = parent;
res->SetInnerNode(true);
res->ExtractFromXML(child, rawData, childIndex);

childIndex += res->GetRawDataSize();
resList.push_back(res);
}
}

std::string ZArray::GetSourceOutputCode(const std::string& prefix)
{
std::string output = "";

for (size_t i = 0; i < arrayCnt; i++)
{
size_t childIndex = rawDataIndex + (i * resSize);
res->SetRawDataIndex(childIndex);
res->ParseRawData();
std::string test = res->GetSourceOutputCode("");
// output += " { " + testFile->declarations[childIndex]->text + " }";
output += testFile->declarations[childIndex]->text;
output += resList.at(i)->GetBodySourceCode();

if (i < arrayCnt - 1)
output += ",\n";
}

if (parent != nullptr)
parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(),
res->GetSourceTypeName(), name, arrayCnt, output);
resList.at(0)->GetSourceTypeName(), name, arrayCnt, output);

return "";
}

size_t ZArray::GetRawDataSize() const
{
return arrayCnt * testFile->resources[0]->GetRawDataSize();
size_t size = 0;
for (auto res : resList)
size += res->GetRawDataSize();
return size;
}

void ZArray::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex)
ZResourceType ZArray::GetResourceType() const
{
rawData = nRawData;
rawDataIndex = nRawDataIndex;
ParseXML(reader);
// arr->ParseRawData();
return ZResourceType::Array;
}
9 changes: 5 additions & 4 deletions ZAPD/ZArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ class ZArray : public ZResource
~ZArray();

void ParseXML(tinyxml2::XMLElement* reader) override;

std::string GetSourceOutputCode(const std::string& prefix) override;
size_t GetRawDataSize() const override;

void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex) override;
ZResourceType GetResourceType() const override;

protected:
size_t arrayCnt;
ZFile* testFile;
};
std::string childName;
std::vector<ZResource*> resList;
};
Loading

0 comments on commit 4410b55

Please sign in to comment.