From 496ebc9a1b0f3df537c70921f877d293819a2428 Mon Sep 17 00:00:00 2001 From: Henny022p Date: Tue, 23 Nov 2021 06:44:00 +0100 Subject: moved tmc_strings --- tools/src/tmc_strings/main.cpp | 799 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 799 insertions(+) create mode 100644 tools/src/tmc_strings/main.cpp (limited to 'tools/src/tmc_strings/main.cpp') diff --git a/tools/src/tmc_strings/main.cpp b/tools/src/tmc_strings/main.cpp new file mode 100644 index 00000000..6490113a --- /dev/null +++ b/tools/src/tmc_strings/main.cpp @@ -0,0 +1,799 @@ +#include +#include +#include + +using namespace std::string_literals; +using json = nlohmann::json; +using u8 = std::uint8_t; +using u16 = std::uint16_t; +using u32 = std::uint32_t; + +const u32 RomStartAddress = 0x8000000; + +namespace { + + struct LanguageTable { + const char *name; + u32 address; + }; + + enum Color { + Color_White, + Color_Red, + Color_Green, + Color_Blue, + Color_Yellow, + + Color_Count, + }; + + constexpr const char *const ColorStrings[] = { + "White", + "Red", + "Green", + "Blue", + "Yellow", + }; + + enum Input { + Input_A, + Input_B, + Input_Left, + Input_Right, + Input_DUp, + Input_DDown, + Input_DLeft, + Input_DRight, + Input_Dpad, + Input_Select, + Input_Start, + + Input_Count, + }; + + constexpr const char *const InputStrings[] = { + "A", + "B", + "Left", + "Right", + "DUp", + "DDown", + "DLeft", + "DRight", + "Dpad", + "Select", + "Start", + }; + + const std::map CharConvertArray = { + {0x0a, "\n"}, + {0x0d, "\r"}, + {0x20, " "}, + {0x21, "!"}, + {0x22, "\""}, + {0x23, "#"}, + {0x24, "$"}, + {0x25, "%"}, + {0x26, "&"}, + {0x27, "\'"}, + {0x28, "("}, + {0x29, ")"}, + {0x2a, "*"}, + {0x2b, "+"}, + {0x2c, ","}, + {0x2d, "-"}, + {0x2e, "."}, + {0x2f, "/"}, + {0x30, "0"}, + {0x31, "1"}, + {0x32, "2"}, + {0x33, "3"}, + {0x34, "4"}, + {0x35, "5"}, + {0x36, "6"}, + {0x37, "7"}, + {0x38, "8"}, + {0x39, "9"}, + {0x3a, ":"}, + {0x3b, ";"}, + {0x3c, "<"}, + {0x3d, "="}, + {0x3e, ">"}, + {0x3f, "?"}, + {0x40, "@"}, + {0x41, "A"}, + {0x42, "B"}, + {0x43, "C"}, + {0x44, "D"}, + {0x45, "E"}, + {0x46, "F"}, + {0x47, "G"}, + {0x48, "H"}, + {0x49, "I"}, + {0x4a, "J"}, + {0x4b, "K"}, + {0x4c, "L"}, + {0x4d, "M"}, + {0x4e, "N"}, + {0x4f, "O"}, + {0x50, "P"}, + {0x51, "Q"}, + {0x52, "R"}, + {0x53, "S"}, + {0x54, "T"}, + {0x55, "U"}, + {0x56, "V"}, + {0x57, "W"}, + {0x58, "X"}, + {0x59, "Y"}, + {0x5a, "Z"}, + {0x5b, "["}, + {0x5c, "\'"}, + {0x5d, "]"}, + {0x5e, "^"}, + {0x5f, "_"}, + {0x60, "`"}, + {0x61, "a"}, + {0x62, "b"}, + {0x63, "c"}, + {0x64, "d"}, + {0x65, "e"}, + {0x66, "f"}, + {0x67, "g"}, + {0x68, "h"}, + {0x69, "i"}, + {0x6a, "j"}, + {0x6b, "k"}, + {0x6c, "l"}, + {0x6d, "m"}, + {0x6e, "n"}, + {0x6f, "o"}, + {0x70, "p"}, + {0x71, "q"}, + {0x72, "r"}, + {0x73, "s"}, + {0x74, "t"}, + {0x75, "u"}, + {0x76, "v"}, + {0x77, "w"}, + {0x78, "x"}, + {0x79, "y"}, + {0x7a, "z"}, + {0x82, ","}, + {0x84, "„"}, + {0x85, "⋯"}, + {0x8A, "Š"}, + {0x8B, "‹"}, + {0x8C, "Œ"}, + {0x8E, "Ž"}, + {0x91, "‘"}, + {0x92, "’"}, + {0x93, "“"}, + {0x94, "”"}, + {0x95, "·"}, + {0x99, "™"}, + {0x9A, "š"}, + {0x9B, "›"}, + {0x9C, "œ"}, + {0x9E, "ž"}, + {0x9F, "Ÿ"}, + {0xA1, "¡"}, + {0xA3, "♪"}, + {0xAA, "ª"}, + {0xAB, "«"}, + {0xB0, "º"}, + {0xB4, "'"}, + {0xB7, "´"}, + {0xBA, "º"}, + {0xBB, "»"}, + {0xBF, "¿"}, + {0xC0, "À"}, + {0xC1, "Á"}, + {0xC2, "Â"}, + {0xC3, "Ã"}, + {0xC4, "Ä"}, + {0xC5, "Å"}, + {0xC6, "Æ"}, + {0xC7, "Ç"}, + {0xC8, "È"}, + {0xC9, "É"}, + {0xCA, "Ê"}, + {0xCB, "Ë"}, + {0xCC, "Ì"}, + {0xCD, "Í"}, + {0xCE, "Î"}, + {0xCF, "Ï"}, + {0xD0, "Đ"}, + {0xD1, "Ñ"}, + {0xD2, "Ò"}, + {0xD3, "Ó"}, + {0xD4, "Ô"}, + {0xD5, "Õ"}, + {0xD6, "Ö"}, + {0xD7, "×"}, + {0xD8, "Ø"}, + {0xD9, "Ù"}, + {0xDA, "Ú"}, + {0xDB, "Û"}, + {0xDC, "Ü"}, + {0xDD, "Ý"}, + {0xDE, "Þ"}, + {0xDF, "β"}, + {0xE0, "à"}, + {0xE1, "á"}, + {0xE2, "â"}, + {0xE3, "ã"}, + {0xE4, "ä"}, + {0xE5, "å"}, + {0xE6, "æ"}, + {0xE7, "ç"}, + {0xE8, "è"}, + {0xE9, "é"}, + {0xEA, "ê"}, + {0xEB, "ë"}, + {0xEC, "ì"}, + {0xED, "í"}, + {0xEE, "î"}, + {0xEF, "ï"}, + {0xF0, "ð"}, + {0xF1, "ñ"}, + {0xF2, "ò"}, + {0xF3, "ó"}, + {0xF4, "ô"}, + {0xF5, "õ"}, + {0xF6, "ö"}, + {0xF7, "÷"}, + {0xF8, "ø"}, + {0xF9, "ù"}, + {0xFA, "ú"}, + {0xFB, "û"}, + {0xFC, "ü"}, + {0xFD, "ý"}, + {0xFE, "þ"}, + {0xFF, "ÿ"}, + }; + + using ConvertFunction = std::string (*const)(const char *&); + + std::string Unk1Handler(const char *&ptr) { + u8 a = *ptr++; + return fmt::format("{{01:{:02X}}}", a); + } + + std::string ColorHandler(const char *&ptr) { + u8 color = *ptr++; + if (color >= Color_Count) + throw std::runtime_error(ptr); + return fmt::format("{{Color:{}}}", ColorStrings[color]); + } + + std::string SoundHandler(const char *&ptr) { + u8 a = *ptr++; + u8 b = *ptr++; + return fmt::format("{{Sound:{:02X}:{:02X}}}", a, b); + } + + std::string Unk4Handler(const char *&ptr) { + u8 a = *ptr++; + if (a == 0x10) { + u8 b = *ptr++; + return fmt::format("{{04:{:02X}:{:02X}}}", a, b); + } else { + return fmt::format("{{04:{:02X}}}", a); + } + } + + std::string ChoiceHandler(const char *&ptr) { + u8 category = *ptr++; + if (category == 0xff) { + return "{Choice:FF}"; + } else { + u8 action = *ptr++; + return fmt::format("{{Choice:{:02X}:{:02X}}}", category, action); + } + } + + std::string VariableHandler(const char *&ptr) { + u8 idx = *ptr++; + if (idx == 0) { + return "{Player}"; + } else { + return fmt::format("{{Var:{:X}}}", idx); + } + } + + std::string Unk7Handler(const char *&ptr) { + u8 a = *ptr++; + u8 b = *ptr++; + return fmt::format("{{07:{:02X}:{:02X}}}", a, b); + } + + std::string Unk8Handler(const char *&ptr) { + u8 a = *ptr++; + if (a != 0xff) + throw std::runtime_error("unmatched unk8: "s + std::to_string(a)); + return "{08:FF}"; + } + + std::string Unk9Handler(const char *&ptr) { + u8 a = *ptr++; + if (a != 0x78 && a != 0x00) + throw std::runtime_error("unmatched unk8: "s + std::to_string(a)); + return fmt::format("{{09:{:02X}}}", a); + } + + std::string InputHandler(const char *&ptr) { + u8 key = *ptr++; + if (key > 8) + throw std::runtime_error("unmatched key: "s + std::to_string(key)); + return fmt::format("{{Key:{}}}", InputStrings[key]); + } + + std::string SymbolHandler(const char *&ptr) { + u8 a = *ptr++; + return fmt::format("{{Symbol:{:02X}}}", a); + } + + const std::map FuncConvertArray = { + {0x01, Unk1Handler}, + {0x02, ColorHandler}, + {0x03, SoundHandler}, + {0x04, Unk4Handler}, + {0x05, ChoiceHandler}, + {0x06, VariableHandler}, + {0x07, Unk7Handler}, + {0x08, Unk8Handler}, + {0x09, Unk9Handler}, + {0x0c, InputHandler}, + {0x0f, SymbolHandler}, + }; + + std::string ParseTMCString(const char *ptr) { + std::string ret; + + while (*ptr) { + u8 c = *ptr++; + + /* Convert character. */ + { + const auto it = CharConvertArray.find(c); + + if (it != std::end(CharConvertArray)) { + ret += it->second; + continue; + } + } + + /* Convert function. */ + { + const auto it = FuncConvertArray.find(c); + + if (it != std::end(FuncConvertArray)) { + ret += it->second(ptr); + continue; + } + } + + throw std::runtime_error(fmt::format("Unknown characters: {}", ptr)); + } + + return ret; + } + + using RevertFunction = void (*)(const char *&, char *&); + + void ColorRevert(const char *&src, char *&dst) { + *dst++ = 0x02; + src++; // ':' + for (u32 i = 0; i < Color_Count; i++) { + const char *const color = ColorStrings[i]; + const std::size_t color_len = std::strlen(color); + if (std::strncmp(src, color, color_len) == 0) { + *dst++ = i; + src += color_len; + return; + } + } + + throw std::runtime_error(fmt::format("Color not found: {}", src)); + } + + void SoundRevert(const char *&src, char *&dst) { + *dst++ = 0x03; + *dst++ = std::strtoul(++src, nullptr, 0x10); + src += 2; + *dst++ = std::strtoul(++src, nullptr, 0x10); + src += 2; + } + + void ChoiceRevert(const char *&src, char *&dst) { + *dst++ = 0x05; + u8 choice = std::strtoul(++src, nullptr, 0x10); + + *dst++ = choice; + src += 2; + + if (choice == 0xff) + return; + + *dst++ = std::strtoul(++src, nullptr, 0x10); + src += 2; + } + + void PlayerRevert(const char *&src, char *&dst) { + *dst++ = 0x06; + *dst++ = 0x00; + + (void)src; + } + + void VariableRevert(const char *&src, char *&dst) { + *dst++ = 0x06; + src++; // ':' + + *dst++ = std::strtoul(src, nullptr, 0x10); + src++; + } + + void KeyRevert(const char *&src, char *&dst) { + *dst++ = 0x0c; + src++; // ':' + for (u32 i = 0; i < Input_Count; i++) { + const char *const input = InputStrings[i]; + const std::size_t input_len = std::strlen(input); + if (std::strncmp(src, input, input_len) == 0) { + *dst++ = i; + src += input_len; + return; + } + } + + throw std::runtime_error(fmt::format("Input not found: {}", src)); + } + + void SymbolRevert(const char *&src, char *&dst) { + *dst++ = 0x0f; + src++; // ':' + + *dst++ = std::strtoul(src, nullptr, 0x10); + src += 2; + } + + const std::pair FuncRevertArray[] = { + {"Color", ColorRevert}, + {"Sound", SoundRevert}, + {"Choice", ChoiceRevert}, + {"Player", PlayerRevert}, + {"Var", VariableRevert}, + {"Key", KeyRevert}, + {"Symbol", SymbolRevert}, + }; + + void WriteTMCString(char *&dst, const std::string &src) { + const char *ptr = src.data(); + + while (*ptr) { + /* Parse special */ + { + if (*ptr == '{') { + ptr++; + const auto it = std::find_if(std::begin(FuncRevertArray), std::end(FuncRevertArray), [&](const auto &data) { + return std::strncmp(ptr, data.first.c_str(), data.first.size()) == 0; + }); + + if (it != std::end(FuncRevertArray)) { + ptr += it->first.size(); + it->second(ptr, dst); + } else { + do { + *dst++ = std::strtoul(ptr, nullptr, 0x10); + ptr += 2; + } while (*ptr == ':' && (ptr++, true)); + } + + if (*ptr != '}') + throw std::runtime_error(fmt::format("unmatched characters: \"{}\"\n", ptr)); + + ptr++; + continue; + } + } + + /* Convert character. */ + { + const auto it = std::find_if(std::begin(CharConvertArray), std::end(CharConvertArray), [ptr](const auto &data) { + return std::strncmp(ptr, data.second.c_str(), data.second.length()) == 0; + }); + + if (it != std::end(CharConvertArray)) { + ptr += it->second.size(); + *dst++ = it->first; + continue; + } + } + + throw std::runtime_error(fmt::format("unmatched characters: \"{}\"\n", ptr)); + } + *dst++ = '\0'; + } + +} + +void ExtractStringTable(std::string &rom_path, const std::vector &tables) { + const std::vector rom = [&]() { + std::vector rom; + + /* Open ROM. */ + std::ifstream rom_file(rom_path, std::ios::in); + + if (!rom_file.good()) { + fmt::print(stderr, "Couldn't open ROM {}\n", rom_path); + exit(EXIT_FAILURE); + } + + /* Get ROM size. */ + rom_file.seekg(0, std::ios::end); + const std::size_t rom_size = rom_file.tellg(); + + /* Read ROM to buffer. */ + rom.resize(rom_size); + rom_file.seekg(0, std::ios::beg); + rom_file.read(&rom[0], rom_size); + + return rom; + }(); + + auto ReadAbsolute = [&](u32 address) -> u32 { + return *(u32 *)&rom[address - RomStartAddress]; + }; + + for (auto &language : tables) { + /* Get category table start. */ + const std::size_t table_start = language.address; + + /* Get category count. */ + const std::size_t category_count = ReadAbsolute(table_start) / sizeof(u32); + + /* Read category offsets. */ + std::vector category_table(category_count); + std::memcpy(&category_table[0], &rom[table_start - RomStartAddress], category_count * sizeof(u32)); + + json j = json::array(); + + for (auto &category_offset : category_table) { + /* Get string table start. */ + const std::size_t category_start = table_start + category_offset; + + /* Get string count. */ + const std::size_t string_count = ReadAbsolute(category_start) / sizeof(u32); + + /* Read string offsets. */ + std::vector string_table(string_count); + std::memcpy(&string_table[0], &rom[category_start - RomStartAddress], string_count * sizeof(u32)); + + auto &category = j.emplace_back(); + + for (std::size_t l = 0; l < string_count; l++) { + /* Get string start. */ + const std::size_t string_start = category_start + string_table[l]; + + /* Parse TMC. */ + category[l] = ParseTMCString(&rom[string_start - RomStartAddress]); + } + } + + const std::string out_path = language.name + ".json"s; + std::ofstream ofs(out_path); + ofs << j.dump(4); + } +} + +void PackStringTable(const std::string &src_path, const std::string &dst_path, const std::size_t out_size) { + const json j = [&]() -> json { + std::ifstream ifs(src_path); + + if (!ifs.good()) { + fmt::print(stderr, "Couldn't open JSON {}\n", src_path); + exit(EXIT_FAILURE); + } + + return json::parse(ifs); + }(); + + std::vector buffer(0x100000); + std::uintptr_t root_start = (std::uintptr_t)buffer.data(); + + char *root_ptr = buffer.data(); + char *table = buffer.data() + j.size() * sizeof(u32); + + for (auto &category : j) { + char *table_ptr = table; + char *str_start = table_ptr + category.size() * sizeof(u32); + char *str_ptr = str_start; + for (auto &str_j : category) { + /* Write string offset to table. */ + *(u32 *)table_ptr = (std::uintptr_t)str_ptr - (std::uintptr_t)table; + table_ptr += sizeof(u32); + + auto str = str_j.get(); + + /* Copy string to table. */ + WriteTMCString(str_ptr, str); + } + + /* Align string table size by 16 bytes. */ + while (static_cast(str_ptr - str_start) & 0xf) { + *str_ptr = 0xff; + str_ptr++; + } + + /* Write category offset to root table. */ + *(u32 *)root_ptr = (std::uintptr_t)table - root_start; + root_ptr += sizeof(u32); + + table = str_ptr; + } + + /* Align table end to 0x10 bytes. */ + while ((std::uintptr_t)table & 0xf) { + *table++ = 0xff; + } + + std::size_t table_size = (uintptr_t)table - root_start; + + if (out_size) { + /* Abort if string table is too big. */ + if (table_size > out_size) { + fmt::print(stderr, "Table is too big. Should be {} but was {}", out_size, table_size); + exit(EXIT_FAILURE); + } + + /* Pad table if it's too small. */ + while (table_size < out_size) { + *table++ = 0xff; + table_size++; + } + } + + std::ofstream ofs(dst_path); + ofs.write(buffer.data(), table_size); +} + +// clang-format off +const std::vector LanguageTableUS = { + {"USA", 0x89B1D90}, +}; + +const std::vector LanguageTableEU = { + {"English", 0x89AEB60}, + {"French", 0x89F7420}, + {"German", 0x8A3EEB0}, + {"Spanish", 0x8A81E70}, + {"Italian", 0x8AC37A0}, +}; +// clang-format on + +#include + +const char *progname; + +void usage() { + fmt::print(stderr, + "tmc_strings (c) Luis Scheurenbrand\n" + "Built: " __TIME__ " " __DATE__ "\n" + "\n" + "Usage: {} [options...]\n" + "Options:\n" + " -x, --extract Extract string table from ROM and store it in json format. (Default)\n" + " -p, --pack Pack a string table from json format.\n" + " --region Specify ROM region. [USA, EU]\n" + " --source Specify source (-x: ROM, -p: JSON)\n" + " --dest Specify string table destination.\n" + " --size Specify string table size.\n", + progname); +} + +// clang-format off +constexpr const struct option long_options[] = { + {"extract", no_argument, nullptr, 'x'}, + {"pack", no_argument, nullptr, 'p'}, + {"region", required_argument, nullptr, 0}, + {"source", required_argument, nullptr, 1}, + {"dest", required_argument, nullptr, 2}, + {"size", required_argument, nullptr, 3}, + {}, +}; +// clang-format on + +int main(int argc, char **argv) { + std::string src_path; + std::string dst_path; + std::size_t max_size = 0; + + progname = (argc < 1) ? "tmc_strings" : argv[0]; + + enum { + Mode_Extract, + Mode_Pack, + } mode = Mode_Extract; + + enum { + Region_USA, + Region_JAPAN, + Region_EU, + } region = Region_USA; + + while (true) { + int opt_index; + int c = getopt_long(argc, argv, "xp", long_options, &opt_index); + if (c == -1) + break; + + switch (c) { + case 'x': + mode = Mode_Extract; + break; + case 'p': + mode = Mode_Pack; + break; + case 0: + if (strcmp(optarg, "USA") == 0) { + region = Region_USA; + } else if (strcmp(optarg, "EU") == 0) { + region = Region_EU; + } else if (strcmp(optarg, "JAPAN") == 0) { + region = Region_JAPAN; + fmt::print("Region unsupported\n\n"); + usage(); + exit(EXIT_FAILURE); + } + break; + case 1: + src_path = optarg; + break; + case 2: + dst_path = optarg; + break; + case 3: + max_size = std::strtoul(optarg, nullptr, 0); + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + switch (mode) { + case Mode_Extract: + if (src_path == "") { + fmt::print("ROM source path not supplied.\n\n"); + usage(); + exit(EXIT_FAILURE); + } + ExtractStringTable(src_path, [region]() { + switch (region) { + case Region_USA: + return LanguageTableUS; + case Region_EU: + return LanguageTableEU; + default: + fmt::print("Region unsupported\n\n"); + usage(); + exit(EXIT_FAILURE); + } + }()); + break; + case Mode_Pack: + if (src_path == "" || dst_path == "") { + fmt::print("Source or destination path not supplied\n\n"); + usage(); + exit(EXIT_FAILURE); + } + if (max_size == 0) { + fmt::print("Max size not supplied. Assuming shiftable.\n"); + } + PackStringTable(src_path, dst_path, max_size); + } + + return EXIT_SUCCESS; +} -- cgit v1.2.3 From dee773da4a12af1c48bf58d6275fe4fed20871b6 Mon Sep 17 00:00:00 2001 From: Henny022p Date: Tue, 23 Nov 2021 09:31:09 +0100 Subject: apply clang-format to tool sources --- tools/src/tmc_strings/main.cpp | 763 ++++++++++++++++------------------------- 1 file changed, 289 insertions(+), 474 deletions(-) (limited to 'tools/src/tmc_strings/main.cpp') diff --git a/tools/src/tmc_strings/main.cpp b/tools/src/tmc_strings/main.cpp index 6490113a..7f5bbf22 100644 --- a/tools/src/tmc_strings/main.cpp +++ b/tools/src/tmc_strings/main.cpp @@ -4,522 +4,339 @@ using namespace std::string_literals; using json = nlohmann::json; -using u8 = std::uint8_t; -using u16 = std::uint16_t; -using u32 = std::uint32_t; +using u8 = std::uint8_t; +using u16 = std::uint16_t; +using u32 = std::uint32_t; const u32 RomStartAddress = 0x8000000; namespace { - struct LanguageTable { - const char *name; - u32 address; - }; - - enum Color { - Color_White, - Color_Red, - Color_Green, - Color_Blue, - Color_Yellow, - - Color_Count, - }; - - constexpr const char *const ColorStrings[] = { - "White", - "Red", - "Green", - "Blue", - "Yellow", - }; - - enum Input { - Input_A, - Input_B, - Input_Left, - Input_Right, - Input_DUp, - Input_DDown, - Input_DLeft, - Input_DRight, - Input_Dpad, - Input_Select, - Input_Start, - - Input_Count, - }; - - constexpr const char *const InputStrings[] = { - "A", - "B", - "Left", - "Right", - "DUp", - "DDown", - "DLeft", - "DRight", - "Dpad", - "Select", - "Start", - }; - - const std::map CharConvertArray = { - {0x0a, "\n"}, - {0x0d, "\r"}, - {0x20, " "}, - {0x21, "!"}, - {0x22, "\""}, - {0x23, "#"}, - {0x24, "$"}, - {0x25, "%"}, - {0x26, "&"}, - {0x27, "\'"}, - {0x28, "("}, - {0x29, ")"}, - {0x2a, "*"}, - {0x2b, "+"}, - {0x2c, ","}, - {0x2d, "-"}, - {0x2e, "."}, - {0x2f, "/"}, - {0x30, "0"}, - {0x31, "1"}, - {0x32, "2"}, - {0x33, "3"}, - {0x34, "4"}, - {0x35, "5"}, - {0x36, "6"}, - {0x37, "7"}, - {0x38, "8"}, - {0x39, "9"}, - {0x3a, ":"}, - {0x3b, ";"}, - {0x3c, "<"}, - {0x3d, "="}, - {0x3e, ">"}, - {0x3f, "?"}, - {0x40, "@"}, - {0x41, "A"}, - {0x42, "B"}, - {0x43, "C"}, - {0x44, "D"}, - {0x45, "E"}, - {0x46, "F"}, - {0x47, "G"}, - {0x48, "H"}, - {0x49, "I"}, - {0x4a, "J"}, - {0x4b, "K"}, - {0x4c, "L"}, - {0x4d, "M"}, - {0x4e, "N"}, - {0x4f, "O"}, - {0x50, "P"}, - {0x51, "Q"}, - {0x52, "R"}, - {0x53, "S"}, - {0x54, "T"}, - {0x55, "U"}, - {0x56, "V"}, - {0x57, "W"}, - {0x58, "X"}, - {0x59, "Y"}, - {0x5a, "Z"}, - {0x5b, "["}, - {0x5c, "\'"}, - {0x5d, "]"}, - {0x5e, "^"}, - {0x5f, "_"}, - {0x60, "`"}, - {0x61, "a"}, - {0x62, "b"}, - {0x63, "c"}, - {0x64, "d"}, - {0x65, "e"}, - {0x66, "f"}, - {0x67, "g"}, - {0x68, "h"}, - {0x69, "i"}, - {0x6a, "j"}, - {0x6b, "k"}, - {0x6c, "l"}, - {0x6d, "m"}, - {0x6e, "n"}, - {0x6f, "o"}, - {0x70, "p"}, - {0x71, "q"}, - {0x72, "r"}, - {0x73, "s"}, - {0x74, "t"}, - {0x75, "u"}, - {0x76, "v"}, - {0x77, "w"}, - {0x78, "x"}, - {0x79, "y"}, - {0x7a, "z"}, - {0x82, ","}, - {0x84, "„"}, - {0x85, "⋯"}, - {0x8A, "Š"}, - {0x8B, "‹"}, - {0x8C, "Œ"}, - {0x8E, "Ž"}, - {0x91, "‘"}, - {0x92, "’"}, - {0x93, "“"}, - {0x94, "”"}, - {0x95, "·"}, - {0x99, "™"}, - {0x9A, "š"}, - {0x9B, "›"}, - {0x9C, "œ"}, - {0x9E, "ž"}, - {0x9F, "Ÿ"}, - {0xA1, "¡"}, - {0xA3, "♪"}, - {0xAA, "ª"}, - {0xAB, "«"}, - {0xB0, "º"}, - {0xB4, "'"}, - {0xB7, "´"}, - {0xBA, "º"}, - {0xBB, "»"}, - {0xBF, "¿"}, - {0xC0, "À"}, - {0xC1, "Á"}, - {0xC2, "Â"}, - {0xC3, "Ã"}, - {0xC4, "Ä"}, - {0xC5, "Å"}, - {0xC6, "Æ"}, - {0xC7, "Ç"}, - {0xC8, "È"}, - {0xC9, "É"}, - {0xCA, "Ê"}, - {0xCB, "Ë"}, - {0xCC, "Ì"}, - {0xCD, "Í"}, - {0xCE, "Î"}, - {0xCF, "Ï"}, - {0xD0, "Đ"}, - {0xD1, "Ñ"}, - {0xD2, "Ò"}, - {0xD3, "Ó"}, - {0xD4, "Ô"}, - {0xD5, "Õ"}, - {0xD6, "Ö"}, - {0xD7, "×"}, - {0xD8, "Ø"}, - {0xD9, "Ù"}, - {0xDA, "Ú"}, - {0xDB, "Û"}, - {0xDC, "Ü"}, - {0xDD, "Ý"}, - {0xDE, "Þ"}, - {0xDF, "β"}, - {0xE0, "à"}, - {0xE1, "á"}, - {0xE2, "â"}, - {0xE3, "ã"}, - {0xE4, "ä"}, - {0xE5, "å"}, - {0xE6, "æ"}, - {0xE7, "ç"}, - {0xE8, "è"}, - {0xE9, "é"}, - {0xEA, "ê"}, - {0xEB, "ë"}, - {0xEC, "ì"}, - {0xED, "í"}, - {0xEE, "î"}, - {0xEF, "ï"}, - {0xF0, "ð"}, - {0xF1, "ñ"}, - {0xF2, "ò"}, - {0xF3, "ó"}, - {0xF4, "ô"}, - {0xF5, "õ"}, - {0xF6, "ö"}, - {0xF7, "÷"}, - {0xF8, "ø"}, - {0xF9, "ù"}, - {0xFA, "ú"}, - {0xFB, "û"}, - {0xFC, "ü"}, - {0xFD, "ý"}, - {0xFE, "þ"}, - {0xFF, "ÿ"}, - }; - - using ConvertFunction = std::string (*const)(const char *&); - - std::string Unk1Handler(const char *&ptr) { - u8 a = *ptr++; - return fmt::format("{{01:{:02X}}}", a); - } +struct LanguageTable { + const char* name; + u32 address; +}; - std::string ColorHandler(const char *&ptr) { - u8 color = *ptr++; - if (color >= Color_Count) - throw std::runtime_error(ptr); - return fmt::format("{{Color:{}}}", ColorStrings[color]); - } +enum Color { + Color_White, + Color_Red, + Color_Green, + Color_Blue, + Color_Yellow, - std::string SoundHandler(const char *&ptr) { - u8 a = *ptr++; - u8 b = *ptr++; - return fmt::format("{{Sound:{:02X}:{:02X}}}", a, b); - } + Color_Count, +}; - std::string Unk4Handler(const char *&ptr) { - u8 a = *ptr++; - if (a == 0x10) { - u8 b = *ptr++; - return fmt::format("{{04:{:02X}:{:02X}}}", a, b); - } else { - return fmt::format("{{04:{:02X}}}", a); - } - } +constexpr const char* const ColorStrings[] = { + "White", "Red", "Green", "Blue", "Yellow", +}; - std::string ChoiceHandler(const char *&ptr) { - u8 category = *ptr++; - if (category == 0xff) { - return "{Choice:FF}"; - } else { - u8 action = *ptr++; - return fmt::format("{{Choice:{:02X}:{:02X}}}", category, action); - } - } +enum Input { + Input_A, + Input_B, + Input_Left, + Input_Right, + Input_DUp, + Input_DDown, + Input_DLeft, + Input_DRight, + Input_Dpad, + Input_Select, + Input_Start, + + Input_Count, +}; - std::string VariableHandler(const char *&ptr) { - u8 idx = *ptr++; - if (idx == 0) { - return "{Player}"; - } else { - return fmt::format("{{Var:{:X}}}", idx); - } - } +constexpr const char* const InputStrings[] = { + "A", "B", "Left", "Right", "DUp", "DDown", "DLeft", "DRight", "Dpad", "Select", "Start", +}; + +const std::map CharConvertArray = { + { 0x0a, "\n" }, { 0x0d, "\r" }, { 0x20, " " }, { 0x21, "!" }, { 0x22, "\"" }, { 0x23, "#" }, { 0x24, "$" }, + { 0x25, "%" }, { 0x26, "&" }, { 0x27, "\'" }, { 0x28, "(" }, { 0x29, ")" }, { 0x2a, "*" }, { 0x2b, "+" }, + { 0x2c, "," }, { 0x2d, "-" }, { 0x2e, "." }, { 0x2f, "/" }, { 0x30, "0" }, { 0x31, "1" }, { 0x32, "2" }, + { 0x33, "3" }, { 0x34, "4" }, { 0x35, "5" }, { 0x36, "6" }, { 0x37, "7" }, { 0x38, "8" }, { 0x39, "9" }, + { 0x3a, ":" }, { 0x3b, ";" }, { 0x3c, "<" }, { 0x3d, "=" }, { 0x3e, ">" }, { 0x3f, "?" }, { 0x40, "@" }, + { 0x41, "A" }, { 0x42, "B" }, { 0x43, "C" }, { 0x44, "D" }, { 0x45, "E" }, { 0x46, "F" }, { 0x47, "G" }, + { 0x48, "H" }, { 0x49, "I" }, { 0x4a, "J" }, { 0x4b, "K" }, { 0x4c, "L" }, { 0x4d, "M" }, { 0x4e, "N" }, + { 0x4f, "O" }, { 0x50, "P" }, { 0x51, "Q" }, { 0x52, "R" }, { 0x53, "S" }, { 0x54, "T" }, { 0x55, "U" }, + { 0x56, "V" }, { 0x57, "W" }, { 0x58, "X" }, { 0x59, "Y" }, { 0x5a, "Z" }, { 0x5b, "[" }, { 0x5c, "\'" }, + { 0x5d, "]" }, { 0x5e, "^" }, { 0x5f, "_" }, { 0x60, "`" }, { 0x61, "a" }, { 0x62, "b" }, { 0x63, "c" }, + { 0x64, "d" }, { 0x65, "e" }, { 0x66, "f" }, { 0x67, "g" }, { 0x68, "h" }, { 0x69, "i" }, { 0x6a, "j" }, + { 0x6b, "k" }, { 0x6c, "l" }, { 0x6d, "m" }, { 0x6e, "n" }, { 0x6f, "o" }, { 0x70, "p" }, { 0x71, "q" }, + { 0x72, "r" }, { 0x73, "s" }, { 0x74, "t" }, { 0x75, "u" }, { 0x76, "v" }, { 0x77, "w" }, { 0x78, "x" }, + { 0x79, "y" }, { 0x7a, "z" }, { 0x82, "," }, { 0x84, "„" }, { 0x85, "⋯" }, { 0x8A, "Š" }, { 0x8B, "‹" }, + { 0x8C, "Œ" }, { 0x8E, "Ž" }, { 0x91, "‘" }, { 0x92, "’" }, { 0x93, "“" }, { 0x94, "”" }, { 0x95, "·" }, + { 0x99, "™" }, { 0x9A, "š" }, { 0x9B, "›" }, { 0x9C, "œ" }, { 0x9E, "ž" }, { 0x9F, "Ÿ" }, { 0xA1, "¡" }, + { 0xA3, "♪" }, { 0xAA, "ª" }, { 0xAB, "«" }, { 0xB0, "º" }, { 0xB4, "'" }, { 0xB7, "´" }, { 0xBA, "º" }, + { 0xBB, "»" }, { 0xBF, "¿" }, { 0xC0, "À" }, { 0xC1, "Á" }, { 0xC2, "Â" }, { 0xC3, "Ã" }, { 0xC4, "Ä" }, + { 0xC5, "Å" }, { 0xC6, "Æ" }, { 0xC7, "Ç" }, { 0xC8, "È" }, { 0xC9, "É" }, { 0xCA, "Ê" }, { 0xCB, "Ë" }, + { 0xCC, "Ì" }, { 0xCD, "Í" }, { 0xCE, "Î" }, { 0xCF, "Ï" }, { 0xD0, "Đ" }, { 0xD1, "Ñ" }, { 0xD2, "Ò" }, + { 0xD3, "Ó" }, { 0xD4, "Ô" }, { 0xD5, "Õ" }, { 0xD6, "Ö" }, { 0xD7, "×" }, { 0xD8, "Ø" }, { 0xD9, "Ù" }, + { 0xDA, "Ú" }, { 0xDB, "Û" }, { 0xDC, "Ü" }, { 0xDD, "Ý" }, { 0xDE, "Þ" }, { 0xDF, "β" }, { 0xE0, "à" }, + { 0xE1, "á" }, { 0xE2, "â" }, { 0xE3, "ã" }, { 0xE4, "ä" }, { 0xE5, "å" }, { 0xE6, "æ" }, { 0xE7, "ç" }, + { 0xE8, "è" }, { 0xE9, "é" }, { 0xEA, "ê" }, { 0xEB, "ë" }, { 0xEC, "ì" }, { 0xED, "í" }, { 0xEE, "î" }, + { 0xEF, "ï" }, { 0xF0, "ð" }, { 0xF1, "ñ" }, { 0xF2, "ò" }, { 0xF3, "ó" }, { 0xF4, "ô" }, { 0xF5, "õ" }, + { 0xF6, "ö" }, { 0xF7, "÷" }, { 0xF8, "ø" }, { 0xF9, "ù" }, { 0xFA, "ú" }, { 0xFB, "û" }, { 0xFC, "ü" }, + { 0xFD, "ý" }, { 0xFE, "þ" }, { 0xFF, "ÿ" }, +}; + +using ConvertFunction = std::string (*const)(const char*&); + +std::string Unk1Handler(const char*& ptr) { + u8 a = *ptr++; + return fmt::format("{{01:{:02X}}}", a); +} - std::string Unk7Handler(const char *&ptr) { - u8 a = *ptr++; +std::string ColorHandler(const char*& ptr) { + u8 color = *ptr++; + if (color >= Color_Count) + throw std::runtime_error(ptr); + return fmt::format("{{Color:{}}}", ColorStrings[color]); +} + +std::string SoundHandler(const char*& ptr) { + u8 a = *ptr++; + u8 b = *ptr++; + return fmt::format("{{Sound:{:02X}:{:02X}}}", a, b); +} + +std::string Unk4Handler(const char*& ptr) { + u8 a = *ptr++; + if (a == 0x10) { u8 b = *ptr++; - return fmt::format("{{07:{:02X}:{:02X}}}", a, b); + return fmt::format("{{04:{:02X}:{:02X}}}", a, b); + } else { + return fmt::format("{{04:{:02X}}}", a); } +} - std::string Unk8Handler(const char *&ptr) { - u8 a = *ptr++; - if (a != 0xff) - throw std::runtime_error("unmatched unk8: "s + std::to_string(a)); - return "{08:FF}"; +std::string ChoiceHandler(const char*& ptr) { + u8 category = *ptr++; + if (category == 0xff) { + return "{Choice:FF}"; + } else { + u8 action = *ptr++; + return fmt::format("{{Choice:{:02X}:{:02X}}}", category, action); } +} - std::string Unk9Handler(const char *&ptr) { - u8 a = *ptr++; - if (a != 0x78 && a != 0x00) - throw std::runtime_error("unmatched unk8: "s + std::to_string(a)); - return fmt::format("{{09:{:02X}}}", a); +std::string VariableHandler(const char*& ptr) { + u8 idx = *ptr++; + if (idx == 0) { + return "{Player}"; + } else { + return fmt::format("{{Var:{:X}}}", idx); } +} - std::string InputHandler(const char *&ptr) { - u8 key = *ptr++; - if (key > 8) - throw std::runtime_error("unmatched key: "s + std::to_string(key)); - return fmt::format("{{Key:{}}}", InputStrings[key]); - } +std::string Unk7Handler(const char*& ptr) { + u8 a = *ptr++; + u8 b = *ptr++; + return fmt::format("{{07:{:02X}:{:02X}}}", a, b); +} - std::string SymbolHandler(const char *&ptr) { - u8 a = *ptr++; - return fmt::format("{{Symbol:{:02X}}}", a); - } +std::string Unk8Handler(const char*& ptr) { + u8 a = *ptr++; + if (a != 0xff) + throw std::runtime_error("unmatched unk8: "s + std::to_string(a)); + return "{08:FF}"; +} - const std::map FuncConvertArray = { - {0x01, Unk1Handler}, - {0x02, ColorHandler}, - {0x03, SoundHandler}, - {0x04, Unk4Handler}, - {0x05, ChoiceHandler}, - {0x06, VariableHandler}, - {0x07, Unk7Handler}, - {0x08, Unk8Handler}, - {0x09, Unk9Handler}, - {0x0c, InputHandler}, - {0x0f, SymbolHandler}, - }; - - std::string ParseTMCString(const char *ptr) { - std::string ret; - - while (*ptr) { - u8 c = *ptr++; - - /* Convert character. */ - { - const auto it = CharConvertArray.find(c); - - if (it != std::end(CharConvertArray)) { - ret += it->second; - continue; - } - } +std::string Unk9Handler(const char*& ptr) { + u8 a = *ptr++; + if (a != 0x78 && a != 0x00) + throw std::runtime_error("unmatched unk8: "s + std::to_string(a)); + return fmt::format("{{09:{:02X}}}", a); +} - /* Convert function. */ - { - const auto it = FuncConvertArray.find(c); +std::string InputHandler(const char*& ptr) { + u8 key = *ptr++; + if (key > 8) + throw std::runtime_error("unmatched key: "s + std::to_string(key)); + return fmt::format("{{Key:{}}}", InputStrings[key]); +} - if (it != std::end(FuncConvertArray)) { - ret += it->second(ptr); - continue; - } - } +std::string SymbolHandler(const char*& ptr) { + u8 a = *ptr++; + return fmt::format("{{Symbol:{:02X}}}", a); +} + +const std::map FuncConvertArray = { + { 0x01, Unk1Handler }, { 0x02, ColorHandler }, { 0x03, SoundHandler }, { 0x04, Unk4Handler }, + { 0x05, ChoiceHandler }, { 0x06, VariableHandler }, { 0x07, Unk7Handler }, { 0x08, Unk8Handler }, + { 0x09, Unk9Handler }, { 0x0c, InputHandler }, { 0x0f, SymbolHandler }, +}; + +std::string ParseTMCString(const char* ptr) { + std::string ret; + + while (*ptr) { + u8 c = *ptr++; - throw std::runtime_error(fmt::format("Unknown characters: {}", ptr)); + /* Convert character. */ + { + const auto it = CharConvertArray.find(c); + + if (it != std::end(CharConvertArray)) { + ret += it->second; + continue; + } } - return ret; - } + /* Convert function. */ + { + const auto it = FuncConvertArray.find(c); - using RevertFunction = void (*)(const char *&, char *&); - - void ColorRevert(const char *&src, char *&dst) { - *dst++ = 0x02; - src++; // ':' - for (u32 i = 0; i < Color_Count; i++) { - const char *const color = ColorStrings[i]; - const std::size_t color_len = std::strlen(color); - if (std::strncmp(src, color, color_len) == 0) { - *dst++ = i; - src += color_len; - return; + if (it != std::end(FuncConvertArray)) { + ret += it->second(ptr); + continue; } } - throw std::runtime_error(fmt::format("Color not found: {}", src)); + throw std::runtime_error(fmt::format("Unknown characters: {}", ptr)); } - void SoundRevert(const char *&src, char *&dst) { - *dst++ = 0x03; - *dst++ = std::strtoul(++src, nullptr, 0x10); - src += 2; - *dst++ = std::strtoul(++src, nullptr, 0x10); - src += 2; + return ret; +} + +using RevertFunction = void (*)(const char*&, char*&); + +void ColorRevert(const char*& src, char*& dst) { + *dst++ = 0x02; + src++; // ':' + for (u32 i = 0; i < Color_Count; i++) { + const char* const color = ColorStrings[i]; + const std::size_t color_len = std::strlen(color); + if (std::strncmp(src, color, color_len) == 0) { + *dst++ = i; + src += color_len; + return; + } } - void ChoiceRevert(const char *&src, char *&dst) { - *dst++ = 0x05; - u8 choice = std::strtoul(++src, nullptr, 0x10); + throw std::runtime_error(fmt::format("Color not found: {}", src)); +} - *dst++ = choice; - src += 2; +void SoundRevert(const char*& src, char*& dst) { + *dst++ = 0x03; + *dst++ = std::strtoul(++src, nullptr, 0x10); + src += 2; + *dst++ = std::strtoul(++src, nullptr, 0x10); + src += 2; +} - if (choice == 0xff) - return; +void ChoiceRevert(const char*& src, char*& dst) { + *dst++ = 0x05; + u8 choice = std::strtoul(++src, nullptr, 0x10); - *dst++ = std::strtoul(++src, nullptr, 0x10); - src += 2; - } + *dst++ = choice; + src += 2; - void PlayerRevert(const char *&src, char *&dst) { - *dst++ = 0x06; - *dst++ = 0x00; + if (choice == 0xff) + return; - (void)src; - } + *dst++ = std::strtoul(++src, nullptr, 0x10); + src += 2; +} - void VariableRevert(const char *&src, char *&dst) { - *dst++ = 0x06; - src++; // ':' +void PlayerRevert(const char*& src, char*& dst) { + *dst++ = 0x06; + *dst++ = 0x00; - *dst++ = std::strtoul(src, nullptr, 0x10); - src++; - } + (void)src; +} - void KeyRevert(const char *&src, char *&dst) { - *dst++ = 0x0c; - src++; // ':' - for (u32 i = 0; i < Input_Count; i++) { - const char *const input = InputStrings[i]; - const std::size_t input_len = std::strlen(input); - if (std::strncmp(src, input, input_len) == 0) { - *dst++ = i; - src += input_len; - return; - } - } +void VariableRevert(const char*& src, char*& dst) { + *dst++ = 0x06; + src++; // ':' - throw std::runtime_error(fmt::format("Input not found: {}", src)); + *dst++ = std::strtoul(src, nullptr, 0x10); + src++; +} + +void KeyRevert(const char*& src, char*& dst) { + *dst++ = 0x0c; + src++; // ':' + for (u32 i = 0; i < Input_Count; i++) { + const char* const input = InputStrings[i]; + const std::size_t input_len = std::strlen(input); + if (std::strncmp(src, input, input_len) == 0) { + *dst++ = i; + src += input_len; + return; + } } - void SymbolRevert(const char *&src, char *&dst) { - *dst++ = 0x0f; - src++; // ':' + throw std::runtime_error(fmt::format("Input not found: {}", src)); +} + +void SymbolRevert(const char*& src, char*& dst) { + *dst++ = 0x0f; + src++; // ':' - *dst++ = std::strtoul(src, nullptr, 0x10); - src += 2; - } + *dst++ = std::strtoul(src, nullptr, 0x10); + src += 2; +} + +const std::pair FuncRevertArray[] = { + { "Color", ColorRevert }, { "Sound", SoundRevert }, { "Choice", ChoiceRevert }, { "Player", PlayerRevert }, + { "Var", VariableRevert }, { "Key", KeyRevert }, { "Symbol", SymbolRevert }, +}; - const std::pair FuncRevertArray[] = { - {"Color", ColorRevert}, - {"Sound", SoundRevert}, - {"Choice", ChoiceRevert}, - {"Player", PlayerRevert}, - {"Var", VariableRevert}, - {"Key", KeyRevert}, - {"Symbol", SymbolRevert}, - }; - - void WriteTMCString(char *&dst, const std::string &src) { - const char *ptr = src.data(); - - while (*ptr) { - /* Parse special */ - { - if (*ptr == '{') { - ptr++; - const auto it = std::find_if(std::begin(FuncRevertArray), std::end(FuncRevertArray), [&](const auto &data) { +void WriteTMCString(char*& dst, const std::string& src) { + const char* ptr = src.data(); + + while (*ptr) { + /* Parse special */ + { + if (*ptr == '{') { + ptr++; + const auto it = + std::find_if(std::begin(FuncRevertArray), std::end(FuncRevertArray), [&](const auto& data) { return std::strncmp(ptr, data.first.c_str(), data.first.size()) == 0; }); - if (it != std::end(FuncRevertArray)) { - ptr += it->first.size(); - it->second(ptr, dst); - } else { - do { - *dst++ = std::strtoul(ptr, nullptr, 0x10); - ptr += 2; - } while (*ptr == ':' && (ptr++, true)); - } - - if (*ptr != '}') - throw std::runtime_error(fmt::format("unmatched characters: \"{}\"\n", ptr)); - - ptr++; - continue; + if (it != std::end(FuncRevertArray)) { + ptr += it->first.size(); + it->second(ptr, dst); + } else { + do { + *dst++ = std::strtoul(ptr, nullptr, 0x10); + ptr += 2; + } while (*ptr == ':' && (ptr++, true)); } + + if (*ptr != '}') + throw std::runtime_error(fmt::format("unmatched characters: \"{}\"\n", ptr)); + + ptr++; + continue; } + } - /* Convert character. */ - { - const auto it = std::find_if(std::begin(CharConvertArray), std::end(CharConvertArray), [ptr](const auto &data) { + /* Convert character. */ + { + const auto it = + std::find_if(std::begin(CharConvertArray), std::end(CharConvertArray), [ptr](const auto& data) { return std::strncmp(ptr, data.second.c_str(), data.second.length()) == 0; }); - if (it != std::end(CharConvertArray)) { - ptr += it->second.size(); - *dst++ = it->first; - continue; - } + if (it != std::end(CharConvertArray)) { + ptr += it->second.size(); + *dst++ = it->first; + continue; } - - throw std::runtime_error(fmt::format("unmatched characters: \"{}\"\n", ptr)); } - *dst++ = '\0'; - } + throw std::runtime_error(fmt::format("unmatched characters: \"{}\"\n", ptr)); + } + *dst++ = '\0'; } -void ExtractStringTable(std::string &rom_path, const std::vector &tables) { +} // namespace + +void ExtractStringTable(std::string& rom_path, const std::vector& tables) { const std::vector rom = [&]() { std::vector rom; @@ -543,11 +360,9 @@ void ExtractStringTable(std::string &rom_path, const std::vector return rom; }(); - auto ReadAbsolute = [&](u32 address) -> u32 { - return *(u32 *)&rom[address - RomStartAddress]; - }; + auto ReadAbsolute = [&](u32 address) -> u32 { return *(u32*)&rom[address - RomStartAddress]; }; - for (auto &language : tables) { + for (auto& language : tables) { /* Get category table start. */ const std::size_t table_start = language.address; @@ -560,7 +375,7 @@ void ExtractStringTable(std::string &rom_path, const std::vector json j = json::array(); - for (auto &category_offset : category_table) { + for (auto& category_offset : category_table) { /* Get string table start. */ const std::size_t category_start = table_start + category_offset; @@ -571,7 +386,7 @@ void ExtractStringTable(std::string &rom_path, const std::vector std::vector string_table(string_count); std::memcpy(&string_table[0], &rom[category_start - RomStartAddress], string_count * sizeof(u32)); - auto &category = j.emplace_back(); + auto& category = j.emplace_back(); for (std::size_t l = 0; l < string_count; l++) { /* Get string start. */ @@ -588,7 +403,7 @@ void ExtractStringTable(std::string &rom_path, const std::vector } } -void PackStringTable(const std::string &src_path, const std::string &dst_path, const std::size_t out_size) { +void PackStringTable(const std::string& src_path, const std::string& dst_path, const std::size_t out_size) { const json j = [&]() -> json { std::ifstream ifs(src_path); @@ -603,16 +418,16 @@ void PackStringTable(const std::string &src_path, const std::string &dst_path, c std::vector buffer(0x100000); std::uintptr_t root_start = (std::uintptr_t)buffer.data(); - char *root_ptr = buffer.data(); - char *table = buffer.data() + j.size() * sizeof(u32); + char* root_ptr = buffer.data(); + char* table = buffer.data() + j.size() * sizeof(u32); - for (auto &category : j) { - char *table_ptr = table; - char *str_start = table_ptr + category.size() * sizeof(u32); - char *str_ptr = str_start; - for (auto &str_j : category) { + for (auto& category : j) { + char* table_ptr = table; + char* str_start = table_ptr + category.size() * sizeof(u32); + char* str_ptr = str_start; + for (auto& str_j : category) { /* Write string offset to table. */ - *(u32 *)table_ptr = (std::uintptr_t)str_ptr - (std::uintptr_t)table; + *(u32*)table_ptr = (std::uintptr_t)str_ptr - (std::uintptr_t)table; table_ptr += sizeof(u32); auto str = str_j.get(); @@ -628,7 +443,7 @@ void PackStringTable(const std::string &src_path, const std::string &dst_path, c } /* Write category offset to root table. */ - *(u32 *)root_ptr = (std::uintptr_t)table - root_start; + *(u32*)root_ptr = (std::uintptr_t)table - root_start; root_ptr += sizeof(u32); table = str_ptr; @@ -675,7 +490,7 @@ const std::vector LanguageTableEU = { #include -const char *progname; +const char* progname; void usage() { fmt::print(stderr, @@ -705,7 +520,7 @@ constexpr const struct option long_options[] = { }; // clang-format on -int main(int argc, char **argv) { +int main(int argc, char** argv) { std::string src_path; std::string dst_path; std::size_t max_size = 0; -- cgit v1.2.3