14 for (
const auto [key, char_value] : CharEncoder) {
15 if (value == char_value) {
23 if (value <
DICTOFF || value == 0xFF) {
30 for (
const auto& text_element : TextCommands) {
31 if (text_element.ID == b) {
39 auto it = std::ranges::find_if(SpecialChars,
41 return text_element.
ID == value;
43 if (it != SpecialChars.end()) {
51 std::vector<TextElement> commands_and_chars = TextCommands;
52 commands_and_chars.insert(commands_and_chars.end(), SpecialChars.begin(),
54 for (
auto& text_element : commands_and_chars) {
55 match = text_element.MatchMe(str);
56 if (match.size() > 0) {
57 if (text_element.HasArgument) {
58 std::string arg = match[1].str().substr(1);
60 return ParsedElement(text_element, std::stoi(arg,
nullptr, 16));
61 }
catch (
const std::invalid_argument& e) {
62 util::logf(
"Error parsing argument for %s: %s", text_element.GenericToken.c_str(), arg.c_str());
64 }
catch (
const std::out_of_range& e) {
65 util::logf(
"Argument out of range for %s: %s", text_element.GenericToken.c_str(), arg.c_str());
74 const auto dictionary_element =
77 match = dictionary_element.MatchMe(str);
78 if (match.size() > 0) {
81 DICTOFF + std::stoi(match[1].str(),
nullptr, 16));
82 }
catch (
const std::exception& e) {
83 util::logf(
"Error parsing dictionary token: %s", match[1].str().c_str());
91 if (CharEncoder.contains(value)) {
92 char c = CharEncoder.at(value);
100 text_element != std::nullopt) {
101 return text_element->GenericToken;
106 special_element != std::nullopt) {
107 return special_element->GenericToken;
112 if (dictionary >= 0) {
114 static_cast<unsigned char>(dictionary));
121 std::vector<uint8_t> bytes;
122 std::string temp_string = std::move(str);
124 while (pos < temp_string.size()) {
126 if (temp_string[pos] ==
'[') {
127 int next = temp_string.find(
']', pos);
135 const auto dictionary_element =
138 if (!parsedElement.
Active) {
139 util::logf(
"Error parsing message: %s", temp_string);
141 }
else if (parsedElement.
Parent == dictionary_element) {
142 bytes.push_back(parsedElement.
Value);
144 bytes.push_back(parsedElement.
Parent.
ID);
147 bytes.push_back(parsedElement.
Value);
166 std::vector<DictionaryEntry> AllDictionaries;
168 std::vector<uint8_t> bytes;
169 std::stringstream stringBuilder;
175 int temppush_backress =
180 while (address < temppush_backress) {
181 uint8_t uint8_tDictionary = rom->
data()[address++];
182 bytes.push_back(uint8_tDictionary);
186 AllDictionaries.push_back(
DictionaryEntry{(uint8_t)i, stringBuilder.str()});
189 std::ranges::sort(AllDictionaries,
194 return AllDictionaries;
198 std::string str,
const std::vector<DictionaryEntry>& dictionary) {
199 std::string temp = std::move(str);
200 for (
const auto& entry : dictionary) {
201 if (entry.ContainedInString(temp)) {
202 temp = entry.ReplaceInstancesOfIn(temp);
209 uint8_t value,
const std::vector<DictionaryEntry>& dictionary) {
210 for (
const auto& entry : dictionary) {
211 if (entry.ID +
DICTOFF == value) {
219 const std::vector<uint8_t>& rom_data,
int* current_pos) {
221 int pos = *current_pos;
222 uint8_t current_byte;
223 std::vector<uint8_t> temp_bytes_raw;
224 std::vector<uint8_t> temp_bytes_parsed;
225 std::string current_message_raw;
226 std::string current_message_parsed;
230 current_byte = rom_data[pos++];
233 message_data.
ID = message_data.
ID + 1;
235 message_data.
RawString = current_message_raw;
236 message_data.
Data = temp_bytes_raw;
240 temp_bytes_raw.clear();
241 temp_bytes_parsed.clear();
242 current_message_raw.clear();
243 current_message_parsed.clear();
246 }
else if (current_byte == 0xFF) {
250 temp_bytes_raw.push_back(current_byte);
254 if (text_element != std::nullopt) {
255 current_message_raw.append(text_element->GetParamToken());
256 current_message_parsed.append(text_element->GetParamToken());
257 temp_bytes_parsed.push_back(current_byte);
263 if (dictionary >= 0) {
264 current_message_raw.append(
"[");
266 current_message_raw.append(
":");
267 current_message_raw.append(
269 current_message_raw.append(
"]");
271 auto mutable_rom_data =
const_cast<uint8_t*
>(rom_data.data());
277 for (uint32_t i = address; i < address_end; i++) {
278 temp_bytes_parsed.push_back(rom_data[i]);
286 if (CharEncoder.contains(current_byte)) {
287 std::string str =
"";
288 str.push_back(CharEncoder.at(current_byte));
289 current_message_raw.append(str);
290 current_message_parsed.append(str);
291 temp_bytes_parsed.push_back(current_byte);
300 std::vector<MessageData>& message_data,
301 const std::vector<DictionaryEntry>& dictionary_entries) {
302 std::vector<std::string> parsed_messages;
304 for (
auto& message : message_data) {
305 std::string parsed_message =
"";
307 for (
size_t pos = 0; pos < message.Data.size(); ++pos) {
308 uint8_t
byte = message.
Data[pos];
312 if (text_element != std::nullopt) {
315 text_element->ID ==
kLine3) {
316 parsed_message.append(
"\n");
319 if (text_element->HasArgument && pos + 1 < message.Data.size()) {
320 uint8_t arg_byte = message.Data[pos + 1];
321 parsed_message.append(text_element->GetParamToken(arg_byte));
324 parsed_message.append(text_element->GetParamToken());
331 if (special_element != std::nullopt) {
332 parsed_message.append(special_element->GetParamToken());
339 for (
const auto& entry : dictionary_entries) {
340 if (entry.ID ==
byte -
DICTOFF) {
345 parsed_message.append(dic_entry.
Contents);
350 if (CharEncoder.contains(
byte)) {
351 parsed_message.push_back(CharEncoder.at(
byte));
354 parsed_messages.push_back(parsed_message);
357 return parsed_messages;
361 std::vector<MessageData> list_of_texts;
364 std::vector<uint8_t> raw_message;
365 std::vector<uint8_t> parsed_message;
366 std::string current_raw_message;
367 std::string current_parsed_message;
369 uint8_t current_byte = 0;
370 while (current_byte != 0xFF) {
371 current_byte = rom[pos++];
373 list_of_texts.push_back(
374 MessageData(message_id++, pos, current_raw_message, raw_message,
375 current_parsed_message, parsed_message));
377 parsed_message.clear();
378 current_raw_message.clear();
379 current_parsed_message.clear();
381 }
else if (current_byte == 0xFF) {
385 raw_message.push_back(current_byte);
388 if (text_element != std::nullopt) {
389 parsed_message.push_back(current_byte);
390 if (text_element->HasArgument) {
391 current_byte = rom[pos++];
392 raw_message.push_back(current_byte);
393 parsed_message.push_back(current_byte);
396 current_raw_message.append(text_element->GetParamToken(current_byte));
397 current_parsed_message.append(text_element->GetParamToken(current_byte));
408 if (special_element != std::nullopt) {
409 current_raw_message.append(special_element->GetParamToken());
410 current_parsed_message.append(special_element->GetParamToken());
411 parsed_message.push_back(current_byte);
417 if (dictionary >= 0) {
418 current_raw_message.append(absl::StrFormat(
424 uint32_t address_end =
427 for (uint32_t i = address; i < address_end; i++) {
428 parsed_message.push_back(rom[i]);
436 if (CharEncoder.contains(current_byte)) {
437 std::string str =
"";
438 str.push_back(CharEncoder.at(current_byte));
439 current_raw_message.append(str);
440 current_parsed_message.append(str);
441 parsed_message.push_back(current_byte);
445 return list_of_texts;
449 std::vector<std::string>& parsed_messages,
450 std::vector<MessageData>& expanded_messages,
451 std::vector<DictionaryEntry>& dictionary) {
452 static Rom expanded_message_rom;
453 if (!expanded_message_rom.
LoadFromFile(expanded_message_path).ok()) {
454 return absl::InternalError(
"Failed to load expanded message ROM");
457 auto parsed_expanded_messages =
460 for (
const auto& expanded_message : expanded_messages) {
461 parsed_messages.push_back(parsed_expanded_messages[expanded_message.ID]);
463 return absl::OkStatus();
467 nlohmann::json j = nlohmann::json::array();
468 for (
const auto& msg : messages) {
471 {
"address", msg.Address},
472 {
"raw_string", msg.RawString},
473 {
"parsed_string", msg.ContentsParsed}
480 const std::vector<MessageData>& messages) {
483 std::ofstream file(path);
484 if (!file.is_open()) {
485 return absl::InternalError(absl::StrFormat(
"Failed to open file for writing: %s", path));
488 return absl::OkStatus();
489 }
catch (
const std::exception& e) {
490 return absl::InternalError(absl::StrFormat(
"JSON export failed: %s", e.what()));
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::Status LoadFromFile(const std::string &filename, const LoadOptions &options=LoadOptions::Defaults())
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
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 DICTOFF
std::optional< TextElement > FindMatchingCommand(uint8_t b)
ParsedElement FindMatchingElement(const std::string &str)
int8_t FindDictionaryEntry(uint8_t value)
std::string HexWord(uint16_t word, HexStringParams params)
std::string HexByte(uint8_t byte, HexStringParams params)
void logf(const absl::FormatSpec< Args... > &format, Args &&... args)
uint32_t Get24LocalFromPC(uint8_t *data, int addr, bool pc=true)
uint32_t SnesToPc(uint32_t addr) noexcept
std::vector< uint8_t > Data
std::vector< uint8_t > DataParsed
std::string ContentsParsed