[Scummvm-git-logs] scummvm master -> 5775637bb86001685d8b599cddb523219b77367a

sev- sev at scummvm.org
Tue Jul 13 07:53:42 UTC 2021


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

Summary:
2ba156184c SCUMM: Add Macintosh b/w rendering mode
71581fdff4 SCUMM: Make text either white or black in Macintosh b/w mode
d73bb1c87e SCUMM: Implement shaded text in Macintosh b/w mode
e2544841df SCUMM: Handle shadow palette in Macintosh b/w mode
5775637bb8 COMMON: Add translator's note for the Macintosh b/w render mode


Commit: 2ba156184ce29b2235697b4185074f9cc32fb57f
    https://github.com/scummvm/scummvm/commit/2ba156184ce29b2235697b4185074f9cc32fb57f
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-07-13T09:53:36+02:00

Commit Message:
SCUMM: Add Macintosh b/w rendering mode

This is currently only (partially) implemented for the 16-color Mac
versions of Loom and Indiana Jones and the Last Crusade. The text is
still drawn in color, since that's rendered separately, but I'm
committing this now while it still works.

Changed paths:
  A graphics/macega.h
    base/commandLine.cpp
    common/rendermode.cpp
    common/rendermode.h
    engines/scumm/gfx_mac.cpp
    engines/scumm/palette.cpp


diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 553dccb7ca..fb360116bb 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -168,7 +168,7 @@ static const char HELP_STRING[] =
 	"                           (default: enabled)\n"
 	"  --render-mode=MODE       Enable additional render modes (hercGreen, hercAmber,\n"
 	"                           cga, ega, vga, amiga, fmtowns, pc9821, pc9801, 2gs,\n"
-	"                           atari, macintosh)\n"
+	"                           atari, macintosh, macintoshbw)\n"
 #ifdef ENABLE_EVENTRECORDER
 	"  --record-mode=MODE       Specify record mode for event recorder (record, playback,\n"
 	"                           passthrough [default])\n"
diff --git a/common/rendermode.cpp b/common/rendermode.cpp
index ab345a7b36..b39e334ee2 100644
--- a/common/rendermode.cpp
+++ b/common/rendermode.cpp
@@ -44,6 +44,7 @@ const RenderModeDescription g_renderModes[] = {
 	{ "2gs", "Apple IIgs", kRenderApple2GS },
 	{ "atari", "Atari ST", kRenderAtariST },
 	{ "macintosh", "Macintosh", kRenderMacintosh },
+	{ "macintoshbw", _s("Macintosh b/w"), kRenderMacintoshBW },
 	{nullptr, nullptr, kRenderDefault}
 };
 
diff --git a/common/rendermode.h b/common/rendermode.h
index 7432dcb5aa..9ef32eed8f 100644
--- a/common/rendermode.h
+++ b/common/rendermode.h
@@ -57,7 +57,8 @@ enum RenderMode {
 	kRenderPC9801 = 9,
 	kRenderApple2GS = 10,
 	kRenderAtariST = 11,
-	kRenderMacintosh = 12
+	kRenderMacintosh = 12,
+	kRenderMacintoshBW = 13
 };
 
 struct RenderModeDescription {
diff --git a/engines/scumm/gfx_mac.cpp b/engines/scumm/gfx_mac.cpp
index f836f0b0a9..62a3145bed 100644
--- a/engines/scumm/gfx_mac.cpp
+++ b/engines/scumm/gfx_mac.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "common/system.h"
+#include "graphics/macega.h"
 #include "scumm/actor.h"
 #include "scumm/charset.h"
 #include "scumm/usage_bits.h"
@@ -29,6 +30,7 @@
 namespace Scumm {
 
 void ScummEngine::mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, int width, int height) {
+
 	const byte *pixels = vs->getPixels(x, top);
 	const byte *ts = (byte *)_textSurface.getBasePtr(x * 2, y * 2);
 	byte *mac = (byte *)_macScreen->getBasePtr(x * 2, y * 2);
@@ -37,23 +39,43 @@ void ScummEngine::mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, i
 	int tsPitch = _textSurface.pitch;
 	int macPitch = _macScreen->pitch;
 
-	for (int h = 0; h < height; h++) {
-		for (int w = 0; w < width; w++) {
-			if (ts[2 * w] == CHARSET_MASK_TRANSPARENCY)
-				mac[2 * w] = pixels[w];
-			if (ts[2 * w + 1] == CHARSET_MASK_TRANSPARENCY)
-				mac[2 * w + 1] = pixels[w];
-			if (ts[2 * w + tsPitch] == CHARSET_MASK_TRANSPARENCY)
-				mac[2 * w + macPitch] = pixels[w];
-			if (ts[2 * w + tsPitch + 1] == CHARSET_MASK_TRANSPARENCY)
-				mac[2 * w + macPitch + 1] = pixels[w];
+	if (_renderMode == Common::kRenderMacintoshBW) {
+		for (int h = 0; h < height; h++) {
+			for (int w = 0; w < width; w++) {
+				if (ts[2 * w] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w] = Graphics::macEGADither[pixels[w]][0];
+				if (ts[2 * w + 1] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w + 1] = Graphics::macEGADither[pixels[w]][1];
+				if (ts[2 * w + tsPitch] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w + macPitch] = Graphics::macEGADither[pixels[w]][2];
+				if (ts[2 * w + tsPitch + 1] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w + macPitch + 1] = Graphics::macEGADither[pixels[w]][3];
+			}
+
+			pixels += pixelsPitch;
+			ts += tsPitch * 2;
+			mac += macPitch * 2;
 		}
+	} else {
+		for (int h = 0; h < height; h++) {
+			for (int w = 0; w < width; w++) {
+				if (ts[2 * w] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w] = pixels[w];
+				if (ts[2 * w + 1] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w + 1] = pixels[w];
+				if (ts[2 * w + tsPitch] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w + macPitch] = pixels[w];
+				if (ts[2 * w + tsPitch + 1] == CHARSET_MASK_TRANSPARENCY)
+					mac[2 * w + macPitch + 1] = pixels[w];
+			}
 
-		pixels += pixelsPitch;
-		ts += tsPitch * 2;
-		mac += macPitch * 2;
+			pixels += pixelsPitch;
+			ts += tsPitch * 2;
+			mac += macPitch * 2;
+		}
 	}
 
+
 	_system->copyRectToScreen(_macScreen->getBasePtr(x * 2, y * 2), _macScreen->pitch, x * 2, y * 2, width * 2, height * 2);
 }
 
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 10fc5a64a7..4a0dbeeae0 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -25,6 +25,7 @@
 #include "common/textconsole.h"
 #include "common/util.h"
 
+#include "graphics/macega.h"
 #include "graphics/palette.h"
 
 #include "scumm/resource.h"
@@ -137,20 +138,6 @@ void ScummEngine::resetPalette() {
 		0xFF, 0x99, 0x99, 	0xFF, 0x55, 0xFF, 	0xFF, 0xFF, 0x77, 	0xFF, 0xFF, 0xFF
 	};
 
-	// Theoreticaly, it should be possible to get the palette from the
-	// game's "clut" reosurce. But when I try that, I still get the wrong
-	// colours. This table is based on what Basilisk II draws.
-
-// 6 = brown
-// 11 = bright cyan
-
-	static const byte tableMacPalette[] = {
-		0x00, 0x00, 0x00,	0x00, 0x00, 0xBE,	0x00, 0xBE, 0x00,	0x00, 0xBE, 0xBE,
-		0xBE, 0x00, 0x00,	0xBE, 0x00, 0xBE,	0xBE, 0x75, 0x00,	0xBE, 0xBE, 0xBE,
-		0x75, 0x75, 0x75,	0x75, 0x75, 0xFC,	0x75, 0xFC, 0x75,	0x75, 0xFC, 0xFC,
-		0xFC, 0x75, 0x75,	0xFC, 0x75, 0xFC,	0xFC, 0xFC, 0x75,	0xFC, 0xFC, 0xFC
-	};
-
 	static const byte tableEGAPalette[] = {
 		0x00, 0x00, 0x00, 	0x00, 0x00, 0xAA, 	0x00, 0xAA, 0x00, 	0x00, 0xAA, 0xAA,
 		0xAA, 0x00, 0x00, 	0xAA, 0x00, 0xAA, 	0xAA, 0x55, 0x00, 	0xAA, 0xAA, 0xAA,
@@ -254,7 +241,7 @@ void ScummEngine::resetPalette() {
 			if ((_game.platform == Common::kPlatformAmiga) || (_game.platform == Common::kPlatformAtariST))
 				setPaletteFromTable(tableAmigaPalette, sizeof(tableAmigaPalette) / 3);
 			else if ((_game.id == GID_LOOM || _game.id == GID_INDY3) && _game.platform == Common::kPlatformMacintosh)
-				setPaletteFromTable(tableMacPalette, sizeof(tableMacPalette) / 3);
+				setPaletteFromTable(Graphics::macEGAPalette, sizeof(Graphics::macEGAPalette) / 3);
 			else
 				setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3);
 		}
diff --git a/graphics/macega.h b/graphics/macega.h
new file mode 100644
index 0000000000..d2f0fc981a
--- /dev/null
+++ b/graphics/macega.h
@@ -0,0 +1,81 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef GRAPHICS_MACEGA_H
+#define GRAPHICS_MACEGA_H
+
+namespace Graphics {
+
+// This is the palette that Basilisk II uses by default for 16-color games.
+// It's basically the same as EGA, but a little bit brighter. While it does
+// seem like games can have their own palette (CLUT) resources, at least Loom
+// didn't seem to use it. (I could be wrong about that.)
+
+static const byte macEGAPalette[] = {
+	0x00, 0x00, 0x00,	// Black
+	0x00, 0x00, 0xBE,	// Blue
+	0x00, 0xBE, 0x00,	// Green
+	0x00, 0xBE, 0xBE,	// Cyan
+	0xBE, 0x00, 0x00,	// Red
+	0xBE, 0x00, 0xBE,	// Magenta
+	0xBE, 0x75, 0x00,	// Brown
+	0xBE, 0xBE, 0xBE,	// Light Gray
+	0x75, 0x75, 0x75,	// Dark Gray
+	0x75, 0x75, 0xFC,	// Bright Blue
+	0x75, 0xFC, 0x75,	// Bright Green
+	0x75, 0xFC, 0xFC,	// Bright Cyan
+	0xFC, 0x75, 0x75,	// Bright Red
+	0xFC, 0x75, 0xFC,	// Bright Magenta
+	0xFC, 0xFC, 0x75,	// Bright Yellow
+	0xFC, 0xFC, 0xFC	// White
+};
+
+// Each color has its own 2x2 dithering pattern. This array remaps them to the
+// color indexes for black and white. The order of the pixels is upper left,
+// upper right, lower left, lower right. I don't know if this is the standard
+// method, but it does seem to be what LucasArts used so maybe it's useful for
+// other games as well.
+//
+// One obvious candidate would be the Mac AGI games, though looking at
+// screenshots makes me suspect that they used 3x2 pixels for each color.
+
+const byte macEGADither[16][4] = {
+	{  0,  0,  0,  0 },	// Black
+	{  0,  0,  0, 15 },	// Blue
+	{  0,  0, 15,  0 },	// Green
+	{  0,  0, 15, 15 },	// Cyan
+	{  0, 15,  0,  0 },	// Red
+	{  0, 15,  0, 15 },	// Magenta
+	{  0, 15, 15,  0 },	// Brown
+	{  0, 15, 15, 15 },	// Light Gray
+	{ 15,  0,  0,  0 },	// Dark Gray
+	{ 15,  0,  0, 15 },	// Bright Blue
+	{ 15,  0, 15,  0 },	// Bright Green
+	{ 15,  0, 15, 15 },	// Bright Cyan
+	{ 15, 15,  0,  0 },	// Bright Red
+	{ 15, 15,  0, 15 },	// Bright Magenta
+	{ 15, 15, 15,  0 },	// Bright Yellow
+	{ 15, 15, 15, 15 }	// White
+};
+
+} // end of namespace Graphics
+
+#endif // GRAPHICS_MACEGA_H


Commit: 71581fdff4d738d5a3d9fbb4baa7167ed57a36a1
    https://github.com/scummvm/scummvm/commit/71581fdff4d738d5a3d9fbb4baa7167ed57a36a1
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-07-13T09:53:36+02:00

Commit Message:
SCUMM: Make text either white or black in Macintosh b/w mode

I still need to add code for drawing disabled text for the Loom notes
and Indy 3 verbs.

Changed paths:
    engines/scumm/charset.cpp
    engines/scumm/charset.h


diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index a17e163910..3dba2dd9e7 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1776,8 +1776,28 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
 	_lastTop = _top;
 }
 
+byte CharsetRendererMac::getTextColor() {
+	if (_vm->_renderMode == Common::kRenderMacintoshBW) {
+		if (_color == 0 || _color == 15)
+			return _color;
+		return 15;
+	}
+	return _color;
+}
+
+byte CharsetRendererMac::getTextShadowColor() {
+	if (_vm->_renderMode == Common::kRenderMacintoshBW) {
+		if (getTextColor() == 0)
+			return 15;
+		return 0;
+	}
+	return _shadowColor;
+}
+
 void CharsetRendererMac::printCharInternal(int chr, int color, bool shadow, int x, int y) {
 	if (shadow) {
+		byte shadowColor = getTextShadowColor();
+
 		if (_vm->_game.id == GID_LOOM) {
 			// Shadowing is a bit of guesswork. It doesn't look
 			// like it's using the Mac's built-in form of shadowed
@@ -1790,31 +1810,41 @@ void CharsetRendererMac::printCharInternal(int chr, int color, bool shadow, int
 			_macFonts[_curId].drawChar(&_vm->_textSurface, chr, x + 3, y + 3, 0);
 
 			if (color != -1) {
-				_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 2, y, _shadowColor);
-				_macFonts[_curId].drawChar(_vm->_macScreen, chr, x, y + 2, _shadowColor);
-				_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 3, y + 3, _shadowColor);
+				_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 2, y, shadowColor);
+				_macFonts[_curId].drawChar(_vm->_macScreen, chr, x, y + 2, shadowColor);
+				_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 3, y + 3, shadowColor);
 			}
 		} else {
 			// Indy 3 uses simpler shadowing, and doesn't need the
 			// "draw only on text surface" hack.
 
 			_macFonts[_curId].drawChar(&_vm->_textSurface, chr, x + 2, y + 2, 0);
-			_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 2, y + 2, _shadowColor);
+			_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 2, y + 2, shadowColor);
 		}			
 	}
 
 	_macFonts[_curId].drawChar(&_vm->_textSurface, chr, x + 1, y + 1, 0);
 
-	if (color != -1)
+	if (color != -1) {
+		if (color != -1) {
+			color = getTextColor();
+		}
+
 		_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 1, y + 1, color);
+	}
 }
 
 void CharsetRendererMac::printCharToTextBox(int chr, int color, int x, int y) {
-	_macFonts[_curId].drawChar(_vm->_macIndy3TextBox, chr, x + 5, y + 11, _color);
+	if (_vm->_renderMode == Common::kRenderMacintoshBW)
+		color = 15;
+
+	_macFonts[_curId].drawChar(_vm->_macIndy3TextBox, chr, x + 5, y + 11, color);
 }
 
 void CharsetRendererMac::drawChar(int chr, Graphics::Surface &s, int x, int y) {
-	_macFonts[_curId].drawChar(&s, chr, x, y, _color);
+	byte color = getTextColor();
+
+	_macFonts[_curId].drawChar(&s, chr, x, y, color);
 }
 
 void CharsetRendererMac::setColor(byte color) {
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index 6839519058..3e00d131b4 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -284,6 +284,9 @@ protected:
 	void printCharInternal(int chr, int color, bool shadow, int x, int y);
 	void printCharToTextBox(int chr, int color, int x, int y);
 
+	byte getTextColor();
+	byte getTextShadowColor();
+
 public:
 	CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile);
 


Commit: d73bb1c87e7642c91c13b0b7525885a4559da9c6
    https://github.com/scummvm/scummvm/commit/d73bb1c87e7642c91c13b0b7525885a4559da9c6
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-07-13T09:53:36+02:00

Commit Message:
SCUMM: Implement shaded text in Macintosh b/w mode

I just need to test Loom a bit more. Indy 3 should be pretty safe, since
most of the text is printed in text boxes, which never use shaded text.

Changed paths:
    engines/scumm/charset.cpp
    engines/scumm/charset.h


diff --git a/engines/scumm/charset.cpp b/engines/scumm/charset.cpp
index 3dba2dd9e7..bd7a4f9671 100644
--- a/engines/scumm/charset.cpp
+++ b/engines/scumm/charset.cpp
@@ -1517,6 +1517,7 @@ CharsetRendererMac::CharsetRendererMac(ScummEngine *vm, const Common::String &fo
 	 : CharsetRendererCommon(vm) {
 
 	_pad = false;
+	_glyphSurface = NULL;
 
 	// Indy 3 provides an "Indy" font in two sizes, 9 and 12, which are
 	// used for the text boxes. The smaller font can be used for a
@@ -1541,41 +1542,65 @@ CharsetRendererMac::CharsetRendererMac(ScummEngine *vm, const Common::String &fo
 	// 60 is an upside-down note, i.e. the one used for c'.
 	// 95 is a used for the rest of the notes.
 
-	if (_vm->_game.id == GID_INDY3 || _vm->_game.id == GID_LOOM) {
-		Common::MacResManager resource;
-		resource.open(fontFile);
+	Common::MacResManager resource;
+	resource.open(fontFile);
 
-		Common::String fontFamilyName = (_vm->_game.id == GID_LOOM) ? "Loom" : "Indy";
+	Common::String fontFamilyName = (_vm->_game.id == GID_LOOM) ? "Loom" : "Indy";
 
-		Common::SeekableReadStream *fond = resource.getResource(MKTAG('F', 'O', 'N', 'D'), fontFamilyName);
-		Graphics::MacFontFamily fontFamily;
+	Common::SeekableReadStream *fond = resource.getResource(MKTAG('F', 'O', 'N', 'D'), fontFamilyName);
 
-		if (fond) {
-			if (fontFamily.load(*fond)) {
-				Common::Array<Graphics::MacFontFamily::AsscEntry> *assoc = fontFamily.getAssocTable();
-				for (uint i = 0; i < assoc->size(); i++) {
-					int fontId = -1;
-					int fontSize = (*assoc)[i]._fontSize;
+	if (!fond)
+		return;
 
-					if (_vm->_game.id == GID_INDY3) {
-						if (fontSize == 9)
-							fontId = 1;
-						else if (fontSize == 12)
-							fontId = 0;
-					} else {
-						if (fontSize == 13)
-							fontId = 0;
-					}
-					if (fontId != -1) {
-						Common::SeekableReadStream *font = resource.getResource(MKTAG('F', 'O', 'N', 'T'), (*assoc)[i]._fontID);
-						_macFonts[fontId].loadFont(*font, &fontFamily, fontSize, 0);
-						delete font;
-					}
-				}
-			}
-			delete fond;
+	Graphics::MacFontFamily fontFamily;
+	if (!fontFamily.load(*fond)) {
+		delete fond;
+		return;
+	}
+
+	Common::Array<Graphics::MacFontFamily::AsscEntry> *assoc = fontFamily.getAssocTable();
+	for (uint i = 0; i < assoc->size(); i++) {
+		int fontId = -1;
+		int fontSize = (*assoc)[i]._fontSize;
+
+		if (_vm->_game.id == GID_INDY3) {
+			if (fontSize == 9)
+				fontId = 1;
+			else if (fontSize == 12)
+				fontId = 0;
+		} else {
+			if (fontSize == 13)
+				fontId = 0;
+		}
+		if (fontId != -1) {
+			Common::SeekableReadStream *font = resource.getResource(MKTAG('F', 'O', 'N', 'T'), (*assoc)[i]._fontID);
+			_macFonts[fontId].loadFont(*font, &fontFamily, fontSize, 0);
+			delete font;
 		}
 	}
+
+	delete fond;
+
+	if (_vm->_renderMode == Common::kRenderMacintoshBW) {
+		int numFonts = (_vm->_game.id == GID_INDY3) ? 2 : 1;
+		int maxHeight = -1;
+		int maxWidth = -1;
+
+		for (int i = 0; i < numFonts; i++) {
+			maxHeight = MAX(maxHeight, _macFonts[i].getFontHeight());
+			maxWidth = MAX(maxWidth, _macFonts[i].getMaxCharWidth());
+		}
+
+		_glyphSurface = new Graphics::Surface();
+		_glyphSurface->create(maxWidth, maxHeight, Graphics::PixelFormat::createFormatCLUT8());
+	}
+}
+
+CharsetRendererMac::~CharsetRendererMac() {
+	if (_glyphSurface) {
+		_glyphSurface->free();
+		delete _glyphSurface;
+	}
 }
 
 void CharsetRendererMac::setCurID(int32 id) {
@@ -1638,6 +1663,10 @@ int CharsetRendererMac::getCharWidth(uint16 chr) {
 }
 
 void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
+	// This function does most of the heavy lifting printing the game
+	// text. It's the only function that needs to be able to handle
+	// disabled text.
+
 	// If this is the beginning of a line, assume the position will be
 	// correct without any padding.
 
@@ -1778,7 +1807,11 @@ void CharsetRendererMac::printChar(int chr, bool ignoreCharsetMask) {
 
 byte CharsetRendererMac::getTextColor() {
 	if (_vm->_renderMode == Common::kRenderMacintoshBW) {
-		if (_color == 0 || _color == 15)
+		// White and black can be rendered as is, and 8 is the color
+		// used for disabled text (verbs in Indy 3, notes in Loom).
+		// Everything else should be white.
+
+		if (_color == 0 || _color == 15 || _color == 8)
 			return _color;
 		return 15;
 	}
@@ -1826,15 +1859,41 @@ void CharsetRendererMac::printCharInternal(int chr, int color, bool shadow, int
 	_macFonts[_curId].drawChar(&_vm->_textSurface, chr, x + 1, y + 1, 0);
 
 	if (color != -1) {
-		if (color != -1) {
-			color = getTextColor();
-		}
+		color = getTextColor();
+
+		if (_vm->_renderMode == Common::kRenderMacintoshBW && color != 0 && color != 15) {
+			_glyphSurface->fillRect(Common::Rect(_glyphSurface->w, _glyphSurface->h), 0);
+			_macFonts[_curId].drawChar(_glyphSurface, chr, 0, 0, 15);
+
+			byte *src = (byte *)_glyphSurface->getBasePtr(0, 0);
+			byte *dst = (byte *)_vm->_macScreen->getBasePtr(x + 1, y + 1);
 
-		_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 1, y + 1, color);
+			for (int h = 0; h < _glyphSurface->h; h++) {
+				bool pixel = ((y + h + 1) & 1) == 0;
+
+				for (int w = 0; w < _glyphSurface->w; w++) {
+					if (src[w]) {
+						if (pixel)
+							dst[w] = 15;
+						else
+							dst[w] = 0;
+					}
+					pixel = !pixel;
+				}
+				src += _glyphSurface->pitch;
+				dst += _vm->_macScreen->pitch;
+			}
+		} else {
+			_macFonts[_curId].drawChar(_vm->_macScreen, chr, x + 1, y + 1, color);
+		}
 	}
 }
 
 void CharsetRendererMac::printCharToTextBox(int chr, int color, int x, int y) {
+	// This function handles printing most of the text in the text boxes
+	// in Indiana Jones and the last crusade. In black and white mode, all
+	// text is white. Text is never disabled.
+
 	if (_vm->_renderMode == Common::kRenderMacintoshBW)
 		color = 15;
 
@@ -1842,7 +1901,14 @@ void CharsetRendererMac::printCharToTextBox(int chr, int color, int x, int y) {
 }
 
 void CharsetRendererMac::drawChar(int chr, Graphics::Surface &s, int x, int y) {
-	byte color = getTextColor();
+	// This function is used for drawing most of the text outside of what
+	// the game scripts request. It's used for the text box captions in
+	// Indiana Jones and the Last Crusade, and for the practice mode box
+	// in Loom.
+	int color = _color;
+
+	if (_vm->_renderMode == Common::kRenderMacintoshBW)
+		color = 15;
 
 	_macFonts[_curId].drawChar(&s, chr, x, y, color);
 }
diff --git a/engines/scumm/charset.h b/engines/scumm/charset.h
index 3e00d131b4..d436213a39 100644
--- a/engines/scumm/charset.h
+++ b/engines/scumm/charset.h
@@ -287,8 +287,11 @@ protected:
 	byte getTextColor();
 	byte getTextShadowColor();
 
+	Graphics::Surface *_glyphSurface;
+
 public:
 	CharsetRendererMac(ScummEngine *vm, const Common::String &fontFile);
+	~CharsetRendererMac() override;
 
 	void setCurID(int32 id) override;
 	int getFontHeight() override;


Commit: e2544841df99b864a85079859020a8f8dc561d0e
    https://github.com/scummvm/scummvm/commit/e2544841df99b864a85079859020a8f8dc561d0e
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-07-13T09:53:36+02:00

Commit Message:
SCUMM: Handle shadow palette in Macintosh b/w mode

In Macintosh b/w mode, there really is no such thing as palette
manipulation. Any color changes have to be handled by the renderer.
Instead of marking the palette as dirty, changes to the shadow palette
trigger a full redraw of the screen.

At the time of writing, I'm only aware of two things that use this: The
lightning flashes at Castle Brunwald in Indiana Jones and the Last
Crusade, and the scene where the dragon finds Rusty in Loom. I have
verified that both of these seem to work correctly.

Changed paths:
    engines/scumm/gfx_mac.cpp
    engines/scumm/palette.cpp
    engines/scumm/script_v5.cpp


diff --git a/engines/scumm/gfx_mac.cpp b/engines/scumm/gfx_mac.cpp
index 62a3145bed..a874601322 100644
--- a/engines/scumm/gfx_mac.cpp
+++ b/engines/scumm/gfx_mac.cpp
@@ -39,17 +39,30 @@ void ScummEngine::mac_drawStripToScreen(VirtScreen *vs, int top, int x, int y, i
 	int tsPitch = _textSurface.pitch;
 	int macPitch = _macScreen->pitch;
 
+	// In b/w Mac rendering mode, the shadow palette is implemented here,
+	// and not as a palette manipulation. See special cases in o5_roomOps()
+	// and updatePalette().
+	//
+	// This is used at the very least for the lightning flashes at Castle
+	// Brunwald in Indy 3, as well as the scene where the dragon finds
+	// Rusty in Loom.
+	//
+	// Interestingly, the original Mac interpreter does not seem to do
+	// this, and instead just renders the scene as if the palette was
+	// unmodified. At least, that's what Mini vMac did when I tried it.
+
 	if (_renderMode == Common::kRenderMacintoshBW) {
 		for (int h = 0; h < height; h++) {
 			for (int w = 0; w < width; w++) {
+				int color = _shadowPalette[pixels[w]];
 				if (ts[2 * w] == CHARSET_MASK_TRANSPARENCY)
-					mac[2 * w] = Graphics::macEGADither[pixels[w]][0];
+					mac[2 * w] = Graphics::macEGADither[color][0];
 				if (ts[2 * w + 1] == CHARSET_MASK_TRANSPARENCY)
-					mac[2 * w + 1] = Graphics::macEGADither[pixels[w]][1];
+					mac[2 * w + 1] = Graphics::macEGADither[color][1];
 				if (ts[2 * w + tsPitch] == CHARSET_MASK_TRANSPARENCY)
-					mac[2 * w + macPitch] = Graphics::macEGADither[pixels[w]][2];
+					mac[2 * w + macPitch] = Graphics::macEGADither[color][2];
 				if (ts[2 * w + tsPitch + 1] == CHARSET_MASK_TRANSPARENCY)
-					mac[2 * w + macPitch + 1] = Graphics::macEGADither[pixels[w]][3];
+					mac[2 * w + macPitch + 1] = Graphics::macEGADither[color][3];
 			}
 
 			pixels += pixelsPitch;
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 4a0dbeeae0..c89df06dff 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -1419,7 +1419,11 @@ void ScummEngine::updatePalette() {
 		for (i = _palDirtyMin; i <= _palDirtyMax; i++) {
 			byte *data;
 
-			if (_game.features & GF_SMALL_HEADER && _game.version > 2)
+			// In b/w Mac rendering mode, the shadow palette is
+			// handled by the renderer itself. See comment in
+			// mac_drawStripToScreen().
+
+			if (_game.features & GF_SMALL_HEADER && _game.version > 2 && _renderMode != Common::kRenderMacintoshBW)
 				data = _currentPalette + _shadowPalette[i] * 3;
 			else
 				data = _currentPalette + i * 3;
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index ae38a8931e..87a90208eb 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1698,7 +1698,15 @@ void ScummEngine_v5::o5_roomOps() {
 			}
 			assertRange(0, a, 256, "o5_roomOps: 4: room color slot");
 			_shadowPalette[b] = a;
-			setDirtyColors(b, b);
+
+			// In b/w Mac rendering mode, the shadow palette is
+			// handled by the renderer itself. See comment in
+			// mac_drawStripToScreen().
+
+			if (_renderMode == Common::kRenderMacintoshBW) {
+				_fullRedraw = true;
+			} else
+				setDirtyColors(b, b);
 		} else {
 			a = getVarOrDirectWord(PARAM_1);
 			b = getVarOrDirectWord(PARAM_2);


Commit: 5775637bb86001685d8b599cddb523219b77367a
    https://github.com/scummvm/scummvm/commit/5775637bb86001685d8b599cddb523219b77367a
Author: Torbjörn Andersson (eriktorbjorn at users.sourceforge.net)
Date: 2021-07-13T09:53:36+02:00

Commit Message:
COMMON: Add translator's note for the Macintosh b/w render mode

Changed paths:
    common/rendermode.cpp


diff --git a/common/rendermode.cpp b/common/rendermode.cpp
index b39e334ee2..0907190ef5 100644
--- a/common/rendermode.cpp
+++ b/common/rendermode.cpp
@@ -44,6 +44,7 @@ const RenderModeDescription g_renderModes[] = {
 	{ "2gs", "Apple IIgs", kRenderApple2GS },
 	{ "atari", "Atari ST", kRenderAtariST },
 	{ "macintosh", "Macintosh", kRenderMacintosh },
+	// I18N: Macintosh black-and-white
 	{ "macintoshbw", _s("Macintosh b/w"), kRenderMacintoshBW },
 	{nullptr, nullptr, kRenderDefault}
 };




More information about the Scummvm-git-logs mailing list