Add mk64 factories

This commit is contained in:
=
2024-03-09 07:39:51 -06:00
committed by Lywx
parent f06ed7388d
commit a2d735c528
12 changed files with 467 additions and 22 deletions
+1
View File
@@ -8,6 +8,7 @@ debug/
!src/factories/debug/
*.z64
*.n64
*.inc.c
headers/
build/
code/
+8 -2
View File
@@ -16,7 +16,10 @@
#include "factories/DisplayListFactory.h"
#include "factories/BlobFactory.h"
#include "factories/LightsFactory.h"
#include "factories/mk64/WaypointFactory.h"
#include "factories/mk64/CourseVtx.h"
#include "factories/mk64/Waypoints.h"
#include "factories/mk64/TrackSections.h"
#include "factories/mk64/SpawnData.h"
#include "spdlog/spdlog.h"
#include "hj/sha1.h"
@@ -54,7 +57,10 @@ void Companion::Init(const ExportType type) {
this->RegisterFactory("SM64:GEO_LAYOUT", std::make_shared<SM64::GeoLayoutFactory>());
// MK64 specific
this->RegisterFactory("MK64:TRACKWAYPOINTS", std::make_shared<MK64::WaypointFactory>());
this->RegisterFactory("MK64:COURSEVTX", std::make_shared<MK64::CourseVtxFactory>());
this->RegisterFactory("MK64:TRACKWAYPOINTS", std::make_shared<MK64::WaypointsFactory>());
this->RegisterFactory("MK64:TRACKSECTIONS", std::make_shared<MK64::TrackSectionsFactory>());
this->RegisterFactory("MK64:SPAWNDATA", std::make_shared<MK64::SpawnDataFactory>());
this->Process();
}
+20 -16
View File
@@ -7,25 +7,29 @@ enum class ResourceType {
None = 0x00000000,
// Common
Archive = 0x4F415243, // OARC (UNUSED)
DisplayList = 0x4F444C54, // ODLT
Vertex = 0x4F565458, // OVTX
Matrix = 0x4F4D5458, // OMTX
Array = 0x4F415252, // OARR
Blob = 0x4F424C42, // OBLB
Texture = 0x4F544558, // OTEX
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
Lights = 0x46669697, // LGTS
Archive = 0x4F415243, // OARC (UNUSED)
DisplayList = 0x4F444C54, // ODLT
Vertex = 0x4F565458, // OVTX
Matrix = 0x4F4D5458, // OMTX
Array = 0x4F415252, // OARR
Blob = 0x4F424C42, // OBLB
Texture = 0x4F544558, // OTEX
Bank = 0x42414E4B, // BANK
Sample = 0x41554643, // AIFC
Sequence = 0x53455143, // SEQC
Lights = 0x46669697, // LGTS
// SM64
Anim = 0x414E494D, // ANIM
SDialog = 0x53444C47, // SDLG
Dictionary = 0x44494354, // DICT
GeoLayout = 0x47454F20, // GEO
Anim = 0x414E494D, // ANIM
SDialog = 0x53444C47, // SDLG
Dictionary = 0x44494354, // DICT
GeoLayout = 0x47454F20, // GEO
// MK64
Waypoints = 0x46665666, // TrackWaypoints
CourseVertex = 0x43565458, // CVTX
TrackSection = 0x5343544E, // SCTN
Waypoints = 0x57505453, // WPTS
Metadata = 0x4D444154, // MDAT
SpawnData = 0x53444154, // SDAT
};
} // namespace LUS
+1 -1
View File
@@ -59,7 +59,7 @@ void VtxCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> r
}
if (Companion::Instance->IsDebug()) {
write << fourSpaceTab << "// 0x" << std::hex << std::uppercase << (offset + (16 * vtx.size())) << "\n";
write << fourSpaceTab << "// 0x" << std::hex << std::uppercase << (offset + (sizeof(VtxRaw) * vtx.size())) << "\n";
}
write << "}; // size = 0x" << std::hex << std::uppercase << (sizeof(VtxRaw) * vtx.size()) << "\n\n";
+108
View File
@@ -0,0 +1,108 @@
#include "CourseVtx.h"
#include "Companion.h"
#include "utils/Decompressor.h"
#define NUM(x) std::dec << std::setfill(' ') << std::setw(6) << x
#define COL(c) "0x" << std::hex << std::setw(2) << std::setfill('0') << c
void MK64::CourseVtxHeaderExporter::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 CourseVtx " << symbol << "[];\n";
}
void MK64::CourseVtxCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto vtx = std::static_pointer_cast<CourseVtxData>(raw)->mVtxs;
const auto symbol = GetSafeNode(node, "symbol", entryName);
const auto offset = GetSafeNode<uint32_t>(node, "offset");
if (Companion::Instance->IsDebug()) {
write << "// 0x" << std::hex << std::uppercase << offset << "\n";
}
write << "CourseVtx " << symbol << "[] = {\n";
for (int i = 0; i < vtx.size(); ++i) {
auto v = vtx[i];
auto x = v.ob[0];
auto y = v.ob[1];
auto z = v.ob[2];
auto tc1 = v.tc[0];
auto tc2 = v.tc[1];
auto c1 = (uint16_t) v.cn[0];
auto c2 = (uint16_t) v.cn[1];
auto c3 = (uint16_t) v.cn[2];
auto c4 = (uint16_t) v.cn[3];
if(i <= vtx.size() - 1) {
write << fourSpaceTab;
}
// {{{ x, y, z }, { tc1, tc2 }, { c1, c2, c3, c4 }}}
write << "{{{" << NUM(x) << ", " << NUM(y) << ", " << NUM(z) << "}, {" << NUM(tc1) << ", " << NUM(tc2) << "}, {" << COL(c1) << ", " << COL(c2) << ", " << COL(c3) << ", " << COL(c4) << "}}},\n";
}
if (Companion::Instance->IsDebug()) {
write << fourSpaceTab << "// 0x" << std::hex << std::uppercase << (offset + (sizeof(CourseVtx) * vtx.size())) << "\n";
}
write << "};\n\n";
}
void MK64::CourseVtxBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto vtx = std::static_pointer_cast<CourseVtxData>(raw);
auto writer = LUS::BinaryWriter();
WriteHeader(writer, LUS::ResourceType::CourseVertex, 0);
writer.Write((uint32_t) vtx->mVtxs.size());
for(auto v : vtx->mVtxs) {
writer.Write(v.ob[0]);
writer.Write(v.ob[1]);
writer.Write(v.ob[2]);
writer.Write(v.tc[0]);
writer.Write(v.tc[1]);
writer.Write(v.cn[0]);
writer.Write(v.cn[1]);
writer.Write(v.cn[2]);
writer.Write(v.cn[3]);
}
writer.Finish(write);
}
std::optional<std::shared_ptr<IParsedData>> MK64::CourseVtxFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto count = GetSafeNode<size_t>(node, "count");
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
LUS::BinaryReader reader(segment.data, count * sizeof(CourseVtx));
reader.SetEndianness(LUS::Endianness::Big);
std::vector<CourseVtx> vertices;
for(size_t i = 0; i < count; i++) {
auto x = reader.ReadInt16();
auto y = reader.ReadInt16();
auto z = reader.ReadInt16();
auto tc1 = reader.ReadInt16();
auto tc2 = reader.ReadInt16();
auto cn1 = reader.ReadUByte();
auto cn2 = reader.ReadUByte();
auto cn3 = reader.ReadUByte();
auto cn4 = reader.ReadUByte();
vertices.push_back(CourseVtx({
{x, y, z}, {tc1, tc2}, {cn1, cn2, cn3, cn4}
}));
}
return std::make_shared<CourseVtxData>(vertices);
}
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include "../BaseFactory.h"
namespace MK64 {
struct CourseVtx {
int16_t ob[3]; /* x, y, z */
int16_t tc[2]; /* texture coord */
uint8_t cn[4]; /* color & alpha */
};
class CourseVtxData : public IParsedData {
public:
std::vector<CourseVtx> mVtxs;
explicit CourseVtxData(std::vector<CourseVtx> vtxs) : mVtxs(vtxs) {}
};
class CourseVtxHeaderExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class CourseVtxBinaryExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class CourseVtxCodeExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class CourseVtxFactory : 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, CourseVtxCodeExporter)
REGISTER(Header, CourseVtxHeaderExporter)
REGISTER(Binary, CourseVtxBinaryExporter)
};
}
bool SupportModdedAssets() override { return false; }
};
}
+90
View File
@@ -0,0 +1,90 @@
#include "SpawnData.h"
#include "Companion.h"
#include "utils/Decompressor.h"
#define NUM(x) std::dec << std::setfill(' ') << std::setw(6) << x
#define COL(c) "0x" << std::hex << std::setw(2) << std::setfill('0') << c
void MK64::SpawnDataHeaderExporter::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 ActorSpawnData " << symbol << "[];\n";
}
void MK64::SpawnDataCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto spawns = std::static_pointer_cast<SpawnDataData>(raw)->mSpawns;
const auto symbol = GetSafeNode(node, "symbol", entryName);
const auto offset = GetSafeNode<uint32_t>(node, "offset");
if (Companion::Instance->IsDebug()) {
write << "// 0x" << std::hex << std::uppercase << offset << "\n";
}
write << "ActorSpawnData " << symbol << "[] = {\n";
for (int i = 0; i < spawns.size(); i++) {
auto x = spawns[i].x;
auto y = spawns[i].y;
auto z = spawns[i].z;
auto id = spawns[i].id;
if(i <= spawns.size() - 1) {
write << fourSpaceTab;
}
// { x, y, z, id },
write << "{" << NUM(x) << ", " << NUM(y) << ", " << NUM(z) << ", " << NUM(id) << " },\n";
}
if (Companion::Instance->IsDebug()) {
write << fourSpaceTab << "// 0x" << std::hex << std::uppercase << (offset + (sizeof(MK64::ActorSpawnData) * spawns.size())) << "\n";
}
write << "};\n\n";
}
void MK64::SpawnDataBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto spawns = std::static_pointer_cast<SpawnDataData>(raw)->mSpawns;
auto writer = LUS::BinaryWriter();
WriteHeader(writer, LUS::ResourceType::SpawnData, 0);
writer.Write((uint32_t) spawns.size());
for(auto s : spawns) {
writer.Write(s.x);
writer.Write(s.y);
writer.Write(s.z);
writer.Write(s.id);
}
writer.Finish(write);
}
std::optional<std::shared_ptr<IParsedData>> MK64::SpawnDataFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto count = GetSafeNode<size_t>(node, "count");
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
LUS::BinaryReader reader(segment.data, count * sizeof(MK64::ActorSpawnData));
reader.SetEndianness(LUS::Endianness::Big);
std::vector<MK64::ActorSpawnData> spawns;
for(size_t i = 0; i < count; i++) {
auto x = reader.ReadInt16();
auto y = reader.ReadInt16();
auto z = reader.ReadInt16();
auto id = reader.ReadUInt16();
spawns.push_back(MK64::ActorSpawnData({
x, y, z, id
}));
}
return std::make_shared<SpawnDataData>(spawns);
}
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include "../BaseFactory.h"
namespace MK64 {
struct ActorSpawnData {
int16_t x;
int16_t y;
int16_t z;
uint16_t id;
};
class SpawnDataData : public IParsedData {
public:
std::vector<ActorSpawnData> mSpawns;
explicit SpawnDataData(std::vector<ActorSpawnData> spawns) : mSpawns(spawns) {}
};
class SpawnDataHeaderExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class SpawnDataBinaryExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class SpawnDataCodeExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class SpawnDataFactory : 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, SpawnDataCodeExporter)
REGISTER(Header, SpawnDataHeaderExporter)
REGISTER(Binary, SpawnDataBinaryExporter)
};
}
bool SupportModdedAssets() override { return false; }
};
}
+91
View File
@@ -0,0 +1,91 @@
#include "TrackSections.h"
#include "Companion.h"
#include "utils/Decompressor.h"
#define NUM(x) std::dec << std::setfill(' ') << std::setw(6) << x
#define COL(c) "0x" << std::hex << std::setw(2) << std::setfill('0') << c
void MK64::TrackSectionsHeaderExporter::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 TrackSections " << symbol << "[];\n";
}
void MK64::TrackSectionsCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto sections = std::static_pointer_cast<TrackSectionsData>(raw)->mSecs;
const auto symbol = GetSafeNode(node, "symbol", entryName);
const auto offset = GetSafeNode<uint32_t>(node, "offset");
if (Companion::Instance->IsDebug()) {
write << "// 0x" << std::hex << std::uppercase << offset << "\n";
}
write << "TrackSections " << symbol << "[] = {\n";
for (int i = 0; i < sections.size(); i++) {
auto entry = sections[i];
auto addr = entry.addr;
auto surf = entry.surfaceType;
auto sect = entry.sectionId;
auto flags = entry.flags;
if(i <= sections.size() - 1) {
write << fourSpaceTab;
}
// { addr, surface, section, flags },
write << "{" << NUM(addr) << ", " << NUM(surf) << ", " << NUM(sect) << ", " << NUM(flags) << "},\n";
}
if (Companion::Instance->IsDebug()) {
write << fourSpaceTab << "// 0x" << std::hex << std::uppercase << (offset + (sizeof(TrackSections) * sections.size())) << "\n";
}
write << "};\n\n";
}
void MK64::TrackSectionsBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) {
auto sections = std::static_pointer_cast<TrackSectionsData>(raw);
auto writer = LUS::BinaryWriter();
WriteHeader(writer, LUS::ResourceType::TrackSection, 0);
writer.Write((uint32_t) sections->mSecs.size());
for(auto entry : sections->mSecs) {
writer.Write(entry.addr);
writer.Write(entry.surfaceType);
writer.Write(entry.sectionId);
writer.Write(entry.flags);
}
writer.Finish(write);
}
std::optional<std::shared_ptr<IParsedData>> MK64::TrackSectionsFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto count = GetSafeNode<size_t>(node, "count");
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
LUS::BinaryReader reader(segment.data, count * sizeof(MK64::TrackSections));
reader.SetEndianness(LUS::Endianness::Big);
std::vector<MK64::TrackSections> sections;
for(size_t i = 0; i < count; i++) {
auto addr = reader.ReadUInt32();
auto surf = reader.ReadInt8();
auto sect = reader.ReadInt8();
auto flags = reader.ReadUInt16();
sections.push_back(MK64::TrackSections({
addr, surf, sect, flags,
}));
}
return std::make_shared<TrackSectionsData>(sections);
}
+49
View File
@@ -0,0 +1,49 @@
#pragma once
#include "../BaseFactory.h"
namespace MK64 {
struct TrackSections {
uint32_t addr;
uint8_t surfaceType;
uint8_t sectionId;
uint16_t flags;
};
class TrackSectionsData : public IParsedData {
public:
std::vector<TrackSections> mSecs;
explicit TrackSectionsData(std::vector<TrackSections> sections) : mSecs(sections) {}
};
class TrackSectionsHeaderExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class TrackSectionsBinaryExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class TrackSectionsCodeExporter : public BaseExporter {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class TrackSectionsFactory : 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, TrackSectionsCodeExporter)
REGISTER(Header, TrackSectionsHeaderExporter)
REGISTER(Binary, TrackSectionsBinaryExporter)
};
}
bool SupportModdedAssets() override { return false; }
};
}
@@ -1,4 +1,4 @@
#include "WaypointFactory.h"
#include "Waypoints.h"
#include "Companion.h"
#include "utils/Decompressor.h"
@@ -57,7 +57,7 @@ void MK64::WaypointBinaryExporter::Export(std::ostream &write, std::shared_ptr<I
writer.Finish(write);
}
std::optional<std::shared_ptr<IParsedData>> MK64::WaypointFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
std::optional<std::shared_ptr<IParsedData>> MK64::WaypointsFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
auto count = GetSafeNode<size_t>(node, "count");
auto [_, segment] = Decompressor::AutoDecode(node, buffer);
@@ -30,7 +30,7 @@ namespace MK64 {
void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
class WaypointFactory : public BaseFactory {
class WaypointsFactory : 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 {