[Scummvm-cvs-logs] scummvm master -> 7a169c90f676ead7de6aa2624ac257ff5e85c10e

m-kiewitz m_kiewitz at users.sourceforge.net
Sun Feb 28 11:23:31 CET 2016


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

Summary:
7a169c90f6 AGI: Hercules rendering for game screen


Commit: 7a169c90f676ead7de6aa2624ac257ff5e85c10e
    https://github.com/scummvm/scummvm/commit/7a169c90f676ead7de6aa2624ac257ff5e85c10e
Author: Martin Kiewitz (m_kiewitz at users.sourceforge.net)
Date: 2016-02-28T11:23:31+01:00

Commit Message:
AGI: Hercules rendering for game screen

Changed paths:
    engines/agi/agi.cpp
    engines/agi/font.cpp
    engines/agi/graphics.cpp
    engines/agi/graphics.h
    engines/agi/palette.h
    engines/agi/text.cpp



diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index 6773398..6e63cd3 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -283,18 +283,7 @@ void AgiBase::initRenderMode() {
 
 	switch (platform) {
 	case Common::kPlatformDOS:
-		switch (configRenderMode) {
-		case Common::kRenderCGA:
-			_renderMode = Common::kRenderCGA;
-			break;
-		// Hercules is not supported atm
-		//case Common::kRenderHercA:
-		//case Common::kRenderHercG:
-		//	_renderMode = Common::kRenderHercG;
-		//	break;
-		default:
-			break;
-		}
+		// Keep EGA
 		break;
 	case Common::kPlatformAmiga:
 		_renderMode = Common::kRenderAmiga;
@@ -323,6 +312,12 @@ void AgiBase::initRenderMode() {
 	case Common::kRenderVGA:
 		_renderMode = Common::kRenderVGA;
 		break;
+	case Common::kRenderHercG:
+		_renderMode = Common::kRenderHercG;
+		break;
+	case Common::kRenderHercA:
+		_renderMode = Common::kRenderHercA;
+		break;
 	case Common::kRenderAmiga:
 		_renderMode = Common::kRenderAmiga;
 		break;
diff --git a/engines/agi/font.cpp b/engines/agi/font.cpp
index c453ee5..5e6ba1e 100644
--- a/engines/agi/font.cpp
+++ b/engines/agi/font.cpp
@@ -624,6 +624,16 @@ void GfxFont::init() {
 	if (ConfMan.getBool("herculesfont")) {
 		// User wants, that we use Hercules hires font, try to load it
 		loadFontHercules();
+	} else {
+		switch (_vm->_renderMode) {
+		case Common::kRenderHercA:
+		case Common::kRenderHercG:
+			// Render mode is Hercules, we try to load Hercules hires font
+			loadFontHercules();
+			break;
+		default:
+			break;
+		}
 	}
 
 	if (!_fontData) {
@@ -650,6 +660,8 @@ void GfxFont::init() {
 				}
 			}
 			break;
+		case Common::kRenderHercA:
+		case Common::kRenderHercG:
 		case Common::kRenderCGA:
 		case Common::kRenderEGA:
 		case Common::kRenderVGA:
@@ -699,6 +711,11 @@ void GfxFont::overwriteSaveRestoreDialogCharacter() {
 
 // Overwrite extended character set (0x80-0xFF) with Russian characters
 void GfxFont::overwriteExtendedWithRussianSet() {
+	if (_fontIsHires) {
+		// TODO: Implement overwriting hires font characters too
+		return;
+	}
+
 	if (!_fontDataAllocated) {
 		// nothing allocated, we need to allocate space ourselves to be able to modify an internal font
 		_fontDataAllocated = (uint8 *)calloc(256, 8);
diff --git a/engines/agi/graphics.cpp b/engines/agi/graphics.cpp
index 5fa652c..6d3563a 100644
--- a/engines/agi/graphics.cpp
+++ b/engines/agi/graphics.cpp
@@ -69,6 +69,8 @@ GfxMgr::GfxMgr(AgiBase *vm, GfxFont *font) : _vm(vm), _font(font) {
  * @see deinit_video()
  */
 int GfxMgr::initVideo() {
+	bool forceHires = false;
+
 	// Set up palettes
 	initPalette(_paletteTextMode, PALETTE_EGA);
 
@@ -82,6 +84,14 @@ int GfxMgr::initVideo() {
 	case Common::kRenderVGA:
 		initPalette(_paletteGfxMode, PALETTE_VGA, 256, 8);
 		break;
+	case Common::kRenderHercG:
+		initPalette(_paletteGfxMode, PALETTE_HERCULES_GREEN, 2, 8);
+		forceHires = true;
+		break;
+	case Common::kRenderHercA:
+		initPalette(_paletteGfxMode, PALETTE_HERCULES_AMBER, 2, 8);
+		forceHires = true;
+		break;
 	case Common::kRenderAmiga:
 		if (!ConfMan.getBool("altamigapalette")) {
 			// Set the correct Amiga palette depending on AGI interpreter version
@@ -137,7 +147,7 @@ int GfxMgr::initVideo() {
 
 	//bool forcedUpscale = true;
 
-	if (_font->isFontHires()) {
+	if (_font->isFontHires() || forceHires) {
 		// Upscaling enable
 		_upscaledHires = DISPLAY_UPSCALED_640x400;
 		_displayScreenWidth = 640;
@@ -154,6 +164,8 @@ int GfxMgr::initVideo() {
 	case Common::kRenderEGA:
 	case Common::kRenderCGA:
 	case Common::kRenderVGA:
+	case Common::kRenderHercG:
+	case Common::kRenderHercA:
 		initMouseCursor(&_mouseCursor, MOUSECURSOR_SCI, 11, 16, 0, 0);
 		initMouseCursor(&_mouseCursorBusy, MOUSECURSOR_SCI_BUSY, 15, 16, 7, 8);
 		break;
@@ -500,6 +512,10 @@ void GfxMgr::render_Block(int16 x, int16 y, int16 width, int16 height, bool copy
 		return;
 
 	switch (_vm->_renderMode) {
+	case Common::kRenderHercG:
+	case Common::kRenderHercA:
+		render_BlockHercules(x, y, width, height, copyToScreen);
+		break;
 	case Common::kRenderCGA:
 		render_BlockCGA(x, y, width, height, copyToScreen);
 		break;
@@ -654,6 +670,106 @@ void GfxMgr::render_BlockCGA(int16 x, int16 y, int16 width, int16 height, bool c
 	}
 }
 
+static const uint8 herculesColorMapping[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x88, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+	0x80, 0x10, 0x02, 0x20, 0x01, 0x08, 0x40, 0x04,
+	0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,
+	0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+	0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00,
+	0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88,
+	0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+	0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88, 0x00,
+	0xD7, 0xFF, 0x7D, 0xFF, 0xD7, 0xFF, 0x7D, 0xFF,
+	0xDD, 0x55, 0x77, 0xAA, 0xDD, 0x55, 0x77, 0xAA,
+	0x7F, 0xEF, 0xFD, 0xDF, 0xFE, 0xF7, 0xBF, 0xFB,
+	0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,
+	0x77, 0xBB, 0xDD, 0xEE, 0x77, 0xBB, 0xDD, 0xEE,
+	0x77, 0xFF, 0xFF, 0xFF, 0xDD, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+// Sierra actually seems to have rendered the whole screen all the time
+void GfxMgr::render_BlockHercules(int16 x, int16 y, int16 width, int16 height, bool copyToScreen) {
+	uint32 offsetVisual = SCRIPT_WIDTH * y + x;
+	uint32 offsetDisplay = getDisplayOffsetToGameScreenPos(x, y);
+	int16 remainingWidth = width;
+	int16 remainingHeight = height;
+	byte curColor = 0;
+	int16 displayWidth = width * (2 + _displayWidthMulAdjust);
+
+	assert(_upscaledHires == DISPLAY_UPSCALED_640x400);
+
+	uint16 lookupOffset1 = (y * 2 & 0x07);
+	uint16 lookupOffset2 = 0;
+	bool   getUpperNibble = false;
+	byte   herculesColors1 = 0;
+	byte   herculesColors2 = 0;
+
+	while (remainingHeight) {
+		remainingWidth = width;
+
+		lookupOffset1 = (lookupOffset1 + 0) & 0x07;
+		lookupOffset2 = (lookupOffset1 + 1) & 0x07;
+
+		getUpperNibble = (x & 1) ? false : true;
+		while (remainingWidth) {
+			curColor = _activeScreen[offsetVisual++] & 0x0F;
+
+			if (getUpperNibble) {
+				herculesColors1 = herculesColorMapping[curColor * 8 + lookupOffset1] & 0x0F;
+				herculesColors2 = herculesColorMapping[curColor * 8 + lookupOffset2] & 0x0F;
+			} else {
+				herculesColors1 = herculesColorMapping[curColor * 8 + lookupOffset1] >> 4;
+				herculesColors2 = herculesColorMapping[curColor * 8 + lookupOffset2] >> 4;
+			}
+			getUpperNibble ^= true;
+
+			_displayScreen[offsetDisplay + 0] = (herculesColors1 & 0x08) ? 1 : 0;
+			_displayScreen[offsetDisplay + 1] = (herculesColors1 & 0x04) ? 1 : 0;
+			_displayScreen[offsetDisplay + 2] = (herculesColors1 & 0x02) ? 1 : 0;
+			_displayScreen[offsetDisplay + 3] = (herculesColors1 & 0x01) ? 1 : 0;
+
+			_displayScreen[offsetDisplay + _displayScreenWidth + 0] = (herculesColors2 & 0x08) ? 1 : 0;
+			_displayScreen[offsetDisplay + _displayScreenWidth + 1] = (herculesColors2 & 0x04) ? 1 : 0;
+			_displayScreen[offsetDisplay + _displayScreenWidth + 2] = (herculesColors2 & 0x02) ? 1 : 0;
+			_displayScreen[offsetDisplay + _displayScreenWidth + 3] = (herculesColors2 & 0x01) ? 1 : 0;
+
+			offsetDisplay += 4;
+			remainingWidth--;
+		}
+
+		lookupOffset1 += 2;
+
+		offsetVisual += SCRIPT_WIDTH - width;
+		offsetDisplay += _displayScreenWidth - displayWidth;
+		offsetDisplay += _displayScreenWidth;;
+
+		remainingHeight--;
+	}
+}
+
+// Table used for at least Manhunter 2, it renders 2 lines -> 3 lines instead of 4
+// Manhunter 1 is shipped with a broken Hercules font
+// King's Quest 4 aborts right at the start, when Hercules rendering is active
+#if 0
+static const uint8 herculesCoordinateOffset[] = {
+	0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x01, 0x02,
+	0x04, 0x05, 0x07, 0x00, 0x02, 0x03, 0x05, 0x06
+};
+
+static const uint8 herculesColorMapping[] = {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x08, 0x00,
+	0x80, 0x10, 0x02, 0x20, 0x01, 0x08, 0x40, 0x04,	0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00,
+	0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,	0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00,
+	0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88,	0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+	0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88, 0x00,	0xD7, 0xFF, 0x7D, 0xFF, 0xD7, 0xFF, 0x7D, 0xFF,
+	0xDD, 0x55, 0x77, 0xAA, 0xDD, 0x55, 0x77, 0xAA,	0x7F, 0xEF, 0xFD, 0xDF, 0xFE, 0xF7, 0xBF, 0xFB,
+	0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF,	0x77, 0xBB, 0xDD, 0xEE, 0x77, 0xBB, 0xDD, 0xEE,
+	0x7F, 0xEF, 0xFB, 0xBF, 0xEF, 0xFE, 0xBF, 0xFD,	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+#endif
+
 void GfxMgr::transition_Amiga() {
 	uint16 screenPos = 1;
 	uint32 screenStepPos = 1;
@@ -876,6 +992,10 @@ void GfxMgr::drawBox(int16 x, int16 y, int16 width, int16 height, byte backgroun
 		drawDisplayRect(x, +1, y + height, -2, width, -2, 0, 1, 0);
 		drawDisplayRect(x, +1, y, +1, 0, 1, height, -2, 0);
 		break;
+	case Common::kRenderHercA:
+	case Common::kRenderHercG:
+		lineColor = 0; // change linecolor to black
+		// supposed to fall through
 	case Common::kRenderCGA:
 	case Common::kRenderEGA:
 	case Common::kRenderVGA:
@@ -895,6 +1015,11 @@ void GfxMgr::drawDisplayRect(int16 x, int16 y, int16 width, int16 height, byte c
 	case Common::kRenderCGA:
 		drawDisplayRectCGA(x, y, width, height, color);
 		break;
+	case Common::kRenderHercG:
+	case Common::kRenderHercA:
+		if (color)
+			color = 1; // change any color except black to green/amber
+		// supposed to fall through
 	case Common::kRenderEGA:
 	default:
 		drawDisplayRectEGA(x, y, width, height, color);
diff --git a/engines/agi/graphics.h b/engines/agi/graphics.h
index c523b61..1cb595c 100644
--- a/engines/agi/graphics.h
+++ b/engines/agi/graphics.h
@@ -180,6 +180,7 @@ public:
 private:
 	void render_BlockEGA(int16 x, int16 y, int16 width, int16 height, bool copyToScreen);
 	void render_BlockCGA(int16 x, int16 y, int16 width, int16 height, bool copyToScreen);
+	void render_BlockHercules(int16 x, int16 y, int16 width, int16 height, bool copyToScreen);
 
 public:
 	void transition_Amiga();
diff --git a/engines/agi/palette.h b/engines/agi/palette.h
index e0db81e..40c31da 100644
--- a/engines/agi/palette.h
+++ b/engines/agi/palette.h
@@ -60,6 +60,22 @@ static const uint8 PALETTE_CGA[4 * 3] = {
 };
 
 /**
+ * 2 color Hercules (green) palette. Using 8-bit RGB values.
+ */
+static const uint8 PALETTE_HERCULES_GREEN[2 * 3] = {
+	0x00, 0x00, 0x00, // black
+	0x00, 0xdc, 0x28  // green
+};
+
+/**
+ * 2 color Hercules (amber) palette. Using 8-bit RGB values.
+ */
+static const uint8 PALETTE_HERCULES_AMBER[2 * 3] = {
+	0x00, 0x00, 0x00, // black
+	0xdc, 0xb4, 0x00  // amber
+};
+
+/**
  * Atari ST AGI palette.
  * Used by all of the tested Atari ST AGI games
  * from Donald Duck's Playground (1986) to Manhunter II (1989).
diff --git a/engines/agi/text.cpp b/engines/agi/text.cpp
index 31f364d..18254d8 100644
--- a/engines/agi/text.cpp
+++ b/engines/agi/text.cpp
@@ -179,6 +179,16 @@ void TextMgr::charAttrib_Set(byte foreground, byte background) {
 				_textAttrib.combinedBackground = 0;
 			}
 			break;
+		case Common::kRenderHercA:
+		case Common::kRenderHercG:
+			if (background) {
+				_textAttrib.combinedForeground = 0;
+				_textAttrib.combinedBackground = 1;
+			} else {
+				_textAttrib.combinedForeground = 1;
+				_textAttrib.combinedBackground = 0;
+			}
+			break;
 		default:
 			// EGA-handling:
 			if (background) {






More information about the Scummvm-git-logs mailing list