[Scummvm-git-logs] scummvm master -> 85a191de2bae669cf7b23d47165baa892a27bc4d

athrxx noreply at scummvm.org
Sun Jul 31 22:09:46 UTC 2022


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:
85a191de2b SCUMM: (v6/EGA) - improved mouse cursor handling and some other fixes


Commit: 85a191de2bae669cf7b23d47165baa892a27bc4d
    https://github.com/scummvm/scummvm/commit/85a191de2bae669cf7b23d47165baa892a27bc4d
Author: athrxx (athrxx at scummvm.org)
Date: 2022-07-31T23:57:15+02:00

Commit Message:
SCUMM: (v6/EGA) - improved mouse cursor handling and some other fixes

The mouse cursors get dithered correctly now and due to earlier fixes SAMNMAX seems to be in as good a state as DOTT regarding EGA dithering mode, so I enable it. Also added a post-load fix for the palette and the mouse cursors.

Changed paths:
    engines/scumm/cursor.cpp
    engines/scumm/palette.cpp
    engines/scumm/saveload.cpp
    engines/scumm/scumm.cpp
    engines/scumm/scumm.h
    engines/scumm/scumm_v6.h


diff --git a/engines/scumm/cursor.cpp b/engines/scumm/cursor.cpp
index d404e560ade..ce2cb4f9682 100644
--- a/engines/scumm/cursor.cpp
+++ b/engines/scumm/cursor.cpp
@@ -113,9 +113,17 @@ void ScummEngine_v6::setCursorTransparency(int a) {
 
 	size = _cursor.width * _cursor.height;
 
-	for (i = 0; i < size; i++)
-		if (_grabbedCursor[i] == (byte)a)
-			_grabbedCursor[i] = 0xFF;
+	if (_enableEGADithering) {
+		for (i = 0; i < size; i += 2) {
+			int st = 1 ^ ((i / (_cursor.width << 1)) & 1);
+			if (_grabbedCursor[i] == _egaColorMap[st][a] && _grabbedCursor[i + 1] == _egaColorMap[st ^ 1][a])
+				_grabbedCursor[i] = _grabbedCursor[i + 1] = 0xFF;
+		}
+	} else {
+		for (i = 0; i < size; i++)
+			if (_grabbedCursor[i] == (byte)a)
+				_grabbedCursor[i] = 0xFF;
+	}
 
 	updateCursor();
 }
@@ -153,43 +161,51 @@ void ScummEngine_v6::setDefaultCursor() {
 	setCursorFromBuffer(default_v6_cursor, 16, 13, 16);
 }
 
-void ScummEngine::setCursorFromBuffer(const byte *ptr, int width, int height, int pitch) {
+void ScummEngine_v6::setCursorFromBuffer(const byte *ptr, int width, int height, int pitch) {
 	uint size;
 	byte *dst;
 
-	int sclW = _enableEGADithering ? 2 : 1;
-	int sclH = _enableEGADithering ? 2 : 1;
-
-	size = width * sclW * height * sclH * _bytesPerPixel;
+	size = width * height * _bytesPerPixel;
+	if (_enableEGADithering)
+		size <<= 2;
 	if (size > sizeof(_grabbedCursor))
 		error("grabCursor: grabbed cursor too big");
 
-	_cursor.width = width * sclW;
-	_cursor.height = height * sclH;
+	_cursor.width = width;
+	_cursor.height = height;
 	_cursor.animate = 0;
 
-	dst = _grabbedCursor;
+	dst = _enableEGADithering ? _compositeBuf : _grabbedCursor;
 	for (; height; height--) {
-		for (int h2 = sclH; h2; --h2) {
-			const byte *s1 = ptr;
-			const byte *s2 = 0;
-			byte *d = dst;
-			for (int w = width; w; --w) {
-				for (int w2 = sclW; w2; --w2) {
-					s2 = s1;
-					for (int w3 = _bytesPerPixel; w3; --w3)
-						*d++ = *s2++;
-				}
-				s1 = s2;
-			}
-			dst += width * sclW * _bytesPerPixel;
-		}
+		memcpy(dst, ptr, width * _bytesPerPixel);
+		dst += width * _bytesPerPixel;
 		ptr += pitch;
 	}
 
+	if (_enableEGADithering)
+		ditherCursor();
+
 	updateCursor();
 }
 
+void ScummEngine_v6::ditherCursor() {
+	int x = 0;
+	int y = 0;
+	int pitch = _cursor.width;
+
+	// We temporarily put the transparency color in the EGA color tables.
+	uint8 backupEGA0 = _egaColorMap[0][255];
+	uint8 backupEGA1 = _egaColorMap[1][255];
+	_egaColorMap[0][255] = _egaColorMap[1][255] = 0xFF;
+
+	ditherVGAtoEGA(pitch, x, y, _cursor.width, _cursor.height);
+
+	_egaColorMap[0][255] = backupEGA0;
+	_egaColorMap[1][255] = backupEGA1;
+
+	memcpy(_grabbedCursor, _hercCGAScaleBuf, _cursor.width * _cursor.height);
+}
+
 void ScummEngine_v70he::setCursorFromImg(uint img, uint room, uint imgindex) {
 	_resExtractor->setCursor(img);
 }
@@ -391,6 +407,8 @@ void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
 	height *= 8;
 
 	size = width * height;
+	if (_enableEGADithering)
+		size <<= 2;
 	if (size > sizeof(_grabbedCursor))
 		error("useBompCursor: cursor too big (%d)", size);
 
@@ -404,7 +422,10 @@ void ScummEngine_v6::useBompCursor(const byte *im, int width, int height) {
 	} else {
 		im += 18;
 	}
-	decompressBomp(_grabbedCursor, im, width, height);
+	decompressBomp(_enableEGADithering ? _compositeBuf : _grabbedCursor, im, width, height);
+
+	if (_enableEGADithering)
+		ditherCursor();
 
 	updateCursor();
 }
diff --git a/engines/scumm/palette.cpp b/engines/scumm/palette.cpp
index 99d8dc6a8bd..76f431ba98c 100644
--- a/engines/scumm/palette.cpp
+++ b/engines/scumm/palette.cpp
@@ -252,6 +252,12 @@ void ScummEngine::resetPalette() {
 		} else if (_renderMode == Common::kRenderEGA && _supportsEGADithering) {
 			setPaletteFromTable(tableEGAPalette, sizeof(tableEGAPalette) / 3);
 			_enableEGADithering = true;
+			// Set the color tables to sane values (for games that dither the mouse cursor
+			// right at the beginning, before these tables get filled normally.
+			if (_currentRoom == 0) {
+				for (uint16 i = 0; i < 256; ++i)
+					_egaColorMap[0][i] = _egaColorMap[1][i] = i & 0x0F;
+			}
 #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
 		} else if (_game.platform == Common::kPlatformFMTowns) {
 			if (_game.id == GID_INDY4 || _game.id == GID_MONKEY2)
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index bce0c2ff4a8..47bd5f5d887 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -1172,7 +1172,7 @@ void ScummEngine::saveLoadWithSerializer(Common::Serializer &s) {
 			x *= 2;
 			x += (kHercWidth - _screenWidth * 2) / 2;
 			y = y * 7 / 4;
-		} else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2)) {
+		} else if (_macScreen || (_useCJKMode && _textSurfaceMultiplier == 2) || _renderMode == Common::kRenderCGA_BW || _enableEGADithering) {
 			x *= 2;
 			y *= 2;
 		}
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 353ed881468..2f0f0444f95 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -243,8 +243,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
 
 	// VGA games which support an EGA dithering mode
 	static const byte egaModeIDs[] = {
-		/*GID_SAMNMAX,*/	// Not supported in the original interpreter. It works, but is too glitchy to have it enabled without further fine tuning...
-		GID_TENTACLE,		// Not supported in the original interpreter. Less glitchy than SAM, so I leave it enabled. I guess, people who actually select this will know what they're doing.
+		GID_SAMNMAX,		// Not supported in the original interpreter. Glitches might occur.
+		GID_TENTACLE,		// Not supported in the original interpreter. Glitches might occur.
 		GID_LOOM,			// Supported in the original interpreter.
 		GID_MONKEY,
 		GID_MONKEY_VGA,
@@ -2691,13 +2691,13 @@ void ScummEngine_v3::scummLoop_handleSaveLoad() {
 			_townsPlayer->restoreAfterLoad();
 	}
 }
+
 void ScummEngine_v5::scummLoop_handleSaveLoad() {
 	bool processIQPoints = (_game.id == GID_INDY4) && (_saveLoadFlag == 2 || _loadFromLauncher);
 	_loadFromLauncher = false;
 
 	ScummEngine::scummLoop_handleSaveLoad();
 
-	
 	if (_videoModeChanged) {
 		_videoModeChanged = false;
 		warning("Loading savegame with a different render mode setting. Glitches might occur");
@@ -2734,6 +2734,33 @@ void ScummEngine_v5::scummLoop_handleSaveLoad() {
 		runScript(145, 0, 0, nullptr);
 }
 
+void ScummEngine_v6::scummLoop_handleSaveLoad() {
+	ScummEngine::scummLoop_handleSaveLoad();
+
+	if (_videoModeChanged) {
+		_videoModeChanged = false;
+		warning("Loading savegame with a different render mode setting. Glitches might occur");
+		if (_supportsEGADithering) {
+			// Reconstruct the screen palette.
+			setCurrentPalette(_curPalIndex);
+			// Reconstruct mouse cursor (crosshair for DOTT, verb cursor for SAM).
+			if (_game.id == GID_SAMNMAX) {
+				setCursorFromImg(VAR(177), VAR(177) > 890 ? 94 : 93, 1);
+				if (VAR(177) > 890) {
+					// The inventory item cursors require some extra treatment...
+					setCursorTransparency(180);
+					setCursorTransparency(178);
+					setCursorTransparency(176);
+					setCursorTransparency(6);
+					setCursorTransparency(0);
+				}
+			} else {
+				setDefaultCursor();
+			}
+		}
+	}
+}
+
 #ifdef ENABLE_SCUMM_7_8
 void ScummEngine_v8::scummLoop_handleSaveLoad() {
 	ScummEngine::scummLoop_handleSaveLoad();
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 2435580ab5f..671f5a8b217 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -1054,8 +1054,6 @@ protected:
 	void setShadowPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor, int start, int end);
 	virtual void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
 
-	void setCursorFromBuffer(const byte *ptr, int width, int height, int pitch);
-
 public:
 	void markRectAsDirty(VirtScreenNumber virt, int left, int right, int top, int bottom, int dirtybit = 0);
 	void markRectAsDirty(VirtScreenNumber virt, const Common::Rect& rect, int dirtybit = 0) {
diff --git a/engines/scumm/scumm_v6.h b/engines/scumm/scumm_v6.h
index d1ccd9435ee..f4dd5b811a0 100644
--- a/engines/scumm/scumm_v6.h
+++ b/engines/scumm/scumm_v6.h
@@ -108,6 +108,7 @@ public:
 protected:
 	void setupOpcodes() override;
 
+	void scummLoop_handleSaveLoad() override;
 	void scummLoop_handleActors() override;
 	void processKeyboard(Common::KeyState lastKeyHit) override;
 
@@ -143,6 +144,8 @@ protected:
 	void useIm01Cursor(const byte *im, int w, int h);
 	void useBompCursor(const byte *im, int w, int h);
 	void grabCursor(int x, int y, int w, int h);
+	void setCursorFromBuffer(const byte *ptr, int width, int height, int pitch);
+	void ditherCursor();
 
 	virtual void drawBlastTexts() {}
 	virtual void removeBlastTexts() {}




More information about the Scummvm-git-logs mailing list