1#ifndef YAZE_APP_EDITOR_MESSAGE_MESSAGE_DATA_H
2#define YAZE_APP_EDITOR_MESSAGE_MESSAGE_DATA_H
85#include <unordered_map>
88#include <nlohmann/json.hpp>
89#include "absl/strings/match.h"
90#include "absl/strings/str_format.h"
91#include "absl/strings/str_replace.h"
105static const std::unordered_map<uint8_t, wchar_t> CharEncoder = {
106 {0x00,
'A'}, {0x01,
'B'}, {0x02,
'C'}, {0x03,
'D'}, {0x04,
'E'},
107 {0x05,
'F'}, {0x06,
'G'}, {0x07,
'H'}, {0x08,
'I'}, {0x09,
'J'},
108 {0x0A,
'K'}, {0x0B,
'L'}, {0x0C,
'M'}, {0x0D,
'N'}, {0x0E,
'O'},
109 {0x0F,
'P'}, {0x10,
'Q'}, {0x11,
'R'}, {0x12,
'S'}, {0x13,
'T'},
110 {0x14,
'U'}, {0x15,
'V'}, {0x16,
'W'}, {0x17,
'X'}, {0x18,
'Y'},
111 {0x19,
'Z'}, {0x1A,
'a'}, {0x1B,
'b'}, {0x1C,
'c'}, {0x1D,
'd'},
112 {0x1E,
'e'}, {0x1F,
'f'}, {0x20,
'g'}, {0x21,
'h'}, {0x22,
'i'},
113 {0x23,
'j'}, {0x24,
'k'}, {0x25,
'l'}, {0x26,
'm'}, {0x27,
'n'},
114 {0x28,
'o'}, {0x29,
'p'}, {0x2A,
'q'}, {0x2B,
'r'}, {0x2C,
's'},
115 {0x2D,
't'}, {0x2E,
'u'}, {0x2F,
'v'}, {0x30,
'w'}, {0x31,
'x'},
116 {0x32,
'y'}, {0x33,
'z'}, {0x34,
'0'}, {0x35,
'1'}, {0x36,
'2'},
117 {0x37,
'3'}, {0x38,
'4'}, {0x39,
'5'}, {0x3A,
'6'}, {0x3B,
'7'},
118 {0x3C,
'8'}, {0x3D,
'9'}, {0x3E,
'!'}, {0x3F,
'?'}, {0x40,
'-'},
119 {0x41,
'.'}, {0x42,
','}, {0x44,
'>'}, {0x45,
'('}, {0x46,
')'},
120 {0x4C,
'"'}, {0x51,
'\''}, {0x59,
' '}, {0x5A,
'<'}, {0x5F, L
'¡'},
121 {0x60, L
'¡'}, {0x61, L
'¡'}, {0x62, L
' '}, {0x63, L
' '}, {0x64, L
' '},
122 {0x65,
' '}, {0x66,
'_'},
159 return absl::StrContains(std::string(s),
Contents);
165 auto replaced_string = std::string(s);
166 size_t pos = replaced_string.find(
Contents);
167 while (pos != std::string::npos) {
171 return replaced_string;
190 std::string str,
const std::vector<DictionaryEntry>& dictionary);
194 uint8_t value,
const std::vector<DictionaryEntry>& dictionary);
215 const std::vector<uint8_t>& rawData,
216 const std::string& parsedString,
217 const std::vector<uint8_t>& parsedData)
240 std::string_view message_string,
241 const std::vector<DictionaryEntry>& dictionary) {
242 std::stringstream protons;
243 bool command =
false;
245 for (
const auto& c : message_string) {
248 }
else if (c ==
']') {
258 std::string protons_string = protons.str();
259 std::string replaced_string =
261 std::string final_string =
262 absl::StrReplaceAll(replaced_string, {{
CHEESE,
""}});
270 const std::vector<DictionaryEntry>& dictionary) {
290 const std::string& description) {
302 "\\[%s(:[0-9A-F]{1,2})?\\]",
303 absl::StrReplaceAll(
Token, {{
"[",
"\\["}, {
"]",
"\\]"}}));
306 "\\[%s\\]", absl::StrReplaceAll(
Token, {{
"[",
"\\["}, {
"]",
"\\]"}}));
313 return absl::StrFormat(
"[%s:%02X]",
Token, value);
315 return absl::StrFormat(
"[%s]",
Token);
319 std::smatch
MatchMe(
const std::string& dfrag)
const {
322 std::regex_match(dfrag, match, pattern);
332const static std::string kWindowBorder =
"Window border";
333const static std::string kWindowPosition =
"Window position";
334const static std::string kScrollSpeed =
"Scroll speed";
335const static std::string kTextDrawSpeed =
"Text draw speed";
336const static std::string kTextColor =
"Text color";
337const static std::string kPlayerName =
"Player name";
338const static std::string kLine1Str =
"Line 1";
339const static std::string kLine2Str =
"Line 2";
340const static std::string kLine3Str =
"Line 3";
341const static std::string kWaitForKey =
"Wait for key";
342const static std::string kScrollText =
"Scroll text";
343const static std::string kDelayX =
"Delay X";
344const static std::string kBCDNumber =
"BCD number";
345const static std::string kSoundEffect =
"Sound effect";
346const static std::string kChoose3 =
"Choose 3";
347const static std::string kChoose2High =
"Choose 2 high";
348const static std::string kChoose2Low =
"Choose 2 low";
349const static std::string kChoose2Indented =
"Choose 2 indented";
350const static std::string kChooseItem =
"Choose item";
351const static std::string kNextAttractImage =
"Next attract image";
352const static std::string kBankMarker =
"Bank marker (automatic)";
353const static std::string kCrash =
"Crash";
355static const std::vector<TextElement> TextCommands = {
356 TextElement(0x6B,
"W",
true, kWindowBorder),
357 TextElement(0x6D,
"P",
true, kWindowPosition),
358 TextElement(0x6E,
"SPD",
true, kScrollSpeed),
359 TextElement(0x7A,
"S",
true, kTextDrawSpeed),
360 TextElement(0x77,
"C",
true, kTextColor),
361 TextElement(0x6A,
"L",
false, kPlayerName),
362 TextElement(0x74,
"1",
false, kLine1Str),
363 TextElement(0x75,
"2",
false, kLine2Str),
364 TextElement(0x76,
"3",
false, kLine3Str),
365 TextElement(0x7E,
"K",
false, kWaitForKey),
366 TextElement(0x73,
"V",
false, kScrollText),
367 TextElement(0x78,
"WT",
true, kDelayX),
368 TextElement(0x6C,
"N",
true, kBCDNumber),
369 TextElement(0x79,
"SFX",
true, kSoundEffect),
370 TextElement(0x71,
"CH3",
false, kChoose3),
371 TextElement(0x72,
"CH2",
false, kChoose2High),
372 TextElement(0x6F,
"CH2L",
false, kChoose2Low),
373 TextElement(0x68,
"CH2I",
false, kChoose2Indented),
374 TextElement(0x69,
"CHI",
false, kChooseItem),
375 TextElement(0x67,
"IMG",
false, kNextAttractImage),
376 TextElement(0x80,
kBankToken,
false, kBankMarker),
377 TextElement(0x70,
"NONO",
false, kCrash),
386static const std::vector<TextElement> SpecialChars = {
387 TextElement(0x43,
"...",
false,
"Ellipsis …"),
388 TextElement(0x4D,
"UP",
false,
"Arrow ↑"),
389 TextElement(0x4E,
"DOWN",
false,
"Arrow ↓"),
390 TextElement(0x4F,
"LEFT",
false,
"Arrow ←"),
391 TextElement(0x50,
"RIGHT",
false,
"Arrow →"),
392 TextElement(0x5B,
"A",
false,
"Button Ⓐ"),
393 TextElement(0x5C,
"B",
false,
"Button Ⓑ"),
394 TextElement(0x5D,
"X",
false,
"Button ⓧ"),
395 TextElement(0x5E,
"Y",
false,
"Button ⓨ"),
396 TextElement(0x52,
"HP1L",
false,
"1 HP left"),
397 TextElement(0x53,
"HP1R",
false,
"1 HP right"),
398 TextElement(0x54,
"HP2L",
false,
"2 HP left"),
399 TextElement(0x55,
"HP3L",
false,
"3 HP left"),
400 TextElement(0x56,
"HP3R",
false,
"3 HP right"),
401 TextElement(0x57,
"HP4L",
false,
"4 HP left"),
402 TextElement(0x58,
"HP4R",
false,
"4 HP right"),
403 TextElement(0x47,
"HY0",
false,
"Hieroglyph ☥"),
404 TextElement(0x48,
"HY1",
false,
"Hieroglyph 𓈗"),
405 TextElement(0x49,
"HY2",
false,
"Hieroglyph Ƨ"),
406 TextElement(0x4A,
"LFL",
false,
"Link face left"),
407 TextElement(0x4B,
"LFR",
false,
"Link face right"),
438 const std::vector<uint8_t>& rom_data,
int* current_pos);
444 std::vector<MessageData>& message_data,
445 const std::vector<DictionaryEntry>& dictionary_entries);
455 std::vector<std::string>& parsed_messages,
456 std::vector<MessageData>& expanded_messages,
457 std::vector<DictionaryEntry>& dictionary);
464 const std::vector<MessageData>& messages);
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
std::vector< MessageData > ReadAllTextData(uint8_t *rom, int pos)
uint8_t FindMatchingCharacter(char value)
const std::string kBankToken
nlohmann::json SerializeMessagesToJson(const std::vector< MessageData > &messages)
DictionaryEntry FindRealDictionaryEntry(uint8_t value, const std::vector< DictionaryEntry > &dictionary)
const std::string DICTIONARYTOKEN
constexpr uint8_t kScrollVertical
std::string ParseTextDataByte(uint8_t value)
absl::Status LoadExpandedMessages(std::string &expanded_message_path, std::vector< std::string > &parsed_messages, std::vector< MessageData > &expanded_messages, std::vector< DictionaryEntry > &dictionary)
std::string ReplaceAllDictionaryWords(std::string str, const std::vector< DictionaryEntry > &dictionary)
constexpr int kPointersDictionaries
constexpr int kNumDictionaryEntries
absl::StatusOr< MessageData > ParseSingleMessage(const std::vector< uint8_t > &rom_data, int *current_pos)
std::vector< std::string > ParseMessageData(std::vector< MessageData > &message_data, const std::vector< DictionaryEntry > &dictionary_entries)
std::optional< TextElement > FindMatchingSpecial(uint8_t value)
constexpr uint8_t kMessageTerminator
constexpr int kTextData2End
std::vector< DictionaryEntry > BuildDictionaryEntries(Rom *rom)
std::vector< uint8_t > ParseMessageToData(std::string str)
absl::Status ExportMessagesToJson(const std::string &path, const std::vector< MessageData > &messages)
constexpr uint8_t kWidthArraySize
constexpr uint8_t DICTOFF
std::optional< TextElement > FindMatchingCommand(uint8_t b)
ParsedElement FindMatchingElement(const std::string &str)
int8_t FindDictionaryEntry(uint8_t value)
constexpr int kTextDataEnd
bool ContainedInString(std::string_view s) const
std::string ReplaceInstancesOfIn(std::string_view s) const
DictionaryEntry(uint8_t i, std::string_view s)
std::vector< uint8_t > Data
DictionaryEntry()=default
MessageData(const MessageData &other)
std::vector< uint8_t > Data
std::vector< uint8_t > DataParsed
std::string ContentsParsed
std::string OptimizeMessageForDictionary(std::string_view message_string, const std::vector< DictionaryEntry > &dictionary)
void SetMessage(const std::string &message, const std::vector< DictionaryEntry > &dictionary)
MessageData(int id, int address, const std::string &rawString, const std::vector< uint8_t > &rawData, const std::string &parsedString, const std::vector< uint8_t > &parsedData)
ParsedElement(const TextElement &textElement, uint8_t value)
std::smatch MatchMe(const std::string &dfrag) const
std::string StrictPattern
TextElement(uint8_t id, const std::string &token, bool arg, const std::string &description)
bool operator==(const TextElement &other) const
std::string GetParamToken(uint8_t value=0) const