diff options
| author | KiritoDv <kiritodev01@gmail.com> | 2024-05-15 19:16:26 -0600 |
|---|---|---|
| committer | KiritoDv <kiritodev01@gmail.com> | 2024-05-15 19:16:26 -0600 |
| commit | b6524bfb136bb18434dac06fbffb349f83ce4af1 (patch) | |
| tree | 7659bdfc7ebea8db199238678fc5dab9c77025d3 /src/factories/sf64/MessageFactory.cpp | |
| parent | 311638a3bff9ea8af6799dc20ae4abf8c8a52ad1 (diff) | |
Fixed dependency system and modding reimport
Diffstat (limited to 'src/factories/sf64/MessageFactory.cpp')
| -rw-r--r-- | src/factories/sf64/MessageFactory.cpp | 128 |
1 files changed, 127 insertions, 1 deletions
diff --git a/src/factories/sf64/MessageFactory.cpp b/src/factories/sf64/MessageFactory.cpp index ee1beb0..81b167f 100644 --- a/src/factories/sf64/MessageFactory.cpp +++ b/src/factories/sf64/MessageFactory.cpp @@ -4,6 +4,7 @@ #include "spdlog/spdlog.h" #include "Companion.h" #include <regex> +#include <sstream> #define END_CODE 0 #define NEWLINE_CODE 1 @@ -50,6 +51,21 @@ std::unordered_map<std::string, std::string> ASCIITable = { { "CLN", ":" }, { "PIP", "| " } }; +std::vector<std::string> gASCIIFullTable = { + "\0", "\n", "{NP:2}", "{NP:3}", "{NP:4}", "{NP:5}", "{NP:6}", "{NP:7}", + "{PRI:0}", "{PRI:1}", "{PRI:2}", "{PRI:3}", " ", "{HSP}", "{QSP}", "{NXT}", + "{C:<}", "{C:^}", "{C:>}", "{C:v}", "^", "<", "v", ">", + "A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", + "Q", "R", "S", "T", "U", "V", "W", "X", + "Y", "Z", "a", "b", "c", "d", "e", "f", + "g", "h", "i", "j", "k", "l", "m", "n", + "o", "p", "q", "r", "s", "t", "u", "v", + "w", "x", "y", "z", "!", "?", "-", ",", + ".", "0", "1", "2", "3", "4", "5", "6", + "7", "8", "9", "'", "(", ")", ":", "|", +}; + ExportResult SF64::MessageHeaderExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement) { const auto symbol = GetSafeNode(node, "symbol", entryName); @@ -105,6 +121,34 @@ ExportResult SF64::MessageBinaryExporter::Export(std::ostream &write, std::share return std::nullopt; } +ExportResult SF64::MessageModdingExporter::Export(std::ostream&write, std::shared_ptr<IParsedData> raw, std::string&entryName, YAML::Node&node, std::string* replacement) { + const auto data = std::static_pointer_cast<MessageData>(raw); + const auto symbol = GetSafeNode(node, "symbol", entryName); + *replacement += ".yml"; + + auto count = data->mMessage.size(); + std::stringstream stream; + YAML::Emitter out; + out << YAML::BeginMap; + out << YAML::Key << symbol; + out << YAML::Value << YAML::BeginSeq; + + for(size_t i = 0; i < count; i++) { + if(data->mMessage[i] == NEWLINE_CODE){ + stream << "\0"; + out << stream.str(); + stream.str(""); + } else { + stream << gASCIIFullTable[data->mMessage[i]]; + } + } + + out << YAML::EndSeq << YAML::EndMap; + write.write(out.c_str(), out.size()); + + return std::nullopt; +} + std::optional<std::shared_ptr<IParsedData>> SF64::MessageFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { std::vector<uint16_t> message; std::ostringstream mesgStr; @@ -113,7 +157,6 @@ std::optional<std::shared_ptr<IParsedData>> SF64::MessageFactory::parse(std::vec reader.SetEndianness(LUS::Endianness::Big); uint16_t c; - bool lastWasSpace = false; std::string whitespace = ""; do { c = reader.ReadUInt16(); @@ -139,4 +182,87 @@ std::optional<std::shared_ptr<IParsedData>> SF64::MessageFactory::parse(std::vec } while(c != END_CODE); return std::make_shared<MessageData>(message, mesgStr.str()); +} + +std::optional<uint16_t> getCharByCode(const std::string& code) { + auto it = std::find(gASCIIFullTable.begin(), gASCIIFullTable.end(), code) - gASCIIFullTable.begin(); + if(it < gASCIIFullTable.size()){ + return it; + } + return std::nullopt; +} + +std::optional<std::shared_ptr<IParsedData>> SF64::MessageFactory::parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) { + std::vector<uint16_t> message; + std::ostringstream mesgStr; + std::string whitespace = ""; + + YAML::Node node; + + try { + std::string text((char*) buffer.data(), buffer.size()); + node = YAML::Load(text.c_str()); + } catch (YAML::ParserException& e) { + SPDLOG_ERROR("Failed to parse message data: {}", e.what()); + SPDLOG_ERROR("{}", (char*) buffer.data()); + return std::nullopt; + } + + std::regex fmt("\\(([^)]+)\\)"); + + std::vector<std::string> lines = node.begin()->second.as<std::vector<std::string>>(); + for(auto& line : lines){ + for(size_t i = 0; i < line.size(); i++){ + char c = line[i]; + std::string enumCode; + if(c == '{' && line.substr(i).find('}') != std::string::npos){ + auto code = line.substr(i, line.substr(i).find('}') + 1); + auto opcode = getCharByCode(code); + if(opcode.has_value()){ + auto x = opcode.value(); + message.push_back(x); + i += line.substr(i).find('}'); + enumCode = gCharCodeEnums[x]; + } else { + SPDLOG_WARN("Unknown character: {}", code); + } + } else { + auto code = getCharByCode(std::string(1, c)); + if(code.has_value()){ + auto x = code.value(); + message.push_back(x); + enumCode = gCharCodeEnums[x]; + } else { + SPDLOG_WARN("Unknown character: {}", c); + } + } + + if(!enumCode.empty()) { + if(enumCode.find("SP") != std::string::npos && whitespace.empty()) { + whitespace = " "; + } + if(c == NEWLINE_CODE) { + whitespace += "\n"; + } + if (c >= CLF_CODE) { + mesgStr << whitespace; + whitespace = ""; + } + if(enumCode.starts_with("_")){ + mesgStr << enumCode.substr(1); + } else if(ASCIITable.contains(enumCode)){ + mesgStr << ASCIITable[enumCode]; + } + } + } + + if(line != lines.back()){ + message.push_back(NEWLINE_CODE); + mesgStr << "\n"; + } + } + + message.push_back(END_CODE); + + return std::make_shared<MessageData>(message, mesgStr.str()); }
\ No newline at end of file |
