diff options
Diffstat (limited to 'src/factories/DisplayListFactory.cpp')
| -rw-r--r-- | src/factories/DisplayListFactory.cpp | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/src/factories/DisplayListFactory.cpp b/src/factories/DisplayListFactory.cpp index 60344f6..144d666 100644 --- a/src/factories/DisplayListFactory.cpp +++ b/src/factories/DisplayListFactory.cpp @@ -4,6 +4,7 @@ #include "spdlog/spdlog.h" #include "Companion.h" #include <fstream> +#include <tuple> #include "n64/gbi-otr.h" #ifdef STANDALONE @@ -195,21 +196,32 @@ void DebugDisplayList(uint32_t w0, uint32_t w1) { #endif std::optional<std::tuple<std::string, YAML::Node>> SearchVtx(uint32_t ptr) { - auto decs = Companion::Instance->GetNodesByType("VTX"); - - if (!decs.has_value()) { + const auto* decs = Companion::Instance->GetNodesByTypeRef("VTX", Companion::Instance->GetConfig().includeAutogen); + if (decs == nullptr) { return std::nullopt; } - for (auto& dec : decs.value()) { - auto [name, node] = dec; + auto realAddr = ptr; + bool hasRealAddr = false; + if (IS_SEGMENTED(realAddr) && Companion::Instance->GetCompressedSegmentOffset(&realAddr)) { + hasRealAddr = true; + } + + for (const auto& dec : *decs) { + const auto& [name, node] = dec; - auto offset = GetSafeNode<uint32_t>(node, "offset"); - auto count = GetSafeNode<uint32_t>(node, "count"); + auto offset = GetSafeNode<uint32_t>(const_cast<YAML::Node&>(node), "offset"); + auto count = GetSafeNode<uint32_t>(const_cast<YAML::Node&>(node), "count"); auto end = ALIGN16((count * sizeof(N64Vtx_t))); - if (ptr > offset && ptr < offset + end) { - return std::make_tuple(GetSafeNode<std::string>(node, "symbol", name), node); + // ptr == offset just means the block's first vertex — still a valid hit. + // The old strict > missed it, and that's what spawned every bogus + // "_seg1_vtx_0" autogen. + if (ptr >= offset && ptr < offset + end) { + return std::make_tuple(GetSafeNode<std::string>(const_cast<YAML::Node&>(node), "symbol", name), node); + } + if (hasRealAddr && realAddr >= offset && realAddr < offset + end) { + return std::make_tuple(GetSafeNode<std::string>(const_cast<YAML::Node&>(node), "symbol", name), node); } } @@ -263,6 +275,14 @@ ExportResult DListBinaryExporter::Export(std::ostream& write, std::shared_ptr<IP auto ptr = Companion::Instance->PatchVirtualAddr(w1); auto overlap = GFXDOverride::GetVtxOverlap(ptr); + if (!overlap.has_value() && IS_SEGMENTED(ptr)) { + uint32_t flatPtr = ptr; + if (Companion::Instance->GetCompressedSegmentOffset(&flatPtr)) { + overlap = GFXDOverride::GetVtxOverlap(flatPtr); + if (overlap.has_value()) + ptr = flatPtr; + } + } if (overlap.has_value()) { auto ovnode = std::get<1>(overlap.value()); auto path = Companion::Instance->RelativePath(std::get<0>(overlap.value())); @@ -325,9 +345,15 @@ ExportResult DListBinaryExporter::Export(std::ostream& write, std::shared_ptr<IP auto branch = (w0 >> 16) & G_DL_NO_PUSH; // Export displaylist segment addresses as an index into a buffer of gfx - value = gsSPDisplayListOTRHash(ptr); - w0 = value.words.w0; - w1 = value.words.w1; + if ((Companion::Instance->GetGBIMinorVersion() == GBIMinorVersion::Mk64) && (SEGMENT_NUMBER(w1) == 0x07)) { + value = gsSPDisplayListOTRIndex(w1); + w0 = value.words.w0; + w1 = value.words.w1; + } else { + value = gsSPDisplayListOTRHash(ptr); + w0 = value.words.w0; + w1 = value.words.w1; + } writer.Write(w0); writer.Write(w1); @@ -413,6 +439,19 @@ ExportResult DListBinaryExporter::Export(std::ostream& write, std::shared_ptr<IP uint32_t newW0 = (G_SETTIMG_OTR_HASH << 24) | (w0 & 0x00FFFFFF); writer.Write(newW0); writer.Write(ptr); + } else if ((Companion::Instance->GetGBIMinorVersion() == GBIMinorVersion::Mk64) && + ((SEGMENT_NUMBER(w1) == 0x03) || (SEGMENT_NUMBER(w1) == 0x05))) { + // Export texture segment addresses as segmented addresses + w1 |= 1; + writer.Write(w0); + writer.Write(w1); + // Segment 4 and 0x0B-0x0F are BK64's runtime animated-texture slots. + // Nothing static to resolve, so the segmented address just passes through. + } else if ((Companion::Instance->GetGBIMinorVersion() == GBIMinorVersion::BK64) && + (SEGMENT_NUMBER(w1) == 0x04 || (SEGMENT_NUMBER(w1) >= 0x0B && SEGMENT_NUMBER(w1) <= 0x0F))) { + w1 |= 1; + writer.Write(w0); + writer.Write(w1); } else { // Export texture segment addresses as segmented addresses N64Gfx value = gsDPSetTextureOTRImage(C0(21, 3), C0(19, 2), C0(0, 10), ptr); @@ -592,6 +631,13 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint SPDLOG_INFO("Found vtx at 0x{:X} matching last vtx at 0x{:X}", adjPtr, lOffset); GFXDOverride::RegisterVTXOverlap(adjPtr, search.value()); } + + if (IS_SEGMENTED(adjPtr) && Companion::Instance->GetCompressedSegmentOffset(&adjPtr)) { + if (adjPtr > lOffset && adjPtr < lOffset + lSize) { + SPDLOG_INFO("Found vtx at 0x{:X} matching last vtx at 0x{:X}", adjPtr, lOffset); + GFXDOverride::RegisterVTXOverlap(adjPtr, search.value()); + } + } } else { YAML::Node vtx; vtx["type"] = "VTX"; @@ -600,7 +646,7 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint Companion::Instance->AddAsset(vtx); } } else { - SPDLOG_WARN("Found vtx at 0x{:X}", w1); + SPDLOG_INFO("Found registered vtx at 0x{:X}", w1); } } |
