diff options
Diffstat (limited to 'src/factories/sm64/CollisionFactory.cpp')
| -rw-r--r-- | src/factories/sm64/CollisionFactory.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
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 |
