[Scummvm-cvs-logs] scummvm master -> f5fa2edd220fca94d6b45e5cbc922cbdd5ec22f5

somaen einarjohants at gmail.com
Mon Sep 23 19:10:56 CEST 2013


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

Summary:
c0c3854fe2 WINTERMUTE: Match type of angle constant to struct in TransformStruct, silence warnings
b4161f54b6 WINTERMUTE: Add support for additive/subtractive blending in TransparentSurface
d6c21f8c1e WINTERMUTE: Pass blendMode to blit() in RenderTicket.
f5fa2edd22 WINTERMUTE: Remove asserts in Blend-functions in TransparentSurface.


Commit: c0c3854fe2bcdd7ec986c26edcce1c2d93797a19
    https://github.com/scummvm/scummvm/commit/c0c3854fe2bcdd7ec986c26edcce1c2d93797a19
Author: Tobia Tesan (tobia.tesan at gmail.com)
Date: 2013-09-23T10:05:58-07:00

Commit Message:
WINTERMUTE: Match type of angle constant to struct in TransformStruct, silence warnings

Changed paths:
    engines/wintermute/graphics/transform_struct.h



diff --git a/engines/wintermute/graphics/transform_struct.h b/engines/wintermute/graphics/transform_struct.h
index 702664a..2d98dc4 100644
--- a/engines/wintermute/graphics/transform_struct.h
+++ b/engines/wintermute/graphics/transform_struct.h
@@ -55,7 +55,7 @@ public:
 
 	Point32 _zoom;   ///< Zoom; 100 = no zoom
 	Point32 _hotspot; ///< Position of the hotspot
-	uint32 _angle;   ///< Rotation angle, in degrees
+	int32 _angle;   ///< Rotation angle, in degrees
 	byte _flip;      ///< Bitflag: see TransparentSurface::FLIP_XXX
 	bool _alphaDisable;
 	TSpriteBlendMode _blendMode;


Commit: b4161f54b6a7b99503ea2da1dab6e13523a504fe
    https://github.com/scummvm/scummvm/commit/b4161f54b6a7b99503ea2da1dab6e13523a504fe
Author: Tobia Tesan (tobia.tesan at gmail.com)
Date: 2013-09-23T10:06:32-07:00

Commit Message:
WINTERMUTE: Add support for additive/subtractive blending in TransparentSurface

Changed paths:
    engines/wintermute/graphics/transparent_surface.cpp
    engines/wintermute/graphics/transparent_surface.h



diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
index cd20035..4ba74b0 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -31,9 +31,262 @@
 
 namespace Wintermute {
 
+void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
+void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep);
+
+// These gather together various blendPixel functions for use with templates.
+
+class BlenderAdditive {
+public:
+	static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+	static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+	static void blendPixel(byte *in, byte *out);
+	static void blendPixel(byte *in, byte *out, int colorMod);
+};
+
+class BlenderSubtractive {
+public:
+	static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+	static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+	static void blendPixel(byte *in, byte *out);
+	static void blendPixel(byte *in, byte *out, int colorMod);
+};
+
+class BlenderNormal {
+public:
+	static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
+	static void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb);
+	static void blendPixel(byte *in, byte *out);
+	static void blendPixel(byte *in, byte *out, int colorMod);
+};
+
+/**
+ * Perform additive blending of a pixel, applying beforehand a given colormod.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ * @param *outa, *outr, *outg, *outb pointer to the colormod components.
+ */
+
+void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
+
+
+	assert(!(*cr == 255 && *ca == 255 && *cb == 255 && *cg == 255));
+	// Just use the faster, sans-colormod version
+
+	if (*ca != 255) {
+		ina = (ina) * (*ca) >> 8;
+	}
+
+	if (ina == 0) {
+		return;
+	} else {
+		if (*cb != 255)
+			*outb = MIN(*outb + ((inb * (*cb) * ina) >> 16), 255);
+		else
+			*outb = MIN(*outb + (inb * ina >> 8), 255);
+
+		if (*cg != 255)
+			*outg = MIN(*outg + ((ing * (*cg) * ina) >> 16), 255);
+		else
+			*outg = MIN(*outg + (ing * ina >> 8), 255);
+
+		if (*cr != 255)
+			*outr = MIN(*outr + ((inr * (*cr) * ina) >> 16), 255);
+		else
+			*outr = MIN(*outr + (inr * ina >> 8), 255);
+	}
+}
+
+/**
+ * Perform subtractive blending of a pixel, applying beforehand a given colormod.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ * @param *outa, *outr, *outg, *outb pointer to the colormod components.
+ */
+
+void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
+
+	assert(!(*cr == 255 && *ca == 255 && *cb == 255 && *cg == 255));
+	// Just use the faster, sans-colormod version
+
+	//if (*ca != 255) {
+	//	ina = ina * (*ca) >> 8;
+	// }
+
+	// As weird as it is, evidence suggests that alphamod is ignored when doing
+	// subtractive...
+
+	// TODO if ina == 255 fast version
+
+	if (ina == 0) {
+		return;
+	} else {
+		if (*cb != 255)
+			*outb = MAX(*outb - ((inb * (*cb)  * (*outb) * ina) >> 24), 0);
+		else
+			*outb = MAX(*outb - (inb * (*outb) * ina >> 16), 0);
+
+		if (*cg != 255)
+			*outg = MAX(*outg - ((ing * (*cg)  * (*outg) * ina) >> 24), 0);
+		else
+			*outg = MAX(*outg - (ing * (*outg) * ina >> 16), 0);
+
+		if (*cr != 255)
+			*outr = MAX(*outr - ((inr * (*cr) *  (*outr) * ina) >> 24), 0);
+		else
+			*outr = MAX(*outr - (inr * (*outr) * ina >> 16), 0);
+	}
+}
+
+/**
+ * Perform "regular" alphablending of a pixel, applying beforehand a given colormod.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ * @param *outa, *outr, *outg, *outb pointer to the colormod components.
+ */
+
+void BlenderNormal::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
+
+	assert(!(*cr == 255 && *ca == 255 && *cb == 255 && *cg == 255));
+	// Just use the faster, sans-colormod version
+
+	if (*ca != 255) {
+		ina = ina * (*ca) >> 8;
+	}
+
+	if (ina == 0) {
+		return;
+	} else if (ina == 255) {
+		if (*cb != 255)
+			*outb = (inb * (*cb)) >> 8;
+		else
+			*outb = inb;
+
+		if (*cr != 255)
+			*outr = (inr * (*cr)) >> 8;
+		else
+			*outr = inr;
+
+		if (*cg != 255)
+			*outg = (ing * (*cg)) >> 8;
+		else
+			*outg = ing;
+
+		*outa = ina;
+
+		return;
+
+	} else {
+
+		*outa = 255;
+		*outb = (*outb * (255 - ina) >> 8);
+		*outr = (*outr * (255 - ina) >> 8);
+		*outg = (*outg * (255 - ina) >> 8);
+
+		if (*cb == 0)
+			*outb = *outb;
+		else if (*cb != 255)
+			*outb = *outb + (inb * ina * (*cb) >> 16);
+		else
+			*outb = *outb + (inb * ina >> 8);
+
+		if (*cr == 0)
+			*outr = *outr;
+		else if (*cr != 255)
+			*outr = *outr + (inr * ina * (*cr) >> 16);
+		else
+			*outr = *outr + (inr * ina >> 8);
+
+		if (*cg == 0)
+			*outg = *outg;
+		else if (*cg != 255)
+			*outg = *outg + (ing * ina * (*cg) >> 16);
+		else
+			*outg = *outg + (ing * ina >> 8);
+
+		return;
+	}
+}
+
+/**
+ * Perform "regular" alphablending of a pixel.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ */
+
+void BlenderNormal::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
+
+	if (ina == 0) {
+		return;
+	} else if (ina == 255) {
+		*outb = inb;
+		*outg = ing;
+		*outr = inr;
+		*outa = ina;
+		return;
+	} else {
+		*outa = 255;
+		*outb = ((inb * ina) + *outb * (255 - ina)) >> 8;
+		*outg = ((ing * ina) + *outg * (255 - ina)) >> 8;
+		*outr = ((inr * ina) + *outr * (255 - ina)) >> 8;
+	}
+}
+
+/**
+ * Perform subtractive blending of a pixel.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ */
+
+void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
+
+	if (ina == 0) {
+		return;
+	} else if (ina == 255) {
+		*outa = *outa;
+		*outr = *outr - (inr * (*outr) >> 8);
+		*outg = *outg - (ing * (*outg) >> 8);
+		*outb = *outb - (inb * (*outb) >> 8);
+		return;
+	} else {
+		*outa = *outa;
+		*outb = MAX(*outb - ((inb * (*outb)) * ina >> 16), 0);
+		*outg = MAX(*outg - ((ing * (*outg)) * ina >> 16), 0);
+		*outr = MAX(*outr - ((inr * (*outr)) * ina >> 16), 0);
+		return;
+	}
+}
+
+/**
+ * Perform additive blending of a pixel.
+ * @param ina, inr, ing, inb: the input pixel, split into its components.
+ * @param *outa, *outr, *outg, *outb pointer to the output pixel.
+ */
+
+void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb) {
+
+	if (ina == 0) {
+		return;
+	} else if (ina == 255) {
+		*outa = *outa;
+		*outr = MIN(*outr + inr, 255);
+		*outg = MIN(*outg + ing, 255);
+		*outb = MIN(*outb + inb, 255);
+		return;
+	} else {
+		*outa = *outa;
+		*outb = MIN((inb * ina >> 8) + *outb, 255);
+		*outg = MIN((ing * ina >> 8) + *outg, 255);
+		*outr = MIN((inr * ina >> 8) + *outr, 255);
+		return;
+	}
+}
 
 #if ENABLE_BILINEAR
 void TransparentSurface::copyPixelBilinear(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst) {
+
+	// TODO: Do some optimization on this. This is completely naive.
+	
 	int srcW = srcRect.width();
 	int srcH = srcRect.height();
 	int dstW = dstRect.width();
@@ -106,20 +359,23 @@ void TransparentSurface::copyPixelBilinear(float projX, float projY, int dstX, i
 
 		for (int c = 0; c < 4; c++) {
 			dest[c] = (byte)(
-						  ((float)Q11s[c]) * q11x * q11y +
-						  ((float)Q21s[c]) * q21x * q21y +
-						  ((float)Q12s[c]) * q12x * q12y +
-						  ((float)Q22s[c]) * (1.0 -
-											  q11x * q11y -
-											  q21x * q21y -
-											  q12x * q12y)
-					  );
+			              ((float)Q11s[c]) * q11x * q11y +
+			              ((float)Q21s[c]) * q21x * q21y +
+			              ((float)Q12s[c]) * q12x * q12y +
+			              ((float)Q22s[c]) * (1.0 -
+			                                  q11x * q11y -
+			                                  q21x * q21y -
+			                                  q12x * q12y)
+			          );
 		}
 	}
 	WRITE_UINT32((byte *)dst->getBasePtr(dstX + dstRect.left, dstY + dstRect.top), color);
 }
 #else
 void TransparentSurface::copyPixelNearestNeighbor(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst) {
+
+	// TODO: Have the Rect arguments become completely useless at this point?
+
 	int srcW = srcRect.width();
 	int srcH = srcRect.height();
 	int dstW = dstRect.width();
@@ -157,21 +413,19 @@ TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Sur
 	}
 }
 
-void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
-	byte *in, *out;
-
-#ifdef SCUMM_LITTLE_ENDIAN
-	const int aIndex = 0;
-#else
-	const int aIndex = 3;
-#endif
+void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+/**
+ * Optimized version of doBlit to be used w/opaque blitting (no alpha).
+ */
+	byte *in;
+	byte *out;
 
 	for (uint32 i = 0; i < height; i++) {
 		out = outo;
 		in = ino;
 		memcpy(out, in, width * 4);
 		for (uint32 j = 0; j < width; j++) {
-			out[aIndex] = 0xFF;
+			out[TransparentSurface::kAIndex] = 0xFF;
 			out += 4;
 		}
 		outo += pitch;
@@ -179,112 +433,111 @@ void doBlitOpaque(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pit
 	}
 }
 
-void doBlitBinary(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
-	byte *in, *out;
-	
-#ifdef SCUMM_LITTLE_ENDIAN
-	const int aIndex = 0;
-#else
-	const int aIndex = 3;
-#endif
-	const int aShift = 0;//img->format.aShift;
+/**
+ * Optimized version of doBlit to be used w/binary blitting (blit or no-blit, no blending).
+ */
+
+void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
+
+	byte *in;
+	byte *out;
 
 	for (uint32 i = 0; i < height; i++) {
 		out = outo;
 		in = ino;
 		for (uint32 j = 0; j < width; j++) {
 			uint32 pix = *(uint32 *)in;
-			int a = (pix >> aShift) & 0xff;
-			in += inStep;
+			int a = (pix >> TransparentSurface::kAShift) & 0xff;
 
 			if (a == 0) { // Full transparency
-				out += 4;
 			} else { // Full opacity (Any value not exactly 0 is Opaque here)
 				*(uint32 *)out = pix;
-				out[aIndex] = 0xFF;
-				out += 4;
+				out[TransparentSurface::kAIndex] = 0xFF;
 			}
+			out += 4;
+			in += inStep;
 		}
 		outo += pitch;
 		ino += inoStep;
 	}
 }
 
-void doBlitAlpha(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep) {
-	byte *in, *out;
+/**
+ * What we have here is a template method that calls blendPixel() from a different
+ * class - the one we call it with - thus performing a different type of blending.
+ *
+ * @param *ino a pointer to the input surface
+ * @param *outo a pointer to the output surface
+ * @param width width of the input surface
+ * @param height height of the input surface
+ * @param pitch pitch of the output surface - that is, width in bytes of every row, usually bpp * width of the TARGET surface (the area we are blitting to might be smaller, do the math)
+ * @inStep size in bytes to skip to address each pixel, usually bpp of the source surface
+ * @inoStep width in bytes of every row on the *input* surface / kind of like pitch
+ * @color colormod in 0xAARRGGBB format - 0xFFFFFFFF for no colormod
+ */
 
-#ifdef SCUMM_LITTLE_ENDIAN
-	const int aIndex = 0;
-	const int bIndex = 1;
-	const int gIndex = 2;
-	const int rIndex = 3;
-#else
-	const int aIndex = 3;
-	const int bIndex = 2;
-	const int gIndex = 1;
-	const int rIndex = 0;
-#endif
+template<class Blender> 
+void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
 
-	const int bShift = 8;//img->format.bShift;
-	const int gShift = 16;//img->format.gShift;
-	const int rShift = 24;//img->format.rShift;
-	const int aShift = 0;//img->format.aShift;
+	byte *in;
+	byte *out;
 
-	const int bShiftTarget = 8;//target.format.bShift;
-	const int gShiftTarget = 16;//target.format.gShift;
-	const int rShiftTarget = 24;//target.format.rShift;
+	if (color == 0xffffffff) {
 
-	for (uint32 i = 0; i < height; i++) {
-		out = outo;
-		in = ino;
-		for (uint32 j = 0; j < width; j++) {
-			uint32 pix = *(uint32 *)in;
-			uint32 oPix = *(uint32 *) out;
-			int b = (pix >> bShift) & 0xff;
-			int g = (pix >> gShift) & 0xff;
-			int r = (pix >> rShift) & 0xff;
-			int a = (pix >> aShift) & 0xff;
-			int outb, outg, outr, outa;
-			in += inStep;
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
 
-			switch (a) {
-				case 0: // Full transparency
-					out += 4;
-					break;
-				case 255: // Full opacity
-					outb = b;
-					outg = g;
-					outr = r;
-					outa = a;
-
-					out[aIndex] = outa;
-					out[bIndex] = outb;
-					out[gIndex] = outg;
-					out[rIndex] = outr;
-					out += 4;
-					break;
-
-				default: // alpha blending
-					outa = 255;
-					outb = ((b * a) + ((oPix >> bShiftTarget) & 0xff) * (255-a)) >> 8;
-					outg = ((g * a) + ((oPix >> gShiftTarget) & 0xff) * (255-a)) >> 8;
-					outr = ((r * a) + ((oPix >> rShiftTarget) & 0xff) * (255-a)) >> 8;
-
-					out[aIndex] = outa;
-					out[bIndex] = outb;
-					out[gIndex] = outg;
-					out[rIndex] = outr;
-					out += 4;
+				byte *outa = &out[TransparentSurface::kAIndex];
+				byte *outr = &out[TransparentSurface::kRIndex];
+				byte *outg = &out[TransparentSurface::kGIndex];
+				byte *outb = &out[TransparentSurface::kBIndex];
+
+				Blender::blendPixel(in[TransparentSurface::kAIndex],
+					in[TransparentSurface::kRIndex],
+					in[TransparentSurface::kGIndex],
+					in[TransparentSurface::kBIndex],
+					outa, outr, outg, outb);
+
+				in += inStep;
+				out += 4;
 			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	} else {
+
+		byte ca = (color >> TransparentSurface::kAModShift) & 0xFF;
+		byte cr = (color >> TransparentSurface::kRModShift) & 0xFF;
+		byte cg = (color >> TransparentSurface::kGModShift) & 0xFF;
+		byte cb = (color >> TransparentSurface::kBModShift) & 0xFF;
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				byte *outa = &out[TransparentSurface::kAIndex];
+				byte *outr = &out[TransparentSurface::kRIndex];
+				byte *outg = &out[TransparentSurface::kGIndex];
+				byte *outb = &out[TransparentSurface::kBIndex];
+
+				Blender::blendPixel(in[TransparentSurface::kAIndex],
+					in[TransparentSurface::kRIndex],
+					in[TransparentSurface::kGIndex],
+					in[TransparentSurface::kBIndex],
+					outa, outr, outg, outb, &ca, &cr, &cg, &cb);
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
 		}
-		outo += pitch;
-		ino += inoStep;
 	}
 }
 
-
-Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int posY, int flipping, Common::Rect *pPartRect, uint color, int width, int height) {
-	int ca = (color >> 24) & 0xff;
+Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int posY, int flipping, Common::Rect *pPartRect, uint color, int width, int height, TSpriteBlendMode blendMode) {
 
 	Common::Rect retSize;
 	retSize.top = 0;
@@ -292,13 +545,11 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
 	retSize.setWidth(0);
 	retSize.setHeight(0);
 	// Check if we need to draw anything at all
+	int ca = (color >> 24) & 0xff;
+
 	if (ca == 0)
 		return retSize;
 
-	int cr = (color >> 16) & 0xff;
-	int cg = (color >> 8) & 0xff;
-	int cb = (color >> 0) & 0xff;
-
 	// Create an encapsulating surface for the data
 	TransparentSurface srcImage(*this, false);
 	// TODO: Is the data really in the screen format?
@@ -325,11 +576,11 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
 		srcImage.h = pPartRect->height();
 
 		debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping,
-			  pPartRect->left,  pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height);
+		      pPartRect->left,  pPartRect->top, pPartRect->width(), pPartRect->height(), color, width, height);
 	} else {
 
 		debug(6, "Blit(%d, %d, %d, [%d, %d, %d, %d], %08x, %d, %d)", posX, posY, flipping, 0, 0,
-			  srcImage.w, srcImage.h, color, width, height);
+		      srcImage.w, srcImage.h, color, width, height);
 	}
 
 	if (width == -1)
@@ -385,117 +636,24 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
 			yp = img->h - 1;
 		}
 
-		byte *ino = (byte *)img->getBasePtr(xp, yp);
+		byte *ino= (byte *)img->getBasePtr(xp, yp);
 		byte *outo = (byte *)target.getBasePtr(posX, posY);
-		byte *in, *out;
-
-#ifdef SCUMM_LITTLE_ENDIAN
-		const int aIndex = 0;
-		const int bIndex = 1;
-		const int gIndex = 2;
-		const int rIndex = 3;
-#else
-		const int aIndex = 3;
-		const int bIndex = 2;
-		const int gIndex = 1;
-		const int rIndex = 0;
-#endif
 
-		const int bShift = 8;//img->format.bShift;
-		const int gShift = 16;//img->format.gShift;
-		const int rShift = 24;//img->format.rShift;
-		const int aShift = 0;//img->format.aShift;
-
-		const int bShiftTarget = 8;//target.format.bShift;
-		const int gShiftTarget = 16;//target.format.gShift;
-		const int rShiftTarget = 24;//target.format.rShift;
-
-		if (ca == 255 && cb == 255 && cg == 255 && cr == 255) {
-			if (_alphaMode == ALPHA_FULL) {
-				doBlitAlpha(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
-			} else if (_alphaMode == ALPHA_BINARY) {
-				doBlitBinary(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
-			} else if (_alphaMode == ALPHA_OPAQUE) {
-				doBlitOpaque(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
-			}
+		if (color == 0xFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_OPAQUE) {
+			doBlitOpaqueFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+		} else if (color == 0xFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_BINARY) {
+			doBlitBinaryFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
 		} else {
-			for (int i = 0; i < img->h; i++) {
-				out = outo;
-				in = ino;
-				for (int j = 0; j < img->w; j++) {
-					uint32 pix = *(uint32 *)in;
-					uint32 o_pix = *(uint32 *) out;
-					int b = (pix >> bShift) & 0xff;
-					int g = (pix >> gShift) & 0xff;
-					int r = (pix >> rShift) & 0xff;
-					int a = (pix >> aShift) & 0xff;
-					int outb, outg, outr, outa;
-					in += inStep;
-
-					if (ca != 255) {
-						a = a * ca >> 8;
-					}
-					switch (a) {
-					case 0: // Full transparency
-						out += 4;
-						break;
-					case 255: // Full opacity
-						if (cb != 255)
-							outb = (b * cb) >> 8;
-						else
-							outb = b;
-
-						if (cg != 255)
-							outg = (g * cg) >> 8;
-						else
-							outg = g;
-
-						if (cr != 255)
-							outr = (r * cr) >> 8;
-						else
-							outr = r;
-						outa = a;
-						out[aIndex] = outa;
-						out[bIndex] = outb;
-						out[gIndex] = outg;
-						out[rIndex] = outr;
-						out += 4;
-						break;
-
-					default: // alpha blending
-						outa = 255;
-						outb = ((o_pix >> bShiftTarget) & 0xff) * (255 - a);
-						outg = ((o_pix >> gShiftTarget) & 0xff) * (255 - a);
-						outr = ((o_pix >> rShiftTarget) & 0xff) * (255 - a);
-						if (cb == 0)
-							outb = outb >> 8;
-						else if (cb != 255)
-							outb = ((outb<<8) + b * a * cb) >> 16;
-						else
-							outb = (outb + b * a) >> 8;
-						if (cg == 0)
-							outg = outg >> 8;
-						else if (cg != 255)
-							outg = ((outg<<8) + g * a * cg) >> 16;
-						else
-							outg = (outg + g * a) >> 8;
-						if (cr == 0)
-							outr = outr >> 8;
-						else if (cr != 255)
-							outr = ((outr<<8) + r * a * cr) >> 16;
-						else
-							outr = (outr + r * a) >> 8;
-						out[aIndex] = outa;
-						out[bIndex] = outb;
-						out[gIndex] = outg;
-						out[rIndex] = outr;
-						out += 4;
-					}
-				}
-				outo += target.pitch;
-				ino += inoStep;
+			if (blendMode == BLEND_ADDITIVE) {
+				doBlit<BlenderAdditive>(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+			} else if (blendMode == BLEND_SUBTRACTIVE) {
+				doBlit<BlenderSubtractive>(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+			} else {
+				assert(blendMode == BLEND_NORMAL);
+				doBlit<BlenderNormal>(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
 			}
 		}
+
 	}
 
 	retSize.setWidth(img->w);
@@ -555,6 +713,7 @@ TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transfo
 }
 
 TransparentSurface *TransparentSurface::scale(uint16 newWidth, uint16 newHeight) const {
+
 	Common::Rect srcRect(0, 0, (int16)w, (int16)h);
 	Common::Rect dstRect(0, 0, (int16)newWidth, (int16)newHeight);
 
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index 598aaa5..821b5c5 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -54,8 +54,28 @@ struct TransparentSurface : public Graphics::Surface {
 	void disableColorKey();
 
 #if ENABLE_BILINEAR
+	/*
+	 * Pick color from a point in source and copy it to a pixel in target.
+	 * The point in the source can be a float - we have subpixel accuracy in the arguments.
+	 * We do bilinear interpolation to estimate the color of the point even if the 
+	 * point is specuified w/subpixel accuracy.
+	 *
+	 * @param projX, projY, point in the source to pick color from.
+	 * @param dstX, dstY destionation pixel
+	 * @param *src, *dst pointer to the source and dest surfaces
+	 */
 	static void copyPixelBilinear(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst);
 #else
+	/*
+	 * Pick color from a point in source and copy it to a pixel in target.
+	 * The point in the source can be a float - we have subpixel accuracy in the arguments.
+	 * HOWEVER, this particular function just does nearest neighbor.
+	 * Use copyPixelBilinear if you interpolation.
+	 *
+	 * @param projX, projY, point in the source to pick color from.
+	 * @param dstX, dstY destionation pixel
+	 * @param *src, *dst pointer to the source and dest surfaces
+	 */
 	static void copyPixelNearestNeighbor(float projX, float projY, int dstX, int dstY, const Common::Rect &srcRect, const Common::Rect &dstRect, const TransparentSurface *src, TransparentSurface *dst);
 #endif
 	// Enums
@@ -63,26 +83,50 @@ struct TransparentSurface : public Graphics::Surface {
 	 @brief The possible flipping parameters for the blit methode.
 	 */
 	enum FLIP_FLAGS {
-		/// The image will not be flipped.
-		FLIP_NONE = 0,
-		/// The image will be flipped at the horizontal axis.
-		FLIP_H = 1,
-		/// The image will be flipped at the vertical axis.
-		FLIP_V = 2,
-		/// The image will be flipped at the horizontal and vertical axis.
-		FLIP_HV = FLIP_H | FLIP_V,
-		/// The image will be flipped at the horizontal and vertical axis.
-		FLIP_VH = FLIP_H | FLIP_V
+	    /// The image will not be flipped.
+	    FLIP_NONE = 0,
+	    /// The image will be flipped at the horizontal axis.
+	    FLIP_H = 1,
+	    /// The image will be flipped at the vertical axis.
+	    FLIP_V = 2,
+	    /// The image will be flipped at the horizontal and vertical axis.
+	    FLIP_HV = FLIP_H | FLIP_V,
+	    /// The image will be flipped at the horizontal and vertical axis.
+	    FLIP_VH = FLIP_H | FLIP_V
 	};
 
 	enum AlphaType {
-		ALPHA_OPAQUE = 0,
-		ALPHA_BINARY = 1,
-		ALPHA_FULL = 2
+	    ALPHA_OPAQUE = 0,
+	    ALPHA_BINARY = 1,
+	    ALPHA_FULL = 2
 	};
 
 	AlphaType _alphaMode;
 
+	#ifdef SCUMM_LITTLE_ENDIAN
+	static const int kAIndex = 0;
+	static const int kBIndex = 1;
+	static const int kGIndex = 2;
+	static const int kRIndex = 3;
+	#else
+	static const int kAIndex = 3;
+	static const int kBIndex = 2;
+	static const int kGIndex = 1;
+	static const int kRIndex = 0;
+	#endif
+
+	static const int kBShift = 8;//img->format.bShift;
+	static const int kGShift = 16;//img->format.gShift;
+	static const int kRShift = 24;//img->format.rShift;
+	static const int kAShift = 0;//img->format.aShift;
+
+
+	static const int kBModShift = 0;//img->format.bShift;
+	static const int kGModShift = 8;//img->format.gShift;
+	static const int kRModShift = 16;//img->format.rShift;
+	static const int kAModShift = 24;//img->format.aShift;
+
+
 	/**
 	 @brief renders the surface to another surface
 	 @param pDest a pointer to the target image. In most cases this is the framebuffer.
@@ -115,10 +159,26 @@ struct TransparentSurface : public Graphics::Surface {
 	                  int flipping = FLIP_NONE,
 	                  Common::Rect *pPartRect = nullptr,
 	                  uint color = BS_ARGB(255, 255, 255, 255),
-	                  int width = -1, int height = -1);
+	                  int width = -1, int height = -1,
+	                  TSpriteBlendMode blend = BLEND_NORMAL);
 	void applyColorKey(uint8 r, uint8 g, uint8 b, bool overwriteAlpha = false);
-
+	
+	/**
+	 * @brief Scale function; this returns a transformed version of this surface after rotation and
+	 * scaling. Please do not use this if angle != 0, use rotoscale.
+	 *
+	 * @param transform a TransformStruct wrapping the required info. @see TransformStruct
+	 * 
+	 */
 	TransparentSurface *scale(uint16 newWidth, uint16 newHeight) const;
+
+	/**
+	 * @brief Rotoscale function; this returns a transformed version of this surface after rotation and
+	 * scaling. Please do not use this if angle == 0, use plain old scaling function.
+	 *
+	 * @param transform a TransformStruct wrapping the required info. @see TransformStruct
+	 * 
+	 */
 	TransparentSurface *rotoscale(const TransformStruct &transform) const;
 };
 
@@ -134,7 +194,6 @@ struct TransparentSurface : public Graphics::Surface {
     }
 };*/
 
-
 } // End of namespace Wintermute
 
 


Commit: d6c21f8c1e93842d7a1573fc72ce9528b6ed52b7
    https://github.com/scummvm/scummvm/commit/d6c21f8c1e93842d7a1573fc72ce9528b6ed52b7
Author: Tobia Tesan (tobia.tesan at gmail.com)
Date: 2013-09-23T10:06:57-07:00

Commit Message:
WINTERMUTE: Pass blendMode to blit() in RenderTicket.

Changed paths:
    engines/wintermute/base/gfx/osystem/render_ticket.cpp



diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index b1720c1..d79d5ba 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -132,7 +132,7 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
 			src._alphaMode = _owner->getAlphaType();
 		}
 	}
-	src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height());
+	src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height(), _transform._blendMode);
 	if (doDelete) {
 		delete clipRect;
 	}


Commit: f5fa2edd220fca94d6b45e5cbc922cbdd5ec22f5
    https://github.com/scummvm/scummvm/commit/f5fa2edd220fca94d6b45e5cbc922cbdd5ec22f5
Author: Einar Johan Trøan Sømåen (einarjohants at gmail.com)
Date: 2013-09-23T10:07:24-07:00

Commit Message:
WINTERMUTE: Remove asserts in Blend-functions in TransparentSurface.

Changed paths:
    engines/wintermute/graphics/transparent_surface.cpp



diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
index 4ba74b0..411ff1f 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -68,11 +68,6 @@ public:
  */
 
 void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
-
-
-	assert(!(*cr == 255 && *ca == 255 && *cb == 255 && *cg == 255));
-	// Just use the faster, sans-colormod version
-
 	if (*ca != 255) {
 		ina = (ina) * (*ca) >> 8;
 	}
@@ -105,10 +100,6 @@ void BlenderAdditive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *o
  */
 
 void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
-
-	assert(!(*cr == 255 && *ca == 255 && *cb == 255 && *cg == 255));
-	// Just use the faster, sans-colormod version
-
 	//if (*ca != 255) {
 	//	ina = ina * (*ca) >> 8;
 	// }
@@ -146,10 +137,6 @@ void BlenderSubtractive::blendPixel(byte ina, byte inr, byte ing, byte inb, byte
  */
 
 void BlenderNormal::blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb, byte *ca, byte *cr, byte *cg, byte *cb) {
-
-	assert(!(*cr == 255 && *ca == 255 && *cb == 255 && *cg == 255));
-	// Just use the faster, sans-colormod version
-
 	if (*ca != 255) {
 		ina = ina * (*ca) >> 8;
 	}






More information about the Scummvm-git-logs mailing list