diff options
| author | Anghelo Carvajal <angheloalf95@gmail.com> | 2021-03-19 15:44:55 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-19 14:44:55 -0400 |
| commit | 50122b91242734ebf893af9f64b674127b73d831 (patch) | |
| tree | f83b0178b80bfae85729b9c7bf499b5e08bf74c7 /ZAPD/ZAnimation.cpp | |
| parent | 50ad6f96dc6d2ab8668bf7f7bf11e53dc52636b6 (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.cpp | 272 |
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"; +} |
