Add support for UTF-8 encoded scenario files

If `encoding = utf8` is specified in system3.ini, system3-sdl2 uses
UTF-8 as its multibyte character encoding. It will be used to run games
translated into non-(Japanese|English) languages.
This commit is contained in:
kichikuou
2021-09-04 15:21:52 +09:00
parent 92487ada06
commit 14d0033db3
8 changed files with 78 additions and 7 deletions
+56 -1
View File
@@ -22,6 +22,50 @@ private:
}
};
class Utf8Encoding : public Encoding {
public:
int mblen(const unsigned char* s)
{
if (*s <= 0xbf)
return 1;
if (*s <= 0xdf)
return 2;
if (*s <= 0xef)
return 3;
return 4;
}
int next_codepoint(const unsigned char** str)
{
int code;
const unsigned char *s = *str;
if (*s <= 0x7f) {
code = *s++;
} else if (*s <= 0xbf) {
// Invalid UTF-8 sequence
code = '?';
s++;
} else if (*s <= 0xdf) {
code = (s[0] & 0x1f) << 6 | (s[1] & 0x3f);
s += 2;
} else if (*s <= 0xef) {
code = (s[0] & 0xf) << 12 | (s[1] & 0x3f) << 6 | (s[2] & 0x3f);
s += 3;
} else if (*s <= 0xf7) {
code = (s[0] & 0x7) << 18 | (s[1] & 0x3f) << 12 | (s[2] & 0x3f) << 6 | (s[3] & 0x3f);
s += 4;
} else {
code = 0xfffd; // REPLACEMENT CHARACTER
s++;
while (0x80 <= *s && *s <= 0xbf)
s++;
}
*str = s;
return code;
}
};
int Encoding::mbslen(const unsigned char* s)
{
int len = 0;
@@ -32,7 +76,18 @@ int Encoding::mbslen(const unsigned char* s)
return len;
}
std::unique_ptr<Encoding> Encoding::create()
std::unique_ptr<Encoding> Encoding::create(const char* name)
{
if (!strcasecmp(name, "Shift_JIS") ||
!strcasecmp(name, "Shift-JIS") ||
!strcasecmp(name, "SJIS") ||
!strcasecmp(name, "CP932"))
return std::make_unique<SjisEncoding>();
if (!strcasecmp(name, "UTF-8") ||
!strcasecmp(name, "UTF8"))
return std::make_unique<Utf8Encoding>();
WARNING("Unrecognized encoding: \"%s\"", name);
return std::make_unique<SjisEncoding>();
}