Refactored vtx overlap function

This commit is contained in:
KiritoDv
2024-03-10 15:58:45 -06:00
committed by Lywx
parent c4bb1ad8ee
commit 5d4bd639df
6 changed files with 135 additions and 24 deletions
+21
View File
@@ -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;
+1
View File
@@ -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; };
+64 -23
View File
@@ -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);
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);
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);
}
}
} else {
SPDLOG_WARN("Could not find vtx at 0x{:X}", w1);
SPDLOG_WARN("Found vtx at 0x{:X}", w1);
}
}
+1
View File
@@ -2,6 +2,7 @@
#include "BaseFactory.h"
#include "n64/CommandMacros.h"
#include <tuple>
class DListData : public IParsedData {
public:
+41
View File
@@ -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();
}
}
+7 -1
View File
@@ -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();
};