diff window/render.cc @ 60:e16e13d8cd68

Replaced SATURATE -> ADD, implemented objComposite, corrected minor things
author Thibaut GIRKA <thib@sitedethib.com>
date Fri, 18 Dec 2009 20:41:38 +0100
parents c7bcc0ec2267
children 4416cfac86ae
line wrap: on
line diff
--- a/window/render.cc
+++ b/window/render.cc
@@ -251,49 +251,56 @@ void DSurfaceFillA(Surface* dsto, const 
 #define CMASK1 0xff00ff
 #define CMASK2 0x00ff00
 
-inline void blit_pixel(Uint32* dmem, Uint32* smem, const unsigned char* amem, bool use_srcalpha) {
-	Uint32 d = *dmem;
-	Uint32 s = *smem;
-	Uint32 as = s>>ASHIFT;
+inline void blit_pixel(Uint32* dest, Uint32* src, const unsigned char* alpha, bool use_srcalpha) {
+	Uint32 dest_value = *dest;
+	Uint32 src_value = *src;
+	Uint32 as = src_value >> ASHIFT;
 	if (as == 255 || (!use_srcalpha) ) {
-		as = *amem;
+		as = *alpha;
 	} else {
-		as += as>>7; /* 0-0xff -> 0-0x100 */
-		as *= *amem;
+		as += (as >> 7); /* 0-0xff -> 0-0x100 */
+		as *= *alpha;
 		as >>= 8;
 	}
-	as += as>>7;
-	Uint32 s1 = s & CMASK1;
-	Uint32 d1 = d & CMASK1;
-	d1 = (d1 + (((s1-d1) * as) >> 8)) & CMASK1;
-	s &= CMASK2;
-	d &= CMASK2;
-	d = (d + (((s-d) * as) >> 8)) & CMASK2;
-	*dmem = d1 | d | 0xff000000;
+	as += as >> 7;
+	// Isolate Red and Blue components
+	Uint32 src_c1 = src_value & CMASK1;
+	Uint32 dest_c1 = dest_value & CMASK1;
+	// Blend Red and Blue components
+	dest_c1 = (dest_c1 + (((src_c1-dest_c1) * as) >> 8)) & CMASK1;
+	// Isolate Green component
+	src_value &= CMASK2;
+	dest_value &= CMASK2;
+	// Blend Green component
+	dest_value = (dest_value + (((src_value-dest_value) * as) >> 8)) & CMASK2;
+	// Put it alltogether
+	*dest = dest_c1 | dest_value | 0xff000000;
 }
 
-static void blit_line(Uint32* dmem, Uint32* smem, const unsigned char* amem,int ax0, int ax1, int awidth, int aj0, int aj1, bool use_srcalpha) {
+static void blit_line(Uint32* dest, Uint32* src, const unsigned char* alpha,int ax0, int ax1, int awidth, int aj0, int aj1, bool use_srcalpha) {
 	int j;
 	int ax = ax0;
-	const unsigned char* a = amem + ax0;
-	Uint32* d = dmem;
-	Uint32* s = smem;
+	const unsigned char* a = alpha + ax0;
 	if (awidth == 1) { //  わりとよくあるので最適化
 		for (j=aj0; j < aj1; j++) {
-			blit_pixel(d++, s++, amem, use_srcalpha);
+			blit_pixel(dest++, src++, alpha, use_srcalpha);
 		}
-	} else {
+	}
+	else
+	{
 		for (j=aj0; j < aj1; j++) {
 			for (; ax<awidth; ax++)
-				blit_pixel(d++, s++, a++, use_srcalpha);
+				blit_pixel(dest++, src++, a++, use_srcalpha);
 			ax = 0;
-			a = amem;
+			a = alpha;
 		}
-		for (; ax < ax1; ax++) blit_pixel(d++, s++, a++, use_srcalpha);
+		for (; ax < ax1; ax++)
+			blit_pixel(dest++, src++, a++, use_srcalpha);
 	}
 }
 
-void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect) {
+void DSurfaceBlitAlpha(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, const unsigned char* alpha, const Rect& alpharect)
+{
 	SDL_Surface* dst = (SDL_Surface*)dst_o;
 	SDL_Surface* src = (SDL_Surface*)src_o;
 	SDL_PixelFormat& fmt = *dst->format;
@@ -346,7 +353,7 @@ void DSurfaceBlitAlpha(Surface* src_o, c
 	SDL_UnlockSurface(dst);
 }
 
-void DSurfaceBlitSaturate(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, unsigned char alpha) {
+void DSurfaceBlitAdd(Surface* src_o, const Rect& srcrect_o, Surface* dst_o, const Rect& dstrect_o, unsigned char alpha) {
 	SDL_Surface* dst = (SDL_Surface*)dst_o;
 	SDL_Surface* src = (SDL_Surface*)src_o;
 
@@ -370,21 +377,31 @@ void DSurfaceBlitSaturate(Surface* src_o
 	int rshift = fmt.Rshift - fmt.Rloss; int rmask = fmt.Rmask;
 	int gshift = fmt.Gshift - fmt.Gloss; int gmask = fmt.Gmask;
 	int bshift = fmt.Bshift - fmt.Bloss; int bmask = fmt.Bmask;
+	int ashift = src->format->Ashift - src->format->Aloss; int amask = src->format->Amask;
 	int allmask = rmask | gmask | bmask;
-	int i;
-	for (i=0; i<height; i++) {
+	int i, j;
+	for (i=0; i < height; i++) {
 		char* d = dmem; char* s = smem;
-		int j; for (j=0; j<width; j++) {
+		for (j=0; j < width; j++) {
 			Uint32 sd = *(Uint32*)s;
 			Uint32 dd = *(Uint32*)d;
 			if (sd&allmask) {
 				Uint32 sr = (sd&rmask)>>rshift;
 				Uint32 sg = (sd&gmask)>>gshift;
 				Uint32 sb = (sd&bmask)>>bshift;
-				if (alpha != ALPHA_MAX) {
-					sr = (sr*alpha)>>8;
-					sg = (sg*alpha)>>8;
-					sb = (sb*alpha)>>8;
+				Uint32 alpha2 = alpha;
+				if (amask)
+				{
+					alpha2 = ((sd&amask)>>ashift);
+					alpha2 += alpha2 >> 7;
+					alpha2 *= alpha;
+					alpha2 >>= 8;
+				}
+				
+				if (alpha2 != ALPHA_MAX) {
+					sr = (sr*alpha2)>>8;
+					sg = (sg*alpha2)>>8;
+					sb = (sb*alpha2)>>8;
 				}
 				Uint32 dr = sr + ((dd&rmask)>>rshift);
 				Uint32 dg = sg + ((dd&gmask)>>gshift);