summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiritoDv <kiritodev01@gmail.com>2024-03-26 00:11:46 -0600
committerKiritoDv <kiritodev01@gmail.com>2024-03-26 00:11:46 -0600
commiteb2dca9c14247da51a5fdac1f1e3f66cf0c660c4 (patch)
treeed7d203d728f66a2ad55b44087696bdda97874f5
parentaa22c0803efa346b7886e8c2d44a04eddb020b3c (diff)
Fixed geo layout factory bugs and some sm64 related stuff
-rw-r--r--src/Companion.cpp12
-rw-r--r--src/audio/AudioManager.cpp4
-rw-r--r--src/factories/AudioHeaderFactory.cpp2
-rw-r--r--src/factories/AudioHeaderFactory.h20
-rw-r--r--src/factories/DisplayListFactory.cpp116
-rw-r--r--src/factories/DisplayListOverrides.cpp29
-rw-r--r--src/factories/DisplayListOverrides.h3
-rw-r--r--src/factories/LightsFactory.cpp2
-rw-r--r--src/factories/VtxFactory.cpp2
-rw-r--r--src/factories/sm64/GeoLayoutFactory.cpp237
-rw-r--r--src/factories/sm64/GeoLayoutFactory.h11
11 files changed, 234 insertions, 204 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp
index b6d2605..225c4a1 100644
--- a/src/Companion.cpp
+++ b/src/Companion.cpp
@@ -1079,11 +1079,14 @@ std::optional<YAML::Node> Companion::AddAsset(YAML::Node asset) {
}
auto rom = this->GetRomData();
- auto factory = this->GetFactory(type)->get();
+ auto factory = this->GetFactory(type);
+
+ if(!factory.has_value()) {
+ return std::nullopt;
+ }
std::string output;
std::string typeId = ConvertType(type);
- int index;
if(symbol != "") {
output = symbol;
@@ -1095,10 +1098,11 @@ std::optional<YAML::Node> Companion::AddAsset(YAML::Node asset) {
asset["autogen"] = true;
asset["symbol"] = output;
- auto result = factory->parse(rom, asset);
+ auto result = this->RegisterAsset(output, asset);
if(result.has_value()){
- return std::get<1>(this->RegisterAsset(output, asset).value());
+ asset["path"] = std::get<0>(result.value());
+ return std::get<1>(result.value());
}
return std::nullopt;
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index c4b612c..686403d 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -655,13 +655,13 @@ void AudioManager::create_aifc(int32_t index, LUS::BinaryWriter &out) {
}
AudioBankSample AudioManager::get_aifc(int32_t index) {
- int32_t idx = -1;
+ int32_t idx = 0;
for(auto &sample_bank : this->loaded_tbl.banks){
auto offsets = PyUtils::keys(sample_bank->entries);
std::sort(offsets.begin(), offsets.end());
for(auto &offset : offsets){
- if(++idx == index){
+ if(idx++ == index){
return *sample_bank->entries[offset];
}
}
diff --git a/src/factories/AudioHeaderFactory.cpp b/src/factories/AudioHeaderFactory.cpp
index d1cceb5..1644a35 100644
--- a/src/factories/AudioHeaderFactory.cpp
+++ b/src/factories/AudioHeaderFactory.cpp
@@ -5,5 +5,5 @@
std::optional<std::shared_ptr<IParsedData>> AudioHeaderFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& data) {
AudioManager::Instance->initialize(buffer, data);
- return std::nullopt;
+ return std::make_shared<IParsedData>();
} \ No newline at end of file
diff --git a/src/factories/AudioHeaderFactory.h b/src/factories/AudioHeaderFactory.h
index 5372eb5..ce61413 100644
--- a/src/factories/AudioHeaderFactory.h
+++ b/src/factories/AudioHeaderFactory.h
@@ -2,10 +2,26 @@
#include "BaseFactory.h"
+class AudioDummyExporter : public BaseExporter {
+public:
+ ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override {
+ return std::nullopt;
+ }
+};
+
class AudioHeaderFactory : public BaseFactory {
public:
std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override;
- inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
- return {};
+ std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override {
+ return std::nullopt;
+ }
+ std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override {
+ return {
+ REGISTER(Modding, AudioDummyExporter)
+ REGISTER(Header, AudioDummyExporter)
+ REGISTER(Binary, AudioDummyExporter)
+ REGISTER(Code, AudioDummyExporter)
+ };
}
+ bool SupportModdedAssets() override { return true; }
}; \ No newline at end of file
diff --git a/src/factories/DisplayListFactory.cpp b/src/factories/DisplayListFactory.cpp
index b83ea75..b5d71dd 100644
--- a/src/factories/DisplayListFactory.cpp
+++ b/src/factories/DisplayListFactory.cpp
@@ -111,7 +111,8 @@ ExportResult DListCodeExporter::Export(std::ostream &write, std::shared_ptr<IPar
gfxd_timg_callback(GFXDOverride::Texture);
gfxd_dl_callback(GFXDOverride::DisplayList);
gfxd_tlut_callback(GFXDOverride::Palette);
- gfxd_lightsn_callback(GFXDOverride::Light);
+ gfxd_lightsn_callback(GFXDOverride::Lights);
+ gfxd_light_callback(GFXDOverride::Light);
GFXDSetGBIVersion();
gfxd_puts(("Gfx " + symbol + "[] = {\n").c_str());
@@ -123,6 +124,8 @@ ExportResult DListCodeExporter::Export(std::ostream &write, std::shared_ptr<IPar
if (Companion::Instance->IsDebug()) {
write << "// count: " << std::to_string(sz / 8) << " Gfx\n";
+ } else {
+ write << "\n";
}
return offset + sz;
@@ -318,64 +321,28 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
processing = false;
}
- if(const auto decl = Companion::Instance->GetNodeByAddr(w1); !decl.has_value()){
- SPDLOG_INFO("Addr to Display list command at 0x{:X} not in yaml, autogenerating it", w1);
-
- auto rom = Companion::Instance->GetRomData();
- auto factory = Companion::Instance->GetFactory("GFX")->get();
-
- std::string output;
- YAML::Node dl;
- uint32_t ptr = w1;
-
- if(Decompressor::IsSegmented(w1)){
- SPDLOG_INFO("Found segmented display list at 0x{:X}", w1);
- output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(ptr)) +"_dl_" + Torch::to_hex(SEGMENT_OFFSET(ptr), false));
- } else {
- SPDLOG_INFO("Found display list at 0x{:X}", ptr);
- output = Companion::Instance->NormalizeAsset("dl_" + Torch::to_hex(ptr, false));
- }
-
- dl["type"] = "GFX";
- dl["offset"] = ptr;
- dl["symbol"] = output;
- dl["autogen"] = true;
-
- auto result = factory->parse(rom, dl);
-
- if(!result.has_value()){
- continue;
- }
-
- Companion::Instance->RegisterAsset(output, dl);
- } else {
- SPDLOG_WARN("Could not find display list at 0x{:X}", w1);
- }
+ YAML::Node gfx;
+ gfx["type"] = "GFX";
+ gfx["offset"] = w1;
+ Companion::Instance->AddAsset(gfx);
}
// This opcode is generally used as part of multiple macros such as gsSPSetLights1.
// We need to process gsSPLight which is a subcommand inside G_MOVEMEM (0x03).
if(opcode == GBI(G_MOVEMEM)) {
// 0x03860000 or 0x03880000 subcommand will contain 0x86/0x88 for G_MV_L0 and G_MV_L1. Other subcommands also exist.
- uint8_t subcommand = (w0 >> 16) & 0xFF;
+ uint8_t subcommand = (w0 >> 16) & 0xFF;
uint8_t index = 0;
uint8_t offset = 0;
bool light = false;
switch (Companion::Instance->GetGBIVersion()) {
- case GBIVersion::f3d:
- index = C0(16, 8);
-
- if(index == GBI(G_MV_L0) || index == GBI(G_MV_L1)) {
- light = true;
- }
-
- break;
// If needing light generation on G_MV_L0 then we'll need to walk the DL ptr forward/backward to check for 0xBC
// Otherwise mk64 will break.
+ // PD: Mega, this works for sm64 too, why you didn't implement it? >:(
+ // PD: Im jk, <3
+ case GBIVersion::f3d:
case GBIVersion::f3dex:
- offset = w1;
-
/*
* Only generate lights on the second gsSPLight.
* gsSPSetLights1(name) outputs three macros:
@@ -397,34 +364,11 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
break;
}
- if(const auto decl = Companion::Instance->GetNodeByAddr(w1); !decl.has_value() && light){
- SPDLOG_INFO("Addr to Lights1 command at 0x{:X} not in yaml, autogenerating it", w1);
- auto rom = Companion::Instance->GetRomData();
- auto factory = Companion::Instance->GetFactory("LIGHTS")->get();
-
- std::string output;
- YAML::Node light;
- uint32_t ptr = w1;
-
- if(Decompressor::IsSegmented(w1)){
- SPDLOG_INFO("Found segmented lights at 0x{:X}", w1);
- ptr = w1;
- output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_lights1_" + Torch::to_hex(SEGMENT_OFFSET(ptr), false));
- } else {
- SPDLOG_INFO("Found lights at 0x{:X}", ptr);
- output = Companion::Instance->NormalizeAsset("lights1_" + Torch::to_hex(w1, false));
- }
-
- light["type"] = "lights";
- light["offset"] = ptr;
- light["symbol"] = output;
- light["autogen"] = true;
- auto result = factory->parse(rom, light);
- if(result.has_value()){
- Companion::Instance->RegisterAsset(output, light);
- }
- } else {
- SPDLOG_WARN("Could not find lights at 0x{:X}", w1);
+ if(light){
+ YAML::Node lnode;
+ lnode["type"] = "LIGHTS";
+ lnode["offset"] = w1;
+ Companion::Instance->AddAsset(lnode);
}
}
@@ -462,33 +406,11 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint
GFXDOverride::RegisterVTXOverlap(w1, search.value());
}
} else {
- SPDLOG_INFO("Addr to Vtx array at 0x{:X} not in yaml, autogenerating it", w1);
-
- auto ptr = w1;
- auto rom = Companion::Instance->GetRomData();
- auto factory = Companion::Instance->GetFactory("VTX")->get();
-
- std::string output;
YAML::Node vtx;
-
- if(Decompressor::IsSegmented(w1)){
- SPDLOG_INFO("Creating segmented vtx from 0x{:X}", ptr);
- ptr = w1;
- output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_vtx_" + Torch::to_hex(SEGMENT_OFFSET(ptr), false));
- } else {
- SPDLOG_INFO("Creating vtx from 0x{:X}", ptr);
- output = Companion::Instance->NormalizeAsset("vtx_" + Torch::to_hex(w1, false));
- }
-
vtx["type"] = "VTX";
- vtx["offset"] = ptr;
+ vtx["offset"] = w1;
vtx["count"] = nvtx;
- vtx["symbol"] = output;
- vtx["autogen"] = true;
- auto result = factory->parse(rom, vtx);
- if(result.has_value()){
- Companion::Instance->RegisterAsset(output, vtx);
- }
+ Companion::Instance->AddAsset(vtx);
}
} else {
SPDLOG_WARN("Found vtx at 0x{:X}", w1);
diff --git a/src/factories/DisplayListOverrides.cpp b/src/factories/DisplayListOverrides.cpp
index 32c9b5c..4e7d1a7 100644
--- a/src/factories/DisplayListOverrides.cpp
+++ b/src/factories/DisplayListOverrides.cpp
@@ -112,17 +112,42 @@ int Palette(uint32_t ptr, int32_t idx, int32_t count) {
return 0;
}
-int Light(uint32_t ptr, int32_t count) {
+int Lights(uint32_t ptr, int32_t count) {
auto dec = Companion::Instance->GetNodeByAddr(ptr);
if(dec.has_value()){
auto node = std::get<1>(dec.value());
auto symbol = GetSafeNode<std::string>(node, "symbol");
- SPDLOG_INFO("Found Light: 0x{:X} Symbol: {}", ptr, symbol);
+ SPDLOG_INFO("Found Lightsn: 0x{:X} Symbol: {}", ptr, symbol);
gfxd_puts(symbol.c_str());
return 1;
}
+ SPDLOG_WARN("Could not find lights at 0x{:X}", ptr);
+ return 0;
+}
+
+int Light(uint32_t ptr) {
+ auto res = Companion::Instance->GetNodeByAddr(ptr);
+
+ if(res.has_value()){
+ auto node = std::get<1>(res.value());
+ auto symbol = GetSafeNode<std::string>(node, "symbol");
+ SPDLOG_INFO("Found Light A Ptr: 0x{:X} Symbol: {}", ptr, symbol);
+ gfxd_puts(("&" + symbol + ".a").c_str());
+ return 1;
+ }
+
+ res = Companion::Instance->GetNodeByAddr(ptr - 0x8);
+
+ if(res.has_value()){
+ auto node = std::get<1>(res.value());
+ auto symbol = GetSafeNode<std::string>(node, "symbol");
+ SPDLOG_INFO("Found Light L Ptr: 0x{:X} Symbol: {}", ptr, symbol);
+ gfxd_puts(("&" + symbol + ".l").c_str());
+ return 1;
+ }
+
SPDLOG_WARN("Could not find light at 0x{:X}", ptr);
return 0;
}
diff --git a/src/factories/DisplayListOverrides.h b/src/factories/DisplayListOverrides.h
index 2da6c52..5b938c1 100644
--- a/src/factories/DisplayListOverrides.h
+++ b/src/factories/DisplayListOverrides.h
@@ -42,7 +42,8 @@ void Triangle2(const Gfx* gfx);
int Vtx(uint32_t vtx, int32_t num);
int Texture(uint32_t timg, int32_t fmt, int32_t siz, int32_t width, int32_t height, int32_t pal);
int Palette(uint32_t tlut, int32_t idx, int32_t count);
-int Light(uint32_t lightsn, int32_t count);
+int Lights(uint32_t lightsn, int32_t count);
+int Light(uint32_t light);
int DisplayList(uint32_t dl);
void RegisterVTXOverlap(uint32_t ptr, std::tuple<std::string, YAML::Node>& vtx);
std::optional<std::tuple<std::string, YAML::Node>> GetVtxOverlap(uint32_t ptr);
diff --git a/src/factories/LightsFactory.cpp b/src/factories/LightsFactory.cpp
index a26a17a..b1cd91e 100644
--- a/src/factories/LightsFactory.cpp
+++ b/src/factories/LightsFactory.cpp
@@ -20,7 +20,7 @@ ExportResult LightsCodeExporter::Export(std::ostream &write, std::shared_ptr<IPa
auto light = std::static_pointer_cast<LightsData>(raw)->mLights;
auto symbol = GetSafeNode(node, "symbol", entryName);
- write << "Lights1 " << symbol << " = gdSPDefLights1 (\n";
+ write << "Lights1 " << symbol << " = gdSPDefLights1(\n";
// Ambient
auto r = (int16_t) light.a.l.col[0];
diff --git a/src/factories/VtxFactory.cpp b/src/factories/VtxFactory.cpp
index 928f1c7..d09e23f 100644
--- a/src/factories/VtxFactory.cpp
+++ b/src/factories/VtxFactory.cpp
@@ -55,6 +55,8 @@ ExportResult VtxCodeExporter::Export(std::ostream &write, std::shared_ptr<IParse
if (Companion::Instance->IsDebug()) {
write << "// count: " << std::to_string(vtx.size()) << " Vtxs\n";
+ } else {
+ write << "\n";
}
return offset + vtx.size() * sizeof(VtxRaw);
diff --git a/src/factories/sm64/GeoLayoutFactory.cpp b/src/factories/sm64/GeoLayoutFactory.cpp
index 5f23254..3a0e524 100644
--- a/src/factories/sm64/GeoLayoutFactory.cpp
+++ b/src/factories/sm64/GeoLayoutFactory.cpp
@@ -6,85 +6,136 @@
#include "geo/GeoUtils.h"
#include "utils/TorchUtils.h"
-uint64_t RegisterOrLoadGeoLayout(uint32_t ptr) {
-
- auto dec = Companion::Instance->GetNodeByAddr(Torch::translate(ptr));
- if(dec.has_value()){
- uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
- SPDLOG_INFO("Found Geo Layout: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
- return hash;
- }
-
- SPDLOG_INFO("Addr to Geo Layout at 0x{:X} not in yaml, autogenerating it", ptr);
- auto addr = Companion::Instance->GetFileOffsetFromSegmentedAddr(SEGMENT_NUMBER(ptr));
- if(!addr.has_value()) {
- SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(ptr));
- return 0;
+uint64_t RegisterAutoGen(uint32_t ptr, std::string type) {
+ if(!Companion::Instance->IsOTRMode()) {
+ return ptr;
}
- auto rom = Companion::Instance->GetRomData();
- auto factory = Companion::Instance->GetFactory("SM64:GEO_LAYOUT")->get();
- std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(ptr)) +"_geo_" + Torch::to_hex(ptr, false));
- YAML::Node dl;
- dl["type"] = "SM64:GEO_LAYOUT";
- dl["offset"] = ptr;
- dl["symbol"] = output;
- auto result = factory->parse(rom, dl);
-
- if(!result.has_value()){
- return 0;
- }
-
- auto ndec = Companion::Instance->RegisterAsset(output, dl);
+ YAML::Node node;
+ node["type"] = type;
+ node["offset"] = ptr;
+ const auto result = Companion::Instance->AddAsset(node);
- if(ndec.has_value()){
- uint64_t hash = CRC64(std::get<0>(ndec.value()).c_str());
- SPDLOG_INFO("Found Geo Layout: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(ndec.value()));
+ if(result.has_value()){
+ auto path = GetSafeNode<std::string>(node, "path");
+ uint64_t hash = CRC64(path.c_str());
+ SPDLOG_INFO("Found {}: 0x{:X} Hash: 0x{:X} Path: {}", type, ptr, hash, path);
return hash;
}
return 0;
}
-uint64_t RegisterOrLoadDisplayList(uint32_t ptr) {
+ExportResult SM64::GeoCodeExporter::Export(std::ostream&write, std::shared_ptr<IParsedData> data, std::string&entryName, YAML::Node&node, std::string* replacement) {
+ const auto cmds = std::static_pointer_cast<GeoLayout>(data)->commands;
+ const auto symbol = GetSafeNode(node, "symbol", entryName);
+ auto offset = GetSafeNode<uint32_t>(node, "offset");
+ size_t size = 0;
+ uint32_t indentCount = 1;
+ uint32_t cmdCount = 0;
- auto dec = Companion::Instance->GetNodeByAddr(Torch::translate(ptr));
- if(dec.has_value()){
- uint64_t hash = CRC64(std::get<0>(dec.value()).c_str());
- SPDLOG_INFO("Found Display List: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(dec.value()));
- return hash;
- }
+ write << "GeoLayout " << symbol << "[] = {\n";
- SPDLOG_INFO("Addr to Display List at 0x{:X} not in yaml, autogenerating it", ptr);
- auto addr = Companion::Instance->GetFileOffsetFromSegmentedAddr(SEGMENT_NUMBER(ptr));
- if(!addr.has_value()) {
- SPDLOG_ERROR("Segment data missing from game config\nPlease add an entry for segment {}", SEGMENT_NUMBER(ptr));
- return 0;
- }
+ for(auto& [opcode, arguments] : cmds) {
+ bool commaFlag = false;
+
+ for (uint32_t i = 0; i < indentCount; ++i) {
+ write << fourSpaceTab;
+ }
+
+ if (opcode == GeoOpcode::CloseNode) {
+ --indentCount;
+ } else if (opcode == GeoOpcode::OpenNode) {
+ ++indentCount;
+ }
+
+ write << opcode << "(";
+ for(auto& args : arguments) {
+ if (commaFlag) {
+ write << ", ";
+ } else {
+ commaFlag = true;
+ }
- auto rom = Companion::Instance->GetRomData();
- auto factory = Companion::Instance->GetFactory("GFX")->get();
- std::string output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(ptr)) +"_dl_" + Torch::to_hex(ptr, false));
- YAML::Node dl;
- dl["type"] = "GFX";
- dl["mio0"] = addr.value();
- dl["offset"] = SEGMENT_OFFSET(ptr);
- dl["symbol"] = output;
- auto result = factory->parse(rom, dl);
-
- if(!result.has_value()){
- return 0;
+ switch(static_cast<GeoArgumentType>(args.index())) {
+ case GeoArgumentType::U8: {
+ write << static_cast<uint32_t>(std::get<uint8_t>(args));
+ break;
+ }
+ case GeoArgumentType::S8: {
+ write << static_cast<uint32_t>(std::get<int8_t>(args));
+ break;
+ }
+ case GeoArgumentType::U16: {
+ write << std::get<uint16_t>(args);
+ break;
+ }
+ case GeoArgumentType::S16: {
+ write << std::get<int16_t>(args);
+ break;
+ }
+ case GeoArgumentType::U32: {
+ write << "0x" << std::hex << std::get<uint32_t>(args);
+ break;
+ }
+ case GeoArgumentType::S32: {
+ write << std::get<int32_t>(args);
+ break;
+ }
+ case GeoArgumentType::U64: {
+ write << "0x" << std::hex << std::get<uint64_t>(args);
+ break;
+ }
+ case GeoArgumentType::VEC2F: {
+ const auto [x, y] = std::get<Vec2f>(args);
+ write << x << ", " << y;
+ break;
+ }
+ case GeoArgumentType::VEC3F: {
+ const auto [x, y, z] = std::get<Vec3f>(args);
+ write << x << ", " << y << ", " << z;
+ break;
+ }
+ case GeoArgumentType::VEC3S: {
+ const auto [x, y, z] = std::get<Vec3s>(args);
+ write << x << ", " << y << ", " << z;
+ break;
+ }
+ case GeoArgumentType::VEC3I: {
+ const auto [x, y, z] = std::get<Vec3i>(args);
+ write << x << ", " << y << ", " << z;
+ break;
+ }
+ case GeoArgumentType::VEC4F: {
+ const auto [x, y, z, w] = std::get<Vec4f>(args);
+ write << x << ", " << y << ", " << z << ", " << w;
+ break;
+ }
+ case GeoArgumentType::VEC4S: {
+ const auto [x, y, z, w] = std::get<Vec4s>(args);
+ write << x << ", " << y << ", " << z << ", " << w;
+ break;
+ }
+ case GeoArgumentType::STRING: {
+ write << std::get<std::string>(args);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ write << "),\n";
+ ++cmdCount;
}
- auto ndec = Companion::Instance->RegisterAsset(output, dl);
+ write << "};\n";
- if(ndec.has_value()){
- uint64_t hash = CRC64(std::get<0>(ndec.value()).c_str());
- SPDLOG_INFO("Found Display List: 0x{:X} Hash: 0x{:X} Path: {}", ptr, hash, std::get<0>(ndec.value()));
- return hash;
+ if (Companion::Instance->IsDebug()) {
+ write << "// count: " << std::to_string(cmdCount) << " GeoLayout\n";
}
- return 0;
+ return offset + size;
}
ExportResult SM64::GeoBinaryExporter::Export(std::ostream&write, std::shared_ptr<IParsedData> data, std::string&entryName, YAML::Node&node, std::string* replacement) {
@@ -96,63 +147,63 @@ ExportResult SM64::GeoBinaryExporter::Export(std::ostream&write, std::shared_ptr
writer.Write(static_cast<uint8_t>(opcode));
for(auto& args : arguments) {
- switch(args.index()) {
- case 0: {
+ switch(static_cast<GeoArgumentType>(args.index())) {
+ case GeoArgumentType::U8: {
writer.Write(std::get<uint8_t>(args));
break;
}
- case 1: {
+ case GeoArgumentType::S8: {
writer.Write(std::get<int8_t>(args));
break;
}
- case 2: {
+ case GeoArgumentType::U16: {
writer.Write(std::get<uint16_t>(args));
break;
}
- case 3: {
+ case GeoArgumentType::S16: {
writer.Write(std::get<int16_t>(args));
break;
}
- case 4: {
+ case GeoArgumentType::U32: {
writer.Write(std::get<uint32_t>(args));
break;
}
- case 5: {
+ case GeoArgumentType::S32: {
writer.Write(std::get<int32_t>(args));
break;
}
- case 6: {
+ case GeoArgumentType::U64: {
writer.Write(std::get<uint64_t>(args));
break;
}
- case 7: {
+ case GeoArgumentType::VEC2F: {
const auto [x, y] = std::get<Vec2f>(args);
writer.Write(x);
writer.Write(y);
break;
}
- case 8: {
+ case GeoArgumentType::VEC3F: {
const auto [x, y, z] = std::get<Vec3f>(args);
writer.Write(x);
writer.Write(y);
writer.Write(z);
break;
}
- case 9: {
+ case GeoArgumentType::VEC3S: {
const auto [x, y, z] = std::get<Vec3s>(args);
writer.Write(x);
writer.Write(y);
writer.Write(z);
break;
}
- case 10: {
+ case GeoArgumentType::VEC3I: {
const auto [x, y, z] = std::get<Vec3i>(args);
writer.Write(x);
writer.Write(y);
writer.Write(z);
break;
}
- case 11: {
+ case GeoArgumentType::VEC4F: {
const auto [x, y, z, w] = std::get<Vec4f>(args);
writer.Write(x);
writer.Write(y);
@@ -160,7 +211,7 @@ ExportResult SM64::GeoBinaryExporter::Export(std::ostream&write, std::shared_ptr
writer.Write(w);
break;
}
- case 12: {
+ case GeoArgumentType::VEC4S: {
const auto [x, y, z, w] = std::get<Vec4s>(args);
writer.Write(x);
writer.Write(y);
@@ -193,8 +244,9 @@ ExportResult SM64::GeoHeaderExporter::Export(std::ostream&write, std::shared_ptr
}
std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) {
- const size_t offset = Torch::translate(GetSafeNode<uint32_t>(node, "offset"));
- auto cmd = buffer.data() + offset;
+ auto [_, segment] = Decompressor::AutoDecode(node, buffer);
+ auto cmd = segment.data;
+
bool processing = true;
std::vector<GeoCommand> commands;
@@ -207,9 +259,8 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
switch(opcode){
case GeoOpcode::BranchAndLink: {
- uint32_t ptr = cur_geo_cmd_u32(0x04);
- arguments.emplace_back(ptr);
- arguments.emplace_back(RegisterOrLoadGeoLayout(ptr));
+ auto ptr = cur_geo_cmd_u32(0x04);
+ arguments.emplace_back(RegisterAutoGen(ptr, "SM64:GEO_LAYOUT"));
cmd += 0x08 << CMD_SIZE_SHIFT;
break;
@@ -223,7 +274,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
auto ptr = cur_geo_cmd_u32(0x04);
arguments.emplace_back(jmp);
- arguments.emplace_back(RegisterOrLoadGeoLayout(ptr));
+ arguments.emplace_back(RegisterAutoGen(ptr, "SM64:GEO_LAYOUT"));
cmd += 0x08 << CMD_SIZE_SHIFT;
break;
@@ -350,7 +401,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
Vec3s translation = {};
Vec3s rotation = {};
auto params = cur_geo_cmd_u8(0x01);
- auto cmd_pos = reinterpret_cast<int16_t *>(&cmd[0x04]);
+ auto cmd_pos = reinterpret_cast<int16_t *>(cmd);
arguments.emplace_back(params);
@@ -371,7 +422,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
break;
case 3:
arguments.emplace_back(cmd_pos[1]);
- cmd_pos += 2 << CMD_SIZE_SHIFT;
+ cmd_pos += 0x04 << CMD_SIZE_SHIFT;
break;
default: {
break;
@@ -380,7 +431,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
if (params & 0x80) {
auto ptr = BSWAP32(*reinterpret_cast<uint32_t*>(&cmd_pos[0]));
- arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
+ arguments.emplace_back(RegisterAutoGen(ptr, "GFX"));
cmd_pos += 2 << CMD_SIZE_SHIFT;
}
@@ -401,7 +452,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
if (params & 0x80) {
auto ptr = BSWAP32(*reinterpret_cast<uint32_t*>(&cmd_pos[0]));
- arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
+ arguments.emplace_back(RegisterAutoGen(ptr, "GFX"));
cmd_pos += 2 << CMD_SIZE_SHIFT;
}
@@ -416,7 +467,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
auto cmd_pos = reinterpret_cast<int16_t*>(cmd);
arguments.emplace_back(layer);
- arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
+ arguments.emplace_back(RegisterAutoGen(ptr, "GFX"));
read_vec3s(translation, &cmd_pos[1]);
arguments.emplace_back(translation);
@@ -430,14 +481,14 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
auto params = cur_geo_cmd_u8(0x01);
auto cmd_pos = reinterpret_cast<int16_t*>(cmd);
- read_vec3s(translation, &cmd_pos[1]);
+ cmd_pos = read_vec3s(translation, &cmd_pos[1]);
arguments.emplace_back(params);
arguments.emplace_back(translation);
if (params & 0x80) {
auto ptr = BSWAP32(*reinterpret_cast<uint32_t*>(&cmd_pos[0]));
- arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
+ arguments.emplace_back(RegisterAutoGen(ptr, "GFX"));
cmd_pos += 0x02 << CMD_SIZE_SHIFT;
}
@@ -449,7 +500,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
auto ptr = cur_geo_cmd_u32(0x04);
arguments.emplace_back(layer);
- arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
+ arguments.emplace_back(RegisterAutoGen(ptr, "GFX"));
cmd += 0x08 << CMD_SIZE_SHIFT;
break;
@@ -527,7 +578,7 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
if (params & 0x80) {
auto ptr = cur_geo_cmd_u32(0x08);
- arguments.emplace_back(RegisterOrLoadDisplayList(ptr));
+ arguments.emplace_back(RegisterAutoGen(ptr, "GFX"));
cmd += 0x04 << CMD_SIZE_SHIFT;
}
@@ -551,8 +602,8 @@ std::optional<std::shared_ptr<IParsedData>> SM64::GeoLayoutFactory::parse(std::v
break;
}
default: {
- SPDLOG_ERROR("Unknown geo command {}", opcode);
- throw std::runtime_error("Unknown geo command");
+ SPDLOG_ERROR("Unknown geo command '{}'", opcode);
+ throw std::runtime_error("Unknown geo command " + std::to_string(static_cast<uint8_t>(opcode)));
}
}
diff --git a/src/factories/sm64/GeoLayoutFactory.h b/src/factories/sm64/GeoLayoutFactory.h
index e769b64..2cc7120 100644
--- a/src/factories/sm64/GeoLayoutFactory.h
+++ b/src/factories/sm64/GeoLayoutFactory.h
@@ -5,7 +5,11 @@
#include <vector>
#include <variant>
-typedef std::variant<uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, Vec2f, Vec3f, Vec3s, Vec3i, Vec4f, Vec4s> GeoArgument;
+typedef std::variant<uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, Vec2f, Vec3f, Vec3s, Vec3i, Vec4f, Vec4s, std::string> GeoArgument;
+
+enum class GeoArgumentType {
+ U8, S8, U16, S16, U32, S32, U64, VEC2F, VEC3F, VEC3S, VEC3I, VEC4F, VEC4S, STRING
+};
namespace SM64 {
@@ -21,6 +25,10 @@ public:
explicit GeoLayout(std::vector<GeoCommand> commands) : commands(std::move(commands)) {}
};
+class GeoCodeExporter : public BaseExporter {
+ ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
+};
+
class GeoHeaderExporter : public BaseExporter {
ExportResult Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override;
};
@@ -36,6 +44,7 @@ public:
return {
REGISTER(Header, GeoHeaderExporter)
REGISTER(Binary, GeoBinaryExporter)
+ REGISTER(Code, GeoCodeExporter)
};
}
};