diff --git a/Languages/po/zh_TW.po b/Languages/po/zh_TW.po index de7db5c6f4..bce8ddee17 100644 --- a/Languages/po/zh_TW.po +++ b/Languages/po/zh_TW.po @@ -5503,7 +5503,7 @@ msgstr "您必須輸入一個有效的設定檔名稱。" #: Source/Core/DolphinWX/Src/ConfigMain.cpp:917 msgid "You must restart Dolphin in order for the change to take effect." -msgstr "You must restart Dolphin in order for the change to take effect." +msgstr "您必須重新啟動 Dolphin 使更改生效。" #: Source/Core/Core/Src/DSP/DSPCore.cpp:109 msgid "" diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 99bc2ae6ca..25885552ef 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -34,7 +34,39 @@ bool AsciiToHex(const char* _szValue, u32& result) bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) { - int writtenCount = vsnprintf(out, outsize, format, args); + int writtenCount; + +#ifdef _WIN32 + // You would think *printf are simple, right? Iterate on each character, + // if it's a format specifier handle it properly, etc. + // + // Nooooo. Not according to the C standard. + // + // According to the C99 standard (7.19.6.1 "The fprintf function") + // The format shall be a multibyte character sequence + // + // Because some character encodings might have '%' signs in the middle of + // a multibyte sequence (SJIS for example only specifies that the first + // byte of a 2 byte sequence is "high", the second byte can be anything), + // printf functions have to decode the multibyte sequences and try their + // best to not screw up. + // + // Unfortunately, on Windows, the locale for most languages is not UTF-8 + // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the + // locale, and completely fails when trying to decode UTF-8 as EUC-CN. + // + // On the other hand, the fix is simple: because we use UTF-8, no such + // multibyte handling is required as we can simply assume that no '%' char + // will be present in the middle of a multibyte sequence. + // + // This is why we lookup an ANSI (cp1252) locale here and use _vsnprintf_l. + static locale_t c_locale = NULL; + if (!c_locale) + c_locale = _create_locale(LC_ALL, ".1252"); + writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args); +#else + writtenCount = vsnprintf(out, outsize, format, args); +#endif if (writtenCount > 0 && writtenCount < outsize) { @@ -58,10 +90,9 @@ std::string StringFromFormat(const char* format, ...) va_start(args, format); required = _vscprintf(format, args); buf = new char[required + 1]; - vsnprintf(buf, required, format, args); + CharArrayFromFormatV(buf, required + 1, format, args); va_end(args); - buf[required] = '\0'; std::string temp = buf; delete[] buf; #else