[Scummvm-cvs-logs] SF.net SVN: scummvm:[53554] scummvm/trunk

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Sun Oct 17 15:08:01 CEST 2010


Revision: 53554
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53554&view=rev
Author:   athrxx
Date:     2010-10-17 13:08:00 +0000 (Sun, 17 Oct 2010)

Log Message:
-----------
SCUMM/FM-TOWNS: more improvements to japanese font drawing

- made use of LordHotos graphics/sjis code to reduce code duplication
- japanese mode for version 3 and 5 works fine now with few exceptions (some line spacing glitches in MI1 intro etc.)

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/screen.cpp
    scummvm/trunk/engines/scumm/charset.cpp
    scummvm/trunk/engines/scumm/charset.h
    scummvm/trunk/engines/scumm/gfx.cpp
    scummvm/trunk/engines/scumm/scumm.cpp
    scummvm/trunk/engines/scumm/scumm.h
    scummvm/trunk/engines/scumm/string.cpp
    scummvm/trunk/graphics/sjis.cpp
    scummvm/trunk/graphics/sjis.h

Modified: scummvm/trunk/engines/kyra/screen.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen.cpp	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/engines/kyra/screen.cpp	2010-10-17 13:08:00 UTC (rev 53554)
@@ -3313,7 +3313,7 @@
     : _colorMap(0), _font(font), _invisColor(invisColor), _is16Color(is16Color), _screen(s) {
 	assert(_font);
 
-	_font->enableOutline(outlineSize);
+	_font->setShadowMode(outlineSize ? Graphics::FontSJIS::kShadowTypeOutline : Graphics::FontSJIS::kShadowTypeNone);
 
 	_sjisWidth = _font->getMaxFontWidth() >> 1;
 	_fontHeight = _font->getFontHeight() >> 1;
@@ -3345,9 +3345,9 @@
 
 	if (!_is16Color) {
 		if (_colorMap[0] == _invisColor)
-			_font->enableOutline(false);
+			_font->setShadowMode(Graphics::FontSJIS::kShadowTypeNone);
 		else
-			_font->enableOutline(true);
+			_font->setShadowMode(Graphics::FontSJIS::kShadowTypeOutline);
 	}
 }
 

Modified: scummvm/trunk/engines/scumm/charset.cpp
===================================================================
--- scummvm/trunk/engines/scumm/charset.cpp	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/engines/scumm/charset.cpp	2010-10-17 13:08:00 UTC (rev 53554)
@@ -55,20 +55,12 @@
 #ifdef DISABLE_TOWNS_DUAL_LAYER_MODE
 		error("FM-Towns Kanji font drawing requires dual graphics layer support which is disabled in this build");
 #endif
-		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")) {
-			error("SCUMM::Font: Couldn't open fmt_fnt.rom");
-		} else {
-			_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();
-		}
+		// use FM-TOWNS font rom, since game files don't have kanji font resources	
+		_cjkFont = Graphics::FontSJIS::createFont(Common::kPlatformFMTowns);
+		if (!_cjkFont)
+			error("SCUMM::Font: Couldn't open file 'FMT_FNT.ROM'");
 		_textSurfaceMultiplier = 2;
+		_useCJKMode = true;
 	} else if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN) {
 		int numChar = 3418;
 		_2byteWidth = 12;
@@ -170,90 +162,6 @@
 	}
 }
 
-static int SJIStoFMTChunk(int f, int s) { //converts sjis code to fmt font offset
-	enum {
-		KANA = 0,
-		KANJI = 1,
-		EKANJI = 2
-	};
-	int base = s - ((s + 1) % 32);
-	int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, 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;
-	}
-
-	// Base corrections
-	if (base == 0x7f && s == 0x7f)
-		base -= 0x20;
-	if (base == 0x9f && s == 0xbe)
-		base += 0x20;
-	if (base == 0xbf && s == 0xde)
-		base += 0x20;
-	//if (base == 0x7f && s == 0x9e)
-	//	base += 0x20;
-
-	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:
-		debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p);
-		return 0;
-	}
-
-	debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
-	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 {<upperBound>,<lowerBound>} in the array represents a SJIS range.
@@ -330,9 +238,8 @@
 			}
 
 			idx = (SWAP_CONSTANT_16(idx) & 0x7fff) - 1;
-		} else {
-			idx = SJIStoFMTChunk((idx % 256), (idx / 256));
 		}
+
 		break;
 	case Common::ZH_TWN:
 		{
@@ -458,9 +365,9 @@
 int CharsetRendererCommon::getFontHeight() {
 	if (_vm->_useCJKMode) {
 		if (_vm->_game.platform == Common::kPlatformFMTowns) {
-			static const uint8 sjisFontHeightM1[] = { 0, 9, 10, 9, 10, 9, 10, 0, 0 };
-			static const uint8 sjisFontHeightM2[] = { 8, 8, 9, 9, 9, 8, 9, 9, 9, 8 };
-			static const uint8 sjisFontHeightI4[] = { 8, 8, 9, 9, 9, 8, 8, 8, 8, 8 };
+			static const uint8 sjisFontHeightM1[] = { 0, 8, 10, 9, 10, 9, 10, 0, 0 };
+			static const uint8 sjisFontHeightM2[] = { 0, 8, 9, 9, 9, 8, 9, 9, 9, 8 };
+			static const uint8 sjisFontHeightI4[] = { 0, 8, 9, 9, 9, 8, 8, 8, 8, 8 };
 			const uint8 *htbl = (_vm->_game.id == GID_MONKEY) ? sjisFontHeightM1 : ((_vm->_game.id == GID_INDY4) ? sjisFontHeightI4 : sjisFontHeightM2);
 			return (_vm->_game.version == 3) ? 8 : htbl[_curId];
 		} else {
@@ -479,17 +386,19 @@
 			if ((chr & 0xff00) == 0xfd00) {
 				chr &= 0xff;
 			} else if (chr >= 256) {
-				spacing = 9;
-			} else if (chr >= 128) {
-				spacing = 5;
+				spacing = 8;
+			} else if (useTownsFontRomCharacter(chr)) {
+				spacing = 4;
 			}
 
 			if (spacing) {
-				static const uint8 sjisWidthM1[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
-				static const uint8 sjisWidthM2[] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 0 };
-				static const uint8 sjisWidthI4[] = { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 };
-				const uint8 *wtbl = (_vm->_game.id == GID_MONKEY) ? sjisWidthM1 : ((_vm->_game.id == GID_INDY4) ? sjisWidthI4 : sjisWidthM2);
-				spacing += wtbl[_curId];
+				if (_vm->_game.id == GID_MONKEY) {
+					spacing++;
+					if (_curId == 2)
+						spacing++;
+				} else if (_vm->_game.id != GID_INDY4 && _curId == 1) {
+					spacing++;
+				}
 			}
 			
 		} else if (chr >= 0x80) {
@@ -507,6 +416,22 @@
 	return spacing;
 }
 
+bool CharsetRendererClassic::useTownsFontRomCharacter(uint16 chr) {
+#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
+	if (_vm->_game.platform != Common::kPlatformFMTowns || !_vm->_useCJKMode)
+		return false;
+
+	if (chr < 128) {
+		if (((_vm->_game.id == GID_MONKEY2 && _curId != 0) || (_vm->_game.id == GID_INDY4 && _curId != 3)) && (chr > 31 && chr != 94 && chr != 95 && chr != 126 && chr != 127))
+			return true;
+		return false;
+	}
+	return true;
+#else
+	return false;
+#endif
+}
+
 int CharsetRenderer::getStringWidth(int arg, const byte *text) {
 	int pos = 0;
 	int width = 1;
@@ -736,11 +661,22 @@
 void CharsetRendererCommon::enableShadow(bool enable) {
 	if (enable) {
 		if (_vm->_game.platform == Common::kPlatformFMTowns) {
-			_shadowColor =
+			_shadowColor = 8;
 #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
-				_vm->_game.version == 5 ? _vm->_townsCharsetColorMap[0] : 0x88;
-#else
-				8;
+			_shadowColor = _vm->_game.version == 5 ? _vm->_townsCharsetColorMap[0] : 0x88;
+			if (_vm->_cjkFont) {
+				if (_vm->_game.version == 5) {
+					if (_vm->_game.id == GID_MONKEY) {
+						_vm->_cjkFont->setShadowMode((_curId == 2 || _curId == 4 || _curId == 6) ? Graphics::FontSJIS::kShadowTypeOutline : Graphics::FontSJIS::kShadowTypeNone);
+					} else if (_vm->_game.id == GID_MONKEY2) {
+						_vm->_cjkFont->setShadowMode((_curId != 1 && _curId != 3 && _curId != 5) ? Graphics::FontSJIS::kShadowTypeOutline : Graphics::FontSJIS::kShadowTypeNone);
+					} else if (_vm->_game.id == GID_INDY4) {
+						_vm->_cjkFont->setShadowMode((_curId == 2 || _curId == 3 || _curId == 4) ? Graphics::FontSJIS::kShadowTypeOutline : Graphics::FontSJIS::kShadowTypeNone);
+					}					
+				} else {
+					_vm->_cjkFont->setShadowMode(Graphics::FontSJIS::kShadowTypeScumm3Towns);
+				}
+			}
 #endif
 			_shadowMode = kFMTOWNSShadowMode;
 		} else {
@@ -748,6 +684,8 @@
 			_shadowMode = kNormalShadowMode;
 		}
 	} else {
+		if (_vm->_cjkFont)
+			_vm->_cjkFont->setShadowMode(Graphics::FontSJIS::kShadowTypeNone);
 		_shadowMode = kNoShadowMode;
 	}
 }
@@ -775,12 +713,14 @@
 		return;
 
 	if (_vm->_useCJKMode && chr > 127) {
-		charPtr = _vm->get2byteCharPtr(chr);
-		width = _vm->_2byteWidth;
-		height = _vm->_2byteHeight;
-		if (!is2byte) {
-			width >>= 1;
-			height >>= 1;
+		if (_vm->_game.platform == Common::kPlatformFMTowns) {
+			charPtr = 0;
+			width = _vm->_cjkFont->getCharWidth(chr);
+			height = _vm->_cjkFont->getFontHeight();
+		} else {
+			width = _vm->_2byteWidth;
+			height = _vm->_2byteHeight;
+			charPtr = _vm->get2byteCharPtr(chr);
 		}
 	} else {
 		charPtr = _fontPtr + chr * 8;
@@ -796,8 +736,8 @@
 	origHeight = height;
 
 	if (_shadowMode != kNoShadowMode) {
-		width += _vm->_textSurfaceMultiplier;
-		height += _vm->_textSurfaceMultiplier;
+		width++;
+		height++;
 	}
 
 	if (_firstChar) {
@@ -823,10 +763,16 @@
 #endif
 		(ignoreCharsetMask || !vs->hasTwoBuffers)) {
 		dst = vs->getPixels(_left, drawTop);
-		drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel);
+		if (charPtr)
+			drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel);
+		else if (_vm->_cjkFont)
+			_vm->_cjkFont->drawChar(dst, chr, vs->pitch, vs->bytesPerPixel, _color, _shadowColor);
 	} else {
 		dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
-		drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte));
+		if (charPtr)
+			drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte));
+		else if (_vm->_cjkFont)
+			_vm->_cjkFont->drawChar(dst, chr, _vm->_textSurface.pitch, vs->bytesPerPixel, _color, _shadowColor);
 		if (is2byte)
 			origWidth /= _vm->_textSurfaceMultiplier;
 	}
@@ -852,9 +798,17 @@
 	int width, height;
 	int is2byte = (chr >= 0x80 && _vm->_useCJKMode) ? 1 : 0;
 	if (is2byte) {
-		charPtr = _vm->get2byteCharPtr(chr);
-		width = _vm->_2byteWidth;
-		height = _vm->_2byteHeight;
+		if (_vm->_game.platform == Common::kPlatformFMTowns) {
+			width = _vm->_cjkFont->getCharWidth(chr);
+			height = _vm->_cjkFont->getFontHeight();
+			dst = (byte *)s.pixels + y * s.pitch + x;
+			_vm->_cjkFont->drawChar(dst, chr, s.pitch, s.bytesPerPixel, _color, _shadowColor);
+			return;
+		} else {
+			charPtr = _vm->get2byteCharPtr(chr);
+			width = _vm->_2byteWidth;
+			height = _vm->_2byteHeight;
+		}
 	} else {
 		charPtr = _fontPtr + chr * 8;
 //		width = height = 8;
@@ -940,19 +894,31 @@
 
 #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
 	processTownsCharsetColors(_bytesPerPixel);
-#endif
 
-	if (_vm->_useCJKMode && chr >= 256) {
-		charPtr = _vm->get2byteCharPtr(chr);
+	if (_vm->_game.platform == Common::kPlatformFMTowns && _vm->_useCJKMode) {
+		if ((chr & 0xff00) == 0xfd00)
+			chr &= 0xff;
+	}
+	
+	if (useTownsFontRomCharacter(chr)) {
+		charPtr = 0;
+		_vm->_cjkChar = chr;
 		enableShadow(true);
-		if (chr >= 256) {			
-			width = _vm->_2byteWidth;
-			height = _vm->_2byteHeight;
-		} else {
-			width = _vm->_2byteWidth / 2;
-			height = _vm->_2byteHeight / 2;
-		}
+		origWidth = width = getCharWidth(chr);
+		origHeight = height = getFontHeight();
 		offsX = offsY = 0;
+	} else
+#endif	
+	if (_vm->_useCJKMode && (chr >= 128)) {
+		enableShadow(true);
+		origWidth = width = _vm->_2byteWidth;
+		origHeight = height = _vm->_2byteHeight;
+		charPtr = _vm->get2byteCharPtr(chr);
+		offsX = offsY = 0;
+		if (_shadowMode != kNoShadowMode) {
+			width++;
+			height++;
+		}
 	} else {
 		uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
 		assert(charOffs < 0x14000);
@@ -960,9 +926,9 @@
 			return;
 		charPtr = _fontPtr + charOffs;
 
-		width = charPtr[0];
-		height = charPtr[1];
-	
+		width = origWidth = charPtr[0];
+		height = origHeight = charPtr[1];
+
 		if (_disableOffsX) {
 			offsX = 0;
 		} else {
@@ -973,13 +939,7 @@
 
 		charPtr += 4;	// Skip over char header
 	}
-	origWidth = width;
-	origHeight = height;
 
-	if (_shadowMode != kNoShadowMode) {
-		width += _vm->_textSurfaceMultiplier;
-		height += _vm->_textSurfaceMultiplier;
-	}
 	if (_firstChar) {
 		_str.left = 0;
 		_str.top = 0;
@@ -990,16 +950,8 @@
 	_top += offsY;
 	_left += offsX;
 
-	int boxWidth = origWidth;
-	int boxHeight = origHeight;
-
-	if (is2byte) {
-		boxWidth /= _vm->_textSurfaceMultiplier;
-		boxHeight /= _vm->_textSurfaceMultiplier;
-	}
-
-	if (_left + boxWidth > _right + 1 || _left < 0) {
-		_left += boxWidth;
+	if (_left + origWidth > _right + 1 || _left < 0) {
+		_left += origWidth;
 		_top -= offsY;
 		return;
 	}
@@ -1037,16 +989,16 @@
 
 	printCharIntern(is2byte, charPtr, origWidth, origHeight, width, height, vs, ignoreCharsetMask);
 
-	_left += boxWidth;
+	_left += origWidth;
 
 	if (_str.right < _left) {
 		_str.right = _left;
-		if (_shadowMode != kNoShadowMode)
+		if (_vm->_game.platform != Common::kPlatformFMTowns && _shadowMode != kNoShadowMode)
 			_str.right++;
 	}
 
-	if (_str.bottom < _top + boxHeight)
-		_str.bottom = _top + boxHeight;
+	if (_str.bottom < _top + origHeight)
+		_str.bottom = _top + origHeight;
 
 	_top -= offsY;
 }
@@ -1109,10 +1061,12 @@
 			drawTop = _top - _vm->_screenTop;
 		}
 
-		if (is2byte) {
+		if (!charPtr && _vm->_cjkFont)
+			_vm->_cjkFont->drawChar(dstPtr, _vm->_cjkChar, dstSurface.pitch, dstSurface.bytesPerPixel, _vm->_townsCharsetColorMap[1], _shadowColor);
+		else if (is2byte) {
 			drawBits1(dstSurface, dstPtr, charPtr, drawTop, origWidth, origHeight, dstSurface.bytesPerPixel);
 		} else {
-			drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight, _vm->_useCJKMode);
+			drawBitsN(dstSurface, dstPtr, charPtr, *_fontPtr, drawTop, origWidth, origHeight, _vm->_textSurfaceMultiplier == 2);
 		}
 
 		if (_blitAlso && vs->hasTwoBuffers) {
@@ -1160,9 +1114,17 @@
 
 	if (is2byte) {
 		enableShadow(true);
-		charPtr = _vm->get2byteCharPtr(chr);
-		width = _vm->_2byteWidth;
-		height = _vm->_2byteHeight;
+		if (_vm->_game.platform == Common::kPlatformFMTowns) {
+			width = _vm->_cjkFont->getCharWidth(chr);
+			height = _vm->_cjkFont->getFontHeight();
+			dst = (byte *)s.pixels + y * s.pitch + x;
+			_vm->_cjkFont->drawChar(dst, chr, s.pitch, s.bytesPerPixel, _color, _shadowColor);
+			return;
+		} else {
+			charPtr = _vm->get2byteCharPtr(chr);
+			width = _vm->_2byteWidth;
+			height = _vm->_2byteHeight;
+		}
 	} else {
 		uint32 charOffs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
 		assert(charOffs < 0x10000);

Modified: scummvm/trunk/engines/scumm/charset.h
===================================================================
--- scummvm/trunk/engines/scumm/charset.h	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/engines/scumm/charset.h	2010-10-17 13:08:00 UTC (rev 53554)
@@ -38,9 +38,9 @@
 struct VirtScreen;
 
 static inline bool checkSJISCode(byte c) {
-	if ((c > 0x84 && c < 0x88) || (c > 0x9f && c < 0xe0) || (c > 0xea /* && c <= 0xff */))
-		return false;
-	return true;
+	if ((c >= 0x80 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfd))
+		return true;
+	return false;
 }
 
 
@@ -115,6 +115,7 @@
 	void enableShadow(bool enable);
 	virtual void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth, bool scale2x = false);
 
+
 public:
 	CharsetRendererCommon(ScummEngine *vm);
 
@@ -136,6 +137,11 @@
 	void drawChar(int chr, const Graphics::Surface &s, int x, int y);
 
 	int getCharWidth(uint16 chr);
+
+	// Some SCUMM 5 games contain hard coded logic to determine whether to use
+	// the SCUMM fonts or the FM-Towns font rom to draw a character. For the other
+	// games we will simply check for a character greater 127.
+	bool useTownsFontRomCharacter(uint16 chr);
 };
 
 class CharsetRendererNES : public CharsetRendererCommon {

Modified: scummvm/trunk/engines/scumm/gfx.cpp
===================================================================
--- scummvm/trunk/engines/scumm/gfx.cpp	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/engines/scumm/gfx.cpp	2010-10-17 13:08:00 UTC (rev 53554)
@@ -1013,11 +1013,6 @@
 
 	if (rect.left > vs->w)
 		return;
-
-#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
-	if (_game.platform == Common::kPlatformFMTowns && _game.id == GID_MONKEY && vs->number == kVerbVirtScreen && rect.bottom <= 154)
-		rect.right = 320;
-#endif
 	
 	// Convert 'rect' to local (virtual screen) coordinates
 	rect.top -= vs->topline;
@@ -1025,13 +1020,18 @@
 
 	rect.clip(vs->w, vs->h);
 
+	const int height = rect.height();
+	const int width = rect.width();
+
+#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
+	if (_game.platform == Common::kPlatformFMTowns && _game.id == GID_MONKEY && vs->number == kVerbVirtScreen && rect.bottom <= 154)
+		rect.right = 320;
+#endif
+
 	markRectAsDirty(vs->number, rect, USAGE_BIT_RESTORED);
 
 	screenBuf = vs->getPixels(rect.left, rect.top);
 
-	const int height = rect.height();
-	const int width = rect.width();
-
 	if (!height)
 		return;
 

Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/engines/scumm/scumm.cpp	2010-10-17 13:08:00 UTC (rev 53554)
@@ -281,6 +281,8 @@
 #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
 	_townsScreen = 0;
 #endif
+	_cjkFont = 0;
+	_cjkChar = 0;
 	_shadowPalette = NULL;
 	_shadowPaletteSize = 0;
 	memset(_currentPalette, 0, sizeof(_currentPalette));
@@ -631,6 +633,7 @@
 #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
 	delete _townsScreen;
 #endif
+	delete _cjkFont;
 
 	delete _debugger;
 

Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/engines/scumm/scumm.h	2010-10-17 13:08:00 UTC (rev 53554)
@@ -36,6 +36,7 @@
 #include "common/rect.h"
 #include "common/str.h"
 #include "graphics/surface.h"
+#include "graphics/sjis.h"
 
 #include "scumm/gfx.h"
 #include "scumm/detection.h"
@@ -1421,6 +1422,8 @@
 	bool towns_isRectInStringBox(int x1, int y1, int x2, int y2);
 	byte _townsPaletteFlags;
 	byte _townsCharsetColorMap[16];
+	Graphics::FontSJIS *_cjkFont;
+	uint16 _cjkChar;
 
 protected:
 	void towns_drawStripToScreen(VirtScreen *vs, int dstX, int dstY, int srcX, int srcY, int w, int h);

Modified: scummvm/trunk/engines/scumm/string.cpp
===================================================================
--- scummvm/trunk/engines/scumm/string.cpp	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/engines/scumm/string.cpp	2010-10-17 13:08:00 UTC (rev 53554)
@@ -634,9 +634,7 @@
 #endif
 		} else {
 			if (c & 0x80 && _useCJKMode) {
-				if (_language == Common::JA_JPN && !checkSJISCode(c)) {
-					c = 0x20; //not in S-JIS
-				} else {
+				if (checkSJISCode(c)) {
 					byte *buffer = _charsetBuffer + _charsetBufPos;
 					c += *buffer++ * 256; //LE
 					_charsetBufPos = buffer - _charsetBuffer;
@@ -993,11 +991,8 @@
 				}
 			}
 			if (c & 0x80 && _useCJKMode) {
-				if (_language == Common::JA_JPN && !checkSJISCode(c)) {
-					c = 0x20; //not in S-JIS
-				} else {
+				if (checkSJISCode(c))
 					c += buf[i++] * 256;
-				}
 			}
 			_charset->printChar(c, true);
 			_charset->_blitAlso = false;
@@ -1129,7 +1124,8 @@
 			// Skip these characters
 		} else {
 			if (!(chr == '@') || (_game.id == GID_CMI && _language == Common::ZH_TWN) ||
-				(_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN))
+				(_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN) ||
+				(_game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN))
 			{
 				*dst++ = chr;
 			}

Modified: scummvm/trunk/graphics/sjis.cpp
===================================================================
--- scummvm/trunk/graphics/sjis.cpp	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/graphics/sjis.cpp	2010-10-17 13:08:00 UTC (rev 53554)
@@ -53,7 +53,7 @@
 }
 
 template<typename Color>
-void FontSJISBase::blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c) const {
+void FontSJISBase::blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c1, Color c2) const {
 	for (int y = 0; y < h; ++y) {
 		Color *d = (Color *)dst;
 		dst += pitch;
@@ -63,8 +63,13 @@
 			if (!(x % 8))
 				mask = *glyph++;
 
-			if (mask & 0x80)
-				*d = c;
+			if (mask & 0x80) {
+				*d = c1;
+				if (_shadowType == kShadowTypeScumm3 ||	_shadowType == kShadowTypeScumm3Towns)
+					d[1] = d[pitch] = c2;
+				if (_shadowType == kShadowTypeScumm3)
+					d[pitch + 1] = c2;
+			}
 			++d;
 			mask <<= 1;
 		}
@@ -122,24 +127,24 @@
 	}
 
 	uint8 outline[18 * 18];
-	if (_outlineEnabled) {
+	if (_shadowType == kShadowTypeOutline) {
 		memset(outline, 0, sizeof(outline));
 		createOutline(outline, glyphSource, width, height);
 	}
 
 	if (bpp == 1) {
-		if (_outlineEnabled) {
+		if (_shadowType == kShadowTypeOutline) {
 			blitCharacter<uint8>(outline, width + 2, height + 2, (uint8 *)dst, pitch, c2);
 			blitCharacter<uint8>(glyphSource, width, height, (uint8 *)dst + pitch + 1, pitch, c1);
 		} else {
-			blitCharacter<uint8>(glyphSource, width, height, (uint8 *)dst, pitch, c1);
+			blitCharacter<uint8>(glyphSource, width, height, (uint8 *)dst, pitch, c1, c2);
 		}
 	} else if (bpp == 2) {
-		if (_outlineEnabled) {
+		if (_shadowType == kShadowTypeOutline) {
 			blitCharacter<uint16>(outline, width + 2, height + 2, (uint8 *)dst, pitch, c2);
 			blitCharacter<uint16>(glyphSource, width, height, (uint8 *)dst + pitch + 2, pitch, c1);
 		} else {
-			blitCharacter<uint16>(glyphSource, width, height, (uint8 *)dst, pitch, c1);
+			blitCharacter<uint16>(glyphSource, width, height, (uint8 *)dst, pitch, c1, c2);
 		}
 	} else {
 		error("FontSJISBase::drawChar: unsupported bpp: %d", bpp);
@@ -148,7 +153,7 @@
 
 uint FontSJISBase::getCharWidth(uint16 ch) const {
 	if (is8x16(ch))
-		return _outlineEnabled ? 10 : 8;
+		return (_shadowType == kShadowTypeOutline) ? 10 : (_shadowType == kShadowTypeNone ? 8 : 9);
 	else
 		return getMaxFontWidth();
 }

Modified: scummvm/trunk/graphics/sjis.h
===================================================================
--- scummvm/trunk/graphics/sjis.h	2010-10-17 12:46:15 UTC (rev 53553)
+++ scummvm/trunk/graphics/sjis.h	2010-10-17 13:08:00 UTC (rev 53554)
@@ -71,13 +71,20 @@
 	virtual bool loadData() = 0;
 
 	/**
-	 * Enable outline drawing.
+	 * Enable outline/shadow drawing.
 	 *
 	 * After changing outline state, getFontHeight and getMaxFontWidth / getCharWidth might return
 	 * different values!
 	 */
-	virtual void enableOutline(bool enable) {}
+	enum ShadowType {
+		kShadowTypeNone,
+		kShadowTypeOutline,
+		kShadowTypeScumm3,
+		kShadowTypeScumm3Towns
+	};
 
+	virtual void setShadowMode(ShadowType type) {}
+
 	/**
 	 * Returns the height of the font.
 	 */
@@ -122,22 +129,23 @@
  */
 class FontSJISBase : public FontSJIS {
 public:
-	FontSJISBase() : _outlineEnabled(false) {}
+	FontSJISBase() : _shadowType(kShadowTypeNone) {}
 
-	void enableOutline(bool enable) { _outlineEnabled = enable; }
+	void setShadowMode(ShadowType type) { _shadowType = type; }
 
-	uint getFontHeight() const { return _outlineEnabled ? 18 : 16; }
-	uint getMaxFontWidth() const { return _outlineEnabled ? 18 : 16; }
+	uint getFontHeight() const { return (_shadowType == kShadowTypeOutline) ? 18 : (_shadowType == kShadowTypeNone ? 16 : 17); }
+	
+	uint getMaxFontWidth() const { return (_shadowType == kShadowTypeOutline) ? 18 : (_shadowType == kShadowTypeNone ? 16 : 17); }
 
 	uint getCharWidth(uint16 ch) const;
 
 	void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const;
 private:
 	template<typename Color>
-	void blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c) const;
+	void blitCharacter(const uint8 *glyph, const int w, const int h, uint8 *dst, int pitch, Color c1, Color c2 = 0) const;
 	void createOutline(uint8 *outline, const uint8 *glyph, const int w, const int h) const;
 protected:
-	bool _outlineEnabled;
+	ShadowType _shadowType;
 
 	bool is8x16(uint16 ch) const;
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list