diff options
| author | KiritoDv <kiritodev01@gmail.com> | 2024-03-31 10:58:38 -0600 |
|---|---|---|
| committer | Lywx <kiritodev01@gmail.com> | 2024-04-13 00:02:32 -0600 |
| commit | 1afbbddb327e4376aa759cc21560d98620696b35 (patch) | |
| tree | 22429123d3ca78c37247ef17b45d60cd1a49712a | |
| parent | 8dda6f54595cf3b04a08ef13b7c799961f533b6e (diff) | |
[WIP] Splitted export
| -rw-r--r-- | src/Companion.cpp | 192 | ||||
| -rw-r--r-- | src/Companion.h | 13 |
2 files changed, 110 insertions, 95 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp index 273c806..275e442 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -168,11 +168,7 @@ void Companion::ParseEnums(std::string& header) { } } -void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binary) { - std::ostringstream stream; - - this->gCurrentWrapper = binary; - +std::optional<ParseResultData> Companion::ParseNode(YAML::Node& node, std::string& name) { auto type = GetSafeNode<std::string>(node, "type"); std::transform(type.begin(), type.end(), type.begin(), ::toupper); @@ -188,16 +184,14 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar auto factory = this->GetFactory(type); if(!factory.has_value()){ throw std::runtime_error("No factory by the name '"+type+"' found for '"+name+"'"); - return; } - auto impl = factory->get(); auto exporter = impl->GetExporter(this->gConfig.exporterType); if(!exporter.has_value()){ SPDLOG_WARN("No exporter found for {}", name); - return; + return std::nullopt; } std::optional<std::shared_ptr<IParsedData>> result; @@ -205,7 +199,7 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar auto path = fs::path(this->gConfig.moddingPath) / this->gModdedAssetPaths[name]; if(!fs::exists(path)) { SPDLOG_ERROR("Modded asset {} not found", this->gModdedAssetPaths[name]); - return; + return std::nullopt; } std::ifstream input(path, std::ios::binary); @@ -219,7 +213,7 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar if(!result.has_value()){ SPDLOG_ERROR("Failed to process {}", name); - return; + return std::nullopt; } for (auto [fst, snd] : this->gAssetDependencies[this->gCurrentFile]) { @@ -229,95 +223,18 @@ void Companion::ExtractNode(YAML::Node& node, std::string& name, SWrapper* binar std::string doutput = (this->gCurrentDirectory / fst).string(); std::replace(doutput.begin(), doutput.end(), '\\', '/'); this->gAssetDependencies[this->gCurrentFile][fst].second = true; - this->ExtractNode(snd.first, doutput, binary); + this->ParseNode(snd.first, doutput); spdlog::set_pattern(regular); SPDLOG_INFO("------------------------------------------------"); spdlog::set_pattern(line); } - ExportResult endptr = std::nullopt; - - switch (this->gConfig.exporterType) { - case ExportType::Binary: { - if(binary == nullptr) { - break; - } - - stream.str(""); - stream.clear(); - exporter->get()->Export(stream, result.value(), name, node, &name); - auto data = stream.str(); - binary->CreateFile(name, std::vector(data.begin(), data.end())); - break; - } - case ExportType::Modding: { - stream.str(""); - stream.clear(); - std::string ogname = name; - exporter->get()->Export(stream, result.value(), name, node, &name); - - auto data = stream.str(); - if(data.empty()) { - break; - } - - std::string dpath = Instance->GetOutputPath() + "/" + name; - if(!exists(fs::path(dpath).parent_path())){ - create_directories(fs::path(dpath).parent_path()); - } - - this->gModdedAssetPaths[ogname] = name; - - std::ofstream file(dpath, std::ios::binary); - file.write(data.c_str(), data.size()); - file.close(); - break; - } - default: { - endptr = exporter->get()->Export(stream, result.value(), name, node, &name); - break; - } - } SPDLOG_INFO("Processed {}", name); - WriteEntry entry; - if(node["offset"]) { - auto alignment = GetSafeNode<uint32_t>(node, "alignment", impl->GetAlignment()); - if(!endptr.has_value()) { - entry = { - node["offset"].as<uint32_t>(), - alignment, - stream.str(), - std::nullopt - }; - } else { - switch (endptr->index()) { - case 0: - entry = { - node["offset"].as<uint32_t>(), - alignment, - stream.str(), - std::get<size_t>(endptr.value()) - }; - break; - case 1: { - const auto oentry = std::get<OffsetEntry>(endptr.value()); - entry = { - oentry.start, - alignment, - stream.str(), - oentry.end - }; - break; - } - default: - SPDLOG_ERROR("Invalid endptr index {}", endptr->index()); - SPDLOG_ERROR("Type of endptr: {}", typeid(endptr).name()); - throw std::runtime_error("We should never reach this point"); - } - } - } - this->gWriteMap[this->gCurrentFile][type].push_back(entry); + + return ParseResultData { + name, type, node, result + }; } void Companion::ParseModdingConfig() { @@ -668,6 +585,7 @@ void Companion::Process() { AudioManager::Instance = new AudioManager(); auto wrapper = this->gConfig.exporterType == ExportType::Binary ? new SWrapper(this->gConfig.outputPath) : nullptr; + this->gCurrentWrapper = wrapper; auto vWriter = LUS::BinaryWriter(); vWriter.SetEndianness(LUS::Endianness::Big); @@ -811,7 +729,7 @@ void Companion::Process() { auto output = (this->gCurrentDirectory / entryName / childName).string(); std::replace(output.begin(), output.end(), '\\', '/'); this->gConfig.segment.temporal.clear(); - this->ExtractNode(node, output, wrapper); + this->ParseNode(node, output); } } else { if(gCurrentFileOffset && assetNode["offset"]) { @@ -823,7 +741,7 @@ void Companion::Process() { std::string output = (this->gCurrentDirectory / entryName).string(); std::replace(output.begin(), output.end(), '\\', '/'); this->gConfig.segment.temporal.clear(); - this->ExtractNode(assetNode, output, wrapper); + this->ParseNode(assetNode, output); } spdlog::set_pattern(regular); @@ -831,6 +749,92 @@ void Companion::Process() { spdlog::set_pattern(line); } + for(auto& result : this->gParseResults[this->gCurrentFile]){ + std::ostringstream stream; + ExportResult endptr = std::nullopt; + WriteEntry wEntry; + + auto data = result.data.value(); + const auto impl = this->GetFactory(result.type)->get(); + const auto exporter = impl->GetExporter(this->gConfig.exporterType)->get(); + + switch (this->gConfig.exporterType) { + case ExportType::Binary: { + stream.str(""); + stream.clear(); + exporter->Export(stream, data, result.name, result.node, &result.name); + auto data = stream.str();; + break; + } + case ExportType::Modding: { + stream.str(""); + stream.clear(); + std::string ogname = result.name; + exporter->Export(stream, data, result.name, result.node, &result.name); + + auto data = stream.str(); + if(data.empty()) { + break; + } + + std::string dpath = Instance->GetOutputPath() + "/" + result.name; + if(!exists(fs::path(dpath).parent_path())){ + create_directories(fs::path(dpath).parent_path()); + } + + this->gModdedAssetPaths[ogname] = result.name; + + std::ofstream file(dpath, std::ios::binary); + file.write(data.c_str(), data.size()); + file.close(); + break; + } + default: { + endptr = exporter->Export(stream, data, result.name, result.node, &result.name); + break; + } + } + + if(result.node["offset"]) { + auto alignment = GetSafeNode<uint32_t>(result.node, "alignment", impl->GetAlignment()); + if(!endptr.has_value()) { + wEntry = { + result.node["offset"].as<uint32_t>(), + alignment, + stream.str(), + std::nullopt + }; + } else { + switch (endptr->index()) { + case 0: + wEntry = { + result.node["offset"].as<uint32_t>(), + alignment, + stream.str(), + std::get<size_t>(endptr.value()) + }; + break; + case 1: { + const auto oentry = std::get<OffsetEntry>(endptr.value()); + wEntry = { + oentry.start, + alignment, + stream.str(), + oentry.end + }; + break; + } + default: + SPDLOG_ERROR("Invalid endptr index {}", endptr->index()); + SPDLOG_ERROR("Type of endptr: {}", typeid(endptr).name()); + throw std::runtime_error("We should never reach this point"); + } + } + } + + this->gWriteMap[this->gCurrentFile][result.type].push_back(wEntry); + } + auto fsout = fs::path(this->gConfig.outputPath); if(this->gConfig.exporterType == ExportType::Modding) { diff --git a/src/Companion.h b/src/Companion.h index 93b3dde..88e23c8 100644 --- a/src/Companion.h +++ b/src/Companion.h @@ -75,6 +75,13 @@ struct TorchConfig { bool modding; }; +struct ParseResultData { + std::string name; + std::string type; + YAML::Node node; + std::optional<std::shared_ptr<IParsedData>> data; +}; + class Companion { public: static Companion* Instance; @@ -151,9 +158,12 @@ private: std::optional<VRAMEntry> gCurrentVram; CompressionType gCurrentCompressionType = CompressionType::None; std::vector<Table> gTables; + + std::unordered_map<std::string, std::vector<ParseResultData>> gParseResults; + + std::unordered_map<std::string, std::string> gModdedAssetPaths; std::variant<std::vector<std::string>, std::string> gWriteOrder; std::unordered_map<std::string, std::shared_ptr<BaseFactory>> gFactories; - std::unordered_map<std::string, std::string> gModdedAssetPaths; std::unordered_map<std::string, std::map<std::string, std::vector<WriteEntry>>> gWriteMap; std::unordered_map<std::string, std::map<std::string, std::pair<YAML::Node, bool>>> gAssetDependencies; std::unordered_map<std::string, std::unordered_map<uint32_t, std::tuple<std::string, YAML::Node>>> gAddrMap; @@ -167,4 +177,5 @@ private: void ExtractNode(YAML::Node& node, std::string& name, SWrapper* binary); void ProcessTables(YAML::Node& rom); void LoadYAMLRecursively(const std::string &dirPath, std::vector<YAML::Node> &result, bool skipRoot); + std::optional<ParseResultData> ParseNode(YAML::Node& node, std::string& name); }; |
