Skip to content

Instantly share code, notes, and snippets.

@bgK
Created January 12, 2015 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bgK/1a7dec00decd86df0720 to your computer and use it in GitHub Desktop.
Save bgK/1a7dec00decd86df0720 to your computer and use it in GitHub Desktop.
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