[Scummvm-cvs-logs] SF.net SVN: scummvm: [27998] scummvm/trunk/engines/scumm

sev at users.sourceforge.net sev at users.sourceforge.net
Tue Jul 10 02:39:13 CEST 2007


Revision: 27998
          http://scummvm.svn.sourceforge.net/scummvm/?rev=27998&view=rev
Author:   sev
Date:     2007-07-09 17:39:12 -0700 (Mon, 09 Jul 2007)

Log Message:
-----------
Preliminary (and buggy) Kanji support.

Modified Paths:
--------------
    scummvm/trunk/engines/scumm/charset.cpp
    scummvm/trunk/engines/scumm/gfx.cpp
    scummvm/trunk/engines/scumm/input.cpp
    scummvm/trunk/engines/scumm/scumm.cpp
    scummvm/trunk/engines/scumm/scumm.h

Modified: scummvm/trunk/engines/scumm/charset.cpp
===================================================================
--- scummvm/trunk/engines/scumm/charset.cpp	2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/charset.cpp	2007-07-10 00:39:12 UTC (rev 27998)
@@ -48,6 +48,8 @@
 void ScummEngine::loadCJKFont() {
 	Common::File fp;
 	_useCJKMode = false;
+	_textSurfaceMultiplier = 1;
+
 	if (_language == Common::JA_JPN && _game.version <= 5) { // FM-TOWNS v3 / v5 Kanji
 		int numChar = 256 * 32;
 		_2byteWidth = 16;
@@ -60,6 +62,7 @@
 			fp.read(_2byteFontPtr, ((_2byteWidth + 7) / 8) * _2byteHeight * numChar);
 			fp.close();
 		}
+		_textSurfaceMultiplier = 2;
 	} else if (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN) {
 		int numChar = 0;
 		const char *fontFile = NULL;
@@ -85,6 +88,7 @@
 		if (fontFile && fp.open(fontFile)) {
 			debug(2, "Loading CJK Font");
 			_useCJKMode = true;
+			_textSurfaceMultiplier = 1; // No multiplication here
 			fp.seek(2, SEEK_CUR);
 			_2byteWidth = fp.readByte();
 			_2byteHeight = fp.readByte();
@@ -276,7 +280,7 @@
 // do spacing for variable width old-style font
 int CharsetRendererClassic::getCharWidth(byte chr) {
 	if (chr >= 0x80 && _vm->_useCJKMode)
-		return _vm->_2byteWidth / 2;
+		return _vm->_2byteWidth;
 	int spacing = 0;
 
 	int offs = READ_LE_UINT32(_fontPtr + chr * 4 + 4);
@@ -1160,7 +1164,7 @@
 
 int CharsetRendererV3::getCharWidth(byte chr) {
 	if (chr & 0x80 && _vm->_useCJKMode)
-		return _vm->_2byteWidth / 2;
+		return _vm->_2byteWidth;
 	int spacing = 0;
 
 	spacing = *(_widthTable + chr);
@@ -1257,18 +1261,18 @@
 		_hasMask = true;
 		_textScreenID = vs->number;
 	}
-	if (ignoreCharsetMask || !vs->hasTwoBuffers) {
+	if ((ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) {
 		dst = vs->getPixels(_left, drawTop);
 		drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight);
 	} else {
-		dst = (byte *)_vm->_textSurface.getBasePtr(_left, _top);
+		dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
 		drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight);
 	}
 
 	if (_str.left > _left)
 		_str.left = _left;
 
-	_left += origWidth;
+	_left += origWidth / _vm->_textSurfaceMultiplier;
 
 	if (_str.right < _left) {
 		_str.right = _left;
@@ -1276,8 +1280,8 @@
 			_str.right++;
 	}
 
-	if (_str.bottom < _top + height)
-		_str.bottom = _top + height;
+	if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
+		_str.bottom = _top + height / _vm->_textSurfaceMultiplier;
 }
 
 void CharsetRendererV3::drawChar(int chr, const Graphics::Surface &s, int x, int y) {
@@ -1391,8 +1395,8 @@
 	_top += offsY;
 	_left += offsX;
 
-	if (_left + origWidth > _right + 1 || _left < 0) {
-		_left += origWidth;
+	if (_left + origWidth / _vm->_textSurfaceMultiplier > _right + 1 || _left < 0) {
+		_left += origWidth / _vm->_textSurfaceMultiplier;
 		_top -= offsY;
 		return;
 	}
@@ -1424,7 +1428,7 @@
 
 	printCharIntern(is2byte, charPtr, origWidth, origHeight, width, height, vs, ignoreCharsetMask);
 
-	_left += origWidth;
+	_left += origWidth / _vm->_textSurfaceMultiplier;
 
 	if (_str.right < _left) {
 		_str.right = _left;
@@ -1432,8 +1436,8 @@
 			_str.right++;
 	}
 
-	if (_str.bottom < _top + height)
-		_str.bottom = _top + height;
+	if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
+		_str.bottom = _top + height / _vm->_textSurfaceMultiplier;
 
 	_top -= offsY;
 }
@@ -1473,12 +1477,12 @@
 	} else {
 		Graphics::Surface dstSurface;
 		Graphics::Surface backSurface;
-		if (ignoreCharsetMask || !vs->hasTwoBuffers) {
+		if ((ignoreCharsetMask || !vs->hasTwoBuffers) && !(_vm->_useCJKMode && _vm->_textSurfaceMultiplier == 2)) {
 			dstSurface = *vs;
 			dstPtr = vs->getPixels(_left, drawTop);
 		} else {
 			dstSurface = _vm->_textSurface;
-			dstPtr = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch + _left;
+			dstPtr = (byte *)_vm->_textSurface.pixels + (_top - _vm->_screenTop) * _vm->_textSurface.pitch * _vm->_textSurfaceMultiplier + _left * _vm->_textSurfaceMultiplier;
 		}
 
 		if (_blitAlso && vs->hasTwoBuffers) {

Modified: scummvm/trunk/engines/scumm/gfx.cpp
===================================================================
--- scummvm/trunk/engines/scumm/gfx.cpp	2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/gfx.cpp	2007-07-10 00:39:12 UTC (rev 27998)
@@ -561,8 +561,25 @@
 		return;
 	
 	const byte *src = vs->getPixels(x, top);
+	int m = _textSurfaceMultiplier;
+	byte *dst;
+	int vsPitch;
 	int pitch = vs->pitch;
 
+	if (_useCJKMode && _textSurfaceMultiplier == 2) {
+		dst = _fmtownsBuf;
+
+		scale2x(dst, _screenWidth * m, src, vs->pitch,  width, height);
+		src = dst;
+
+		vsPitch = _screenWidth * m - width * m;
+
+	} else {
+		vsPitch = vs->pitch - width;
+	}
+
+	dst = _compositeBuf;
+		
 	if (_game.version < 7) {
 		// For The Dig, FT and COMI, we just blit everything to the screen at once.
 		// For older games, things are more complicated. First off, we need to
@@ -572,7 +589,7 @@
 
 		// Compute pointer to the text surface
 		assert(_compositeBuf);
-		const byte *text = (byte *)_textSurface.getBasePtr(x, y);
+		const byte *text = (byte *)_textSurface.getBasePtr(x * m, y * m);
 
 		// The values x, width, etc. are all multiples of 8 at this point,
 		// so loop unrolloing might be a good idea...
@@ -594,19 +611,18 @@
 		//         but also more complicated to implement, and incurs a bigger overhead when
 		//         writing to the text surface.
 #ifdef __DS__
-		DS::asmDrawStripToScreen(height, width, text, src, _compositeBuf, vs->pitch, width, _textSurface.pitch);
+		DS::asmDrawStripToScreen(height, width, text, src, dst, vs->pitch, width, _textSurface.pitch);
 #else
-		byte *dst = _compositeBuf;
-		for (int h = 0; h < height; ++h) {
-			for (int w = 0; w < width; ++w) {
+		for (int h = 0; h < height * m; ++h) {
+			for (int w = 0; w < width * m; ++w) {
 				byte tmp = *text++;
 				if (tmp == CHARSET_MASK_TRANSPARENCY)
 					tmp = *src;
 				*dst++ = tmp;
 				src++;
 			}
-			src += vs->pitch - width;
-			text += _textSurface.pitch - width;
+			src += vsPitch;
+			text += _textSurface.pitch - width * m;
 		}
 #endif
 
@@ -621,6 +637,12 @@
 
 			// center image on the screen
 			x += (Common::kHercW - _screenWidth * 2) / 2;	// (720 - 320*2)/2 = 40
+		} else if (_useCJKMode && m == 2) {
+			pitch *= m;
+			x *= m;
+			y *= m;
+			width *= m;
+			height *= m;
 		} else {
 			if (_renderMode == Common::kRenderCGA)
 				ditherCGA(_compositeBuf, width, x, y, width, height);
@@ -721,7 +743,26 @@
 	*height = dsty - *y;
 }
 
+void ScummEngine::scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
+	byte *dstL1 = dst;
+	byte *dstL2 = dst + dstPitch;
 
+	int dstAdd = dstPitch * 2 - w * 2;
+	int srcAdd = srcPitch - w;
+
+	while (h--) {
+		for (int x = 0; x < w; ++x, dstL1 += 2, dstL2 += 2) {
+			uint16 col = *src++;
+			col |= col << 8;
+			*(uint16*)(dstL1) = col;
+			*(uint16*)(dstL2) = col;
+		}
+		dstL1 += dstAdd; dstL2 += dstAdd;
+		src += srcAdd;
+	}
+}
+
+
 #pragma mark -
 #pragma mark --- Background buffers & charset mask ---
 #pragma mark -
@@ -1117,8 +1158,8 @@
 			error("can only copy bg to main window");
 		blit(backbuff, vs->pitch, bgbuff, vs->pitch, width, height);
 		if (_charset->_hasMask) {
-			byte *mask = (byte *)_textSurface.getBasePtr(x, y - _screenTop);
-			fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width, height);
+			byte *mask = (byte *)_textSurface.getBasePtr(x * _textSurfaceMultiplier, (y - _screenTop) * _textSurfaceMultiplier);
+			fill(mask, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, width * _textSurfaceMultiplier, height * _textSurfaceMultiplier);
 		}
 	} else if (_game.heversion >= 71) {
 		// Flags are used for different methods in HE games
@@ -3362,8 +3403,18 @@
 	for (i = 0; i < w * h; i++) {
 		x = offsets[i] % vs->pitch;
 		y = offsets[i] / vs->pitch;
-		_system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
 
+		if (_useCJKMode && _textSurfaceMultiplier == 2) {
+			int m = _textSurfaceMultiplier;
+			byte *dst = _fmtownsBuf + x * m + y * m * _screenWidth * m;
+			scale2x(dst, _screenWidth * m, vs->getPixels(x, y), vs->pitch,  width, height);
+
+			_system->copyRectToScreen(dst, _screenWidth * m, x * m, (y + vs->topline) * m, width * m, height * m);
+		} else {
+			_system->copyRectToScreen(vs->getPixels(x, y), vs->pitch, x, y + vs->topline, width, height);
+		}
+
+
 		if (++blits >= blits_before_refresh) {
 			blits = 0;
 			waitForTimer(30);
@@ -3391,16 +3442,30 @@
 
 	step = (step * delay) / kScrolltime;
 
+	byte *src;
+	int m = _textSurfaceMultiplier;
+	int vsPitch = vs->pitch;
+
 	switch (dir) {
 	case 0:
 		//up
 		y = 1 + step;
 		while (y < vs->h) {
 			moveScreen(0, -step, vs->h);
-			_system->copyRectToScreen(vs->getPixels(0, y - step),
-				vs->pitch,
-				0, vs->h - step,
-				vs->w, step);
+
+			src = vs->getPixels(0, y - step);
+			if (_useCJKMode && m == 2) {
+				int x1 = 0, y1 = vs->h - step;
+				byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+				scale2x(dst, _screenWidth * m, src, vs->pitch, vs->w, step);
+				src = dst;
+				vsPitch = _screenWidth * 2;
+			}
+
+			_system->copyRectToScreen(src,
+				vsPitch,
+				0 * m, (vs->h - step) * m,
+				vs->w * m, step * m);
 			_system->updateScreen();
 			waitForTimer(delay);
 
@@ -3412,10 +3477,18 @@
 		y = 1 + step;
 		while (y < vs->h) {
 			moveScreen(0, step, vs->h);
-			_system->copyRectToScreen(vs->getPixels(0, vs->h - y),
-				vs->pitch,
+			src = vs->getPixels(0, vs->h - y);
+			if (_useCJKMode && m == 2) {
+				int x1 = 0, y1 = 0;
+				byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+				scale2x(dst, _screenWidth * m, src, vs->pitch, vs->w, step);
+				src = dst;
+				vsPitch = _screenWidth * 2;
+			}
+			_system->copyRectToScreen(src,
+				vsPitch,
 				0, 0,
-				vs->w, step);
+				vs->w * m, step * m);
 			_system->updateScreen();
 			waitForTimer(delay);
 
@@ -3427,10 +3500,18 @@
 		x = 1 + step;
 		while (x < vs->w) {
 			moveScreen(-step, 0, vs->h);
-			_system->copyRectToScreen(vs->getPixels(x - step, 0),
-				vs->pitch,
-				vs->w - step, 0,
-				step, vs->h);
+			src = vs->getPixels(x - step, 0);
+			if (_useCJKMode && m == 2) {
+				int x1 = vs->w - step, y1 = 0;
+				byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+				scale2x(dst, _screenWidth * m, src, vs->pitch, step, vs->h);
+				src = dst;
+				vsPitch = _screenWidth * 2;
+			}
+			_system->copyRectToScreen(src,
+				vsPitch,
+				(vs->w - step) * m, 0,
+				step * m, vs->h * m);
 			_system->updateScreen();
 			waitForTimer(delay);
 
@@ -3442,8 +3523,16 @@
 		x = 1 + step;
 		while (x < vs->w) {
 			moveScreen(step, 0, vs->h);
-			_system->copyRectToScreen(vs->getPixels(vs->w - x, 0),
-				vs->pitch,
+			src = vs->getPixels(vs->w - x, 0);
+			if (_useCJKMode && m == 2) {
+				int x1 = 0, y1 = 0;
+				byte *dst = _fmtownsBuf + x1 * m + y1 * m * _screenWidth * m;
+				scale2x(dst, _screenWidth * m, src, vs->pitch, step, vs->h);
+				src = dst;
+				vsPitch = _screenWidth * 2;
+			}
+			_system->copyRectToScreen(src,
+				vsPitch,
 				0, 0,
 				step, vs->h);
 			_system->updateScreen();

Modified: scummvm/trunk/engines/scumm/input.cpp
===================================================================
--- scummvm/trunk/engines/scumm/input.cpp	2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/input.cpp	2007-07-10 00:39:12 UTC (rev 27998)
@@ -162,8 +162,11 @@
 
 			if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
 				_mouse.x -= (Common::kHercW - _screenWidth * 2) / 2;
-				_mouse.x /= 2;
+				_mouse.x >>= 1;
 				_mouse.y = _mouse.y * 4 / 7;
+			} else if (_useCJKMode && _textSurfaceMultiplier == 2) {
+				_mouse.x >>= 1;
+				_mouse.y >>= 1;
 			}
 			break;
 		case Common::EVENT_LBUTTONUP:

Modified: scummvm/trunk/engines/scumm/scumm.cpp
===================================================================
--- scummvm/trunk/engines/scumm/scumm.cpp	2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/scumm.cpp	2007-07-10 00:39:12 UTC (rev 27998)
@@ -587,6 +587,7 @@
 
 	free(_compositeBuf);
 	free(_herculesBuf);
+	free(_fmtownsBuf);
 
 	delete _debugger;
 	
@@ -1078,12 +1079,19 @@
 		_fileHandle = new ScummFile();
 	}
 	
+	// Load CJK font, if present
+	// Load it earlier so _useCJKMode variable could be set
+	loadCJKFont();
+
 	// Initialize backend
 	_system->beginGFXTransaction();
 		bool defaultTo1XScaler = false;
 		if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
 			_system->initSize(Common::kHercW, Common::kHercH);
 			defaultTo1XScaler = true;
+		} else if (_useCJKMode) {
+			_system->initSize(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier);
+			defaultTo1XScaler = true;
 		} else {
 			_system->initSize(_screenWidth, _screenHeight);
 			defaultTo1XScaler = (_screenWidth > 320);
@@ -1135,14 +1143,11 @@
 	// Load localization data, if present
 	loadLanguageBundle();
 
-	// Load CJK font, if present
-	loadCJKFont();
-
 	// Create the charset renderer
 	setupCharsetRenderer();
 
 	// Create and clear the text surface
-	_textSurface.create(_screenWidth, _screenHeight, 1);
+	_textSurface.create(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier, 1);
 	clearTextSurface();
 
 	// Create the costume renderer
@@ -1210,6 +1215,13 @@
 #if (defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
 	Graphics::initfonts();
 #endif
+
+	_fmtownsBuf = 0;
+	if (_game.platform == Common::kPlatformFMTowns && _language == Common::JA_JPN) {
+		_fmtownsBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
+	}
+
+	_compositeBuf = (byte *)malloc(_screenWidth * _textSurfaceMultiplier * _screenHeight * _textSurfaceMultiplier);
 }
 
 #ifndef DISABLE_SCUMM_7_8

Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h	2007-07-09 21:56:35 UTC (rev 27997)
+++ scummvm/trunk/engines/scumm/scumm.h	2007-07-10 00:39:12 UTC (rev 27998)
@@ -1026,10 +1026,12 @@
 	// Screen rendering
 	byte *_compositeBuf;
 	byte *_herculesBuf;
+	byte *_fmtownsBuf;
 	virtual void drawDirtyScreenParts();
 	void updateDirtyScreen(VirtScreenNumber slot);
 	void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
 	void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
+	void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h);
 
 public:
 	VirtScreen *findVirtScreen(int y);
@@ -1151,6 +1153,7 @@
 	 * drawStripToScreen() composits it over the game graphics.
 	 */
 	Graphics::Surface _textSurface;
+	int _textSurfaceMultiplier;
 
 protected:
 	byte _charsetColor;


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