[Scummvm-git-logs] scummvm master -> 4dab11649ac1226a2d2438906478a65172118df9

neuromancer noreply at scummvm.org
Wed Jun 24 18:12:37 UTC 2026


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

Summary:
c94ba2a0c4 EEM: corrected decoding of some images from the EEM1 Mac
2c4a794b5e EEM: improve intro in the EEM1 Mac
d79a68bc13 EEM: better fit for text ballons on EEM1 Mac
4dab11649a EEM: fixed colors for some screens in EEM1 Mac


Commit: c94ba2a0c496fdb00c588db5c3ab1f13b418e9ff
    https://github.com/scummvm/scummvm/commit/c94ba2a0c496fdb00c588db5c3ab1f13b418e9ff
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-24T20:12:21+02:00

Commit Message:
EEM: corrected decoding of some images from the EEM1 Mac

Changed paths:
    engines/eem/eem.cpp
    engines/eem/site.cpp
    engines/eem/site.h


diff --git a/engines/eem/eem.cpp b/engines/eem/eem.cpp
index d89eea60354..999cbc36f5f 100644
--- a/engines/eem/eem.cpp
+++ b/engines/eem/eem.cpp
@@ -211,17 +211,29 @@ void setInteractiveCursorPalette(const Picture &cursor, byte transparent) {
 	CursorMan.replaceCursorPalette(palette, 0, 256);
 }
 
-void installMouseCursor(DBDArchive &pics, bool interactive) {
+void installMouseCursor(DBDArchive &pics, bool interactive, bool mac) {
 	Picture cursor;
 	if (!pics.getPicture(kPicMousePointer, cursor) || cursor.surface.empty())
 		error("EEM: mouse cursor PIC 0x%x missing", kPicMousePointer);
 
 	const byte transparent = (byte)(cursor.flags >> 8);
 	CursorMan.replaceCursor(cursor.surface.rawSurface(), 0, 0, transparent);
-	if (interactive)
+	if (interactive) {
 		setInteractiveCursorPalette(cursor, transparent);
-	else
+	} else if (mac) {
+		// Mac sprite art is authored with palette index 0 = white and
+		// 0xFF = black, but ~2/3 of the site ColorTables store those endpoints
+		// swapped (the original relied on QuickDraw CopyBits colour-matching to
+		// reconcile that). Pin white/black in a dedicated cursor palette so the
+		// pointer's body stays white instead of turning black on those sites.
+		byte pal[kPalSize];
+		g_system->getPaletteManager()->grabPalette(pal, 0, 256);
+		pal[0] = pal[1] = pal[2] = 0xFF;
+		pal[0xFF * 3 + 0] = pal[0xFF * 3 + 1] = pal[0xFF * 3 + 2] = 0x00;
+		CursorMan.replaceCursorPalette(pal, 0, 256);
+	} else {
 		CursorMan.replaceCursorPalette(nullptr, 0, 0);
+	}
 }
 
 EEMEngine::EEMEngine(OSystem *syst, const ADGameDescription *gameDesc)
@@ -424,7 +436,7 @@ Common::Error EEMEngine::run() {
 	_audio->setVoiceEnabled(_voiceOn);
 	syncSoundSettings();
 
-	installMouseCursor(_picsArchive, false);
+	installMouseCursor(_picsArchive, false, isMacintosh());
 	CursorMan.showMouse(false);
 
 	// _AllBlack @ 172b:0d4b.
@@ -726,7 +738,7 @@ void EEMEngine::setInteractiveMouseCursor(bool active) {
 		return;
 
 	_interactiveMouseCursor = active;
-	installMouseCursor(_picsArchive, active);
+	installMouseCursor(_picsArchive, active, isMacintosh());
 	// The red-outline highlight replaced any London cursor shape; force the
 	// next setSiteHotspotCursorId to reinstall.
 	_siteCursorId = -1;
diff --git a/engines/eem/site.cpp b/engines/eem/site.cpp
index 5a9d6e95c87..117eb842cc6 100644
--- a/engines/eem/site.cpp
+++ b/engines/eem/site.cpp
@@ -186,6 +186,15 @@ void blitMacMaskedSurface(Graphics::Surface *dst, const Picture &p,
 	blitMacMaskedSurface(dst, p, x, y, flipX, paletteMap);
 }
 
+void remapMacSurfaceEndpoints(Graphics::ManagedSurface &surface,
+							  const MacSpritePaletteMap &paletteMap) {
+	for (int y = 0; y < surface.h; y++) {
+		byte *row = (byte *)surface.getBasePtr(0, y);
+		for (int x = 0; x < surface.w; x++)
+			row[x] = mapMacSpriteColor(row[x], paletteMap);
+	}
+}
+
 // `_UpdateAnimations @ 172b:09c1`
 void blitAnimFrameAnchored(Graphics::Surface *screen, const Picture &p,
 						   int anchorX, int anchorY) {
@@ -1734,8 +1743,18 @@ bool SiteScreen::renderFloppyHotspotPartnerPose(uint siteNum) {
 }
 
 void SiteScreen::renderBackground(uint siteNum) {
+	// Mac art uses index 0 = white / 0xFF = black, but most site ColorTables
+	// store those endpoints swapped. Backgrounds are copied straight to the
+	// screen, so normalize their endpoints to the active palette first (sprites
+	// already do this through blitMacMaskedSurface).
+	const bool mac = _vm->isMacintosh();
+	const MacSpritePaletteMap macMap =
+		mac ? getMacSpritePaletteMap() : MacSpritePaletteMap();
+
 	Picture frame;
 	if (_vm->getPics().loadEntry(0x3d, frame)) {
+		if (mac)
+			remapMacSurfaceEndpoints(frame.surface, macMap);
 		g_system->copyRectToScreen(frame.surface.getPixels(),
 								   frame.surface.pitch,
 								   0, 0, frame.surface.w, frame.surface.h);
@@ -1765,9 +1784,12 @@ void SiteScreen::renderBackground(uint siteNum) {
 		const int y = _vm->scaleY(0x14);
 		const int w = MIN<int>(scene.surface.w, _vm->screenWidth() - x);
 		const int h = MIN<int>(scene.surface.h, _vm->screenHeight() - y);
-		if (w > 0 && h > 0)
+		if (w > 0 && h > 0) {
+			if (mac)
+				remapMacSurfaceEndpoints(scene.surface, macMap);
 			g_system->copyRectToScreen(scene.surface.getPixels(),
 									   scene.surface.pitch, x, y, w, h);
+		}
 	}
 }
 
diff --git a/engines/eem/site.h b/engines/eem/site.h
index 8c65d9c0eee..17576110e69 100644
--- a/engines/eem/site.h
+++ b/engines/eem/site.h
@@ -87,6 +87,13 @@ void blitMacAnimFrameAnchored(Graphics::Surface *dst, const Picture &p,
 							  int anchorX, int anchorY,
 							  const MacSpritePaletteMap &paletteMap);
 
+/// Remap a whole Mac surface's white/black endpoint indices (0x00 / 0xFF) to the
+/// active ColorTable's real white/black slots. Backgrounds are copied straight
+/// to the screen, so without this their white areas turn black on the many site
+/// ColorTables that store the endpoints swapped.
+void remapMacSurfaceEndpoints(Graphics::ManagedSurface &surface,
+							  const MacSpritePaletteMap &paletteMap);
+
 /// Rotate one VGA palette range by one slot (START→END direction).
 void cyclePaletteRange(uint8 start, uint8 end);
 


Commit: 2c4a794b5e7351875a7f3cad199eaf2539d219c7
    https://github.com/scummvm/scummvm/commit/2c4a794b5e7351875a7f3cad199eaf2539d219c7
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-24T20:12:21+02:00

Commit Message:
EEM: improve intro in the EEM1 Mac

Changed paths:
    engines/eem/eem.cpp


diff --git a/engines/eem/eem.cpp b/engines/eem/eem.cpp
index 999cbc36f5f..00d795b35d4 100644
--- a/engines/eem/eem.cpp
+++ b/engines/eem/eem.cpp
@@ -59,7 +59,7 @@ const uint kPalEAKids          = 0x25;
 const uint kPalHighScore       = 0x27;
 const uint kPalStormLogo       = 0x26;  // Floppy FUN_23d2_0605
 const uint kMacPicEAKidsLogo   = 0x213; // FUN_000092be
-const uint kMacPicTitleRoom    = 0x20d; // FUN_000096fa title room
+// PIC 0x20d is the clubhouse scene; the title sequence (FUN_000096fa) omits it.
 const uint kMacPicTitleDark    = 0x20e;
 const uint kMacPicTitleFinal   = 0x20f;
 const uint kMacPicTitleIn0     = 0x210;
@@ -1288,9 +1288,10 @@ void EEMEngine::showMacTitleIntro() {
 		return;
 	}
 
-	Picture room, titleDark, titleFinal;
-	if (!_picsArchive.getPicture(kMacPicTitleRoom, room) ||
-		!_picsArchive.getPicture(kMacPicTitleDark, titleDark) ||
+	// FUN_000096fa uses only the dark-eye (0x20e) and lit-eye (0x20f) frames; the
+	// eye "powers up" from one to the other (PIC 0x20d, the clubhouse, isn't used).
+	Picture titleDark, titleFinal;
+	if (!_picsArchive.getPicture(kMacPicTitleDark, titleDark) ||
 		!_picsArchive.getPicture(kMacPicTitleFinal, titleFinal)) {
 		warning("Mac title base pictures failed to load");
 		return;
@@ -1317,7 +1318,7 @@ void EEMEngine::showMacTitleIntro() {
 
 	Graphics::ManagedSurface frame(kMacScreenWidth, kMacScreenHeight,
 								   Graphics::PixelFormat::createFormatCLUT8());
-	frame.blitFrom(room.surface, Common::Point(0, 0));
+	frame.blitFrom(titleDark.surface, Common::Point(0, 0));
 	copyNativeSurfaceToScreen(frame);
 
 	byte black[kPalSize] = {};
@@ -1326,11 +1327,11 @@ void EEMEngine::showMacTitleIntro() {
 	fadePaletteFromBlack(target);
 
 	for (int i = 0; i < 0x2c && !shouldQuit() && !_skipIntro; i++) {
-		frame.blitFrom(room.surface, Common::Point(0, 0));
+		frame.blitFrom(titleDark.surface, Common::Point(0, 0));
 		const int revealW = (i + 1) * kMacScreenWidth / 0x2c;
 		if (revealW > 0) {
 			const Common::Rect src(0, 0, revealW, kMacScreenHeight);
-			frame.blitFrom(titleDark.surface, src, Common::Point(0, 0));
+			frame.blitFrom(titleFinal.surface, src, Common::Point(0, 0));
 		}
 
 		switch (i) {


Commit: d79a68bc13ca970aa09392a2d091f3b67674ec40
    https://github.com/scummvm/scummvm/commit/d79a68bc13ca970aa09392a2d091f3b67674ec40
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-24T20:12:21+02:00

Commit Message:
EEM: better fit for text ballons on EEM1 Mac

Changed paths:
    engines/eem/detection.cpp
    engines/eem/eem.cpp
    engines/eem/eem.h
    engines/eem/graphics.cpp


diff --git a/engines/eem/detection.cpp b/engines/eem/detection.cpp
index 9665f18d349..48ab6e43f2f 100644
--- a/engines/eem/detection.cpp
+++ b/engines/eem/detection.cpp
@@ -35,7 +35,7 @@ const PlainGameDescriptor eemGames[] = {
 #define GUI_OPTIONS_EEM_FLOPPY GUIO4(GAMEOPTION_HIDE_HIGHLIGHT_BOXES, GAMEOPTION_SKIP_REPEATED_CASES, GUIO_MIDIADLIB, GUIO_MIDIMT32)
 #define GUI_OPTIONS_EEM_CD     GUIO6(GAMEOPTION_HIDE_HIGHLIGHT_BOXES, GAMEOPTION_FIT_DIALOG_BALLOONS, GAMEOPTION_SKIP_REPEATED_CASES, GAMEOPTION_RESTORED_CONTENT, GUIO_MIDIADLIB, GUIO_MIDIMT32)
 #define GUI_OPTIONS_EEM_DEMO   GUIO2(GAMEOPTION_HIDE_HIGHLIGHT_BOXES, GUIO_NOMIDI)
-#define GUI_OPTIONS_EEM_MAC    GUIO2(GAMEOPTION_HIDE_HIGHLIGHT_BOXES, GUIO_NOMIDI)
+#define GUI_OPTIONS_EEM_MAC    GUIO3(GAMEOPTION_HIDE_HIGHLIGHT_BOXES, GAMEOPTION_FIT_DIALOG_BALLOONS, GUIO_NOMIDI)
 
 const ADGameDescription gameDescriptions[] = {
 	{
diff --git a/engines/eem/eem.cpp b/engines/eem/eem.cpp
index 00d795b35d4..cd59898e5b7 100644
--- a/engines/eem/eem.cpp
+++ b/engines/eem/eem.cpp
@@ -390,9 +390,12 @@ static bool loadMacFont(EEMFont &font) {
 		   loadMacFontResource(font, kMacSmallFontResource, 9);
 }
 
+// Speech balloons use the 14pt Eagle Eye font: the bubble art and the
+// fit-to-text metrics are both sized for it, so it is most likely the size the
+// original shipped (the 9pt FONT left the text undersized with blank space).
 static bool loadMacDialogFont(EEMFont &font) {
-	return loadMacFontResource(font, kMacSmallFontResource, 9) ||
-		   loadMacFontResource(font, kMacFontResource, 14);
+	return loadMacFontResource(font, kMacFontResource, 14) ||
+		   loadMacFontResource(font, kMacSmallFontResource, 9);
 }
 
 Common::Error EEMEngine::run() {
diff --git a/engines/eem/eem.h b/engines/eem/eem.h
index c90c52279f0..a00e5cfa847 100644
--- a/engines/eem/eem.h
+++ b/engines/eem/eem.h
@@ -246,6 +246,10 @@ public:
 	/// Pick a shorter balloon sibling when wrapped text leaves empty lines.
 	uint16 fitBalloonToText(uint16 bubNum, const Common::String &text);
 
+	/// How many `lineH`-tall text lines fit in balloon `balloonId` (the balloon
+	/// height is scaled to native coordinates on Mac).
+	uint getBalloonLineCapacity(uint16 balloonId, int lineH) const;
+
 	/// `_ParseString @ 1b66:07c3`. 
 	Common::String parseString(const Common::String &raw,
 							   const Common::String &playerName,
@@ -546,7 +550,7 @@ private:
 	DBDArchive _buttonArchive;   ///< BUTTON.DBD/.DBX (`_GetButton`)
 	Mystery    _mystery;         ///< M<n>.BIN
 	EEMFont    _font;            ///< FONT.FNT (8 px)
-	EEMFont    _dialogFont;      ///< Mac small FONT used inside speech balloons.
+	EEMFont    _dialogFont;      ///< Mac 14pt FONT used inside speech balloons.
 
 	Common::Array<byte> _sitePals; ///< 40 × 768 bytes, 6-bit VGA.
 
diff --git a/engines/eem/graphics.cpp b/engines/eem/graphics.cpp
index 1832c6fcd95..860f3fdf40d 100644
--- a/engines/eem/graphics.cpp
+++ b/engines/eem/graphics.cpp
@@ -109,13 +109,16 @@ bool findBalloonFamily(uint16 balloonId, uint16 &first, uint16 &last) {
 	return false;
 }
 
-uint getBalloonLineCapacity(uint16 balloonId, int lineH) {
+uint EEMEngine::getBalloonLineCapacity(uint16 balloonId, int lineH) const {
 	const uint idx = balloonId & 0x7F;
 	if (idx >= ARRAYSIZE(kBalloonInsetTable) || lineH <= 0)
 		return 0;
 
 	const BalloonInsets &insets = kBalloonInsetTable[idx];
-	return MAX<uint>(1, ((int)insets.indDY - (int)insets.y) / lineH + 1);
+	int textHeight = (int)insets.indDY - (int)insets.y;
+	if (isMacintosh())
+		textHeight = scaleY(textHeight); // table is in DOS coords; Mac renders scaled
+	return MAX<uint>(1, textHeight / lineH + 1);
 }
 
 bool EEMEngine::floppyHotspotSearched(uint siteIdx, uint hotspotIdx) const {
@@ -741,8 +744,9 @@ void EEMEngine::setPartnerEraseBg(const Graphics::ManagedSurface *bg) {
 
 uint16 EEMEngine::fitBalloonToText(uint16 bubNum,
 								   const Common::String &text) {
-	// Opt-in via "fit_dialog_balloons", CD only
-	if (isFloppy() || isMacintosh() || !ConfMan.getBool("fit_dialog_balloons"))
+	// Opt-in via "fit_dialog_balloons" (CD and Mac; the DOS floppy balloon
+	// layout has no smaller siblings to fall back to).
+	if (isFloppy() || !ConfMan.getBool("fit_dialog_balloons"))
 		return bubNum;
 
 	const uint16 originalId = bubNum & 0x7F;
@@ -757,7 +761,9 @@ uint16 EEMEngine::fitBalloonToText(uint16 bubNum,
 		return bubNum;
 
 	Common::Array<Common::String> lines;
-	_font.wordWrapText(text, MAX<int>(8, (int)originalInsets.w), lines);
+	const int wrapW = isMacintosh() ? scaleX((int)originalInsets.w)
+									: (int)originalInsets.w;
+	_font.wordWrapText(text, MAX<int>(8, wrapW), lines);
 	if (lines.empty())
 		return bubNum;
 


Commit: 4dab11649ac1226a2d2438906478a65172118df9
    https://github.com/scummvm/scummvm/commit/4dab11649ac1226a2d2438906478a65172118df9
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-24T20:12:21+02:00

Commit Message:
EEM: fixed colors for some screens in EEM1 Mac

Changed paths:
    engines/eem/ui.cpp


diff --git a/engines/eem/ui.cpp b/engines/eem/ui.cpp
index 27a88aa3691..cb5b4739084 100644
--- a/engines/eem/ui.cpp
+++ b/engines/eem/ui.cpp
@@ -2049,6 +2049,12 @@ void EEMEngine::doSetup() {
 }
 
 void EEMEngine::setupDrawScreen() {
+	// The setup screen shares the map overview's ColorTable. Set it explicitly
+	// so the screen is correct no matter where it was entered from: the zoomed
+	// detail map leaves its own palette (0x23) active, which would otherwise
+	// bleed through here.
+	setSitePalette(0x24);
+
 	Graphics::ManagedSurface scratch(screenWidth(), screenHeight(),
 		Graphics::PixelFormat::createFormatCLUT8());
 	scratch.clear();
@@ -4302,8 +4308,14 @@ void EEMEngine::drawBigMapDetail(int scrollX, int scrollY,
 	scratch.clear();
 
 	Picture frame;
-	if (_picsArchive.getPicture(0x43, frame))
+	if (_picsArchive.getPicture(0x43, frame)) {
+		// The frame and its buttons use the normal 0x00=white / 0xFF=black
+		// convention, but the detail-map ColorTable (0x23) swaps those endpoints,
+		// so normalize them or the SETUP button's black border renders white.
+		if (mac)
+			remapMacSurfaceEndpoints(frame.surface, getMacSpritePaletteMap());
 		scratch.simpleBlitFrom(frame.surface);
+	}
 
 	const int copyW = MIN<int>(mapW - scrollX, kMapWinW);
 	const int copyH = MIN<int>(mapH - scrollY, kMapWinH);




More information about the Scummvm-git-logs mailing list