diff options
author | Max Horn | 2003-06-04 14:37:43 +0000 |
---|---|---|
committer | Max Horn | 2003-06-04 14:37:43 +0000 |
commit | 6fd0e4a07f7502cf88e0d65a7030836196c15852 (patch) | |
tree | 15622623c1b5e89dea1ae57d208101cf93d4d3e3 | |
parent | 97aaab94108c3ddbac82a130ddb4f4050867a880 (diff) | |
download | scummvm-rg350-6fd0e4a07f7502cf88e0d65a7030836196c15852.tar.gz scummvm-rg350-6fd0e4a07f7502cf88e0d65a7030836196c15852.tar.bz2 scummvm-rg350-6fd0e4a07f7502cf88e0d65a7030836196c15852.zip |
Patch #747021: DIG&CMI 2 byte charset support (very heavily modified by me; still needs more cleanup but already works well enough)
svn-id: r8293
-rw-r--r-- | scumm/charset.cpp | 241 | ||||
-rw-r--r-- | scumm/charset.h | 8 | ||||
-rw-r--r-- | scumm/nut_renderer.cpp | 74 | ||||
-rw-r--r-- | scumm/nut_renderer.h | 1 | ||||
-rw-r--r-- | scumm/scumm.h | 8 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 67 | ||||
-rw-r--r-- | scumm/smush/smush_font.cpp | 70 | ||||
-rw-r--r-- | scumm/smush/smush_font.h | 3 | ||||
-rw-r--r-- | scumm/string.cpp | 22 |
9 files changed, 354 insertions, 140 deletions
diff --git a/scumm/charset.cpp b/scumm/charset.cpp index 4a37b555d2..56d89113f5 100644 --- a/scumm/charset.cpp +++ b/scumm/charset.cpp @@ -79,16 +79,13 @@ void CharsetRendererV3::setCurID(byte id) { // do spacing for variable width old-style font int CharsetRendererClassic::getCharWidth(byte chr) { + if(chr >= 0x80 && _vm->_CJKMode) + return 6; int spacing = 0; int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); if (offs) { - spacing = _fontPtr[offs]; - if (_fontPtr[offs + 2] >= 0x80) { - spacing += _fontPtr[offs + 2] - 0x100; - } else { - spacing += _fontPtr[offs + 2]; - } + spacing = _fontPtr[offs] + (signed char)_fontPtr[offs + 2]; } return spacing; @@ -536,16 +533,10 @@ void CharsetRendererV3::printChar(int chr) { // Indy3 / Zak256 / Loom VirtScreen *vs; byte *char_ptr, *dest_ptr, *mask_ptr; - unsigned int buffer = 0, bit = 0, x = 0, y = 0; bool useMask; int w, h; + int drawTop; - if (!_dropShadow) { - w = h = 8; - } else { - w = h = 9; - } - _vm->checkRange(_vm->_maxCharsets - 1, 0, _curId, "Printing with bad charset %d"); if ((vs = _vm->findVirtScreen(_top)) == NULL) @@ -554,6 +545,8 @@ void CharsetRendererV3::printChar(int chr) { if (chr == '@') return; + _vm->_charsetColorMap[1] = _color; + if (_firstChar) { _str.left = _left; _str.top = _top; @@ -562,55 +555,23 @@ void CharsetRendererV3::printChar(int chr) { _firstChar = false; } + w = h = 8; + if (_dropShadow) { + w++; + h++; + } + + drawTop = _top - vs->topline; char_ptr = _fontPtr + chr * 8; - dest_ptr = vs->screenPtr + vs->xstart + (_top - vs->topline) * _vm->_screenWidth + _left; - mask_ptr = _vm->getMaskBuffer(_left, _top - vs->topline, 0); + dest_ptr = vs->screenPtr + vs->xstart + drawTop * _vm->_screenWidth + _left; + mask_ptr = _vm->getMaskBuffer(_left, drawTop, 0); useMask = (vs->number == 0 && !_ignoreCharsetMask); - _vm->updateDirtyRect(vs->number, _left, _left + w, _top - vs->topline, _top - vs->topline + h, 0); + _vm->updateDirtyRect(vs->number, _left, _left + w, drawTop, drawTop + h, 0); if (vs->number == 0) _hasMask = true; - for (y = 0; y < 8; y++) { - byte maskmask = revBitMask[_left & 7]; - int maskpos = 0; - - for (x = 0; x < 8; x++) { - if ((bit >>= 1) == 0) { - buffer = *char_ptr++; - bit = 0x80; - } - if (buffer & bit) { - if (_dropShadow) { - *(dest_ptr + x + 1) = 0; - *(dest_ptr + x + _vm->_screenWidth) = 0; - *(dest_ptr + x + _vm->_screenWidth + 1) = 0; - } - *(dest_ptr + x) = _color; - - if (useMask) { - mask_ptr[maskpos] |= maskmask; - if (_dropShadow) { - mask_ptr[maskpos + _vm->gdi._numStrips] |= maskmask; - if (maskmask == 1) { - mask_ptr[maskpos + 1] |= 0x80; - mask_ptr[maskpos + _vm->gdi._numStrips + 1] |= 0x80; - } else { - mask_ptr[maskpos] |= (maskmask >> 1); - mask_ptr[maskpos + _vm->gdi._numStrips] |= (maskmask >> 1); - } - } - } - } - maskmask >>= 1; - if (maskmask == 0) { - maskmask = 0x80; - maskpos++; - } - } - dest_ptr += _vm->_screenWidth; - mask_ptr += _vm->gdi._numStrips; - } + drawBits1(vs, dest_ptr, char_ptr, mask_ptr, drawTop, 8, 8); if (_str.left > _left) _str.left = _left; @@ -628,10 +589,11 @@ void CharsetRendererV3::printChar(int chr) { } void CharsetRendererClassic::printChar(int chr) { - int width, height; + int width, height, origWidth, origHeight; int offsX, offsY; - int d; VirtScreen *vs; + const byte *charPtr; + int is2byte = (chr >= 0x80 && _vm->_CJKMode) ? 1 : 0; _vm->checkRange(_vm->_maxCharsets - 1, 1, _curId, "Printing with bad charset %d"); @@ -641,20 +603,41 @@ void CharsetRendererClassic::printChar(int chr) { if (chr == '@') return; - _bpp = *_fontPtr; _vm->_charsetColorMap[1] = _color; + + if(is2byte) { + _dropShadow = true; + charPtr = g_scumm->get2byteCharPtr(chr); + width = g_scumm->_2byteWidth; + height = g_scumm->_2byteHeight; + offsX = offsY = 0; + } else { + uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); + assert(charOffs < 0x10000); + if (!charOffs) + return; + charPtr = _fontPtr + charOffs; + + width = charPtr[0]; + height = charPtr[1]; + + if (_disableOffsX) { + offsX = 0; + } else { + offsX = (signed char)charPtr[2]; + } + + offsY = (signed char)charPtr[3]; - uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4); - - if (!charOffs) - return; - - assert(charOffs < 0x10000); - - _charPtr = _fontPtr + charOffs; - - width = _charPtr[0]; - height = _charPtr[1]; + charPtr += 4; // Skip over char header + } + origWidth = width; + origHeight = height; + + if (_dropShadow) { + width++; + height++; + } if (_firstChar) { _str.left = 0; _str.top = 0; @@ -662,25 +645,11 @@ void CharsetRendererClassic::printChar(int chr) { _str.bottom = 0; } - if (_disableOffsX) { - offsX = 0; - } else { - d = _charPtr[2]; - if (d >= 0x80) - d -= 0x100; - offsX = d; - } - - d = _charPtr[3]; - if (d >= 0x80) - d -= 0x100; - offsY = d; - _top += offsY; _left += offsX; - if (_left + width > _right + 1 || _left < 0) { - _left += width; + if (_left + origWidth > _right + 1 || _left < 0) { + _left += origWidth; _top -= offsY; return; } @@ -704,48 +673,55 @@ void CharsetRendererClassic::printChar(int chr) { int drawTop = _top - vs->topline; if (drawTop < 0) drawTop = 0; - int bottom = drawTop + height + offsY; - _vm->updateDirtyRect(vs->number, _left, _left + width, drawTop, bottom, 0); + _vm->updateDirtyRect(vs->number, _left, _left + width, drawTop, drawTop + height + offsY, 0); if (vs->number != 0) _blitAlso = false; if (vs->number == 0 && !_ignoreCharsetMask) _hasMask = true; - _charPtr += 4; byte *mask = _vm->getMaskBuffer(_left, drawTop, 0); byte *dst = vs->screenPtr + vs->xstart + drawTop * _vm->_screenWidth + _left; + byte *back = dst; if (_blitAlso) { - byte *back = dst; dst = _vm->getResourceAddress(rtBuffer, vs->number + 5) + vs->xstart + drawTop * _vm->_screenWidth + _left; + } - drawBits(vs, dst, mask, drawTop, width, height); + if(is2byte) { + drawBits1(vs, dst, charPtr, mask, drawTop, origWidth, origHeight); + } else { + byte bpp = *_fontPtr; + drawBitsN(vs, dst, charPtr, mask, bpp, drawTop, origWidth, origHeight); + } + if (_blitAlso) { int h = height; do { memcpy(back, dst, width); back += _vm->_screenWidth; dst += _vm->_screenWidth; } while (--h); - } else { - drawBits(vs, dst, mask, drawTop, width, height); } - _left += width; - if (_left > _str.right) + _left += origWidth; + + if (_str.right < _left) { _str.right = _left; + if (_dropShadow) + _str.right++; + } - if (_top + height > _str.bottom) + if (_str.bottom < _top + height) _str.bottom = _top + height; _top -= offsY; } -void CharsetRendererClassic::drawBits(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height) { +void CharsetRendererClassic::drawBitsN(VirtScreen *vs, byte *dst, const byte *src, byte *mask, byte bpp, int drawTop, int width, int height) { byte maskmask; int y, x; int maskpos; @@ -753,29 +729,28 @@ void CharsetRendererClassic::drawBits(VirtScreen *vs, byte *dst, byte *mask, int byte numbits, bits; bool useMask = (vs->number == 0 && !_ignoreCharsetMask); - bits = *_charPtr++; + assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8); + bits = *src++; numbits = 8; - y = 0; - for (y = 0; y < height && y + drawTop < vs->height; y++) { maskmask = revBitMask[_left & 7]; maskpos = 0; for (x = 0; x < width; x++) { - color = (bits >> (8 - _bpp)) & 0xFF; + color = (bits >> (8 - bpp)) & 0xFF; if (color) { + *dst = _vm->_charsetColorMap[color]; if (useMask) { mask[maskpos] |= maskmask; } - *dst = _vm->_charsetColorMap[color]; } dst++; - bits <<= _bpp; - numbits -= _bpp; + bits <<= bpp; + numbits -= bpp; if (numbits == 0) { - bits = *_charPtr++; + bits = *src++; numbits = 8; } maskmask >>= 1; @@ -789,6 +764,54 @@ void CharsetRendererClassic::drawBits(VirtScreen *vs, byte *dst, byte *mask, int } } +void CharsetRendererCommon::drawBits1(VirtScreen *vs, byte *dst, const byte *src, byte *mask, int drawTop, int width, int height) { + byte maskmask; + int y, x; + int maskpos; + byte bits = 0; + bool useMask = (vs->number == 0 && !_ignoreCharsetMask); + + for (y = 0; y < height && y + drawTop < vs->height; y++) { + maskmask = revBitMask[_left & 7]; + maskpos = 0; + + for (x = 0; x < width; x++) { + if((x % 8) == 0) + bits = *src++; + if (bits & revBitMask[x % 8]) { + if (_dropShadow) { + *(dst + 1) = 0; + *(dst + _vm->_screenWidth) = 0; + *(dst + _vm->_screenWidth + 1) = 0; + } + *dst = _vm->_charsetColorMap[1]; + if (useMask) { + mask[maskpos] |= maskmask; + if (_dropShadow) { + mask[maskpos + _vm->gdi._numStrips] |= maskmask; + if (maskmask == 1) { + mask[maskpos + 1] |= 0x80; + mask[maskpos + _vm->gdi._numStrips + 1] |= 0x80; + } else { + mask[maskpos] |= (maskmask >> 1); + mask[maskpos + _vm->gdi._numStrips] |= (maskmask >> 1); + } + } + } + } + dst++; + maskmask >>= 1; + if (maskmask == 0) { + maskmask = 0x80; + maskpos++; + } + } + + dst += _vm->_screenWidth - width; + mask += _vm->gdi._numStrips; + } +} + CharsetRendererNut::CharsetRendererNut(Scumm *vm) : CharsetRenderer(vm) { _current = 0; @@ -843,8 +866,14 @@ void CharsetRendererNut::printChar(int chr) { int width = _current->getCharWidth(chr); int height = _current->getCharHeight(chr); + if(chr >= 256 && _vm->_CJKMode) + width = 16; + _hasMask = true; - _current->drawChar((char)chr, _left, _top, _color, !_ignoreCharsetMask); + if(chr >= 256 && _vm->_CJKMode) + _current->draw2byte(chr, _left, _top, _color, !_ignoreCharsetMask); + else + _current->drawChar((char)chr, _left, _top, _color, !_ignoreCharsetMask); _vm->updateDirtyRect(0, _left, _left + width, _top, _top + height, 0); _left += width; diff --git a/scumm/charset.h b/scumm/charset.h index c436591542..21acf3497d 100644 --- a/scumm/charset.h +++ b/scumm/charset.h @@ -76,6 +76,8 @@ class CharsetRendererCommon : public CharsetRenderer { protected: byte *_fontPtr; + void drawBits1(VirtScreen *vs, byte *dst, const byte *src, byte *mask, int drawTop, int width, int height); + public: CharsetRendererCommon(Scumm *vm) : CharsetRenderer(vm) {} @@ -86,11 +88,9 @@ public: class CharsetRendererClassic : public CharsetRendererCommon { protected: - byte _bpp; - byte *_charPtr; - int getCharWidth(byte chr); - void drawBits(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height); + + void drawBitsN(VirtScreen *vs, byte *dst, const byte *src, byte *mask, byte bpp, int drawTop, int width, int height); public: CharsetRendererClassic(Scumm *vm) : CharsetRendererCommon(vm) {} diff --git a/scumm/nut_renderer.cpp b/scumm/nut_renderer.cpp index c8c0d92a18..8c4c35abde 100644 --- a/scumm/nut_renderer.cpp +++ b/scumm/nut_renderer.cpp @@ -22,6 +22,7 @@ #include "scumm.h" #include "nut_renderer.h" + NutRenderer::NutRenderer(Scumm *vm) { _vm = vm; _initialized = false; @@ -133,7 +134,10 @@ int32 NutRenderer::getCharWidth(byte c) { return 0; } - return READ_LE_UINT16(_dataSrc + _offsets[c] + 6); + if(c & 0x80 && _vm->_CJKMode) + return 8; + else + return READ_LE_UINT16(_dataSrc + _offsets[c] + 6) + 2; } int32 NutRenderer::getCharHeight(byte c) { @@ -143,7 +147,10 @@ int32 NutRenderer::getCharHeight(byte c) { return 0; } - return READ_LE_UINT16(_dataSrc + _offsets[c] + 8); + if(c & 0x80 && _vm->_CJKMode) + return 16; + else + return READ_LE_UINT16(_dataSrc + _offsets[c] + 8); } int32 NutRenderer::getStringWidth(const byte *string) { @@ -208,23 +215,11 @@ void NutRenderer::drawChar(byte c, int32 x, int32 y, byte color, bool useMask) { byte pixel = *src++; if (x + tx < 0 || x + tx >= _vm->_screenWidth || y + ty < 0 || y + ty >= _vm->_screenHeight) continue; -#if 1 if (pixel != 0) { dst[tx] = color; if (useMask) mask[maskpos] |= maskmask; } -#else - if (pixel != 0) { - if (pixel == 0x01) - pixel = (color == 0) ? 0xf : color; - if (pixel == 0xff) - pixel = 0x0; - dst[tx] = pixel; - if (useMask) - mask[maskpos] |= maskmask; - } -#endif maskmask >>= 1; if (maskmask == 0) { maskmask = 0x80; @@ -239,3 +234,54 @@ void NutRenderer::drawChar(byte c, int32 x, int32 y, byte color, bool useMask) { y -= offsetY[i]; } } + +void NutRenderer::draw2byte(int c, int32 x, int32 y, byte color, bool useMask) { + if (_loaded == false) { + debug(2, "NutRenderer::draw2byte() Font is not loaded"); + return; + } + + int width = g_scumm->_2byteWidth; + int height = g_scumm->_2byteHeight; + byte *src = g_scumm->get2byteCharPtr(c); + byte bits = 0; + + byte *dst, *mask = NULL; + byte maskmask; + int maskpos; + + dst = _vm->virtscr[0].screenPtr + y * _vm->_screenWidth + x + _vm->virtscr[0].xstart; + mask = _vm->getMaskBuffer(x, y, 0); + +// drawBits1(&_vm->virtscr[0], dst, src, mask, ?, width, height); + for (int ty = 0; ty < height; ty++) { + maskmask = revBitMask[x & 7]; + maskpos = 0; + for (int tx = 0; tx < width; tx++) { + if((tx % 8) == 0) + bits = *src++; + if (x + tx < 0 || x + tx >= _vm->_screenWidth || y + ty < 0 || y + ty >= _vm->_screenHeight) + continue; + if (bits & revBitMask[tx % 8]) { + dst[tx] = color; + dst[tx+1] = 0; + if (useMask) { + mask[maskpos] |= maskmask; + if (maskmask == 1) { + mask[maskpos + 1] |= 0x80; + } else { + mask[maskpos] |= (maskmask >> 1); + } + } + } + + maskmask >>= 1; + if (maskmask == 0) { + maskmask = 0x80; + maskpos++; + } + } + dst += _vm->_screenWidth; + mask += _vm->gdi._numStrips; + } +} diff --git a/scumm/nut_renderer.h b/scumm/nut_renderer.h index 3194c7ef7c..21f035a5cd 100644 --- a/scumm/nut_renderer.h +++ b/scumm/nut_renderer.h @@ -41,6 +41,7 @@ public: ~NutRenderer(); bool loadFont(const char *filename, const char *dir); + void draw2byte(int c, int32 x, int32 y, byte color, bool useMask); void drawChar(byte c, int32 x, int32 y, byte color, bool useMask); // void drawString(const char *string, int32 x, int32 y, byte color, int32 mode); int32 getCharWidth(byte c); diff --git a/scumm/scumm.h b/scumm/scumm.h index 1a9421f5dc..9e047bafae 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -1065,6 +1065,14 @@ protected: void loadLanguageBundle(); public: void translateText(const byte *text, byte *trans_buff); // Used by class ScummDialog + + // Somewhat hackish stuff for 2 byte support (Chinese/Japanese/Korean) + bool _CJKMode; + int _2byteHeight; + int _2byteWidth; + byte *get2byteCharPtr(int idx); + + protected: #if defined(SCUMM_LITTLE_ENDIAN) diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index 47ec05c74d..e08e4e5de5 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -56,6 +56,26 @@ extern void drawError(char*); Scumm *g_scumm = 0; ScummDebugger *g_debugger; +byte *_2byteFontPtr; +int _2byteWidth; +int _2byteHeight; +bool _CJKMode; + +byte *Scumm::get2byteCharPtr(int idx) { + /* + switch(language) + case korean: + return ( (idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1; + case japanese: + ... + case taiwan: + ... + */ + idx = ( (idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1; // only for korean + return _2byteFontPtr + 2 * _2byteHeight * idx; +} + + extern NewGui *g_gui; extern uint16 _debugLevel; @@ -636,6 +656,52 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst) _saveLoadCompatible = false; } loadLanguageBundle(); + + // Load CJK font + if((_gameId == GID_DIG || _gameId == GID_CMI) && (_language == KO_KOR || _language == JA_JPN || _language == ZH_TWN)) { + File fp; + const char *fontFile = NULL; + _CJKMode = false; + switch(_language) { + case KO_KOR: + _CJKMode = true; + fontFile = "korean.fnt"; + break; + case JA_JPN: + _CJKMode = true; + fontFile = (_gameId == GID_DIG) ? "kanji16.fnt" : "japanese.fnt"; + break; + case ZH_TWN: + if(_gameId == GID_CMI) { + _CJKMode = true; + fontFile = "chinese.fnt"; + } + break; + } + if(_CJKMode && fp.open(fontFile, getGameDataPath(), 1)) { + debug(2, "Loading CJK Font"); + fp.seek(2,SEEK_CUR); + _2byteWidth = fp.readByte(); //FIXME: is this correct? + _2byteHeight = fp.readByte(); + + int numChar = 0; + switch(_language) { + case KO_KOR: + numChar = 2350; + break; + case JA_JPN: + numChar = (_gameId == GID_DIG) ? 1 : 1; //FIXME + break; + case ZH_TWN: + numChar = 1; //FIXME + break; + } + _2byteFontPtr = new byte[2 * _2byteHeight * numChar]; + fp.read(_2byteFontPtr, 2 * _2byteHeight * numChar); + fp.close(); + } + } + _audioNames = NULL; } @@ -643,6 +709,7 @@ Scumm::~Scumm () { delete [] _actors; + delete _2byteFontPtr; delete _charset; delete _pauseDialog; delete _optionsDialog; diff --git a/scumm/smush/smush_font.cpp b/scumm/smush/smush_font.cpp index 7741ad8205..fe9e2333bc 100644 --- a/scumm/smush/smush_font.cpp +++ b/scumm/smush/smush_font.cpp @@ -79,7 +79,7 @@ bool SmushFont::loadFont(const char *filename, const char *directory) { } _nbChars = READ_LE_UINT16(_dataSrc + 10); - int32 offset = READ_BE_UINT32(_dataSrc + 4) + 8; + int offset = READ_BE_UINT32(_dataSrc + 4) + 8; for (int l = 0; l < _nbChars; l++) { if (READ_BE_UINT32(_dataSrc + offset) == 'FRME') { offset += 8; @@ -105,6 +105,14 @@ bool SmushFont::loadFont(const char *filename, const char *directory) { } int SmushFont::getCharWidth(byte v) { + if(v >= 0x80 && g_scumm->_CJKMode) { + if(g_scumm->_gameId == GID_CMI) + return 8; + if(g_scumm->_gameId == GID_DIG) + return 6; + return 0; + } + if(v >= _nbChars) error("invalid character in SmushFont::charWidth : %d (%d)", v, _nbChars); @@ -112,6 +120,14 @@ int SmushFont::getCharWidth(byte v) { } int SmushFont::getCharHeight(byte v) { + if(v >= 0x80 && g_scumm->_CJKMode) { + if(g_scumm->_gameId == GID_CMI) + return 16; + if(g_scumm->_gameId == GID_DIG) + return 10; + return 0; + } + if(v >= _nbChars) error("invalid character in SmushFont::charHeight : %d (%d)", v, _nbChars); @@ -179,8 +195,8 @@ int SmushFont::drawChar(byte *buffer, int dst_width, int x, int y, byte chr) { byte *dst = buffer + dst_width * y + x; if(_original) { - for(int32 j = 0; j < h; j++) { - for(int32 i = 0; i < w; i++) { + for(int j = 0; j < h; j++) { + for(int i = 0; i < w; i++) { char value = *src++; if(value) dst[i] = value; } @@ -188,7 +204,7 @@ int SmushFont::drawChar(byte *buffer, int dst_width, int x, int y, byte chr) { } } else { char color = (_color != -1) ? _color : 1; - if (_new_colors == true) { + if (_new_colors) { for(int j = 0; j < h; j++) { for(int i = 0; i < w; i++) { char value = *src++; @@ -219,6 +235,41 @@ int SmushFont::drawChar(byte *buffer, int dst_width, int x, int y, byte chr) { return w; } +int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, int idx) { + int w = g_scumm->_2byteWidth; + int h = g_scumm->_2byteHeight; + + byte *src = g_scumm->get2byteCharPtr(idx); + byte *dst = buffer + dst_width * (y + (g_scumm->_gameId == GID_CMI ? 7 : 2)) + x; + byte bits = 0; + + if(_original) { + for(int j = 0; j < h; j++) { + for(int i = 0; i < w; i++) { + char value = 1;//*src++; + if(value) dst[i] = value; + } + dst += dst_width; + } + } else { + char color = (_color != -1) ? _color : 1; + if (_new_colors) + color = 0xff; //FIXME; + for(int j = 0; j < h; j++) { + for(int i = 0; i < w; i++) { + if((i % 8) == 0) + bits = *src++; + if (bits & revBitMask[i % 8]) { + dst[i + 1] = 0; + dst[i] = color; + } + } + dst += dst_width; + } + } + return w + 1; +} + static char **split(char *str, char sep) { char **ret = new char *[62]; int n = 0; @@ -243,8 +294,13 @@ static char **split(char *str, char sep) { } void SmushFont::drawSubstring(char *str, byte *buffer, int dst_width, int x, int y) { - for(int i = 0; str[i] != 0; i++) - x += drawChar(buffer, dst_width, x, y, str[i]); + for(int i = 0; str[i] != 0; i++) { + if((byte)str[i] >= 0x80 && g_scumm->_CJKMode) { + x += draw2byte(buffer, dst_width, x, y, (byte)str[i] + 256 * (byte)str[i+1]); + i++; + } else + x += drawChar(buffer, dst_width, x, y, str[i]); + } } void SmushFont::drawStringAbsolute(char *str, byte *buffer, int dst_width, int x, int y) { @@ -419,7 +475,7 @@ void SmushFont::drawStringWrap(char *str, byte *buffer, int dst_width, int dst_h delete []substrings; } -void SmushFont::drawStringWrapCentered(char *str, byte *buffer, int dst_width, int dst_height, int x, int32 y, int width) { +void SmushFont::drawStringWrapCentered(char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width) { debug(9, "SmushFont::drawStringWrapCentered(%s, %d, %d)", str, x, y); int max_substr_width = 0; diff --git a/scumm/smush/smush_font.h b/scumm/smush/smush_font.h index 46f0e21453..8e9b06b33d 100644 --- a/scumm/smush/smush_font.h +++ b/scumm/smush/smush_font.h @@ -50,6 +50,7 @@ protected: int getStringWidth(char *str); int getCharHeight(byte c); int getStringHeight(char *str); + int draw2byte(byte *buffer, int dst_width, int x, int y, int idx); int drawChar(byte *buffer, int dst_width, int x, int y, byte chr); void drawSubstring(char *str, byte *buffer, int dst_width, int x, int y); void decodeCodec(byte *dst, byte *src, int length); @@ -60,7 +61,7 @@ public: void setColor(byte c) { _color = c; } void drawStringCentered(char *str, byte *buffer, int dst_width, int dst_height, int y, int xmin, int width, int offset); void drawStringWrap(char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width); - void drawStringWrapCentered(char *str, byte *buffer, int dst_width, int dst_height, int x, int32 y, int width); + void drawStringWrapCentered(char *str, byte *buffer, int dst_width, int dst_height, int x, int y, int width); void drawStringAbsolute(char *str, byte *buffer, int dst_width, int x, int y); }; diff --git a/scumm/string.cpp b/scumm/string.cpp index c141501e1f..2bb3e5ee22 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -242,6 +242,8 @@ void Scumm::CHARSET_1() { if (c != 0xFF) { _charset->_left = _charset->_nextLeft; _charset->_top = _charset->_nextTop; + if(c & 0x80 && _CJKMode) + c += *buffer++ * 256; if (_features & GF_AFTER_V2 || _features & GF_AFTER_V3) { _charset->printChar(c); } else if (_features & GF_AFTER_V6) { @@ -339,8 +341,8 @@ void Scumm::CHARSET_1() { void Scumm::drawString(int a) { byte buf[256]; byte *space; - int i; - byte fontHeight = 0, chr; + int i, c; + byte fontHeight = 0; uint color; _msgPtrToAdd = buf; @@ -396,10 +398,10 @@ void Scumm::drawString(int a) { buf[1] = 0; } - for (i = 0; (chr = buf[i++]) != 0;) { - if (chr == 0xFE || chr == 0xFF) { - chr = buf[i++]; - switch (chr) { + for (i = 0; (c = buf[i++]) != 0;) { + if (c == 0xFE || c == 0xFF) { + c = buf[i++]; + switch (c) { case 9: case 10: case 13: @@ -429,7 +431,9 @@ void Scumm::drawString(int a) { if (_string[a].no_talk_anim == 0) _charset->_blitAlso = true; } - _charset->printChar(chr); + if(c >= 0x80 && _CJKMode) + c += buf[i++] * 256; + _charset->printChar(c); _charset->_blitAlso = false; } } @@ -701,7 +705,7 @@ void Scumm::drawBlastTexts() { // FIXME byte *buf; - byte c; + int c; int i; _charset->_ignoreCharsetMask = true; @@ -731,6 +735,8 @@ void Scumm::drawBlastTexts() { if (c != 0 && c != 0xFF) { _charset->_left = _charset->_nextLeft; _charset->_top = _charset->_nextTop; + if(c >= 0x80 && _CJKMode) + c += *buf++ * 256; _charset->printChar(c); _charset->_nextLeft = _charset->_left; _charset->_nextTop = _charset->_top; |