MYST3: Add support for more subtitles charsets

Fix #1156
This commit is contained in:
Bastien Bouclet 2015-01-12 19:52:52 +01:00
parent c0ccf26b05
commit 47fe2503b7
2 changed files with 59 additions and 16 deletions

View File

@ -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

View File

@ -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