summaryrefslogtreecommitdiff
path: root/src/factories/sf64/MessageFactory.cpp
diff options
context:
space:
mode:
authorKiritoDv <kiritodev01@gmail.com>2024-05-15 19:16:26 -0600
committerKiritoDv <kiritodev01@gmail.com>2024-05-15 19:16:26 -0600
commitb6524bfb136bb18434dac06fbffb349f83ce4af1 (patch)
tree7659bdfc7ebea8db199238678fc5dab9c77025d3 /src/factories/sf64/MessageFactory.cpp
parent311638a3bff9ea8af6799dc20ae4abf8c8a52ad1 (diff)
Fixed dependency system and modding reimport
Diffstat (limited to 'src/factories/sf64/MessageFactory.cpp')
-rw-r--r--src/factories/sf64/MessageFactory.cpp128
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