#include "MessageLookupFactory.h" #include "utils/Decompressor.h" #include "spdlog/spdlog.h" #include "Companion.h" ExportResult SF64::MessageLookupHeaderExporter::Export(std::ostream &write, std::shared_ptr 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 std::nullopt; } write << "extern MsgLookup " << symbol << "[];\n"; } ExportResult SF64::MessageLookupCodeExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto table = std::static_pointer_cast(raw)->mTable; const auto symbol = GetSafeNode(node, "symbol", entryName); auto offset = GetSafeNode(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(node, "symbol"); } write << "{ " << m.id << std::dec << ", " << msgSymbol << " }, "; } write << "\n};\n"; return (IS_SEGMENTED(offset) ? SEGMENT_OFFSET(offset) : offset) + table.size() * sizeof(uint16_t); } ExportResult SF64::MessageLookupBinaryExporter::Export(std::ostream &write, std::shared_ptr raw, std::string& entryName, YAML::Node &node, std::string* replacement ) { auto writer = LUS::BinaryWriter(); const auto data = std::static_pointer_cast(raw); WriteHeader(writer, LUS::ResourceType::MessageTable, 0); writer.Write(static_cast(data->mTable.size())); for(auto m : data->mTable) { writer.Write(m.id); writer.Write(m.ptr); } writer.Finish(write); } std::optional> SF64::MessageLookupFactory::parse(std::vector& buffer, YAML::Node& node) { const auto vram = GetSafeNode(node, "vram"); const auto offset = GetSafeNode(node, "offset"); std::vector 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(message); }