mirror of
https://github.com/izzy2lost/Torch.git
synced 2026-07-06 00:18:35 -07:00
Refactored vtx overlap function
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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; };
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "BaseFactory.h"
|
||||
#include "n64/CommandMacros.h"
|
||||
#include <tuple>
|
||||
|
||||
class DListData : public IParsedData {
|
||||
public:
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
Reference in New Issue
Block a user