diff options
| author | KiritoDv <kiritodev01@gmail.com> | 2024-03-10 21:22:26 -0600 |
|---|---|---|
| committer | Lywx <kiritodev01@gmail.com> | 2024-03-11 00:05:16 -0600 |
| commit | 595f7512d49b582e9ef2c4d082aa775d2ae600f4 (patch) | |
| tree | e6f652b9276956cf2b6afd564060b2b689cf0a56 /src | |
| parent | 04a66e743b643ab0589dbef7e8d3531763013fe0 (diff) | |
Fixed message and lookup factories
Diffstat (limited to 'src')
| -rw-r--r-- | src/Companion.cpp | 2 | ||||
| -rw-r--r-- | src/factories/ResourceType.h | 1 | ||||
| -rw-r--r-- | src/factories/sf64/MessageFactory.cpp | 115 | ||||
| -rw-r--r-- | src/factories/sf64/MessageFactory.h | 4 | ||||
| -rw-r--r-- | src/factories/sf64/MessageLookupFactory.cpp | 109 | ||||
| -rw-r--r-- | src/factories/sf64/MessageLookupFactory.h | 46 |
6 files changed, 267 insertions, 10 deletions
diff --git a/src/Companion.cpp b/src/Companion.cpp index cc273b7..f9cfa8d 100644 --- a/src/Companion.cpp +++ b/src/Companion.cpp @@ -29,6 +29,7 @@ #include <iostream> #include <filesystem> #include "factories/sf64/MessageFactory.h" +#include "factories/sf64/MessageLookupFactory.h" using namespace std::chrono; namespace fs = std::filesystem; @@ -68,6 +69,7 @@ void Companion::Init(const ExportType type) { // SF64 specific this->RegisterFactory("SF64:ANIM", std::make_shared<SF64::AnimFactory>()); this->RegisterFactory("SF64:MESSAGE", std::make_shared<SF64::MessageFactory>()); + this->RegisterFactory("SF64:MSG_TABLE", std::make_shared<SF64::MessageLookupFactory>()); this->Process(); } diff --git a/src/factories/ResourceType.h b/src/factories/ResourceType.h index 1c36317..27e7f82 100644 --- a/src/factories/ResourceType.h +++ b/src/factories/ResourceType.h @@ -35,5 +35,6 @@ enum class ResourceType { // SF64 AnimData = 0x414E494D, // ANIM Message = 0x4D53474C, // MSG + MessageTable = 0x4D534754, // MSGT }; } // namespace LUS diff --git a/src/factories/sf64/MessageFactory.cpp b/src/factories/sf64/MessageFactory.cpp index 4f136c7..3734202 100644 --- a/src/factories/sf64/MessageFactory.cpp +++ b/src/factories/sf64/MessageFactory.cpp @@ -5,6 +5,26 @@ #include "Companion.h" #define END_CODE 0x0 +#define NEWLINE_CODE 0x1 +#define SPC 15 +#define CLF 16 +#define CUP 17 +#define CRT 18 +#define CDN 19 +#define AUP 20 +#define ALF 21 +#define ADN 22 +#define ART 23 +#define EXM 50 +#define QST 51 +#define DSH 52 +#define CMA 53 +#define PRD 54 +#define APS 55 +#define LPR 56 +#define RPR 57 +#define CLN 58 +#define PIP 59 std::vector<std::string> gCharCodeEnums = { "END", "NWL", "NP2", "NP3", "NP4", "NP5", "NP6", "NP7", @@ -32,6 +52,80 @@ void SF64::MessageHeaderExporter::Export(std::ostream &write, std::shared_ptr<IP write << "extern Vtx " << symbol << "[];\n"; } +void TextToStream(std::ostream& stream, int charCode) { + switch (charCode) { + case NEWLINE_CODE: + stream << "\n// "; + break; + // case CLF: + // stream << "(C<)"; + // break; + // case CUP: + // stream << "(C^)"; + // break; + // case CRT: + // stream << "(C>)"; + // 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<char>('A' + (charCode - 24)); + } else if(charCode > 49 && charCode < 58) { + stream << static_cast<char>('a' + (charCode - 58)); + } else if(charCode > 80 && charCode < 90) { + stream << static_cast<char>('0' + (charCode - 81)); + } + break; + } +} + void SF64::MessageCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto message = std::static_pointer_cast<MessageData>(raw)->mMessage; const auto symbol = GetSafeNode(node, "symbol", entryName); @@ -48,17 +142,22 @@ void SF64::MessageCodeExporter::Export(std::ostream &write, std::shared_ptr<IPar write << "// 0x" << std::hex << std::uppercase << offset << "\n"; } + for (int i = 0; i < message.size(); ++i) { + TextToStream(write, message[i]); + } + write << "u16 " << symbol << "[] = {\n" << fourSpaceTab; for (int i = 0; i < message.size(); ++i) { auto m = message[i]; - if(m == 0){ - write << "\n" << fourSpaceTab; - } write << gCharCodeEnums[m] << ", "; + + if(m == NEWLINE_CODE){ + write << "\n" << fourSpaceTab; + } } - write << "};\n"; + write << "\n};\n"; if (Companion::Instance->IsDebug()) { write << "// count: " << std::to_string(message.size()) << " chars\n"; @@ -82,16 +181,16 @@ void SF64::MessageBinaryExporter::Export(std::ostream &write, std::shared_ptr<IP } std::optional<std::shared_ptr<IParsedData>> SF64::MessageFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { - std::vector<uint8_t> message; + std::vector<uint16_t> message; auto [_, segment] = Decompressor::AutoDecode(node, buffer); LUS::BinaryReader reader(segment.data, segment.size); reader.SetEndianness(LUS::Endianness::Big); - size_t idx = 0; - while(segment.data[idx] != END_CODE){ - auto c = segment.data[idx++]; + uint16_t c = reader.ReadUInt16(); + while(c != END_CODE){ message.push_back(c); + c = reader.ReadUInt16(); } message.push_back(END_CODE); diff --git a/src/factories/sf64/MessageFactory.h b/src/factories/sf64/MessageFactory.h index 6c4bb53..7565cc4 100644 --- a/src/factories/sf64/MessageFactory.h +++ b/src/factories/sf64/MessageFactory.h @@ -6,9 +6,9 @@ namespace SF64 { class MessageData : public IParsedData { public: - std::vector<uint8_t> mMessage; + std::vector<uint16_t> mMessage; - MessageData(std::vector<uint8_t> message) : mMessage(message) {} + MessageData(std::vector<uint16_t> message) : mMessage(message) {} }; class MessageCodeExporter : public BaseExporter { diff --git a/src/factories/sf64/MessageLookupFactory.cpp b/src/factories/sf64/MessageLookupFactory.cpp new file mode 100644 index 0000000..a63b62f --- /dev/null +++ b/src/factories/sf64/MessageLookupFactory.cpp @@ -0,0 +1,109 @@ +#include "MessageLookupFactory.h" + +#include "utils/Decompressor.h" +#include "spdlog/spdlog.h" +#include "Companion.h" + +void SF64::MessageLookupHeaderExporter::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); + + if(Companion::Instance->IsOTRMode()){ + write << "static const char " << symbol << "[] = \"__OTR__" << (*replacement) << "\";\n\n"; + return; + } + + write << "extern MsgLookup " << symbol << "[];\n"; +} + +void SF64::MessageLookupCodeExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + auto table = std::static_pointer_cast<MessageTable>(raw)->mTable; + const auto symbol = GetSafeNode(node, "symbol", entryName); + auto offset = GetSafeNode<uint32_t>(node, "offset"); + + if (IS_SEGMENTED(offset)) { + offset = SEGMENT_OFFSET(offset); + } + + if (Companion::Instance->IsDebug()) { + if (IS_SEGMENTED(offset)) { + offset = SEGMENT_OFFSET(offset); + } + write << "// 0x" << std::hex << std::uppercase << offset << "\n"; + } + + write << "// clang-format on\n"; + write << "MsgLookup " << symbol << "[] = {\n" << fourSpaceTab; + for (int i = 0; i < table.size(); ++i) { + auto m = table[i]; + if(i % 4 == 0 && i != 0){ + write << "\n" << fourSpaceTab; + } + + auto dec = Companion::Instance->GetNodeByAddr(m.ptr); + std::string msgSymbol = "NULL"; + + if(dec.has_value()){ + auto node = std::get<1>(dec.value()); + msgSymbol = GetSafeNode<std::string>(node, "symbol"); + } + + write << "{ " << m.id << ", " << msgSymbol << " }, "; + } + + write << "\n};\n"; + + if (Companion::Instance->IsDebug()) { + write << "// 0x" << std::hex << std::uppercase << (offset + (table.size() * sizeof(uint16_t))) << "\n"; + } + + write << "\n"; +} + +void SF64::MessageLookupBinaryExporter::Export(std::ostream &write, std::shared_ptr<IParsedData> raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { + auto writer = LUS::BinaryWriter(); + const auto data = std::static_pointer_cast<MessageTable>(raw); + + WriteHeader(writer, LUS::ResourceType::MessageTable, 0); + + writer.Write(static_cast<uint32_t>(data->mTable.size())); + for(auto m : data->mTable) { + writer.Write(m.id); + writer.Write(m.ptr); + } + writer.Finish(write); +} + +std::optional<std::shared_ptr<IParsedData>> SF64::MessageLookupFactory::parse(std::vector<uint8_t>& buffer, YAML::Node& node) { + const auto vram = GetSafeNode<uint32_t>(node, "vram"); + const auto offset = GetSafeNode<uint32_t>(node, "offset"); + std::vector<MessageEntry> message; + + auto [_, segment] = Decompressor::AutoDecode(node, buffer); + LUS::BinaryReader reader(segment.data, segment.size); + reader.SetEndianness(LUS::Endianness::Big); + + int32_t id = reader.ReadInt32(); + uint32_t ptr = reader.ReadInt32(); + + while(id != -1) { + + YAML::Node entry; + + ptr = (SEGMENT_NUMBER(offset) << 24) | (ptr - vram); + std::string output = "gMsg_ID_" + std::to_string(id); + entry["type"] = "SF64:MESSAGE"; + entry["offset"] = ptr; + entry["symbol"] = output; + entry["autogen"] = true; + SPDLOG_INFO("Message ID: {} Ptr: {:X} Offset: {:X}", id, ptr, (SEGMENT_NUMBER(offset) << 24) | (ptr - vram)); + + Companion::Instance->RegisterAsset(output, entry); + message.push_back({id, ptr}); + id = reader.ReadInt32(); + ptr = reader.ReadInt32(); + } + + message.push_back({-1, 0}); + + return std::make_shared<MessageTable>(message); +}
\ No newline at end of file diff --git a/src/factories/sf64/MessageLookupFactory.h b/src/factories/sf64/MessageLookupFactory.h new file mode 100644 index 0000000..8413aec --- /dev/null +++ b/src/factories/sf64/MessageLookupFactory.h @@ -0,0 +1,46 @@ +#pragma once + +#include "../BaseFactory.h" + +namespace SF64 { + +struct MessageEntry { + int32_t id; + uint32_t ptr; +}; + +class MessageTable : public IParsedData { +public: + std::vector<MessageEntry> mTable; + + MessageTable(const std::vector<MessageEntry>&table) : mTable(table) {} +}; + +class MessageLookupCodeExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class MessageLookupHeaderExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class MessageLookupBinaryExporter : public BaseExporter { + void Export(std::ostream& write, std::shared_ptr<IParsedData> data, std::string& entryName, YAML::Node& node, std::string* replacement) override; +}; + +class MessageLookupFactory : public BaseFactory { +public: + std::optional<std::shared_ptr<IParsedData>> parse(std::vector<uint8_t>& buffer, YAML::Node& data) override; + std::optional<std::shared_ptr<IParsedData>> parse_modding(std::vector<uint8_t>& buffer, YAML::Node& data) override { + return std::nullopt; + } + inline std::unordered_map<ExportType, std::shared_ptr<BaseExporter>> GetExporters() override { + return { + REGISTER(Code, MessageLookupCodeExporter) + REGISTER(Header, MessageLookupHeaderExporter) + REGISTER(Binary, MessageLookupBinaryExporter) + }; + } + bool SupportModdedAssets() override { return false; } +}; +}
\ No newline at end of file |
