[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