[Scummvm-git-logs] scummvm master -> f28300f27f97761fc52597fa7e44430bba9c8f6d

athrxx noreply at scummvm.org
Mon Jul 11 16:27:11 UTC 2022


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
dd39b406c0 COMMON: add CGA b/w render mode
f28300f27f SCUMM: (V1) - add support for CGA black & white


Commit: dd39b406c036cbc598d1a0cab010b742f382edf4
    https://github.com/scummvm/scummvm/commit/dd39b406c036cbc598d1a0cab010b742f382edf4
Author: athrxx (athrxx at scummvm.org)
Date: 2022-07-11T18:16:23+02:00

Commit Message:
COMMON: add CGA b/w render mode

(for SCUMM v1)

Changed paths:
    common/gui_options.cpp
    common/gui_options.h
    common/rendermode.cpp
    common/rendermode.h


diff --git a/common/gui_options.cpp b/common/gui_options.cpp
index 39d41275776..6191adb7e1b 100644
--- a/common/gui_options.cpp
+++ b/common/gui_options.cpp
@@ -63,7 +63,8 @@ const struct GameOpt {
 	{ GUIO_RENDERHERCGREEN,		"hercGreen" },
 	{ GUIO_RENDERHERCAMBER,		"hercAmber" },
 	{ GUIO_RENDERCGA,			"cga" },
-	{ GUIO_RENDERCGACOMP,		"cgacomp" },
+	{ GUIO_RENDERCGACOMP,		"cgaComp" },
+	{ GUIO_RENDERCGABW,			"cgaBW" },
 	{ GUIO_RENDEREGA,			"ega" },
 	{ GUIO_RENDERVGA,			"vga" },
 	{ GUIO_RENDERAMIGA,			"amiga" },
diff --git a/common/gui_options.h b/common/gui_options.h
index c56a5439bd4..eda1c48689f 100644
--- a/common/gui_options.h
+++ b/common/gui_options.h
@@ -60,6 +60,7 @@
 #define GUIO_RENDERMACINTOSH	"\x23"
 #define GUIO_RENDERMACINTOSHBW	"\x28"	// Setting this to 0x28 is not ideal, but there is no free slot left. Maybe we need to migrate to 3-digit numbers...
 #define GUIO_RENDERCGACOMP		"\x29"
+#define GUIO_RENDERCGABW		"\x2a"
 
 #define GUIO_LINKSPEECHTOSFX "\x24"
 #define GUIO_LINKMUSICTOSFX  "\x25"
diff --git a/common/rendermode.cpp b/common/rendermode.cpp
index 630e0b78e95..300102fb1c9 100644
--- a/common/rendermode.cpp
+++ b/common/rendermode.cpp
@@ -35,6 +35,8 @@ const RenderModeDescription g_renderModes[] = {
 	{ "hercAmber", _s("Hercules Amber"), kRenderHercA },
 	{ "cga", "CGA", kRenderCGA },
 	{ "cgaComp", "CGA Composite", kRenderCGAComp },
+	// I18N: CGA black-and-white
+	{ "cgaBW", "CGA b/w", kRenderCGA_BW },
 	{ "ega", "EGA", kRenderEGA },
 	{ "vga", "VGA", kRenderVGA },
 	{ "amiga", "Amiga", kRenderAmiga },
@@ -72,6 +74,7 @@ static const RenderGUIOMapping s_renderGUIOMapping[] = {
 	{ kRenderMacintosh,		GUIO_RENDERMACINTOSH },
 	{ kRenderMacintoshBW,	GUIO_RENDERMACINTOSHBW },
 	{ kRenderCGAComp,	    GUIO_RENDERCGACOMP },
+	{ kRenderCGA_BW,	    GUIO_RENDERCGABW }
 };
 
 DECLARE_TRANSLATION_ADDITIONAL_CONTEXT("Hercules Green", "lowres")
diff --git a/common/rendermode.h b/common/rendermode.h
index 145e0ffe48e..240ebee07d4 100644
--- a/common/rendermode.h
+++ b/common/rendermode.h
@@ -58,7 +58,8 @@ enum RenderMode {
 	kRenderAtariST = 11,
 	kRenderMacintosh = 12,
 	kRenderMacintoshBW = 13,
-	kRenderCGAComp = 14
+	kRenderCGAComp = 14,
+	kRenderCGA_BW = 15,
 };
 
 struct RenderModeDescription {


Commit: f28300f27f97761fc52597fa7e44430bba9c8f6d
    https://github.com/scummvm/scummvm/commit/f28300f27f97761fc52597fa7e44430bba9c8f6d
Author: athrxx (athrxx at scummvm.org)
Date: 2022-07-11T18:16:29+02:00

Commit Message:
SCUMM: (V1) - add support for CGA black & white

Changed paths:
    NEWS.md
    engines/scumm/cursor.cpp
    engines/scumm/gfx.cpp
    engines/scumm/input.cpp
    engines/scumm/palette.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h
    engines/scumm/vars.cpp
    engines/scumm/verbs.cpp


diff --git a/NEWS.md b/NEWS.md
index 60f3965c641..fa4c065d7c7 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -21,8 +21,8 @@ For a more comprehensive changelog of the latest experimental code, see:
    - Added support for the Hebrew version of Legend of Kyrandia 3.
 
  SCUMM:
-   - Add support for CGA, CGA Composite and Hercules modes for SCUMM 1
-     versions of Zak McKracken and Maniac Mansion.
+   - Add support for CGA, CGA Composite, CGA black & white and Hercules modes
+     for SCUMM 1 versions of Zak McKracken and Maniac Mansion.
 
  Toon:
    - Made game menus behave like in the original.
diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index 34e72766718..ff8f6531ffc 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -469,10 +469,10 @@ void ScummEngine_v2::setBuiltinCursor(int idx) {
 		color = default_v0_cursor_colors[idx];
 	else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
 		color = (idx & 1) * 3;
-	else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
+	else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG || _renderMode == Common::kRenderCGA_BW)
 		color = idx & 1;
 	else
-		color = default_cursor_colors[idx];	
+		color = default_cursor_colors[idx];
 
 	if (_game.platform == Common::kPlatformNES) {
 		_cursor.width = 8;
@@ -566,7 +566,7 @@ void ScummEngine_v2::setBuiltinCursor(int idx) {
 		*(hotspot + (_cursor.width * 5) - 1) = color;
 		*(hotspot + (_cursor.width * 5) + 1) = color;
 
-		if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
+		if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG || _renderMode == Common::kRenderCGA_BW) {
 			const byte *src = &_grabbedCursor[_cursor.width * _cursor.height - 1];
 
 			_cursor.width <<= 1;
@@ -579,10 +579,11 @@ void ScummEngine_v2::setBuiltinCursor(int idx) {
 
 			while (dst2 >= _grabbedCursor) {
 				for (i = _cursor.width >> 1; i; --i) {
+					uint8 col2 = (_renderMode == Common::kRenderCGA_BW) ? *src : 0xFF;
+					*dst1-- = col2;
+					*dst1-- = col2;
 					*dst2-- = *src;
 					*dst2-- = *src--;
-					*dst1-- = 0xFF;
-					*dst1-- = 0xFF;
 				}
 				dst1 -= _cursor.width;
 				dst2 -= _cursor.width;
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index 93d7006a3fa..ebc7f3e6bce 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -768,14 +768,11 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
 				}
 			}
 		} else if (_game.version == 1) {
-			src = postProcessV1Graphics(vs, x, y, width, height);
-			if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
-				pitch = kHercWidth;
-
+			src = postProcessV1Graphics(vs, pitch, x, y, width, height);
 		} else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
-			ditherHerc(_compositeBuf, _herculesBuf, width, &x, &y, &width, &height);
+			ditherHerc(_compositeBuf, _hercCGAScaleBuf, width, &x, &y, &width, &height);
 
-			src = _herculesBuf + x + y * kHercWidth;
+			src = _hercCGAScaleBuf + x + y * kHercWidth;
 			pitch = kHercWidth;
 
 			// center image on the screen
@@ -795,7 +792,7 @@ void ScummEngine::drawStripToScreen(VirtScreen *vs, int x, int width, int top, i
 	_system->copyRectToScreen(src, pitch, x, y, width, height);
 }
 
-const byte *ScummEngine::postProcessV1Graphics(VirtScreen *vs, int &x, int &y, int &width, int &height) const {
+const byte *ScummEngine::postProcessV1Graphics(VirtScreen *vs, int &pitch, int &x, int &y, int &width, int &height) const {
 	static const byte zakVrbColMap[] =	{ 0x0, 0x5, 0x5, 0x5, 0xA, 0xA, 0xA, 0xF, 0xF, 0x5, 0x5, 0x5, 0xA, 0xA, 0xF, 0xF };
 	static const byte zakTxtColMap[] =	{ 0x0, 0xF, 0xA, 0x5, 0xA, 0x5, 0x5, 0xF, 0xA, 0xA, 0xA, 0xA, 0xA, 0x5, 0x5, 0xF };
 	static const byte mmVrbColMap[] =	{ 0x0, 0x5, 0x5, 0x5, 0xA, 0xA, 0xA, 0xF, 0xA, 0x5, 0x5, 0x5, 0xA, 0xA, 0xA, 0xF };
@@ -807,10 +804,11 @@ const byte *ScummEngine::postProcessV1Graphics(VirtScreen *vs, int &x, int &y, i
 	byte *res = _compositeBuf;
 	byte *dst = _compositeBuf;
 	const byte *src = res;
+	bool renderHerc = (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG);
 
-	if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp) {
-		const byte *colMap = (_game.id == GID_ZAK) ? (vs->number == kVerbVirtScreen ? zakVrbColMap : zakTxtColMap) : (vs->number == kVerbVirtScreen ? mmVrbColMap : mmTxtColMap);
+	const byte *colMap = (_game.id == GID_ZAK) ? ((vs->number == kVerbVirtScreen || renderHerc) ? zakVrbColMap : zakTxtColMap) : (vs->number == kVerbVirtScreen ? mmVrbColMap : mmTxtColMap);
 
+	if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp) {
 		if (vs->number == kMainVirtScreen) {
 			for (int h = height; h; --h) {
 				for (int w = width >> 1; w; --w) {
@@ -827,50 +825,79 @@ const byte *ScummEngine::postProcessV1Graphics(VirtScreen *vs, int &x, int &y, i
 			}
 		}
 
-	} else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
-		const byte *colMap = (_game.id == GID_ZAK) ? zakVrbColMap : (vs->number == kVerbVirtScreen ? mmVrbColMap : mmTxtColMap);
-		dst = res = _herculesBuf;
+	} else if (renderHerc || _renderMode == Common::kRenderCGA_BW) {
+		// The monochrome rendering is very similiar for Hercules and CGA b/w.
+		// For Hercules we have to do some corrections to fit into the 350 pixels
+		// height. The text and verb vs are rendered in normal height, only the
+		// main vs gets scaled by leaving out every other line. And we center the
+		// image horizontally within the 720 pixels width.
+		// For CGA b/w the origial resolution is 640x200, so we just scale that
+		// to our 640x400 by repeating each line.
+		pitch = renderHerc ? kHercWidth : (_screenWidth << 1);
+		dst = res = _hercCGAScaleBuf;
+		int pitch1 = (pitch - width) << 1;
 
 		if (vs->number == kMainVirtScreen) {
-			uint32 *dst2 = (uint32*)(dst + kHercWidth);
-			int pitch = (kHercWidth - width) << 1;
-			int pitch2 = pitch >> 2;
-			y = (y - vs->topline) * 2 + vs->topline;
-			height = MIN<int>(height << 1, kHercHeight - y);
+			uint32 *dst2 = (uint32*)(dst + pitch);
+			int pitch2 = pitch1 >> 2;
+			int height2 = height;
+
+			if (renderHerc) {
+				y = (y - vs->topline) * 2 + vs->topline;
+				height = MIN<int>(height << 1, kHercHeight - y);
+				height2 = height >> 1;
+			}
 
-			for (int h = height >> 1; h; --h) {
+			for (int h = height2; h; --h) {
 				for (int w = width >> 1; w; --w) {
+					const uint32 *s = (const uint32*)dst;
 					*dst++ = (*src >> 3) & 1;
 					*dst++ = (*src >> 2) & 1;
 					*dst++ = (*src >> 1) & 1;
 					*dst++ = *src & 1;
-					*dst2++ = 0;
+					*dst2++ = renderHerc ? 0 : *s;
 					src += 2;
 				}
-				dst += pitch;
+				dst += pitch1;
 				dst2 += pitch2;
 			}
 
 		} else {
-			int pitch = kHercWidth - (width << 1);
-			y -= vs->topline;
-			if (vs->number == kVerbVirtScreen) {
-				y += vs->topline * 2 - 16;
-				height = MIN<int>(height, kHercHeight - y);
+			if (renderHerc) {
+				pitch1 = kHercWidth - (width << 1);
+				y -= vs->topline;
+				if (vs->number == kVerbVirtScreen) {
+					y += vs->topline * 2 - 16;
+					height = MIN<int>(height, kHercHeight - y);
+				}
 			}
 
+			uint16 *dst2 = (uint16*)(dst + pitch);
+			int pitch2 = pitch1 >> 1;
+
 			for (int h = height; h; --h) {
 				for (int w = width; w; --w) {
+					const uint16 *s = (const uint16*)dst;
 					uint8 col = colMap[*src++];
 					*dst++ = (col >> 1) & 1;
 					*dst++ = col & 1;
+					if (!renderHerc)
+						*dst2++ = *s;
 				}
-				dst += pitch;
+				dst += pitch1;
+				dst2 += pitch2;
 			}
 		}
 
-		x = x * 2 + 40;
-		width *= 2;
+		x <<= 1;
+		width <<= 1;
+
+		if (renderHerc) {
+			x += 40;
+		} else {
+			y <<= 1;
+			height <<= 1;
+		}
 
 	} else if (vs->number == kTextVirtScreen) {
 		// For EGA, the omly colors that need remapping are for the kTextVirtScreen.
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 1ff06dd54f9..e4d65b4572d 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -209,7 +209,7 @@ void ScummEngine::parseEvent(Common::Event event) {
 				_mouse.y = _mouse.y * 4 / 7;
 			}
 			
-		} else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2)) {
+		} else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2) || _renderMode == Common::kRenderCGA_BW) {
 			_mouse.x >>= 1;
 			_mouse.y >>= 1;
 		}
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 0534127cc5f..ed0edf2bbdd 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -207,6 +207,9 @@ void ScummEngine::resetPalette() {
 			setPaletteFromTable(tableHercGPalette, sizeof(tableHercGPalette) / 3);
 		} else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp) {
 			setPaletteFromTable(_cgaColors[cgaPalIndex * 2 + cgaPalIntensity], sizeof(_cgaColors[0]) / 3);
+		} else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGA_BW) {
+			setPalColor(0, 0x00, 0x00, 0x00);
+			setPalColor(1, 0xff, 0xff, 0xff);
 		} else {
 			setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3);
 		}
@@ -479,7 +482,7 @@ void ScummEngine::updateColorTableV1(int renderMode) {
 	};
 
 	int tbl = (_game.platform == Common::kPlatformC64) ? 0 : (_game.id == GID_ZAK ? 1 : 3);
-	if (renderMode == Common::kRenderHercA || renderMode == Common::kRenderHercG || renderMode == Common::kRenderCGA)
+	if (renderMode == Common::kRenderHercA || renderMode == Common::kRenderHercG || renderMode == Common::kRenderCGA || renderMode == Common::kRenderCGA_BW)
 		++tbl;
 
 	assert(_gdi);
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 9e5d6d94ab3..0eb268a82d2 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -254,7 +254,12 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
 			_renderMode = Common::kRenderDefault;
 		break;
 
+	case Common::kRenderCGA_BW:
 	case Common::kRenderCGAComp:
+		if (_game.version > 1 || _game.platform != Common::kPlatformDOS)
+			_renderMode = Common::kRenderDefault;
+		break;
+
 	case Common::kRenderCGA:
 	case Common::kRenderEGA:
 	case Common::kRenderAmiga:
@@ -317,9 +322,11 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
 	else
 		_compositeBuf = nullptr;
 
-	if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
-		_herculesBuf = (byte *)malloc(kHercWidth * kHercHeight);
-	}
+	if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
+		_hercCGAScaleBuf = (byte *)malloc(kHercWidth * kHercHeight);
+	else if (_renderMode == Common::kRenderCGA_BW)
+		_hercCGAScaleBuf = (byte *)malloc(_screenWidth * 2 * _screenHeight * 2);
+
 	updateColorTableV1(_renderMode);
 
 	_isRTL = (_language == Common::HE_ISR && _game.heversion == 0)
@@ -387,9 +394,7 @@ ScummEngine::~ScummEngine() {
 	free(_arraySlot);
 
 	free(_compositeBuf);
-	free(_herculesBuf);
-	delete[] _ditheringTableV1;
-
+	free(_hercCGAScaleBuf);
 	free(_16BitPalette);
 
 	if (_macScreen) {
@@ -1115,6 +1120,8 @@ Common::Error ScummEngine::init() {
 	// Initialize backend
 	if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
 		initGraphics(kHercWidth, kHercHeight);
+	} else if (_renderMode == Common::kRenderCGA_BW) {
+		initGraphics(_screenWidth * 2, _screenHeight * 2);
 	} else {
 		int screenWidth = _screenWidth;
 		int screenHeight = _screenHeight;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index e99fc357e17..09c4aa09172 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1059,8 +1059,7 @@ public:
 protected:
 	// Screen rendering
 	byte *_compositeBuf;
-	byte *_herculesBuf = nullptr;
-	const uint16 *_ditheringTableV1 = nullptr;
+	byte *_hercCGAScaleBuf = nullptr;
 
 	virtual void drawDirtyScreenParts();
 	void updateDirtyScreen(VirtScreenNumber slot);
@@ -1072,7 +1071,7 @@ protected:
 	void mac_undrawIndy3TextBox();
 	void mac_undrawIndy3CreditsText();
 
-	const byte *postProcessV1Graphics(VirtScreen *vs, int &x, int &y, int &width, int &height) const;
+	const byte *postProcessV1Graphics(VirtScreen *vs, int &pitch, int &x, int &y, int &width, int &height) const;
 	void ditherCGA(byte *dst, int dstPitch, int x, int y, int width, int height) const;
 
 public:
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 9f445349e66..375356266a7 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -793,6 +793,8 @@ void ScummEngine::resetScummVars() {
 			VAR(VAR_VIDEOMODE) = 82;
 		else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
 			VAR(VAR_VIDEOMODE) = 4;
+		else if (_renderMode == Common::kRenderCGA_BW)
+			VAR(VAR_VIDEOMODE) = 6;
 		else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
 			VAR(VAR_VIDEOMODE) = 30;
 		else if (_renderMode == Common::kRenderEGA)
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 66c3e3c7d25..4dc1356375b 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -198,7 +198,7 @@ void ScummEngine_v2::initV2MouseOver() {
 	_hiLiteColorVerbArrow = _hiLiteColorInvSentence = 14;
 	if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderCGAComp)
 		_hiLiteColorInvSentence = 15;
-	else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG)
+	else if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG || _renderMode == Common::kRenderCGA_BW)
 		_hiLiteColorVerbArrow = _hiLiteColorInvSentence = 15;
 
 	if (_game.platform == Common::kPlatformC64) {




More information about the Scummvm-git-logs mailing list