[Scummvm-cvs-logs] scummvm master -> 1ebb8aa6debe7fab79bd058730ac07e360a7b486

sev- sev at scummvm.org
Sun Jun 15 20:16:04 CEST 2014


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

Summary:
215f5f9a49 WINTERMUTE: Speeding up blitting routines for TransparentSurface
7322d905b3 COMMON: Copy TransparentSurface from Wintermute engine to common code
385f8358ab WINTERMUTE: Switch to use of moved to OSystem TransparentSurface
5c706dde27 SWORD25: Switch to common TransparentSurface
1ebb8aa6de Merge pull request #466 from sev-/transparent-surface


Commit: 215f5f9a495c5072b398307bce12c940094b1d28
    https://github.com/scummvm/scummvm/commit/215f5f9a495c5072b398307bce12c940094b1d28
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2014-06-02T18:41:21+03:00

Commit Message:
WINTERMUTE: Speeding up blitting routines for 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 5fe0d13..b16ba0f 100644
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ b/engines/wintermute/graphics/transparent_surface.cpp
@@ -41,252 +41,31 @@
 
 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:
-	inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
-	inline 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);
-	inline void blendPixel(byte *in, byte *out);
-	inline void blendPixel(byte *in, byte *out, int colorMod);
-};
-
-class BlenderSubtractive {
-public:
-	inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
-	inline 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);
-	inline void blendPixel(byte *in, byte *out);
-	inline void blendPixel(byte *in, byte *out, int colorMod);
-};
-
-class BlenderNormal {
-public:
-	inline void blendPixel(byte ina, byte inr, byte ing, byte inb, byte *outa, byte *outr, byte *outg, byte *outb);
-	inline 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);
-	inline void blendPixel(byte *in, byte *out);
-	inline 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) {
-	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) {
-	//if (*ca != 255) {
-	//	ina = ina * (*ca) >> 8;
-	// }
-
-	// As weird as it is, evidence suggests that alphamod is ignored when doing
-	// subtractive...
+static const int kAShift = 0;//img->format.aShift;
 
-	// TODO if ina == 255 fast version
+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;
 
-	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);
-		}
+#ifdef SCUMM_LITTLE_ENDIAN
+static const int kAIndex = 0;
+static const int kBIndex = 1;
+static const int kGIndex = 2;
+static const int kRIndex = 3;
 
-		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) {
-	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;
-	}
-}
+#else
+static const int kAIndex = 3;
+static const int kBIndex = 2;
+static const int kGIndex = 1;
+static const int kRIndex = 0;
+#endif
 
+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);
+void doBlitAlphaBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
+void doBlitAdditiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
+void doBlitSubtractiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
 
 TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
 
@@ -318,7 +97,7 @@ void doBlitOpaqueFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
 		in = ino;
 		memcpy(out, in, width * 4);
 		for (uint32 j = 0; j < width; j++) {
-			out[TransparentSurface::kAIndex] = 0xFF;
+			out[kAIndex] = 0xFF;
 			out += 4;
 		}
 		outo += pitch;
@@ -339,12 +118,11 @@ void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
 		in = ino;
 		for (uint32 j = 0; j < width; j++) {
 			uint32 pix = *(uint32 *)in;
-			int a = (pix >> TransparentSurface::kAShift) & 0xff;
+			int a = (pix >> kAShift) & 0xff;
 
-			if (a == 0) { // Full transparency
-			} else { // Full opacity (Any value not exactly 0 is Opaque here)
+			if (a != 0) {   // Full opacity (Any value not exactly 0 is Opaque here)
 				*(uint32 *)out = pix;
-				out[TransparentSurface::kAIndex] = 0xFF;
+				out[kAIndex] = 0xFF;
 			}
 			out += 4;
 			in += inStep;
@@ -355,9 +133,7 @@ void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
 }
 
 /**
- * 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.
- *
+ * Optimized version of doBlit to be used with alpha blended blitting
  * @param ino a pointer to the input surface
  * @param outo a pointer to the output surface
  * @param width width of the input surface
@@ -367,10 +143,65 @@ void doBlitBinaryFast(byte *ino, byte *outo, uint32 width, uint32 height, uint32
  * @inoStep width in bytes of every row on the *input* surface / kind of like pitch
  * @color colormod in 0xAARRGGBB format - 0xFFFFFFFF for no colormod
  */
+void doBlitAlphaBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
+	byte *in;
+	byte *out;
 
-template<class Blender>
-void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
-	Blender b;
+	if (color == 0xffffffff) {
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				if (in[kAIndex] != 0) {
+					out[kAIndex] = 255;
+					out[kRIndex] = ((in[kRIndex] * in[kAIndex]) + out[kRIndex] * (255 - in[kAIndex])) >> 8;
+					out[kGIndex] = ((in[kGIndex] * in[kAIndex]) + out[kGIndex] * (255 - in[kAIndex])) >> 8;
+					out[kBIndex] = ((in[kBIndex] * in[kAIndex]) + out[kBIndex] * (255 - in[kAIndex])) >> 8;
+				}
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	} else {
+
+		byte ca = (color >> kAModShift) & 0xFF;
+		byte cr = (color >> kRModShift) & 0xFF;
+		byte cg = (color >> kGModShift) & 0xFF;
+		byte cb = (color >> kBModShift) & 0xFF;
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				uint32 ina = in[kAIndex] * ca >> 8;
+				out[kAIndex] = 255;
+				out[kBIndex] = (out[kBIndex] * (255 - ina) >> 8);
+				out[kGIndex] = (out[kGIndex] * (255 - ina) >> 8);
+				out[kRIndex] = (out[kRIndex] * (255 - ina) >> 8);
+
+				out[kBIndex] = out[kBIndex] + (in[kBIndex] * ina * cb >> 16);
+				out[kGIndex] = out[kGIndex] + (in[kGIndex] * ina * cg >> 16);
+				out[kRIndex] = out[kRIndex] + (in[kRIndex] * ina * cr >> 16);
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	}
+}
+
+/**
+ * Optimized version of doBlit to be used with additive blended blitting
+ */
+void doBlitAdditiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
 	byte *in;
 	byte *out;
 
@@ -381,16 +212,78 @@ void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, in
 			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];
+				if (in[kAIndex] != 0) {
+					out[kRIndex] = MIN((in[kRIndex] * in[kAIndex] >> 8) + out[kRIndex], 255);
+					out[kGIndex] = MIN((in[kGIndex] * in[kAIndex] >> 8) + out[kGIndex], 255);
+					out[kBIndex] = MIN((in[kBIndex] * in[kAIndex] >> 8) + out[kBIndex], 255);
+				}
 
-				b.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 >> kAModShift) & 0xFF;
+		byte cr = (color >> kRModShift) & 0xFF;
+		byte cg = (color >> kGModShift) & 0xFF;
+		byte cb = (color >> kBModShift) & 0xFF;
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				uint32 ina = in[kAIndex] * ca >> 8;
+
+				if (cb != 255) {
+					out[kBIndex] = MIN(out[kBIndex] + ((in[kBIndex] * cb * ina) >> 16), 255u);
+				} else {
+					out[kBIndex] = MIN(out[kBIndex] + (in[kBIndex] * ina >> 8), 255u);
+				}
+
+				if (cg != 255) {
+					out[kGIndex] = MIN(out[kGIndex] + ((in[kGIndex] * cg * ina) >> 16), 255u);
+				} else {
+					out[kGIndex] = MIN(out[kGIndex] + (in[kGIndex] * ina >> 8), 255u);
+				}
+
+				if (cr != 255) {
+					out[kRIndex] = MIN(out[kRIndex] + ((in[kRIndex] * cr * ina) >> 16), 255u);
+				} else {
+					out[kRIndex] = MIN(out[kRIndex] + (in[kRIndex] * ina >> 8), 255u);
+				}
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	}
+}
+
+/**
+ * Optimized version of doBlit to be used with subtractive blended blitting
+ */
+void doBlitSubtractiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
+	byte *in;
+	byte *out;
+
+	if (color == 0xffffffff) {
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				if (in[kAIndex] != 0) {
+					out[kRIndex] = MAX(out[kRIndex] - ((in[kRIndex] * out[kRIndex]) * in[kAIndex] >> 16), 0);
+					out[kGIndex] = MAX(out[kGIndex] - ((in[kGIndex] * out[kGIndex]) * in[kAIndex] >> 16), 0);
+					out[kBIndex] = MAX(out[kBIndex] - ((in[kBIndex] * out[kBIndex]) * in[kAIndex] >> 16), 0);
+				}
 
 				in += inStep;
 				out += 4;
@@ -400,26 +293,34 @@ void doBlit(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, in
 		}
 	} 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;
+		byte cr = (color >> kRModShift) & 0xFF;
+		byte cg = (color >> kGModShift) & 0xFF;
+		byte cb = (color >> 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];
+				out[kAIndex] = 255;
+				if (cb != 255) {
+					out[kBIndex] = MAX(out[kBIndex] - ((in[kBIndex] * cb  * (out[kBIndex]) * in[kAIndex]) >> 24), 0);
+				} else {
+					out[kBIndex] = MAX(out[kBIndex] - (in[kBIndex] * (out[kBIndex]) * in[kAIndex] >> 16), 0);
+				}
+
+				if (cg != 255) {
+					out[kGIndex] = MAX(out[kGIndex] - ((in[kGIndex] * cg  * (out[kGIndex]) * in[kAIndex]) >> 24), 0);
+				} else {
+					out[kGIndex] = MAX(out[kGIndex] - (in[kGIndex] * (out[kGIndex]) * in[kAIndex] >> 16), 0);
+				}
+
+				if (cr != 255) {
+					out[kRIndex] = MAX(out[kRIndex] - ((in[kRIndex] * cr * (out[kRIndex]) * in[kAIndex]) >> 24), 0);
+				} else {
+					out[kRIndex] = MAX(out[kRIndex] - (in[kRIndex] * (out[kRIndex]) * in[kAIndex] >> 16), 0);
+				}
 
-				b.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;
 			}
@@ -540,12 +441,12 @@ Common::Rect TransparentSurface::blit(Graphics::Surface &target, int posX, int p
 			doBlitBinaryFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
 		} else {
 			if (blendMode == BLEND_ADDITIVE) {
-				doBlit<BlenderAdditive>(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+				doBlitAdditiveBlend(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);
+				doBlitSubtractiveBlend(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);
+				doBlitAlphaBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
 			}
 		}
 
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
index 4ad9bf0..e5049a5 100644
--- a/engines/wintermute/graphics/transparent_surface.h
+++ b/engines/wintermute/graphics/transparent_surface.h
@@ -74,29 +74,6 @@ struct TransparentSurface : public Graphics::Surface {
 	    ALPHA_FULL = 2
 	};
 
-#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


Commit: 7322d905b37c222983e48219853aae105670e374
    https://github.com/scummvm/scummvm/commit/7322d905b37c222983e48219853aae105670e374
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2014-06-15T15:43:06+03:00

Commit Message:
COMMON: Copy TransparentSurface from Wintermute engine to common code

Changed paths:
  A graphics/transform_struct.cpp
  A graphics/transform_struct.h
  A graphics/transform_tools.cpp
  A graphics/transform_tools.h
  A graphics/transparent_surface.cpp
  A graphics/transparent_surface.h
    graphics/module.mk



diff --git a/graphics/module.mk b/graphics/module.mk
index 5918775..2705322 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -17,6 +17,9 @@ MODULE_OBJS := \
 	scaler/thumbnail_intern.o \
 	sjis.o \
 	surface.o \
+	transform_struct.o \
+	transform_tools.o \
+	transparent_surface.o \
 	thumbnail.o \
 	VectorRenderer.o \
 	VectorRendererSpec.o \
diff --git a/graphics/transform_struct.cpp b/graphics/transform_struct.cpp
new file mode 100644
index 0000000..a6beada
--- /dev/null
+++ b/graphics/transform_struct.cpp
@@ -0,0 +1,120 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "graphics/transform_struct.h"
+#include "graphics/transparent_surface.h"
+
+namespace Graphics {
+
+void TransformStruct::init(Common::Point zoom, uint32 angle, Common::Point hotspot, bool alphaDisable, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, Common::Point offset) {
+	_zoom = zoom;
+	_angle = angle;
+	_hotspot = hotspot;
+	_blendMode = blendMode;
+	_rgbaMod = rgbaMod;
+	_alphaDisable = alphaDisable;
+	_flip = 0;
+	_flip += FLIP_H * mirrorX;
+	_flip += FLIP_V * mirrorY;
+	_offset = offset;
+	_numTimesX = 1;
+	_numTimesY = 1;
+}
+
+TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
+	init(Common::Point(zoomX, zoomY),
+		angle,
+		Common::Point(hotspotX, hotspotY),
+		false,
+		blendMode,
+		rgbaMod,
+		mirrorX, mirrorY,
+		Common::Point(offsetX, offsetY));
+}
+
+TransformStruct::TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
+	init(Common::Point((int)(zoomX / 100.0 * kDefaultZoomX),
+		     (int)(zoomY / 100.0 * kDefaultZoomY)),
+		angle,
+		Common::Point(hotspotX, hotspotY),
+		false,
+		blendMode,
+		rgbaMod,
+		mirrorX, mirrorY,
+		Common::Point(offsetX, offsetY));
+}
+
+TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY) {
+	init(Common::Point(zoomX, zoomY),
+		kDefaultAngle,
+		Common::Point(kDefaultHotspotX, kDefaultHotspotY),
+		false,
+		blendMode,
+		rgbaMod,
+		mirrorX,
+		mirrorY,
+		Common::Point(kDefaultOffsetX, kDefaultOffsetY));
+}
+
+TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY) {
+	init(Common::Point(zoomX, zoomY),
+		angle,
+		Common::Point(hotspotX, hotspotY),
+		true,
+		BLEND_NORMAL,
+		kDefaultRgbaMod,
+		false, false,
+		Common::Point(kDefaultOffsetX, kDefaultOffsetY));
+}
+
+TransformStruct::TransformStruct(int32 numTimesX, int32 numTimesY) {
+	init(Common::Point(kDefaultZoomX, kDefaultZoomY),
+		kDefaultAngle,
+		Common::Point(kDefaultHotspotX, kDefaultHotspotY),
+		false,
+		BLEND_NORMAL,
+		kDefaultRgbaMod,
+		false, false,
+		Common::Point(kDefaultOffsetX, kDefaultOffsetY));
+	_numTimesX = numTimesX;
+	_numTimesY = numTimesY;
+}
+
+TransformStruct::TransformStruct() {
+	init(Common::Point(kDefaultZoomX, kDefaultZoomY),
+		kDefaultAngle,
+		Common::Point(kDefaultHotspotX, kDefaultHotspotY),
+		true,
+		BLEND_NORMAL,
+		kDefaultRgbaMod,
+		false, false,
+		Common::Point(kDefaultOffsetX, kDefaultOffsetY));
+}
+
+bool TransformStruct::getMirrorX() const {
+	return (bool)(_flip & FLIP_H);
+}
+
+bool TransformStruct::getMirrorY() const {
+	return (bool)(_flip & FLIP_V);
+}
+} // End of namespace Graphics
diff --git a/graphics/transform_struct.h b/graphics/transform_struct.h
new file mode 100644
index 0000000..640daf9
--- /dev/null
+++ b/graphics/transform_struct.h
@@ -0,0 +1,97 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GRAPHICS_TRANSFORM_STRUCT_H
+#define GRAPHICS_TRANSFORM_STRUCT_H
+
+#include "common/rect.h"
+
+namespace Graphics {
+
+enum TSpriteBlendMode {
+	BLEND_UNKNOWN       = -1,
+	BLEND_NORMAL        = 0,
+	BLEND_ADDITIVE      = 1,
+	BLEND_SUBTRACTIVE   = 2,
+	NUM_BLEND_MODES
+};
+
+/**
+ * Contains all the required information that define a transform.
+ * Same source sprite + same TransformStruct = Same resulting sprite.
+ * Has a number of overloaded constructors to accomodate various argument lists.
+ */
+
+const int32 kDefaultZoomX = 100;
+const int32 kDefaultZoomY = 100;
+const uint32 kDefaultRgbaMod = 0xFFFFFFFF;
+const int32 kDefaultHotspotX = 0;
+const int32 kDefaultHotspotY = 0;
+const int32 kDefaultOffsetX = 0;
+const int32 kDefaultOffsetY = 0;
+const int32 kDefaultAngle = 0;	
+
+struct TransformStruct {
+private:
+	void init(Common::Point zoom, uint32 angle, Common::Point hotspot, bool alphaDisable, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX, bool mirrorY, Common::Point offset);
+
+public:
+	TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false, int32 offsetX = 0, int32 offsetY = 0);
+	TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false, int32 offsetX = 0, int32 offsetY = 0);
+	TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false);
+	TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX = 0, int32 hotspotY = 0);
+	TransformStruct(int32 numTimesX, int32 numTimesY);
+	TransformStruct();
+
+	Common::Point _zoom;   ///< Zoom; 100 = no zoom
+	Common::Point _hotspot; ///< Position of the hotspot
+	int32 _angle;   ///< Rotation angle, in degrees
+	byte _flip;      ///< Bitflag: see TransparentSurface::FLIP_XXX
+	bool _alphaDisable;
+	TSpriteBlendMode _blendMode;
+	uint32 _rgbaMod;      ///< RGBa
+	Common::Point _offset;
+	int32 _numTimesX;
+	int32 _numTimesY;
+
+	bool getMirrorX() const;
+	bool getMirrorY() const;
+
+	bool operator==(const TransformStruct &compare) const {
+		return (compare._angle == _angle &&
+				compare._flip == _flip &&
+				compare._zoom == _zoom  &&
+				compare._offset == _offset &&
+				compare._alphaDisable == _alphaDisable  &&
+				compare._rgbaMod == _rgbaMod &&
+				compare._blendMode == _blendMode &&
+				compare._numTimesX == _numTimesX &&
+				compare._numTimesY == _numTimesY
+			   );
+	}
+
+	bool operator!=(const TransformStruct &compare) const {
+		return !(compare == *this);
+	}
+};
+} // End of namespace Graphics
+#endif
diff --git a/graphics/transform_tools.cpp b/graphics/transform_tools.cpp
new file mode 100644
index 0000000..6e87b63
--- /dev/null
+++ b/graphics/transform_tools.cpp
@@ -0,0 +1,87 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+
+#include "graphics/transform_tools.h"
+#include <math.h>
+
+namespace Graphics {
+
+FloatPoint TransformTools::transformPoint(FloatPoint point, const float rotate, const Common::Point &zoom, const bool mirrorX, const bool mirrorY) {
+	float rotateRad = rotate * M_PI / 180.0f;
+	float x = point.x;
+	float y = point.y;
+	x = (x * zoom.x) / kDefaultZoomX;
+	y = (y * zoom.y) / kDefaultZoomY;
+#if 0
+	// TODO: Mirroring should be done before rotation, but the blitting
+	// code does the inverse, so we match that for now.
+	if (mirrorX)
+		x *= -1;
+	if (mirrorY)
+		y *= -1;
+#endif
+	FloatPoint newPoint;
+	newPoint.x = x * cos(rotateRad) - y * sin(rotateRad);
+	newPoint.y = x * sin(rotateRad) + y * cos(rotateRad);
+	if (mirrorX) {
+		newPoint.x *= -1;
+	}
+	if (mirrorY) {
+		newPoint.y *= -1;
+	}
+	return newPoint;
+}
+
+Common::Rect TransformTools::newRect(const Common::Rect &oldRect, const TransformStruct &transform, Common::Point *newHotspot) {
+	Common::Point nw(oldRect.left, oldRect.top);
+	Common::Point ne(oldRect.right, oldRect.top);
+	Common::Point sw(oldRect.left, oldRect.bottom);
+	Common::Point se(oldRect.right, oldRect.bottom);
+
+	FloatPoint nw1, ne1, sw1, se1;
+
+	nw1 = transformPoint(nw - transform._hotspot, transform._angle, transform._zoom);
+	ne1 = transformPoint(ne - transform._hotspot, transform._angle, transform._zoom);
+	sw1 = transformPoint(sw - transform._hotspot, transform._angle, transform._zoom);
+	se1 = transformPoint(se - transform._hotspot, transform._angle, transform._zoom);
+
+	float top = MIN(nw1.y, MIN(ne1.y, MIN(sw1.y, se1.y)));
+	float bottom = MAX(nw1.y, MAX(ne1.y, MAX(sw1.y, se1.y)));
+	float left = MIN(nw1.x, MIN(ne1.x, MIN(sw1.x, se1.x)));
+	float right = MAX(nw1.x, MAX(ne1.x, MAX(sw1.x, se1.x)));
+
+	if (newHotspot) {
+		newHotspot->y = (uint32)(-floor(top));
+		newHotspot->x = (uint32)(-floor(left));
+	}
+
+	Common::Rect res;
+	res.top = (int32)(floor(top)) + transform._hotspot.y;
+	res.bottom = (int32)(ceil(bottom)) + transform._hotspot.y;
+	res.left = (int32)(floor(left)) + transform._hotspot.x;
+	res.right = (int32)(ceil(right)) + transform._hotspot.x;
+
+	return res;
+}
+
+} // End of namespace Graphics
diff --git a/graphics/transform_tools.h b/graphics/transform_tools.h
new file mode 100644
index 0000000..c618f7c
--- /dev/null
+++ b/graphics/transform_tools.h
@@ -0,0 +1,77 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GRAPHICS_TRANSFORM_TOOLS_H
+#define GRAPHICS_TRANSFORM_TOOLS_H
+
+#include "common/rect.h"
+#include "graphics/transform_struct.h"
+
+namespace Graphics {
+
+	static const float kEpsilon = 0.00001;  // arbitrarily taken number
+
+	struct FloatPoint {
+		float x;
+		float y;
+		FloatPoint() : x(0), y(0) {}
+		FloatPoint(float x1, float y1) : x(x1), y(y1) {}
+		FloatPoint(const Common::Point p) : x(p.x), y(p.y) {}
+		bool operator==(const FloatPoint &p) const { return fabs(x - p.x) < kEpsilon && fabs(y - p.y) < kEpsilon; }
+		bool operator!=(const FloatPoint  &p) const { return fabs(x - p.x) > kEpsilon || fabs(y - p.y) > kEpsilon; }
+		FloatPoint operator+(const FloatPoint &delta) const { return FloatPoint (x + delta.x, y + delta.y);     }
+		FloatPoint operator-(const FloatPoint &delta) const { return FloatPoint (x - delta.x, y - delta.y);     }
+
+		FloatPoint& operator+=(const FloatPoint &delta) {
+			x += delta.x;
+			y += delta.y;
+			return *this;
+		}
+		FloatPoint& operator-=(const FloatPoint &delta) {
+			x -= delta.x;
+			y -= delta.y;
+			return *this;
+		}
+	};
+
+class TransformTools {
+public:
+	/**
+	 * Basic transform (scale + rotate) for a single point
+	 */
+	static FloatPoint transformPoint(FloatPoint point, const float rotate, const Common::Point &zoom, const bool mirrorX = false, const bool mirrorY = false);
+
+	/**
+	 * @param &point the point on which the transform is to be applied
+	 * @param rotate the angle in degrees
+	 * @param &zoom  zoom x,y in percent
+	 * @param mirrorX flip along the vertical axis?
+	 * @param mirrorY flip along the horizontal axis?
+	 * @return the smallest rect that can contain the transformed sprite
+	 * and, as a side-effect, "newHotspot" will tell you where the hotspot will
+	 * have ended up in the new rect, for centering.
+	 */
+	static Common::Rect newRect(const Common::Rect &oldRect, const TransformStruct &transform, Common::Point *newHotspot);
+};
+
+} // End of namespace Wintermute
+#endif
diff --git a/graphics/transparent_surface.cpp b/graphics/transparent_surface.cpp
new file mode 100644
index 0000000..c2d334e
--- /dev/null
+++ b/graphics/transparent_surface.cpp
@@ -0,0 +1,851 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *
+ * The bottom part of this is file is adapted from SDL_rotozoom.c. The
+ * relevant copyright notice for those specific functions can be found at the
+ * top of that section.
+ *
+ */
+
+
+
+#include "common/algorithm.h"
+#include "common/endian.h"
+#include "common/util.h"
+#include "common/rect.h"
+#include "common/math.h"
+#include "common/textconsole.h"
+#include "graphics/primitives.h"
+#include "graphics/transparent_surface.h"
+#include "graphics/transform_tools.h"
+
+//#define ENABLE_BILINEAR
+
+namespace Graphics {
+
+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;
+
+#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
+
+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);
+void doBlitAlphaBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
+void doBlitAdditiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
+void doBlitSubtractiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
+
+TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
+
+TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _alphaMode(ALPHA_FULL) {
+	if (copyData) {
+		copyFrom(surf);
+	} else {
+		w = surf.w;
+		h = surf.h;
+		pitch = surf.pitch;
+		format = surf.format;
+		// We need to cast the const qualifier away here because 'pixels'
+		// always needs to be writable. 'surf' however is a constant Surface,
+		// thus getPixels will always return const pixel data.
+		pixels = const_cast<void *>(surf.getPixels());
+	}
+}
+
+/**
+ * Optimized version of doBlit to be used w/opaque blitting (no alpha).
+ */
+void doBlitOpaqueFast(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;
+		memcpy(out, in, width * 4);
+		for (uint32 j = 0; j < width; j++) {
+			out[kAIndex] = 0xFF;
+			out += 4;
+		}
+		outo += pitch;
+		ino += inoStep;
+	}
+}
+
+/**
+ * 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 >> kAShift) & 0xff;
+
+			if (a != 0) {   // Full opacity (Any value not exactly 0 is Opaque here)
+				*(uint32 *)out = pix;
+				out[kAIndex] = 0xFF;
+			}
+			out += 4;
+			in += inStep;
+		}
+		outo += pitch;
+		ino += inoStep;
+	}
+}
+
+/**
+ * Optimized version of doBlit to be used with alpha blended blitting
+ * @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
+ */
+void doBlitAlphaBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
+	byte *in;
+	byte *out;
+
+	if (color == 0xffffffff) {
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				if (in[kAIndex] != 0) {
+					out[kAIndex] = 255;
+					out[kRIndex] = ((in[kRIndex] * in[kAIndex]) + out[kRIndex] * (255 - in[kAIndex])) >> 8;
+					out[kGIndex] = ((in[kGIndex] * in[kAIndex]) + out[kGIndex] * (255 - in[kAIndex])) >> 8;
+					out[kBIndex] = ((in[kBIndex] * in[kAIndex]) + out[kBIndex] * (255 - in[kAIndex])) >> 8;
+				}
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	} else {
+
+		byte ca = (color >> kAModShift) & 0xFF;
+		byte cr = (color >> kRModShift) & 0xFF;
+		byte cg = (color >> kGModShift) & 0xFF;
+		byte cb = (color >> kBModShift) & 0xFF;
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				uint32 ina = in[kAIndex] * ca >> 8;
+				out[kAIndex] = 255;
+				out[kBIndex] = (out[kBIndex] * (255 - ina) >> 8);
+				out[kGIndex] = (out[kGIndex] * (255 - ina) >> 8);
+				out[kRIndex] = (out[kRIndex] * (255 - ina) >> 8);
+
+				out[kBIndex] = out[kBIndex] + (in[kBIndex] * ina * cb >> 16);
+				out[kGIndex] = out[kGIndex] + (in[kGIndex] * ina * cg >> 16);
+				out[kRIndex] = out[kRIndex] + (in[kRIndex] * ina * cr >> 16);
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	}
+}
+
+/**
+ * Optimized version of doBlit to be used with additive blended blitting
+ */
+void doBlitAdditiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
+	byte *in;
+	byte *out;
+
+	if (color == 0xffffffff) {
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				if (in[kAIndex] != 0) {
+					out[kRIndex] = MIN((in[kRIndex] * in[kAIndex] >> 8) + out[kRIndex], 255);
+					out[kGIndex] = MIN((in[kGIndex] * in[kAIndex] >> 8) + out[kGIndex], 255);
+					out[kBIndex] = MIN((in[kBIndex] * in[kAIndex] >> 8) + out[kBIndex], 255);
+				}
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	} else {
+
+		byte ca = (color >> kAModShift) & 0xFF;
+		byte cr = (color >> kRModShift) & 0xFF;
+		byte cg = (color >> kGModShift) & 0xFF;
+		byte cb = (color >> kBModShift) & 0xFF;
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				uint32 ina = in[kAIndex] * ca >> 8;
+
+				if (cb != 255) {
+					out[kBIndex] = MIN(out[kBIndex] + ((in[kBIndex] * cb * ina) >> 16), 255u);
+				} else {
+					out[kBIndex] = MIN(out[kBIndex] + (in[kBIndex] * ina >> 8), 255u);
+				}
+
+				if (cg != 255) {
+					out[kGIndex] = MIN(out[kGIndex] + ((in[kGIndex] * cg * ina) >> 16), 255u);
+				} else {
+					out[kGIndex] = MIN(out[kGIndex] + (in[kGIndex] * ina >> 8), 255u);
+				}
+
+				if (cr != 255) {
+					out[kRIndex] = MIN(out[kRIndex] + ((in[kRIndex] * cr * ina) >> 16), 255u);
+				} else {
+					out[kRIndex] = MIN(out[kRIndex] + (in[kRIndex] * ina >> 8), 255u);
+				}
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	}
+}
+
+/**
+ * Optimized version of doBlit to be used with subtractive blended blitting
+ */
+void doBlitSubtractiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
+	byte *in;
+	byte *out;
+
+	if (color == 0xffffffff) {
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				if (in[kAIndex] != 0) {
+					out[kRIndex] = MAX(out[kRIndex] - ((in[kRIndex] * out[kRIndex]) * in[kAIndex] >> 16), 0);
+					out[kGIndex] = MAX(out[kGIndex] - ((in[kGIndex] * out[kGIndex]) * in[kAIndex] >> 16), 0);
+					out[kBIndex] = MAX(out[kBIndex] - ((in[kBIndex] * out[kBIndex]) * in[kAIndex] >> 16), 0);
+				}
+
+				in += inStep;
+				out += 4;
+			}
+			outo += pitch;
+			ino += inoStep;
+		}
+	} else {
+
+		byte cr = (color >> kRModShift) & 0xFF;
+		byte cg = (color >> kGModShift) & 0xFF;
+		byte cb = (color >> kBModShift) & 0xFF;
+
+		for (uint32 i = 0; i < height; i++) {
+			out = outo;
+			in = ino;
+			for (uint32 j = 0; j < width; j++) {
+
+				out[kAIndex] = 255;
+				if (cb != 255) {
+					out[kBIndex] = MAX(out[kBIndex] - ((in[kBIndex] * cb  * (out[kBIndex]) * in[kAIndex]) >> 24), 0);
+				} else {
+					out[kBIndex] = MAX(out[kBIndex] - (in[kBIndex] * (out[kBIndex]) * in[kAIndex] >> 16), 0);
+				}
+
+				if (cg != 255) {
+					out[kGIndex] = MAX(out[kGIndex] - ((in[kGIndex] * cg  * (out[kGIndex]) * in[kAIndex]) >> 24), 0);
+				} else {
+					out[kGIndex] = MAX(out[kGIndex] - (in[kGIndex] * (out[kGIndex]) * in[kAIndex] >> 16), 0);
+				}
+
+				if (cr != 255) {
+					out[kRIndex] = MAX(out[kRIndex] - ((in[kRIndex] * cr * (out[kRIndex]) * in[kAIndex]) >> 24), 0);
+				} else {
+					out[kRIndex] = MAX(out[kRIndex] - (in[kRIndex] * (out[kRIndex]) * in[kAIndex] >> 16), 0);
+				}
+
+				in += inStep;
+				out += 4;
+			}
+			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, TSpriteBlendMode blendMode) {
+
+	Common::Rect retSize;
+	retSize.top = 0;
+	retSize.left = 0;
+	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;
+	}
+
+	// Create an encapsulating surface for the data
+	TransparentSurface srcImage(*this, false);
+	// TODO: Is the data really in the screen format?
+	if (format.bytesPerPixel != 4) {
+		warning("TransparentSurface can only blit 32bpp images, but got %d", format.bytesPerPixel * 8);
+		return retSize;
+	}
+
+	if (pPartRect) {
+
+		int xOffset = pPartRect->left;
+		int yOffset = pPartRect->top;
+
+		if (flipping & FLIP_V) {
+			yOffset = srcImage.h - pPartRect->bottom;
+		}
+
+		if (flipping & FLIP_H) {
+			xOffset = srcImage.w - pPartRect->right;
+		}
+
+		srcImage.pixels = getBasePtr(xOffset, yOffset);
+		srcImage.w = pPartRect->width();
+		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);
+	} 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);
+	}
+
+	if (width == -1) {
+		width = srcImage.w;
+	}
+	if (height == -1) {
+		height = srcImage.h;
+	}
+
+#ifdef SCALING_TESTING
+	// Hardcode scaling to 66% to test scaling
+	width = width * 2 / 3;
+	height = height * 2 / 3;
+#endif
+
+	Graphics::Surface *img = nullptr;
+	Graphics::Surface *imgScaled = nullptr;
+	byte *savedPixels = nullptr;
+	if ((width != srcImage.w) || (height != srcImage.h)) {
+		// Scale the image
+		img = imgScaled = srcImage.scale(width, height);
+		savedPixels = (byte *)img->getPixels();
+	} else {
+		img = &srcImage;
+	}
+
+	// Handle off-screen clipping
+	if (posY < 0) {
+		img->h = MAX(0, (int)img->h - -posY);
+		img->setPixels((byte *)img->getBasePtr(0, -posY));
+		posY = 0;
+	}
+
+	if (posX < 0) {
+		img->w = MAX(0, (int)img->w - -posX);
+		img->setPixels((byte *)img->getBasePtr(-posX, 0));
+		posX = 0;
+	}
+
+	img->w = CLIP((int)img->w, 0, (int)MAX((int)target.w - posX, 0));
+	img->h = CLIP((int)img->h, 0, (int)MAX((int)target.h - posY, 0));
+
+	if ((img->w > 0) && (img->h > 0)) {
+		int xp = 0, yp = 0;
+
+		int inStep = 4;
+		int inoStep = img->pitch;
+		if (flipping & FLIP_H) {
+			inStep = -inStep;
+			xp = img->w - 1;
+		}
+
+		if (flipping & FLIP_V) {
+			inoStep = -inoStep;
+			yp = img->h - 1;
+		}
+
+		byte *ino = (byte *)img->getBasePtr(xp, yp);
+		byte *outo = (byte *)target.getBasePtr(posX, posY);
+
+		if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_OPAQUE) {
+			doBlitOpaqueFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+		} else if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_BINARY) {
+			doBlitBinaryFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
+		} else {
+			if (blendMode == BLEND_ADDITIVE) {
+				doBlitAdditiveBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+			} else if (blendMode == BLEND_SUBTRACTIVE) {
+				doBlitSubtractiveBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+			} else {
+				assert(blendMode == BLEND_NORMAL);
+				doBlitAlphaBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
+			}
+		}
+
+	}
+
+	retSize.setWidth(img->w);
+	retSize.setHeight(img->h);
+
+	if (imgScaled) {
+		imgScaled->setPixels(savedPixels);
+		imgScaled->free();
+		delete imgScaled;
+	}
+
+	return retSize;
+}
+
+/**
+ * Writes a color key to the alpha channel of the surface
+ * @param rKey  the red component of the color key
+ * @param gKey  the green component of the color key
+ * @param bKey  the blue component of the color key
+ * @param overwriteAlpha if true, all other alpha will be set fully opaque
+ */
+void TransparentSurface::applyColorKey(uint8 rKey, uint8 gKey, uint8 bKey, bool overwriteAlpha) {
+	assert(format.bytesPerPixel == 4);
+	for (int i = 0; i < h; i++) {
+		for (int j = 0; j < w; j++) {
+			uint32 pix = ((uint32 *)pixels)[i * w + j];
+			uint8 r, g, b, a;
+			format.colorToARGB(pix, a, r, g, b);
+			if (r == rKey && g == gKey && b == bKey) {
+				a = 0;
+				((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
+			} else if (overwriteAlpha) {
+				a = 255;
+				((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
+			}
+		}
+	}
+}
+
+AlphaType TransparentSurface::getAlphaMode() const {
+	return _alphaMode;
+}
+
+void TransparentSurface::setAlphaMode(AlphaType mode) {
+	_alphaMode = mode;
+}
+
+
+
+
+
+
+/*
+
+The below two functions are adapted from SDL_rotozoom.c,
+taken from SDL_gfx-2.0.18.
+
+Its copyright notice:
+
+=============================================================================
+SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
+
+Copyright (C) 2001-2012  Andreas Schiffler
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+
+Andreas Schiffler -- aschiffler at ferzkopp dot net
+=============================================================================
+
+
+The functions have been adapted for different structures and coordinate
+systems.
+
+*/
+
+
+
+
+
+TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const {
+
+	assert(transform._angle != 0); // This would not be ideal; rotoscale() should never be called in conditional branches where angle = 0 anyway.
+
+	Common::Point newHotspot;
+	Common::Rect srcRect(0, 0, (int16)w, (int16)h);
+	Common::Rect rect = TransformTools::newRect(Common::Rect(srcRect), transform, &newHotspot);
+	Common::Rect dstRect(0, 0, (int16)(rect.right - rect.left), (int16)(rect.bottom - rect.top));
+
+	TransparentSurface *target = new TransparentSurface();
+	assert(format.bytesPerPixel == 4);
+
+	int srcW = w;
+	int srcH = h;
+	int dstW = dstRect.width();
+	int dstH = dstRect.height();
+
+	target->create((uint16)dstW, (uint16)dstH, this->format);
+
+	if (transform._zoom.x == 0 || transform._zoom.y == 0) {
+		return target;
+	}
+
+	uint32 invAngle = 360 - (transform._angle % 360);
+	float invCos = cos(invAngle * M_PI / 180.0);
+	float invSin = sin(invAngle * M_PI / 180.0);
+
+	struct tColorRGBA { byte r; byte g; byte b; byte a; };
+	int icosx = (int)(invCos * (65536.0f * kDefaultZoomX / transform._zoom.x));
+	int isinx = (int)(invSin * (65536.0f * kDefaultZoomX / transform._zoom.x));
+	int icosy = (int)(invCos * (65536.0f * kDefaultZoomY / transform._zoom.y));
+	int isiny = (int)(invSin * (65536.0f * kDefaultZoomY / transform._zoom.y));
+
+
+	bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
+
+	int xd = (srcRect.left + transform._hotspot.x) << 16;
+	int yd = (srcRect.top + transform._hotspot.y) << 16;
+	int cx = newHotspot.x;
+	int cy = newHotspot.y;
+
+	int ax = -icosx * cx;
+	int ay = -isiny * cx;
+	int sw = srcW - 1;
+	int sh = srcH - 1;
+
+	tColorRGBA *pc = (tColorRGBA*)target->getBasePtr(0, 0);
+
+	for (int y = 0; y < dstH; y++) {
+		int t = cy - y;
+		int sdx = ax + (isinx * t) + xd;
+		int sdy = ay - (icosy * t) + yd;
+		for (int x = 0; x < dstW; x++) {
+			int dx = (sdx >> 16);
+			int dy = (sdy >> 16);
+			if (flipx) {
+				dx = sw - dx;
+			}
+			if (flipy) {
+				dy = sh - dy;
+			}
+
+#ifdef ENABLE_BILINEAR
+			if ((dx > -1) && (dy > -1) && (dx < sw) && (dy < sh)) {
+				const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
+				tColorRGBA c00, c01, c10, c11, cswap;
+				c00 = *sp;
+				sp += 1;
+				c01 = *sp;
+				sp += (this->pitch / 4);
+				c11 = *sp;
+				sp -= 1;
+				c10 = *sp;
+				if (flipx) {
+					cswap = c00; c00=c01; c01=cswap;
+					cswap = c10; c10=c11; c11=cswap;
+				}
+				if (flipy) {
+					cswap = c00; c00=c10; c10=cswap;
+					cswap = c01; c01=c11; c11=cswap;
+				}
+				/*
+				* Interpolate colors
+				*/
+				int ex = (sdx & 0xffff);
+				int ey = (sdy & 0xffff);
+				int t1, t2;
+				t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
+				t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
+				pc->r = (((t2 - t1) * ey) >> 16) + t1;
+				t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
+				t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
+				pc->g = (((t2 - t1) * ey) >> 16) + t1;
+				t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
+				t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
+				pc->b = (((t2 - t1) * ey) >> 16) + t1;
+				t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
+				t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
+				pc->a = (((t2 - t1) * ey) >> 16) + t1;
+			}
+#else
+			if ((dx >= 0) && (dy >= 0) && (dx < srcW) && (dy < srcH)) {
+				const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
+				*pc = *sp;
+			}
+#endif
+			sdx += icosx;
+			sdy += isiny;
+			pc++;
+		}
+	}
+	return target;
+}
+
+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);
+
+	TransparentSurface *target = new TransparentSurface();
+
+	assert(format.bytesPerPixel == 4);
+
+	int srcW = srcRect.width();
+	int srcH = srcRect.height();
+	int dstW = dstRect.width();
+	int dstH = dstRect.height();
+
+	target->create((uint16)dstW, (uint16)dstH, this->format);
+
+#ifdef ENABLE_BILINEAR
+
+	// NB: The actual order of these bytes may not be correct, but
+	// since all values are treated equal, that does not matter.
+	struct tColorRGBA { byte r; byte g; byte b; byte a; };
+
+	bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
+
+
+	int *sax = new int[dstW + 1];
+	int *say = new int[dstH + 1];
+	assert(sax && say);
+
+	/*
+	* Precalculate row increments
+	*/
+	int spixelw = (srcW - 1);
+	int spixelh = (srcH - 1);
+	int sx = (int) (65536.0f * (float) spixelw / (float) (dstW - 1));
+	int sy = (int) (65536.0f * (float) spixelh / (float) (dstH - 1));
+
+	/* Maximum scaled source size */
+	int ssx = (srcW << 16) - 1;
+	int ssy = (srcH << 16) - 1;
+
+	/* Precalculate horizontal row increments */
+	int csx = 0;
+	int *csax = sax;
+	for (int x = 0; x <= dstW; x++) {
+		*csax = csx;
+		csax++;
+		csx += sx;
+
+		/* Guard from overflows */
+		if (csx > ssx) {
+			csx = ssx;
+		}
+	}
+
+	/* Precalculate vertical row increments */
+	int csy = 0;
+	int *csay = say;
+	for (int y = 0; y <= dstH; y++) {
+		*csay = csy;
+		csay++;
+		csy += sy;
+
+		/* Guard from overflows */
+		if (csy > ssy) {
+			csy = ssy;
+		}
+	}
+
+	const tColorRGBA *sp = (const tColorRGBA *) getBasePtr(0, 0);
+	tColorRGBA *dp = (tColorRGBA *) target->getBasePtr(0, 0);
+	int spixelgap = srcW;
+
+	if (flipx) {
+		sp += spixelw;
+	}
+	if (flipy) {
+		sp += spixelgap * spixelh;
+	}
+
+	csay = say;
+	for (int y = 0; y < dstH; y++) {
+		const tColorRGBA *csp = sp;
+		csax = sax;
+		for (int x = 0; x < dstW; x++) {
+			/*
+			* Setup color source pointers
+			*/
+			int ex = (*csax & 0xffff);
+			int ey = (*csay & 0xffff);
+			int cx = (*csax >> 16);
+			int cy = (*csay >> 16);
+
+			const tColorRGBA *c00, *c01, *c10, *c11;
+			c00 = sp;
+			c01 = sp;
+			c10 = sp;
+			if (cy < spixelh) {
+				if (flipy) {
+					c10 -= spixelgap;
+				} else {
+					c10 += spixelgap;
+				}
+			}
+			c11 = c10;
+			if (cx < spixelw) {
+				if (flipx) {
+					c01--;
+					c11--;
+				} else {
+					c01++;
+					c11++;
+				}
+			}
+
+			/*
+			* Draw and interpolate colors
+			*/
+			int t1, t2;
+			t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
+			t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
+			dp->r = (((t2 - t1) * ey) >> 16) + t1;
+			t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
+			t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
+			dp->g = (((t2 - t1) * ey) >> 16) + t1;
+			t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
+			t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
+			dp->b = (((t2 - t1) * ey) >> 16) + t1;
+			t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
+			t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
+			dp->a = (((t2 - t1) * ey) >> 16) + t1;
+
+			/*
+			* Advance source pointer x
+			*/
+			int *salastx = csax;
+			csax++;
+			int sstepx = (*csax >> 16) - (*salastx >> 16);
+			if (flipx) {
+				sp -= sstepx;
+			} else {
+				sp += sstepx;
+			}
+
+			/*
+			* Advance destination pointer x
+			*/
+			dp++;
+		}
+		/*
+		* Advance source pointer y
+		*/
+		int *salasty = csay;
+		csay++;
+		int sstepy = (*csay >> 16) - (*salasty >> 16);
+		sstepy *= spixelgap;
+		if (flipy) {
+			sp = csp - sstepy;
+		} else {
+			sp = csp + sstepy;
+		}
+	}
+
+	delete[] sax;
+	delete[] say;
+
+#else
+
+	int *scaleCacheX = new int[dstW];
+	for (int x = 0; x < dstW; x++) {
+		scaleCacheX[x] = (x * srcW) / dstW;
+	}
+
+	for (int y = 0; y < dstH; y++) {
+		uint32 *destP = (uint32 *)target->getBasePtr(0, y);
+		const uint32 *srcP = (const uint32 *)getBasePtr(0, (y * srcH) / dstH);
+		for (int x = 0; x < dstW; x++) {
+			*destP++ = srcP[scaleCacheX[x]];
+		}
+	}
+	delete[] scaleCacheX;
+
+#endif
+
+	return target;
+
+}
+
+} // End of namespace Graphics
diff --git a/graphics/transparent_surface.h b/graphics/transparent_surface.h
new file mode 100644
index 0000000..cc35f8e
--- /dev/null
+++ b/graphics/transparent_surface.h
@@ -0,0 +1,152 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef GRAPHICS_TRANSPARENTSURFACE_H
+#define GRAPHICS_TRANSPARENTSURFACE_H
+
+#include "graphics/surface.h"
+#include "graphics/transform_struct.h"
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+// TODO: Find a better solution for this.
+#define BS_RGB(R,G,B)       (0xFF000000 | ((R) << 16) | ((G) << 8) | (B))
+#define BS_ARGB(A,R,G,B)    (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
+
+namespace Graphics {
+
+// Enums
+/**
+ @brief The possible flipping parameters for the blit method.
+ */
+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
+};
+
+enum AlphaType {
+    ALPHA_OPAQUE = 0,
+    ALPHA_BINARY = 1,
+    ALPHA_FULL = 2
+};
+
+/**
+ * A transparent graphics surface, which implements alpha blitting.
+ */
+struct TransparentSurface : public Graphics::Surface {
+	TransparentSurface();
+	TransparentSurface(const Graphics::Surface &surf, bool copyData = false);
+
+	void setColorKey(char r, char g, char b);
+	void disableColorKey();
+
+	/**
+	 @brief renders the surface to another surface
+	 @param target a pointer to the target surface. In most cases this is the framebuffer.
+	 @param posX the position on the X-axis in the target image in pixels where the image is supposed to be rendered.<br>
+	 The default value is 0.
+	 @param posY the position on the Y-axis in the target image in pixels where the image is supposed to be rendered.<br>
+	 The default value is 0.
+	 @param flipping how the the image should be flipped.<br>
+	 The default value is BS_Image::FLIP_NONE (no flipping)
+	 @param pPartRect Pointer on Common::Rect which specifies the section to be rendered. If the whole image has to be rendered the Pointer is NULL.<br>
+	 This referes to the unflipped and unscaled image.<br>
+	 The default value is NULL.
+	 @param color an ARGB color value, which determines the parameters for the color modulation und alpha blending.<br>
+	 The alpha component of the color determines the alpha blending parameter (0 = no covering, 255 = full covering).<br>
+	 The color components determines the color for color modulation.<br>
+	 The default value is BS_ARGB(255, 255, 255, 255) (full covering, no color modulation).
+	 The macros BS_RGB and BS_ARGB can be used for the creation of the color value.
+	 @param width the output width of the screen section.
+	 The images will be scaled if the output width of the screen section differs from the image section.<br>
+	 The value -1 determines that the image should not be scaled.<br>
+	 The default value is -1.
+	 @param height the output height of the screen section.
+	 The images will be scaled if the output width of the screen section differs from the image section.<br>
+	 The value -1 determines that the image should not be scaled.<br>
+	 The default value is -1.
+	 @return returns false if the rendering failed.
+	 */
+	Common::Rect blit(Graphics::Surface &target, int posX = 0, int posY = 0,
+	                  int flipping = FLIP_NONE,
+	                  Common::Rect *pPartRect = nullptr,
+	                  uint color = BS_ARGB(255, 255, 255, 255),
+	                  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 newWidth the resulting width.
+	 * @param newHeight the resulting height.
+	 * @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;
+	AlphaType getAlphaMode() const;
+	void setAlphaMode(AlphaType);
+private:
+	AlphaType _alphaMode;
+
+};
+
+/**
+ * A deleter for Surface objects which can be used with SharedPtr.
+ *
+ * This deleter assures Surface::free is called on deletion.
+ */
+/*struct SharedPtrTransparentSurfaceDeleter {
+    void operator()(TransparentSurface *ptr) {
+        ptr->free();
+        delete ptr;
+    }
+};*/
+
+} // End of namespace Graphics
+
+
+#endif


Commit: 385f8358ab2ea138a39eb6fc76d246b3c5f48e45
    https://github.com/scummvm/scummvm/commit/385f8358ab2ea138a39eb6fc76d246b3c5f48e45
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2014-06-15T15:43:18+03:00

Commit Message:
WINTERMUTE: Switch to use of moved to OSystem TransparentSurface

Changed paths:
  R engines/wintermute/graphics/transform_struct.cpp
  R engines/wintermute/graphics/transform_struct.h
  R engines/wintermute/graphics/transform_tools.cpp
  R engines/wintermute/graphics/transform_tools.h
  R engines/wintermute/graphics/transparent_surface.cpp
  R engines/wintermute/graphics/transparent_surface.h
    engines/wintermute/base/base_frame.cpp
    engines/wintermute/base/base_frame.h
    engines/wintermute/base/base_object.cpp
    engines/wintermute/base/base_object.h
    engines/wintermute/base/base_persistence_manager.cpp
    engines/wintermute/base/base_sprite.cpp
    engines/wintermute/base/base_sprite.h
    engines/wintermute/base/base_sub_frame.cpp
    engines/wintermute/base/base_sub_frame.h
    engines/wintermute/base/font/base_font_truetype.cpp
    engines/wintermute/base/gfx/base_image.cpp
    engines/wintermute/base/gfx/base_surface.cpp
    engines/wintermute/base/gfx/base_surface.h
    engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
    engines/wintermute/base/gfx/osystem/base_render_osystem.h
    engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
    engines/wintermute/base/gfx/osystem/base_surface_osystem.h
    engines/wintermute/base/gfx/osystem/render_ticket.cpp
    engines/wintermute/base/gfx/osystem/render_ticket.h
    engines/wintermute/dctypes.h
    engines/wintermute/module.mk



diff --git a/engines/wintermute/base/base_frame.cpp b/engines/wintermute/base/base_frame.cpp
index f2c24b8..471185f 100644
--- a/engines/wintermute/base/base_frame.cpp
+++ b/engines/wintermute/base/base_frame.cpp
@@ -76,7 +76,7 @@ BaseFrame::~BaseFrame() {
 
 
 //////////////////////////////////////////////////////////////////////
-bool BaseFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, float zoomY, bool precise, uint32 alpha, bool allFrames, float rotate, TSpriteBlendMode blendMode) {
+bool BaseFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, float zoomY, bool precise, uint32 alpha, bool allFrames, float rotate, Graphics::TSpriteBlendMode blendMode) {
 	bool res;
 
 	for (uint32 i = 0; i < _subframes.size(); i++) {
diff --git a/engines/wintermute/base/base_frame.h b/engines/wintermute/base/base_frame.h
index 49a5659..ff9e67a 100644
--- a/engines/wintermute/base/base_frame.h
+++ b/engines/wintermute/base/base_frame.h
@@ -31,6 +31,7 @@
 
 #include "engines/wintermute/base/base_scriptable.h"
 #include "engines/wintermute/coll_templ.h"
+#include "graphics/transform_struct.h"
 
 namespace Wintermute {
 class BaseSound;
@@ -51,7 +52,7 @@ public:
 	int32 _moveX;
 	uint32 _delay;
 	BaseArray<BaseSubFrame *> _subframes;
-	bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, bool allFrames = false, float rotate = 0.0f, TSpriteBlendMode blendMode = BLEND_NORMAL);
+	bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, bool allFrames = false, float rotate = 0.0f, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL);
 	bool loadBuffer(char *buffer, int lifeTime, bool keepLoaded);
 
 	BaseFrame(BaseGame *inGame);
diff --git a/engines/wintermute/base/base_object.cpp b/engines/wintermute/base/base_object.cpp
index 708df8d..cce3561 100644
--- a/engines/wintermute/base/base_object.cpp
+++ b/engines/wintermute/base/base_object.cpp
@@ -95,7 +95,7 @@ BaseObject::BaseObject(BaseGame *inGame) : BaseScriptHolder(inGame) {
 	_sFXType = SFX_NONE;
 	_sFXParam1 = _sFXParam2 = _sFXParam3 = _sFXParam4 = 0;
 
-	_blendMode = BLEND_NORMAL;
+	_blendMode = Graphics::BLEND_NORMAL;
 }
 
 
@@ -807,10 +807,10 @@ bool BaseObject::scSetProperty(const char *name, ScValue *value) {
 	//////////////////////////////////////////////////////////////////////////
 	else if (strcmp(name, "BlendMode") == 0) {
 		int i = value->getInt();
-		if (i < BLEND_NORMAL || i >= NUM_BLEND_MODES) {
-			i = BLEND_NORMAL;
+		if (i < Graphics::BLEND_NORMAL || i >= Graphics::NUM_BLEND_MODES) {
+			i = Graphics::BLEND_NORMAL;
 		}
-		_blendMode = (TSpriteBlendMode)i;
+		_blendMode = (Graphics::TSpriteBlendMode)i;
 		return STATUS_OK;
 	}
 
diff --git a/engines/wintermute/base/base_object.h b/engines/wintermute/base/base_object.h
index f5036f4..8ca8ffc 100644
--- a/engines/wintermute/base/base_object.h
+++ b/engines/wintermute/base/base_object.h
@@ -33,6 +33,7 @@
 #include "engines/wintermute/base/base_script_holder.h"
 #include "engines/wintermute/persistent.h"
 #include "common/events.h"
+#include "graphics/transform_struct.h"
 
 namespace Wintermute {
 
@@ -75,7 +76,7 @@ protected:
 	int32 _iD;
 	char *_soundEvent;
 public:
-	TSpriteBlendMode _blendMode;
+	Graphics::TSpriteBlendMode _blendMode;
 	virtual bool afterMove();
 	float _scale;
 	uint32 _alphaColor;
diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp
index bea55fb..bb5e0c4 100644
--- a/engines/wintermute/base/base_persistence_manager.cpp
+++ b/engines/wintermute/base/base_persistence_manager.cpp
@@ -36,7 +36,7 @@
 #include "engines/wintermute/base/gfx/base_image.h"
 #include "engines/wintermute/base/save_thumb_helper.h"
 #include "engines/wintermute/base/sound/base_sound.h"
-#include "engines/wintermute/graphics/transparent_surface.h"
+#include "graphics/transparent_surface.h"
 #include "engines/wintermute/wintermute.h"
 #include "graphics/scaler.h"
 #include "image/bmp.h"
@@ -173,7 +173,7 @@ void BasePersistenceManager::getSaveStateDesc(int slot, SaveStateDescriptor &des
 		Image::BitmapDecoder bmpDecoder;
 		if (bmpDecoder.loadStream(thumbStream)) {
 			const Graphics::Surface *bmpSurface = bmpDecoder.getSurface();
-			TransparentSurface *scaleableSurface = new TransparentSurface(*bmpSurface, false);
+			Graphics::TransparentSurface *scaleableSurface = new Graphics::TransparentSurface(*bmpSurface, false);
 			Graphics::Surface *scaled = scaleableSurface->scale(kThumbnailWidth, kThumbnailHeight2);
 			Graphics::Surface *thumb = scaled->convertTo(g_system->getOverlayFormat());
 			desc.setThumbnail(thumb);
diff --git a/engines/wintermute/base/base_sprite.cpp b/engines/wintermute/base/base_sprite.cpp
index 2e00998..04060bf 100644
--- a/engines/wintermute/base/base_sprite.cpp
+++ b/engines/wintermute/base/base_sprite.cpp
@@ -418,7 +418,7 @@ bool BaseSprite::getCurrentFrame(float zoomX, float zoomY) {
 
 
 //////////////////////////////////////////////////////////////////////
-bool BaseSprite::display(int x, int y, BaseObject *registerVal, float zoomX, float zoomY, uint32 alpha, float rotate, TSpriteBlendMode blendMode) {
+bool BaseSprite::display(int x, int y, BaseObject *registerVal, float zoomX, float zoomY, uint32 alpha, float rotate, Graphics::TSpriteBlendMode blendMode) {
 	if (_currentFrame < 0 || _currentFrame >= (int32)_frames.size()) {
 		return STATUS_OK;
 	}
diff --git a/engines/wintermute/base/base_sprite.h b/engines/wintermute/base/base_sprite.h
index 9228799..ec71512 100644
--- a/engines/wintermute/base/base_sprite.h
+++ b/engines/wintermute/base/base_sprite.h
@@ -32,7 +32,7 @@
 
 #include "engines/wintermute/coll_templ.h"
 #include "engines/wintermute/base/base_script_holder.h"
-#include "engines/wintermute/graphics/transform_tools.h"
+#include "graphics/transform_tools.h"
 
 namespace Wintermute {
 class BaseFrame;
@@ -45,17 +45,17 @@ public:
 	void setDefaults();
 	DECLARE_PERSISTENT(BaseSprite, BaseScriptHolder)
 
-	bool getBoundingRect(Rect32 *rect, int x, int y, float scaleX = kDefaultZoomX, float scaleY = kDefaultZoomY);
+	bool getBoundingRect(Rect32 *rect, int x, int y, float scaleX = Graphics::kDefaultZoomX, float scaleY = Graphics::kDefaultZoomY);
 	int32 _moveY;
 	int32 _moveX;
-	bool display(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = kDefaultZoomX, float zoomY = kDefaultZoomY, uint32 alpha = kDefaultRgbaMod, float rotate = kDefaultAngle, TSpriteBlendMode blendMode = BLEND_NORMAL);
-	bool getCurrentFrame(float zoomX = kDefaultZoomX, float zoomY = kDefaultZoomY);
+	bool display(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = Graphics::kDefaultZoomX, float zoomY = Graphics::kDefaultZoomY, uint32 alpha = Graphics::kDefaultRgbaMod, float rotate = Graphics::kDefaultAngle, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL);
+	bool getCurrentFrame(float zoomX = Graphics::kDefaultZoomX, float zoomY = Graphics::kDefaultZoomY);
 	void reset();
 	bool isChanged();
 	bool isFinished();
 	bool loadBuffer(char *buffer, bool compete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
 	bool loadFile(const Common::String &filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
-	bool draw(int x, int y, BaseObject *Register = nullptr, float zoomX = kDefaultZoomX, float zoomY = kDefaultZoomY, uint32 alpha = kDefaultRgbaMod);
+	bool draw(int x, int y, BaseObject *Register = nullptr, float zoomX = Graphics::kDefaultZoomX, float zoomY = Graphics::kDefaultZoomY, uint32 alpha = Graphics::kDefaultRgbaMod);
 	bool _looping;
 	int32 _currentFrame;
 	bool addFrame(const char *filename, uint32 delay = 0, int hotspotX = 0, int hotspotY = 0, Rect32 *rect = nullptr);
diff --git a/engines/wintermute/base/base_sub_frame.cpp b/engines/wintermute/base/base_sub_frame.cpp
index 3a6e28b..4388942 100644
--- a/engines/wintermute/base/base_sub_frame.cpp
+++ b/engines/wintermute/base/base_sub_frame.cpp
@@ -37,8 +37,8 @@
 #include "engines/wintermute/base/gfx/base_renderer.h"
 #include "engines/wintermute/base/scriptables/script_value.h"
 #include "engines/wintermute/base/scriptables/script_stack.h"
-#include "engines/wintermute/graphics/transform_tools.h"
-#include "engines/wintermute/graphics/transform_struct.h"
+#include "graphics/transform_tools.h"
+#include "graphics/transform_struct.h"
 
 namespace Wintermute {
 
@@ -47,9 +47,9 @@ IMPLEMENT_PERSISTENT(BaseSubFrame, false)
 //////////////////////////////////////////////////////////////////////////
 BaseSubFrame::BaseSubFrame(BaseGame *inGame) : BaseScriptable(inGame, true) {
 	_surface = nullptr;
-	_hotspotX = kDefaultHotspotX;
-	_hotspotY = kDefaultHotspotY;
-	_alpha = kDefaultRgbaMod;
+	_hotspotX = Graphics::kDefaultHotspotX;
+	_hotspotY = Graphics::kDefaultHotspotY;
+	_alpha = Graphics::kDefaultRgbaMod;
 	_transparent = 0xFFFF00FF;
 
 	_wantsDefaultRect = false;
@@ -234,7 +234,7 @@ const char* BaseSubFrame::getSurfaceFilename() {
 }
 
 //////////////////////////////////////////////////////////////////////
-bool BaseSubFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, float zoomY, bool precise, uint32 alpha, float rotate, TSpriteBlendMode blendMode) {
+bool BaseSubFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, float zoomY, bool precise, uint32 alpha, float rotate, Graphics::TSpriteBlendMode blendMode) {
 
 	rotate = fmod(rotate, 360.0f);
 	if (rotate < 0) {
@@ -246,7 +246,7 @@ bool BaseSubFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, fl
 	}
 
 	if (registerOwner != nullptr && !_decoration) {
-		if (zoomX == kDefaultZoomX && zoomY == kDefaultZoomY) {
+		if (zoomX == Graphics::kDefaultZoomX && zoomY == Graphics::kDefaultZoomY) {
 			BaseEngine::getRenderer()->addRectToList(new BaseActiveRect(_gameRef,  registerOwner, this, x - _hotspotX + getRect().left, y  - _hotspotY + getRect().top, getRect().right - getRect().left, getRect().bottom - getRect().top, zoomX, zoomY, precise));
 		} else {
 			BaseEngine::getRenderer()->addRectToList(new BaseActiveRect(_gameRef,  registerOwner, this, (int)(x - (_hotspotX + getRect().left) * (zoomX / 100)), (int)(y - (_hotspotY + getRect().top) * (zoomY / 100)), (int)((getRect().right - getRect().left) * (zoomX / 100)), (int)((getRect().bottom - getRect().top) * (zoomY / 100)), zoomX, zoomY, precise));
@@ -259,24 +259,26 @@ bool BaseSubFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, fl
 	bool res;
 
 	//if (Alpha==0xFFFFFFFF) Alpha = _alpha; // TODO: better (combine owner's and self alpha)
-	if (_alpha != kDefaultRgbaMod) {
+	if (_alpha != Graphics::kDefaultRgbaMod) {
 		alpha = _alpha;
 	}
 
-	if (rotate != kDefaultAngle) {
-		Point32 boxOffset, rotatedHotspot, hotspotOffset, newOrigin;
-		Point32 origin(x, y);
-		Rect32 oldRect = getRect();
-		Point32 newHotspot;
-		TransformStruct transform = TransformStruct(zoomX, zoomY, (uint32)rotate, _hotspotX, _hotspotY, blendMode, alpha, _mirrorX, _mirrorY, 0, 0);
-		Rect32 newRect = TransformTools::newRect (oldRect, transform, &newHotspot);
+	if (rotate != Graphics::kDefaultAngle) {
+		Point32 boxOffset, rotatedHotspot, hotspotOffset;
+		Common::Point origin(x, y);
+		Common::Point newOrigin;
+		Rect32 oldRect1 = getRect();
+		Common::Rect oldRect(oldRect1.top, oldRect1.left, oldRect1.bottom, oldRect1.right);
+		Common::Point newHotspot;
+		Graphics::TransformStruct transform = Graphics::TransformStruct(zoomX, zoomY, (uint32)rotate, _hotspotX, _hotspotY, blendMode, alpha, _mirrorX, _mirrorY, 0, 0);
+		Rect32 newRect = Graphics::TransformTools::newRect(oldRect, transform, &newHotspot);
 		newOrigin = origin - newHotspot;
 		res = _surface->displayTransform(newOrigin.x, newOrigin.y, oldRect, newRect, transform);
 	} else {
-		if (zoomX == kDefaultZoomX && zoomY == kDefaultZoomY) {
+		if (zoomX == Graphics::kDefaultZoomX && zoomY == Graphics::kDefaultZoomY) {
 			res = _surface->displayTrans(x - _hotspotX, y - _hotspotY, getRect(), alpha, blendMode, _mirrorX, _mirrorY);
 		} else {
-			res = _surface->displayTransZoom((int)(x - _hotspotX * (zoomX / kDefaultZoomX)), (int)(y - _hotspotY * (zoomY / kDefaultZoomY)), getRect(), zoomX, zoomY, alpha, blendMode, _mirrorX, _mirrorY);
+			res = _surface->displayTransZoom((int)(x - _hotspotX * (zoomX / Graphics::kDefaultZoomX)), (int)(y - _hotspotY * (zoomY / Graphics::kDefaultZoomY)), getRect(), zoomX, zoomY, alpha, blendMode, _mirrorX, _mirrorY);
 		}
 	}
 
diff --git a/engines/wintermute/base/base_sub_frame.h b/engines/wintermute/base/base_sub_frame.h
index b2859fa..f156c33 100644
--- a/engines/wintermute/base/base_sub_frame.h
+++ b/engines/wintermute/base/base_sub_frame.h
@@ -32,6 +32,7 @@
 
 #include "engines/wintermute/base/base.h"
 #include "engines/wintermute/base/base_scriptable.h"
+#include "graphics/transform_struct.h"
 
 namespace Wintermute {
 class BaseObject;
@@ -52,7 +53,7 @@ public:
 	BaseSubFrame(BaseGame *inGame);
 	virtual ~BaseSubFrame();
 	bool loadBuffer(char *buffer, int lifeTime, bool keepLoaded);
-	bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, float rotate = 0.0f, TSpriteBlendMode blendMode = BLEND_NORMAL);
+	bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, float rotate = 0.0f, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL);
 	bool getBoundingRect(Rect32 *rect, int x, int y, float scaleX = 100, float scaleY = 100);
 	const char* getSurfaceFilename();
 
diff --git a/engines/wintermute/base/font/base_font_truetype.cpp b/engines/wintermute/base/font/base_font_truetype.cpp
index df9a864..f27b565 100644
--- a/engines/wintermute/base/font/base_font_truetype.cpp
+++ b/engines/wintermute/base/font/base_font_truetype.cpp
@@ -234,7 +234,7 @@ void BaseFontTT::drawText(const byte *text, int x, int y, int width, TTextAlign
 				color = BYTETORGBA(RGBCOLGetR(color), RGBCOLGetG(color), RGBCOLGetB(color), RGBCOLGetA(renderer->_forceAlphaColor));
 				renderer->_forceAlphaColor = 0;
 			}
-			surface->displayTransOffset(x, y - textOffset, rc, color, BLEND_NORMAL, false, false, _layers[i]->_offsetX, _layers[i]->_offsetY);
+			surface->displayTransOffset(x, y - textOffset, rc, color, Graphics::BLEND_NORMAL, false, false, _layers[i]->_offsetX, _layers[i]->_offsetY);
 
 			renderer->_forceAlphaColor = origForceAlpha;
 		}
diff --git a/engines/wintermute/base/gfx/base_image.cpp b/engines/wintermute/base/gfx/base_image.cpp
index e676faf..a1548b8 100644
--- a/engines/wintermute/base/gfx/base_image.cpp
+++ b/engines/wintermute/base/gfx/base_image.cpp
@@ -28,7 +28,7 @@
 
 #include "engines/wintermute/base/gfx/base_image.h"
 #include "engines/wintermute/base/base_file_manager.h"
-#include "engines/wintermute/graphics/transparent_surface.h"
+#include "graphics/transparent_surface.h"
 #include "graphics/surface.h"
 #include "image/png.h"
 #include "image/jpeg.h"
@@ -112,7 +112,7 @@ bool BaseImage::saveBMPFile(const Common::String &filename) const {
 //////////////////////////////////////////////////////////////////////////
 bool BaseImage::resize(int newWidth, int newHeight) {
 	// WME Lite used FILTER_BILINEAR with FreeImage_Rescale here.
-	TransparentSurface temp(*_surface, true);
+	Graphics::TransparentSurface temp(*_surface, true);
 	if (_deletableSurface) {
 		_deletableSurface->free();
 		delete _deletableSurface;
@@ -216,7 +216,7 @@ bool BaseImage::writeBMPToStream(Common::WriteStream *stream) const {
 bool BaseImage::copyFrom(BaseImage *origImage, int newWidth, int newHeight) {
 	// WME Lite used FILTER_BILINEAR with FreeImage_Rescale here.
 
-	TransparentSurface temp(*origImage->_surface, false);
+	Graphics::TransparentSurface temp(*origImage->_surface, false);
 	if (_deletableSurface) {
 		_deletableSurface->free();
 		delete _deletableSurface;
diff --git a/engines/wintermute/base/gfx/base_surface.cpp b/engines/wintermute/base/gfx/base_surface.cpp
index ec42a63..f8b96b5 100644
--- a/engines/wintermute/base/gfx/base_surface.cpp
+++ b/engines/wintermute/base/gfx/base_surface.cpp
@@ -75,7 +75,7 @@ bool BaseSurface::displayHalfTrans(int x, int y, Rect32 rect) {
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurface::displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) {
+bool BaseSurface::displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const Graphics::TransformStruct &transform) {
 	return displayTransform(x, y, rect, newRect, transform);
 }
 
diff --git a/engines/wintermute/base/gfx/base_surface.h b/engines/wintermute/base/gfx/base_surface.h
index 7bd9bcb..ea743bd 100644
--- a/engines/wintermute/base/gfx/base_surface.h
+++ b/engines/wintermute/base/gfx/base_surface.h
@@ -32,7 +32,7 @@
 #include "engines/wintermute/base/base.h"
 #include "engines/wintermute/math/rect32.h"
 #include "graphics/surface.h"
-#include "engines/wintermute/graphics/transform_struct.h"
+#include "graphics/transform_struct.h"
 
 namespace Wintermute {
 
@@ -50,12 +50,12 @@ public:
 
 	virtual bool displayHalfTrans(int x, int y, Rect32 rect);
 	virtual bool isTransparentAt(int x, int y);
-	virtual bool displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
-	virtual bool displayTrans(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
-	virtual bool displayTransOffset(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false, int offsetX = 0, int offsetY = 0) = 0;
-	virtual bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
-	virtual bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) = 0;
-	virtual bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
+	virtual bool displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
+	virtual bool displayTrans(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
+	virtual bool displayTransOffset(int x, int y, Rect32 rect, uint32 alpha = 0xFFFFFFFF, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false, int offsetX = 0, int offsetY = 0) = 0;
+	virtual bool display(int x, int y, Rect32 rect, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
+	virtual bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const Graphics::TransformStruct &transform) = 0;
+	virtual bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = 0xFFFFFFFF, bool transparent = false, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) = 0;
 	virtual bool displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY) = 0;
 	virtual bool restore();
 	virtual bool create(const Common::String &filename, bool defaultCK, byte ckRed, byte ckGreen, byte ckBlue, int lifeTime = -1, bool keepLoaded = false) = 0;
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index 601fcc0..0f6a184 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -35,7 +35,7 @@
 #include "engines/wintermute/base/base_game.h"
 #include "engines/wintermute/base/base_sprite.h"
 #include "common/system.h"
-#include "engines/wintermute/graphics/transparent_surface.h"
+#include "graphics/transparent_surface.h"
 #include "common/queue.h"
 #include "common/config-manager.h"
 
@@ -254,7 +254,7 @@ void BaseRenderOSystem::fadeToColor(byte r, byte g, byte b, byte a) {
 	Common::Rect sizeRect(fillRect);
 	sizeRect.translate(-fillRect.top, -fillRect.left);
 	surf.fillRect(fillRect, col);
-	TransformStruct temp = TransformStruct();
+	Graphics::TransformStruct temp = Graphics::TransformStruct();
 	temp._alphaDisable = false;
 	drawSurface(nullptr, &surf, &sizeRect, &fillRect, temp);
 	surf.free();
@@ -268,7 +268,7 @@ Graphics::PixelFormat BaseRenderOSystem::getPixelFormat() const {
 	return _renderSurface->format;
 }
 
-void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform) {
+void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, Graphics::TransformStruct &transform) {
 
 	if (_disableDirtyRects) {
 		RenderTicket *ticket = new RenderTicket(owner, surf, srcRect, dstRect, transform);
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.h b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
index c9b8a52..bc267fd 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.h
@@ -33,7 +33,7 @@
 #include "common/rect.h"
 #include "graphics/surface.h"
 #include "common/list.h"
-#include "engines/wintermute/graphics/transform_struct.h"
+#include "graphics/transform_struct.h"
 
 namespace Wintermute {
 class BaseSurfaceOSystem;
@@ -110,7 +110,7 @@ public:
 	virtual bool startSpriteBatch() override;
 	virtual bool endSpriteBatch() override;
 	void endSaveLoad();
-	void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct &transform);
+	void drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, Graphics::TransformStruct &transform);
 	BaseSurface *createSurface() override;
 private:
 	/**
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
index 983f9c1..a2a0032 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
@@ -32,8 +32,8 @@
 #include "engines/wintermute/base/gfx/osystem/base_render_osystem.h"
 #include "engines/wintermute/base/gfx/base_image.h"
 #include "engines/wintermute/platform_osystem.h"
-#include "engines/wintermute/graphics/transparent_surface.h"
-#include "engines/wintermute/graphics/transform_tools.h"
+#include "graphics/transparent_surface.h"
+#include "graphics/transform_tools.h"
 #include "graphics/pixelformat.h"
 #include "graphics/surface.h"
 #include "common/stream.h"
@@ -45,7 +45,7 @@ namespace Wintermute {
 BaseSurfaceOSystem::BaseSurfaceOSystem(BaseGame *inGame) : BaseSurface(inGame) {
 	_surface = new Graphics::Surface();
 	_alphaMask = nullptr;
-	_alphaType = TransparentSurface::ALPHA_FULL;
+	_alphaType = Graphics::ALPHA_FULL;
 	_lockPixels = nullptr;
 	_lockPitch = 0;
 	_loaded = false;
@@ -68,10 +68,10 @@ BaseSurfaceOSystem::~BaseSurfaceOSystem() {
 	renderer->invalidateTicketsFromSurface(this);
 }
 
-TransparentSurface::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
+Graphics::AlphaType hasTransparencyType(const Graphics::Surface *surf) {
 	if (surf->format.bytesPerPixel != 4) {
 		warning("hasTransparencyType:: non 32 bpp surface passed as argument");
-		return TransparentSurface::ALPHA_OPAQUE;
+		return Graphics::ALPHA_OPAQUE;
 	}
 	uint8 r, g, b, a;
 	bool seenAlpha = false;
@@ -93,11 +93,11 @@ TransparentSurface::AlphaType hasTransparencyType(const Graphics::Surface *surf)
 		}
 	}
 	if (seenFullAlpha) {
-		return TransparentSurface::ALPHA_FULL;
+		return Graphics::ALPHA_FULL;
 	} else if (seenAlpha) {
-		return TransparentSurface::ALPHA_BINARY;
+		return Graphics::ALPHA_BINARY;
 	} else {
-		return TransparentSurface::ALPHA_OPAQUE;
+		return Graphics::ALPHA_OPAQUE;
 	}
 }
 
@@ -175,7 +175,7 @@ bool BaseSurfaceOSystem::finishLoad() {
 	}
 
 	if (needsColorKey) {
-		TransparentSurface trans(*_surface);
+		Graphics::TransparentSurface trans(*_surface);
 		trans.applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha);
 	}
 
@@ -328,46 +328,46 @@ bool BaseSurfaceOSystem::endPixelOp() {
 
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
+bool BaseSurfaceOSystem::display(int x, int y, Rect32 rect, Graphics::TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
 	_rotation = 0;
-	return drawSprite(x, y, &rect, nullptr, TransformStruct(kDefaultZoomX, kDefaultZoomY,  mirrorX, mirrorY));
+	return drawSprite(x, y, &rect, nullptr, Graphics::TransformStruct(Graphics::kDefaultZoomX, Graphics::kDefaultZoomY,  mirrorX, mirrorY));
 }
 
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayTrans(int x, int y, Rect32 rect, uint32 alpha, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
+bool BaseSurfaceOSystem::displayTrans(int x, int y, Rect32 rect, uint32 alpha, Graphics::TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
 	_rotation = 0;
-	return drawSprite(x, y, &rect, nullptr, TransformStruct(kDefaultZoomX, kDefaultZoomY, blendMode, alpha, mirrorX, mirrorY));
+	return drawSprite(x, y, &rect, nullptr, Graphics::TransformStruct(Graphics::kDefaultZoomX, Graphics::kDefaultZoomY, blendMode, alpha, mirrorX, mirrorY));
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayTransOffset(int x, int y, Rect32 rect, uint32 alpha, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY, int offsetX, int offsetY) {
+bool BaseSurfaceOSystem::displayTransOffset(int x, int y, Rect32 rect, uint32 alpha, Graphics::TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY, int offsetX, int offsetY) {
 	_rotation = 0;
-	return drawSprite(x, y, &rect, nullptr,  TransformStruct(kDefaultZoomX, kDefaultZoomY, kDefaultAngle, kDefaultHotspotX, kDefaultHotspotY, blendMode, alpha, mirrorX, mirrorY, offsetX, offsetY));
+	return drawSprite(x, y, &rect, nullptr,  Graphics::TransformStruct(Graphics::kDefaultZoomX, Graphics::kDefaultZoomY, Graphics::kDefaultAngle, Graphics::kDefaultHotspotX, Graphics::kDefaultHotspotY, blendMode, alpha, mirrorX, mirrorY, offsetX, offsetY));
 }
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
+bool BaseSurfaceOSystem::displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha, Graphics::TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
 	_rotation = 0;
-	return drawSprite(x, y, &rect, nullptr, TransformStruct((int32)zoomX, (int32)zoomY, blendMode, alpha, mirrorX, mirrorY));
+	return drawSprite(x, y, &rect, nullptr, Graphics::TransformStruct((int32)zoomX, (int32)zoomY, blendMode, alpha, mirrorX, mirrorY));
 }
 
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha, bool transparent, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
+bool BaseSurfaceOSystem::displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha, bool transparent, Graphics::TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY) {
 	_rotation = 0;
-	TransformStruct transform;
+	Graphics::TransformStruct transform;
 	if (transparent) {
-		transform = TransformStruct((int32)zoomX, (int32)zoomY, kDefaultAngle, kDefaultHotspotX, kDefaultHotspotY, blendMode, alpha,  mirrorX, mirrorY);
+		transform = Graphics::TransformStruct((int32)zoomX, (int32)zoomY, Graphics::kDefaultAngle, Graphics::kDefaultHotspotX, Graphics::kDefaultHotspotY, blendMode, alpha,  mirrorX, mirrorY);
 	} else {
-		transform = TransformStruct((int32)zoomX, (int32)zoomY, mirrorX, mirrorY);
+		transform = Graphics::TransformStruct((int32)zoomX, (int32)zoomY, mirrorX, mirrorY);
 	}
 	return drawSprite(x, y, &rect, nullptr, transform);
 }
 
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) {
+bool BaseSurfaceOSystem::displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const Graphics::TransformStruct &transform) {
 	_rotation = (uint32)transform._angle;
 	if (transform._angle < 0.0f) {
 		warning("Negative rotation: %d %d", transform._angle, _rotation);
@@ -380,13 +380,13 @@ bool BaseSurfaceOSystem::displayTransform(int x, int y, Rect32 rect, Rect32 newR
 //////////////////////////////////////////////////////////////////////////
 bool BaseSurfaceOSystem::displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY) {
 	assert(numTimesX > 0 && numTimesY > 0);
-	TransformStruct transform(numTimesX, numTimesY);
+	Graphics::TransformStruct transform(numTimesX, numTimesY);
 	return drawSprite(x, y, &rect, nullptr, transform);
 }
 
 
 //////////////////////////////////////////////////////////////////////////
-bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, TransformStruct transform) {
+bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, Graphics::TransformStruct transform) {
 	BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
 
 	if (!_loaded) {
@@ -414,13 +414,13 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
 		position.setHeight(newRect->height());
 	} else {
 
-		Rect32 r;
+		Common::Rect r;
 		r.top = 0;
 		r.left = 0;
 		r.setWidth(rect->width());
 		r.setHeight(rect->height());
 
-		r = TransformTools::newRect(r, transform, 0);
+		r = Graphics::TransformTools::newRect(r, transform, 0);
 
 		position.top = r.top + y + transform._offset.y;
 		position.left = r.left + x + transform._offset.x;
@@ -433,7 +433,7 @@ bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect,
 	// But no checking is in place for that yet.
 
 	// Optimize by not doing alpha-blits if we lack alpha
-	if (_alphaType == TransparentSurface::ALPHA_OPAQUE && !transform._alphaDisable) {
+	if (_alphaType == Graphics::ALPHA_OPAQUE && !transform._alphaDisable) {
 		transform._alphaDisable = true;
 	}
 
@@ -452,9 +452,9 @@ bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAl
 		_surface->copyFrom(surface);
 	}
 	if (hasAlpha) {
-		_alphaType = TransparentSurface::ALPHA_FULL;
+		_alphaType = Graphics::ALPHA_FULL;
 	} else {
-		_alphaType = TransparentSurface::ALPHA_OPAQUE;
+		_alphaType = Graphics::ALPHA_OPAQUE;
 	}
 	BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
 	renderer->invalidateTicketsFromSurface(this);
diff --git a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
index 4a05b2c..9fbbe1d 100644
--- a/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
+++ b/engines/wintermute/base/gfx/osystem/base_surface_osystem.h
@@ -30,7 +30,7 @@
 #define WINTERMUTE_BASE_SURFACESDL_H
 
 #include "graphics/surface.h"
-#include "engines/wintermute/graphics/transparent_surface.h"
+#include "graphics/transparent_surface.h"
 #include "engines/wintermute/base/gfx/base_surface.h"
 #include "common/list.h"
 
@@ -52,12 +52,12 @@ public:
 	bool endPixelOp() override;
 
 
-	bool displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = kDefaultRgbaMod, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
-	bool displayTrans(int x, int y, Rect32 rect, uint32 alpha = kDefaultRgbaMod, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
-	bool displayTransOffset(int x, int y, Rect32 rect, uint32 alpha = kDefaultRgbaMod, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false, int offsetX = 0, int offsetY = 0) override;
-	bool display(int x, int y, Rect32 rect, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
-	bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = kDefaultRgbaMod, bool transparent = false, TSpriteBlendMode blendMode = BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
-	bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const TransformStruct &transform) override;
+	bool displayTransZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = Graphics::kDefaultRgbaMod, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+	bool displayTrans(int x, int y, Rect32 rect, uint32 alpha = Graphics::kDefaultRgbaMod, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+	bool displayTransOffset(int x, int y, Rect32 rect, uint32 alpha = Graphics::kDefaultRgbaMod, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false, int offsetX = 0, int offsetY = 0) override;
+	bool display(int x, int y, Rect32 rect, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+	bool displayZoom(int x, int y, Rect32 rect, float zoomX, float zoomY, uint32 alpha = Graphics::kDefaultRgbaMod, bool transparent = false, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL, bool mirrorX = false, bool mirrorY = false) override;
+	bool displayTransform(int x, int y, Rect32 rect, Rect32 newRect, const Graphics::TransformStruct &transform) override;
 	virtual bool displayTiled(int x, int y, Rect32 rect, int numTimesX, int numTimesY);
 	virtual bool putSurface(const Graphics::Surface &surface, bool hasAlpha = false) override;
 	/*  static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle);
@@ -82,17 +82,17 @@ public:
 		return _height;
 	}
 
-	TransparentSurface::AlphaType getAlphaType() const { return _alphaType; }
+	Graphics::AlphaType getAlphaType() const { return _alphaType; }
 private:
 	Graphics::Surface *_surface;
 	bool _loaded;
 	bool finishLoad();
-	bool drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, TransformStruct transformStruct);
+	bool drawSprite(int x, int y, Rect32 *rect, Rect32 *newRect, Graphics::TransformStruct transformStruct);
 	void genAlphaMask(Graphics::Surface *surface);
 	uint32 getPixelAt(Graphics::Surface *surface, int x, int y);
 
 	uint32 _rotation;
-	TransparentSurface::AlphaType _alphaType;
+	Graphics::AlphaType _alphaType;
 	void *_lockPixels;
 	int _lockPitch;
 	byte *_alphaMask;
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.cpp b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
index f8579df..afe8843 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.cpp
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.cpp
@@ -29,12 +29,12 @@
 
 #include "engines/wintermute/base/gfx/osystem/render_ticket.h"
 #include "engines/wintermute/base/gfx/osystem/base_surface_osystem.h"
-#include "engines/wintermute/graphics/transform_tools.h"
+#include "graphics/transform_tools.h"
 #include "common/textconsole.h"
 
 namespace Wintermute {
 
-RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, TransformStruct transform) :
+RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, Graphics::TransformStruct transform) :
 	_owner(owner),
 	_srcRect(*srcRect),
 	_dstRect(*dstRect),
@@ -57,8 +57,8 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
 		// NB: Mirroring and rotation are probably done in the wrong order.
 		// (Mirroring should most likely be done before rotation. See also
 		// TransformTools.)
-		if (_transform._angle != kDefaultAngle) {
-			TransparentSurface src(*_surface, false);
+		if (_transform._angle != Graphics::kDefaultAngle) {
+			Graphics::TransparentSurface src(*_surface, false);
 			Graphics::Surface *temp = src.rotoscale(transform);
 			_surface->free();
 			delete _surface;
@@ -66,7 +66,7 @@ RenderTicket::RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *s
 		} else if ((dstRect->width() != srcRect->width() ||
 					dstRect->height() != srcRect->height()) &&
 					_transform._numTimesX * _transform._numTimesY == 1) {
-			TransparentSurface src(*_surface, false);
+			Graphics::TransparentSurface src(*_surface, false);
 			Graphics::Surface *temp = src.scale(dstRect->width(), dstRect->height());
 			_surface->free();
 			delete _surface;
@@ -97,7 +97,7 @@ bool RenderTicket::operator==(const RenderTicket &t) const {
 
 // Replacement for SDL2's SDL_RenderCopy
 void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
-	TransparentSurface src(*getSurface(), false);
+	Graphics::TransparentSurface src(*getSurface(), false);
 
 	Common::Rect clipRect;
 	clipRect.setWidth(getSurface()->w);
@@ -105,7 +105,7 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
 
 	if (_owner) {
 		if (_transform._alphaDisable) {
-			src.setAlphaMode(TransparentSurface::ALPHA_OPAQUE);
+			src.setAlphaMode(Graphics::ALPHA_OPAQUE);
 		} else {
 			src.setAlphaMode(_owner->getAlphaType());
 		}
@@ -126,7 +126,7 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
 }
 
 void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const {
-	TransparentSurface src(*getSurface(), false);
+	Graphics::TransparentSurface src(*getSurface(), false);
 	bool doDelete = false;
 	if (!clipRect) {
 		doDelete = true;
@@ -137,7 +137,7 @@ void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect
 
 	if (_owner) {
 		if (_transform._alphaDisable) {
-			src.setAlphaMode(TransparentSurface::ALPHA_OPAQUE);
+			src.setAlphaMode(Graphics::ALPHA_OPAQUE);
 		} else {
 			src.setAlphaMode(_owner->getAlphaType());
 		}
diff --git a/engines/wintermute/base/gfx/osystem/render_ticket.h b/engines/wintermute/base/gfx/osystem/render_ticket.h
index de95273..3d3bd2e 100644
--- a/engines/wintermute/base/gfx/osystem/render_ticket.h
+++ b/engines/wintermute/base/gfx/osystem/render_ticket.h
@@ -29,7 +29,7 @@
 #ifndef WINTERMUTE_RENDER_TICKET_H
 #define WINTERMUTE_RENDER_TICKET_H
 
-#include "engines/wintermute/graphics/transparent_surface.h"
+#include "graphics/transparent_surface.h"
 #include "graphics/surface.h"
 #include "common/rect.h"
 
@@ -51,8 +51,8 @@ class BaseSurfaceOSystem;
  */
 class RenderTicket {
 public:
-	RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRest, TransformStruct transform);
-	RenderTicket() : _isValid(true), _wantsDraw(false), _transform(TransformStruct()) {}
+	RenderTicket(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRest, Graphics::TransformStruct transform);
+	RenderTicket() : _isValid(true), _wantsDraw(false), _transform(Graphics::TransformStruct()) {}
 	~RenderTicket();
 	const Graphics::Surface *getSurface() const { return _surface; }
 	// Non-dirty-rects:
@@ -65,7 +65,7 @@ public:
 	bool _isValid;
 	bool _wantsDraw;
 
-	TransformStruct _transform;
+	Graphics::TransformStruct _transform;
 
 	BaseSurfaceOSystem *_owner;
 	bool operator==(const RenderTicket &a) const;
diff --git a/engines/wintermute/dctypes.h b/engines/wintermute/dctypes.h
index 33e1cc4..90340f4 100644
--- a/engines/wintermute/dctypes.h
+++ b/engines/wintermute/dctypes.h
@@ -200,14 +200,6 @@ enum TTextEncoding {
 	NUM_TEXT_ENCODINGS
 };
 
-enum TSpriteBlendMode {
-	BLEND_UNKNOWN       = -1,
-	BLEND_NORMAL        = 0,
-	BLEND_ADDITIVE      = 1,
-	BLEND_SUBTRACTIVE   = 2,
-	NUM_BLEND_MODES
-};
-
 enum TTTSType {
 	TTS_CAPTION = 0,
 	TTS_TALK,
diff --git a/engines/wintermute/graphics/transform_struct.cpp b/engines/wintermute/graphics/transform_struct.cpp
deleted file mode 100644
index 9483975..0000000
--- a/engines/wintermute/graphics/transform_struct.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "engines/wintermute/graphics/transform_struct.h"
-#include "engines/wintermute/graphics/transparent_surface.h"
-
-namespace Wintermute {
-void TransformStruct::init(Point32 zoom, uint32 angle, Point32 hotspot, bool alphaDisable, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, Point32 offset) {
-	_zoom = zoom;
-	_angle = angle;
-	_hotspot = hotspot;
-	_blendMode = blendMode;
-	_rgbaMod = rgbaMod;
-	_alphaDisable = alphaDisable;
-	_flip = 0;
-	_flip += TransparentSurface::FLIP_H * mirrorX;
-	_flip += TransparentSurface::FLIP_V * mirrorY;
-	_offset = offset;
-	_numTimesX = 1;
-	_numTimesY = 1;
-}
-
-TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
-	init(Point32(zoomX, zoomY),
-		angle,
-		Point32(hotspotX, hotspotY),
-		false,
-		blendMode,
-		rgbaMod,
-		mirrorX, mirrorY,
-		Point32(offsetX, offsetY));
-}
-
-TransformStruct::TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY, int32 offsetX, int32 offsetY) {
-	init(Point32((int32)(zoomX / 100.0 * kDefaultZoomX),
-		     (int32)(zoomY / 100.0 * kDefaultZoomY)),
-		angle,
-		Point32(hotspotX, hotspotY),
-		false,
-		blendMode,
-		rgbaMod,
-		mirrorX, mirrorY,
-		Point32(offsetX, offsetY));
-}
-
-TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 rgbaMod, bool mirrorX, bool mirrorY) {
-	init(Point32(zoomX, zoomY),
-		kDefaultAngle,
-		Point32(kDefaultHotspotX, kDefaultHotspotY),
-		false,
-		blendMode,
-		rgbaMod,
-		mirrorX,
-		mirrorY,
-		Point32(kDefaultOffsetX, kDefaultOffsetY));
-}
-
-TransformStruct::TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY) {
-	init(Point32(zoomX, zoomY),
-		angle,
-		Point32(hotspotX, hotspotY),
-		true,
-		BLEND_NORMAL,
-		kDefaultRgbaMod,
-		false, false,
-		Point32(kDefaultOffsetX, kDefaultOffsetY));
-}
-
-TransformStruct::TransformStruct(int32 numTimesX, int32 numTimesY) {
-	init(Point32(kDefaultZoomX, kDefaultZoomY),
-		kDefaultAngle,
-		Point32(kDefaultHotspotX, kDefaultHotspotY),
-		false,
-		BLEND_NORMAL,
-		kDefaultRgbaMod,
-		false, false,
-		Point32(kDefaultOffsetX, kDefaultOffsetY));
-	_numTimesX = numTimesX;
-	_numTimesY = numTimesY;
-}
-
-TransformStruct::TransformStruct() {
-	init(Point32(kDefaultZoomX, kDefaultZoomY),
-		kDefaultAngle,
-		Point32(kDefaultHotspotX, kDefaultHotspotY),
-		true,
-		BLEND_NORMAL,
-		kDefaultRgbaMod,
-		false, false,
-		Point32(kDefaultOffsetX, kDefaultOffsetY));
-}
-
-bool TransformStruct::getMirrorX() const {
-	return (bool)(_flip & TransparentSurface::FLIP_H);
-}
-
-bool TransformStruct::getMirrorY() const {
-	return (bool)(_flip & TransparentSurface::FLIP_V);
-}
-} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transform_struct.h b/engines/wintermute/graphics/transform_struct.h
deleted file mode 100644
index f80b096..0000000
--- a/engines/wintermute/graphics/transform_struct.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WINTERMUTE_TRANSFORM_STRUCT_H
-#define WINTERMUTE_TRANSFORM_STRUCT_H
-
-#include "engines/wintermute/math/rect32.h"
-#include "engines/wintermute/dctypes.h"
-
-namespace Wintermute {
-/**
- * Contains all the required information that define a transform.
- * Same source sprite + same TransformStruct = Same resulting sprite.
- * Has a number of overloaded constructors to accomodate various argument lists.
- */
-
-const int32 kDefaultZoomX = 100;
-const int32 kDefaultZoomY = 100;
-const uint32 kDefaultRgbaMod = 0xFFFFFFFF;
-const int32 kDefaultHotspotX = 0;
-const int32 kDefaultHotspotY = 0;
-const int32 kDefaultOffsetX = 0;
-const int32 kDefaultOffsetY = 0;
-const int32 kDefaultAngle = 0;	
-
-struct TransformStruct {
-private:
-	void init(Point32 zoom, uint32 angle, Point32 hotspot, bool alphaDisable, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX, bool mirrorY, Point32 offset);
-
-public:
-	TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false, int32 offsetX = 0, int32 offsetY = 0);
-	TransformStruct(float zoomX, float zoomY, uint32 angle, int32 hotspotX, int32 hotspotY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false, int32 offsetX = 0, int32 offsetY = 0);
-	TransformStruct(int32 zoomX, int32 zoomY, TSpriteBlendMode blendMode, uint32 alpha, bool mirrorX = false, bool mirrorY = false);
-	TransformStruct(int32 zoomX, int32 zoomY, uint32 angle, int32 hotspotX = 0, int32 hotspotY = 0);
-	TransformStruct(int32 numTimesX, int32 numTimesY);
-	TransformStruct();
-
-	Point32 _zoom;   ///< Zoom; 100 = no zoom
-	Point32 _hotspot; ///< Position of the hotspot
-	int32 _angle;   ///< Rotation angle, in degrees
-	byte _flip;      ///< Bitflag: see TransparentSurface::FLIP_XXX
-	bool _alphaDisable;
-	TSpriteBlendMode _blendMode;
-	uint32 _rgbaMod;      ///< RGBa
-	Point32 _offset;
-	int32 _numTimesX;
-	int32 _numTimesY;
-
-	bool getMirrorX() const;
-	bool getMirrorY() const;
-
-	bool operator==(const TransformStruct &compare) const {
-		return (compare._angle == _angle &&
-				compare._flip == _flip &&
-				compare._zoom == _zoom  &&
-				compare._offset == _offset &&
-				compare._alphaDisable == _alphaDisable  &&
-				compare._rgbaMod == _rgbaMod &&
-				compare._blendMode == _blendMode &&
-				compare._numTimesX == _numTimesX &&
-				compare._numTimesY == _numTimesY
-			   );
-	}
-
-	bool operator!=(const TransformStruct &compare) const {
-		return !(compare == *this);
-	}
-};
-} // End of namespace Wintermute
-#endif
diff --git a/engines/wintermute/graphics/transform_tools.cpp b/engines/wintermute/graphics/transform_tools.cpp
deleted file mode 100644
index 7a009c2..0000000
--- a/engines/wintermute/graphics/transform_tools.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-
-#include "engines/wintermute/graphics/transform_tools.h"
-#include <math.h>
-
-namespace Wintermute {
-
-FloatPoint TransformTools::transformPoint(FloatPoint point, const float rotate, const Point32 &zoom, const bool mirrorX, const bool mirrorY) {
-	float rotateRad = rotate * M_PI / 180.0f;
-	float x = point.x;
-	float y = point.y;
-	x = (x * zoom.x) / kDefaultZoomX;
-	y = (y * zoom.y) / kDefaultZoomY;
-#if 0
-	// TODO: Mirroring should be done before rotation, but the blitting
-	// code does the inverse, so we match that for now.
-	if (mirrorX)
-		x *= -1;
-	if (mirrorY)
-		y *= -1;
-#endif
-	FloatPoint newPoint;
-	newPoint.x = x * cos(rotateRad) - y * sin(rotateRad);
-	newPoint.y = x * sin(rotateRad) + y * cos(rotateRad);
-	if (mirrorX) {
-		newPoint.x *= -1;
-	}
-	if (mirrorY) {
-		newPoint.y *= -1;
-	}
-	return newPoint;
-}
-
-Rect32 TransformTools::newRect(const Rect32 &oldRect, const TransformStruct &transform, Point32 *newHotspot) {
-	Point32 nw(oldRect.left, oldRect.top);
-	Point32 ne(oldRect.right, oldRect.top);
-	Point32 sw(oldRect.left, oldRect.bottom);
-	Point32 se(oldRect.right, oldRect.bottom);
-
-	FloatPoint nw1, ne1, sw1, se1;
-
-	nw1 = transformPoint(nw - transform._hotspot, transform._angle, transform._zoom);
-	ne1 = transformPoint(ne - transform._hotspot, transform._angle, transform._zoom);
-	sw1 = transformPoint(sw - transform._hotspot, transform._angle, transform._zoom);
-	se1 = transformPoint(se - transform._hotspot, transform._angle, transform._zoom);
-
-	float top = MIN(nw1.y, MIN(ne1.y, MIN(sw1.y, se1.y)));
-	float bottom = MAX(nw1.y, MAX(ne1.y, MAX(sw1.y, se1.y)));
-	float left = MIN(nw1.x, MIN(ne1.x, MIN(sw1.x, se1.x)));
-	float right = MAX(nw1.x, MAX(ne1.x, MAX(sw1.x, se1.x)));
-
-	if (newHotspot) {
-		newHotspot->y = (uint32)(-floor(top));
-		newHotspot->x = (uint32)(-floor(left));
-	}
-
-	Rect32 res;
-	res.top = (int32)(floor(top)) + transform._hotspot.y;
-	res.bottom = (int32)(ceil(bottom)) + transform._hotspot.y;
-	res.left = (int32)(floor(left)) + transform._hotspot.x;
-	res.right = (int32)(ceil(right)) + transform._hotspot.x;
-
-	return res;
-}
-
-} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transform_tools.h b/engines/wintermute/graphics/transform_tools.h
deleted file mode 100644
index e259db0..0000000
--- a/engines/wintermute/graphics/transform_tools.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WINTERMUTE_TRANSFORM_TOOLS_H
-#define WINTERMUTE_TRANSFORM_TOOLS_H
-
-#include "engines/wintermute/math/rect32.h"
-#include "engines/wintermute/math/floatpoint.h"
-#include "engines/wintermute/graphics/transform_struct.h"
-
-namespace Wintermute {
-
-class TransformTools {
-public:
-	/**
-	 * Basic transform (scale + rotate) for a single point
-	 */
-	static FloatPoint transformPoint(FloatPoint point, const float rotate, const Point32 &zoom, const bool mirrorX = false, const bool mirrorY = false);
-
-	/**
-	 * @param &point the point on which the transform is to be applied
-	 * @param rotate the angle in degrees
-	 * @param &zoom  zoom x,y in percent
-	 * @param mirrorX flip along the vertical axis?
-	 * @param mirrorY flip along the horizontal axis?
-	 * @return the smallest rect that can contain the transformed sprite
-	 * and, as a side-effect, "newHotspot" will tell you where the hotspot will
-	 * have ended up in the new rect, for centering.
-	 */
-	static Rect32 newRect(const Rect32 &oldRect, const TransformStruct &transform, Point32 *newHotspot);
-};
-
-} // End of namespace Wintermute
-#endif
diff --git a/engines/wintermute/graphics/transparent_surface.cpp b/engines/wintermute/graphics/transparent_surface.cpp
deleted file mode 100644
index b16ba0f..0000000
--- a/engines/wintermute/graphics/transparent_surface.cpp
+++ /dev/null
@@ -1,851 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- *
- * The bottom part of this is file is adapted from SDL_rotozoom.c. The
- * relevant copyright notice for those specific functions can be found at the
- * top of that section.
- *
- */
-
-
-
-#include "common/algorithm.h"
-#include "common/endian.h"
-#include "common/util.h"
-#include "common/rect.h"
-#include "common/math.h"
-#include "common/textconsole.h"
-#include "graphics/primitives.h"
-#include "engines/wintermute/graphics/transparent_surface.h"
-#include "engines/wintermute/graphics/transform_tools.h"
-
-//#define ENABLE_BILINEAR
-
-namespace Wintermute {
-
-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;
-
-#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
-
-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);
-void doBlitAlphaBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
-void doBlitAdditiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
-void doBlitSubtractiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color);
-
-TransparentSurface::TransparentSurface() : Surface(), _alphaMode(ALPHA_FULL) {}
-
-TransparentSurface::TransparentSurface(const Surface &surf, bool copyData) : Surface(), _alphaMode(ALPHA_FULL) {
-	if (copyData) {
-		copyFrom(surf);
-	} else {
-		w = surf.w;
-		h = surf.h;
-		pitch = surf.pitch;
-		format = surf.format;
-		// We need to cast the const qualifier away here because 'pixels'
-		// always needs to be writable. 'surf' however is a constant Surface,
-		// thus getPixels will always return const pixel data.
-		pixels = const_cast<void *>(surf.getPixels());
-	}
-}
-
-/**
- * Optimized version of doBlit to be used w/opaque blitting (no alpha).
- */
-void doBlitOpaqueFast(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;
-		memcpy(out, in, width * 4);
-		for (uint32 j = 0; j < width; j++) {
-			out[kAIndex] = 0xFF;
-			out += 4;
-		}
-		outo += pitch;
-		ino += inoStep;
-	}
-}
-
-/**
- * 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 >> kAShift) & 0xff;
-
-			if (a != 0) {   // Full opacity (Any value not exactly 0 is Opaque here)
-				*(uint32 *)out = pix;
-				out[kAIndex] = 0xFF;
-			}
-			out += 4;
-			in += inStep;
-		}
-		outo += pitch;
-		ino += inoStep;
-	}
-}
-
-/**
- * Optimized version of doBlit to be used with alpha blended blitting
- * @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
- */
-void doBlitAlphaBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
-	byte *in;
-	byte *out;
-
-	if (color == 0xffffffff) {
-
-		for (uint32 i = 0; i < height; i++) {
-			out = outo;
-			in = ino;
-			for (uint32 j = 0; j < width; j++) {
-
-				if (in[kAIndex] != 0) {
-					out[kAIndex] = 255;
-					out[kRIndex] = ((in[kRIndex] * in[kAIndex]) + out[kRIndex] * (255 - in[kAIndex])) >> 8;
-					out[kGIndex] = ((in[kGIndex] * in[kAIndex]) + out[kGIndex] * (255 - in[kAIndex])) >> 8;
-					out[kBIndex] = ((in[kBIndex] * in[kAIndex]) + out[kBIndex] * (255 - in[kAIndex])) >> 8;
-				}
-
-				in += inStep;
-				out += 4;
-			}
-			outo += pitch;
-			ino += inoStep;
-		}
-	} else {
-
-		byte ca = (color >> kAModShift) & 0xFF;
-		byte cr = (color >> kRModShift) & 0xFF;
-		byte cg = (color >> kGModShift) & 0xFF;
-		byte cb = (color >> kBModShift) & 0xFF;
-
-		for (uint32 i = 0; i < height; i++) {
-			out = outo;
-			in = ino;
-			for (uint32 j = 0; j < width; j++) {
-
-				uint32 ina = in[kAIndex] * ca >> 8;
-				out[kAIndex] = 255;
-				out[kBIndex] = (out[kBIndex] * (255 - ina) >> 8);
-				out[kGIndex] = (out[kGIndex] * (255 - ina) >> 8);
-				out[kRIndex] = (out[kRIndex] * (255 - ina) >> 8);
-
-				out[kBIndex] = out[kBIndex] + (in[kBIndex] * ina * cb >> 16);
-				out[kGIndex] = out[kGIndex] + (in[kGIndex] * ina * cg >> 16);
-				out[kRIndex] = out[kRIndex] + (in[kRIndex] * ina * cr >> 16);
-
-				in += inStep;
-				out += 4;
-			}
-			outo += pitch;
-			ino += inoStep;
-		}
-	}
-}
-
-/**
- * Optimized version of doBlit to be used with additive blended blitting
- */
-void doBlitAdditiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
-	byte *in;
-	byte *out;
-
-	if (color == 0xffffffff) {
-
-		for (uint32 i = 0; i < height; i++) {
-			out = outo;
-			in = ino;
-			for (uint32 j = 0; j < width; j++) {
-
-				if (in[kAIndex] != 0) {
-					out[kRIndex] = MIN((in[kRIndex] * in[kAIndex] >> 8) + out[kRIndex], 255);
-					out[kGIndex] = MIN((in[kGIndex] * in[kAIndex] >> 8) + out[kGIndex], 255);
-					out[kBIndex] = MIN((in[kBIndex] * in[kAIndex] >> 8) + out[kBIndex], 255);
-				}
-
-				in += inStep;
-				out += 4;
-			}
-			outo += pitch;
-			ino += inoStep;
-		}
-	} else {
-
-		byte ca = (color >> kAModShift) & 0xFF;
-		byte cr = (color >> kRModShift) & 0xFF;
-		byte cg = (color >> kGModShift) & 0xFF;
-		byte cb = (color >> kBModShift) & 0xFF;
-
-		for (uint32 i = 0; i < height; i++) {
-			out = outo;
-			in = ino;
-			for (uint32 j = 0; j < width; j++) {
-
-				uint32 ina = in[kAIndex] * ca >> 8;
-
-				if (cb != 255) {
-					out[kBIndex] = MIN(out[kBIndex] + ((in[kBIndex] * cb * ina) >> 16), 255u);
-				} else {
-					out[kBIndex] = MIN(out[kBIndex] + (in[kBIndex] * ina >> 8), 255u);
-				}
-
-				if (cg != 255) {
-					out[kGIndex] = MIN(out[kGIndex] + ((in[kGIndex] * cg * ina) >> 16), 255u);
-				} else {
-					out[kGIndex] = MIN(out[kGIndex] + (in[kGIndex] * ina >> 8), 255u);
-				}
-
-				if (cr != 255) {
-					out[kRIndex] = MIN(out[kRIndex] + ((in[kRIndex] * cr * ina) >> 16), 255u);
-				} else {
-					out[kRIndex] = MIN(out[kRIndex] + (in[kRIndex] * ina >> 8), 255u);
-				}
-
-				in += inStep;
-				out += 4;
-			}
-			outo += pitch;
-			ino += inoStep;
-		}
-	}
-}
-
-/**
- * Optimized version of doBlit to be used with subtractive blended blitting
- */
-void doBlitSubtractiveBlend(byte *ino, byte *outo, uint32 width, uint32 height, uint32 pitch, int32 inStep, int32 inoStep, uint32 color) {
-	byte *in;
-	byte *out;
-
-	if (color == 0xffffffff) {
-
-		for (uint32 i = 0; i < height; i++) {
-			out = outo;
-			in = ino;
-			for (uint32 j = 0; j < width; j++) {
-
-				if (in[kAIndex] != 0) {
-					out[kRIndex] = MAX(out[kRIndex] - ((in[kRIndex] * out[kRIndex]) * in[kAIndex] >> 16), 0);
-					out[kGIndex] = MAX(out[kGIndex] - ((in[kGIndex] * out[kGIndex]) * in[kAIndex] >> 16), 0);
-					out[kBIndex] = MAX(out[kBIndex] - ((in[kBIndex] * out[kBIndex]) * in[kAIndex] >> 16), 0);
-				}
-
-				in += inStep;
-				out += 4;
-			}
-			outo += pitch;
-			ino += inoStep;
-		}
-	} else {
-
-		byte cr = (color >> kRModShift) & 0xFF;
-		byte cg = (color >> kGModShift) & 0xFF;
-		byte cb = (color >> kBModShift) & 0xFF;
-
-		for (uint32 i = 0; i < height; i++) {
-			out = outo;
-			in = ino;
-			for (uint32 j = 0; j < width; j++) {
-
-				out[kAIndex] = 255;
-				if (cb != 255) {
-					out[kBIndex] = MAX(out[kBIndex] - ((in[kBIndex] * cb  * (out[kBIndex]) * in[kAIndex]) >> 24), 0);
-				} else {
-					out[kBIndex] = MAX(out[kBIndex] - (in[kBIndex] * (out[kBIndex]) * in[kAIndex] >> 16), 0);
-				}
-
-				if (cg != 255) {
-					out[kGIndex] = MAX(out[kGIndex] - ((in[kGIndex] * cg  * (out[kGIndex]) * in[kAIndex]) >> 24), 0);
-				} else {
-					out[kGIndex] = MAX(out[kGIndex] - (in[kGIndex] * (out[kGIndex]) * in[kAIndex] >> 16), 0);
-				}
-
-				if (cr != 255) {
-					out[kRIndex] = MAX(out[kRIndex] - ((in[kRIndex] * cr * (out[kRIndex]) * in[kAIndex]) >> 24), 0);
-				} else {
-					out[kRIndex] = MAX(out[kRIndex] - (in[kRIndex] * (out[kRIndex]) * in[kAIndex] >> 16), 0);
-				}
-
-				in += inStep;
-				out += 4;
-			}
-			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, TSpriteBlendMode blendMode) {
-
-	Common::Rect retSize;
-	retSize.top = 0;
-	retSize.left = 0;
-	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;
-	}
-
-	// Create an encapsulating surface for the data
-	TransparentSurface srcImage(*this, false);
-	// TODO: Is the data really in the screen format?
-	if (format.bytesPerPixel != 4) {
-		warning("TransparentSurface can only blit 32 bpp images");
-		return retSize;
-	}
-
-	if (pPartRect) {
-
-		int xOffset = pPartRect->left;
-		int yOffset = pPartRect->top;
-
-		if (flipping & FLIP_V) {
-			yOffset = srcImage.h - pPartRect->bottom;
-		}
-
-		if (flipping & FLIP_H) {
-			xOffset = srcImage.w - pPartRect->right;
-		}
-
-		srcImage.pixels = getBasePtr(xOffset, yOffset);
-		srcImage.w = pPartRect->width();
-		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);
-	} 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);
-	}
-
-	if (width == -1) {
-		width = srcImage.w;
-	}
-	if (height == -1) {
-		height = srcImage.h;
-	}
-
-#ifdef SCALING_TESTING
-	// Hardcode scaling to 66% to test scaling
-	width = width * 2 / 3;
-	height = height * 2 / 3;
-#endif
-
-	Graphics::Surface *img = nullptr;
-	Graphics::Surface *imgScaled = nullptr;
-	byte *savedPixels = nullptr;
-	if ((width != srcImage.w) || (height != srcImage.h)) {
-		// Scale the image
-		img = imgScaled = srcImage.scale(width, height);
-		savedPixels = (byte *)img->getPixels();
-	} else {
-		img = &srcImage;
-	}
-
-	// Handle off-screen clipping
-	if (posY < 0) {
-		img->h = MAX(0, (int)img->h - -posY);
-		img->setPixels((byte *)img->getBasePtr(0, -posY));
-		posY = 0;
-	}
-
-	if (posX < 0) {
-		img->w = MAX(0, (int)img->w - -posX);
-		img->setPixels((byte *)img->getBasePtr(-posX, 0));
-		posX = 0;
-	}
-
-	img->w = CLIP((int)img->w, 0, (int)MAX((int)target.w - posX, 0));
-	img->h = CLIP((int)img->h, 0, (int)MAX((int)target.h - posY, 0));
-
-	if ((img->w > 0) && (img->h > 0)) {
-		int xp = 0, yp = 0;
-
-		int inStep = 4;
-		int inoStep = img->pitch;
-		if (flipping & TransparentSurface::FLIP_H) {
-			inStep = -inStep;
-			xp = img->w - 1;
-		}
-
-		if (flipping & TransparentSurface::FLIP_V) {
-			inoStep = -inoStep;
-			yp = img->h - 1;
-		}
-
-		byte *ino = (byte *)img->getBasePtr(xp, yp);
-		byte *outo = (byte *)target.getBasePtr(posX, posY);
-
-		if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_OPAQUE) {
-			doBlitOpaqueFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
-		} else if (color == 0xFFFFFFFF && blendMode == BLEND_NORMAL && _alphaMode == ALPHA_BINARY) {
-			doBlitBinaryFast(ino, outo, img->w, img->h, target.pitch, inStep, inoStep);
-		} else {
-			if (blendMode == BLEND_ADDITIVE) {
-				doBlitAdditiveBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
-			} else if (blendMode == BLEND_SUBTRACTIVE) {
-				doBlitSubtractiveBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
-			} else {
-				assert(blendMode == BLEND_NORMAL);
-				doBlitAlphaBlend(ino, outo, img->w, img->h, target.pitch, inStep, inoStep, color);
-			}
-		}
-
-	}
-
-	retSize.setWidth(img->w);
-	retSize.setHeight(img->h);
-
-	if (imgScaled) {
-		imgScaled->setPixels(savedPixels);
-		imgScaled->free();
-		delete imgScaled;
-	}
-
-	return retSize;
-}
-
-/**
- * Writes a color key to the alpha channel of the surface
- * @param rKey  the red component of the color key
- * @param gKey  the green component of the color key
- * @param bKey  the blue component of the color key
- * @param overwriteAlpha if true, all other alpha will be set fully opaque
- */
-void TransparentSurface::applyColorKey(uint8 rKey, uint8 gKey, uint8 bKey, bool overwriteAlpha) {
-	assert(format.bytesPerPixel == 4);
-	for (int i = 0; i < h; i++) {
-		for (int j = 0; j < w; j++) {
-			uint32 pix = ((uint32 *)pixels)[i * w + j];
-			uint8 r, g, b, a;
-			format.colorToARGB(pix, a, r, g, b);
-			if (r == rKey && g == gKey && b == bKey) {
-				a = 0;
-				((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
-			} else if (overwriteAlpha) {
-				a = 255;
-				((uint32 *)pixels)[i * w + j] = format.ARGBToColor(a, r, g, b);
-			}
-		}
-	}
-}
-
-TransparentSurface::AlphaType TransparentSurface::getAlphaMode() const {
-	return _alphaMode;
-}
-
-void TransparentSurface::setAlphaMode(TransparentSurface::AlphaType mode) {
-	_alphaMode = mode;
-}
-
-
-
-
-
-
-/*
-
-The below two functions are adapted from SDL_rotozoom.c,
-taken from SDL_gfx-2.0.18.
-
-Its copyright notice:
-
-=============================================================================
-SDL_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
-
-Copyright (C) 2001-2012  Andreas Schiffler
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not
-claim that you wrote the original software. If you use this software
-in a product, an acknowledgment in the product documentation would be
-appreciated but is not required.
-
-2. Altered source versions must be plainly marked as such, and must not be
-misrepresented as being the original software.
-
-3. This notice may not be removed or altered from any source
-distribution.
-
-Andreas Schiffler -- aschiffler at ferzkopp dot net
-=============================================================================
-
-
-The functions have been adapted for different structures and coordinate
-systems.
-
-*/
-
-
-
-
-
-TransparentSurface *TransparentSurface::rotoscale(const TransformStruct &transform) const {
-
-	assert(transform._angle != 0); // This would not be ideal; rotoscale() should never be called in conditional branches where angle = 0 anyway.
-
-	Point32 newHotspot;
-	Common::Rect srcRect(0, 0, (int16)w, (int16)h);
-	Rect32 rect = TransformTools::newRect(Rect32(srcRect), transform, &newHotspot);
-	Common::Rect dstRect(0, 0, (int16)(rect.right - rect.left), (int16)(rect.bottom - rect.top));
-
-	TransparentSurface *target = new TransparentSurface();
-	assert(format.bytesPerPixel == 4);
-
-	int srcW = w;
-	int srcH = h;
-	int dstW = dstRect.width();
-	int dstH = dstRect.height();
-
-	target->create((uint16)dstW, (uint16)dstH, this->format);
-
-	if (transform._zoom.x == 0 || transform._zoom.y == 0) {
-		return target;
-	}
-
-	uint32 invAngle = 360 - (transform._angle % 360);
-	float invCos = cos(invAngle * M_PI / 180.0);
-	float invSin = sin(invAngle * M_PI / 180.0);
-
-	struct tColorRGBA { byte r; byte g; byte b; byte a; };
-	int icosx = (int)(invCos * (65536.0f * kDefaultZoomX / transform._zoom.x));
-	int isinx = (int)(invSin * (65536.0f * kDefaultZoomX / transform._zoom.x));
-	int icosy = (int)(invCos * (65536.0f * kDefaultZoomY / transform._zoom.y));
-	int isiny = (int)(invSin * (65536.0f * kDefaultZoomY / transform._zoom.y));
-
-
-	bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
-
-	int xd = (srcRect.left + transform._hotspot.x) << 16;
-	int yd = (srcRect.top + transform._hotspot.y) << 16;
-	int cx = newHotspot.x;
-	int cy = newHotspot.y;
-
-	int ax = -icosx * cx;
-	int ay = -isiny * cx;
-	int sw = srcW - 1;
-	int sh = srcH - 1;
-
-	tColorRGBA *pc = (tColorRGBA*)target->getBasePtr(0, 0);
-
-	for (int y = 0; y < dstH; y++) {
-		int t = cy - y;
-		int sdx = ax + (isinx * t) + xd;
-		int sdy = ay - (icosy * t) + yd;
-		for (int x = 0; x < dstW; x++) {
-			int dx = (sdx >> 16);
-			int dy = (sdy >> 16);
-			if (flipx) {
-				dx = sw - dx;
-			}
-			if (flipy) {
-				dy = sh - dy;
-			}
-
-#ifdef ENABLE_BILINEAR
-			if ((dx > -1) && (dy > -1) && (dx < sw) && (dy < sh)) {
-				const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
-				tColorRGBA c00, c01, c10, c11, cswap;
-				c00 = *sp;
-				sp += 1;
-				c01 = *sp;
-				sp += (this->pitch / 4);
-				c11 = *sp;
-				sp -= 1;
-				c10 = *sp;
-				if (flipx) {
-					cswap = c00; c00=c01; c01=cswap;
-					cswap = c10; c10=c11; c11=cswap;
-				}
-				if (flipy) {
-					cswap = c00; c00=c10; c10=cswap;
-					cswap = c01; c01=c11; c11=cswap;
-				}
-				/*
-				* Interpolate colors
-				*/
-				int ex = (sdx & 0xffff);
-				int ey = (sdy & 0xffff);
-				int t1, t2;
-				t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff;
-				t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff;
-				pc->r = (((t2 - t1) * ey) >> 16) + t1;
-				t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff;
-				t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff;
-				pc->g = (((t2 - t1) * ey) >> 16) + t1;
-				t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff;
-				t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff;
-				pc->b = (((t2 - t1) * ey) >> 16) + t1;
-				t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff;
-				t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff;
-				pc->a = (((t2 - t1) * ey) >> 16) + t1;
-			}
-#else
-			if ((dx >= 0) && (dy >= 0) && (dx < srcW) && (dy < srcH)) {
-				const tColorRGBA *sp = (const tColorRGBA *)getBasePtr(dx, dy);
-				*pc = *sp;
-			}
-#endif
-			sdx += icosx;
-			sdy += isiny;
-			pc++;
-		}
-	}
-	return target;
-}
-
-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);
-
-	TransparentSurface *target = new TransparentSurface();
-
-	assert(format.bytesPerPixel == 4);
-
-	int srcW = srcRect.width();
-	int srcH = srcRect.height();
-	int dstW = dstRect.width();
-	int dstH = dstRect.height();
-
-	target->create((uint16)dstW, (uint16)dstH, this->format);
-
-#ifdef ENABLE_BILINEAR
-
-	// NB: The actual order of these bytes may not be correct, but
-	// since all values are treated equal, that does not matter.
-	struct tColorRGBA { byte r; byte g; byte b; byte a; };
-
-	bool flipx = false, flipy = false; // TODO: See mirroring comment in RenderTicket ctor
-
-
-	int *sax = new int[dstW + 1];
-	int *say = new int[dstH + 1];
-	assert(sax && say);
-
-	/*
-	* Precalculate row increments
-	*/
-	int spixelw = (srcW - 1);
-	int spixelh = (srcH - 1);
-	int sx = (int) (65536.0f * (float) spixelw / (float) (dstW - 1));
-	int sy = (int) (65536.0f * (float) spixelh / (float) (dstH - 1));
-
-	/* Maximum scaled source size */
-	int ssx = (srcW << 16) - 1;
-	int ssy = (srcH << 16) - 1;
-
-	/* Precalculate horizontal row increments */
-	int csx = 0;
-	int *csax = sax;
-	for (int x = 0; x <= dstW; x++) {
-		*csax = csx;
-		csax++;
-		csx += sx;
-
-		/* Guard from overflows */
-		if (csx > ssx) {
-			csx = ssx;
-		}
-	}
-
-	/* Precalculate vertical row increments */
-	int csy = 0;
-	int *csay = say;
-	for (int y = 0; y <= dstH; y++) {
-		*csay = csy;
-		csay++;
-		csy += sy;
-
-		/* Guard from overflows */
-		if (csy > ssy) {
-			csy = ssy;
-		}
-	}
-
-	const tColorRGBA *sp = (const tColorRGBA *) getBasePtr(0, 0);
-	tColorRGBA *dp = (tColorRGBA *) target->getBasePtr(0, 0);
-	int spixelgap = srcW;
-
-	if (flipx) {
-		sp += spixelw;
-	}
-	if (flipy) {
-		sp += spixelgap * spixelh;
-	}
-
-	csay = say;
-	for (int y = 0; y < dstH; y++) {
-		const tColorRGBA *csp = sp;
-		csax = sax;
-		for (int x = 0; x < dstW; x++) {
-			/*
-			* Setup color source pointers
-			*/
-			int ex = (*csax & 0xffff);
-			int ey = (*csay & 0xffff);
-			int cx = (*csax >> 16);
-			int cy = (*csay >> 16);
-
-			const tColorRGBA *c00, *c01, *c10, *c11;
-			c00 = sp;
-			c01 = sp;
-			c10 = sp;
-			if (cy < spixelh) {
-				if (flipy) {
-					c10 -= spixelgap;
-				} else {
-					c10 += spixelgap;
-				}
-			}
-			c11 = c10;
-			if (cx < spixelw) {
-				if (flipx) {
-					c01--;
-					c11--;
-				} else {
-					c01++;
-					c11++;
-				}
-			}
-
-			/*
-			* Draw and interpolate colors
-			*/
-			int t1, t2;
-			t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
-			t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
-			dp->r = (((t2 - t1) * ey) >> 16) + t1;
-			t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
-			t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
-			dp->g = (((t2 - t1) * ey) >> 16) + t1;
-			t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
-			t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
-			dp->b = (((t2 - t1) * ey) >> 16) + t1;
-			t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
-			t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
-			dp->a = (((t2 - t1) * ey) >> 16) + t1;
-
-			/*
-			* Advance source pointer x
-			*/
-			int *salastx = csax;
-			csax++;
-			int sstepx = (*csax >> 16) - (*salastx >> 16);
-			if (flipx) {
-				sp -= sstepx;
-			} else {
-				sp += sstepx;
-			}
-
-			/*
-			* Advance destination pointer x
-			*/
-			dp++;
-		}
-		/*
-		* Advance source pointer y
-		*/
-		int *salasty = csay;
-		csay++;
-		int sstepy = (*csay >> 16) - (*salasty >> 16);
-		sstepy *= spixelgap;
-		if (flipy) {
-			sp = csp - sstepy;
-		} else {
-			sp = csp + sstepy;
-		}
-	}
-
-	delete[] sax;
-	delete[] say;
-
-#else
-
-	int *scaleCacheX = new int[dstW];
-	for (int x = 0; x < dstW; x++) {
-		scaleCacheX[x] = (x * srcW) / dstW;
-	}
-
-	for (int y = 0; y < dstH; y++) {
-		uint32 *destP = (uint32 *)target->getBasePtr(0, y);
-		const uint32 *srcP = (const uint32 *)getBasePtr(0, (y * srcH) / dstH);
-		for (int x = 0; x < dstW; x++) {
-			*destP++ = srcP[scaleCacheX[x]];
-		}
-	}
-	delete[] scaleCacheX;
-
-#endif
-
-	return target;
-
-}
-
-} // End of namespace Wintermute
diff --git a/engines/wintermute/graphics/transparent_surface.h b/engines/wintermute/graphics/transparent_surface.h
deleted file mode 100644
index e5049a5..0000000
--- a/engines/wintermute/graphics/transparent_surface.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef GRAPHICS_TRANSPARENTSURFACE_H
-#define GRAPHICS_TRANSPARENTSURFACE_H
-
-#include "graphics/surface.h"
-#include "engines/wintermute/graphics/transform_struct.h"
-
-/*
- * This code is based on Broken Sword 2.5 engine
- *
- * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
- *
- * Licensed under GNU GPL v2
- *
- */
-
-// TODO: Find a better solution for this.
-#define BS_RGB(R,G,B)       (0xFF000000 | ((R) << 16) | ((G) << 8) | (B))
-#define BS_ARGB(A,R,G,B)    (((A) << 24) | ((R) << 16) | ((G) << 8) | (B))
-
-namespace Wintermute {
-
-/**
- * A transparent graphics surface, which implements alpha blitting.
- */
-struct TransparentSurface : public Graphics::Surface {
-	TransparentSurface();
-	TransparentSurface(const Graphics::Surface &surf, bool copyData = false);
-
-	void setColorKey(char r, char g, char b);
-	void disableColorKey();
-
-	// Enums
-	/**
-	 @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
-	};
-
-	enum AlphaType {
-	    ALPHA_OPAQUE = 0,
-	    ALPHA_BINARY = 1,
-	    ALPHA_FULL = 2
-	};
-
-
-	/**
-	 @brief renders the surface to another surface
-	 @param target a pointer to the target surface. In most cases this is the framebuffer.
-	 @param posX the position on the X-axis in the target image in pixels where the image is supposed to be rendered.<br>
-	 The default value is 0.
-	 @param posY the position on the Y-axis in the target image in pixels where the image is supposed to be rendered.<br>
-	 The default value is 0.
-	 @param flipping how the the image should be flipped.<br>
-	 The default value is BS_Image::FLIP_NONE (no flipping)
-	 @param pPartRect Pointer on Common::Rect which specifies the section to be rendered. If the whole image has to be rendered the Pointer is NULL.<br>
-	 This referes to the unflipped and unscaled image.<br>
-	 The default value is NULL.
-	 @param color an ARGB color value, which determines the parameters for the color modulation und alpha blending.<br>
-	 The alpha component of the color determines the alpha blending parameter (0 = no covering, 255 = full covering).<br>
-	 The color components determines the color for color modulation.<br>
-	 The default value is BS_ARGB(255, 255, 255, 255) (full covering, no color modulation).
-	 The macros BS_RGB and BS_ARGB can be used for the creation of the color value.
-	 @param width the output width of the screen section.
-	 The images will be scaled if the output width of the screen section differs from the image section.<br>
-	 The value -1 determines that the image should not be scaled.<br>
-	 The default value is -1.
-	 @param height the output height of the screen section.
-	 The images will be scaled if the output width of the screen section differs from the image section.<br>
-	 The value -1 determines that the image should not be scaled.<br>
-	 The default value is -1.
-	 @return returns false if the rendering failed.
-	 */
-	Common::Rect blit(Graphics::Surface &target, int posX = 0, int posY = 0,
-	                  int flipping = FLIP_NONE,
-	                  Common::Rect *pPartRect = nullptr,
-	                  uint color = BS_ARGB(255, 255, 255, 255),
-	                  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 newWidth the resulting width.
-	 * @param newHeight the resulting height.
-	 * @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;
-	AlphaType getAlphaMode() const;
-	void setAlphaMode(AlphaType);
-private:
-	AlphaType _alphaMode;
-
-};
-
-/**
- * A deleter for Surface objects which can be used with SharedPtr.
- *
- * This deleter assures Surface::free is called on deletion.
- */
-/*struct SharedPtrTransparentSurfaceDeleter {
-    void operator()(TransparentSurface *ptr) {
-        ptr->free();
-        delete ptr;
-    }
-};*/
-
-} // End of namespace Wintermute
-
-
-#endif
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index 19fb3d6..1b6c52e 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -89,9 +89,6 @@ MODULE_OBJS := \
 	base/save_thumb_helper.o \
 	base/timer.o \
 	detection.o \
-	graphics/transform_struct.o \
-	graphics/transform_tools.o \
-	graphics/transparent_surface.o \
 	math/math_util.o \
 	math/matrix4.o \
 	math/vector2.o \


Commit: 5c706dde274753b62c9fc72d5d33b4f42100c11a
    https://github.com/scummvm/scummvm/commit/5c706dde274753b62c9fc72d5d33b4f42100c11a
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2014-06-15T15:43:25+03:00

Commit Message:
SWORD25: Switch to common TransparentSurface

Changed paths:
    engines/sword25/gfx/animation.cpp
    engines/sword25/gfx/bitmapresource.h
    engines/sword25/gfx/dynamicbitmap.cpp
    engines/sword25/gfx/graphicengine.cpp
    engines/sword25/gfx/image/image.h
    engines/sword25/gfx/image/imgloader.cpp
    engines/sword25/gfx/image/renderedimage.cpp
    engines/sword25/gfx/image/renderedimage.h
    engines/sword25/gfx/image/swimage.h
    engines/sword25/gfx/image/vectorimage.h
    engines/sword25/gfx/image/vectorimagerenderer.cpp
    engines/sword25/gfx/staticbitmap.cpp
    engines/sword25/gfx/text.cpp
    engines/sword25/sword25.cpp



diff --git a/engines/sword25/gfx/animation.cpp b/engines/sword25/gfx/animation.cpp
index eeb7885..e2662fb 100644
--- a/engines/sword25/gfx/animation.cpp
+++ b/engines/sword25/gfx/animation.cpp
@@ -189,14 +189,14 @@ bool Animation::doRender(RectangleList *updateRects) {
 	bool result;
 	if (isScalingAllowed() && (_width != pBitmapResource->getWidth() || _height != pBitmapResource->getHeight())) {
 		result = pBitmapResource->blit(_absoluteX, _absoluteY,
-		                               (animationDescriptionPtr->getFrame(_currentFrame).flipV ? BitmapResource::FLIP_V : 0) |
-		                               (animationDescriptionPtr->getFrame(_currentFrame).flipH ? BitmapResource::FLIP_H : 0),
+		                               (animationDescriptionPtr->getFrame(_currentFrame).flipV ? Graphics::FLIP_V : 0) |
+		                               (animationDescriptionPtr->getFrame(_currentFrame).flipH ? Graphics::FLIP_H : 0),
 		                               0, _modulationColor, _width, _height,
 									   updateRects);
 	} else {
 		result = pBitmapResource->blit(_absoluteX, _absoluteY,
-		                               (animationDescriptionPtr->getFrame(_currentFrame).flipV ? BitmapResource::FLIP_V : 0) |
-		                               (animationDescriptionPtr->getFrame(_currentFrame).flipH ? BitmapResource::FLIP_H : 0),
+		                               (animationDescriptionPtr->getFrame(_currentFrame).flipV ? Graphics::FLIP_V : 0) |
+		                               (animationDescriptionPtr->getFrame(_currentFrame).flipH ? Graphics::FLIP_H : 0),
 		                               0, _modulationColor, -1, -1,
 									   updateRects);
 	}
diff --git a/engines/sword25/gfx/bitmapresource.h b/engines/sword25/gfx/bitmapresource.h
index 7a4daed..2ae891f 100644
--- a/engines/sword25/gfx/bitmapresource.h
+++ b/engines/sword25/gfx/bitmapresource.h
@@ -40,22 +40,6 @@ namespace Sword25 {
 
 class BitmapResource : public Resource {
 public:
-	/**
-	    @brief Die möglichen Flippingparameter für die Blit-Methode.
-	*/
-	enum FLIP_FLAGS {
-		/// Das Bild wird nicht gespiegelt.
-		FLIP_NONE = 0,
-		/// Das Bild wird an der horizontalen Achse gespiegelt.
-		FLIP_H = 1,
-		/// Das Bild wird an der vertikalen Achse gespiegelt.
-		FLIP_V = 2,
-		/// Das Bild wird an der horizontalen und vertikalen Achse gespiegelt.
-		FLIP_HV = FLIP_H | FLIP_V,
-		/// Das Bild wird an der horizontalen und vertikalen Achse gespiegelt.
-		FLIP_VH = FLIP_H | FLIP_V
-	};
-
 	BitmapResource(const Common::String &filename, Image *pImage) :
 					_pImage(pImage), Resource(filename, Resource::TYPE_BITMAP) {}
 	virtual ~BitmapResource() { delete _pImage; }
@@ -120,7 +104,7 @@ public:
 	            - IsColorModulationAllowed()
 	*/
 	bool blit(int posX = 0, int posY = 0,
-	          int flipping = FLIP_NONE,
+	          int flipping = Graphics::FLIP_NONE,
 	          Common::Rect *pSrcPartRect = NULL,
 	          uint color = BS_ARGB(255, 255, 255, 255),
 	          int width = -1, int height = -1,
diff --git a/engines/sword25/gfx/dynamicbitmap.cpp b/engines/sword25/gfx/dynamicbitmap.cpp
index ce9c056..a335f87 100644
--- a/engines/sword25/gfx/dynamicbitmap.cpp
+++ b/engines/sword25/gfx/dynamicbitmap.cpp
@@ -86,8 +86,8 @@ bool DynamicBitmap::doRender(RectangleList *updateRects) {
 		// a bit slow when drawing videos, but it's not the main
 		// bottleneck.
 		result = _image->blit(_absoluteX, _absoluteY,
-		                       (_flipV ? BitmapResource::FLIP_V : 0) |
-		                       (_flipH ? BitmapResource::FLIP_H : 0),
+		                       (_flipV ? Graphics::FLIP_V : 0) |
+		                       (_flipH ? Graphics::FLIP_H : 0),
 		                       0, _modulationColor, -1, -1,
 							   updateRects);
 #else
@@ -105,8 +105,8 @@ bool DynamicBitmap::doRender(RectangleList *updateRects) {
 		return true;
 	} else {
 		result = _image->blit(_absoluteX, _absoluteY,
-		                       (_flipV ? BitmapResource::FLIP_V : 0) |
-		                       (_flipH ? BitmapResource::FLIP_H : 0),
+		                       (_flipV ? Graphics::FLIP_V : 0) |
+		                       (_flipH ? Graphics::FLIP_H : 0),
 		                       0, _modulationColor, _width, _height,
 							   updateRects);
 	}
diff --git a/engines/sword25/gfx/graphicengine.cpp b/engines/sword25/gfx/graphicengine.cpp
index 2a870c0..f887c3c 100644
--- a/engines/sword25/gfx/graphicengine.cpp
+++ b/engines/sword25/gfx/graphicengine.cpp
@@ -183,7 +183,7 @@ bool GraphicEngine::fill(const Common::Rect *fillRectPtr, uint color) {
 
 	if (rect.width() > 0 && rect.height() > 0) {
 		if (ca == 0xff) {
-			_backSurface.fillRect(rect, color);
+			_backSurface.fillRect(rect, BS_ARGB(cr, cg, cb, ca));
 		} else {
 			byte *outo = (byte *)_backSurface.getBasePtr(rect.left, rect.top);
 			byte *out;
@@ -192,23 +192,23 @@ bool GraphicEngine::fill(const Common::Rect *fillRectPtr, uint color) {
 				out = outo;
 				for (int j = rect.left; j < rect.right; j++) {
 #if defined(SCUMM_LITTLE_ENDIAN)
+					*out = 255;
+					out++;
 					*out += (byte)(((cb - *out) * ca) >> 8);
 					out++;
 					*out += (byte)(((cg - *out) * ca) >> 8);
 					out++;
 					*out += (byte)(((cr - *out) * ca) >> 8);
 					out++;
-					*out = 255;
-					out++;
 #else
-					*out = 255;
-					out++;
 					*out += (byte)(((cr - *out) * ca) >> 8);
 					out++;
 					*out += (byte)(((cg - *out) * ca) >> 8);
 					out++;
 					*out += (byte)(((cb - *out) * ca) >> 8);
 					out++;
+					*out = 255;
+					out++;
 #endif
 				}
 
diff --git a/engines/sword25/gfx/image/image.h b/engines/sword25/gfx/image/image.h
index 8fbf802..f8cb0df 100644
--- a/engines/sword25/gfx/image/image.h
+++ b/engines/sword25/gfx/image/image.h
@@ -43,6 +43,7 @@
 #include "sword25/kernel/common.h"
 #include "common/rect.h"
 #include "sword25/gfx/graphicengine.h"
+#include "graphics/transparent_surface.h"
 
 namespace Sword25 {
 
@@ -52,23 +53,6 @@ class Image {
 public:
 	virtual ~Image() {}
 
-	// Enums
-	/**
-	    @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
-	};
-
 	//@{
 	/** @name Accessor methods */
 
@@ -100,7 +84,7 @@ public:
 	    @param PosY the position on the Y-axis in the target image in pixels where the image is supposed to be rendered.<br>
 	                The default value is 0.
 	    @param Flipping how the the image should be flipped.<br>
-	                    The default value is BS_Image::FLIP_NONE (no flipping)
+	                    The default value is Graphics::FLIP_NONE (no flipping)
 	    @param pSrcPartRect Pointer on Common::Rect which specifies the section to be rendered. If the whole image has to be rendered the Pointer is NULL.<br>
 	                        This referes to the unflipped and unscaled image.<br>
 	                        The default value is NULL.
@@ -128,7 +112,7 @@ public:
 	            - IsSetContentAllowed()
 	*/
 	virtual bool blit(int posX = 0, int posY = 0,
-	                  int flipping = FLIP_NONE,
+	                  int flipping = Graphics::FLIP_NONE,
 	                  Common::Rect *pPartRect = NULL,
 	                  uint color = BS_ARGB(255, 255, 255, 255),
 	                  int width = -1, int height = -1,
diff --git a/engines/sword25/gfx/image/imgloader.cpp b/engines/sword25/gfx/image/imgloader.cpp
index b4b3030..f299cee 100644
--- a/engines/sword25/gfx/image/imgloader.cpp
+++ b/engines/sword25/gfx/image/imgloader.cpp
@@ -45,7 +45,7 @@ bool ImgLoader::decodePNGImage(const byte *fileDataPtr, uint fileSize, byte *&un
 		error("Error while reading PNG image");
 
 	const Graphics::Surface *sourceSurface = png.getSurface();
-	Graphics::Surface *pngSurface = sourceSurface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24), png.getPalette());
+	Graphics::Surface *pngSurface = sourceSurface->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0), png.getPalette());
 
 	width = pngSurface->w;
 	height = pngSurface->h;
@@ -70,7 +70,7 @@ bool ImgLoader::decodeThumbnailImage(const byte *pFileData, uint fileSize, byte
 	uint32 totalSize = pitch * height;
 	pUncompressedData = new byte[totalSize];
 	uint32 *dst = (uint32 *)pUncompressedData;	// treat as uint32, for pixelformat output
-	const Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
+	const Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	byte r, g, b;
 
 	for (uint32 i = 0; i < totalSize / 4; i++) {
diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index 107b4cd..de79630 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -100,9 +100,6 @@ static byte *readSavegameThumbnail(const Common::String &filename, uint &fileSiz
 }
 
 RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
-	_data(0),
-	_width(0),
-	_height(0),
 	_isTransparent(true) {
 	result = false;
 
@@ -130,10 +127,18 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
 
 	// Uncompress the image
 	int pitch;
+	byte *dst;
+	int w, h;
 	if (isPNG)
-		result = ImgLoader::decodePNGImage(pFileData, fileSize, _data, _width, _height, pitch);
+		result = ImgLoader::decodePNGImage(pFileData, fileSize, dst, w, h, pitch);
 	else
-		result = ImgLoader::decodeThumbnailImage(pFileData, fileSize, _data, _width, _height, pitch);
+		result = ImgLoader::decodeThumbnailImage(pFileData, fileSize, dst, w, h, pitch);
+
+	_surface.w = w;
+	_surface.h = h;
+	_surface.pitch = w * 4;
+	_surface.setPixels(dst);
+	_surface.format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 
 	if (!result) {
 		error("Could not decode image.");
@@ -157,12 +162,9 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
 // -----------------------------------------------------------------------------
 
 RenderedImage::RenderedImage(uint width, uint height, bool &result) :
-	_width(width),
-	_height(height),
 	_isTransparent(true) {
 
-	_data = new byte[width * height * 4];
-	Common::fill(_data, &_data[width * height * 4], 0);
+	_surface.create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
 
 	_backSurface = Kernel::getInstance()->getGfx()->getSurface();
 
@@ -172,9 +174,11 @@ RenderedImage::RenderedImage(uint width, uint height, bool &result) :
 	return;
 }
 
-RenderedImage::RenderedImage() : _width(0), _height(0), _data(0), _isTransparent(true) {
+RenderedImage::RenderedImage() : _isTransparent(true) {
 	_backSurface = Kernel::getInstance()->getGfx()->getSurface();
 
+	_surface.format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+
 	_doCleanup = false;
 
 	return;
@@ -183,8 +187,6 @@ RenderedImage::RenderedImage() : _width(0), _height(0), _data(0), _isTransparent
 // -----------------------------------------------------------------------------
 
 RenderedImage::~RenderedImage() {
-	if (_doCleanup)
-		delete[] _data;
 }
 
 // -----------------------------------------------------------------------------
@@ -198,17 +200,17 @@ bool RenderedImage::fill(const Common::Rect *pFillRect, uint color) {
 
 bool RenderedImage::setContent(const byte *pixeldata, uint size, uint offset, uint stride) {
 	// Check if PixelData contains enough pixel to create an image with image size equals width * height
-	if (size < static_cast<uint>(_width * _height * 4)) {
-		error("PixelData vector is too small to define a 32 bit %dx%d image.", _width, _height);
+	if (size < static_cast<uint>(_surface.w * _surface.h * 4)) {
+		error("PixelData vector is too small to define a 32 bit %dx%d image.", _surface.w, _surface.h);
 		return false;
 	}
 
 	const byte *in = &pixeldata[offset];
-	byte *out = _data;
+	byte *out = (byte *)_surface.getPixels();
 
-	for (int i = 0; i < _height; i++) {
-		memcpy(out, in, _width * 4);
-		out += _width * 4;
+	for (int i = 0; i < _surface.h; i++) {
+		memcpy(out, in, _surface.w * 4);
+		out += _surface.w * 4;
 		in += stride;
 	}
 
@@ -216,9 +218,10 @@ bool RenderedImage::setContent(const byte *pixeldata, uint size, uint offset, ui
 }
 
 void RenderedImage::replaceContent(byte *pixeldata, int width, int height) {
-	_width = width;
-	_height = height;
-	_data = pixeldata;
+	_surface.w = width;
+	_surface.h = height;
+	_surface.pitch = width * 4;
+	_surface.setPixels(pixeldata);
 }
 // -----------------------------------------------------------------------------
 
@@ -230,251 +233,26 @@ uint RenderedImage::getPixel(int x, int y) {
 // -----------------------------------------------------------------------------
 
 bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRect, uint color, int width, int height, RectangleList *updateRects) {
-	int ca = (color >> 24) & 0xff;
-
-	// Check if we need to draw anything at all
-	if (ca == 0)
-		return true;
-
-	int cr = (color >> 16) & 0xff;
-	int cg = (color >> 8) & 0xff;
-	int cb = (color >> 0) & 0xff;
-
-	// Create an encapsulating surface for the data
-	Graphics::Surface srcImage;
-	// TODO: Is the data really in the screen format?
-	srcImage.init(_width, _height, _width * 4, _data, g_system->getScreenFormat());
-
-	if (pPartRect) {
-		srcImage.setPixels(&_data[pPartRect->top * srcImage.pitch + pPartRect->left * 4]);
-		srcImage.w = pPartRect->right - pPartRect->left;
-		srcImage.h = pPartRect->bottom - pPartRect->top;
-
-		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);
-	} 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);
-	}
-
-	if (width == -1)
-		width = srcImage.w;
-	if (height == -1)
-		height = srcImage.h;
-
-#ifdef SCALING_TESTING
-	// Hardcode scaling to 66% to test scaling
-	width = width * 2 / 3;
-	height = height * 2 / 3;
-#endif
-
-	Graphics::Surface *img;
-	Graphics::Surface *imgScaled = NULL;
-	byte *savedPixels = NULL;
-	if ((width != srcImage.w) || (height != srcImage.h)) {
-		// Scale the image
-		img = imgScaled = scale(srcImage, width, height);
-		savedPixels = (byte *)img->getPixels();
-	} else {
-		img = &srcImage;
-	}
-
-	for (RectangleList::iterator it = updateRects->begin(); it != updateRects->end(); ++it) {
-		const Common::Rect &clipRect = *it;
-
-		int skipLeft = 0, skipTop = 0;
-		int drawX = posX, drawY = posY;
-		int drawWidth = img->w;
-		int drawHeight = img->h;
-
-		// Handle clipping
-		if (drawX < clipRect.left) {
-			skipLeft = clipRect.left - drawX;
-			drawWidth -= skipLeft;
-			drawX = clipRect.left;
-		}
-
-		if (drawY < clipRect.top) {
-			skipTop = clipRect.top - drawY;
-			drawHeight -= skipTop;
-			drawY = clipRect.top;
-		}
-
-		if (drawX + drawWidth >= clipRect.right)
-			drawWidth = clipRect.right - drawX;
-
-		if (drawY + drawHeight >= clipRect.bottom)
-			drawHeight = clipRect.bottom - drawY;
-
-		if ((drawWidth > 0) && (drawHeight > 0)) {
-			int xp = 0, yp = 0;
-
-			int inStep = 4;
-			int inoStep = img->pitch;
-			if (flipping & Image::FLIP_V) {
-				inStep = -inStep;
-				xp = img->w - 1 - skipLeft;
-			} else {
-				xp = skipLeft;
-			}
-
-			if (flipping & Image::FLIP_H) {
-				inoStep = -inoStep;
-				yp = img->h - 1 - skipTop;
-			} else {
-				yp = skipTop;
-			}
-
-			byte *ino = (byte *)img->getBasePtr(xp, yp);
-			byte *outo = (byte *)_backSurface->getBasePtr(drawX, drawY);
-
-#if defined(SCUMM_LITTLE_ENDIAN)
-			// Simple memcpy if the source bitmap doesn't have transparent pixels and the drawing transparency is 255
-			// NOTE Only possible with LE-machines at the moment, maybe it would be feasible to convert the bitmap pixels at loading time?
-			if (!_isTransparent && ca == 255) {
-				for (int i = 0; i < drawHeight; i++) {
-					memcpy(outo, ino, drawWidth * 4);
-					outo += _backSurface->pitch;
-					ino += inoStep;
-				}
-			} else
-#endif
-			{
-				byte *in, *out;
-				for (int i = 0; i < drawHeight; i++) {
-					out = outo;
-					in = ino;
-					for (int j = 0; j < drawWidth; j++) {
-						uint32 pix = *(uint32 *)in;
-						int a = (pix >> 24) & 0xff;
-						in += inStep;
-
-						if (ca != 255) {
-							a = a * ca >> 8;
-						}
-
-						if (a == 0) {
-							// Full transparency
-							out += 4;
-							continue;
-						}
-
-						int b = (pix >> 0) & 0xff;
-						int g = (pix >> 8) & 0xff;
-						int r = (pix >> 16) & 0xff;
-
-						if (a == 255) {
-#if defined(SCUMM_LITTLE_ENDIAN)
-							if (cb != 255)
-								b = (b * cb) >> 8;
-							if (cg != 255)
-								g = (g * cg) >> 8;
-							if (cr != 255)
-								r = (r * cr) >> 8;
-							*(uint32 *)out = (255 << 24) | (r << 16) | (g << 8) | b;
-							out += 4;
-#else
-							*out++ = a;
-							if (cr != 255)
-								*out++ = (r * cr) >> 8;
-							else
-								*out++ = r;
-							if (cg != 255)
-								*out++ = (g * cg) >> 8;
-							else
-								*out++ = g;
-							if (cb != 255)
-								*out++ = (b * cb) >> 8;
-							else
-								*out++ = b;
-#endif
-						} else {
-#if defined(SCUMM_LITTLE_ENDIAN)
-							pix = *(uint32 *)out;
-							int outb = ((pix >> 0) & 0xff) * (255 - a);
-							int outg = ((pix >> 8) & 0xff) * (255 - a);
-							int outr = ((pix >> 16) & 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;
-							*(uint32 *)out = (255 << 24) | (outr << 16) | (outg << 8) | outb;
-							out += 4;
-#else
-							*out = 255;
-							out++;
-							if (cr == 0)
-								*out = (*out * (255-a)) >> 8;
-							else if (cr != 255)
-								*out = (((*out * (255-a)) << 8) + r * a * cr) >> 16;
-							else
-								*out = ((*out * (255-a)) + r * a) >> 8;
-							out++;
-							if (cg == 0)
-								*out = (*out * (255-a)) >> 8;
-							else if (cg != 255)
-								*out = (((*out * (255-a)) << 8) + g * a * cg) >> 16;
-							else
-								*out = ((*out * (255-a)) + g * a) >> 8;
-							out++;
-							if (cb == 0)
-								*out = (*out * (255-a)) >> 8;
-							else if (cb != 255)
-								*out = (((*out * (255-a)) << 8) + b * a * cb) >> 16;
-							else
-								*out = ((*out * (255-a)) + b * a) >> 8;
-							out++;
-#endif
-						}
-					}
-					outo += _backSurface->pitch;
-					ino += inoStep;
-				}
-			}
-
-		}
-
-	}
-
-	if (imgScaled) {
-		imgScaled->setPixels(savedPixels);
-		imgScaled->free();
-		delete imgScaled;
-	}
+	_surface.blit(*_backSurface, posX, posY, flipping, pPartRect, color, width, height);
 
 	return true;
 }
 
 void RenderedImage::copyDirectly(int posX, int posY) {
-	byte *data = _data;
-	int w = _width;
-	int h = _height;
+	byte *data = (byte *)_surface.getPixels();
+	int w = _surface.w;
+	int h = _surface.h;
 
 	// Handle off-screen clipping
 	if (posY < 0) {
-		h = MAX(0, (int)_height - -posY);
-		data = (byte *)_data + _width * -posY;
+		h = MAX(0, (int)_surface.h - -posY);
+		data = (byte *)_surface.getPixels() + _surface.w * -posY;
 		posY = 0;
 	}
 
 	if (posX < 0) {
-		w = MAX(0, (int)_width - -posX);
-		data = (byte *)_data + (-posX * 4);
+		w = MAX(0, (int)_surface.h - -posX);
+		data = (byte *)_surface.getPixels() + (-posX * 4);
 		posX = 0;
 	}
 
@@ -487,9 +265,9 @@ void RenderedImage::copyDirectly(int posX, int posY) {
 void RenderedImage::checkForTransparency() {
 	// Check if the source bitmap has any transparent pixels at all
 	_isTransparent = false;
-	byte *data = _data;
-	for (int i = 0; i < _height; i++) {
-		for (int j = 0; j < _width; j++) {
+	byte *data = (byte *)_surface.getPixels();
+	for (int i = 0; i < _surface.h; i++) {
+		for (int j = 0; j < _surface.w; j++) {
 			_isTransparent = data[3] != 0xff;
 			if (_isTransparent)
 				return;
diff --git a/engines/sword25/gfx/image/renderedimage.h b/engines/sword25/gfx/image/renderedimage.h
index 3cc9725..5b65a27 100644
--- a/engines/sword25/gfx/image/renderedimage.h
+++ b/engines/sword25/gfx/image/renderedimage.h
@@ -39,6 +39,7 @@
 #include "sword25/kernel/common.h"
 #include "sword25/gfx/image/image.h"
 #include "sword25/gfx/graphicengine.h"
+#include "graphics/transparent_surface.h"
 
 namespace Sword25 {
 
@@ -60,10 +61,10 @@ public:
 	virtual ~RenderedImage();
 
 	virtual int getWidth() const {
-		return _width;
+		return _surface.w;
 	}
 	virtual int getHeight() const {
-		return _height;
+		return _surface.h;
 	}
 	virtual GraphicEngine::COLOR_FORMATS getColorFormat() const {
 		return GraphicEngine::CF_ARGB32;
@@ -72,7 +73,7 @@ public:
 	void copyDirectly(int posX, int posY);
 
 	virtual bool blit(int posX = 0, int posY = 0,
-	                  int flipping = Image::FLIP_NONE,
+	                  int flipping = Graphics::FLIP_NONE,
 	                  Common::Rect *pPartRect = NULL,
 	                  uint color = BS_ARGB(255, 255, 255, 255),
 	                  int width = -1, int height = -1,
@@ -108,9 +109,7 @@ public:
 	virtual bool isSolid() const { return !_isTransparent; }
 
 private:
-	byte *_data;
-	int  _width;
-	int  _height;
+	Graphics::TransparentSurface _surface;
 	bool _doCleanup;
 	bool _isTransparent;
 
diff --git a/engines/sword25/gfx/image/swimage.h b/engines/sword25/gfx/image/swimage.h
index b31c231..60978eb 100644
--- a/engines/sword25/gfx/image/swimage.h
+++ b/engines/sword25/gfx/image/swimage.h
@@ -55,7 +55,7 @@ public:
 	}
 
 	virtual bool blit(int posX = 0, int posY = 0,
-	                  int flipping = Image::FLIP_NONE,
+	                  int flipping = Graphics::FLIP_NONE,
 	                  Common::Rect *pPartRect = NULL,
 	                  uint color = BS_ARGB(255, 255, 255, 255),
 	                  int width = -1, int height = -1,
diff --git a/engines/sword25/gfx/image/vectorimage.h b/engines/sword25/gfx/image/vectorimage.h
index a99d532..057064f 100644
--- a/engines/sword25/gfx/image/vectorimage.h
+++ b/engines/sword25/gfx/image/vectorimage.h
@@ -209,7 +209,7 @@ public:
 	}
 	virtual bool setContent(const byte *pixeldata, uint size, uint offset, uint stride);
 	virtual bool blit(int posX = 0, int posY = 0,
-	                  int flipping = FLIP_NONE,
+	                  int flipping = Graphics::FLIP_NONE,
 	                  Common::Rect *pPartRect = NULL,
 	                  uint color = BS_ARGB(255, 255, 255, 255),
 	                  int width = -1, int height = -1,
diff --git a/engines/sword25/gfx/image/vectorimagerenderer.cpp b/engines/sword25/gfx/image/vectorimagerenderer.cpp
index c7a79fd..c69cb49 100644
--- a/engines/sword25/gfx/image/vectorimagerenderer.cpp
+++ b/engines/sword25/gfx/image/vectorimagerenderer.cpp
@@ -52,7 +52,7 @@ void art_rgb_fill_run1(byte *buf, byte r, byte g, byte b, int n) {
 		memset(buf, g, n + n + n + n);
 	} else {
 		uint32 *alt = (uint32 *)buf;
-		uint32 color = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(0xff, r, g, b);
+		uint32 color = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(r, g, b, 0xff);
 
 		for (i = 0; i < n; i++)
 			*alt++ = color;
@@ -66,22 +66,22 @@ void art_rgb_run_alpha1(byte *buf, byte r, byte g, byte b, int alpha, int n) {
 	for (i = 0; i < n; i++) {
 #if defined(SCUMM_LITTLE_ENDIAN)
 		v = *buf;
+		*buf++ = MIN(v + alpha, 0xff);
+		v = *buf;
 		*buf++ = v + (((b - v) * alpha + 0x80) >> 8);
 		v = *buf;
 		*buf++ = v + (((g - v) * alpha + 0x80) >> 8);
 		v = *buf;
 		*buf++ = v + (((r - v) * alpha + 0x80) >> 8);
-		v = *buf;
-		*buf++ = MIN(v + alpha, 0xff);
 #else
 		v = *buf;
-		*buf++ = MIN(v + alpha, 0xff);
-		v = *buf;
 		*buf++ = v + (((r - v) * alpha + 0x80) >> 8);
 		v = *buf;
 		*buf++ = v + (((g - v) * alpha + 0x80) >> 8);
 		v = *buf;
 		*buf++ = v + (((b - v) * alpha + 0x80) >> 8);
+		v = *buf;
+		*buf++ = MIN(v + alpha, 0xff);
 #endif
 	}
 }
diff --git a/engines/sword25/gfx/staticbitmap.cpp b/engines/sword25/gfx/staticbitmap.cpp
index 14e2012..1a6c812 100644
--- a/engines/sword25/gfx/staticbitmap.cpp
+++ b/engines/sword25/gfx/staticbitmap.cpp
@@ -98,14 +98,14 @@ bool StaticBitmap::doRender(RectangleList *updateRects) {
 	bool result;
 	if (_scaleFactorX == 1.0f && _scaleFactorY == 1.0f) {
 		result = bitmapResourcePtr->blit(_absoluteX, _absoluteY,
-		                                 (_flipV ? BitmapResource::FLIP_V : 0) |
-		                                 (_flipH ? BitmapResource::FLIP_H : 0),
+		                                 (_flipV ? Graphics::FLIP_V : 0) |
+		                                 (_flipH ? Graphics::FLIP_H : 0),
 		                                 0, _modulationColor, -1, -1,
 										 updateRects);
 	} else {
 		result = bitmapResourcePtr->blit(_absoluteX, _absoluteY,
-		                                 (_flipV ? BitmapResource::FLIP_V : 0) |
-		                                 (_flipH ? BitmapResource::FLIP_H : 0),
+		                                 (_flipV ? Graphics::FLIP_V : 0) |
+		                                 (_flipH ? Graphics::FLIP_H : 0),
 		                                 0, _modulationColor, _width, _height,
 										 updateRects);
 	}
diff --git a/engines/sword25/gfx/text.cpp b/engines/sword25/gfx/text.cpp
index b0a9e4e..904435f 100644
--- a/engines/sword25/gfx/text.cpp
+++ b/engines/sword25/gfx/text.cpp
@@ -99,7 +99,7 @@ void Text::setText(const Common::String &text) {
 }
 
 void Text::setColor(uint32 modulationColor) {
-	uint32 newModulationColor = (modulationColor & 0x00ffffff) | (_modulationColor & 0xff000000);
+	uint32 newModulationColor = (modulationColor & 0xffffff00) | (_modulationColor & 0x000000ff);
 	if (newModulationColor != _modulationColor) {
 		_modulationColor = newModulationColor;
 		forceRefresh();
@@ -108,7 +108,7 @@ void Text::setColor(uint32 modulationColor) {
 
 void Text::setAlpha(int alpha) {
 	assert(alpha >= 0 && alpha < 256);
-	uint32 newModulationColor = (_modulationColor & 0x00ffffff) | alpha << 24;
+	uint32 newModulationColor = (_modulationColor & 0xffffff00) | alpha;
 	if (newModulationColor != _modulationColor) {
 		_modulationColor = newModulationColor;
 		forceRefresh();
@@ -173,7 +173,7 @@ bool Text::doRender(RectangleList *updateRects) {
 
 			Common::Rect renderRect(curX, curY, curX + curRect.width(), curY + curRect.height());
 			renderRect.translate(curRect.left - curX, curRect.top - curY);
-			result = charMapPtr->blit(curX, curY, Image::FLIP_NONE, &renderRect, _modulationColor, -1, -1, updateRects);
+			result = charMapPtr->blit(curX, curY, Graphics::FLIP_NONE, &renderRect, _modulationColor, -1, -1, updateRects);
 			if (!result)
 				break;
 
diff --git a/engines/sword25/sword25.cpp b/engines/sword25/sword25.cpp
index 259deb2..bb0aab3 100644
--- a/engines/sword25/sword25.cpp
+++ b/engines/sword25/sword25.cpp
@@ -97,7 +97,7 @@ Common::Error Sword25Engine::run() {
 
 Common::Error Sword25Engine::appStart() {
 	// Initialize the graphics mode to ARGB8888
-	Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
+	Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
 	initGraphics(800, 600, true, &format);
 	if (format != g_system->getScreenFormat())
 		return Common::kUnsupportedColorMode;


Commit: 1ebb8aa6debe7fab79bd058730ac07e360a7b486
    https://github.com/scummvm/scummvm/commit/1ebb8aa6debe7fab79bd058730ac07e360a7b486
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2014-06-15T21:15:31+03:00

Commit Message:
Merge pull request #466 from sev-/transparent-surface

COMMON: Move TransparentSurface to common code

Changed paths:
  A graphics/transform_struct.cpp
  A graphics/transform_struct.h
  A graphics/transform_tools.cpp
  A graphics/transform_tools.h
  A graphics/transparent_surface.cpp
  A graphics/transparent_surface.h
  R engines/wintermute/graphics/transform_struct.cpp
  R engines/wintermute/graphics/transform_struct.h
  R engines/wintermute/graphics/transform_tools.cpp
  R engines/wintermute/graphics/transform_tools.h
  R engines/wintermute/graphics/transparent_surface.cpp
  R engines/wintermute/graphics/transparent_surface.h
    engines/sword25/gfx/animation.cpp
    engines/sword25/gfx/bitmapresource.h
    engines/sword25/gfx/dynamicbitmap.cpp
    engines/sword25/gfx/graphicengine.cpp
    engines/sword25/gfx/image/image.h
    engines/sword25/gfx/image/imgloader.cpp
    engines/sword25/gfx/image/renderedimage.cpp
    engines/sword25/gfx/image/renderedimage.h
    engines/sword25/gfx/image/swimage.h
    engines/sword25/gfx/image/vectorimage.h
    engines/sword25/gfx/image/vectorimagerenderer.cpp
    engines/sword25/gfx/staticbitmap.cpp
    engines/sword25/gfx/text.cpp
    engines/sword25/sword25.cpp
    engines/wintermute/base/base_frame.cpp
    engines/wintermute/base/base_frame.h
    engines/wintermute/base/base_object.cpp
    engines/wintermute/base/base_object.h
    engines/wintermute/base/base_persistence_manager.cpp
    engines/wintermute/base/base_sprite.cpp
    engines/wintermute/base/base_sprite.h
    engines/wintermute/base/base_sub_frame.cpp
    engines/wintermute/base/base_sub_frame.h
    engines/wintermute/base/font/base_font_truetype.cpp
    engines/wintermute/base/gfx/base_image.cpp
    engines/wintermute/base/gfx/base_surface.cpp
    engines/wintermute/base/gfx/base_surface.h
    engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
    engines/wintermute/base/gfx/osystem/base_render_osystem.h
    engines/wintermute/base/gfx/osystem/base_surface_osystem.cpp
    engines/wintermute/base/gfx/osystem/base_surface_osystem.h
    engines/wintermute/base/gfx/osystem/render_ticket.cpp
    engines/wintermute/base/gfx/osystem/render_ticket.h
    engines/wintermute/dctypes.h
    engines/wintermute/module.mk
    graphics/module.mk









More information about the Scummvm-git-logs mailing list