Skip to content

Commit

Permalink
how animated
Browse files Browse the repository at this point in the history
  • Loading branch information
petrie911 authored and KiritoDv committed Mar 11, 2024
1 parent 70800a9 commit 6ea4f04
Show file tree
Hide file tree
Showing 3 changed files with 231 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Companion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
180 changes: 180 additions & 0 deletions src/factories/sf64/AnimFactory.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
48 changes: 48 additions & 0 deletions src/factories/sf64/AnimFactory.h
Original file line number Diff line number Diff line change
@@ -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; }
};

0 comments on commit 6ea4f04

Please sign in to comment.