summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpetrie911 <petrie911@yahoo.com>2024-03-10 19:26:21 -0500
committerLywx <kiritodev01@gmail.com>2024-03-10 19:48:02 -0600
commit6ea4f0476628fb44f59e4fa3519bbd3b811cfb23 (patch)
treefd65abacb757f795806313c5a7aa7c0672238c45
parent70800a914487440a7464ab826c4628f920ecc273 (diff)
how animated
-rw-r--r--src/Companion.cpp3
-rw-r--r--src/factories/sf64/AnimFactory.cpp180
-rw-r--r--src/factories/sf64/AnimFactory.h48
3 files changed, 231 insertions, 0 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp
index b95566c..55da325 100644
--- a/src/Companion.cpp
+++ b/src/Companion.cpp
@@ -63,6 +63,9 @@ void Companion::Init(const ExportType type) {
this->RegisterFactory("MK64:TRACKSECTIONS", std::make_shared<MK64::TrackSectionsFactory>());
this->RegisterFactory("MK64:SPAWNDATA", std::make_shared<MK64::SpawnDataFactory>());
+ // SF64 specific
+ this->RegisterFactory("ANIM", std::make_shared<AnimFactory>());
+
this->Process();
}
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
diff --git a/src/factories/sf64/AnimFactory.h b/src/factories/sf64/AnimFactory.h
new file mode 100644
index 0000000..28f88d8
--- /dev/null
+++ b/src/factories/sf64/AnimFactory.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "../BaseFactory.h"
+
+struct JointKey {
+ uint16_t keys[6];
+};
+
+class AnimData : public IParsedData {
+public:
+ int16_t mFrameCount;
+ int16_t mLimbCount;
+ uint32_t mDataOffset;
+ uint32_t mKeyOffset;
+ std::vector<int16_t> mFrameData;
+ std::vector<JointKey> mJointKeys;
+
+
+ AnimData(int16_t frameCount, int16_t limbCount, uint32_t dataOffset, std::vector<int16_t> frameData, uint32_t keyOffset, std::vector<JointKey> jointKeys);
+};
+
+class AnimHeaderExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class AnimBinaryExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class AnimCodeExporter : public BaseExporter {
+ void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class AnimFactory : public BaseFactory {
+public:
+ std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
+ std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override {
+ return std::nullopt;
+ }
+ inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
+ return {
+ REGISTER(Code, AnimCodeExporter)
+ REGISTER(Header, AnimHeaderExporter)
+ REGISTER(Binary, AnimBinaryExporter)
+ };
+ }
+ bool SupportModdedAssets() override { return false; }
+}; \ No newline at end of file