From 2d31fc3af87526eefb63746c77ea3e7e7d32e90a Mon Sep 17 00:00:00 2001 From: Travis Howell Date: Sun, 22 Nov 2009 08:20:20 +0000 Subject: Add patch for Tobias, for Kanji support in Japanese PCE version of Loom, with minor changes. svn-id: r46061 --- engines/scumm/charset.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++- engines/scumm/charset.h | 8 ++++ engines/scumm/gfx.cpp | 2 +- engines/scumm/scumm.cpp | 52 ++++++++++++--------- engines/scumm/string.cpp | 4 +- 5 files changed, 155 insertions(+), 24 deletions(-) (limited to 'engines') diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp index 5af0c41d6e..00c1f194ca 100644 --- a/engines/scumm/charset.cpp +++ b/engines/scumm/charset.cpp @@ -66,6 +66,21 @@ void ScummEngine::loadCJKFont() { fp.close(); } _textSurfaceMultiplier = 2; + } else if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN) { + int numChar = 3418; + _2byteWidth = 12; + _2byteHeight = 12; + // use PC-Engine System Card, since game files don't have kanji font resources + if (!fp.open("pce.cdbios")) { + error("SCUMM::Font: Couldn't open System Card pce.cdbios"); + } else { + _useCJKMode = true; + debug(2, "Loading PC-Engine System Card"); + fp.seek(0x30000); + _2byteFontPtr = new byte[_2byteWidth * _2byteHeight * numChar / 8]; + fp.read(_2byteFontPtr, _2byteWidth * _2byteHeight * numChar / 8); + fp.close(); + } } else if (_game.version >= 7 && (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN)) { int numChar = 0; const char *fontFile = NULL; @@ -210,13 +225,73 @@ static int SJIStoFMTChunk(int f, int s) { //converts sjis code to fmt font offse return ((chunk_f + chunk) * 32 + (s - base)) + cr; } +static int SJIStoPCEChunk(int f, int s) { //converts sjis code to pce font offset + // rangeTbl maps SJIS char-codes to the PCE System Card font rom. + // Each pair {,} in the array represents a SJIS range. + const int rangeCnt = 45; + static const uint16 rangeTbl[rangeCnt][2] = { + // Symbols + {0x8140,0x817E},{0x8180,0x81AC}, + // 0-9 + {0x824F,0x8258}, + // Latin upper + {0x8260,0x8279}, + // Latin lower + {0x8281,0x829A}, + // Kana + {0x829F,0x82F1},{0x8340,0x837E},{0x8380,0x8396}, + // Greek upper + {0x839F,0x83B6}, + // Greek lower + {0x83BF,0x83D6}, + // Cyrillic upper + {0x8440,0x8460}, + // Cyrillic lower + {0x8470,0x847E},{0x8480,0x8491}, + // Kanji + {0x889F,0x88FC}, + {0x8940,0x897E},{0x8980,0x89FC}, + {0x8A40,0x8A7E},{0x8A80,0x8AFC}, + {0x8B40,0x8B7E},{0x8B80,0x8BFC}, + {0x8C40,0x8C7E},{0x8C80,0x8CFC}, + {0x8D40,0x8D7E},{0x8D80,0x8DFC}, + {0x8E40,0x8E7E},{0x8E80,0x8EFC}, + {0x8F40,0x8F7E},{0x8F80,0x8FFC}, + {0x9040,0x907E},{0x9080,0x90FC}, + {0x9140,0x917E},{0x9180,0x91FC}, + {0x9240,0x927E},{0x9280,0x92FC}, + {0x9340,0x937E},{0x9380,0x93FC}, + {0x9440,0x947E},{0x9480,0x94FC}, + {0x9540,0x957E},{0x9580,0x95FC}, + {0x9640,0x967E},{0x9680,0x96FC}, + {0x9740,0x977E},{0x9780,0x97FC}, + {0x9840,0x9872} + }; + + int ch = (f << 8) | (s & 0xFF); + int offset = 0; + for (int i = 0; i < rangeCnt; ++i) { + if (ch >= rangeTbl[i][0] && ch <= rangeTbl[i][1]) + return offset + ch - rangeTbl[i][0]; + offset += rangeTbl[i][1] - rangeTbl[i][0] + 1; + } + + debug(4, "Invalid Char: 0x%x", ch); + return 0; +} + 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)); + if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) { + idx = SJIStoPCEChunk((idx % 256), (idx / 256)); + return _2byteFontPtr + (_2byteWidth * _2byteHeight / 8) * idx; + } else { + idx = SJIStoFMTChunk((idx % 256), (idx / 256)); + } break; case Common::ZH_TWN: { @@ -994,6 +1069,42 @@ void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, con } } +void CharsetRendererPCE::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth) { + int y, x; + int bitCount = 0; + byte bits = 0; + + const bool resetLineBitCount = (_vm->_language != Common::JA_JPN || width != 12); + + for (y = 0; y < height && y + drawTop < s.h; y++) { + if (resetLineBitCount) + bitCount = 0; + for (x = 0; x < width; x++) { + if ((bitCount % 8) == 0) + bits = *src++; + if ((bits & revBitMask(bitCount % 8)) && y + drawTop >= 0) { + if (bitDepth == 2) { + if (_shadowMode != kNoShadowMode) { + WRITE_UINT16(dst + s.pitch + 2, 0); + } + WRITE_UINT16(dst, _vm->_16BitPalette[_color]); + } else { + if (_shadowMode != kNoShadowMode) { + *(dst + 1) = _shadowColor; + *(dst + s.pitch) = _shadowColor; + *(dst + s.pitch + 1) = _shadowColor; + } + *dst = _color; + } + } + dst += bitDepth; + bitCount++; + } + + dst += s.pitch - width * bitDepth; + } +} + #ifdef ENABLE_SCUMM_7_8 CharsetRendererNut::CharsetRendererNut(ScummEngine *vm) : CharsetRenderer(vm) { diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h index 8c48ef29f5..4b6d5a98f9 100644 --- a/engines/scumm/charset.h +++ b/engines/scumm/charset.h @@ -164,6 +164,14 @@ public: int getCharWidth(byte chr); }; +class CharsetRendererPCE : public CharsetRendererV3 { +protected: + void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth); + +public: + CharsetRendererPCE(ScummEngine *vm) : CharsetRendererV3(vm) {} +}; + class CharsetRendererV2 : public CharsetRendererV3 { protected: bool _deleteFontPtr; diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index 203d746184..651bbec1ab 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -1089,7 +1089,7 @@ void ScummEngine::clearCharsetMask() { } void ScummEngine::clearTextSurface() { - memset(_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, _textSurface.pitch * _textSurface.h); + fill((byte*)_textSurface.pixels, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, _textSurface.w, _textSurface.h, _textSurface.bytesPerPixel); } byte *ScummEngine::getMaskBuffer(int x, int y, int z) { diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 3140ae9b9a..8e93b4a929 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -1089,22 +1089,27 @@ Common::Error ScummEngine::init() { // Initialize backend if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) { initGraphics(Common::kHercW, Common::kHercH, true); - } else if (_useCJKMode) { - initGraphics(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, - // CJK FT and DIG use usual NUT fonts, not FM-TOWNS ROM, so - // there is no text surface for them. This takes that into account - (_screenWidth * _textSurfaceMultiplier > 320)); - } else if (_game.features & GF_16BIT_COLOR) { + } else { + int screenWidth = _screenWidth; + int screenHeight = _screenHeight; + if (_useCJKMode) { + // CJK FT and DIG use usual NUT fonts, not FM-TOWNS ROM, so + // there is no text surface for them. This takes that into account + screenWidth *= _textSurfaceMultiplier; + screenHeight *= _textSurfaceMultiplier; + } + if (_game.features & GF_16BIT_COLOR) { #ifdef USE_RGB_COLOR - Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); - initGraphics(_screenWidth, _screenHeight, _screenWidth > 320, &format); - if (format != _system->getScreenFormat()) - return Common::kUnsupportedColorMode; + Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); + initGraphics(screenWidth, screenHeight, screenWidth > 320, &format); + if (format != _system->getScreenFormat()) + return Common::kUnsupportedColorMode; #else - error("16bit color support is required for this game"); + error("16bit color support is required for this game"); #endif - } else { - initGraphics(_screenWidth, _screenHeight, _screenWidth > 320); + } else { + initGraphics(screenWidth, screenHeight, (screenWidth > 320)); + } } setupScumm(); @@ -1259,18 +1264,23 @@ void ScummEngine_v7::setupScumm() { #endif void ScummEngine::setupCharsetRenderer() { - if (_game.platform == Common::kPlatformNES) - _charset = new CharsetRendererNES(this); - else if (_game.version <= 2) - _charset = new CharsetRendererV2(this, _language); - else if (_game.version == 3) - _charset = new CharsetRendererV3(this); + if (_game.version <= 2) { + if (_game.platform == Common::kPlatformNES) + _charset = new CharsetRendererNES(this); + else + _charset = new CharsetRendererV2(this, _language); + } else if (_game.version == 3) { + if (_game.platform == Common::kPlatformPCEngine) + _charset = new CharsetRendererPCE(this); + else + _charset = new CharsetRendererV3(this); #ifdef ENABLE_SCUMM_7_8 - else if (_game.version == 8) + } else if (_game.version == 8) { _charset = new CharsetRendererNut(this); #endif - else + } else { _charset = new CharsetRendererClassic(this); + } } void ScummEngine::setupCostumeRenderer() { diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp index e99bea87de..8d380511bd 100644 --- a/engines/scumm/string.cpp +++ b/engines/scumm/string.cpp @@ -1093,7 +1093,9 @@ int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) } } else { if (!(chr == '@' && _game.heversion <= 71) || - (_game.id == GID_CMI && _language == Common::ZH_TWN)) { + (_game.id == GID_CMI && _language == Common::ZH_TWN) || + (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN)) + { *dst++ = chr; } } -- cgit v1.2.3