aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2003-06-04 14:37:43 +0000
committerMax Horn2003-06-04 14:37:43 +0000
commit6fd0e4a07f7502cf88e0d65a7030836196c15852 (patch)
tree15622623c1b5e89dea1ae57d208101cf93d4d3e3
parent97aaab94108c3ddbac82a130ddb4f4050867a880 (diff)
downloadscummvm-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.cpp241
-rw-r--r--scumm/charset.h8
-rw-r--r--scumm/nut_renderer.cpp74
-rw-r--r--scumm/nut_renderer.h1
-rw-r--r--scumm/scumm.h8
-rw-r--r--scumm/scummvm.cpp67
-rw-r--r--scumm/smush/smush_font.cpp70
-rw-r--r--scumm/smush/smush_font.h3
-rw-r--r--scumm/string.cpp22
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;