summaryrefslogtreecommitdiff
path: root/ZAPD/ZSkeleton.cpp
diff options
context:
space:
mode:
authorlouist103 <35883445+louist103@users.noreply.github.com>2023-05-07 19:58:50 -0400
committerGitHub <noreply@github.com>2023-05-07 19:58:50 -0400
commit885c8474881af4f92a822c7afba90a7ecc02170c (patch)
tree617ee076cb91ecccd193dcacafb61600927954c2 /ZAPD/ZSkeleton.cpp
parentc99b3ccd9d9926e8d4d11c76d53c87f8023e1d70 (diff)
ZAPD Update (#2851)
* git subrepo clone --force --branch=rebase2 C:/ZeldaStuff/ZAPDTR ZAPDTR/ subrepo: subdir: "ZAPDTR" merged: "6aa54a551" upstream: origin: "C:/ZeldaStuff/ZAPDTR" branch: "rebase2" commit: "6aa54a551" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * git subrepo clone --force --branch=rebase2 C:/ZeldaStuff/ZAPDTR ZAPDTR/ subrepo: subdir: "ZAPDTR" merged: "88b012240" upstream: origin: "C:/ZeldaStuff/ZAPDTR" branch: "rebase2" commit: "88b012240" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Update (its broken) * fix the enum * git subrepo push --remote=C:/ZeldaStuff/ZAPDTR/ ZAPDTR subrepo: subdir: "ZAPDTR" merged: "b7b6e1c82" upstream: origin: "C:/ZeldaStuff/ZAPDTR/" branch: "rebase2" commit: "b7b6e1c82" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * New names for LUS actions * git subrepo push --remote=C:/ZeldaStuff/ZAPDTR/ ZAPDTR subrepo: subdir: "ZAPDTR" merged: "c5cfebeee" upstream: origin: "C:/ZeldaStuff/ZAPDTR/" branch: "rebase2" commit: "c5cfebeee" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * git subrepo clone (merge) --force --branch=rebase2 C:/ZeldaStuff/ZAPDTR ZAPDTR/ subrepo: subdir: "ZAPDTR" merged: "d5f4769b8" upstream: origin: "C:/ZeldaStuff/ZAPDTR" branch: "rebase2" commit: "d5f4769b8" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Fix missing commands in the exporter. * Cleanups. * git subrepo pull --force --remote=https://github.com/harbourmasters/ZAPDTR --branch=master ZAPDTR subrepo: subdir: "ZAPDTR" merged: "d4c35b90a" upstream: origin: "https://github.com/harbourmasters/ZAPDTR" branch: "master" commit: "d4c35b90a" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Add unordered_map include to fix MacOS * fix string_view * Update Main.cpp * fix string view * So close I can almost taste it * So close * Fix missed git marker. * Fix surface types and * Update ZFile.cpp * Delete Jenkinsfile --------- Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com>
Diffstat (limited to 'ZAPD/ZSkeleton.cpp')
-rw-r--r--ZAPD/ZSkeleton.cpp223
1 files changed, 206 insertions, 17 deletions
diff --git a/ZAPD/ZSkeleton.cpp b/ZAPD/ZSkeleton.cpp
index bff4b82..a071209 100644
--- a/ZAPD/ZSkeleton.cpp
+++ b/ZAPD/ZSkeleton.cpp
@@ -10,10 +10,15 @@
REGISTER_ZFILENODE(Skeleton, ZSkeleton);
REGISTER_ZFILENODE(LimbTable, ZLimbTable);
-ZSkeleton::ZSkeleton(ZFile* nParent) : ZResource(nParent), limbsTable(nParent)
+ZSkeleton::ZSkeleton(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("Type");
RegisterRequiredAttribute("LimbType");
+ genOTRDef = true;
+
+ RegisterOptionalAttribute("EnumName");
+ RegisterOptionalAttribute("LimbNone");
+ RegisterOptionalAttribute("LimbMax");
genOTRDef = true;
}
@@ -44,6 +49,41 @@ void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader)
limbTypeXml.c_str()),
"Defaulting to 'Standard'.");
}
+
+ enumName = registeredAttributes.at("EnumName").value;
+ limbNoneName = registeredAttributes.at("LimbNone").value;
+ limbMaxName = registeredAttributes.at("LimbMax").value;
+
+ if (enumName != "")
+ {
+ if (limbNoneName == "" || limbMaxName == "")
+ {
+ HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
+ "'EnumName' attribute was used but either 'LimbNone' or "
+ "'LimbMax' attribute is missing",
+ "");
+ }
+ }
+
+ if (limbNoneName != "")
+ {
+ if (limbMaxName == "")
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::MissingAttribute, parent, this, rawDataIndex,
+ "'LimbNone' attribute was used but 'LimbMax' attribute is missing", "");
+ }
+ }
+
+ if (limbMaxName != "")
+ {
+ if (limbNoneName == "")
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::MissingAttribute, parent, this, rawDataIndex,
+ "'LimbMax' attribute was used but 'LimbNone' attribute is missing", "");
+ }
+ }
}
void ZSkeleton::ParseRawData()
@@ -58,12 +98,6 @@ void ZSkeleton::ParseRawData()
{
dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8);
}
-
- if (limbsArrayAddress != 0 && GETSEGNUM(limbsArrayAddress) == parent->segment)
- {
- uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress);
- limbsTable.ExtractFromBinary(ptr, limbType, limbCount);
- }
}
void ZSkeleton::DeclareReferences(const std::string& prefix)
@@ -74,14 +108,33 @@ void ZSkeleton::DeclareReferences(const std::string& prefix)
ZResource::DeclareReferences(defaultPrefix);
- if (limbsArrayAddress != 0 && GETSEGNUM(limbsArrayAddress) == parent->segment)
+ if (limbsArrayAddress != SEGMENTED_NULL && GETSEGNUM(limbsArrayAddress) == parent->segment)
{
- uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress);
+ offset_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress);
+
if (!parent->HasDeclaration(ptr))
{
- limbsTable.SetName(StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str()));
- limbsTable.DeclareReferences(prefix);
- limbsTable.GetSourceOutputCode(prefix);
+ limbsTable = new ZLimbTable(parent);
+ limbsTable->ExtractFromBinary(ptr, limbType, limbCount);
+ limbsTable->SetName(StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str()));
+ parent->AddResource(limbsTable);
+ }
+ else
+ {
+ limbsTable = static_cast<ZLimbTable*>(parent->FindResource(ptr));
+ }
+
+ if (limbsTable->enumName == "")
+ {
+ limbsTable->enumName = enumName;
+ }
+ if (limbsTable->limbNoneName == "")
+ {
+ limbsTable->limbNoneName = limbNoneName;
+ }
+ if (limbsTable->limbMaxName == "")
+ {
+ limbsTable->limbMaxName = limbMaxName;
}
}
}
@@ -92,15 +145,27 @@ std::string ZSkeleton::GetBodySourceCode() const
Globals::Instance->GetSegmentedPtrName(limbsArrayAddress, parent, "", limbArrayName,
parent->workerID);
+ std::string countStr;
+ assert(limbsTable != nullptr);
+ // There are some Skeletons with the wrong limb count on them, so this check is necessary.
+ if (limbsTable->count == limbCount)
+ {
+ countStr = StringHelper::Sprintf("ARRAY_COUNT(%s)", limbArrayName.c_str());
+ }
+ else
+ {
+ countStr = StringHelper::Sprintf("%i", limbCount);
+ }
+
switch (type)
{
case ZSkeletonType::Normal:
case ZSkeletonType::Curve:
- return StringHelper::Sprintf("\n\t%s, %i\n", limbArrayName.c_str(), limbCount);
+ return StringHelper::Sprintf("\n\t%s, %s\n", limbArrayName.c_str(), countStr.c_str());
case ZSkeletonType::Flex:
- return StringHelper::Sprintf("\n\t{ %s, %i }, %i\n", limbArrayName.c_str(), limbCount,
- dListCount);
+ return StringHelper::Sprintf("\n\t{ %s, %s }, %i\n", limbArrayName.c_str(),
+ countStr.c_str(), dListCount);
}
// TODO: Throw exception?
@@ -156,6 +221,9 @@ ZLimbTable::ZLimbTable(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("LimbType");
RegisterRequiredAttribute("Count");
+ RegisterOptionalAttribute("EnumName");
+ RegisterOptionalAttribute("LimbNone");
+ RegisterOptionalAttribute("LimbMax");
}
void ZLimbTable::ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nLimbType, size_t nCount)
@@ -182,6 +250,40 @@ void ZLimbTable::ParseXML(tinyxml2::XMLElement* reader)
}
count = StringHelper::StrToL(registeredAttributes.at("Count").value);
+
+ enumName = registeredAttributes.at("EnumName").value;
+ limbNoneName = registeredAttributes.at("LimbNone").value;
+ limbMaxName = registeredAttributes.at("LimbMax").value;
+
+ if (enumName != "")
+ {
+ if (limbNoneName == "" || limbMaxName == "")
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::MissingAttribute, parent, this, rawDataIndex,
+ "'EnumName' attribute was used but 'LimbNone'/'LimbMax' attributes is missing", "");
+ }
+ }
+
+ if (limbNoneName != "")
+ {
+ if (limbMaxName == "")
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::MissingAttribute, parent, this, rawDataIndex,
+ "'LimbNone' attribute was used but 'LimbMax' attribute is missing", "");
+ }
+ }
+
+ if (limbMaxName != "")
+ {
+ if (limbNoneName == "")
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::MissingAttribute, parent, this, rawDataIndex,
+ "'LimbMax' attribute was used but 'LimbNone' attribute is missing", "");
+ }
+ }
}
void ZLimbTable::ParseRawData()
@@ -190,6 +292,8 @@ void ZLimbTable::ParseRawData()
const auto& rawData = parent->GetRawData();
uint32_t ptr = rawDataIndex;
+
+ limbsAddresses.reserve(count);
for (size_t i = 0; i < count; i++)
{
limbsAddresses.push_back(BitConverter::ToUInt32BE(rawData, ptr));
@@ -204,7 +308,7 @@ void ZLimbTable::DeclareReferences(const std::string& prefix)
varPrefix = prefix;
ZResource::DeclareReferences(varPrefix);
-
+ limbsReferences.reserve(count);
for (size_t i = 0; i < count; i++)
{
segptr_t limbAddress = limbsAddresses[i];
@@ -212,15 +316,28 @@ void ZLimbTable::DeclareReferences(const std::string& prefix)
if (limbAddress != 0 && GETSEGNUM(limbAddress) == parent->segment)
{
uint32_t limbOffset = Seg2Filespace(limbAddress, parent->baseAddress);
+ ZLimb* limb;
+
if (!parent->HasDeclaration(limbOffset))
{
- ZLimb* limb = new ZLimb(parent);
+ limb = new ZLimb(parent);
limb->ExtractFromBinary(limbOffset, limbType);
limb->SetName(limb->GetDefaultName(varPrefix));
limb->DeclareVar(varPrefix, "");
limb->DeclareReferences(varPrefix);
parent->AddResource(limb);
}
+ else
+ {
+ limb = static_cast<ZLimb*>(parent->FindResource(limbOffset));
+ assert(limb != nullptr);
+ assert(limb->GetResourceType() == ZResourceType::Limb);
+ }
+
+ limb->limbsTable = this;
+ limb->SetLimbIndex(i + 1);
+
+ limbsReferences.push_back(limb);
}
}
}
@@ -250,6 +367,13 @@ std::string ZLimbTable::GetBodySourceCode() const
parent->workerID);
body += StringHelper::Sprintf("\t%s,", limbName.c_str());
+ auto& limb = limbsReferences.at(i);
+ std::string limbEnumName = limb->enumName;
+ if (limbEnumName != "")
+ {
+ body += StringHelper::Sprintf(" /* %s */", limbEnumName.c_str());
+ }
+
if (i + 1 < count)
body += "\n";
}
@@ -257,6 +381,46 @@ std::string ZLimbTable::GetBodySourceCode() const
return body;
}
+std::string ZLimbTable::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix)
+{
+ if (limbNoneName == "" || limbMaxName == "" || enumName == "")
+ {
+ // Don't produce a enum of any of those attributes is missing
+ return "";
+ }
+
+ std::string limbEnum = StringHelper::Sprintf("typedef enum %s {\n", enumName.c_str());
+
+ // This assumes there isn't any skeleton with more than 0x100 limbs
+
+ limbEnum += StringHelper::Sprintf(" /* 0x00 */ %s,\n", limbNoneName.c_str());
+
+ size_t i = 0;
+ for (; i < count; i++)
+ {
+ auto& limb = limbsReferences.at(i);
+ std::string limbEnumName = limb->enumName;
+
+ if (limbEnumName == "")
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::MissingAttribute, parent, this, rawDataIndex,
+ "Skeleton's enum attributes were used but at least one limb is missing its "
+ "'LimbName' attribute",
+ StringHelper::Sprintf("When processing limb %02i, named '%s' at offset '0x%X'",
+ i + 1, limb->GetName().c_str(), limb->GetRawDataIndex()));
+ }
+
+ limbEnum += StringHelper::Sprintf(" /* 0x%02X */ %s,\n", i + 1, limbEnumName.c_str());
+ }
+
+ limbEnum += StringHelper::Sprintf(" /* 0x%02X */ %s\n", i + 1, limbMaxName.c_str());
+
+ limbEnum += StringHelper::Sprintf("} %s;\n", enumName.c_str());
+
+ return limbEnum;
+}
+
std::string ZLimbTable::GetSourceTypeName() const
{
switch (limbType)
@@ -287,3 +451,28 @@ size_t ZLimbTable::GetRawDataSize() const
{
return 4 * limbsAddresses.size();
}
+
+std::string ZLimbTable::GetLimbEnumName(uint8_t limbIndex) const
+{
+ if (limbIndex == 0xFF)
+ {
+ return "LIMB_DONE";
+ }
+
+ if (limbIndex < count)
+ {
+ std::string limbEnumName = limbsReferences.at(limbIndex)->enumName;
+ if (limbEnumName != "")
+ {
+ return StringHelper::Sprintf("%s - 1", limbEnumName.c_str());
+ }
+ }
+ else
+ {
+ HANDLE_WARNING_RESOURCE(WarningType::InvalidExtractedData, parent, this, rawDataIndex,
+ StringHelper::Sprintf("Limb index '%02i' out of range", limbIndex),
+ "");
+ }
+
+ return StringHelper::Sprintf("0x%02X", limbIndex);
+}