[Scummvm-git-logs] scummvm master -> 80430b475691d64631498c682506955261df43ba

sev- sev at scummvm.org
Sat Jul 25 11:29:14 UTC 2020


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

Summary:
44e948a283 GRAPHICS: Support full alpha when blitting using masks in ManagedSurface
731596b5f7 GRAPHICS: Support converting between different palettes using ManagedSurface
80430b4756 GRAPHICS: Ensure that creating a ManagedSurface from another preserves the palette


Commit: 44e948a283cfee541d2fa73bd707ca34b0716313
    https://github.com/scummvm/scummvm/commit/44e948a283cfee541d2fa73bd707ca34b0716313
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2020-07-25T13:29:09+02:00

Commit Message:
GRAPHICS: Support full alpha when blitting using masks in ManagedSurface

Changed paths:
    graphics/managed_surface.cpp
    graphics/managed_surface.h


diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index d5d7f614c4..598e13861b 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -361,17 +361,62 @@ void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Rect
 		srcAlpha, palette, mask, maskOnly);
 }
 
+template<typename TSRC, typename TDEST>
+void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &srcFormat, const Graphics::PixelFormat &destFormat,
+		uint overrideColor, uint srcAlpha, const uint32 *palette) {
+	if (srcFormat == destFormat && srcAlpha == 0xff) {
+		// Matching formats, so we can do a straight copy
+		destVal = overrideColor ? overrideColor : srcVal;
+		return;
+	}
+
+	// Otherwise we have to manually decode and re-encode each pixel
+	byte aSrc, rSrc, gSrc, bSrc;
+	if (srcFormat.bytesPerPixel == 1) {
+		assert(palette != nullptr);	// Catch the cases when palette is missing
+
+		// Get the palette color
+		const uint32 col = palette[srcVal];
+		rSrc = col & 0xff;
+		gSrc = (col >> 8) & 0xff;
+		bSrc = (col >> 16) & 0xff;
+		aSrc = (col >> 24) & 0xff;
+	} else {
+		srcFormat.colorToARGB(srcVal, aSrc, rSrc, gSrc, bSrc);
+	}
+
+	byte rDest, gDest, bDest;
+	destFormat.colorToRGB(destVal, rDest, gDest, bDest);
+
+	if (srcAlpha != 0xff) {
+		aSrc = aSrc * srcAlpha / 255;
+	}
+
+	if (aSrc == 0) {
+		// Completely transparent, so skip
+		return;
+	} else if (aSrc == 0xff) {
+		// Completely opaque, so copy RGB values over
+		rDest = rSrc;
+		gDest = gSrc;
+		bDest = bSrc;
+	} else {
+		// Partially transparent, so calculate new pixel colors
+		double alpha = (double)aSrc / 255.0;
+		rDest = static_cast<byte>((rSrc * alpha) + (rDest * (1.0 - alpha)));
+		gDest = static_cast<byte>((gSrc * alpha) + (gDest * (1.0 - alpha)));
+		bDest = static_cast<byte>((bSrc * alpha) + (bDest * (1.0 - alpha)));
+	}
+
+	destVal = destFormat.ARGBToColor(0xff, rDest, gDest, bDest);
+}
+
 template<typename TSRC, typename TDEST>
 void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, const Common::Rect &destRect,
 		TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *palette,
 		const Surface *mask, bool maskOnly) {
 	int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width();
 	int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height();
-	const Graphics::PixelFormat &srcFormat = src.format;
-	const Graphics::PixelFormat &destFormat = dest.format;
-	byte aSrc, rSrc, gSrc, bSrc;
-	byte rDest, gDest, bDest;
-	double alpha;
 
 	// Loop through drawing output lines
 	for (int destY = destRect.top, scaleYCtr = 0; destY < destRect.bottom; ++destY, scaleYCtr += scaleY) {
@@ -398,50 +443,10 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
 				TSRC mskVal = mskLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD];
 				if (!mskVal)
 					continue;
-			}
 
-			if (srcFormat == destFormat && srcAlpha == 0xff) {
-				// Matching formats, so we can do a straight copy
-				destLine[xCtr] = overrideColor ? overrideColor : srcVal;
+				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, mskVal, palette);
 			} else {
-				// Otherwise we have to manually decode and re-encode each pixel
-				if (srcFormat.bytesPerPixel == 1) {
-					assert(palette != nullptr);	// Catch the cases when palette is missing
-
-					// Get the palette color
-					const uint32 col = palette[srcVal];
-					rSrc = col & 0xff;
-					gSrc = (col >> 8) & 0xff;
-					bSrc = (col >> 16) & 0xff;
-					aSrc = (col >> 24) & 0xff;
-				} else {
-					srcFormat.colorToARGB(srcVal, aSrc, rSrc, gSrc, bSrc);
-				}
-				destFormat.colorToRGB(destLine[xCtr], rDest, gDest, bDest);
-
-				if (srcAlpha != 0xff) {
-					aSrc = aSrc * srcAlpha / 255;
-				}
-
-				if (aSrc == 0) {
-					// Completely transparent, so skip
-					continue;
-				}
-				else if (aSrc == 0xff) {
-					// Completely opaque, so copy RGB values over
-					rDest = rSrc;
-					gDest = gSrc;
-					bDest = bSrc;
-				}
-				else {
-					// Partially transparent, so calculate new pixel colors
-					alpha = (double)aSrc / 255.0;
-					rDest = static_cast<byte>((rSrc * alpha) + (rDest * (1.0 - alpha)));
-					gDest = static_cast<byte>((gSrc * alpha) + (gDest * (1.0 - alpha)));
-					bDest = static_cast<byte>((bSrc * alpha) + (bDest * (1.0 - alpha)));
-				}
-
-				destLine[xCtr] = destFormat.ARGBToColor(0xff, rDest, gDest, bDest);
+				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, srcAlpha, palette);
 			}
 		}
 	}
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index 290b04aba4..40d66f2731 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -299,7 +299,7 @@ public:
 	 * Copies another surface into this one ignoring pixels of a designated transparent color
 	 * @param src			Source surface
 	 * @param destPos		Destination position to draw the surface
-	 * @param mask			Mask definition (0-skip, other-copy)
+	 * @param mask			Mask definition
 	 */
 	void transBlitFrom(const Surface &src, const Common::Point &destPos,
 		const ManagedSurface &mask);
@@ -308,7 +308,7 @@ public:
 	 * Copies another surface into this one ignoring pixels of a designated transparent color
 	 * @param src			Source surface
 	 * @param destPos		Destination position to draw the surface
-	 * @param mask			Mask definition (0-skip, other-copy)
+	 * @param mask			Mask definition
 	 */
 	void transBlitFrom(const Surface &src, const Common::Point &destPos,
 		const Surface &mask);
@@ -323,8 +323,6 @@ public:
 	 * @param overrideColor	Optional color to use instead of non-transparent pixels from
 	 *						the source surface
 	 * @param srcAlpha		Optional additional transparency applied to src
-	 * @param mask			Optional parameter with mask definition (0-skip, other-copy)
-	 * @param maskOnly		Optional parameter for using mask over transColor
 	 */
 	void transBlitFrom(const Surface &src, const Common::Rect &srcRect, const Common::Point &destPos,
 		uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff);
@@ -340,7 +338,7 @@ public:
 	 * @param overrideColor	Optional color to use instead of non-transparent pixels from
 	 *						the source surface
 	 * @param srcAlpha		Optional additional transparency applied to src
-	 * @param mask			Optional parameter with mask definition (0-skip, other-copy)
+	 * @param mask			Optional parameter with mask definition
 	 * @param maskOnly		Optional parameter for using mask over transColor
 	 */
 	void transBlitFrom(const Surface &src, const Common::Rect &srcRect, const Common::Rect &destRect,
@@ -376,7 +374,7 @@ public:
 	 * Copies another surface into this one ignoring pixels of a designated transparent color
 	 * @param src			Source surface
 	 * @param destPos		Destination position to draw the surface
-	 * @param mask			Mask definition (0-skip, other-copy)
+	 * @param mask			Mask definition
 	 */
 	void transBlitFrom(const ManagedSurface &src, const Common::Point &destPos,
 		const ManagedSurface &mask);
@@ -406,6 +404,8 @@ public:
 	 * @param overrideColor	Optional color to use instead of non-transparent pixels from
 	 *						the source surface
 	 * @param srcAlpha		Optional additional transparency applied to src
+	 * @param mask			Optional parameter with mask definition
+	 * @param maskOnly		Optional parameter for using mask over transColor
 	 */
 	void transBlitFrom(const ManagedSurface &src, const Common::Rect &srcRect, const Common::Rect &destRect,
 		uint transColor = 0, bool flipped = false, uint overrideColor = 0, uint srcAlpha = 0xff,


Commit: 731596b5f7cb7b4839ca76d975affc9f8db17fa4
    https://github.com/scummvm/scummvm/commit/731596b5f7cb7b4839ca76d975affc9f8db17fa4
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2020-07-25T13:29:09+02:00

Commit Message:
GRAPHICS: Support converting between different palettes using ManagedSurface

Changed paths:
    graphics/managed_surface.cpp
    graphics/managed_surface.h


diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index 598e13861b..421acee135 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -321,7 +321,7 @@ void ManagedSurface::transBlitFrom(const Surface &src, const Common::Rect &srcRe
 		const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor, uint srcAlpha,
 		const Surface *mask, bool maskOnly) {
 	transBlitFromInner(src, srcRect, destRect, transColor, flipped, overrideColor, srcAlpha,
-		nullptr, mask, maskOnly);
+		nullptr, nullptr, mask, maskOnly);
 }
 
 void ManagedSurface::transBlitFrom(const ManagedSurface &src, uint transColor, bool flipped,
@@ -355,15 +355,53 @@ void ManagedSurface::transBlitFrom(const ManagedSurface &src, const Common::Rect
 		const Surface *mask, bool maskOnly) {
 	if (transColor == (uint)-1 && src._transparentColorSet)
 		transColor = src._transparentColor;
-	const uint32 *palette = src._paletteSet ? src._palette : nullptr;
+	const uint32 *srcPalette = src._paletteSet ? src._palette : nullptr;
+	const uint32 *dstPalette = _paletteSet ? _palette : nullptr;
 
 	transBlitFromInner(src._innerSurface, srcRect, destRect, transColor, flipped, overrideColor,
-		srcAlpha, palette, mask, maskOnly);
+		srcAlpha, srcPalette, dstPalette, mask, maskOnly);
+}
+
+static uint findBestColor(const uint32 *palette, byte cr, byte cg, byte cb) {
+	uint bestColor = 0;
+	double min = 0xFFFFFFFF;
+
+	for (uint i = 0; i < 256; ++i) {
+		uint col = palette[i];
+
+		int rmean = ((col & 0xff) + cr) / 2;
+		int r = (col & 0xff) - cr;
+		int g = ((col >> 8) & 0xff) - cg;
+		int b = ((col >> 16) & 0xff) - cb;
+
+		double dist = sqrt((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8));
+		if (min > dist) {
+			bestColor = i;
+			min = dist;
+		}
+	}
+
+	return bestColor;
+}
+
+static byte *createPaletteLookup(const uint32 *srcPalette, const uint32 *dstPalette) {
+	byte *lookup = new byte[256];
+
+	for (int i = 0; i < 256; i++) {
+		uint col = srcPalette[i];
+		if (col == dstPalette[i]) {
+			lookup[i] = i;
+		} else {
+			lookup[i] = findBestColor(dstPalette, col & 0xff, (col >> 8) & 0xff, (col >> 16) & 0xff);
+		}
+	}
+
+	return lookup;
 }
 
 template<typename TSRC, typename TDEST>
 void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &srcFormat, const Graphics::PixelFormat &destFormat,
-		uint overrideColor, uint srcAlpha, const uint32 *palette) {
+		uint overrideColor, uint srcAlpha, const uint32 *srcPalette, const byte *lookup) {
 	if (srcFormat == destFormat && srcAlpha == 0xff) {
 		// Matching formats, so we can do a straight copy
 		destVal = overrideColor ? overrideColor : srcVal;
@@ -373,10 +411,10 @@ void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &sr
 	// Otherwise we have to manually decode and re-encode each pixel
 	byte aSrc, rSrc, gSrc, bSrc;
 	if (srcFormat.bytesPerPixel == 1) {
-		assert(palette != nullptr);	// Catch the cases when palette is missing
+		assert(srcPalette != nullptr);	// Catch the cases when palette is missing
 
 		// Get the palette color
-		const uint32 col = palette[srcVal];
+		const uint32 col = srcPalette[srcVal];
 		rSrc = col & 0xff;
 		gSrc = (col >> 8) & 0xff;
 		bSrc = (col >> 16) & 0xff;
@@ -411,13 +449,31 @@ void transBlitPixel(TSRC srcVal, TDEST &destVal, const Graphics::PixelFormat &sr
 	destVal = destFormat.ARGBToColor(0xff, rDest, gDest, bDest);
 }
 
+template<>
+void transBlitPixel<byte, byte>(byte srcVal, byte &destVal, const Graphics::PixelFormat &srcFormat, const Graphics::PixelFormat &destFormat,
+		uint overrideColor, uint srcAlpha, const uint32 *srcPalette, const byte *lookup) {
+	if (srcAlpha == 0) {
+		// Completely transparent, so skip
+		return;
+	}
+
+	destVal = overrideColor ? overrideColor : srcVal;
+
+	if (lookup)
+		destVal = lookup[destVal];
+}
+
 template<typename TSRC, typename TDEST>
 void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, const Common::Rect &destRect,
-		TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *palette,
-		const Surface *mask, bool maskOnly) {
+		TSRC transColor, bool flipped, uint overrideColor, uint srcAlpha, const uint32 *srcPalette,
+		const uint32 *dstPalette, const Surface *mask, bool maskOnly) {
 	int scaleX = SCALE_THRESHOLD * srcRect.width() / destRect.width();
 	int scaleY = SCALE_THRESHOLD * srcRect.height() / destRect.height();
 
+	byte *lookup = nullptr;
+	if (srcPalette && dstPalette)
+		lookup = createPaletteLookup(srcPalette, dstPalette);
+
 	// Loop through drawing output lines
 	for (int destY = destRect.top, scaleYCtr = 0; destY < destRect.bottom; ++destY, scaleYCtr += scaleY) {
 		if (destY < 0 || destY >= dest.h)
@@ -444,22 +500,24 @@ void transBlit(const Surface &src, const Common::Rect &srcRect, Surface &dest, c
 				if (!mskVal)
 					continue;
 
-				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, mskVal, palette);
+				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, mskVal, srcPalette, lookup);
 			} else {
-				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, srcAlpha, palette);
+				transBlitPixel<TSRC, TDEST>(srcVal, destLine[xCtr], src.format, dest.format, overrideColor, srcAlpha, srcPalette, lookup);
 			}
 		}
 	}
+
+	delete lookup;
 }
 
 #define HANDLE_BLIT(SRC_BYTES, DEST_BYTES, SRC_TYPE, DEST_TYPE) \
 	if (src.format.bytesPerPixel == SRC_BYTES && format.bytesPerPixel == DEST_BYTES) \
-		transBlit<SRC_TYPE, DEST_TYPE>(src, srcRect, _innerSurface, destRect, transColor, flipped, overrideColor, srcAlpha, palette, mask, maskOnly); \
+		transBlit<SRC_TYPE, DEST_TYPE>(src, srcRect, _innerSurface, destRect, transColor, flipped, overrideColor, srcAlpha, srcPalette, dstPalette, mask, maskOnly); \
 	else
 
 void ManagedSurface::transBlitFromInner(const Surface &src, const Common::Rect &srcRect,
 		const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor,
-		uint srcAlpha, const uint32 *palette, const Surface *mask, bool maskOnly) {
+		uint srcAlpha, const uint32 *srcPalette, const uint32 *dstPalette, const Surface *mask, bool maskOnly) {
 	if (src.w == 0 || src.h == 0 || destRect.width() == 0 || destRect.height() == 0)
 		return;
 
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index 40d66f2731..c79122f31c 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -92,7 +92,7 @@ protected:
 	 */
 	void transBlitFromInner(const Surface &src, const Common::Rect &srcRect,
 		const Common::Rect &destRect, uint transColor, bool flipped, uint overrideColor,
-		uint srcAlpha, const uint32 *palette, const Surface *mask, bool maskOnly);
+		uint srcAlpha, const uint32 *srcPalette, const uint32 *dstPalette, const Surface *mask, bool maskOnly);
 public:
 	/**
 	 * Clips the given source bounds so the passed destBounds will be entirely on-screen


Commit: 80430b475691d64631498c682506955261df43ba
    https://github.com/scummvm/scummvm/commit/80430b475691d64631498c682506955261df43ba
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2020-07-25T13:29:09+02:00

Commit Message:
GRAPHICS: Ensure that creating a ManagedSurface from another preserves the palette

Changed paths:
    graphics/managed_surface.cpp
    graphics/screen.cpp


diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index 421acee135..23452e95a4 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -90,6 +90,12 @@ ManagedSurface &ManagedSurface::operator=(const ManagedSurface &surf) {
 		_innerSurface.h = surf.h;
 		_innerSurface.pitch = surf.pitch;
 		this->format = surf.format;
+
+		// Copy miscellaneous properties
+		_transparentColorSet = surf._transparentColorSet;
+		_transparentColor = surf._transparentColor;
+		_paletteSet = surf._paletteSet;
+		Common::copy(&surf._palette[0], &surf._palette[256], _palette);
 	}
 
 	return *this;
@@ -123,6 +129,12 @@ void ManagedSurface::create(ManagedSurface &surf, const Common::Rect &bounds) {
 	_innerSurface.h = bounds.height();
 	_owner = &surf;
 	_disposeAfterUse = DisposeAfterUse::NO;
+
+	// Copy miscellaneous properties
+	_transparentColorSet = surf._transparentColorSet;
+	_transparentColor = surf._transparentColor;
+	_paletteSet = surf._paletteSet;
+	Common::copy(&surf._palette[0], &surf._palette[256], _palette);
 }
 
 void ManagedSurface::free() {
@@ -568,12 +580,18 @@ void ManagedSurface::setPalette(const byte *colors, uint start, uint num) {
 	}
 
 	_paletteSet = true;
+
+	if (_owner)
+		_owner->setPalette(colors, start, num);
 }
 
 void ManagedSurface::setPalette(const uint32 *colors, uint start, uint num) {
 	assert(start < 256 && (start + num) <= 256);
 	Common::copy(colors, colors + num, &_palette[start]);
 	_paletteSet = true;
+
+	if (_owner)
+		_owner->setPalette(colors, start, num);
 }
 
 } // End of namespace Graphics
diff --git a/graphics/screen.cpp b/graphics/screen.cpp
index f55ed2057b..59ab767543 100644
--- a/graphics/screen.cpp
+++ b/graphics/screen.cpp
@@ -122,6 +122,7 @@ void Screen::setPalette(const byte palette[PALETTE_SIZE]) {
 void Screen::setPalette(const byte *palette, uint start, uint num) {
 	assert(format.bytesPerPixel == 1);
 	g_system->getPaletteManager()->setPalette(palette, start, num);
+	ManagedSurface::setPalette(palette, start, num);
 }
 
 void Screen::clearPalette() {




More information about the Scummvm-git-logs mailing list