summaryrefslogtreecommitdiff
path: root/src/factories
diff options
context:
space:
mode:
Diffstat (limited to 'src/factories')
-rw-r--r--src/factories/BaseFactory.h4
-rw-r--r--src/factories/sm64/AnimationFactory.cpp37
-rw-r--r--src/factories/sm64/CollisionFactory.cpp116
-rw-r--r--src/factories/sm64/CollisionFactory.h36
4 files changed, 175 insertions, 18 deletions
diff --git a/src/factories/BaseFactory.h b/src/factories/BaseFactory.h
index 18c03ef..c30bb92 100644
--- a/src/factories/BaseFactory.h
+++ b/src/factories/BaseFactory.h
@@ -81,12 +81,16 @@ public:
class BaseExporter {
public:
+ virtual ~BaseExporter() = default;
+
virtual ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) = 0;
static void WriteHeader(LUS::BinaryWriter& write, LUS::ResourceType resType, int32_t version);
};
class BaseFactory {
public:
+ virtual ~BaseFactory() = default;
+
virtual std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) = 0;
virtual std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) {
return std::nullopt;
diff --git a/src/factories/sm64/AnimationFactory.cpp b/src/factories/sm64/AnimationFactory.cpp
index 1b4070d..3174cd5 100644
--- a/src/factories/sm64/AnimationFactory.cpp
+++ b/src/factories/sm64/AnimationFactory.cpp
@@ -1,6 +1,10 @@
#include "AnimationFactory.h"
+
+#include <utils/Decompressor.h>
#include "spdlog/spdlog.h"
+#define ANIM_INDEX_COUNT(boneCount) ((boneCount) + 1) * 2 * 6
+
ExportResult SM64::AnimationBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto writer = LUS::BinaryWriter();
const auto anim = std::static_pointer_cast<AnimationData>(raw);
@@ -29,11 +33,7 @@ ExportResult SM64::AnimationBinaryExporter::Export(std::ostream &write, std::sha
}
std::optional<std::shared_ptr<IParsedData>> SM64::AnimationFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
- auto headerNode = GetSafeNode<YAML::Node>(node, "header");
- auto valuesNode = GetSafeNode<YAML::Node>(node, "values");
- auto indexNode = GetSafeNode<YAML::Node>(node, "indices");
-
- LUS::BinaryReader header(reinterpret_cast<char *>(buffer.data()) + GetSafeNode<uint32_t>(headerNode, "offset"), GetSafeNode<uint32_t>(headerNode, "size"));
+ auto header = Decompressor::AutoDecode(node, buffer).GetReader();
header.SetEndianness(LUS::Endianness::Big);
auto flags = header.ReadInt16();
@@ -42,26 +42,27 @@ std::optional<std::shared_ptr<IParsedData>> SM64::AnimationFactory::parse(std::v
auto loopStart = header.ReadInt16();
auto loopEnd = header.ReadInt16();
auto unusedBoneCount = header.ReadInt16();
- header.ReadUInt32();
- header.ReadUInt32();
+ auto valuesAddr = header.ReadUInt32();
+ auto indicesAddr = header.ReadUInt32();
auto length = header.ReadUInt32();
- LUS::BinaryReader indices(reinterpret_cast<char*>(buffer.data()) + GetSafeNode<uint32_t>(indexNode, "offset"), GetSafeNode<uint32_t>(indexNode, "size"));
- indices.SetEndianness(LUS::Endianness::Big);
- size_t indexLength = GetSafeNode<uint32_t>(indexNode, "size") / sizeof(int16_t);
- std::vector<int16_t> indicesData;
- for (size_t i = 0; i < indexLength; i++) {
- indicesData.push_back(indices.ReadInt16());
- }
+ auto values = Decompressor::AutoDecodeByOffset(valuesAddr, indicesAddr - valuesAddr, buffer).GetReader();
+ values.SetEndianness(LUS::Endianness::Big);
- LUS::BinaryReader values(reinterpret_cast<char*>(buffer.data()) + GetSafeNode<uint32_t>(valuesNode, "offset"), GetSafeNode<uint32_t>(valuesNode, "size"));
- values.SetEndianness(LUS::Endianness::Big);
- size_t entries = GetSafeNode<uint32_t>(valuesNode, "size") / sizeof(uint16_t);
std::vector<uint16_t> valuesData;
- for (size_t i = 0; i < entries; i++) {
+ for (size_t i = 0; i < values.GetLength() / sizeof(uint16_t); i++) {
valuesData.push_back(values.ReadUInt16());
}
+ auto indicesCount = ANIM_INDEX_COUNT(unusedBoneCount);
+ auto indices = Decompressor::AutoDecodeByOffset(indicesAddr, indicesCount * sizeof(int16_t), buffer).GetReader();
+ indices.SetEndianness(LUS::Endianness::Big);
+
+ std::vector<int16_t> indicesData;
+ for (size_t i = 0; i < indicesCount; i++) {
+ indicesData.push_back(indices.ReadInt16());
+ }
+
SPDLOG_INFO("Flags: {}", flags);
SPDLOG_INFO("Anim-Y Trans Divisor: {}", animYTransDivisor);
SPDLOG_INFO("Start Frame: {}", startFrame);
diff --git a/src/factories/sm64/CollisionFactory.cpp b/src/factories/sm64/CollisionFactory.cpp
new file mode 100644
index 0000000..71b75d2
--- /dev/null
+++ b/src/factories/sm64/CollisionFactory.cpp
@@ -0,0 +1,116 @@
+#include "CollisionFactory.h"
+
+#include <Companion.h>
+#include <utils/Decompressor.h>
+
+#define BASE(val, cmd, enumname) val == Companion::Instance->GetValueFromEnum(enumname, cmd)
+
+#define COL_INIT(v) BASE(v, "TERRAIN_LOAD_VERTICES", "TerrainLoadCommands")
+#define COL_TRI_STOP(v) BASE(v, "TERRAIN_LOAD_END", "TerrainLoadCommands")
+#define COL_TRI_INIT(surf) BASE(v, surf, "SurfaceTypes")
+
+#define SURFACE_TYPE(type) Companion::Instance->GetEnumFromValue("SurfaceTypes", type).value_or(std::to_string(type))
+
+enum class ProcessingState {
+ None,
+ Vertex,
+ Triangle,
+ Special
+};
+
+ExportResult SM64::CollisionCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
+ auto offset = GetSafeNode<uint32_t>(node, "offset");
+ auto symbol = GetSafeNode(node, "symbol", entryName);
+ auto collision = std::static_pointer_cast<CollisionData>(raw);
+
+ size_t cmd_size = collision->mCommandList.size();
+ ProcessingState state = ProcessingState::None;
+
+ size_t vtxCount = 0;
+
+ for(size_t i = 0; i < collision->mCommandList.size(); i++){
+ auto cmd = collision->mCommandList[i];
+
+ if(COL_INIT(cmd)){
+ vtxCount = collision->mCommandList[++i];
+ write << "COL_INIT(),\n";
+ write << "COL_VERTEX_INIT(" << vtxCount << "),\n";
+ state = ProcessingState::Vertex;
+ continue;
+ }
+
+ switch(state) {
+ case ProcessingState::Vertex:
+ if(vtxCount > 0){
+ auto x = collision->mCommandList[i + 0];
+ auto y = collision->mCommandList[i + 1];
+ auto z = collision->mCommandList[i + 2];
+
+ write << "COL_VERTEX(" << x << ", " << y << ", " << z << "),\n";
+ vtxCount--;
+ } else {
+ int32_t surf = collision->mCommandList[i];
+ auto triCount = collision->mCommandList[++i];
+
+ write << "COL_TRI_INIT(" << SURFACE_TYPE(surf) << ", " << triCount << "),\n";
+ state = ProcessingState::Triangle;
+ }
+ break;
+ case ProcessingState::Triangle:
+ if(!COL_TRI_STOP(cmd)){
+ auto v1 = collision->mCommandList[i + 0];
+ auto v2 = collision->mCommandList[i + 1];
+ auto v3 = collision->mCommandList[i + 2];
+
+ write << "COL_TRI(" << v1 << ", " << v2 << ", " << v3 << "),\n";
+ } else {
+ write << "COL_TRI_STOP(),\n";
+ state = ProcessingState::None;
+ }
+ break;
+ }
+
+ if(state == ProcessingState::Vertex){
+
+ continue;
+ }
+
+
+ }
+
+ return offset + cmd_size * sizeof(int16_t);
+}
+
+
+ExportResult SM64::CollisionHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
+ auto collision = std::static_pointer_cast<CollisionData>(raw);
+
+ return std::nullopt;
+}
+
+ExportResult SM64::CollisionBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) {
+ auto collision = std::static_pointer_cast<CollisionData>(raw);
+
+ return std::nullopt;
+}
+
+std::optional<std::shared_ptr<IParsedData>> SM64::CollisionFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
+ auto [root, segment] = Decompressor::AutoDecode(node, buffer);
+
+ LUS::BinaryReader reader(segment.data, segment.size);
+ reader.SetEndianness(LUS::Endianness::Big);
+ std::vector<int16_t> commands;
+ bool processing = true;
+
+ while(processing){
+ auto cmd = reader.ReadInt16();
+
+ if(COL_TRI_STOP(cmd)){
+ processing = false;
+ }
+
+ commands.push_back(cmd);
+ }
+
+ return std::nullopt;
+} \ No newline at end of file
diff --git a/src/factories/sm64/CollisionFactory.h b/src/factories/sm64/CollisionFactory.h
new file mode 100644
index 0000000..f4bfab4
--- /dev/null
+++ b/src/factories/sm64/CollisionFactory.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "../BaseFactory.h"
+
+namespace SM64 {
+class CollisionData : public IParsedData {
+public:
+ std::vector<int16_t> mCommandList;
+
+ CollisionData(std::vector<int16_t>& commandList) : mCommandList(commandList) {}
+};
+
+class CollisionCodeExporter : public BaseExporter {
+ ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class CollisionHeaderExporter : public BaseExporter {
+ ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class CollisionBinaryExporter : public BaseExporter {
+ ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
+class CollisionFactory : public BaseFactory {
+public:
+ std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
+ std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
+ return {
+ REGISTER(Code, CollisionCodeExporter)
+ REGISTER(Header, CollisionHeaderExporter)
+ REGISTER(Binary, CollisionBinaryExporter)
+ };
+ }
+};
+} \ No newline at end of file