Index: scumm/charset.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/charset.cpp,v
retrieving revision 2.38
diff -u -r2.38 charset.cpp
--- scumm/charset.cpp	2 Jun 2003 23:23:45 -0000	2.38
+++ scumm/charset.cpp	3 Jun 2003 16:17:51 -0000
@@ -23,6 +23,27 @@
 #include "scumm.h"
 #include "nut_renderer.h"
 
+bool _2byte_pos_hack;
+
+int get2byteIndex(int idx)
+{
+	/*
+		switch(language)
+		case korean:
+			return ( (idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1;
+		case japanese:
+			...
+		case taiwan:
+			...
+	*/
+	return ( (idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1; // only for korean
+}
+
+bool Scumm::checkCJKLanguage()
+{
+	return (_language == KO_KOR || _language == JA_JPN || _language == ZH_TWN);
+}
+
 CharsetRenderer::CharsetRenderer(Scumm *vm) {
 
 	_nextLeft = 0;
@@ -79,6 +100,8 @@
 
 // do spacing for variable width old-style font
 int CharsetRendererClassic::getCharWidth(byte chr) {
+	if(chr >= 0x80 && _CJKMode)
+		return 6;
 	int spacing = 0;
 
 	int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
@@ -628,6 +651,7 @@
 	int offsX, offsY;
 	int d;
 	VirtScreen *vs;
+	int is2byte = 0;
 
 	_vm->checkRange(_vm->_maxCharsets - 1, 1, _curId, "Printing with bad charset %d");
 	
@@ -640,7 +664,9 @@
 	_bpp = *_fontPtr;
 	_vm->_charsetColorMap[1] = _color;
 
-	uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
+	is2byte = (chr >= 0x80 && _CJKMode) ? 1 : 0;
+
+	uint32 charOffs = READ_LE_UINT32(_fontPtr + (is2byte ? 0x0f : chr) * 4 + 4); //HACK!
 
 	if (!charOffs)
 		return;
@@ -649,7 +675,7 @@
 
 	_charPtr = _fontPtr + charOffs;
 
-	width = _charPtr[0];
+	if(is2byte) width = _charPtr[0] - 1; else width = _charPtr[0]; //HACK!!!
 	height = _charPtr[1];
 	if (_firstChar) {
 		_str.left = 0;
@@ -714,21 +740,29 @@
 	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;
+	}
 
+	if(is2byte) {
+		width = _2byte_width;
+		height = _2byte_height;
+		_charPtr = (byte *)&_2byte[get2byteIndex(chr) * 18];
+		_bpp = 1;
+		draw2byte(vs, dst, mask, drawTop, width, height);
+//		drawBits(vs, dst, mask, drawTop, width, height);
+	} else
 		drawBits(vs, dst, mask, drawTop, width, height);
 
+	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;
@@ -752,8 +786,6 @@
 	bits = *_charPtr++;
 	numbits = 8;
 
-	y = 0;
-
 	for (y = 0; y < height && y + drawTop < vs->height; y++) {
 		maskmask = revBitMask[_left & 7];
 		maskpos = 0;
@@ -785,6 +817,49 @@
 	}
 }
 
+void CharsetRendererClassic::draw2byte(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height) {
+	byte maskmask;
+	int y, x;
+	int maskpos;
+	//int color;
+	byte numbits, bits;
+	bool useMask = (vs->number == 0 && !_ignoreCharsetMask);
+
+	bits = *_charPtr++;
+	numbits = 8;
+
+	for (y = 0; y < height && y + drawTop < vs->height; y++) {
+		maskmask = revBitMask[_left & 7];
+		maskpos = 0;
+
+		for (x = 0; x < width; x++) {
+			if(x && ((x % 8) == 0))
+				bits = *_charPtr++;
+			if (bits & revBitMask[x % 8]) {
+				*(dst + x + 1) = _vm->_charsetColorMap[0];
+				*(dst + x    ) = _vm->_charsetColorMap[1]; //FIXME?
+				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++;
+			}
+		}
+
+		bits = *_charPtr++;
+		dst += _vm->_screenWidth;
+		mask += _vm->gdi._numStrips;
+	}
+}
+
 CharsetRendererNut::CharsetRendererNut(Scumm *vm)
 	 : CharsetRenderer(vm) {
 	_current = 0;
@@ -839,8 +914,14 @@
 	int width = _current->getCharWidth(chr);
 	int height = _current->getCharHeight(chr);
 
+	if(chr >= 256 && _CJKMode)
+		width = 16;
+
 	_hasMask = true;
-	_current->drawChar((char)chr, _left, _top, _color, !_ignoreCharsetMask);
+	if(chr >= 256 && _CJKMode)
+		_current->draw2byte(chr, _left, _top + (_2byte_pos_hack ? 6 : 0), _color, !_ignoreCharsetMask);
+	else
+		_current->drawChar((char)chr, _left, _top, _color, !_ignoreCharsetMask);
 	_vm->updateDirtyRect(0, _left, _left + width, _top, _top + height, 0);
 
 	_left += width;
@@ -849,5 +930,7 @@
 
 	if (_top + height > _str.bottom)
 		_str.bottom = _top + height;
+
+	_2byte_pos_hack = false;
 }
 
Index: scumm/charset.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/charset.h,v
retrieving revision 2.17
diff -u -r2.17 charset.h
--- scumm/charset.h	21 May 2003 16:28:01 -0000	2.17
+++ scumm/charset.h	3 Jun 2003 16:17:51 -0000
@@ -90,6 +90,7 @@
 	byte *_charPtr;
 
 	int getCharWidth(byte chr);
+	void draw2byte(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height);
 	void drawBits(VirtScreen *vs, byte *dst, byte *mask, int drawTop, int width, int height);
 
 public:
Index: scumm/nut_renderer.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.cpp,v
retrieving revision 1.25
diff -u -r1.25 nut_renderer.cpp
--- scumm/nut_renderer.cpp	1 Jun 2003 14:30:26 -0000	1.25
+++ scumm/nut_renderer.cpp	3 Jun 2003 16:17:51 -0000
@@ -22,6 +22,9 @@
 #include "scumm.h"
 #include "nut_renderer.h"
 
+extern int get2byteIndex(int idx);
+
+
 NutRenderer::NutRenderer(Scumm *vm) {
 	_vm = vm;
 	_initialized = false;
@@ -133,7 +136,10 @@
 		return 0;
 	}
 
-	return READ_LE_UINT16(_dataSrc + _offsets[c] + 6);
+	if(c & 0x80 && _CJKMode)
+		return 8;
+	else
+		return READ_LE_UINT16(_dataSrc + _offsets[c] + 6) + 2;
 }
 
 int32 NutRenderer::getCharHeight(byte c) {
@@ -143,7 +149,10 @@
 		return 0;
 	}
 
-	return READ_LE_UINT16(_dataSrc + _offsets[c] + 8);
+	if(c & 0x80 && _CJKMode)
+		return 16;
+	else
+		return READ_LE_UINT16(_dataSrc + _offsets[c] + 8);
 }
 
 int32 NutRenderer::getStringWidth(const byte *string) {
@@ -237,5 +246,58 @@
 	
 		x -= offsetX[i];
 		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 _2byteIndex = get2byteIndex(c);
+	int width = _2byte_width;
+	int height = _2byte_height;
+	char *_2bPtr = &_2byte[_2byteIndex * (_2byte_height * 2)];
+
+	byte *dst, *mask = NULL;
+	byte maskmask;
+	int maskpos;
+	
+	dst = _vm->virtscr[0].screenPtr + y * _vm->_screenWidth + x + _vm->virtscr[0].xstart;
+	mask = _vm->getResourceAddress(rtBuffer, 9)
+					+ (y * _vm->_screenWidth + x) / 8 + _vm->_screenStartStrip;
+
+	for (int ty = 0; ty < height; ty++) {
+		maskmask = revBitMask[x & 7];
+		maskpos = 0;
+		for (int tx = 0; tx < width; tx++) {
+			if (x + tx < 0 || x + tx >= _vm->_screenWidth || y + ty < 0 || y + ty >= _vm->_screenHeight)
+				continue;
+			if(tx && ((tx % 8) == 0))
+				_2bPtr++;
+			if (*_2bPtr & revBitMask[tx % 8]) {
+				*(dst + tx + 1) = 0;
+				*(dst + tx) = color;
+				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++;
+			}
+		}
+
+		_2bPtr++;
+		dst += _vm->_screenWidth;
+		mask += _vm->gdi._numStrips;
 	}
 }
Index: scumm/nut_renderer.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/nut_renderer.h,v
retrieving revision 1.7
diff -u -r1.7 nut_renderer.h
--- scumm/nut_renderer.h	27 May 2003 15:31:13 -0000	1.7
+++ scumm/nut_renderer.h	3 Jun 2003 16:17:51 -0000
@@ -41,6 +41,7 @@
 	~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);
Index: scumm/scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.238
diff -u -r1.238 scumm.h
--- scumm/scumm.h	2 Jun 2003 23:54:51 -0000	1.238
+++ scumm/scumm.h	3 Jun 2003 16:17:52 -0000
@@ -1064,6 +1064,7 @@
 
 	void loadLanguageBundle();
 public:
+	bool checkCJKLanguage();
 	void translateText(const byte *text, byte *trans_buff);	// Used by class ScummDialog
 protected:
 
@@ -1197,6 +1198,14 @@
 
 // This is a constant lookup table of reverse bit masks
 extern const byte revBitMask[8];
+
+//nasty hacks
+extern bool _CJKMode;
+extern int _gid;
+extern char *_2byte;
+extern int _2byte_height;
+extern int _2byte_width;
+extern bool _2byte_pos_hack;
 
 /* Direction conversion functions (between old dir and new dir format) */
 int newDirToOldDir(int dir);
Index: scumm/scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
retrieving revision 2.204
diff -u -r2.204 scummvm.cpp
--- scumm/scummvm.cpp	2 Jun 2003 18:15:09 -0000	2.204
+++ scumm/scummvm.cpp	3 Jun 2003 16:17:52 -0000
@@ -56,6 +56,12 @@
 Scumm *g_scumm = 0;
 ScummDebugger *g_debugger;
 
+int _gid;
+char *_2byte;
+int _2byte_width;
+int _2byte_height;
+bool _CJKMode;
+
 extern NewGui *g_gui;
 extern uint16 _debugLevel;
 
@@ -636,6 +642,53 @@
 		_saveLoadCompatible = false;
 	}
 	loadLanguageBundle();
+
+	// Load CJK font
+	if((_gameId == GID_DIG || _gameId == GID_CMI) && checkCJKLanguage()) {
+		_gid = _gameId;
+		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);
+			_2byte_width = fp.readByte(); //FIXME: is this correct?
+			_2byte_height = 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;
+			}
+			_2byte = new char[2 * _2byte_height * numChar];
+			fp.read(_2byte, 2 * _2byte_height * numChar);
+			fp.close();
+		}
+	}
+
 	_audioNames = NULL;
 }
 
@@ -643,6 +696,7 @@
 {
 	delete [] _actors;
 	
+	delete _2byte;
 	delete _charset;
 	delete _pauseDialog;
 	delete _optionsDialog;
Index: scumm/string.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/string.cpp,v
retrieving revision 1.130
diff -u -r1.130 string.cpp
--- scumm/string.cpp	2 Jun 2003 23:54:52 -0000	1.130
+++ scumm/string.cpp	3 Jun 2003 16:17:52 -0000
@@ -242,6 +242,11 @@
 		if (c != 0xFF) {
 			_charset->_left = _charset->_nextLeft;
 			_charset->_top = _charset->_nextTop;
+			if(c & 0x80 && _CJKMode) {
+				c += *buffer++ * 256;
+				if(_gameId == GID_CMI)
+					_2byte_pos_hack = true; //HACK: �������� y��ǥ�� ���� �ʴ�.
+			}
 			if (_features & GF_AFTER_V2 || _features & GF_AFTER_V3) {
 				_charset->printChar(c);
 			} else if (_features & GF_AFTER_V6) {
@@ -429,7 +434,13 @@
 				if (_string[a].no_talk_anim == 0)
 					_charset->_blitAlso = true;
 			}
-			_charset->printChar(chr);
+			if(chr >= 0x80 && _CJKMode) {
+				if(_gameId == GID_CMI)
+					_2byte_pos_hack = true;
+				_charset->printChar(chr + (buf[i++] * 256));
+			}
+			else
+				_charset->printChar(chr);
 			_charset->_blitAlso = false;
 		}
 	}
@@ -731,7 +742,10 @@
 			if (c != 0 && c != 0xFF) {
 				_charset->_left = _charset->_nextLeft;
 				_charset->_top = _charset->_nextTop;
-				_charset->printChar(c);
+ 				if(c >= 0x80 && _CJKMode)
+ 					_charset->printChar(c + (*buf++ * 256));
+ 				else
+ 					_charset->printChar(c);
 				_charset->_nextLeft = _charset->_left;
 				_charset->_nextTop = _charset->_top;
 			}
Index: scumm/smush/smush_font.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_font.cpp,v
retrieving revision 1.2
diff -u -r1.2 smush_font.cpp
--- scumm/smush/smush_font.cpp	30 Apr 2003 11:26:36 -0000	1.2
+++ scumm/smush/smush_font.cpp	3 Jun 2003 16:17:52 -0000
@@ -27,6 +27,8 @@
 
 #include "smush_font.h"
 
+extern int get2byteIndex(int idx);
+
 SmushFont::SmushFont(bool use_original_colors, bool new_colors) :
 	_nbChars(0),
 	_color(-1),
@@ -105,6 +107,9 @@
 }
 
 int SmushFont::getCharWidth(byte v) {
+	if(v >= 0x80 && _CJKMode)
+		return get2byteCharWidth();
+
 	if(v >= _nbChars)
 		error("invalid character in SmushFont::charWidth : %d (%d)", v, _nbChars);
 
@@ -112,6 +117,9 @@
 }
 
 int SmushFont::getCharHeight(byte v) {
+	if(v >= 0x80 && _CJKMode)
+		return get2byteCharHeight();
+
 	if(v >= _nbChars)
 		error("invalid character in SmushFont::charHeight : %d (%d)", v, _nbChars);
 
@@ -219,6 +227,71 @@
 	return w;
 }
 
+int SmushFont::get2byteCharWidth() {
+	if(_gid == GID_CMI)
+		return 8;
+	if(_gid == GID_DIG)
+		return 6;
+	return 0;
+}
+int SmushFont::get2byteCharHeight() {
+	if(_gid == GID_CMI)
+		return 16;
+	if(_gid == GID_DIG)
+		return 10;
+	return 0;
+}
+
+int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, byte fst, byte snd) {
+	int w = _2byte_width;
+	int h = _2byte_height;
+
+	int _2byteIndex = get2byteIndex(fst + (snd * 256));
+	char *_2bytePtr = &_2byte[_2byteIndex * (_2byte_height * 2)];
+	char *pData = _2bytePtr;
+	byte *dst = buffer + dst_width * (y + (_gid == GID_CMI ? 7 : 2)) + x;
+
+	if(_original) {
+		for(int32 j = 0; j < h; j++) {
+			for(int32 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 == true) {
+			for(int j = 0; j < h; j++) {
+				for(int i = 0; i < w; i++) {
+					if(i && ((i % 8) == 0))
+						pData++;
+					if (*pData & revBitMask[i % 8]) {
+						dst[i + 1] = 0;
+						dst[i] = 0xff; //FIXME
+					}
+				}
+				pData++;
+				dst += dst_width;
+			}
+		} else {
+			for(int j = 0; j < h; j++) {
+				for(int i = 0; i < w; i++) {
+					if(i && ((i % 8) == 0))
+						pData++;
+					if (*pData & revBitMask[i % 8]) {
+						dst[i + 1] = 0;
+						dst[i] = color;
+					}
+				}
+				pData++;
+				dst += dst_width;
+			}
+		}
+	}
+	return w + 1;
+}
+
 static char **split(char *str, char sep) {
 	char **ret = new char *[62];
 	int n = 0;
@@ -243,8 +316,13 @@
 }
 
 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 && _CJKMode) {
+			x += draw2byte(buffer, dst_width, x, y, str[i], 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) {
Index: scumm/smush/smush_font.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/smush/smush_font.h,v
retrieving revision 1.2
diff -u -r1.2 smush_font.h
--- scumm/smush/smush_font.h	17 Mar 2003 13:16:26 -0000	1.2
+++ scumm/smush/smush_font.h	3 Jun 2003 16:17:52 -0000
@@ -46,10 +46,13 @@
 
 protected:
 
+	int get2byteCharWidth();
+	int get2byteCharHeight();
 	int getCharWidth(byte c);
 	int getStringWidth(char *str);
 	int getCharHeight(byte c);
 	int getStringHeight(char *str);
+	int draw2byte(byte *buffer, int dst_width, int x, int y, byte fst, byte snd);
 	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);
