diff --git a/ZAPD/HighLevel/HLAnimationIntermediette.cpp b/ZAPD/HighLevel/HLAnimationIntermediette.cpp index f21d28ab6..a316ddf6f 100644 --- a/ZAPD/HighLevel/HLAnimationIntermediette.cpp +++ b/ZAPD/HighLevel/HLAnimationIntermediette.cpp @@ -62,7 +62,7 @@ HLAnimationIntermediette* HLAnimationIntermediette::FromZAnimation(ZAnimation* z ZAnimation* HLAnimationIntermediette::ToZAnimation() { - ZAnimation* zAnim = new ZAnimation(nullptr); + ZAnimation* zAnim = new ZNormalAnimation(nullptr); return zAnim; } diff --git a/ZAPD/Main.cpp b/ZAPD/Main.cpp index c414edf2c..21c7c036e 100644 --- a/ZAPD/Main.cpp +++ b/ZAPD/Main.cpp @@ -14,9 +14,11 @@ #if !defined(_MSC_VER) && !defined(__CYGWIN__) #include +#include #include // for __cxa_demangle #include // for dladdr #include +#include #include #endif @@ -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]; @@ -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++) diff --git a/ZAPD/StringHelper.h b/ZAPD/StringHelper.h index 1249cec45..b07a99f0e 100644 --- a/ZAPD/StringHelper.h +++ b/ZAPD/StringHelper.h @@ -5,6 +5,7 @@ #include #include #include +#include class StringHelper { @@ -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); + } }; diff --git a/ZAPD/ZAnimation.cpp b/ZAPD/ZAnimation.cpp index 749abd95c..f011a294e 100644 --- a/ZAPD/ZAnimation.cpp +++ b/ZAPD/ZAnimation.cpp @@ -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 ""; @@ -120,16 +115,6 @@ std::string ZNormalAnimation::GetSourceTypeName() const return "AnimationHeader"; } -void ZNormalAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, - const std::vector& nRawData, - const uint32_t nRawDataIndex) -{ - rawData = std::move(nRawData); - rawDataIndex = nRawDataIndex; - ParseXML(reader); - ParseRawData(); -} - void ZNormalAnimation::ParseRawData() { ZAnimation::ParseRawData(); @@ -196,16 +181,6 @@ std::string ZLinkAnimation::GetSourceTypeName() const return "LinkAnimationHeader"; } -void ZLinkAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, - const std::vector& nRawData, - const uint32_t nRawDataIndex) -{ - rawData = std::move(nRawData); - rawDataIndex = nRawDataIndex; - ParseXML(reader); - ParseRawData(); -} - void ZLinkAnimation::ParseRawData() { ZAnimation::ParseRawData(); @@ -251,6 +226,7 @@ std::string TransformData::GetSourceTypeName() ZCurveAnimation::ZCurveAnimation(ZFile* nParent) : ZAnimation(nParent) { + RegisterOptionalAttribute("SkelOffset"); } ZCurveAnimation::~ZCurveAnimation() @@ -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() diff --git a/ZAPD/ZAnimation.h b/ZAPD/ZAnimation.h index ce62a95f1..513ee5939 100644 --- a/ZAPD/ZAnimation.h +++ b/ZAPD/ZAnimation.h @@ -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 @@ -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& nRawData, - const uint32_t nRawDataIndex) override; - protected: virtual void ParseRawData() override; }; @@ -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& nRawData, - const uint32_t nRawDataIndex) override; - protected: virtual void ParseRawData() override; }; diff --git a/ZAPD/ZArray.cpp b/ZAPD/ZArray.cpp index 5429277be..3194eac2d 100644 --- a/ZAPD/ZArray.cpp +++ b/ZAPD/ZArray.cpp @@ -1,4 +1,5 @@ #include "ZArray.h" +#include #include "Globals.h" #include "StringHelper.h" #include "ZFile.h" @@ -8,49 +9,57 @@ 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"; @@ -58,21 +67,20 @@ std::string ZArray::GetSourceOutputCode(const std::string& prefix) 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& nRawData, - const uint32_t nRawDataIndex) +ZResourceType ZArray::GetResourceType() const { - rawData = nRawData; - rawDataIndex = nRawDataIndex; - ParseXML(reader); - // arr->ParseRawData(); + return ZResourceType::Array; } diff --git a/ZAPD/ZArray.h b/ZAPD/ZArray.h index b00bee4f7..f43dc1242 100644 --- a/ZAPD/ZArray.h +++ b/ZAPD/ZArray.h @@ -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& nRawData, - const uint32_t nRawDataIndex) override; + ZResourceType GetResourceType() const override; protected: size_t arrayCnt; - ZFile* testFile; -}; \ No newline at end of file + std::string childName; + std::vector resList; +}; diff --git a/ZAPD/ZBlob.cpp b/ZAPD/ZBlob.cpp index 3131c1272..e377bcf8c 100644 --- a/ZAPD/ZBlob.cpp +++ b/ZAPD/ZBlob.cpp @@ -11,27 +11,7 @@ REGISTER_ZFILENODE(Blob, ZBlob); ZBlob::ZBlob(ZFile* nParent) : ZResource(nParent) { -} - -ZBlob::ZBlob(const std::vector& nRawData, uint32_t nRawDataIndex, size_t size, - std::string nName, ZFile* nParent) - : ZBlob(nParent) -{ - rawDataIndex = nRawDataIndex; - rawData = - std::vector(nRawData.data() + rawDataIndex, nRawData.data() + rawDataIndex + size); - name = std::move(nName); -} - -void ZBlob::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) -{ - rawDataIndex = nRawDataIndex; - - ParseXML(reader); - long size = strtol(reader->Attribute("Size"), NULL, 16); - rawData = - std::vector(nRawData.data() + rawDataIndex, nRawData.data() + rawDataIndex + size); + RegisterRequiredAttribute("Size"); } // Build Source File Mode @@ -42,7 +22,7 @@ ZBlob* ZBlob::BuildFromXML(XMLElement* reader, const std::string& inFolder, bool blob->ParseXML(reader); if (readFile) - blob->rawData = File::ReadAllBytes(inFolder + "/" + blob->name + ".bin"); + blob->blobData = File::ReadAllBytes(inFolder + "/" + blob->name + ".bin"); return blob; } @@ -51,21 +31,33 @@ ZBlob* ZBlob::FromFile(const std::string& filePath) { ZBlob* blob = new ZBlob(nullptr); blob->name = StringHelper::Split(Path::GetFileNameWithoutExtension(filePath), ".")[0]; - blob->rawData = File::ReadAllBytes(filePath); + blob->blobData = File::ReadAllBytes(filePath); return blob; } +void ZBlob::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); + + blobSize = StringHelper::StrToL(registeredAttributes.at("Size").value, 16); +} + +void ZBlob::ParseRawData() +{ + blobData.assign(rawData.data() + rawDataIndex, rawData.data() + rawDataIndex + blobSize); +} + std::string ZBlob::GetSourceOutputCode(const std::string& prefix) { sourceOutput = ""; - for (size_t i = 0; i < rawData.size(); i += 1) + for (size_t i = 0; i < blobData.size(); i += 1) { if (i % 16 == 0) sourceOutput += " "; - sourceOutput += StringHelper::Sprintf("0x%02X, ", rawData[i]); + sourceOutput += StringHelper::Sprintf("0x%02X, ", blobData[i]); if (i % 16 == 15) sourceOutput += "\n"; @@ -86,7 +78,7 @@ std::string ZBlob::GetSourceOutputHeader(const std::string& prefix) void ZBlob::Save(const fs::path& outFolder) { - File::WriteAllBytes(outFolder / (name + ".bin"), rawData); + File::WriteAllBytes(outFolder / (name + ".bin"), blobData); } bool ZBlob::IsExternalResource() const @@ -108,3 +100,8 @@ ZResourceType ZBlob::GetResourceType() const { return ZResourceType::Blob; } + +size_t ZBlob::GetRawDataSize() const +{ + return blobSize; +} diff --git a/ZAPD/ZBlob.h b/ZAPD/ZBlob.h index 633a9c70f..2f8d31572 100644 --- a/ZAPD/ZBlob.h +++ b/ZAPD/ZBlob.h @@ -7,20 +7,25 @@ class ZBlob : public ZResource { public: ZBlob(ZFile* nParent); - ZBlob(const std::vector& nRawData, uint32_t rawDataIndex, size_t size, - std::string nName, ZFile* nParent); - - void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) override; // Extract Mode static ZBlob* BuildFromXML(tinyxml2::XMLElement* reader, const std::string& inFolder, bool readFile); static ZBlob* FromFile(const std::string& filePath); + + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; std::string GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceOutputHeader(const std::string& prefix) override; void Save(const fs::path& outFolder) override; + bool IsExternalResource() const override; - std::string GetExternalExtension() const override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; + std::string GetExternalExtension() const override; + + size_t GetRawDataSize() const override; + +protected: + std::vector blobData; + size_t blobSize = 0; }; diff --git a/ZAPD/ZCollision.cpp b/ZAPD/ZCollision.cpp index fd2f6ee91..34d7ee12d 100644 --- a/ZAPD/ZCollision.cpp +++ b/ZAPD/ZCollision.cpp @@ -19,18 +19,6 @@ ZCollisionHeader::~ZCollisionHeader() delete camData; } -ZResourceType ZCollisionHeader::GetResourceType() const -{ - return ZResourceType::CollisionHeader; -} - -void ZCollisionHeader::ExtractFromXML(tinyxml2::XMLElement* reader, - const std::vector& nRawData, - const uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex); -} - void ZCollisionHeader::ParseRawData() { const uint8_t* data = rawData.data(); @@ -195,11 +183,21 @@ void ZCollisionHeader::ParseRawData() name.c_str(), polyTypeDefSegmentOffset, name.c_str(), camDataSegmentOffset, numWaterBoxes, waterBoxStr); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, DeclarationPadding::Pad16, 44, - "CollisionHeader", + parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, DeclarationPadding::Pad16, + GetRawDataSize(), "CollisionHeader", StringHelper::Sprintf("%s", name.c_str(), rawDataIndex), declaration); } +ZResourceType ZCollisionHeader::GetResourceType() const +{ + return ZResourceType::CollisionHeader; +} + +size_t ZCollisionHeader::GetRawDataSize() const +{ + return 44; +} + PolygonEntry::PolygonEntry(const std::vector& rawData, uint32_t rawDataIndex) { const uint8_t* data = rawData.data(); diff --git a/ZAPD/ZCollision.h b/ZAPD/ZCollision.h index 4f35d9ddd..8b53f2503 100644 --- a/ZAPD/ZCollision.h +++ b/ZAPD/ZCollision.h @@ -90,9 +90,9 @@ class ZCollisionHeader : public ZResource ZCollisionHeader(ZFile* nParent); ~ZCollisionHeader(); + void ParseRawData() override; + ZResourceType GetResourceType() const override; - void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) override; - void ParseRawData() override; + size_t GetRawDataSize() const override; }; diff --git a/ZAPD/ZCutscene.h b/ZAPD/ZCutscene.h index 525ade752..4899c82f8 100644 --- a/ZAPD/ZCutscene.h +++ b/ZAPD/ZCutscene.h @@ -423,6 +423,8 @@ class ZCutscene : public ZCutsceneBase ZCutscene(ZFile* nParent); ~ZCutscene(); + void ParseRawData() override; + std::string GetBodySourceCode() override; void DeclareVar(const std::string& prefix, const std::string& bodyStr) const override; std::string GetSourceOutputCode(const std::string& prefix) override; @@ -439,6 +441,4 @@ class ZCutscene : public ZCutsceneBase int32_t numCommands; int32_t endFrame; std::vector commands; - - void ParseRawData() override; }; diff --git a/ZAPD/ZDisplayList.cpp b/ZAPD/ZDisplayList.cpp index d81460ed7..745442dbb 100644 --- a/ZAPD/ZDisplayList.cpp +++ b/ZAPD/ZDisplayList.cpp @@ -45,6 +45,7 @@ void ZDisplayList::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, const uint32_t nRawDataIndex) { + rawData.assign(nRawData.begin(), nRawData.end()); rawDataIndex = nRawDataIndex; ParseXML(reader); @@ -52,8 +53,8 @@ void ZDisplayList::ExtractFromXML(tinyxml2::XMLElement* reader, int32_t rawDataSize = ZDisplayList::GetDListLength( nRawData, rawDataIndex, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); - rawData = std::vector(nRawData.data() + rawDataIndex, - nRawData.data() + rawDataIndex + rawDataSize); + dlistRawData.assign(nRawData.data() + rawDataIndex, + nRawData.data() + rawDataIndex + rawDataSize); ParseRawData(); } @@ -61,23 +62,23 @@ ZDisplayList::ZDisplayList(std::vector nRawData, uint32_t nRawDataIndex int32_t rawDataSize, ZFile* nParent) : ZDisplayList(nParent) { + rawData.assign(nRawData.begin(), nRawData.end()); fileData = nRawData; rawDataIndex = nRawDataIndex; name = StringHelper::Sprintf("DL_%06X", rawDataIndex); - rawData = std::vector(nRawData.data() + rawDataIndex, - nRawData.data() + rawDataIndex + rawDataSize); + dlistRawData.assign(nRawData.data() + rawDataIndex, + nRawData.data() + rawDataIndex + rawDataSize); ParseRawData(); } void ZDisplayList::ParseRawData() { - size_t numInstructions = rawData.size() / 8; - uint8_t* rawDataArr = rawData.data(); + size_t numInstructions = dlistRawData.size() / 8; instructions.reserve(numInstructions); for (size_t i = 0; i < numInstructions; i++) - instructions.push_back(BitConverter::ToUInt64BE(rawDataArr, (i * 8))); + instructions.push_back(BitConverter::ToUInt64BE(dlistRawData, (i * 8))); } void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, std::string prefix, @@ -416,7 +417,7 @@ int32_t ZDisplayList::GetDListLength(std::vector rawData, uint32_t rawD while (true) { - uint8_t opcode = rawData[rawDataIndex + (i * 8)]; + uint8_t opcode = rawData.at(rawDataIndex + (i * 8)); i++; if (opcode == endDLOpcode) diff --git a/ZAPD/ZDisplayList.h b/ZAPD/ZDisplayList.h index 9f94e39c0..233d80daf 100644 --- a/ZAPD/ZDisplayList.h +++ b/ZAPD/ZDisplayList.h @@ -379,4 +379,7 @@ class ZDisplayList : public ZResource std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; + +protected: + std::vector dlistRawData; }; diff --git a/ZAPD/ZFile.cpp b/ZAPD/ZFile.cpp index d34df8c01..ed106153f 100644 --- a/ZAPD/ZFile.cpp +++ b/ZAPD/ZFile.cpp @@ -143,7 +143,7 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b auto nodeMap = *GetNodeMap(); uint32_t rawDataIndex = 0; - for (XMLElement* child = reader->FirstChildElement(); child != NULL; + for (XMLElement* child = reader->FirstChildElement(); child != nullptr; child = child->NextSiblingElement()) { const char* nameXml = child->Attribute("Name"); diff --git a/ZAPD/ZLimb.cpp b/ZAPD/ZLimb.cpp index aa29e4e48..ce891b28c 100644 --- a/ZAPD/ZLimb.cpp +++ b/ZAPD/ZLimb.cpp @@ -356,11 +356,13 @@ ZLimb::ZLimb(ZFile* nParent) : ZResource(nParent) { dListPtr = 0; dList2Ptr = 0; + RegisterOptionalAttribute("LimbType"); + RegisterOptionalAttribute("Type"); } ZLimb::ZLimb(ZLimbType limbType, const std::string& prefix, const std::vector& nRawData, uint32_t nRawDataIndex, ZFile* nParent) - : ZResource(nParent) + : ZLimb(nParent) { rawData.assign(nRawData.begin(), nRawData.end()); rawDataIndex = nRawDataIndex; @@ -378,44 +380,44 @@ void ZLimb::ParseXML(tinyxml2::XMLElement* reader) ZResource::ParseXML(reader); // Reading from a - const char* limbType = reader->Attribute("LimbType"); - if (limbType == nullptr) // Reading from a - limbType = reader->Attribute("Type"); + std::string limbType = registeredAttributes.at("LimbType").value; + if (limbType == "") // Reading from a + limbType = registeredAttributes.at("Type").value; - if (limbType == nullptr) + if (limbType == "") { fprintf(stderr, - "ZLimb::ParseXML: Warning in '%s'.\n\t Missing 'LimbType' attribute in xml. " - "Defaulting to 'Standard'.\n", + "ZLimb::ParseXML: Warning in '%s'.\n" + "\t Missing 'LimbType' attribute in xml.\n" + "\t Defaulting to 'Standard'.\n", name.c_str()); type = ZLimbType::Standard; } else { - std::string limbTypeStr(limbType); - - if (limbTypeStr == "Standard") + if (limbType == "Standard") { type = ZLimbType::Standard; } - else if (limbTypeStr == "LOD") + else if (limbType == "LOD") { type = ZLimbType::LOD; } - else if (limbTypeStr == "Skin") + else if (limbType == "Skin") { type = ZLimbType::Skin; } - else if (limbTypeStr == "Curve") + else if (limbType == "Curve") { type = ZLimbType::Curve; } else { fprintf(stderr, - "ZLimb::ParseXML: Warning in '%s'.\n\t Invalid LimbType found: '%s'. " - "Defaulting to 'Standard'.\n", - name.c_str(), limbType); + "ZLimb::ParseXML: Warning in '%s'.\n" + "\t Invalid LimbType found: '%s'.\n" + "\t Defaulting to 'Standard'.\n", + name.c_str(), limbType.c_str()); type = ZLimbType::Standard; } } diff --git a/ZAPD/ZMtx.h b/ZAPD/ZMtx.h index cf90b4887..0771f29c4 100644 --- a/ZAPD/ZMtx.h +++ b/ZAPD/ZMtx.h @@ -6,14 +6,11 @@ class ZMtx : public ZResource { -protected: - std::array, 4> mtx; - public: - // ZMtx() = default; ZMtx(ZFile* nParent); ZMtx(const std::string& prefix, const std::vector& nRawData, uint32_t nRawDataIndex, ZFile* nParent); + void ParseRawData() override; void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, uint32_t nRawDataIndex) override; @@ -28,4 +25,7 @@ class ZMtx : public ZResource std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; + +protected: + std::array, 4> mtx; }; diff --git a/ZAPD/ZPath.cpp b/ZAPD/ZPath.cpp index 63970ae4f..39e06fb0b 100644 --- a/ZAPD/ZPath.cpp +++ b/ZAPD/ZPath.cpp @@ -10,6 +10,7 @@ REGISTER_ZFILENODE(Path, ZPath); ZPath::ZPath(ZFile* nParent) : ZResource(nParent) { numPaths = 1; + RegisterOptionalAttribute("NumPaths", "1"); } void ZPath::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, @@ -25,16 +26,13 @@ void ZPath::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); - const char* numPathsXml = reader->Attribute("NumPaths"); - if (numPathsXml != nullptr) - { - numPaths = StringHelper::StrToL(std::string(numPathsXml)); - if (numPaths < 1) - throw std::runtime_error( - StringHelper::Sprintf("ZPath::ParseXML: Fatal error in '%s'.\n" - "\t Invalid value for attribute 'NumPaths': '%i'\n", - name.c_str(), numPaths)); - } + numPaths = StringHelper::StrToL(registeredAttributes.at("NumPaths").value); + + if (numPaths < 1) + throw std::runtime_error( + StringHelper::Sprintf("ZPath::ParseXML: Fatal error in '%s'.\n" + "\t Invalid value for attribute 'NumPaths': '%i'\n", + name.c_str(), numPaths)); } void ZPath::ParseRawData() @@ -72,7 +70,7 @@ std::string ZPath::GetBodySourceCode() const size_t index = 0; for (const auto& entry : pathways) { - declaration += entry.GetBodySourceCode(); + declaration += StringHelper::Sprintf("\t{ %s },", entry.GetBodySourceCode().c_str()); if (index < pathways.size() - 1) declaration += "\n"; @@ -102,6 +100,11 @@ std::string ZPath::GetSourceTypeName() const return "Path"; } +ZResourceType ZPath::GetResourceType() const +{ + return ZResourceType::Path; +} + size_t ZPath::GetRawDataSize() const { return pathways.size() * pathways.at(0).GetRawDataSize(); @@ -183,13 +186,23 @@ std::string PathwayEntry::GetBodySourceCode() const if (Globals::Instance->game == ZGame::MM_RETAIL) declaration += - StringHelper::Sprintf(" { %i, %i, %i, %s },", numPoints, unk1, unk2, listName.c_str()); + StringHelper::Sprintf("%i, %i, %i, %s", numPoints, unk1, unk2, listName.c_str()); else - declaration += StringHelper::Sprintf(" { %i, %s },", numPoints, listName.c_str()); + declaration += StringHelper::Sprintf("%i, %s", numPoints, listName.c_str()); return declaration; } +std::string PathwayEntry::GetSourceTypeName() const +{ + return "Path"; +} + +ZResourceType PathwayEntry::GetResourceType() const +{ + return ZResourceType::Path; +} + size_t PathwayEntry::GetRawDataSize() const { return 0x08; diff --git a/ZAPD/ZPath.h b/ZAPD/ZPath.h index d02f16383..55fc17dc2 100644 --- a/ZAPD/ZPath.h +++ b/ZAPD/ZPath.h @@ -12,7 +12,9 @@ class PathwayEntry : public ZResource void DeclareReferences(const std::string& prefix) override; std::string GetBodySourceCode() const; - void DeclareVar(); + + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; size_t GetRawDataSize() const; segptr_t GetListAddress() const; @@ -41,6 +43,7 @@ class ZPath : public ZResource std::string GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; size_t GetRawDataSize() const override; void SetNumPaths(uint32_t nNumPaths); diff --git a/ZAPD/ZResource.cpp b/ZAPD/ZResource.cpp index 93d48628c..55e142faa 100644 --- a/ZAPD/ZResource.cpp +++ b/ZAPD/ZResource.cpp @@ -3,6 +3,7 @@ #include #include #include "StringHelper.h" +#include "ZFile.h" ZResource::ZResource(ZFile* nParent) { @@ -11,9 +12,13 @@ ZResource::ZResource(ZFile* nParent) name = ""; outName = ""; sourceOutput = ""; - rawData = std::vector(); rawDataIndex = 0; outputDeclaration = true; + + RegisterRequiredAttribute("Name"); + RegisterOptionalAttribute("OutName"); + RegisterOptionalAttribute("Offset"); + RegisterOptionalAttribute("Custom"); } void ZResource::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, @@ -42,41 +47,72 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) { if (reader != nullptr) { - if (reader->Attribute("Name") != nullptr) + // If it is an inner node, then 'Name' isn't required + if (isInner) { - name = reader->Attribute("Name"); - static std::regex r("[a-zA-Z_]+[a-zA-Z0-9_]*", - std::regex::icase | std::regex::optimize); + registeredAttributes.at("Name").isRequired = false; + } - if (!std::regex_match(name, r)) + auto attrs = reader->FirstAttribute(); + while (attrs != nullptr) + { + std::string attrName = attrs->Name(); + bool attrDeclared = false; + + if (registeredAttributes.find(attrName) != registeredAttributes.end()) { - throw std::domain_error( - StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n\t Resource " - "with invalid 'Name' attribute.\n", - name.c_str())); + registeredAttributes[attrName].value = attrs->Value(); + registeredAttributes[attrName].wasSet = true; + attrDeclared = true; } - } - else - name = ""; - if (reader->Attribute("OutName") != nullptr) - outName = reader->Attribute("OutName"); - else - outName = name; - - if (reader->Attribute("Custom") != nullptr) - isCustomAsset = true; - else - isCustomAsset = false; + if (!attrDeclared) + fprintf(stderr, + "ZResource::ParseXML: Warning while parsing '%s'.\n" + "\t Unexpected '%s' attribute in resource '%s'.\n", + parent->GetName().c_str(), attrName.c_str(), reader->Name()); + attrs = attrs->Next(); + } if (!canHaveInner && !reader->NoChildren()) { throw std::runtime_error( - StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n\t Resource '%s' " - "with inner element/child detected.\n", + StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n" + "\t Resource '%s' with inner element/child detected.\n", name.c_str(), reader->Name())); } + for (const auto& attr : registeredAttributes) + { + if (attr.second.isRequired && attr.second.value == "") + throw std::runtime_error(StringHelper::Sprintf( + "ZResource::ParseXML: Fatal error while parsing '%s'.\n" + "\t Missing required attribute '%s' in resource '%s'.\n" + "\t Aborting...", + parent->GetName().c_str(), attr.first.c_str(), reader->Name())); + } + + name = registeredAttributes.at("Name").value; + + static std::regex r("[a-zA-Z_]+[a-zA-Z0-9_]*", std::regex::icase | std::regex::optimize); + + if (!isInner || (isInner && name != "")) + { + if (!std::regex_match(name, r)) + { + throw std::domain_error( + StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n" + "\t Resource with invalid 'Name' attribute.\n", + name.c_str())); + } + } + + outName = registeredAttributes.at("OutName").value; + if (outName == "") + outName = name; + + isCustomAsset = registeredAttributes["Custom"].wasSet; + declaredInXml = true; } } @@ -89,7 +125,7 @@ void ZResource::PreGenSourceFiles() { } -std::string ZResource::GetName() const +const std::string& ZResource::GetName() const { return name; } @@ -99,14 +135,14 @@ const std::string& ZResource::GetOutName() const return outName; } -void ZResource::SetOutName(std::string nName) +void ZResource::SetOutName(const std::string& nName) { outName = nName; } -void ZResource::SetName(std::string nName) +void ZResource::SetName(const std::string& nName) { - name = std::move(nName); + name = nName; } bool ZResource::IsExternalResource() const @@ -144,14 +180,14 @@ uint32_t ZResource::GetRawDataIndex() const return rawDataIndex; } -size_t ZResource::GetRawDataSize() const +void ZResource::SetRawDataIndex(uint32_t value) { - return rawData.size(); + rawDataIndex = value; } -void ZResource::SetRawDataIndex(uint32_t value) +std::string ZResource::GetBodySourceCode() const { - rawDataIndex = value; + return "ERROR"; } std::string ZResource::GetSourceOutputCode(const std::string& prefix) @@ -191,6 +227,27 @@ void ZResource::CalcHash() hash = 0; } +void ZResource::SetInnerNode(bool inner) +{ + isInner = inner; +} + +void ZResource::RegisterRequiredAttribute(const std::string& attr) +{ + ResourceAttribute resAtrr; + resAtrr.key = attr; + resAtrr.isRequired = true; + registeredAttributes[attr] = resAtrr; +} + +void ZResource::RegisterOptionalAttribute(const std::string& attr, const std::string& defaultValue) +{ + ResourceAttribute resAtrr; + resAtrr.key = attr; + resAtrr.value = defaultValue; + registeredAttributes[attr] = resAtrr; +} + uint32_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress) { uint32_t currentPtr = GETSEGOFFSET(segmentedAddress); @@ -200,7 +257,3 @@ uint32_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress) return currentPtr; } - -ZResource::~ZResource() -{ -} \ No newline at end of file diff --git a/ZAPD/ZResource.h b/ZAPD/ZResource.h index 99d3dfff0..24f1f561f 100644 --- a/ZAPD/ZResource.h +++ b/ZAPD/ZResource.h @@ -29,6 +29,7 @@ enum class ZResourceType { Error, Animation, + Array, Background, Blob, CollisionHeader, @@ -38,6 +39,7 @@ enum class ZResourceType Mtx, Path, Room, + RoomCommand, Scalar, Skeleton, String, @@ -47,6 +49,15 @@ enum class ZResourceType Vertex, }; +class ResourceAttribute +{ +public: + std::string key = ""; + std::string value = ""; + bool isRequired = false; + bool wasSet = false; +}; + class ZResource { public: @@ -55,7 +66,7 @@ class ZResource uint32_t hash = 0; ZResource(ZFile* nParent); - virtual ~ZResource(); + virtual ~ZResource() = default; // Parsing from File virtual void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, @@ -66,6 +77,7 @@ class ZResource virtual void ParseXML(tinyxml2::XMLElement* reader); virtual void ParseRawData(); virtual void DeclareReferences(const std::string& prefix); + virtual std::string GetBodySourceCode() const; virtual std::string GetSourceOutputCode(const std::string& prefix); virtual std::string GetSourceOutputHeader(const std::string& prefix); @@ -78,19 +90,20 @@ class ZResource virtual bool IsExternalResource() const; virtual bool DoesSupportArray() const; // Can this type be wrapped in an node? virtual std::string GetSourceTypeName() const; - virtual ZResourceType GetResourceType() const; + virtual ZResourceType GetResourceType() const = 0; virtual std::string GetExternalExtension() const; // Getters/Setters - std::string GetName() const; - void SetName(std::string nName); + const std::string& GetName() const; + void SetName(const std::string& nName); const std::string& GetOutName() const; - void SetOutName(std::string nName); + void SetOutName(const std::string& nName); virtual uint32_t GetRawDataIndex() const; virtual void SetRawDataIndex(uint32_t value); - virtual size_t GetRawDataSize() const; + virtual size_t GetRawDataSize() const = 0; virtual const std::vector& GetRawData() const; virtual void SetRawData(const std::vector& nData); + void SetInnerNode(bool inner); bool WasDeclaredInXml() const; protected: @@ -99,10 +112,24 @@ class ZResource std::vector rawData; uint32_t rawDataIndex; std::string sourceOutput; + bool isInner = false; // Is this resource an inner node of another resource? inside of bool canHaveInner = false; // Can this type have an inner node? bool isCustomAsset; // If set to true, create a reference for the asset in the file, but don't // actually try to extract it from the file bool declaredInXml = false; + + // Reading from this XMLs attributes should be performed in the overrided `ParseXML` method. + std::map registeredAttributes; + + // XML attributes registers. + // Registering XML attributes should be done in constructors. + + // The resource needs this attribute. If it is not provided, then the program will throw an + // exception. + void RegisterRequiredAttribute(const std::string& attr); + // Optional attribute. The resource has to do manual checks and manual warnings. It may or may + // not have a value. + void RegisterOptionalAttribute(const std::string& attr, const std::string& defaultValue = ""); }; uint32_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress); diff --git a/ZAPD/ZRoom/ZRoom.cpp b/ZAPD/ZRoom/ZRoom.cpp index 7e4a79a5f..936b01447 100644 --- a/ZAPD/ZRoom/ZRoom.cpp +++ b/ZAPD/ZRoom/ZRoom.cpp @@ -51,6 +51,7 @@ ZRoom::ZRoom(ZFile* nParent) : ZResource(nParent) { roomCount = -1; canHaveInner = true; + RegisterOptionalAttribute("HackMode"); } ZRoom::~ZRoom() @@ -64,7 +65,6 @@ void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vectorscene = nScene; scene = Globals::Instance->lastScene; if (std::string(reader->Name()) == "Scene") @@ -81,7 +81,7 @@ void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vectorFirstChildElement(); child != NULL; + for (XMLElement* child = reader->FirstChildElement(); child != nullptr; child = child->NextSiblingElement()) { std::string childName = @@ -103,6 +103,7 @@ void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vectorSetInnerNode(true); dList->GetSourceOutputCode(name); delete dList; @@ -112,8 +113,8 @@ void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vectorAttribute("Offset"); int32_t address = strtol(StringHelper::Split(addressStr, "0x")[1].c_str(), NULL, 16); - // ZCutscene* cutscene = new ZCutscene(rawData, address, 9999, parent); ZCutscene* cutscene = new ZCutscene(parent); + cutscene->SetInnerNode(true); cutscene->ExtractFromXML(child, rawData, address); cutscene->GetSourceOutputCode(name); @@ -142,6 +143,7 @@ void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vectorSetInnerNode(true); pathway->SetRawDataIndex(address); pathway->ParseRawData(); pathway->DeclareReferences(name); @@ -288,11 +290,10 @@ void ZRoom::ParseCommands(std::vector& commandList, CommandSet co cmd->ExtractCommandFromRoom(this, rawDataIndex); cmd->DeclareReferences(GetName()); - auto end = std::chrono::steady_clock::now(); - auto diff = std::chrono::duration_cast(end - start).count(); - if (Globals::Instance->profile) { + auto end = std::chrono::steady_clock::now(); + auto diff = std::chrono::duration_cast(end - start).count(); if (diff > 50) printf("OP: %s, TIME: %lims\n", cmd->GetCommandCName().c_str(), diff); } diff --git a/ZAPD/ZRoom/ZRoom.h b/ZAPD/ZRoom/ZRoom.h index 3ca3fc99d..43f12ed7f 100644 --- a/ZAPD/ZRoom/ZRoom.h +++ b/ZAPD/ZRoom/ZRoom.h @@ -46,5 +46,5 @@ class ZRoom : public ZResource size_t GetRawDataSize() const override; ZResourceType GetResourceType() const override; - virtual void PreGenSourceFiles() override; + void PreGenSourceFiles() override; }; diff --git a/ZAPD/ZRoom/ZRoomCommand.cpp b/ZAPD/ZRoom/ZRoomCommand.cpp index e600ca4c7..6c45c32c6 100644 --- a/ZAPD/ZRoom/ZRoomCommand.cpp +++ b/ZAPD/ZRoom/ZRoomCommand.cpp @@ -40,9 +40,14 @@ std::string ZRoomCommand::GetCommandCName() const return "SCmdBase"; } -RoomCommand ZRoomCommand::GetRoomCommand() const +ZResourceType ZRoomCommand::GetResourceType() const { - return RoomCommand::Error; + return ZResourceType::RoomCommand; +} + +size_t ZRoomCommand::GetRawDataSize() const +{ + return 0x08; } std::string ZRoomCommand::GetCommandHex() const diff --git a/ZAPD/ZRoom/ZRoomCommand.h b/ZAPD/ZRoom/ZRoomCommand.h index b89c9188f..e428704fd 100644 --- a/ZAPD/ZRoom/ZRoomCommand.h +++ b/ZAPD/ZRoom/ZRoomCommand.h @@ -69,9 +69,11 @@ class ZRoomCommand : public ZResource virtual std::string GetBodySourceCode() const = 0; + ZResourceType GetResourceType() const override; + // Getters/Setters virtual RoomCommand GetRoomCommand() const = 0; - // virtual size_t GetRawDataSize() const; + size_t GetRawDataSize() const override; virtual std::string GetCommandCName() const; virtual std::string GetCommandHex() const; diff --git a/ZAPD/ZRoot.h b/ZAPD/ZRoot.h deleted file mode 100644 index 6f70f09be..000000000 --- a/ZAPD/ZRoot.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/ZAPD/ZScalar.cpp b/ZAPD/ZScalar.cpp index d68ab83e2..797ac07a1 100644 --- a/ZAPD/ZScalar.cpp +++ b/ZAPD/ZScalar.cpp @@ -11,6 +11,7 @@ ZScalar::ZScalar(ZFile* nParent) : ZResource(nParent) { memset(&scalarData, 0, sizeof(ZScalarData)); scalarType = ZScalarType::ZSCALAR_NONE; + RegisterRequiredAttribute("Type"); } ZScalar::ZScalar(const ZScalarType scalarType, ZFile* nParent) : ZScalar(nParent) @@ -18,18 +19,11 @@ ZScalar::ZScalar(const ZScalarType scalarType, ZFile* nParent) : ZScalar(nParent this->scalarType = scalarType; } -void ZScalar::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex); -} - void ZScalar::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); - std::string type = reader->Attribute("Type"); - scalarType = ZScalar::MapOutputTypeToScalarType(type); + scalarType = ZScalar::MapOutputTypeToScalarType(registeredAttributes.at("Type").value); } ZScalarType ZScalar::MapOutputTypeToScalarType(const std::string& type) @@ -142,43 +136,38 @@ size_t ZScalar::GetRawDataSize() const } void ZScalar::ParseRawData() -{ - ZScalar::ParseRawData(rawData, rawDataIndex); -} - -void ZScalar::ParseRawData(const std::vector& data, const uint32_t offset) { switch (scalarType) { case ZScalarType::ZSCALAR_S8: - scalarData.s8 = BitConverter::ToInt8BE(data, offset); + scalarData.s8 = BitConverter::ToInt8BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_U8: - scalarData.u8 = BitConverter::ToUInt8BE(data, offset); + scalarData.u8 = BitConverter::ToUInt8BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_S16: - scalarData.s16 = BitConverter::ToInt16BE(data, offset); + scalarData.s16 = BitConverter::ToInt16BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_U16: - scalarData.u16 = BitConverter::ToUInt16BE(data, offset); + scalarData.u16 = BitConverter::ToUInt16BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_S32: - scalarData.s32 = BitConverter::ToInt32BE(data, offset); + scalarData.s32 = BitConverter::ToInt32BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_U32: - scalarData.u32 = BitConverter::ToUInt32BE(data, offset); + scalarData.u32 = BitConverter::ToUInt32BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_S64: - scalarData.s64 = BitConverter::ToInt64BE(data, offset); + scalarData.s64 = BitConverter::ToInt64BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_U64: - scalarData.u64 = BitConverter::ToUInt64BE(data, offset); + scalarData.u64 = BitConverter::ToUInt64BE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_F32: - scalarData.f32 = BitConverter::ToFloatBE(data, offset); + scalarData.f32 = BitConverter::ToFloatBE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_F64: - scalarData.f64 = BitConverter::ToDoubleBE(data, offset); + scalarData.f64 = BitConverter::ToDoubleBE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_NONE: fprintf(stderr, "Warning in ZScalar: Invalid type. %d %s %d\n", (int32_t)scalarType, @@ -217,7 +206,7 @@ std::string ZScalar::GetBodySourceCode() const case ZScalarType::ZSCALAR_F64: return StringHelper::Sprintf("%lf", scalarData.f64); default: - return ""; + return "SCALAR_ERROR"; } } diff --git a/ZAPD/ZScalar.h b/ZAPD/ZScalar.h index b04aef4f4..a46c3a16c 100644 --- a/ZAPD/ZScalar.h +++ b/ZAPD/ZScalar.h @@ -40,27 +40,25 @@ class ZScalar : public ZResource friend class ZVector; public: - ZScalarData scalarData; - ZScalarType scalarType; - ZScalar(ZFile* nParent); ZScalar(const ZScalarType scalarType, ZFile* nParent); + void ParseRawData() override; void ParseXML(tinyxml2::XMLElement* reader) override; - std::string GetSourceTypeName() const override; - std::string GetBodySourceCode() const; + std::string GetBodySourceCode() const override; std::string GetSourceOutputCode(const std::string& prefix) override; - size_t GetRawDataSize() const override; - ZResourceType GetResourceType() const override; + bool DoesSupportArray() const override; - void ParseRawData() override; + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; - void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) override; static size_t MapTypeToSize(const ZScalarType scalarType); static ZScalarType MapOutputTypeToScalarType(const std::string& type); static std::string MapScalarTypeToOutputType(const ZScalarType scalarType); protected: - void ParseRawData(const std::vector& data, const uint32_t offset); -}; \ No newline at end of file + ZScalarData scalarData; + ZScalarType scalarType; +}; diff --git a/ZAPD/ZSkeleton.cpp b/ZAPD/ZSkeleton.cpp index c59fc22aa..cb2d2a96d 100644 --- a/ZAPD/ZSkeleton.cpp +++ b/ZAPD/ZSkeleton.cpp @@ -10,11 +10,14 @@ ZSkeleton::ZSkeleton(ZFile* nParent) : ZResource(nParent) type = ZSkeletonType::Normal; limbType = ZLimbType::Standard; dListCount = 0; + + RegisterRequiredAttribute("Type"); + RegisterRequiredAttribute("LimbType"); } ZSkeleton::ZSkeleton(ZSkeletonType nType, ZLimbType nLimbType, const std::string& prefix, const std::vector& nRawData, uint32_t nRawDataIndex, ZFile* nParent) - : ZResource(nParent) + : ZSkeleton(nParent) { rawData.assign(nRawData.begin(), nRawData.end()); rawDataIndex = nRawDataIndex; @@ -51,64 +54,40 @@ void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); - const char* skelTypeXml = reader->Attribute("Type"); + std::string skelTypeXml = registeredAttributes.at("Type").value; - if (skelTypeXml == nullptr) + if (skelTypeXml == "Flex") + type = ZSkeletonType::Flex; + else if (skelTypeXml == "Curve") + type = ZSkeletonType::Curve; + else if (skelTypeXml != "Normal") { fprintf(stderr, - "ZSkeleton::ParseXML: Warning in '%s'.\n\t Type not found found. Defaulting to " - "'Normal'.\n", - name.c_str()); + "ZSkeleton::ParseXML: Warning in '%s'.\n" + "\t Invalid Type found: '%s'.\n" + "\t Defaulting to 'Normal'.\n", + name.c_str(), skelTypeXml.c_str()); type = ZSkeletonType::Normal; } - else - { - std::string skelTypeStr(skelTypeXml); - - if (skelTypeStr == "Flex") - type = ZSkeletonType::Flex; - else if (skelTypeStr == "Curve") - type = ZSkeletonType::Curve; - else if (skelTypeStr != "Normal") - { - fprintf(stderr, - "ZSkeleton::ParseXML: Warning in '%s'.\n\t Invalid Type found: '%s'. " - "Defaulting to 'Normal'.\n", - name.c_str(), skelTypeXml); - type = ZSkeletonType::Normal; - } - } - const char* limbTypeXml = reader->Attribute("LimbType"); + std::string limbTypeXml = registeredAttributes.at("LimbType").value; - if (limbTypeXml == nullptr) - { - fprintf(stderr, - "ZSkeleton::ParseXML: Warning in '%s'.\n\t LimbType not found found. Defaulting to " - "'Standard'.\n", - name.c_str()); + if (limbTypeXml == "Standard") limbType = ZLimbType::Standard; - } + else if (limbTypeXml == "LOD") + limbType = ZLimbType::LOD; + else if (limbTypeXml == "Skin") + limbType = ZLimbType::Skin; + else if (limbTypeXml == "Curve") + limbType = ZLimbType::Curve; else { - std::string limbTypeStr(limbTypeXml); - - if (limbTypeStr == "Standard") - limbType = ZLimbType::Standard; - else if (limbTypeStr == "LOD") - limbType = ZLimbType::LOD; - else if (limbTypeStr == "Skin") - limbType = ZLimbType::Skin; - else if (limbTypeStr == "Curve") - limbType = ZLimbType::Curve; - else - { - fprintf(stderr, - "ZSkeleton::ParseXML: Warning in '%s'.\n\t Invalid LimbType found: '%s'. " - "Defaulting to 'Standard'.\n", - name.c_str(), limbTypeXml); - limbType = ZLimbType::Standard; - } + fprintf(stderr, + "ZSkeleton::ParseXML: Warning in '%s'.\n" + "\t Invalid LimbType found: '%s'.\n" + "\t Defaulting to 'Standard'.\n", + name.c_str(), limbTypeXml.c_str()); + limbType = ZLimbType::Standard; } } diff --git a/ZAPD/ZSkeleton.h b/ZAPD/ZSkeleton.h index 8ceb23b63..6841b828b 100644 --- a/ZAPD/ZSkeleton.h +++ b/ZAPD/ZSkeleton.h @@ -28,18 +28,22 @@ class ZSkeleton : public ZResource ZSkeleton(ZSkeletonType nType, ZLimbType nLimbType, const std::string& prefix, const std::vector& nRawData, uint32_t nRawDataIndex, ZFile* nParent); ~ZSkeleton(); - void ParseXML(tinyxml2::XMLElement* reader) override; - void ParseRawData() override; + void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, const uint32_t nRawDataIndex) override; + + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; + std::string GetSourceOutputCode(const std::string& prefix) override; void GenerateHLIntermediette(HLFileIntermediette& hlFile) override; size_t GetRawDataSize() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; segptr_t GetAddress(); uint8_t GetLimbCount(); + +protected: }; diff --git a/ZAPD/ZSymbol.cpp b/ZAPD/ZSymbol.cpp index 56015c040..3ba69db68 100644 --- a/ZAPD/ZSymbol.cpp +++ b/ZAPD/ZSymbol.cpp @@ -6,6 +6,9 @@ REGISTER_ZFILENODE(Symbol, ZSymbol); ZSymbol::ZSymbol(ZFile* nParent) : ZResource(nParent) { + RegisterOptionalAttribute("Type"); + RegisterOptionalAttribute("TypeSize"); + RegisterOptionalAttribute("Count"); } void ZSymbol::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, @@ -18,42 +21,44 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); - const char* typeXml = reader->Attribute("Type"); + std::string typeXml = registeredAttributes.at("Type").value; - if (typeXml == nullptr) + if (typeXml == "") { fprintf(stderr, - "ZSymbol::ParseXML: Warning in '%s'.\n\t Missing 'Type' attribute in xml. " - "Defaulting to 'void*'.\n", + "ZSymbol::ParseXML: Warning in '%s'.\n" + "\t Missing 'Type' attribute in xml.\n" + "\t Defaulting to 'void*'.\n", name.c_str()); type = "void*"; } else { - type = std::string(typeXml); + type = typeXml; } - const char* typeSizeXml = reader->Attribute("TypeSize"); - if (typeSizeXml == nullptr) + std::string typeSizeXml = registeredAttributes.at("TypeSize").value; + if (typeSizeXml == "") { fprintf(stderr, - "ZSymbol::ParseXML: Warning in '%s'.\n\t Missing 'TypeSize' attribute in xml. " - "Defaulting to '4'.\n", + "ZSymbol::ParseXML: Warning in '%s'.\n" + "\t Missing 'TypeSize' attribute in xml.\n" + "\t Defaulting to '4'.\n", name.c_str()); typeSize = 4; // Size of a word. } else { - typeSize = std::strtoul(typeSizeXml, nullptr, 0); + typeSize = StringHelper::StrToL(typeSizeXml, 0); } - const char* countXml = reader->Attribute("Count"); - if (countXml != nullptr) + if (registeredAttributes.at("Count").wasSet) { isArray = true; - if (!std::string(countXml).empty()) - count = std::strtoul(countXml, nullptr, 0); + std::string countXml = registeredAttributes.at("Count").value; + if (countXml != "") + count = StringHelper::StrToL(countXml, 0); } } diff --git a/ZAPD/ZTexture.cpp b/ZAPD/ZTexture.cpp index f1629de44..b47fd23bb 100644 --- a/ZAPD/ZTexture.cpp +++ b/ZAPD/ZTexture.cpp @@ -14,10 +14,15 @@ ZTexture::ZTexture(ZFile* nParent) : ZResource(nParent) { width = 0; height = 0; + + RegisterRequiredAttribute("Width"); + RegisterRequiredAttribute("Height"); + RegisterRequiredAttribute("Format"); + RegisterOptionalAttribute("TlutOffset"); } void ZTexture::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) + uint32_t nRawDataIndex) { ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex); @@ -65,41 +70,41 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); - if (reader->Attribute("Width") != nullptr) - { - width = atoi(reader->Attribute("Width")); - } - else - { - throw std::runtime_error("Width == nullptr for asset " + - std::string(reader->Attribute("Name"))); - } + std::string widthXml = registeredAttributes.at("Width").value; + std::string heightXml = registeredAttributes.at("Height").value; - if (reader->Attribute("Height") != nullptr) + if (!StringHelper::HasOnlyDigits(widthXml)) { - height = atoi(reader->Attribute("Height")); + throw std::runtime_error(StringHelper::Sprintf( + "ZTexture::ParseXML: Error in %s\n" + "\t Value of 'Width' attribute has non-decimal digits: '%s'.\n", + name.c_str(), widthXml.c_str())); } - else + if (!StringHelper::HasOnlyDigits(heightXml)) { - throw std::runtime_error("Height == nullptr for asset " + - std::string(reader->Attribute("Name"))); + throw std::runtime_error(StringHelper::Sprintf( + "ZTexture::ParseXML: Error in %s\n" + "\t Value of 'Height' attribute has non-decimal digits: '%s'.\n", + name.c_str(), heightXml.c_str())); } - std::string formatStr = reader->Attribute("Format"); + width = StringHelper::StrToL(widthXml); + height = StringHelper::StrToL(heightXml); + std::string formatStr = registeredAttributes.at("Format").value; format = GetTextureTypeFromString(formatStr); if (format == TextureType::Error) throw std::runtime_error("Format " + formatStr + " is not supported!"); - auto tlutOffsetXml = reader->Attribute("TlutOffset"); - if (tlutOffsetXml != nullptr) + const auto& tlutOffsetAttr = registeredAttributes.at("TlutOffset"); + if (tlutOffsetAttr.wasSet) { switch (format) { case TextureType::Palette4bpp: case TextureType::Palette8bpp: - tlutOffset = StringHelper::StrToL(std::string(tlutOffsetXml), 16); + tlutOffset = StringHelper::StrToL(tlutOffsetAttr.value, 16); break; default: diff --git a/ZAPD/ZTexture.h b/ZAPD/ZTexture.h index 06424d6fe..c17ed0b5b 100644 --- a/ZAPD/ZTexture.h +++ b/ZAPD/ZTexture.h @@ -59,11 +59,12 @@ class ZTexture : public ZResource bool isPalette = false; void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) override; + uint32_t nRawDataIndex) override; void FromBinary(const std::vector& nRawData, uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight, TextureType nType, bool nIsPalette); void FromPNG(const fs::path& pngFilePath, TextureType texType); void FromHLTexture(HLTexture* hlTex); + static TextureType GetTextureTypeFromString(std::string str); void ParseXML(tinyxml2::XMLElement* reader) override; diff --git a/ZAPD/ZVector.cpp b/ZAPD/ZVector.cpp index 51c84528b..35845800e 100644 --- a/ZAPD/ZVector.cpp +++ b/ZAPD/ZVector.cpp @@ -12,23 +12,17 @@ ZVector::ZVector(ZFile* nParent) : ZResource(nParent) { scalarType = ZScalarType::ZSCALAR_NONE; dimensions = 0; -} - -void ZVector::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex); + RegisterRequiredAttribute("Type"); + RegisterRequiredAttribute("Dimensions"); } void ZVector::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); - std::string type = reader->Attribute("Type"); - this->scalarType = ZScalar::MapOutputTypeToScalarType(type); + this->scalarType = ZScalar::MapOutputTypeToScalarType(registeredAttributes.at("Type").value); - std::string dimensions = reader->Attribute("Dimensions"); - this->dimensions = strtol(dimensions.c_str(), NULL, 16); + this->dimensions = StringHelper::StrToL(registeredAttributes.at("Dimensions").value, 16); } void ZVector::ParseRawData() diff --git a/ZAPD/ZVector.h b/ZAPD/ZVector.h index e9921b135..d700d4396 100644 --- a/ZAPD/ZVector.h +++ b/ZAPD/ZVector.h @@ -13,20 +13,19 @@ class ZVector : public ZResource ZVector(ZFile* nParent); void ParseXML(tinyxml2::XMLElement* reader) override; - std::string GetSourceTypeName() const override; - std::string GetBodySourceCode() const; - std::string GetSourceOutputCode(const std::string& prefix) override; void ParseRawData() override; - size_t GetRawDataSize() const override; + + std::string GetBodySourceCode() const override; + std::string GetSourceOutputCode(const std::string& prefix) override; + bool DoesSupportArray() const override; + std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; + size_t GetRawDataSize() const override; void SetScalarType(ZScalarType type); void SetDimensions(uint32_t dim); - void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) override; - protected: std::vector scalars; ZScalarType scalarType; diff --git a/ZAPD/ZVtx.cpp b/ZAPD/ZVtx.cpp index 96e6552d0..d56f4faf5 100644 --- a/ZAPD/ZVtx.cpp +++ b/ZAPD/ZVtx.cpp @@ -39,11 +39,6 @@ std::string ZVtx::GetBodySourceCode() const a); } -std::string ZVtx::GetSourceTypeName() const -{ - return "Vtx"; -} - std::string ZVtx::GetSourceOutputCode(const std::string& prefix) { std::string output = GetBodySourceCode(); @@ -79,13 +74,12 @@ bool ZVtx::IsExternalResource() const return true; } -std::string ZVtx::GetExternalExtension() const +std::string ZVtx::GetSourceTypeName() const { - return "vtx"; + return "Vtx"; } -void ZVtx::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) +std::string ZVtx::GetExternalExtension() const { - ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex); + return "vtx"; } diff --git a/ZAPD/ZVtx.h b/ZAPD/ZVtx.h index 910010590..feed30766 100644 --- a/ZAPD/ZVtx.h +++ b/ZAPD/ZVtx.h @@ -17,18 +17,15 @@ class ZVtx : public ZResource ZVtx(ZFile* nParent); - void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector& nRawData, - const uint32_t nRawDataIndex) override; - void ParseRawData() override; - std::string GetBodySourceCode() const; + std::string GetBodySourceCode() const override; std::string GetSourceOutputCode(const std::string& prefix) override; bool IsExternalResource() const override; bool DoesSupportArray() const override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; - virtual std::string GetExternalExtension() const override; + std::string GetExternalExtension() const override; size_t GetRawDataSize() const override; diff --git a/copycheck.py b/copycheck.py old mode 100644 new mode 100755