From 0277b06b4787f099ed0289eb95ceab98175cc8c4 Mon Sep 17 00:00:00 2001 From: KiritoDv Date: Sun, 10 Mar 2024 23:41:36 -0600 Subject: [PATCH] Fully implemented tables and message factories --- src/Companion.cpp | 24 ++++++ src/Companion.h | 20 ++++- src/factories/TextureFactory.cpp | 57 ++++++++----- src/factories/sf64/MessageFactory.cpp | 110 +++++++++----------------- 4 files changed, 117 insertions(+), 94 deletions(-) diff --git a/src/Companion.cpp b/src/Companion.cpp index f9cfa8d..b63c67a 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -245,6 +245,7 @@ void Companion::ParseCurrentFileConfig(YAML::Node node) { } } } + if(node["header"]) { auto header = node["header"]; switch (this->gConfig.exporterType) { @@ -267,6 +268,18 @@ void Companion::ParseCurrentFileConfig(YAML::Node node) { default: break; } } + + if(node["tables"]){ + for(auto table = node["tables"].begin(); table != node["tables"].end(); ++table){ + auto name = table->first.as(); + auto range = table->second["range"].as>(); + auto start = gCurrentSegmentNumber ? gCurrentSegmentNumber << 24 | range[0] : range[0]; + auto end = gCurrentSegmentNumber ? gCurrentSegmentNumber << 24 | range[1] : range[1]; + auto mode = GetSafeNode(table->second, "mode", "APPEND"); + TableMode tMode = mode == "REFERENCE" ? TableMode::Reference : TableMode::Append; + this->gTables.push_back({name, start, end, tMode}); + } + } } void Companion::Process() { @@ -491,6 +504,7 @@ void Companion::Process() { this->gConfig.segment.local.clear(); this->gFileHeader.clear(); this->gCurrentPad = 0; + this->gTables.clear(); GFXDOverride::ClearVtx(); if(root[":config"]) { @@ -762,6 +776,16 @@ CompressionType Companion::GetCompressionType(std::vector& buffer, cons return CompressionType::None; } +std::optional Companion::SearchTable(uint32_t addr){ + for(auto& table : this->gTables){ + if(addr >= table.start || addr <= table.end){ + return table; + } + } + + return std::nullopt; +} + std::optional Companion::GetFileOffsetFromSegmentedAddr(const uint8_t segment) const { auto segments = this->gConfig.segment; diff --git a/src/Companion.h b/src/Companion.h index 8f8f98c..265f2eb 100644 --- a/src/Companion.h +++ b/src/Companion.h @@ -28,12 +28,24 @@ enum class GBIMinorVersion { SM64 }; +enum class TableMode { + Reference, + Append +}; + struct SegmentConfig { std::unordered_map global; std::unordered_map local; std::unordered_map temporal; }; +struct Table { + std::string name; + uint32_t start; + uint32_t end; + TableMode mode; +}; + struct GBIConfig { GBIVersion version = GBIVersion::f3d; GBIMinorVersion subversion = GBIMinorVersion::None; @@ -82,6 +94,7 @@ public: std::optional GetCurrSegmentNumber(void) const { return this->gCurrentSegmentNumber; }; CompressionType GetCurrCompressionType(void) const { return this->gCurrentCompressionType; }; CompressionType GetCompressionType(std::vector& buffer, const uint32_t offset); + std::optional
SearchTable(uint32_t addr); static std::string CalculateHash(const std::vector& data); static void Pack(const std::string& folder, const std::string& output); @@ -102,15 +115,16 @@ private: std::string gCurrentFile; std::string gFileHeader; uint32_t gCurrentPad = 0; + uint32_t gCurrentFileOffset; + uint32_t gCurrentSegmentNumber; + CompressionType gCurrentCompressionType; + std::vector
gTables; std::variant, std::string> gWriteOrder; std::unordered_map> gFactories; std::unordered_map gModdedAssetPaths; std::unordered_map>> gAssetDependencies; std::unordered_map>>> gWriteMap; std::unordered_map>> gAddrMap; - uint32_t gCurrentFileOffset; - uint32_t gCurrentSegmentNumber; - CompressionType gCurrentCompressionType; void ParseCurrentFileConfig(YAML::Node node); void ParseModdingConfig(); diff --git a/src/factories/TextureFactory.cpp b/src/factories/TextureFactory.cpp index 7c9ec4f..6e3142f 100644 --- a/src/factories/TextureFactory.cpp +++ b/src/factories/TextureFactory.cpp @@ -9,6 +9,8 @@ extern "C" { #include "BaseFactory.h" } +bool isTable = false; + static const std::unordered_map gTextureFormats = { { "RGBA16", { TextureType::RGBA16bpp, 16 } }, { "RGBA32", { TextureType::RGBA32bpp, 32 } }, @@ -138,29 +140,44 @@ void TextureCodeExporter::Export(std::ostream &write, std::shared_ptrGetGBIMinorVersion() == GBIMinorVersion::Mk64) { - write << "u8 " << symbol << "[] = {\n"; + const auto searchTable = Companion::Instance->SearchTable(offset); + + if(searchTable.has_value()){ + const auto [name, start, end, mode] = searchTable.value(); + + if(mode != TableMode::Append){ + throw std::runtime_error("Reference mode is not supported for now"); + } + + if(start == offset){ + write << GetSafeNode(node, "ctype", "static const u8") << " " << name << "[][0x" << texture->mBuffer.size() << std::hex << std::uppercase << "] = {\n"; + } + + write << tab << "{\n"; + write << tab << tab << "#include \"" << Companion::Instance->GetOutputPath() + "/" << *replacement << ".inc.c\"\n"; + write << tab << "},\n"; + + if(end == offset){ + write << "};\n"; + } } else { - if(node["ctype"]) { - write << node["ctype"].as() << " " << symbol << "[] = {\n"; - } else { - write << "static const u8 " << symbol << "[] = {\n"; + write << GetSafeNode(node, "ctype", "static const u8") << " " << symbol << "[] = {\n"; + + write << tab << "#include \"" << Companion::Instance->GetOutputPath() + "/" << *replacement << ".inc.c\"\n"; + write << "};\n"; + + if (Companion::Instance->IsDebug()) { + const auto sz = data.size(); + + write << "// size: 0x" << std::hex << std::uppercase << sz << "\n"; + if (IS_SEGMENTED(offset)) { + offset = SEGMENT_OFFSET(offset); + } + write << "// 0x" << std::hex << std::uppercase << (offset + sz) << "\n"; } + + write << "\n"; } - write << tab << "#include \"" << Companion::Instance->GetOutputPath() + "/" << (*replacement) << ".inc.c\"\n"; - write << "};\n"; - - if (Companion::Instance->IsDebug()) { - const auto sz = data.size(); - - write << "// size: 0x" << std::hex << std::uppercase << sz << "\n"; - if (IS_SEGMENTED(offset)) { - offset = SEGMENT_OFFSET(offset); - } - write << "// 0x" << std::hex << std::uppercase << (offset + sz) << "\n"; - } - - write << "\n"; } void TextureBinaryExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement) { diff --git a/src/factories/sf64/MessageFactory.cpp b/src/factories/sf64/MessageFactory.cpp index 3734202..dd2a38d 100644 --- a/src/factories/sf64/MessageFactory.cpp +++ b/src/factories/sf64/MessageFactory.cpp @@ -41,6 +41,14 @@ std::vector gCharCodeEnums = { "_7", "_8", "_9", "APS", "LPR", "RPR", "CLN", "PIP", }; +std::unordered_map ASCIITable = { + { "CLF", "(C<)" }, { "CUP", "(C^)" }, { "CRT", "(C>)" }, { "CDN", "(Cv)" }, + { "AUP", "^" }, { "ALF", "<" }, { "ADN", "v" }, { "ART", ">" }, + { "EXM", "!" }, { "QST", "?" }, { "DSH", "-" }, { "CMA", "," }, + { "PRD", "." }, { "APS", "'" }, { "LPR", "(" }, { "RPR", ")" }, + { "CLN", ":" }, { "PIP", "| " } +}; + void SF64::MessageHeaderExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement) { const auto symbol = GetSafeNode(node, "symbol", entryName); @@ -53,76 +61,15 @@ void SF64::MessageHeaderExporter::Export(std::ostream &write, std::shared_ptr)"; - // break; - // case CDN: - // stream << "(Cv)"; - // break; - // case AUP: - // stream << "^"; - // break; - // case ALF: - // stream << "<"; - // break; - // case ADN: - // stream << "v"; - // break; - // case ART: - // stream << ">"; - // break; - // case EXM: - // stream << "!"; - // break; - // case QST: - // stream << "?"; - // break; - // case DSH: - // stream << "-"; - // break; - // case CMA: - // stream << ","; - // break; - // case PRD: - // stream << "."; - // break; - // case APS: - // stream << "'"; - // break; - // case LPR: - // stream << "("; - // break; - // case RPR: - // stream << ")"; - // break; - // case CLN: - // stream << ":"; - // break; - // case PIP: - // stream << "|"; - // break; - // case SPC: - // stream << " "; - // break; - default: - if(charCode > 23 && charCode < 50) { - stream << static_cast('A' + (charCode - 24)); - } else if(charCode > 49 && charCode < 58) { - stream << static_cast('a' + (charCode - 58)); - } else if(charCode > 80 && charCode < 90) { - stream << static_cast('0' + (charCode - 81)); - } - break; + std::string enumCode = gCharCodeEnums[charCode]; + + if(enumCode.starts_with("_")){ + stream << enumCode.substr(1); + return; + } + + if(ASCIITable.contains(enumCode)){ + stream << ASCIITable[enumCode]; } } @@ -142,9 +89,30 @@ void SF64::MessageCodeExporter::Export(std::ostream &write, std::shared_ptr