diff options
Diffstat (limited to 'scumm/charset.cpp')
-rw-r--r-- | scumm/charset.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/scumm/charset.cpp b/scumm/charset.cpp index 47e3c4ff71..5481b187d1 100644 --- a/scumm/charset.cpp +++ b/scumm/charset.cpp @@ -25,6 +25,164 @@ namespace Scumm { +void ScummEngine::loadCJKFont() { + _useCJKMode = false; + if ((_gameId == GID_DIG || _gameId == GID_CMI) && (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN)) { + File fp; + const char *fontFile = NULL; + switch(_language) { + case Common::KO_KOR: + fontFile = "korean.fnt"; + break; + case Common::JA_JPN: + fontFile = (_gameId == GID_DIG) ? "kanji16.fnt" : "japanese.fnt"; + break; + case Common::ZH_TWN: + if (_gameId == GID_CMI) { + fontFile = "chinese.fnt"; + } + break; + default: + break; + } + if (fontFile && fp.open(fontFile)) { + debug(2, "Loading CJK Font"); + _useCJKMode = true; + fp.seek(2, SEEK_CUR); + _2byteWidth = fp.readByte(); + _2byteHeight = fp.readByte(); + + int numChar = 0; + switch(_language) { + case Common::KO_KOR: + numChar = 2350; + break; + case Common::JA_JPN: + numChar = (_gameId == GID_DIG) ? 1024 : 2048; //FIXME + break; + case Common::ZH_TWN: + numChar = 1; //FIXME + break; + default: + break; + } + _2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar]; + fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar); + fp.close(); + } + } else if (_language == Common::JA_JPN && _version == 5) { //FM Towns Kanji + File fp; + int numChar = 256 * 32; + _2byteWidth = 16; + _2byteHeight = 16; + //use FM Towns font rom, since game files don't have kanji font resources + if (fp.open("fmt_fnt.rom")) { + _useCJKMode = true; + debug(2, "Loading FM Towns Kanji rom"); + _2byteFontPtr = new byte[((_2byteWidth + 7) / 8) * _2byteHeight * numChar]; + fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar); + fp.close(); + } + } +} + +static int SJIStoFMTChunk(int f, int s) //convert sjis code to fmt font offset +{ + enum { + KANA = 0, + KANJI = 1, + EKANJI = 2 + }; + int base = s - (s % 32) - 1; + int c = 0, p = 0, chunk_f = 0, chunk = 0, cr, kanjiType = KANA; + + if (f >= 0x81 && f <= 0x84) kanjiType = KANA; + if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI; + if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI; + + if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) { + c = 48; //correction + p = -8; //correction + } + + if (kanjiType == KANA) {//Kana + chunk_f = (f - 0x81) * 2; + } else if (kanjiType == KANJI) {//Standard Kanji + p += f - 0x88; + chunk_f = c + 2 * p; + } else if (kanjiType == EKANJI) {//Enhanced Kanji + p += f - 0xe0; + chunk_f = c + 2 * p; + } + + if (base == 0x7f && s == 0x7f) + base -= 0x20; //correction + if ((base == 0x7f && s == 0x9e) || (base == 0x9f && s == 0xbe) || (base == 0xbf && s == 0xde)) + base += 0x20; //correction + + switch(base) { + case 0x3f: + cr = 0; //3f + if (kanjiType == KANA) chunk = 1; + else if (kanjiType == KANJI) chunk = 31; + else if (kanjiType == EKANJI) chunk = 111; + break; + case 0x5f: + cr = 0; //5f + if (kanjiType == KANA) chunk = 17; + else if (kanjiType == KANJI) chunk = 47; + else if (kanjiType == EKANJI) chunk = 127; + break; + case 0x7f: + cr = -1; //80 + if (kanjiType == KANA) chunk = 9; + else if (kanjiType == KANJI) chunk = 63; + else if (kanjiType == EKANJI) chunk = 143; + break; + case 0x9f: + cr = 1; //9e + if (kanjiType == KANA) chunk = 2; + else if (kanjiType == KANJI) chunk = 32; + else if (kanjiType == EKANJI) chunk = 112; + break; + case 0xbf: + cr = 1; //be + if (kanjiType == KANA) chunk = 18; + else if (kanjiType == KANJI) chunk = 48; + else if (kanjiType == EKANJI) chunk = 128; + break; + case 0xdf: + cr = 1; //de + if (kanjiType == KANA) chunk = 10; + else if (kanjiType == KANJI) chunk = 64; + else if (kanjiType == EKANJI) chunk = 144; + break; + default: + return 0; + } + + return ((chunk_f + chunk) * 32 + (s - base)) + cr; +} + +byte *ScummEngine::get2byteCharPtr(int idx) { + switch(_language) { + case Common::KO_KOR: + idx = ((idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1; + break; + case Common::JA_JPN: + idx = SJIStoFMTChunk((idx % 256), (idx / 256)); + break; + case Common::ZH_TWN: + default: + idx = 0; + } + return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx; +} + + +#pragma mark - + + CharsetRenderer::CharsetRenderer(ScummEngine *vm) { _nextLeft = 0; |