From ca42db7b753bda8716fa54ee82281c719c66918b Mon Sep 17 00:00:00 2001 From: Pk11 Date: Tue, 16 Jan 2024 00:27:45 -0600 Subject: [PATCH] Update translations (#1668) Adds Vietnamese and new font for it Also adds Czech and Finnish --- crowdin.yml | 2 +- retail/arm9/source/conf_sd.cpp | 9 ++- retail/arm9/source/text.cpp | 66 ++++++++++++------ retail/common/include/igm_text.h | 15 ++-- retail/nitrofiles/fonts/ascii.lz77 | Bin 602 -> 630 bytes retail/nitrofiles/fonts/vietnamese.lz77 | Bin 0 -> 487 bytes .../nitrofiles/languages/ar/in_game_menu.ini | 8 +-- .../nitrofiles/languages/cs/in_game_menu.ini | 31 ++++++++ .../nitrofiles/languages/da/in_game_menu.ini | 6 +- .../nitrofiles/languages/el/in_game_menu.ini | 28 ++++---- .../nitrofiles/languages/fi/in_game_menu.ini | 31 ++++++++ .../nitrofiles/languages/nl/in_game_menu.ini | 16 ++--- .../nitrofiles/languages/pt/in_game_menu.ini | 6 +- .../nitrofiles/languages/sv/in_game_menu.ini | 34 ++++----- .../nitrofiles/languages/vi/in_game_menu.ini | 22 +++--- xcf/igm_font/ascii.xcf | Bin 3872 -> 4220 bytes xcf/igm_font/vietnamese.xcf | Bin 0 -> 5926 bytes 17 files changed, 182 insertions(+), 92 deletions(-) create mode 100644 retail/nitrofiles/fonts/vietnamese.lz77 create mode 100644 retail/nitrofiles/languages/cs/in_game_menu.ini create mode 100644 retail/nitrofiles/languages/fi/in_game_menu.ini create mode 100644 xcf/igm_font/vietnamese.xcf diff --git a/crowdin.yml b/crowdin.yml index 871e29a0e..18dbc5e64 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,4 +1,4 @@ -project_id_env: BOOTSTRAP_CROWDIN_ID +project_id: 452474 api_token_env: CROWDIN_TOKEN preserve_hierarchy: true diff --git a/retail/arm9/source/conf_sd.cpp b/retail/arm9/source/conf_sd.cpp index 38080ecf1..4c2b3d31f 100644 --- a/retail/arm9/source/conf_sd.cpp +++ b/retail/arm9/source/conf_sd.cpp @@ -338,6 +338,9 @@ void getIgmStrings(configuration* conf, bool b4ds) { extendedFont = IgmFont::arabic; extendedFontPath = "nitro:/fonts/arabic.lz77"; igmText->rtl = true; + } else if (strncmp(conf->guiLanguage, "zh", 2) == 0) { + extendedFont = IgmFont::chinese; + extendedFontPath = "nitro:/fonts/chinese.lz77"; } else if (strcmp(conf->guiLanguage, "ru") == 0 || strcmp(conf->guiLanguage, "uk") == 0) { extendedFont = IgmFont::cyrillic; extendedFontPath = "nitro:/fonts/cyrillic.lz77"; @@ -354,9 +357,9 @@ void getIgmStrings(configuration* conf, bool b4ds) { } else if (strcmp(conf->guiLanguage, "ja") == 0 || strcmp(conf->guiLanguage, "ry") == 0) { extendedFont = IgmFont::japanese; extendedFontPath = "nitro:/fonts/japanese.lz77"; - } else if (strncmp(conf->guiLanguage, "zh", 2) == 0) { - extendedFont = IgmFont::chinese; - extendedFontPath = "nitro:/fonts/chinese.lz77"; + } else if (strncmp(conf->guiLanguage, "vi", 2) == 0) { + extendedFont = IgmFont::vietnamese; + extendedFontPath = "nitro:/fonts/vietnamese.lz77"; } FILE *font = fopen("nitro:/fonts/ascii.lz77", "rb"); diff --git a/retail/arm9/source/text.cpp b/retail/arm9/source/text.cpp index 9a02f6d7f..eef05528c 100644 --- a/retail/arm9/source/text.cpp +++ b/retail/arm9/source/text.cpp @@ -6,6 +6,16 @@ IgmFont extendedFont = IgmFont::extendedLatin; +constexpr char16_t mapAscii[] = + u"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + u"ẲẴẪỶỸỴ\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" + u" !\"#$%&'()*+,-./" + u"0123456789:;<=>?" + u"@ABCDEFGHIJKLMNO" + u"PQRSTUVWXYZ[\\]^_" + u"`abcdefghijklmno" + u"pqrstuvwxyz{|}~\x7F"; + constexpr char16_t mapArabic[] = u"ءآأؤإئابةتثجحخدذ" u"رزسشصضطظعغـفقكلم" @@ -16,6 +26,13 @@ constexpr char16_t mapArabic[] = u"ﻔﻖﻗﻘﻚﻛﻜﻞﻟﻠﻢﻣﻤﻦﻧﻨ" u"ﻪﻫﻬﻮﻰﻲﻳﻴ،؟ﻻﻼ"; +constexpr char16_t mapChinese[] = + u"主书亮位儲出到动動区器回图圖地址" + u"块存定屏幕底度式戏截戲择擇数數时" + u"明显時書查模檢游率界畫目看移端置" + u"自至螢視計設說说跳轉转返退选遊選" + u"部重量鐘钟開離面音頂頻顶项频 "; + constexpr char16_t mapCyrillic[] = u"ЂЃ ѓ Љ ЊЌЋЏ" u"ђ љ њќћџ" @@ -68,22 +85,27 @@ constexpr char16_t mapJapanese[] = u"上下主了動定度戻択数明書画終自設" u"説速選量面音"; -constexpr char16_t mapChinese[] = - u"主书亮位儲出到动動区器回图圖地址" - u"块存定屏幕底度式戏截戲择擇数數时" - u"明显時書查模檢游率界畫目看移端置" - u"自至螢視計設說说跳轉转返退选遊選" - u"部重量鐘钟開離面音頂頻顶项频 "; +constexpr char16_t mapVietnamese[] = + u"ẠẮẰẶẤẦẨẬẼẸẾỀỂỄỆỐ" + u"ỒỔỖỘỢỚỜỞỊỎỌỈỦŨỤỲ" + u"Õắằặấầẩậẽẹếềểễệố" + u"ồổỗỠƠộờởịỰỨỪỬơớƯ" + u"ÀÁÂÃẢĂẳẵÈÉÊẺÌÍĨỳ" + u"ĐứÒÓÔạỷừửÙÚỹỵÝỡư" + u"àáâãảăữẫèéêẻìíĩỉ" + u"đựòóôõỏọụùúũủýợỮ"; + constexpr const char16_t *extendedMaps[] = { mapArabic, + mapChinese, mapCyrillic, mapExtendedLatin, mapGreek, mapHangul, mapHebrew, mapJapanese, - mapChinese + mapVietnamese }; std::map> arabicPresentationForms = { @@ -135,13 +157,15 @@ std::map> arabicPresentationForms = { // Can't do a binary search as the maps aren't fully sorted constexpr char getIndex(char16_t c) { - if(c < 0x80) { // ASCII is left as is - return c; - } else { - for(uint i = 0; i < 0x80; i++) { - if(c == extendedMaps[u8(extendedFont)][i]) { - return 0x80 + i; - } + for(uint i = 0; i < 0x80; i++) { + if(c == mapAscii[i]) { + return i; + } + } + + for(uint i = 0; i < 0x80; i++) { + if(c == extendedMaps[u8(extendedFont)][i]) { + return 0x80 + i; } } @@ -208,7 +232,7 @@ void processRTL(unsigned char *begin, unsigned char *end) { } } - char16_t c = *p < 0x80 ? *p : extendedMaps[u8(extendedFont)][(*p) - 0x80]; + char16_t c = *p < 0x80 ? mapAscii[*p] : extendedMaps[u8(extendedFont)][(*p) - 0x80]; nocashMessage(("a" + std::to_string(c)).c_str()); // If at the end of an LTR section within RTL, jump back to the RTL @@ -217,7 +241,7 @@ void processRTL(unsigned char *begin, unsigned char *end) { break; p = ltrBegin; - c = *p < 0x80 ? *p : extendedMaps[u8(extendedFont)][(*p) - 0x80]; + c = *p < 0x80 ? mapAscii[*p] : extendedMaps[u8(extendedFont)][(*p) - 0x80]; ltrBegin = end; rtl = true; // If in RTL and hit a non-RTL character that's not punctuation, switch to LTR @@ -233,7 +257,7 @@ void processRTL(unsigned char *begin, unsigned char *end) { if(allNumbers && !isNumber(c) && !isWeak(c)) allNumbers = false; p--; - c = *p < 0x80 ? *p : extendedMaps[u8(extendedFont)][(*p) - 0x80]; + c = *p < 0x80 ? mapAscii[*p] : extendedMaps[u8(extendedFont)][(*p) - 0x80]; } // Save where we are to return to after printing the LTR section @@ -242,7 +266,7 @@ void processRTL(unsigned char *begin, unsigned char *end) { // If on an RTL char right now, add one if(isStrongRTL(c)) { p++; - c = *p < 0x80 ? *p : extendedMaps[u8(extendedFont)][(*p) - 0x80]; + c = *p < 0x80 ? mapAscii[*p] : extendedMaps[u8(extendedFont)][(*p) - 0x80]; } // Remove all punctuation and, if the section isn't only numbers, @@ -252,14 +276,14 @@ void processRTL(unsigned char *begin, unsigned char *end) { if(p != begin) ltrBegin++; p++; - c = *p < 0x80 ? *p : extendedMaps[u8(extendedFont)][(*p) - 0x80]; + c = *p < 0x80 ? mapAscii[*p] : extendedMaps[u8(extendedFont)][(*p) - 0x80]; } } else { while(isWeak(c)) { if(p != begin) ltrBegin++; p++; - c = *p < 0x80 ? *p : extendedMaps[u8(extendedFont)][(*p) - 0x80]; + c = *p < 0x80 ? mapAscii[*p] : extendedMaps[u8(extendedFont)][(*p) - 0x80]; } } @@ -269,7 +293,7 @@ void processRTL(unsigned char *begin, unsigned char *end) { ltrBegin--; p--; } - c = *p < 0x80 ? *p : extendedMaps[u8(extendedFont)][(*p) - 0x80]; + c = *p < 0x80 ? mapAscii[*p] : extendedMaps[u8(extendedFont)][(*p) - 0x80]; rtl = false; } diff --git a/retail/common/include/igm_text.h b/retail/common/include/igm_text.h index b894e010d..5fbbf465b 100644 --- a/retail/common/include/igm_text.h +++ b/retail/common/include/igm_text.h @@ -30,13 +30,14 @@ static_assert(sizeof(IgmText) == 0xA0C, "IgmText is too big! Allocate more space enum class IgmFont : u8 { arabic = 0, - cyrillic = 1, - extendedLatin = 2, - greek = 3, - hangul = 4, - hebrew = 5, - japanese = 6, - chinese = 7 + chinese = 1, + cyrillic = 2, + extendedLatin = 3, + greek = 4, + hangul = 5, + hebrew = 6, + japanese = 7, + vietnamese = 8 }; #endif diff --git a/retail/nitrofiles/fonts/ascii.lz77 b/retail/nitrofiles/fonts/ascii.lz77 index f444e33ccadd55de7196b70ce141f6decbf0ba45..5b3466255254cf0a46580a67e0b9d0b63af81a19 100644 GIT binary patch literal 630 zcmWNLKTH!*9LK-+`t;7)^nQ1qaG1;S`cfOb5PF^o5YrqF7nwvG1ti2)h7!RLWiSpR z5~JvXe+EfRjEnd;NF0nf!Qxy76CE2D7Nd|c z`W+y>)`F?J9L|uWm_Q1*w$+?HXWMO9Y_wl1N9FQJqX%E_c`}v~`L}07{l$1_W(-Kj zFbs4#>!B{gtkE26PB(8fmw#;k#f-S%IL=Yq5wQaXBi_B2t? zjbbUc-4Bi3r+*6BTq6r~KYaWr;ge@PQIaDito!0OtV`O8XyBkWE?SEvxO?(E%ehrA zSy!KE2M!giK7)O*Hc=Ibv<=4WboLFBj2!b)wYC8Gm6{EURFT&Dpr(e!E_GTJR5bWn z-RB)V@1|aA&!X;7uOlHd2<&$`h|W|vxtG=CKxi23QMeI(GvKmS;e!W?ZtwmFK3|8u literal 602 zcmY+8KWG#|9EIP^jd$a5-2QgmBuiX2bHjP)5WIDTB+5CrvCwouL4p#vOLGS*5v;U` zF)9W`4WvmGM1p@n!O~bIR;DvuEEG~$SO`WdE7!A>2M@mD<2`~vicM^$X}g_Lx|zj6 zmZAL#phBltPI}ni$C2f@LTG5Jkk$Px4nUz0!_U`oC*!9LtVx-x}IT)I`l-{!UA5< zjktRoKkWF$3v(>GOJ}Xt8ki=&N?p#ef~)9{FrViU=Qb@+lg}lzh~sJ$-_^z#UW2?6 zv{%f_qNkD6EVLXMF$OJNt2rh~G`+>FYNeA8F=s**&(jbOzfcxWN$RS)dh9FbpfMwu zM9HTq_`luvY=GUzVr6>_>>ll@6y?fp8Cw`${*{SyYY5d~LpSh-en#Zzb;=a_*d^sy z-e3r-qAY~_aTx;*#SRSC+)-IWsj>lugst-u_ljj?)F; zvAXNRNhFPh%E5w_osDpI-X9>Ol8DWfiG`#bH}Z=2c(3{J5L|$|QeCB5;7@vWWUzar zX%sNzEjZfM;&N}I!!tu!phIW|UD6<3Pymv$YUaJ2i5As-a#zRfVbG7^rK-yT(zAE} zOMycOnNfR6Qta)?#62<8GrY?Xy6n2g^funX%!3UO7r|@E97;`<3AxKu0N3DDAA;qw zqdI6M1&e%zr4(T0nrdy^O`noZm8hH{pGOI-fpCU#l$rR?(ysN{GVr9`G!N3azpocJ z483*Ja4>0pd&?xS>9TZ%?0BXk@w>+T!Bei_M-hG+6~bk?6FT`{$Un^CZCkj-Ar|8$ zNusIq${$^5DCH$eHDC(g+E;$cu`Jm~>JOu_XR>>)NxXhmoa5^S4&&;$N0;#aqP-P? z)d$fE?D4E76eoi>+>(X!7)nwao7yOUGXI)p#1H-VXfdsOY-r`{|A}@vWNvtvI6Bq z7+8QNK`_hYL_XQc1*~k0a278MPz@Upy8*G>W@qLsw&VbiW}u~lKzIKK(uxd!KrR(# n_yuvWB3%AANPtlZLmpi{BjZ1ien!SWpm3>Y3fsJavw#%2N delta 39 vcmeyPut09ZY$hgtk;!wJ^FzcL6H^_+JX| diff --git a/xcf/igm_font/vietnamese.xcf b/xcf/igm_font/vietnamese.xcf new file mode 100644 index 0000000000000000000000000000000000000000..a799a40531d4cb6dac76ab49e5a7bbc03e9a324e GIT binary patch literal 5926 zcmeHLO>bL86n!6#leTs!-%=^ngBFxZ1jP#^7Dz-Cfe@<1Uq}n}nYnXk=FFKp&lwC4?-VDy`^86F zy*$fKLGw3`XGnK|!8UhC zhll;63Ca@ti5tiLok@SM_;@(EUA+6=%@5deQCx?IJA?k_;CQ%a-d}HwCwC9}#dvfu z+`E2$V}GzaIv5=n8=^Lk2e)>LUa^Hw?>d@qMVotYk>-=}ot@p`(V%!8zIVfdvo}9H z8cvGg(eCa37%nHH{rz!&Qf$#Zu+=O(bH>4wei9VSoWj_K5VY0rKl}W6$WlD=yY=Hs@bFjIr3 zfM1v(m=pBFz+{p&TOv1hWy$ZFZZrpkgsj>|&_&nihluB0Bk-c}9+sbt`xeN|IWoB# zo?S_@iY>(GW|m6=MwJo(e#ZXVH=OQ|7O#Z@o2aA0q9 zBm%w)%}`a*b@F8JY{e6rVZnB@7uSZ7?oizrx#5?m?_eqyAg4iEcVy(I#c;WZdRtJH zW&WU^Wf2zlVd*j`i-M`(MTqA2o5$`|2=b)Rr89@5_97yZnNhAYe-mwfiNe9=r}k~J zC7Iebs>(Vm>%!x#)5UtgtxrsAoOlN18!c}QBJ(n&BV{t4s8OdN6LW!W17~gLg$J1R z^Ybn_Bg`CZ;hY%HXA{oF&pl>q#IjGU&idx_<4-TErEcoQHqLI@J}rkDj}3oYg!iuA zsWZuBe92k=Pnm|JB75UG?vJvs^T?O632|z+>)8|bi?Pq@=vSZL$a2p@-U9l=C1hR( zE~aSVsb%`3ht~ZdDCo5SC;mjlN47Q(ZdqPj>8Z^Q7od}j{E%s4Q8hrd{HXfc*^V)S zb;i`!9G)!myi@D-VkgI!1lNG>Q#}n?9buJkK!1^cM){Ov;%N_j{0n!p?BC1H-P>p4WT7nB&I^l17m zEr%rQSfh84&tg|mS4Af*bDlbyYG&z>k>MIScC{SRQRn7q$jlYSqW%7Sm3mH6p=EcT z?@zB!GnSpIaPIfB$sK^)Hr6#GQ6KHWd1w4-*2I<)&ScIb_l_1(>|)za3S7gM@~rcJ Kqw){Og2um|gYl36 literal 0 HcmV?d00001