diff options
Diffstat (limited to 'src/factories/sf64/AnimFactory.cpp')
| -rw-r--r-- | src/factories/sf64/AnimFactory.cpp | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/factories/sf64/AnimFactory.cpp b/src/factories/sf64/AnimFactory.cpp new file mode 100644 index 0000000..c100328 --- /dev/null +++ b/src/factories/sf64/AnimFactory.cpp @@ -0,0 +1,180 @@ +#include "AnimFactory.h" +#include "spdlog/spdlog.h" + +#include "Companion.h" +#include "utils/Decompressor.h" + +#define NUM(x) std::dec << std::setfill(' ') << std::setw(6) << x +#define HEX(x) std::hex << std::setfill(' ') << std::setw(6) << x +// #define COL(c) std::dec << std::setfill(' ') << std::setw(3) << c + +AnimData::AnimData(int16_t frameCount, int16_t limbCount, uint32_t dataOffset, std::vector<int16_t> frameData, uint32_t keyOffset, std::vector<JointKey> jointKeys): mFrameCount(frameCount), mLimbCount(limbCount), mDataOffset(dataOffset), mFrameData(std::move(frameData)), mKeyOffset(keyOffset), mJointKeys(std::move(jointKeys)) { + if((mDataOffset + sizeof(mFrameData) > mKeyOffset) && (mKeyOffset + sizeof(mJointKeys) > mDataOffset)) { + // error 1 + } + if(mJointKeys.size() != limbCount) { + // error 2 + } +} + +void AnimHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { + const auto symbol = GetSafeNode(node, "symbol", entryName); + + if(Companion::Instance->IsOTRMode()){ + write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; + return; + } + + write << "extern Animation " << symbol << ";\n"; +} + +void AnimCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + // auto limbCount = std::static_pointer_cast<AnimData>(raw)->mLimbCount; + // auto frameCount = std::static_pointer_cast<AnimData>(raw)->mFrameCount; + // auto jointKeys = std::static_pointer_cast<AnimData>(raw)->mJointKeys; + // auto frameData = std::static_pointer_cast<AnimData>(raw)->mFrameData; + auto anim = std::static_pointer_cast<AnimData>(raw); + const auto symbol = GetSafeNode(node, "symbol", entryName); + // auto dataName = GetSafeNode(node, "data_symbol", entryName); + // auto keyName = GetSafeNode(node, "key_symbol", entryName); + auto dataOffset = anim->mDataOffset; + auto keyOffset = anim->mKeyOffset; + auto dataSegment = 0; + auto keySegment = 0; + std::ostringstream dataDefaultName; + std::ostringstream keyDefaultName; + + if (IS_SEGMENTED(dataOffset)) { + dataSegment = SEGMENT_NUMBER(dataOffset); + dataOffset = SEGMENT_OFFSET(dataOffset); + } + dataDefaultName << symbol << "_frame_data_" << std::hex << dataOffset; + auto dataName = GetSafeNode(node, "data_symbol", dataDefaultName.str()); + + if (IS_SEGMENTED(keyOffset)) { + keySegment = SEGMENT_NUMBER(keyOffset); + keyOffset = SEGMENT_OFFSET(keyOffset); + } + keyDefaultName << symbol << "_joint_key_" << std::hex << keyOffset; + auto keyName = GetSafeNode(node, "data_symbol", keyDefaultName.str()); + + + // if (Companion::Instance->IsDebug()) { + // write << "// 0x" << std::hex << std::uppercase << offset << "\n"; + // } + + write << "u16 " << dataName << "[] = {"; + for(int i = 0; i < anim->mFrameData.size(); i++) { + + if((i % 12) == 0) { + write << "\n" << fourSpaceTab; + } + // if(i < 3) { + write << NUM(anim->mFrameData[i]) << ", "; + // } else { + // write << HEX(anim->mFrameData[i]) << ", "; + // } + } + write << "\n};\n"; + + write << "\n"; + + write << "JointKey " << keyName << "[] = {\n"; + for(auto joint : anim->mJointKeys) { + write << fourSpaceTab << "{"; + for(int i = 0; i < 6; i++) { + write << NUM(joint.keys[i]) << ", "; + } + write << "},\n"; + } + write << "};\n"; + + write << "\n"; + + + + + + write << "Animation " << symbol << " = {\n"; + write << fourSpaceTab << NUM(anim->mFrameCount) << ", " << NUM(anim->mLimbCount) << ", " << dataName << ", " << keyName << ",\n"; + write << "};\n"; + + write << "\n"; + +} + +void AnimBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + auto anim = std::static_pointer_cast<AnimData>(raw); + auto writer = LUS::BinaryWriter(); + + WriteHeader(writer, LUS::ResourceType::Vertex, 0); + writer.Write(anim->mFrameCount); + writer.Write(anim->mLimbCount); + writer.Write(anim->mFrameData.size()); + writer.Write(anim->mJointKeys.size()); + + for(auto joint : anim->mJointKeys) { + for (int i = 0; i < 6; i++) { + writer.Write(joint.keys[i]); + } + } + for(auto data : anim->mFrameData) { + writer.Write(data); + } + writer.Finish(write); +} + +std::optional<std::shared_ptr<IParsedData>> AnimFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + // uint32_t offset = GetSafeNode<uint32_t>(node, "offset"); + YAML::Node dataNode; + YAML::Node keyNode; + std::vector<JointKey> jointKeys; + std::vector<int16_t> frameData; + auto dataCount = 0; + auto [_, segment] = Decompressor::AutoDecode(node, buffer, 0xC); + LUS::BinaryReader reader(segment.data, segment.size); + + reader.SetEndianness(LUS::Endianness::Big); + // reader.Seek(offset, Start); + int16_t frameCount = reader.ReadInt16(); + int16_t limbCount = reader.ReadInt16(); + uint32_t dataOffset = reader.ReadUInt32(); + uint32_t keyOffset = reader.ReadUInt32(); + + keyNode["offset"] = keyOffset; + dataNode["offset"] = dataOffset; + + auto [__, keySegment] = Decompressor::AutoDecode(keyNode, buffer, sizeof(JointKey) * (limbCount + 1)); + LUS::BinaryReader keyReader(keySegment.data, keySegment.size); + keyReader.SetEndianness(LUS::Endianness::Big); + + for(int i = 0; i <= limbCount; i++) { + auto xLen = keyReader.ReadUInt16(); + auto x = keyReader.ReadUInt16(); + auto yLen = keyReader.ReadUInt16(); + auto y = keyReader.ReadUInt16(); + auto zLen = keyReader.ReadUInt16(); + auto z = keyReader.ReadUInt16(); + + jointKeys.push_back(JointKey({xLen, x, yLen, y, zLen, z})); + if(i == 0 || x != 0) { + dataCount += (xLen < 1) ? 1 : (xLen > frameCount) ? frameCount : xLen; + } + if(i == 0 || y != 0) { + dataCount += (yLen < 1) ? 1 : (yLen > frameCount) ? frameCount : yLen; + } + if(i == 0 || z != 0) { + dataCount += (zLen < 1) ? 1 : (zLen > frameCount) ? frameCount : zLen; + } + } + + auto [___, dataSegment] = Decompressor::AutoDecode(dataNode, buffer, sizeof(uint16_t) * dataCount); + LUS::BinaryReader dataReader(dataSegment.data, dataSegment.size); + dataReader.SetEndianness(LUS::Endianness::Big); + + for(int i = 0; i < dataCount; i++) { + frameData.push_back(dataReader.ReadInt16()); + } + + return std::make_shared<AnimData>(frameCount, limbCount, dataOffset, frameData, keyOffset, jointKeys); +}
\ No newline at end of file |
