From 5d4bd639dfdffcf26edb458485beee1b81b92531 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Sat, 9 Mar 2024 23:12:39 -0600 Subject: Refactored vtx overlap function --- src/factories/DisplayListFactory.cpp | 87 ++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 23 deletions(-) (limited to 'src/factories/DisplayListFactory.cpp') diff --git a/src/factories/DisplayListFactory.cpp b/src/factories/DisplayListFactory.cpp index 59e0321..2310588 100644 --- a/src/factories/DisplayListFactory.cpp +++ b/src/factories/DisplayListFactory.cpp @@ -9,6 +9,7 @@ #include "n64/gbi-otr.h" #define C0(pos, width) ((w0 >> (pos)) & ((1U << width) - 1)) +#define ALIGN16(val) (((val) + 0xF) & ~0xF) std::unordered_map gF3DTable = { { "G_VTX", 0x04 }, @@ -159,6 +160,28 @@ void DebugDisplayList(uint32_t w0, uint32_t w1){ gfxd_execute(); } +std::optional> SearchVtx(uint32_t ptr){ + auto decs = Companion::Instance->GetNodesByType("VTX"); + + if(!decs.has_value()){ + return std::nullopt; + } + + for(auto& dec : decs.value()){ + auto [name, node] = dec; + + auto offset = GetSafeNode(node, "offset"); + auto count = GetSafeNode(node, "count"); + auto end = ALIGN16((count * sizeof(Vtx_t))); + + if(ptr > offset && ptr <= offset + end){ + return std::make_tuple(GetSafeNode(node, "symbol", name), node); + } + } + + return std::nullopt; +} + void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto cmds = std::static_pointer_cast(raw)->mGfxs; auto writer = LUS::BinaryWriter(); @@ -400,39 +423,57 @@ std::optional> DListFactory::parse(std::vectorGetNodeByAddr(w1); - if(const auto decl = Companion::Instance->GetNodeByAddr(w1); !decl.has_value()){ - SPDLOG_INFO("Addr to Vtx array at 0x{:X} not in yaml, autogenerating it", w1); + if(!decl.has_value()){ + auto search = SearchVtx(w1); - auto ptr = w1; - auto rom = Companion::Instance->GetRomData(); - auto factory = Companion::Instance->GetFactory("VTX")->get(); + if(search.has_value()){ + auto [path, vtx] = search.value(); - std::string output; - YAML::Node vtx; + SPDLOG_INFO("Path: {}", path); - if(Decompressor::IsSegmented(w1)){ - SPDLOG_INFO("Found segmented vtx at 0x{:X}", ptr); - ptr = w1; - output = Companion::Instance->NormalizeAsset("seg" + std::to_string(SEGMENT_NUMBER(w1)) +"_vtx_" + Torch::to_hex(SEGMENT_OFFSET(ptr), false)); + auto lOffset = GetSafeNode(vtx, "offset"); + auto lCount = GetSafeNode(vtx, "count"); + auto lSize = ALIGN16(lCount * sizeof(Vtx_t)); + + if(w1 > lOffset && w1 <= lOffset + lSize){ + SPDLOG_INFO("Found vtx at 0x{:X} matching last vtx at 0x{:X}", w1, lOffset); + GFXDOverride::RegisterVTXOverlap(w1, search.value()); + } } else { - SPDLOG_INFO("Found vtx at 0x{:X}", ptr); - output = Companion::Instance->NormalizeAsset("vtx_" + Torch::to_hex(w1, false)); - } + 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["count"] = nvtx; - vtx["symbol"] = output; - auto result = factory->parse(rom, vtx); - if(result.has_value()){ - Companion::Instance->RegisterAsset(output, vtx); + vtx["type"] = "VTX"; + vtx["offset"] = ptr; + vtx["count"] = nvtx; + vtx["symbol"] = output; + auto result = factory->parse(rom, vtx); + if(result.has_value()){ + Companion::Instance->RegisterAsset(output, vtx); + } } } else { - SPDLOG_WARN("Could not find vtx at 0x{:X}", w1); + SPDLOG_WARN("Found vtx at 0x{:X}", w1); } } -- cgit v1.2.3