Created
January 12, 2015 18:47
-
-
Save bgK/1a7dec00decd86df0720 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/engines/myst3/subtitles.cpp b/engines/myst3/subtitles.cpp | |
index 818b243..255faf0 100644 | |
--- a/engines/myst3/subtitles.cpp | |
+++ b/engines/myst3/subtitles.cpp | |
@@ -55,7 +55,8 @@ Subtitles::Subtitles(Myst3Engine *vm) : | |
_surface(0), | |
_texture(0), | |
_frame(-1), | |
- _font(0) { | |
+ _font(0), | |
+ _charset(nullptr) { | |
} | |
Subtitles::~Subtitles() { | |
@@ -68,6 +69,7 @@ Subtitles::~Subtitles() { | |
} | |
delete _font; | |
+ delete[] _charset; | |
} | |
void Subtitles::loadFontSettings(int32 id) { | |
@@ -86,6 +88,14 @@ void Subtitles::loadFontSettings(int32 id) { | |
_surfaceTop = fontNums->getMiscData(6) + Renderer::kTopBorderHeight + Renderer::kFrameHeight; | |
_fontCharsetCode = fontNums->getMiscData(7); | |
+ if (_fontCharsetCode > 0) { | |
+ _fontCharsetCode = 128; // The Japanese subtitles are encoded in CP 932 / Shift JIS | |
+ } | |
+ | |
+ if (_fontCharsetCode < 0) { | |
+ _fontCharsetCode = -_fontCharsetCode; // Negative values are GDI charset codes | |
+ } | |
+ | |
// We draw the subtitles in the adequate resolution so that they are not | |
// scaled up. This is the scale factor of the current resolution | |
// compared to the original | |
@@ -99,15 +109,16 @@ void Subtitles::loadFontSettings(int32 id) { | |
_fontFace = fontText->getTextData(0); | |
- if (_fontCharsetCode == 0) { | |
- // No game-provided charset for the Japanese version | |
- const DirectorySubEntry *fontCharset = _vm->getFileDescription("CHAR", id, 0, DirectorySubEntry::kRawData); | |
- | |
- if (!fontCharset) | |
- error("Unable to load font charset"); | |
+ const DirectorySubEntry *fontCharset = _vm->getFileDescription("CHAR", id, 0, DirectorySubEntry::kRawData); | |
+ // Load the font charset if any | |
+ if (fontCharset) { | |
Common::MemoryReadStream *data = fontCharset->getData(); | |
- data->read(_charset, sizeof(_charset)); | |
+ | |
+ _charset = new uint8[data->size()]; | |
+ | |
+ data->read(_charset, data->size()); | |
+ | |
delete data; | |
} | |
} | |
@@ -172,7 +183,7 @@ bool Subtitles::loadSubtitles(int32 id) { | |
while (true) { | |
uint8 c = crypted->readByte() ^ key++; | |
- if (c >= 32 && _fontCharsetCode == 0) | |
+ if (c >= 32 && _charset) | |
c = _charset[c - 32]; | |
if (!c) | |
@@ -196,6 +207,36 @@ void Subtitles::createTexture() { | |
_texture = _vm->_gfx->createTexture(_surface); | |
} | |
+const char *Subtitles::getCodePage(uint32 gdiCharset) { | |
+ static const struct { | |
+ uint32 charset; | |
+ const char *codepage; | |
+ } codepages[] = { | |
+ { 128, "cp932" }, // SHIFTJIS_CHARSET | |
+ { 129, "cp949" }, // HANGUL_CHARSET | |
+ { 130, "cp1361" }, // JOHAB_CHARSET | |
+ { 134, "cp936" }, // GB2312_CHARSET | |
+ { 136, "cp950" }, // CHINESEBIG5_CHARSET | |
+ { 161, "cp1253" }, // GREEK_CHARSET | |
+ { 162, "cp1254" }, // TURKISH_CHARSET | |
+ { 163, "cp1258" }, // VIETNAMESE_CHARSET | |
+ { 177, "cp1255" }, // HEBREW_CHARSET | |
+ { 178, "cp1256" }, // ARABIC_CHARSET | |
+ { 186, "cp1257" }, // BALTIC_CHARSET | |
+ { 204, "cp1251" }, // RUSSIAN_CHARSET | |
+ { 222, "cp874" }, // THAI_CHARSET | |
+ { 238, "cp1250" } // EASTEUROPE_CHARSET | |
+ }; | |
+ | |
+ for (uint i = 0; i < ARRAYSIZE(codepages); i++) { | |
+ if (gdiCharset == codepages[i].charset) { | |
+ return codepages[i].codepage; | |
+ } | |
+ } | |
+ | |
+ error("Unknown font charset code '%d'", gdiCharset); | |
+} | |
+ | |
void Subtitles::setFrame(int32 frame) { | |
const Phrase *phrase = 0; | |
@@ -225,18 +266,17 @@ void Subtitles::setFrame(int32 frame) { | |
// Draw the new text | |
memset(_surface->getPixels(), 0, _surface->pitch * _surface->h); | |
+ | |
if (_fontCharsetCode == 0) { | |
font->drawString(_surface, phrase->string, 0, _singleLineTop * _scale, _surface->w, 0xFFFFFFFF, Graphics::kTextAlignCenter); | |
- } else if (_fontCharsetCode == 1) { | |
- // The Japanese subtitles are encoded in CP 932 / Shift JIS | |
+ } else { | |
+ const char *codepage = getCodePage(_fontCharsetCode); | |
#ifdef USE_ICONV | |
- Common::U32String unicode = Common::convertToU32String("cp932", phrase->string); | |
+ Common::U32String unicode = Common::convertToU32String(codepage, phrase->string); | |
font->drawString(_surface, unicode, 0, _singleLineTop * _scale, _surface->w, 0xFFFFFFFF, Graphics::kTextAlignCenter); | |
#else | |
- warning("Unable to display Japanese subtitles, iconv support is not compiled in."); | |
+ warning("Unable to display codepage '%s' subtitles, iconv support is not compiled in.", codepage); | |
#endif | |
- } else { | |
- error("Unknown font charset code '%d', fontface '%s'", _fontCharsetCode, _fontFace.c_str()); | |
} | |
// Update the texture | |
diff --git a/engines/myst3/subtitles.h b/engines/myst3/subtitles.h | |
index 1b7be12..5e66f6c 100644 | |
--- a/engines/myst3/subtitles.h | |
+++ b/engines/myst3/subtitles.h | |
@@ -51,6 +51,9 @@ private: | |
bool loadSubtitles(int32 id); | |
void createTexture(); | |
+ /** Return a codepage usable by iconv from a GDI Charset as provided to CreateFont */ | |
+ const char *getCodePage(uint32 gdiCharset); | |
+ | |
struct Phrase { | |
uint32 offset; | |
int32 frame; | |
@@ -77,7 +80,7 @@ private: | |
uint _line2Top; | |
uint _surfaceTop; | |
int32 _fontCharsetCode; | |
- uint8 _charset[255 - 32]; | |
+ uint8 *_charset; | |
}; | |
} // End of namespace Myst3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment