diff options
| author | KiritoDv <kiritodev01@gmail.com> | 2024-03-09 23:12:39 -0600 |
|---|---|---|
| committer | Lywx <kiritodev01@gmail.com> | 2024-03-10 15:58:45 -0600 |
| commit | 5d4bd639dfdffcf26edb458485beee1b81b92531 (patch) | |
| tree | 7495a81317f88140bce0c55c7c3cc3ec7c195b58 /src | |
| parent | c4bb1ad8ee74a2ae4659926717ed7de9ee1e0c69 (diff) | |
Refactored vtx overlap function
Diffstat (limited to 'src')
| -rw-r--r-- | src/Companion.cpp | 21 | ||||
| -rw-r--r-- | src/Companion.h | 1 | ||||
| -rw-r--r-- | src/factories/DisplayListFactory.cpp | 87 | ||||
| -rw-r--r-- | src/factories/DisplayListFactory.h | 1 | ||||
| -rw-r--r-- | src/factories/DisplayListOverrides.cpp | 41 | ||||
| -rw-r--r-- | src/factories/DisplayListOverrides.h | 8 |
6 files changed, 135 insertions, 24 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp index 441f596..81044b3 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -14,6 +14,7 @@ #include "factories/VtxFactory.h" #include "factories/TextureFactory.h" #include "factories/DisplayListFactory.h" +#include "factories/DisplayListOverrides.h" #include "factories/BlobFactory.h" #include "factories/LightsFactory.h" #include "factories/mk64/CourseVtx.h" @@ -482,6 +483,7 @@ void Companion::Process() { this->gConfig.segment.local.clear(); this->gFileHeader.clear(); this->gCurrentPad = 0; + GFXDOverride::ClearVtx(); if(root[":config"]) { this->ParseCurrentFileConfig(root[":config"]); @@ -783,6 +785,25 @@ std::optional<std::tuple<std::string, YAML::Node>> Companion::GetNodeByAddr(cons return this->gAddrMap[this->gCurrentFile][addr]; } +std::optional<std::vector<std::tuple<std::string, YAML::Node>>> Companion::GetNodesByType(const std::string& type){ + std::vector<std::tuple<std::string, YAML::Node>> nodes; + + if(!this->gAddrMap.contains(this->gCurrentFile)){ + return nodes; + } + + for(auto& [addr, tpl] : this->gAddrMap[this->gCurrentFile]){ + auto [name, node] = tpl; + const auto n_type = GetSafeNode<std::string>(node, "type"); + if(n_type == type){ + nodes.push_back(tpl); + } + } + + return nodes; + +} + std::string Companion::NormalizeAsset(const std::string& name) const { auto path = fs::path(this->gCurrentFile).stem().string() + "_" + name; return path; diff --git a/src/Companion.h b/src/Companion.h index fbde351..8f8f98c 100644 --- a/src/Companion.h +++ b/src/Companion.h @@ -76,6 +76,7 @@ public: std::optional<std::uint32_t> GetFileOffsetFromSegmentedAddr(uint8_t segment) const; std::optional<std::tuple<std::string, YAML::Node>> GetNodeByAddr(uint32_t addr); std::optional<std::shared_ptr<BaseFactory>> GetFactory(const std::string& type); + std::optional<std::vector<std::tuple<std::string, YAML::Node>>> GetNodesByType(const std::string& type); std::optional<std::uint32_t> GetFileOffset(void) const { return this->gCurrentFileOffset; }; std::optional<std::uint32_t> GetCurrSegmentNumber(void) const { return this->gCurrentSegmentNumber; }; 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<std::string, uint8_t> gF3DTable = { { "G_VTX", 0x04 }, @@ -159,6 +160,28 @@ void DebugDisplayList(uint32_t w0, uint32_t w1){ gfxd_execute(); } +std::optional<std::tuple<std::string, YAML::Node>> 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<uint32_t>(node, "offset"); + auto count = GetSafeNode<uint32_t>(node, "count"); + auto end = ALIGN16((count * sizeof(Vtx_t))); + + if(ptr > offset && ptr <= offset + end){ + return std::make_tuple(GetSafeNode<std::string>(node, "symbol", name), node); + } + } + + return std::nullopt; +} + void DListBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto cmds = std::static_pointer_cast<DListData>(raw)->mGfxs; auto writer = LUS::BinaryWriter(); @@ -400,39 +423,57 @@ std::optional<std::shared_ptr<IParsedData>> DListFactory::parse(std::vector<uint nvtx = C0(10, 6); break; default: - nvtx = (C0(0, 16)) / sizeof(Vtx); + nvtx = (C0(0, 16)) / sizeof(Vtx_t); break; } + const auto decl = Companion::Instance->GetNodeByAddr(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<uint32_t>(vtx, "offset"); + auto lCount = GetSafeNode<uint32_t>(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); } } diff --git a/src/factories/DisplayListFactory.h b/src/factories/DisplayListFactory.h index 3c9116e..1bdc87e 100644 --- a/src/factories/DisplayListFactory.h +++ b/src/factories/DisplayListFactory.h @@ -2,6 +2,7 @@ #include "BaseFactory.h" #include "n64/CommandMacros.h" +#include <tuple> class DListData : public IParsedData { public: diff --git a/src/factories/DisplayListOverrides.cpp b/src/factories/DisplayListOverrides.cpp index 52a832d..32c9b5c 100644 --- a/src/factories/DisplayListOverrides.cpp +++ b/src/factories/DisplayListOverrides.cpp @@ -10,6 +10,8 @@ namespace GFXDOverride { +std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>> mVtxOverlaps; + void Triangle2(const Gfx* gfx) { auto w0 = gfx->words.w0; auto w1 = gfx->words.w1; @@ -47,6 +49,25 @@ void Quadrangle(const Gfx* gfx) { } int Vtx(uint32_t ptr, int32_t num) { + auto vtx = GetVtxOverlap(ptr); + + if(vtx.has_value()){ + auto symbol = std::get<0>(vtx.value()); + auto node = std::get<1>(vtx.value()); + + auto offset = GetSafeNode<uint32_t>(node, "offset"); + auto count = GetSafeNode<uint32_t>(node, "count"); + auto idx = (ptr - offset) / sizeof(Vtx_t); + + SPDLOG_INFO("Replaced Vtx Overlapped: 0x{:X} Symbol: {}", ptr, symbol); + gfxd_puts("&"); + gfxd_puts(symbol.c_str()); + gfxd_puts("["); + gfxd_puts(std::to_string(idx).c_str()); + gfxd_puts("]"); + return 1; + } + auto dec = Companion::Instance->GetNodeByAddr(ptr); if(dec.has_value()){ @@ -120,4 +141,24 @@ int DisplayList(uint32_t ptr) { SPDLOG_WARN("Could not find display list to override at 0x{:X}", ptr); return 0; } + +std::optional<std::tuple<std::string, YAML::Node>> GetVtxOverlap(uint32_t ptr){ + if(mVtxOverlaps.contains(ptr)){ + SPDLOG_INFO("Found overlap for ptr 0x{:X}", ptr); + return mVtxOverlaps[ptr]; + } + + SPDLOG_INFO("Failed to find overlap for ptr 0x{:X}", ptr); + + return std::nullopt; +} + +void RegisterVTXOverlap(uint32_t ptr, std::tuple<std::string, YAML::Node>& vtx){ + mVtxOverlaps[ptr] = vtx; + SPDLOG_INFO("Register overlap for ptr 0x{:X}", ptr); +} + +void ClearVtx(){ + mVtxOverlaps.clear(); +} } diff --git a/src/factories/DisplayListOverrides.h b/src/factories/DisplayListOverrides.h index 77734ca..2da6c52 100644 --- a/src/factories/DisplayListOverrides.h +++ b/src/factories/DisplayListOverrides.h @@ -1,7 +1,10 @@ #pragma once -#include <cstdint> #include "DisplayListFactory.h" +#include <yaml-cpp/yaml.h> +#include <cstdint> +#include <tuple> +#include <string> typedef struct { uint32_t w0; @@ -41,4 +44,7 @@ int Texture(uint32_t timg, int32_t fmt, int32_t siz, int32_t width, int32_t hei int Palette(uint32_t tlut, int32_t idx, int32_t count); int Light(uint32_t lightsn, int32_t count); 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); +void ClearVtx(); };
\ No newline at end of file |
