[Scummvm-cvs-logs] CVS: scummvm/scumm actor.cpp,1.319,1.320 charset.cpp,2.124,2.125 charset.h,2.36,2.37 gfx.cpp,2.387,2.388 gfx.h,1.99,1.100 input.cpp,2.12,2.13 palette.cpp,2.22,2.23 scumm.cpp,1.329,1.330 scumm.h,1.533,1.534 vars.cpp,1.113,1.114

Eugene Sandulenko sev at users.sourceforge.net
Sat Feb 19 16:18:15 CET 2005


Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6099/scumm

Modified Files:
	actor.cpp charset.cpp charset.h gfx.cpp gfx.h input.cpp 
	palette.cpp scumm.cpp scumm.h vars.cpp 
Log Message:
Patch #1121337 (CGA rendering in early LEC titles).
Differences against patch:
  o Updated documentation
  o Fixed text colors
  o Implemented Hercules dithering

Ditherers are based on loom ega and monkey ega, so for zak and mm they're
wrong, i.e. these games look better than with original ditherers.

TODO:
  Proper ditherers for zak & MM
  EGA ditherers for VGA SCUMM v5 games


Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/actor.cpp,v
retrieving revision 1.319
retrieving revision 1.320
diff -u -d -r1.319 -r1.320
--- actor.cpp	1 Jan 2005 16:09:12 -0000	1.319
+++ actor.cpp	20 Feb 2005 00:17:21 -0000	1.320
@@ -1400,6 +1400,12 @@
 	} else if (_vm->_features & GF_OLD_BUNDLE) {
 		for (i = 0; i < 16; i++)
 			palette[i] = i;
+
+		// Make stuff more visible on CGA. Based on disassembly
+		if (_vm->_renderMode == Common::kRenderCGA) {
+			palette[6] = 5;
+			palette[7] = 15;
+		}
 	} else {
 		for (i = 0; i < 32; i++)
 			palette[i] = 0xFF;

Index: charset.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/charset.cpp,v
retrieving revision 2.124
retrieving revision 2.125
diff -u -d -r2.124 -r2.125
--- charset.cpp	1 Jan 2005 16:09:13 -0000	2.124
+++ charset.cpp	20 Feb 2005 00:17:21 -0000	2.125
@@ -1160,6 +1160,8 @@
 		_color &= 0x7f;
 	} else
 		_dropShadow = false;
+
+	translateColor();
 }
 
 void CharsetRendererV3::printChar(int chr) {
@@ -1253,6 +1255,21 @@
 	drawBits1(s, dst, charPtr, y, width, height);
 }
 
+void CharsetRenderer::translateColor() {
+	// Based on disassembly
+	if (_vm->_renderMode == Common::kRenderCGA) {
+		static byte CGAtextColorMap[16] = {0,  3, 3, 3, 5, 5, 5,  15, 
+										   15, 3, 3, 3, 5, 5, 15, 15};
+		_color = CGAtextColorMap[_color & 0x0f];
+	}
+
+	if (_vm->_renderMode == Common::kRenderHerc) {
+		static byte HercTextColorMap[16] = {0, 15,  2, 15, 15,  5, 15,  15, 
+										   8, 15, 15, 15, 15, 15, 15, 15};
+		_color = HercTextColorMap[_color & 0x0f];
+	}
+}
+
 
 void CharsetRendererClassic::printChar(int chr) {
 	int width, height, origWidth, origHeight;
@@ -1269,6 +1286,8 @@
 	if (chr == '@')
 		return;
 
+	translateColor();
+
 	_vm->_charsetColorMap[1] = _color;
 
 	int type = *_fontPtr;

Index: charset.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/charset.h,v
retrieving revision 2.36
retrieving revision 2.37
diff -u -d -r2.36 -r2.37
--- charset.h	11 Jan 2005 13:25:01 -0000	2.36
+++ charset.h	20 Feb 2005 00:17:22 -0000	2.37
@@ -92,6 +92,7 @@
 
 	int getStringWidth(int a, const byte *str);
 	void addLinebreaks(int a, byte *str, int pos, int maxwidth);
+	void translateColor();
 	
 	virtual void setCurID(byte id) = 0;
 	int getCurID() { return _curId; }
@@ -99,7 +100,7 @@
 	virtual int getFontHeight() = 0;
 	virtual int getCharWidth(byte chr) = 0;
 	
-	virtual void setColor(byte color) { _color = color; }
+	virtual void setColor(byte color) { _color = color; translateColor(); }
 };
 
 class CharsetRendererCommon : public CharsetRenderer {

Index: gfx.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.cpp,v
retrieving revision 2.387
retrieving revision 2.388
diff -u -d -r2.387 -r2.388
--- gfx.cpp	2 Feb 2005 00:30:50 -0000	2.387
+++ gfx.cpp	20 Feb 2005 00:17:22 -0000	2.388
@@ -188,6 +188,7 @@
 	
 	_compositeBuf = 0;
 	_textSurface.pixels = 0;
+	_herculesBuf = 0;
 }
 
 void ScummEngine::initScreens(int b, int h) {
@@ -225,11 +226,17 @@
 	const int size = _vm->_screenWidth * _vm->_screenHeight;
 	free(_compositeBuf);
 	free(_textSurface.pixels);
+	free(_herculesBuf);
 	_compositeBuf = (byte *)malloc(size);
 	_textSurface.pixels = malloc(size);
 	memset(_compositeBuf, CHARSET_MASK_TRANSPARENCY, size);
 	memset(_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, size);
 
+	if (_vm->_renderMode == Common::kRenderHerc) {
+		_herculesBuf = (byte *)malloc(Common::kHercW * Common::kHercH);
+		memset(_herculesBuf, CHARSET_MASK_TRANSPARENCY, Common::kHercW * Common::kHercH);
+	}
+
 	_textSurface.w = _vm->_screenWidth;
 	_textSurface.h = _vm->_screenHeight;
 	_textSurface.pitch = _vm->_screenWidth;
@@ -474,8 +481,8 @@
 		bottom = _vm->_screenTop + _vm->_screenHeight;
 
 	// Convert the vertical coordinates to real screen coords
-	const int y = vs->topline + top - _vm->_screenTop;
-	const int height = bottom - top;
+	int y = vs->topline + top - _vm->_screenTop;
+	int height = bottom - top;
 	
 	// Compute screen etc. buffer pointers
 	const byte *src = vs->getPixels(x, top);
@@ -508,11 +515,105 @@
 		dst += _vm->_screenWidth;
 		text += _textSurface.pitch;
 	}
-	
-	// Finally blit the whole thing to the screen
-	_vm->_system->copyRectToScreen(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
+
+	if (_vm->_renderMode == Common::kRenderCGA)
+		ditherCGA(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
+
+	if (_vm->_renderMode == Common::kRenderHerc) {
+		ditherHerc(_compositeBuf + x + y * _vm->_screenWidth, _herculesBuf, _vm->_screenWidth, &x, &y, &width, &height);
+		// center image on the screen
+		_vm->_system->copyRectToScreen(_herculesBuf + x + y * Common::kHercW, 
+			Common::kHercW, x + (Common::kHercW - _vm->_screenWidth * 2) / 2, y, width, height);
+	} else {
+		// Finally blit the whole thing to the screen
+		_vm->_system->copyRectToScreen(_compositeBuf + x + y * _vm->_screenWidth, _vm->_screenWidth, x, y, width, height);
+	}
 }
 
+// CGA
+// indy3 loom maniac monkey1 zak
+//
+// Herc (720x350)
+// maniac monkey1 zak
+//
+// EGA
+// monkey2 loom maniac monkey1 atlantis indy3 zak loomcd
+
+// CGA dithers 4x4 square with direct substitutes
+// Odd lines have colors swapped, so there will be checkered patterns.
+// But apparently there is a mistake for 10th color.
+void Gdi::ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const {
+	byte *ptr;
+	int idx1, idx2;
+	static byte cgaDither[2][2][16] = {
+		{{0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 3, 1, 3, 2, 1, 3},
+		 {0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3}},
+		{{0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3},
+		 {0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 1, 1, 3, 2, 1, 3}}};
+
+	for (int y1 = 0; y1 < height; y1++) {
+		ptr = dst + y1 * dstPitch;
+
+		idx1 = (y + y1) % 2;
+		for (int x1 = 0; x1 < width; x1++) {
+			idx2 = (x + x1) % 2;
+			*ptr++ = cgaDither[idx1][idx2][*ptr & 0xF];
+		}
+	}
+}
+
+// Hercules dithering. It uses same dithering tables but output is 1bpp and
+// it stretches in this way:
+//         aaaa0
+// aa      aaaa1
+// bb      bbbb0      Here 0 and 1 mean dithering table row number
+// cc -->  bbbb1
+// dd      cccc0
+//         cccc1
+//         dddd0
+void Gdi::ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) const {
+	byte *srcptr, *dstptr;
+	int xo = *x, yo = *y, widtho = *width, heighto = *height;
+	int idx1, idx2, dsty = 0;
+	static byte cgaDither[2][2][16] = {
+		{{0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 3, 1, 3, 2, 1, 3},
+		 {0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3}},
+		{{0, 0, 1, 1, 0, 2, 2, 3, 0, 3, 1, 1, 3, 3, 1, 3},
+		 {0, 1, 0, 1, 2, 2, 0, 0, 3, 1, 1, 1, 3, 2, 1, 3}}};
+
+	// calculate dsty
+	for (int y1 = 0; y1 < yo; y1++) {
+		dsty += 2;
+		if (y1 % 4 == 3)
+			dsty--;
+	}
+	*y = dsty;
+	*x *= 2;
+	*width *= 2;
+	*height = 0;
+
+	for (int y1 = 0; y1 < heighto;) {
+		srcptr = src + y1 * srcPitch;
+		dstptr = hercbuf + dsty * Common::kHercW + xo * 2;
+
+		if (dstptr >= hercbuf + Common::kHercW * Common::kHercH + widtho * 2)
+			debug("Gnaa");
+
+		idx1 = (dsty % 7) % 2;
+		for (int x1 = 0; x1 < widtho; x1++) {
+			idx2 = (xo + x1) % 2;
+			*dstptr++ = cgaDither[idx1][idx2][*srcptr & 0xF] >> 1;
+			*dstptr++ = cgaDither[idx1][idx2][*srcptr & 0xF] & 0x1;
+			srcptr++;
+		}
+		if (idx1 || dsty % 7 == 6)
+			y1++;
+		dsty++;
+		(*height)++;
+	}
+}
+
+
 #pragma mark -
 #pragma mark --- Background buffers & charset mask ---
 #pragma mark -

Index: gfx.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/gfx.h,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -d -r1.99 -r1.100
--- gfx.h	11 Jan 2005 13:25:01 -0000	1.99
+++ gfx.h	20 Feb 2005 00:17:22 -0000	1.100
@@ -216,6 +216,7 @@
 
 protected:
 	byte *_compositeBuf;
+	byte *_herculesBuf;
 
 	byte *_roomPalette;
 	byte _decomp_shr, _decomp_mask;
@@ -256,7 +257,9 @@
 	/* Misc */
 	void drawStripToScreen(VirtScreen *vs, int x, int w, int t, int b);
 	void updateDirtyScreen(VirtScreen *vs);
-	
+	void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
+	void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *width, int *height) const;
+
 	byte *getMaskBuffer(int x, int y, int z);
 	
 	int getZPlanes(const byte *smap_ptr, const byte *zplane_list[9], bool bmapImage) const;

Index: input.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/input.cpp,v
retrieving revision 2.12
retrieving revision 2.13
diff -u -d -r2.12 -r2.13
--- input.cpp	8 Feb 2005 21:39:21 -0000	2.12
+++ input.cpp	20 Feb 2005 00:17:22 -0000	2.13
@@ -130,6 +130,12 @@
 		case OSystem::EVENT_MOUSEMOVE:
 			_mouse.x = event.mouse.x;
 			_mouse.y = event.mouse.y;
+
+			if (_renderMode == Common::kRenderHerc) {
+				_mouse.x -= (Common::kHercW - _screenWidth * 2) / 2;
+				_mouse.x /= 2;
+				_mouse.y = _mouse.y * 4 / 7;
+			}
 			break;
 
 		case OSystem::EVENT_LBUTTONDOWN:

Index: palette.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/palette.cpp,v
retrieving revision 2.22
retrieving revision 2.23
diff -u -d -r2.22 -r2.23
--- palette.cpp	1 Jan 2005 16:09:14 -0000	2.22
+++ palette.cpp	20 Feb 2005 00:17:22 -0000	2.23
@@ -48,6 +48,28 @@
 	setPalColor(15, 255, 255, 255);
 }
 
+void ScummEngine::setupHercPalette() {
+	setPalColor( 0,   0,   0,   0);
+	setPalColor( 1, 0xAE, 0x69, 0x38);
+
+	// Setup cursor palette
+	setPalColor( 7, 170, 170, 170);
+	setPalColor( 8,  85,  85,  85);
+	setPalColor(15, 255, 255, 255);
+}
+
+void ScummEngine::setupCGAPalette() {
+	setPalColor( 0,   0,   0,   0);
+	setPalColor( 1,   0, 168, 168);
+	setPalColor( 2, 168,   0, 168);
+	setPalColor( 3, 168, 168, 168);
+
+	// Setup cursor palette
+	setPalColor( 7, 170, 170, 170);
+	setPalColor( 8,  85,  85,  85);
+	setPalColor(15, 255, 255, 255);
+}
+
 void ScummEngine::setupEGAPalette() {
 	setPalColor( 0,   0,   0,   0);
 	setPalColor( 1,   0,   0, 170);

Index: scumm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.cpp,v
retrieving revision 1.329
retrieving revision 1.330
diff -u -d -r1.329 -r1.330
--- scumm.cpp	18 Feb 2005 00:28:56 -0000	1.329
+++ scumm.cpp	20 Feb 2005 00:17:22 -0000	1.330
@@ -998,6 +998,32 @@
 	}
 	_confirmExit = ConfMan.getBool("confirm_exit");
 
+	if (ConfMan.hasKey("render_mode")) {
+		_renderMode = Common::parseRenderMode(ConfMan.get("render_mode").c_str());
+	} else {
+		_renderMode = Common::kRenderDefault;
+	}
+
+	// Do some render mode restirctions
+	switch (_renderMode) {
+	case Common::kRenderHerc:
+		if (_version > 2 && _gameId != GID_MONKEY_EGA)
+			_renderMode = Common::kRenderDefault;
+		break;
+
+	case Common::kRenderCGA:
+		if (!(_features & GF_16COLOR))
+			_renderMode = Common::kRenderDefault;
+		break;
+
+	case Common::kRenderEGA:
+			_renderMode = Common::kRenderDefault;
+		break;
+
+	default:
+		break;
+	}
+
 	_hexdumpScripts = false;
 	_showStack = false;
 
@@ -1019,6 +1045,11 @@
 	} else if (_features & GF_NES) {
 		_screenWidth = 256;
 		_screenHeight = 240;
+	} else if (_renderMode == Common::kRenderHerc) {
+		_system->setGraphicsMode("1x");
+		_features |= GF_DEFAULT_TO_1X_SCALER;
+		_screenWidth = 320;
+		_screenHeight = 200;
 	} else {
 		_screenWidth = 320;
 		_screenHeight = 200;
@@ -1109,7 +1140,13 @@
 	// Initialize backend
 	_system->beginGFXTransaction();
 		initCommonGFX(detector);
-		_system->initSize(_screenWidth, _screenHeight);
+		if (_renderMode == Common::kRenderHerc) {
+			_system->initSize(Common::kHercW, Common::kHercH);
+			_features |= GF_DEFAULT_TO_1X_SCALER;
+			_system->setGraphicsMode("1x");
+		} else {
+			_system->initSize(_screenWidth, _screenHeight);
+		}
 
 		// FIXME: All this seems a dirty hack to me. We already
 		// have this check in constructor
@@ -1268,6 +1305,10 @@
 			_shadowPalette[i] = i;
 		if ((_features & GF_AMIGA) || (_features & GF_ATARI_ST))
 			setupAmigaPalette();
+		else if (_renderMode == Common::kRenderHerc)
+			setupHercPalette();
+		else if (_renderMode == Common::kRenderCGA)
+			setupCGAPalette();
 		else
 			setupEGAPalette();
 	}

Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.533
retrieving revision 1.534
diff -u -d -r1.533 -r1.534
--- scumm.h	18 Feb 2005 00:28:56 -0000	1.533
+++ scumm.h	20 Feb 2005 00:17:22 -0000	1.534
@@ -868,6 +868,8 @@
 	int _screenStartStrip, _screenEndStrip;
 	int _screenTop;
 
+	Common::RenderMode _renderMode;
+
 protected:
 	ColorCycle _colorCycle[16];	// Palette cycles
 
@@ -930,6 +932,8 @@
 
 	const byte *getPalettePtr(int palindex, int room);
 	void setupAmigaPalette();
+	void setupHercPalette();
+	void setupCGAPalette();
 	void setupEGAPalette();
 	void setupV1ManiacPalette();
 	void setupV1ZakPalette();

Index: vars.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/vars.cpp,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -d -r1.113 -r1.114
--- vars.cpp	1 Jan 2005 16:09:16 -0000	1.113
+++ vars.cpp	20 Feb 2005 00:17:22 -0000	1.114
@@ -553,6 +553,12 @@
 			VAR(VAR_VIDEOMODE) = 50;
 		else if (_gameId == GID_MONKEY2 && (_features & GF_AMIGA))
 			VAR(VAR_VIDEOMODE) = 82;
+		else if (_renderMode == Common::kRenderCGA)
+			VAR(VAR_VIDEOMODE) = 4;
+		else if (_renderMode == Common::kRenderHerc)
+			VAR(VAR_VIDEOMODE) = 30;
+		else if (_renderMode == Common::kRenderEGA)
+			VAR(VAR_VIDEOMODE) = 13;
 		else
 			VAR(VAR_VIDEOMODE) = 19;
 		if (_gameId == GID_LOOM && _features & GF_OLD_BUNDLE) {





More information about the Scummvm-git-logs mailing list