mirror of
https://github.com/izzy2lost/Torch.git
synced 2026-07-06 00:18:35 -07:00
how animated
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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; }
|
||||
};
|
||||
Reference in New Issue
Block a user