summaryrefslogtreecommitdiff
path: root/ZAPD/ZAnimation.cpp
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2021-03-19 15:44:55 -0300
committerGitHub <noreply@github.com>2021-03-19 14:44:55 -0400
commit50122b91242734ebf893af9f64b674127b73d831 (patch)
treef83b0178b80bfae85729b9c7bf499b5e08bf74c7 /ZAPD/ZAnimation.cpp
parent50ad6f96dc6d2ab8668bf7f7bf11e53dc52636b6 (diff)
Add support to `SkelCurve` and its animation type (#98)
* Type="Curve" Signed-off-by: angie <angheloalf95@gmail.com> * Starting to extract CurveLimbs Signed-off-by: angie <angheloalf95@gmail.com> * Fix a few oversights Signed-off-by: angie <angheloalf95@gmail.com> * Reading the TransformUpdateIndex Signed-off-by: angie <angheloalf95@gmail.com> * Export the body of the ZCurveAnimation Signed-off-by: angie <angheloalf95@gmail.com> * Add TransformData Signed-off-by: angie <angheloalf95@gmail.com> * Extracting one element of the arrays Signed-off-by: angie <angheloalf95@gmail.com> * Extract the whole refIndexArr Signed-off-by: Angie <angheloalf95@gmail.com> * fix a typo Signed-off-by: Angie <angheloalf95@gmail.com> * Extract the whole transformData array Signed-off-by: Angie <angheloalf95@gmail.com> * Extract copyValues array Signed-off-by: Angie <angheloalf95@gmail.com>
Diffstat (limited to 'ZAPD/ZAnimation.cpp')
-rw-r--r--ZAPD/ZAnimation.cpp272
1 files changed, 272 insertions, 0 deletions
diff --git a/ZAPD/ZAnimation.cpp b/ZAPD/ZAnimation.cpp
index 21fdf3f..b76087f 100644
--- a/ZAPD/ZAnimation.cpp
+++ b/ZAPD/ZAnimation.cpp
@@ -186,3 +186,275 @@ void ZLinkAnimation::ParseRawData()
//segmentAddress = GETSEGOFFSET(BitConverter::ToInt32BE(data, rawDataIndex + 4));
segmentAddress = (BitConverter::ToInt32BE(data, rawDataIndex + 4));
}
+
+
+/* ZCurveAnimation */
+
+TransformData::TransformData(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset)
+ : parent(parent)
+{
+ unk_00 = BitConverter::ToUInt16BE(rawData, fileOffset + 0);
+ unk_02 = BitConverter::ToUInt16BE(rawData, fileOffset + 2);
+ unk_04 = BitConverter::ToInt16BE(rawData, fileOffset + 4);
+ unk_06 = BitConverter::ToInt16BE(rawData, fileOffset + 6);
+ unk_08 = BitConverter::ToFloatBE(rawData, fileOffset + 8);
+}
+
+TransformData::TransformData(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index)
+ : TransformData(parent, rawData, fileOffset + index * GetRawDataSize())
+{
+}
+
+std::string TransformData::GetBody(const std::string& prefix) const
+{
+ return StringHelper::Sprintf("0x%04X, 0x%04X, %i, %i, %ff",
+ unk_00, unk_02, unk_04, unk_06, unk_08);
+}
+
+size_t TransformData::GetRawDataSize()
+{
+ return 0x0C;
+}
+
+std::string TransformData::GetSourceTypeName()
+{
+ return "TransformData";
+}
+
+
+ZCurveAnimation::ZCurveAnimation(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent)
+{
+ rawData.assign(nRawData.begin(), nRawData.end());
+ rawDataIndex = nRawDataIndex;
+ parent = nParent;
+
+ ParseXML(reader);
+ ParseRawData();
+
+ skel = new ZSkeleton(ZSkeletonType::Curve, ZLimbType::Curve, "CurveAnim",
+ nRawData, Seg2Filespace(skelOffset, parent->baseAddress), nParent);
+
+ size_t transformDataSize = 0;
+ size_t copyValuesSize = 0;
+ if (refIndex != 0) {
+ uint32_t refIndexOffset = Seg2Filespace(refIndex, parent->baseAddress);
+ for (size_t i = 0; i < 3 * 3 * skel->GetLimbCount(); i++) {
+ uint8_t ref = BitConverter::ToUInt8BE(nRawData, refIndexOffset + i);
+ if (ref == 0) {
+ copyValuesSize++;
+ }
+ else {
+ transformDataSize += ref;
+ }
+ refIndexArr.emplace_back(ref);
+ }
+ }
+
+ if (transformData != 0) {
+ uint32_t transformDataOffset = Seg2Filespace(transformData, parent->baseAddress);
+ for (size_t i = 0; i < transformDataSize; i++) {
+ transformDataArr.emplace_back(parent, nRawData, transformDataOffset, i);
+ }
+ }
+
+ if (copyValues != 0) {
+ uint32_t copyValuesOffset = Seg2Filespace(copyValues, parent->baseAddress);
+ for (size_t i = 0; i < copyValuesSize; i++) {
+ copyValuesArr.emplace_back(BitConverter::ToInt16BE(nRawData, copyValuesOffset + i*2));
+ }
+ }
+}
+
+ZCurveAnimation::~ZCurveAnimation()
+{
+ delete skel;
+}
+
+void ZCurveAnimation::ParseXML(tinyxml2::XMLElement* reader)
+{
+ ZAnimation::ParseXML(reader);
+
+ const char* skelOffsetXml = reader->Attribute("SkelOffset");
+ if (skelOffsetXml == nullptr) {
+ throw std::runtime_error("ZCurveAnimation::ParseXML: Fatal error in '%s'. Missing 'SkelOffset' attribute in xml. You need to provide the offset of the curve skeleton.");
+ }
+ skelOffset = std::strtoul(skelOffsetXml, nullptr, 0);
+}
+
+void ZCurveAnimation::ParseRawData()
+{
+ ZAnimation::ParseRawData();
+
+ refIndex = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0);
+ transformData = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
+ copyValues = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
+ unk_0C = BitConverter::ToInt16BE(rawData, rawDataIndex + 12);
+ unk_10 = BitConverter::ToInt16BE(rawData, rawDataIndex + 14);
+}
+
+ZCurveAnimation* ZCurveAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData, int nRawDataIndex, std::string nRelPath, ZFile* nParent)
+{
+ ZCurveAnimation* curve = new ZCurveAnimation(reader, nRawData, nRawDataIndex, nParent);
+ curve->relativePath = std::move(nRelPath);
+
+ curve->parent->AddDeclaration(
+ curve->rawDataIndex, DeclarationAlignment::Align16, curve->GetRawDataSize(),
+ curve->GetSourceTypeName(), curve->name, "");
+
+ return curve;
+}
+
+void ZCurveAnimation::PreGenValues(const std::string& prefix)
+{
+ Declaration* decl = parent->GetDeclaration(skelOffset);
+ if (decl == nullptr) {
+ skel->GetSourceOutputCode(prefix);
+ }
+
+ if (refIndex != 0) {
+ uint32_t refIndexOffset = Seg2Filespace(refIndex, parent->baseAddress);
+ string refIndexStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Ref", refIndexOffset);
+
+ string entryStr = " ";
+ uint16_t arrayItemCnt = refIndexArr.size();
+
+ size_t i = 0;
+ for (auto& child: refIndexArr) {
+ entryStr += StringHelper::Sprintf("0x%02X, %s",
+ child,
+ (i++ % 8 == 7) ? "\n " : "");
+ }
+
+ Declaration* decl = parent->GetDeclaration(refIndexOffset);
+ if (decl == nullptr) {
+ parent->AddDeclarationArray(
+ refIndexOffset, DeclarationAlignment::None,
+ arrayItemCnt * 1, "u8",
+ refIndexStr, arrayItemCnt, entryStr);
+ }
+ else {
+ decl->text = entryStr;
+ }
+ }
+
+ if (transformData != 0) {
+ uint32_t transformDataOffset = Seg2Filespace(transformData, parent->baseAddress);
+ string transformDataStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), TransformData::GetSourceTypeName().c_str(), transformDataOffset);
+
+ string entryStr = "";
+ uint16_t arrayItemCnt = transformDataArr.size();
+
+ size_t i = 0;
+ for (auto& child: transformDataArr) {
+ entryStr += StringHelper::Sprintf(" { %s },%s",
+ child.GetBody(prefix).c_str(),
+ (++i < arrayItemCnt) ? "\n" : "");
+ }
+
+ Declaration* decl = parent->GetDeclaration(transformDataOffset);
+ if (decl == nullptr) {
+ parent->AddDeclarationArray(
+ transformDataOffset, DeclarationAlignment::None,
+ arrayItemCnt * TransformData::GetRawDataSize(), TransformData::GetSourceTypeName(),
+ transformDataStr, arrayItemCnt, entryStr);
+ }
+ else {
+ decl->text = entryStr;
+ }
+ }
+
+ if (copyValues != 0) {
+ uint32_t copyValuesOffset = Seg2Filespace(copyValues, parent->baseAddress);
+ string copyValuesStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Copy", copyValuesOffset);
+
+ string entryStr = " ";
+ uint16_t arrayItemCnt = copyValuesArr.size();
+
+ size_t i = 0;
+ for (auto& child: copyValuesArr) {
+ entryStr += StringHelper::Sprintf("% 6i, %s",
+ child,
+ (i++ % 8 == 7) ? "\n " : "");
+ }
+
+ Declaration* decl = parent->GetDeclaration(copyValuesOffset);
+ if (decl == nullptr) {
+ parent->AddDeclarationArray(
+ copyValuesOffset, DeclarationAlignment::None,
+ arrayItemCnt * 2, "s16",
+ copyValuesStr, arrayItemCnt, entryStr);
+ }
+ else {
+ decl->text = entryStr;
+ }
+ }
+}
+
+int ZCurveAnimation::GetRawDataSize()
+{
+ return 0x10;
+}
+
+std::string ZCurveAnimation::GetSourceOutputCode(const std::string& prefix)
+{
+ string bodyStr = "";
+ uint32_t address = Seg2Filespace(rawDataIndex, parent->baseAddress);
+
+ PreGenValues(prefix);
+
+ string refIndexStr = "NULL";
+ if (refIndex != 0) {
+ uint32_t refIndexOffset = Seg2Filespace(refIndex, parent->baseAddress);
+ Declaration* decl = parent->GetDeclaration(refIndexOffset);
+ if (decl == nullptr) {
+ refIndexStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Ref", refIndexOffset);
+ }
+ else {
+ refIndexStr = decl->varName;
+ }
+ }
+
+ string transformDataStr = "NULL";
+ if (transformData != 0) {
+ uint32_t transformDataOffset = Seg2Filespace(transformData, parent->baseAddress);
+ Declaration* decl = parent->GetDeclaration(transformDataOffset);
+ if (decl == nullptr) {
+ transformDataStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), TransformData::GetSourceTypeName().c_str(), transformDataOffset);
+ }
+ else {
+ transformDataStr = decl->varName;
+ }
+ }
+
+ string copyValuesStr = "NULL";
+ if (copyValues != 0) {
+ uint32_t copyValuesOffset = Seg2Filespace(copyValues, parent->baseAddress);
+ Declaration* decl = parent->GetDeclaration(copyValuesOffset);
+ if (decl == nullptr) {
+ copyValuesStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Copy", copyValuesOffset);
+ }
+ else {
+ copyValuesStr = decl->varName;
+ }
+ }
+
+
+ bodyStr = StringHelper::Sprintf("\n %s,\n %s,\n %s,\n %i, %i\n",
+ refIndexStr.c_str(), transformDataStr.c_str(), copyValuesStr.c_str(), unk_0C, unk_10);
+
+ Declaration* decl = parent->GetDeclaration(address);
+ if (decl == nullptr) {
+ parent->AddDeclaration(address, DeclarationAlignment::None,
+ GetRawDataSize(), GetSourceTypeName(), name, bodyStr);
+ }
+ else {
+ decl->text = bodyStr;
+ }
+
+ return "";
+}
+
+std::string ZCurveAnimation::GetSourceTypeName()
+{
+ return "TransformUpdateIndex";
+}