d/jak2: first pass of jak 2's font (no japanese or korean support yet)

This commit is contained in:
Tyler Wilding
2022-09-27 02:24:31 -04:00
parent 28344c06b0
commit 8dbf3db15d
5 changed files with 251 additions and 19 deletions
+12
View File
@@ -152,6 +152,18 @@
"${workspaceRoot}/decompiler_out"
]
},
{
"type": "default",
"project": "CMakeLists.txt",
"projectTarget": "decompiler.exe (bin\\decompiler.exe)",
"name": "Decompiler - Jak 2 - Extract",
"args": [
"${workspaceRoot}/decompiler/config/jak2_ntsc_v1.jsonc",
"${workspaceRoot}/iso_data",
"${workspaceRoot}/decompiler_out",
"--config-override \"{\\\"decompile_code\\\": false}\""
]
},
{
"type": "default",
"project": "CMakeLists.txt",
+2 -2
View File
@@ -42,15 +42,15 @@ add_library(common
util/DgoWriter.cpp
util/diff.cpp
util/FileUtil.cpp
util/FontUtils.cpp
util/json_util.cpp
util/read_iso_file.cpp
util/SimpleThreadGroup.cpp
util/Timer.cpp
util/os.cpp
util/print_float.cpp
util/FontUtils.cpp
util/FrameLimiter.cpp
util/unicode_util.cpp)
util/unicode_util.cpp )
target_link_libraries(common fmt lzokay replxx libzstd_static)
+232 -16
View File
@@ -29,7 +29,8 @@ bool hex_char(char c) {
const std::unordered_map<std::string, GameTextVersion> sTextVerEnumMap = {
{"jak1-v1", GameTextVersion::JAK1_V1},
{"jak1-v2", GameTextVersion::JAK1_V2}};
{"jak1-v2", GameTextVersion::JAK1_V2},
{"jak2", GameTextVersion::JAK2}};
const std::string& get_text_version_name(GameTextVersion version) {
for (auto& [name, ver] : sTextVerEnumMap) {
@@ -157,6 +158,19 @@ std::string GameTextFontBank::convert_utf8_to_game(std::string str) const {
return str;
}
bool GameTextFontBank::valid_char_range(const char in) const {
if (m_version == GameTextVersion::JAK1_V1 || m_version == GameTextVersion::JAK1_V2) {
return ((in >= '0' && in <= '9') || (in >= 'A' && in <= 'Z') ||
m_passthrus->find(in) != m_passthrus->end()) &&
in != '\\';
} else if (m_version == GameTextVersion::JAK2) {
return ((in >= '0' && in <= '9') || (in >= 'A' && in <= 'Z') || (in >= 'a' && in <= 'z') ||
m_passthrus->find(in) != m_passthrus->end()) &&
in != '\\';
}
return false;
}
/*!
* Turn a normal readable string into a string readable in the in-game font encoding and converts
* \cXX escape sequences
@@ -219,9 +233,7 @@ std::string GameTextFontBank::convert_game_to_utf8(const char* in) const {
if (remap != nullptr) {
result.append(remap->chars);
in += remap->bytes.size() - 1;
} else if (((*in >= '0' && *in <= '9') || (*in >= 'A' && *in <= 'Z') ||
m_passthrus->find(*in) != m_passthrus->end()) &&
*in != '\\') {
} else if (valid_char_range(*in)) {
result.push_back(*in);
} else if (*in == '\n') {
result += "\\n";
@@ -250,9 +262,9 @@ static std::vector<ReplaceInfo> s_replace_info_null = {};
* - Jak & Daxter: The Precursor Legacy (Black Label)
*/
static std::unordered_set<char> s_passthrus = {'~', ' ', ',', '.', '-', '+', '(', ')',
'!', ':', '?', '=', '%', '*', '/', '#',
';', '<', '>', '@', '[', '_'};
static std::unordered_set<char> s_passthrus_jak1 = {'~', ' ', ',', '.', '-', '+', '(', ')',
'!', ':', '?', '=', '%', '*', '/', '#',
';', '<', '>', '@', '[', '_'};
static std::vector<EncodeInfo> s_encode_info_jak1 = {
// random
@@ -578,10 +590,10 @@ static std::vector<ReplaceInfo> s_replace_info_jak1 = {
{"~Y~22L<~Z~Y~24L#~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_SQUARE>"}, // custom
};
GameTextFontBank g_font_bank_jak1(GameTextVersion::JAK1_V1,
&s_encode_info_jak1,
&s_replace_info_jak1,
&s_passthrus);
GameTextFontBank g_font_bank_jak1_v1(GameTextVersion::JAK1_V1,
&s_encode_info_jak1,
&s_replace_info_jak1,
&s_passthrus_jak1);
/*!
* ================================
@@ -815,12 +827,216 @@ static std::vector<EncodeInfo> s_encode_info_jak1_v2 = {
GameTextFontBank g_font_bank_jak1_v2(GameTextVersion::JAK1_V2,
&s_encode_info_jak1_v2,
&s_replace_info_jak1,
&s_passthrus);
&s_passthrus_jak1);
/*!
* ================================
* GAME TEXT FONT BANK - JAK 2
* ================================
* This font is used in:
* - Jak 2 - NTSC - v1
*/
static std::unordered_set<char> s_passthrus_jak2 = {'~', ' ', ',', '.', '-', '+', '(', ')',
'!', ':', '?', '=', '%', '*', '/', '#',
';', '<', '>', '@', '[', '_'};
static std::vector<ReplaceInfo> s_replace_info_jak2 = {
// other
{"A~Y~-21H~-5Vº~Z", "Å"},
{"N~Y~-6Hº~Z~+10H", ""},
{"~+4VÇ~-4V", "ç"},
// tildes
{"N~Y~-22H~-4V<TIL>~Z", "Ñ"},
{"n~Y~-24H~-4V<TIL>~Z", "ñ"},
{"A~Y~-21H~-5V<TIL>~Z", "Ã"}, // custom
{"O~Y~-22H~-4V<TIL>~Z", "Õ"}, // custom
// acute accents
{"A~Y~-21H~-5V'~Z", "Á"},
{"a~Y~-25H~-5V'~Z", "á"},
{"E~Y~-23H~-9V'~Z", "É"},
{"e~Y~-26H~-5V'~Z", "é"},
{"I~Y~-19H~-5V'~Z", "Í"},
{"i~Y~-19H~-8V'~Z", "í"},
{"O~Y~-22H~-4V'~Z", "Ó"},
{"o~Y~-26H~-4V'~Z", "ó"},
{"U~Y~-24H~-3V'~Z", "Ú"},
{"u~Y~-24H~-3V'~Z", "ú"},
// circumflex
{"A~Y~-20H~-4V^~Z", "Â"}, // custom
{"a~Y~-24H~-5V^~Z", "â"},
{"E~Y~-20H~-5V^~Z", "Ê"},
{"e~Y~-25H~-4V^~Zt", "ê"},
{"I~Y~-19H~-5V^~Z", "Î"},
{"i~Y~-19H~-8V^~Z", "î"},
{"O~Y~-20H~-4V^~Z", "Ô"}, // custom
{"o~Y~-25H~-4V^~Z", "ô"},
{"U~Y~-24H~-3V^~Z", "Û"},
{"u~Y~-23H~-3V^~Z", "û"},
// grave accents
{"A~Y~-26H~-8V`~Z", "À"},
{"a~Y~-25H~-5V`~Z", "à"},
{"E~Y~-23H~-9V`~Z", "È"},
{"e~Y~-26H~-5V`~Z", "è"},
{"I~Y~-19H~-5V`~Z", "Ì"},
{"i~Y~-19H~-8V`~Z", "ì"},
{"O~Y~-22H~-4V`~Z", "Ò"}, // custom
{"U~Y~-24H~-3V`~Z", "Ù"},
{"u~Y~-24H~-3V`~Z", "ù"},
// umlaut
{"A~Y~-26H~-8V¨~Z", "Ä"},
{"a~Y~-25H~-5V¨~Z", "ä"},
{"E~Y~-20H~-5V¨~Z", "Ë"},
{"I~Y~-19H~-5V¨~Z", "Ï"}, // custom
{"O~Y~-26H~-8V¨~Z", "Ö"},
{"o~Y~-26H~-4V¨~Z", "ö"},
{"U~Y~-25H~-8V¨~Z", "Ü"},
{"u~Y~-24H~-3V¨~Z", "ü"},
// dakuten katakana
{"~Yウ~Z゛", ""},
{"~Yカ~Z゛", ""},
{"~Yキ~Z゛", ""},
{"~Yク~Z゛", ""},
{"~Yケ~Z゛", ""},
{"~Yコ~Z゛", ""},
{"~Yサ~Z゛", ""},
{"~Yシ~Z゛", ""},
{"~Yス~Z゛", ""},
{"~Yセ~Z゛", ""},
{"~Yソ~Z゛", ""},
{"~Yタ~Z゛", ""},
{"~Yチ~Z゛", ""},
{"~Yツ~Z゛", ""},
{"~Yテ~Z゛", ""},
{"~Yト~Z゛", ""},
{"~Yハ~Z゛", ""},
{"~Yヒ~Z゛", ""},
{"~Yフ~Z゛", ""},
{"~Yヘ~Z゛", ""},
{"~Yホ~Z゛", ""},
// handakuten katakana
{"~Yハ~Z゜", ""},
{"~Yヒ~Z゜", ""},
{"~Yフ~Z゜", ""},
{"~Yヘ~Z゜", ""},
{"~Yホ~Z゜", ""},
// dakuten hiragana
{"~Yか~Z゛", ""},
{"~Yき~Z゛", ""},
{"~Yく~Z゛", ""},
{"~Yけ~Z゛", ""},
{"~Yこ~Z゛", ""},
{"~Yさ~Z゛", ""},
{"~Yし~Z゛", ""},
{"~Yす~Z゛", ""},
{"~Yせ~Z゛", ""},
{"~Yそ~Z゛", ""},
{"~Yた~Z゛", ""},
{"~Yち~Z゛", ""},
{"~Yつ~Z゛", ""},
{"~Yて~Z゛", ""},
{"~Yと~Z゛", ""},
{"~Yは~Z゛", ""},
{"~Yひ~Z゛", ""},
{"~Yふ~Z゛", ""},
{"~Yへ~Z゛", ""},
{"~Yほ~Z゛", ""},
// handakuten hiragana
{"~Yは~Z゜", ""},
{"~Yひ~Z゜", ""},
{"~Yふ~Z゜", ""},
{"~Yへ~Z゜", ""},
{"~Yほ~Z゜", ""},
// japanese punctuation
{",~+8H", ""},
{"~+8H ", " "},
// (hack) special case kanji
{"~~", ""},
// playstation buttons
{"~Y~22L<~Z~Y~27L*~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_X>"},
{"~Y~22L<~Z~Y~26L;~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_TRIANGLE>"},
{"~Y~22L<~Z~Y~25L@~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_CIRCLE>"},
{"~Y~22L<~Z~Y~24L#~Z~Y~1L>~Z~Y~23L[~Z~+26H", "<PAD_SQUARE>"}, // custom
{"~Y~22L~-2H~-12V\\ca6\\ca7~Z~22L~-2H~+17V\\cb0\\cb1~Z~1L~+4H~+3V\\c95~Z~+38H", "<PAD_L1>"},
{"~Y~22L~-2H~-12V\\ca6\\ca7~Z~22L~-2H~+17V\\cb0\\cb1~Z~1L~+6H~+3V\\c94~Z~+38H", "<PAD_R1>"},
{"~Y~22L\\ca1~Z~3L~+17H~-13V\\ca2~Z~22L~+17H~+14V\\ca0~Z~22L~+32H\\ca3~Z~+56H",
"<PAD_DPAD_UP>"},
{"~Y~22L\\ca1~Z~3L~+17H~-13V\\ca2~Z~3L~+17H~+14V\\ca0~Z~22L~+32H\\ca3~Z~+56H",
"<PAD_DPAD_DOWN>"},
{"~Y~22L~-2H~-6V\\ca8\\ca9~Z~22L~-2H~+16V\\cb2\\cb3~Z~1L~+5H~-2V\\c96~Z~+38H", "<PAD_R2>"},
{"~Y~22L~-2H~-6V\\ca8\\ca9~Z~22L~-2H~+16V\\cb2\\cb3~Z~1L~+5H~-2V\\c97~Z~+38H", "<PAD_L2>"},
{"~1L~+8H~Y\\c91~Z~6L~-16H\\c9e~Z~+16h~6L\\ca4~Z~6L~-15V\\c9c~Z~+13V~6L\\c98~Z~-10H~+9V~"
"6L\\c9f~Z~+10H~+9V~6L\\c99~Z~-10H~-11V~6L\\c9d~Z~+10H~-11V~6L\\ca5~Z~+32H",
"<PAD_ANALOG_ANY>"},
{"~Y~1L~+8H\\c91~Z~6L~-8H\\c9e~Z~+24H~6L\\ca4~Z~+40H", "<PAD_ANALOG_LEFT_RIGHT>"},
{"~Y~1L\\c91~Z~6L~-15V\\c9c~Z~+13V~6L\\c98~Z~+26H", "<PAD_ANALOG_UP_DOWN>"},
// TODO
// - ~Y~22L\ca1~Z~22L~+17H~-13V\ca2~Z~22L~+17H~+14V\ca0~Z~22L~+32H\ca3~Z~+56H
// - ~Y~6L<~Z~Y~1L>~Z~Y~23L[~Z~+26H
// - ~Y~3L<~Z~Y~1L>~Z~Y~23L[~Z~+26H
// - ~Y~1L\c85~Z~3L\c8c~Z~7L\c8e~\c5d~-1H~Y~1L\c85~Z~3L\c8d~Z~7L\c8f~Z~+26H
// - ~Y~3L<~Z~Y~1L>~Z~Y~23L[~Z~+26H
// - ~Y~1L\c85~\c5d~-1H~Y~1L\c85~Z~-11H~3L\c86~Z~+26H
// flags
{"~Y~6L\\c81~Z~+15H~1L\\c81~Z~+30H~3L\\c81~Z~+45H", "<FLAG_ITALIAN>"},
{"~Y~5L\\c85~Z~3L\\c8b~\\c5d~-1H~Y~5L\\c85~Z~3L\\c8b~Z~+26H", "<FLAG_SPAIN>"},
{"~Y~39L~~~Z~3L\\c7f~Z~5L\\c80~\\c5d~-1H~Y~39L~~~Z~3L\\c7f~Z~5L\\c80~Z~+26H",
"<FLAG_GERMAN>"},
{"~Y~7L\\c81~Z~+15H~1L\\c81~Z~+30H~3L\\c81~Z~+47H", "<FLAG_FRANCE>"},
{"~Y~1L\\c85~Z~3L\\c9a~Z~7L\\c9b~\\c5d~-1H~Y~1L\\c85~Z~3L\\c90~Z~+26H", "<FLAG_UK>"},
{"~Y~1L\\c85~Z~39L\\c87~\\c5d~-1H~Y~1L\\c85~Z~39L\\c88~Z~-11H~7L\\c8a~Z~-11H~3L\\c89~Z~+26H", "<FLAG_JAPAN>"},
{"~Y~1L\\c85~\\c5d~-1H~Y~1L\\c85~Z~-11H~3L\\c86~Z~+26H", "<FLAG_SOUTH_KOREA>"},
// weird stuff
// - some sort of control character to adjust kerning, ie after `i` and `o`?
{"~+7V", ""},
// - preceeding character has a descender?
{"~-7V", ""},
// - i wonder if this is just a generic code to say "push the next character up or down
// vertically"?
{"~+1V", ""},
{"~-1V", ""},
{"~-4H~-3V\\c19~+3V~-4H",
"<SUPERSCRIPT_QUOTE>"}, // used for the 4<__> place in spanish. the 5th uses the same
// character but looks different...?
{"~Y~-6Hº~Z~+10H", "°"},
{"\\c5e", "œ"}, // ligature o+e
// Color / Emphasis
{"~[~1L", "<COLOR_WHITE>"},
{"~[~32L", "<COLOR_DEFAULT>"}};
static std::vector<EncodeInfo> s_encode_info_jak2 = {
{"_", {0x03}}, // large space
{"ˇ", {0x10}}, // caron
{"`", {0x11}}, // grave accent
{"'", {0x12}}, // apostrophe
{"^", {0x13}}, // circumflex
{"<TIL>", {0x14}}, // tilde
{"¨", {0x15}}, // umlaut
{"º", {0x16}}, // numero/overring
{"¡", {0x17}}, // inverted exclamation mark
{"¿", {0x18}}, // inverted question mark
{"Ç", {0x1d}}, // c-cedilla
{"ß", {0x1f}}, // eszett
};
GameTextFontBank g_font_bank_jak2(GameTextVersion::JAK2,
&s_encode_info_null,
&s_replace_info_null,
&s_passthrus);
&s_encode_info_jak2,
&s_replace_info_jak2,
&s_passthrus_jak2);
/*!
* ========================
@@ -830,7 +1046,7 @@ GameTextFontBank g_font_bank_jak2(GameTextVersion::JAK2,
*/
std::map<GameTextVersion, GameTextFontBank*> g_font_banks = {
{GameTextVersion::JAK1_V1, &g_font_bank_jak1},
{GameTextVersion::JAK1_V1, &g_font_bank_jak1_v1},
{GameTextVersion::JAK1_V2, &g_font_bank_jak1_v2},
{GameTextVersion::JAK2, &g_font_bank_jak2}};
+4
View File
@@ -75,6 +75,10 @@ class GameTextFontBank {
GameTextVersion version() const { return m_version; }
// TODO - methods would help make this code a lot better for different game versions
// hacking it for now
bool valid_char_range(const char in) const;
std::string convert_utf8_to_game_with_escape(const std::string& str) const;
std::string convert_utf8_to_game(std::string str) const;
std::string convert_game_to_utf8(const char* in) const;
+1 -1
View File
@@ -35,7 +35,7 @@
// unpack textures to assets folder
"process_tpages": false,
// unpack game text to assets folder
"process_game_text": false,
"process_game_text": true,
// unpack game count to assets folder
"process_game_count": true,
// write goal imports for art groups