summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiritoDv <kiritodev01@gmail.com>2024-03-31 10:58:38 -0600
committerLywx <kiritodev01@gmail.com>2024-04-13 00:02:32 -0600
commit1afbbddb327e4376aa759cc21560d98620696b35 (patch)
tree22429123d3ca78c37247ef17b45d60cd1a49712a
parent8dda6f54595cf3b04a08ef13b7c799961f533b6e (diff)
[WIP] Splitted export
-rw-r--r--src/Companion.cpp192
-rw-r--r--src/Companion.h13
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);
};