diff options
| -rw-r--r-- | ZAPD/HighLevel/HLModelIntermediette.cpp | 2 | ||||
| -rw-r--r-- | ZAPD/ZFile.cpp | 5 | ||||
| -rw-r--r-- | ZAPD/ZLimb.cpp | 572 | ||||
| -rw-r--r-- | ZAPD/ZLimb.h | 166 | ||||
| -rw-r--r-- | ZAPD/ZSkeleton.cpp | 359 | ||||
| -rw-r--r-- | ZAPD/ZSkeleton.h | 64 |
6 files changed, 891 insertions, 277 deletions
diff --git a/ZAPD/HighLevel/HLModelIntermediette.cpp b/ZAPD/HighLevel/HLModelIntermediette.cpp index 037172e..bd8ec78 100644 --- a/ZAPD/HighLevel/HLModelIntermediette.cpp +++ b/ZAPD/HighLevel/HLModelIntermediette.cpp @@ -259,7 +259,7 @@ void HLModelIntermediette::FromZSkeleton(HLModelIntermediette* model, ZSkeleton* for (int i = 0; i < zSkeleton->limbs.size(); i++) { - ZLimbStandard* limb = zSkeleton->limbs[i]; + ZLimb* limb = zSkeleton->limbs[i]; for (int j = 0; j < model->blocks.size(); j++) { diff --git a/ZAPD/ZFile.cpp b/ZAPD/ZFile.cpp index 220ba11..5046ed1 100644 --- a/ZAPD/ZFile.cpp +++ b/ZAPD/ZFile.cpp @@ -4,6 +4,7 @@ #include "ZRoom/ZRoom.h" #include "ZTexture.h" #include "ZAnimation.h" +#include "ZLimb.h" #include "ZSkeleton.h" #include "ZCollision.h" #include "ZScalar.h" @@ -237,10 +238,10 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b } else if (string(child->Name()) == "Limb") { - ZLimbStandard* limb = nullptr; + ZLimb* limb = nullptr; if (mode == ZFileMode::Extract) - limb = ZLimbStandard::FromXML(child, rawData, rawDataIndex, folderName, this); + limb = ZLimb::FromXML(child, rawData, rawDataIndex, folderName, this); resources.push_back(limb); diff --git a/ZAPD/ZLimb.cpp b/ZAPD/ZLimb.cpp new file mode 100644 index 0000000..b7e6398 --- /dev/null +++ b/ZAPD/ZLimb.cpp @@ -0,0 +1,572 @@ +#include "ZLimb.h" +#include "BitConverter.h" +#include "StringHelper.h" +#include "Globals.h" +#include <cassert> + +using namespace std; + + +Struct_800A57C0::Struct_800A57C0(const std::vector<uint8_t>& rawData, uint32_t fileOffset) +{ + unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00); + unk_2 = BitConverter::ToInt16BE(rawData, fileOffset + 0x02); + unk_4 = BitConverter::ToInt16BE(rawData, fileOffset + 0x04); + unk_6 = BitConverter::ToInt8BE(rawData, fileOffset + 0x06); + unk_7 = BitConverter::ToInt8BE(rawData, fileOffset + 0x07); + unk_8 = BitConverter::ToInt8BE(rawData, fileOffset + 0x08); + unk_9 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x09); +} +Struct_800A57C0::Struct_800A57C0(const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index) + : Struct_800A57C0(rawData, fileOffset + index * GetRawDataSize()) +{ +} + +std::string Struct_800A57C0::GetSourceOutputCode() const +{ + return StringHelper::Sprintf("0x%02X, %i, %i, %i, %i, %i, 0x%02X", + unk_0, unk_2, unk_4, unk_6, unk_7, unk_8, unk_9); +} + +size_t Struct_800A57C0::GetRawDataSize() +{ + return 0x0A; +} + +std::string Struct_800A57C0::GetSourceTypeName() +{ + return "Struct_800A57C0"; +} + + +Struct_800A598C_2::Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset) +{ + unk_0 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x00); + x = BitConverter::ToInt16BE(rawData, fileOffset + 0x02); + y = BitConverter::ToInt16BE(rawData, fileOffset + 0x04); + z = BitConverter::ToInt16BE(rawData, fileOffset + 0x06); + unk_8 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x08); +} +Struct_800A598C_2::Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index) + : Struct_800A598C_2(rawData, fileOffset + index * GetRawDataSize()) +{ +} + +std::string Struct_800A598C_2::GetSourceOutputCode() const +{ + return StringHelper::Sprintf("0x%02X, %i, %i, %i, 0x%02X", + unk_0, x, y, z, unk_8); +} + +size_t Struct_800A598C_2::GetRawDataSize() +{ + return 0x0A; +} + +std::string Struct_800A598C_2::GetSourceTypeName() +{ + return "Struct_800A598C_2"; +} + + +Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset) + : parent(parent) +{ + unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00); + unk_2 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x02); + unk_4 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x04); + unk_8 = BitConverter::ToUInt32BE(rawData, fileOffset + 0x08); + unk_C = BitConverter::ToUInt32BE(rawData, fileOffset + 0x0C); + + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + for (size_t i = 0; i < unk_0; i++) { + unk_8_arr.emplace_back(rawData, unk_8_Offset, i); + } + } + + if (unk_C != 0) { + uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); + for (size_t i = 0; i < unk_2; i++) { + unk_C_arr.emplace_back(rawData, unk_C_Offset, i); + } + } +} +Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index) + : Struct_800A598C(parent, rawData, fileOffset + index * GetRawDataSize()) +{ +} + +void Struct_800A598C::PreGenSourceFiles(const std::string& prefix) +{ + string entryStr; + + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + string unk_8_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A57C0::GetSourceTypeName().c_str(), unk_8_Offset); + + size_t arrayItemCnt = unk_8_arr.size(); + entryStr = ""; + size_t i = 0; + for (auto& child: unk_8_arr) { + entryStr += StringHelper::Sprintf(" { %s },%s", + child.GetSourceOutputCode().c_str(), + (++i < arrayItemCnt) ? "\n" : ""); + } + + Declaration* decl = parent->GetDeclaration(unk_8_Offset); + if (decl == nullptr) { + parent->AddDeclarationArray( + unk_8_Offset, DeclarationAlignment::None, + arrayItemCnt * Struct_800A57C0::GetRawDataSize(), Struct_800A57C0::GetSourceTypeName(), + unk_8_Str, arrayItemCnt, entryStr); + } + else { + decl->text = entryStr; + } + } + + if (unk_C != 0) { + uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); + string unk_C_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A598C_2::GetSourceTypeName().c_str(), unk_C_Offset); + + size_t arrayItemCnt = unk_C_arr.size(); + entryStr = ""; + size_t i = 0; + for (auto& child: unk_C_arr) { + entryStr += StringHelper::Sprintf(" { %s },%s", + child.GetSourceOutputCode().c_str(), + (++i < arrayItemCnt) ? "\n" : ""); + } + + Declaration* decl = parent->GetDeclaration(unk_C_Offset); + if (decl == nullptr) { + parent->AddDeclarationArray( + unk_C_Offset, DeclarationAlignment::None, + arrayItemCnt * Struct_800A598C_2::GetRawDataSize(), Struct_800A598C_2::GetSourceTypeName(), + unk_C_Str, arrayItemCnt, entryStr); + } + else { + decl->text = entryStr; + } + } +} + +std::string Struct_800A598C::GetSourceOutputCode(const std::string& prefix) const +{ + string entryStr; + + string unk_8_Str = "NULL"; + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + unk_8_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A57C0::GetSourceTypeName().c_str(), unk_8_Offset); + } + + string unk_C_Str = "NULL"; + if (unk_C != 0) { + uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); + unk_C_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A598C_2::GetSourceTypeName().c_str(), unk_C_Offset); + } + + entryStr = StringHelper::Sprintf("\n ARRAY_COUNTU(%s), ARRAY_COUNTU(%s),\n", + unk_8_Str.c_str(), unk_C_Str.c_str()); + entryStr += StringHelper::Sprintf(" %i, %s, %s\n ", unk_4, + unk_8_Str.c_str(), unk_C_Str.c_str()); + + return entryStr; +} + +size_t Struct_800A598C::GetRawDataSize() +{ + return 0x10; +} + +std::string Struct_800A598C::GetSourceTypeName() +{ + return "Struct_800A598C"; +} + + +Struct_800A5E28::Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& nRawData, uint32_t fileOffset) + : parent(parent), rawData(nRawData) +{ + unk_0 = BitConverter::ToUInt16BE(nRawData, fileOffset + 0x00); + unk_2 = BitConverter::ToUInt16BE(nRawData, fileOffset + 0x02); + unk_4 = BitConverter::ToUInt32BE(nRawData, fileOffset + 0x04); + unk_8 = BitConverter::ToUInt32BE(nRawData, fileOffset + 0x08); + + if (unk_4 != 0) { + uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); + for (size_t i = 0; i < unk_2; i++) { + unk_4_arr.emplace_back(parent, nRawData, unk_4_Offset, i); + } + } +} +Struct_800A5E28::Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index) + : Struct_800A5E28(parent, rawData, fileOffset + index * GetRawDataSize()) +{ +} + +Struct_800A5E28::~Struct_800A5E28() +{ + delete unk_8_dlist; +} + +void Struct_800A5E28::PreGenSourceFiles(const std::string& prefix) +{ + if (unk_4 != 0) { + uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); + string unk_4_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A598C::GetSourceTypeName().c_str(), unk_4_Offset); + + string entryStr = ""; + uint16_t arrayItemCnt = unk_4_arr.size(); + + size_t i = 0; + for (auto& child: unk_4_arr) { + child.PreGenSourceFiles(prefix); + + entryStr += StringHelper::Sprintf(" { %s },%s", + child.GetSourceOutputCode(prefix).c_str(), + (++i < arrayItemCnt) ? "\n" : ""); + } + + Declaration* decl = parent->GetDeclaration(unk_4_Offset); + if (decl == nullptr) { + parent->AddDeclarationArray( + unk_4_Offset, DeclarationAlignment::None, + arrayItemCnt * Struct_800A598C::GetRawDataSize(), Struct_800A598C::GetSourceTypeName(), + unk_4_Str, arrayItemCnt, entryStr); + } + else { + decl->text = entryStr; + } + } + + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + + int dlistLength = ZDisplayList::GetDListLength(rawData, unk_8_Offset, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + unk_8_dlist = new ZDisplayList(rawData, unk_8_Offset, dlistLength); + unk_8_dlist->parent = parent; + + string dListStr = StringHelper::Sprintf("%sSkinLimbDL_%06X", prefix.c_str(), unk_8_Offset); + unk_8_dlist->SetName(dListStr); + unk_8_dlist->GetSourceOutputCode(prefix); + } +} + +std::string Struct_800A5E28::GetSourceOutputCode(const std::string& prefix) const +{ + string entryStr = ""; + + string unk_4_Str = "NULL"; + if (unk_4 != 0) { + uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); + Declaration* decl = parent->GetDeclaration(unk_4_Offset); + if (decl == nullptr) { + unk_4_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A598C::GetSourceTypeName().c_str(), unk_4_Offset); + } + else { + unk_4_Str = decl->varName; + } + } + + string unk_8_Str = "NULL"; + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + Declaration* decl = parent->GetDeclaration(unk_8_Offset); + if (decl == nullptr) { + // Something went wrong... + unk_8_Str = StringHelper::Sprintf("0x%08X", unk_8); + } + else { + unk_8_Str = decl->varName; + } + } + + return StringHelper::Sprintf("\n %i, ARRAY_COUNTU(%s),\n %s, %s\n", + unk_0, unk_4_Str.c_str(), + unk_4_Str.c_str(), unk_8_Str.c_str()); +} + +size_t Struct_800A5E28::GetRawDataSize() +{ + return 0x0C; +} + +std::string Struct_800A5E28::GetSourceTypeName() +{ + return "Struct_800A5E28"; +} + + +ZLimb::ZLimb(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent) +{ + rawData.assign(nRawData.begin(), nRawData.end()); + rawDataIndex = nRawDataIndex; + parent = nParent; + + segAddress = nRawDataIndex; + + ParseXML(reader); + ParseRawData(); + + if (type == ZLimbType::Skin) { + if (skinSegmentType == ZLimbSkinType::SkinType_4 && skinSegment != 0) { + uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress); + segmentStruct = Struct_800A5E28(parent, rawData, skinSegmentOffset); + } + } +} + +ZLimb::ZLimb(ZLimbType limbType, const std::string& prefix, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent) +{ + rawData.assign(nRawData.begin(), nRawData.end()); + rawDataIndex = nRawDataIndex; + parent = nParent; + type = limbType; + + segAddress = nRawDataIndex; + name = StringHelper::Sprintf("%sLimb_%06X", prefix.c_str(), GetFileAddress()); + + ParseRawData(); +} + +void ZLimb::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); + + // Reading from a <Skeleton/> + const char* limbType = reader->Attribute("LimbType"); + if (limbType == nullptr) { + // Reading from a <Limb/> + limbType = reader->Attribute("Type"); + } + + if (limbType == nullptr) { + fprintf(stderr, "ZLimb::ParseXML: Warning in '%s'.\n\t Missing 'LimbType' attribute in xml. Defaulting to 'Standard'.\n", name.c_str()); + type = ZLimbType::Standard; + } + else { + string limbTypeStr(limbType); + if (limbTypeStr == "Standard") { + type = ZLimbType::Standard; + } + else if(limbTypeStr == "LOD") { + type = ZLimbType::LOD; + } + else if(limbTypeStr == "Skin") { + type = ZLimbType::Skin; + } + else { + fprintf(stderr, "ZLimb::ParseXML: Warning in '%s'.\n\t Invalid LimbType found: '%s'. Defaulting to 'Standard'.\n", name.c_str(), limbType); + type = ZLimbType::Standard; + } + } +} + +void ZLimb::ParseRawData() +{ + transX = BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + transY = BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + transZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + + childIndex = rawData.at(rawDataIndex + 6); + siblingIndex = rawData.at(rawDataIndex + 7); + + switch (type) { + case ZLimbType::LOD: + farDListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12); + case ZLimbType::Standard: + dListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); + break; + case ZLimbType::Skin: + skinSegmentType = static_cast<ZLimbSkinType>(BitConverter::ToInt32BE(rawData, rawDataIndex + 8)); + skinSegment = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12); + break; + } +} + +ZLimb* ZLimb::FromXML(tinyxml2::XMLElement* reader, vector<uint8_t> nRawData, int rawDataIndex, string nRelPath, ZFile* parent) +{ + ZLimb* limb = new ZLimb(reader, nRawData, rawDataIndex, parent); + limb->relativePath = std::move(nRelPath); + + limb->parent->AddDeclaration( + limb->GetFileAddress(), DeclarationAlignment::None, limb->GetRawDataSize(), + limb->GetSourceTypeName(), limb->name, ""); + + return limb; +} + + +int ZLimb::GetRawDataSize() +{ + switch (type) { + case ZLimbType::Standard: + return 0x0C; + case ZLimbType::LOD: + case ZLimbType::Skin: + return 0x10; + } + return 0x0C; +} + +string ZLimb::GetSourceOutputCode(const std::string& prefix) +{ + string dListStr = "NULL"; + string dListStr2 = "NULL"; + + if (dListPtr != 0) { + dListStr = GetLimbDListSourceOutputCode(prefix, "", dListPtr); + } + if (farDListPtr != 0) { + dListStr2 = GetLimbDListSourceOutputCode(prefix, "Far", farDListPtr); + } + + string entryStr = StringHelper::Sprintf("\n { %i, %i, %i },\n 0x%02X, 0x%02X,\n", + transX, transY, transZ, childIndex, siblingIndex); + + switch (type) { + case ZLimbType::Standard: + entryStr += StringHelper::Sprintf(" %s\n", dListStr.c_str()); + break; + case ZLimbType::LOD: + entryStr += StringHelper::Sprintf(" { %s, %s }\n", + dListStr.c_str(), dListStr2.c_str()); + break; + case ZLimbType::Skin: + entryStr += GetSourceOutputCodeSkin(prefix); + break; + } + + Declaration* decl = parent->GetDeclaration(GetFileAddress()); + if (decl == nullptr) { + parent->AddDeclaration(GetFileAddress(), DeclarationAlignment::None, GetRawDataSize(), GetSourceTypeName(), name, entryStr); + } + else { + decl->text = entryStr; + } + + return ""; +} + +std::string ZLimb::GetSourceTypeName() +{ + return GetSourceTypeName(type); +} + +ZResourceType ZLimb::GetResourceType() +{ + return ZResourceType::Limb; +} + +ZLimbType ZLimb::GetLimbType() +{ + return type; +} + +const char* ZLimb::GetSourceTypeName(ZLimbType limbType) +{ + switch (limbType) { + case ZLimbType::Standard: + return "StandardLimb"; + case ZLimbType::LOD: + return "LodLimb"; + case ZLimbType::Skin: + return "SkinLimb"; + } + return "StandardLimb"; +} + +uint32_t ZLimb::GetFileAddress() +{ + return Seg2Filespace(segAddress, parent->baseAddress); +} + +std::string ZLimb::GetLimbDListSourceOutputCode(const std::string& prefix, const std::string& limbPrefix, segptr_t dListPtr) +{ + if (dListPtr == 0) { + return "NULL"; + } + + uint32_t dListOffset = Seg2Filespace(dListPtr, parent->baseAddress); + + string dListStr; + Declaration* decl = parent->GetDeclaration(dListOffset); + if (decl == nullptr) { + dListStr = StringHelper::Sprintf("%s%sLimbDL_%06X", prefix.c_str(), limbPrefix.c_str(), dListOffset); + + int dlistLength = ZDisplayList::GetDListLength(rawData, dListOffset, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + auto& dList = dLists.emplace_back(rawData, dListOffset, dlistLength); + dList.parent = parent; + dList.SetName(dListStr); + dList.GetSourceOutputCode(prefix); + } + else { + dListStr = decl->varName; + } + + return dListStr; +} + +std::string ZLimb::GetSourceOutputCodeSkin_Type_4(const std::string& prefix) +{ + assert(type == ZLimbType::Skin); + assert(skinSegmentType == ZLimbSkinType::SkinType_4); + + if (skinSegment == 0) { + return "NULL"; + } + + uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress); + + string struct_800A5E28_Str; + Declaration* decl = parent->GetDeclaration(skinSegmentOffset); + if (decl == nullptr) { + struct_800A5E28_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A5E28::GetSourceTypeName().c_str(), skinSegmentOffset); + + segmentStruct.PreGenSourceFiles(prefix); + string entryStr = segmentStruct.GetSourceOutputCode(prefix); + + parent->AddDeclaration( + skinSegmentOffset, DeclarationAlignment::None, + Struct_800A5E28::GetRawDataSize(), Struct_800A5E28::GetSourceTypeName(), + struct_800A5E28_Str, entryStr); + } + else { + struct_800A5E28_Str = decl->varName; + } + + return struct_800A5E28_Str; +} + +std::string ZLimb::GetSourceOutputCodeSkin(const std::string& prefix) +{ + assert(type == ZLimbType::Skin); + + string skinSegmentStr = "NULL"; + + if (skinSegment != 0) { + switch (skinSegmentType) { + case ZLimbSkinType::SkinType_4: + skinSegmentStr = "&" + GetSourceOutputCodeSkin_Type_4(prefix); + break; + case ZLimbSkinType::SkinType_DList: + skinSegmentStr = GetLimbDListSourceOutputCode(prefix, "Skin", skinSegment); + break; + default: + fprintf(stderr, "ZLimb::GetSourceOutputCodeSkinType: Error in '%s'.\n\t Unknown segment type for SkinLimb: '%i'. \n\tPlease report this.\n", name.c_str(), static_cast<int32_t>(skinSegmentType)); + case ZLimbSkinType::SkinType_0: + case ZLimbSkinType::SkinType_5: + fprintf(stderr, "ZLimb::GetSourceOutputCodeSkinType: Error in '%s'.\n\t Segment type for SkinLimb not implemented: '%i'.\n", name.c_str(), static_cast<int32_t>(skinSegmentType)); + skinSegmentStr = StringHelper::Sprintf("0x%08X", skinSegment); + break; + } + } + + string entryStr = StringHelper::Sprintf(" 0x%02X, %s\n", + skinSegmentType, skinSegmentStr.c_str()); + + return entryStr; +} diff --git a/ZAPD/ZLimb.h b/ZAPD/ZLimb.h new file mode 100644 index 0000000..cc5e906 --- /dev/null +++ b/ZAPD/ZLimb.h @@ -0,0 +1,166 @@ +#pragma once + +#include <vector> +#include <string> +#include <cstdint> +#include "ZFile.h" +#include "ZDisplayList.h" + + +enum class ZLimbType +{ + Standard, + LOD, + Skin +}; + +// TODO: check if more types exists +enum class ZLimbSkinType +{ + SkinType_0, // Segment = 0 + SkinType_4 = 4, // Segment = segmented address // Struct_800A5E28 + SkinType_5 = 5, // Segment = 0 + SkinType_DList = 11, // Segment = DList address +}; + + +class Struct_800A57C0 +{ +protected: + uint16_t unk_0; + int16_t unk_2; + int16_t unk_4; + int8_t unk_6; + int8_t unk_7; + int8_t unk_8; + uint8_t unk_9; + +public: + Struct_800A57C0(const std::vector<uint8_t>& rawData, uint32_t fileOffset); + Struct_800A57C0(const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index); + + [[nodiscard]] + std::string GetSourceOutputCode() const; + + static size_t GetRawDataSize(); + static std::string GetSourceTypeName(); +}; + + +class Struct_800A598C_2 +{ +protected: + uint8_t unk_0; + int16_t x; + int16_t y; + int16_t z; + uint8_t unk_8; + +public: + Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset); + Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index); + + [[nodiscard]] + std::string GetSourceOutputCode() const; + + static size_t GetRawDataSize(); + static std::string GetSourceTypeName(); +}; + + +class Struct_800A598C +{ +protected: + ZFile* parent; + + uint16_t unk_0; // Length of unk_8 + uint16_t unk_2; // Length of unk_C + uint16_t unk_4; // 0 or 1 // Used as an index for unk_C + segptr_t unk_8; // Struct_800A57C0* + segptr_t unk_C; // Struct_800A598C_2* + + std::vector<Struct_800A57C0> unk_8_arr; + std::vector<Struct_800A598C_2> unk_C_arr; + +public: + Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset); + Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index); + + void PreGenSourceFiles(const std::string& prefix); + [[nodiscard]] + std::string GetSourceOutputCode(const std::string& prefix) const; + + static size_t GetRawDataSize(); + static std::string GetSourceTypeName(); +}; + + +class Struct_800A5E28 +{ +protected: + ZFile* parent; + std::vector<uint8_t> rawData; + + uint16_t unk_0; // Vtx count + uint16_t unk_2; // Length of unk_4 + segptr_t unk_4; // Struct_800A598C* + segptr_t unk_8; // Gfx* + + std::vector<Struct_800A598C> unk_4_arr; + ZDisplayList* unk_8_dlist = nullptr; + +public: + Struct_800A5E28() = default; + Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset); + Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index); + ~Struct_800A5E28(); + + void PreGenSourceFiles(const std::string& prefix); + [[nodiscard]] + std::string GetSourceOutputCode(const std::string& prefix) const; + + static size_t GetRawDataSize(); + static std::string GetSourceTypeName(); +}; + + +class ZLimb : public ZResource +{ +protected: + segptr_t segAddress; + ZLimbType type = ZLimbType::Standard; + + int16_t transX, transY, transZ; + uint8_t childIndex, siblingIndex; + segptr_t dListPtr = 0; + + std::vector<ZDisplayList> dLists; + + segptr_t farDListPtr = 0; // LOD only + + ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only + segptr_t skinSegment = 0; // Skin only + Struct_800A5E28 segmentStruct; // Skin only + + std::string GetLimbDListSourceOutputCode(const std::string& prefix, const std::string& limbPrefix, segptr_t dListPtr); + + std::string GetSourceOutputCodeSkin(const std::string& prefix); + std::string GetSourceOutputCodeSkin_Type_4(const std::string& prefix); + +public: + ZLimb(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent); + ZLimb(ZLimbType limbType, const std::string& prefix, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent); + + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; + static ZLimb* FromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); + int GetRawDataSize() override; + std::string GetSourceOutputCode(const std::string& prefix) override; + std::string GetSourceTypeName() override; + ZResourceType GetResourceType() override; + + ZLimbType GetLimbType(); + static const char* GetSourceTypeName(ZLimbType limbType); + + uint32_t GetFileAddress(); +}; diff --git a/ZAPD/ZSkeleton.cpp b/ZAPD/ZSkeleton.cpp index 173570f..37d9f46 100644 --- a/ZAPD/ZSkeleton.cpp +++ b/ZAPD/ZSkeleton.cpp @@ -1,89 +1,108 @@ #include "ZSkeleton.h" #include "BitConverter.h" #include "StringHelper.h" -#include "Globals.h" #include "HighLevel/HLModelIntermediette.h" -#include <typeinfo> using namespace std; -using namespace tinyxml2; -ZLimbStandard::ZLimbStandard() -{ - name = ""; - transX = 0; - transY = 0; - transZ = 0; - childIndex = 0; - siblingIndex = 0; - dListPtr = 0; - children = vector<ZLimbStandard*>(); -} -ZLimbStandard* ZLimbStandard::FromXML(XMLElement* reader, vector<uint8_t> nRawData, int rawDataIndex, string nRelPath, ZFile* parent) +ZSkeleton::ZSkeleton(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent) { - ZLimbType limbType = ZLimbType::Standard; - string limbName = reader->Attribute("Name"); - int limbAddress = strtol(StringHelper::Split(reader->Attribute("Offset"), "0x")[1].c_str(), NULL, 16); + rawData.assign(nRawData.begin(), nRawData.end()); + rawDataIndex = nRawDataIndex; + parent = nParent; - if (string(reader->Attribute("Type")) == "LOD") - limbType = ZLimbType::LOD; + ParseXML(reader); + ParseRawData(); - ZLimbStandard* limb = ZLimbStandard::FromRawData(nRawData, rawDataIndex); - limb->ParseXML(reader); - limb->parent = parent; - limb->name = limbName; - limb->address = limbAddress; + string defaultPrefix = name; + defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables + uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); - string entryType = limbType == ZLimbType::LOD ? "LodLimb" : "StandardLimb"; + for (size_t i = 0; i < limbCount; i++) { + uint32_t ptr2 = Seg2Filespace(BitConverter::ToUInt32BE(rawData, ptr), parent->baseAddress); - limb->parent->AddDeclaration(limb->address, DeclarationAlignment::None, 12, entryType, StringHelper::Sprintf("%s", limbName.c_str(), limb->address), ""); + ZLimb* limb = new ZLimb(reader, rawData, ptr2, parent); + limb->SetName(StringHelper::Sprintf("%sLimb_%06X", defaultPrefix.c_str(), limb->GetFileAddress())); + limbs.push_back(limb); - return limb; + ptr += 4; + } } -ZLimbStandard* ZLimbStandard::FromRawData(std::vector<uint8_t> nRawData, int rawDataIndex) +ZSkeleton::~ZSkeleton() { - ZLimbStandard* limb = new ZLimbStandard(); - - limb->address = rawDataIndex; - - limb->transX = BitConverter::ToInt16BE(nRawData, rawDataIndex + 0); - limb->transY = BitConverter::ToInt16BE(nRawData, rawDataIndex + 2); - limb->transZ = BitConverter::ToInt16BE(nRawData, rawDataIndex + 4); + for (auto& limb: limbs) { + delete limb; + } +} - limb->childIndex = nRawData[rawDataIndex + 6]; - limb->siblingIndex = nRawData[rawDataIndex + 7]; +void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); - limb->dListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 8) & 0x00FFFFFF; + const char* skelTypeXml = reader->Attribute("Type"); + if (skelTypeXml == nullptr) { + fprintf(stderr, "ZSkeleton::ParseXML: Warning in '%s'.\n\t Type not found found. Defaulting to 'Normal'.\n", name.c_str()); + type = ZSkeletonType::Normal; + } + else { + string skelTypeStr(skelTypeXml); + if (skelTypeStr == "Flex") { + type = ZSkeletonType::Flex; + } + 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; + } + } - return limb; + const char* limbTypeXml = reader->Attribute("LimbType"); + if (limbTypeXml == nullptr) { + fprintf(stderr, "ZSkeleton::ParseXML: Warning in '%s'.\n\t LimbType not found found. Defaulting to 'Standard'.\n", name.c_str()); + limbType = ZLimbType::Standard; + } + else { + string limbTypeStr(limbTypeXml); + if (limbTypeStr == "Standard") { + limbType = ZLimbType::Standard; + } + else if (limbTypeStr == "LOD") { + limbType = ZLimbType::LOD; + } + else if (limbTypeStr == "Skin") { + limbType = ZLimbType::Skin; + } + 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; + } + } } -string ZLimbStandard::GetSourceOutputCode(const std::string& prefix) +void ZSkeleton::ParseRawData() { - string dListStr = dListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetVarName(dListPtr).c_str()); - - string entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, %s", - transX, transY, transZ, childIndex, siblingIndex, dListStr.c_str()); - - Declaration* decl = parent->GetDeclaration(address); - decl->text = entryStr; + ZResource::ParseRawData(); - return ""; + limbsArrayAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex); + limbCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4); + dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8); } -int ZLimbStandard::GetRawDataSize() +ZSkeleton* ZSkeleton::FromXML(tinyxml2::XMLElement* reader, vector<uint8_t> nRawData, int rawDataIndex, string nRelPath, ZFile* nParent) { - return 12; + ZSkeleton* skeleton = new ZSkeleton(reader, nRawData, rawDataIndex, nParent); + skeleton->relativePath = std::move(nRelPath); + + skeleton->parent->AddDeclaration( + skeleton->rawDataIndex, DeclarationAlignment::Align16, skeleton->GetRawDataSize(), + skeleton->GetSourceTypeName(), skeleton->name, ""); + + return skeleton; } -ZSkeleton::ZSkeleton() : ZResource() +void ZSkeleton::Save(const std::string& outFolder) { - type = ZSkeletonType::Normal; - limbs = vector<ZLimbStandard*>(); - rootLimb = nullptr; - dListCount = 0; } void ZSkeleton::GenerateHLIntermediette(HLFileIntermediette& hlFile) @@ -93,176 +112,85 @@ void ZSkeleton::GenerateHLIntermediette(HLFileIntermediette& hlFile) //mdl->blocks.push_back(new HLTerminator()); } -ZSkeleton* ZSkeleton::FromXML(XMLElement* reader, vector<uint8_t> nRawData, int rawDataIndex, string nRelPath, ZFile* nParent) +int ZSkeleton::GetRawDataSize() { - ZSkeleton* skeleton = new ZSkeleton(); - skeleton->name = reader->Attribute("Name"); - skeleton->parent = nParent; - ZLimbType limbType = ZLimbType::Standard; - ZSkeletonType skeletonType = ZSkeletonType::Normal; - int limbCount = 0; - - skeleton->rawData = nRawData; - skeleton->rawDataIndex = rawDataIndex; - - if (reader->Attribute("Type") != nullptr) - { - if (string(reader->Attribute("Type")) == "Flex") - skeletonType = ZSkeletonType::Flex; - else if (string(reader->Attribute("Type")) == "Skin") - skeletonType = ZSkeletonType::Skin; - else if (string(reader->Attribute("Type")) != "Normal") - { - // TODO: Print some error here... - } - } - - skeleton->type = skeletonType; - - if (reader->Attribute("LimbType") != nullptr) - { - //printf("C3\n"); - - if (string(reader->Attribute("LimbType")) == "LOD") - limbType = ZLimbType::LOD; + switch (type) { + case ZSkeletonType::Normal: + return 0x8; + case ZSkeletonType::Flex: + return 0xC; + default: + return 0x8; } - - limbCount = nRawData[rawDataIndex + 4]; - skeleton->dListCount = nRawData[rawDataIndex + 8]; - - ZLimbStandard* currentLimb = nullptr; - - uint32_t ptr = (uint32_t)BitConverter::ToInt32BE(nRawData, rawDataIndex) & 0x00FFFFFF; - - for (int i = 0; i < limbCount; i++) - { - uint32_t ptr2 = (uint32_t)BitConverter::ToInt32BE(nRawData, ptr) & 0x00FFFFFF; - - if (limbType == ZLimbType::Standard) - { - ZLimbStandard* limb = ZLimbStandard::FromRawData(nRawData, ptr2); - skeleton->limbs.push_back(limb); - } - else - { - ZLimbLOD* limb = ZLimbLOD::FromRawData(nRawData, ptr2); - skeleton->limbs.push_back(limb); - } - - ptr += 4; - } - - return skeleton; } std::string ZSkeleton::GetSourceOutputCode(const std::string& prefix) { - if (parent != nullptr) - { - string defaultPrefix = name.c_str(); - defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables - - for (int i = 0; i < limbs.size(); i++) - { - ZLimbStandard* limb = limbs[i]; - - string defaultDLName = StringHelper::Sprintf("%sLimbDL_%06X", defaultPrefix.c_str(), limb->dListPtr); - string dListStr = limb->dListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetDeclarationName(limb->dListPtr, defaultDLName).c_str()); - - if (limb->dListPtr != 0 && parent->GetDeclaration(limb->dListPtr) == nullptr) - { - ZDisplayList* dList = new ZDisplayList(rawData, limb->dListPtr, ZDisplayList::GetDListLength(rawData, limb->dListPtr, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX)); - dList->parent = parent; - dList->SetName(StringHelper::Sprintf("%sLimbDL_%06X", defaultPrefix.c_str(), limb->dListPtr)); - dList->GetSourceOutputCode(defaultPrefix); - } - - string entryStr = ""; - string entryType = ""; - - if (typeid(*limb) == typeid(ZLimbLOD)) - { - ZLimbLOD* limbLOD = (ZLimbLOD*)limbs[i]; - string defaultFarDLName = StringHelper::Sprintf("%sFarLimbDL_%06X", defaultPrefix.c_str(), limbLOD->farDListPtr); - string dListStr2 = limbLOD->farDListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetDeclarationName(limbLOD->farDListPtr, defaultFarDLName).c_str()); - - if (limbLOD->farDListPtr != 0 && parent->GetDeclaration(limbLOD->farDListPtr) == nullptr) - { - ZDisplayList* dList = new ZDisplayList(rawData, limbLOD->farDListPtr, ZDisplayList::GetDListLength(rawData, limbLOD->farDListPtr, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX)); - dList->parent = parent; - dList->SetName(StringHelper::Sprintf("%s_farLimbDL_%06X", defaultPrefix.c_str(), limbLOD->farDListPtr)); - dList->GetSourceOutputCode(defaultPrefix); - } - - entryType = "LodLimb"; - - entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, { %s, %s }", - limbLOD->transX, limbLOD->transY, limbLOD->transZ, limbLOD->childIndex, limbLOD->siblingIndex, dListStr.c_str(), dListStr2.c_str()); - } - else - { - entryType = "StandardLimb"; - - entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, %s", - limb->transX, limb->transY, limb->transZ, limb->childIndex, limb->siblingIndex, dListStr.c_str()); - } - - string limbName = StringHelper::Sprintf("%sLimb_%06X", defaultPrefix.c_str(), limb->address); + if (parent == nullptr) { + return ""; + } - if (parent->HasDeclaration(limb->address)) - limbName = parent->GetDeclarationName(limb->address); + string defaultPrefix = name.c_str(); + defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables - parent->AddDeclaration(limb->address, DeclarationAlignment::None, limb->GetRawDataSize(), entryType, limbName, entryStr); - } + for (auto& limb: limbs) { + limb->GetSourceOutputCode(defaultPrefix); + } + uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); + if (!parent->HasDeclaration(ptr)) + { // Table string tblStr = ""; - for (int i = 0; i < limbs.size(); i++) + for (size_t i = 0; i < limbs.size(); i++) { - ZLimbStandard* limb = limbs[i]; + ZLimb* limb = limbs.at(i); - //string decl = StringHelper::Sprintf(" &_%sLimb_%04X,\n", prefix.c_str(), limb->address); - string decl = ""; - - if (parent->HasDeclaration(limb->address)) { - decl = StringHelper::Sprintf(" &%s,", parent->GetDeclarationName(limb->address).c_str()); - if (i != (limbs.size() - 1)) { - decl += "\n"; - } + string decl = StringHelper::Sprintf(" &%s,", parent->GetDeclarationName(limb->GetFileAddress()).c_str()); + if (i != (limbs.size() - 1)) { + decl += "\n"; } tblStr += decl; } - uint32_t ptr = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex) & 0x00FFFFFF; + parent->AddDeclarationArray(ptr, DeclarationAlignment::None, 4 * limbCount, + StringHelper::Sprintf("static %s*", ZLimb::GetSourceTypeName(limbType)), + StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str()), limbCount, tblStr); + } - if (!parent->HasDeclaration(ptr)) - { - parent->AddDeclarationArray(ptr, DeclarationAlignment::None, 4 * limbs.size(), - "static void*", StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str()), limbs.size(), tblStr); - } + string headerStr; + switch (type) { + case ZSkeletonType::Normal: + headerStr = StringHelper::Sprintf("%sLimbs, %i", defaultPrefix.c_str(), limbCount); + break; + case ZSkeletonType::Flex: + headerStr = StringHelper::Sprintf("%sLimbs, %i, %i", defaultPrefix.c_str(), limbCount, dListCount); + break; + } - if (type == ZSkeletonType::Normal) - { - string headerStr = StringHelper::Sprintf("%sLimbs, %i", defaultPrefix.c_str(), limbs.size()); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, 8, - "SkeletonHeader", StringHelper::Sprintf("%s", name.c_str()), headerStr); - } - else - { - string headerStr = StringHelper::Sprintf("%sLimbs, %i, %i", defaultPrefix.c_str(), limbs.size(), dListCount); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, 12, - "FlexSkeletonHeader", StringHelper::Sprintf("%s", name.c_str()), headerStr); - } + Declaration* decl = parent->GetDeclaration(GetAddress()); + if (decl == nullptr) { + parent->AddDeclaration(GetAddress(), DeclarationAlignment::Align16, + GetRawDataSize(), GetSourceTypeName(), name, headerStr); + } + else { + decl->text = headerStr; } return ""; } -void ZSkeleton::Save(const std::string& outFolder) +std::string ZSkeleton::GetSourceTypeName() { - + switch (type) { + case ZSkeletonType::Normal: + return "SkeletonHeader"; + case ZSkeletonType::Flex: + return "FlexSkeletonHeader"; + } + return "SkeletonHeader"; } ZResourceType ZSkeleton::GetResourceType() @@ -270,36 +198,7 @@ ZResourceType ZSkeleton::GetResourceType() return ZResourceType::Skeleton; } -ZLimbLOD::ZLimbLOD() : ZLimbStandard() -{ - farDListPtr = 0; -} - -ZLimbLOD* ZLimbLOD::FromRawData(vector<uint8_t> nRawData, int rawDataIndex) -{ - ZLimbLOD* limb = new ZLimbLOD(); - - limb->address = rawDataIndex; - - limb->transX = BitConverter::ToInt16BE(nRawData, rawDataIndex + 0); - limb->transY = BitConverter::ToInt16BE(nRawData, rawDataIndex + 2); - limb->transZ = BitConverter::ToInt16BE(nRawData, rawDataIndex + 4); - - limb->childIndex = nRawData[rawDataIndex + 6]; - limb->siblingIndex = nRawData[rawDataIndex + 7]; - - limb->dListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 8) & 0x00FFFFFF; - limb->farDListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 12) & 0x00FFFFFF; - - return limb; -} - -string ZLimbLOD::GetSourceOutputCode(const std::string& prefix) -{ - return std::string(); -} - -int ZLimbLOD::GetRawDataSize() +segptr_t ZSkeleton::GetAddress() { - return 16; + return rawDataIndex; } diff --git a/ZAPD/ZSkeleton.h b/ZAPD/ZSkeleton.h index 836251a..2cafd56 100644 --- a/ZAPD/ZSkeleton.h +++ b/ZAPD/ZSkeleton.h @@ -2,64 +2,40 @@ #include <vector> #include <string> -#include <stdint.h> +#include <cstdint> #include "ZFile.h" - -enum class ZLimbType -{ - Standard, - LOD -}; - -struct ZLimbStandard : public ZResource -{ - uint32_t address; - std::string name; - - int16_t transX, transY, transZ; - uint8_t childIndex, siblingIndex; - uint32_t dListPtr; - - std::vector<ZLimbStandard*> children; - - ZLimbStandard(); - static ZLimbStandard* FromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); - static ZLimbStandard* FromRawData(std::vector<uint8_t> nRawData, int rawDataIndex); - std::string GetSourceOutputCode(const std::string& prefix) override; - int GetRawDataSize() override; -}; - -struct ZLimbLOD : ZLimbStandard -{ - uint32_t farDListPtr; - - ZLimbLOD(); - //static ZLimbLOD* FromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); - static ZLimbLOD* FromRawData(std::vector<uint8_t> nRawData, int rawDataIndex); - std::string GetSourceOutputCode(const std::string& prefix) override; - int GetRawDataSize() override; -}; +#include "ZDisplayList.h" +#include "ZLimb.h" enum ZSkeletonType { Normal, - Flex, - Skin + Flex }; class ZSkeleton : public ZResource { public: - ZSkeletonType type; - std::vector<ZLimbStandard*> limbs; - ZLimbStandard* rootLimb; + ZSkeletonType type = ZSkeletonType::Normal; + ZLimbType limbType = ZLimbType::Standard; + std::vector<ZLimb*> limbs; + segptr_t limbsArrayAddress; + uint8_t limbCount; uint8_t dListCount; // FLEX SKELETON ONLY - ZSkeleton(); - virtual void GenerateHLIntermediette(HLFileIntermediette& hlFile); + ZSkeleton(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent); + ~ZSkeleton(); + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; static ZSkeleton* FromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> nRawData, int rawDataIndex, std::string nRelPath, ZFile* nParent); void Save(const std::string& outFolder) override; - ZResourceType GetResourceType() override; + void GenerateHLIntermediette(HLFileIntermediette& hlFile) override; + int GetRawDataSize() override; std::string GetSourceOutputCode(const std::string& prefix) override; + + std::string GetSourceTypeName() override; + ZResourceType GetResourceType() override; + + segptr_t GetAddress(); }; |
