-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
231 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | ||
}; |