changeset 431:41cadcba32e8

Fixed SDL_DisplayFormatAlpha() on RGB surfaces with alpha
author Sam Lantinga <slouken@libsdl.org>
date Thu, 01 Aug 2002 23:06:39 +0000
parents 60effdbf14ee
children 80a35d43a58f
files docs.html include/SDL_video.h src/video/SDL_blit_N.c src/video/SDL_surface.c
diffstat 4 files changed, 63 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/docs.html	Thu Aug 01 05:16:38 2002 +0000
+++ b/docs.html	Thu Aug 01 23:06:39 2002 +0000
@@ -16,6 +16,7 @@
 Major changes since SDL 1.0.0:
 </H2>
 <UL>
+	<LI> 1.2.5: Fixed SDL_DisplayFormatAlpha() on RGB surfaces with alpha
 	<LI> 1.2.5: Fixed setting OpenGL mode multiple times on Windows
 	<LI> 1.2.5: Added support for Qtopia on embedded systems (thanks David!)
 	<LI> 1.2.4: Added initial support for Atari (thanks Patrice!)
--- a/include/SDL_video.h	Thu Aug 01 05:16:38 2002 +0000
+++ b/include/SDL_video.h	Thu Aug 01 23:06:39 2002 +0000
@@ -645,7 +645,7 @@
  * 	alpha-blend (using the source per-surface alpha value);
  * 	set destination alpha to opaque.
  *     SDL_SRCALPHA not set:
- * 	copy RGB, set destination alpha to opaque.
+ * 	copy RGB, set destination alpha to source per-surface alpha value.
  *     both:
  * 	if SDL_SRCCOLORKEY set, only copy the pixels matching the
  * 	source colour key.
--- a/src/video/SDL_blit_N.c	Thu Aug 01 05:16:38 2002 +0000
+++ b/src/video/SDL_blit_N.c	Thu Aug 01 23:06:39 2002 +0000
@@ -1202,7 +1202,7 @@
 	int srcbpp = srcfmt->BytesPerPixel;
 	SDL_PixelFormat *dstfmt = info->dst;
 	int dstbpp = dstfmt->BytesPerPixel;
-	unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
+	unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0;
 
 	while ( height-- ) {
 		DUFFS_LOOP(
@@ -1358,7 +1358,7 @@
 	SDL_PixelFormat *dstfmt = info->dst;
 	int srcbpp = srcfmt->BytesPerPixel;
 	int dstbpp = dstfmt->BytesPerPixel;
-	unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
+	unsigned alpha = dstfmt->Amask ? srcfmt->alpha : 0;
 
 	while ( height-- ) {
 		DUFFS_LOOP(
--- a/src/video/SDL_surface.c	Thu Aug 01 05:16:38 2002 +0000
+++ b/src/video/SDL_surface.c	Thu Aug 01 23:06:39 2002 +0000
@@ -211,6 +211,7 @@
 	SDL_InvalidateMap(surface->map);
 	return(0);
 }
+/* This function sets the alpha channel of a surface */
 int SDL_SetAlpha (SDL_Surface *surface, Uint32 flag, Uint8 value)
 {
 	Uint32 oldflags = surface->flags;
@@ -269,6 +270,52 @@
 		SDL_InvalidateMap(surface->map);
 	return(0);
 }
+int SDL_SetAlphaChannel(SDL_Surface *surface, Uint8 value)
+{
+	int row, col;
+	int offset;
+	Uint8 *buf;
+
+	if ( (surface->format->Amask != 0xFF000000) &&
+	     (surface->format->Amask != 0x000000FF) ) {
+		SDL_SetError("Unsupported surface alpha mask format");
+		return -1;
+	}
+
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+	if ( surface->format->Amask == 0xFF000000 ) {
+			offset = 3;
+	} else {
+			offset = 0;
+	}
+#else
+	if ( surface->format->Amask == 0xFF000000 ) {
+			offset = 0;
+	} else {
+			offset = 3;
+	}
+#endif /* Byte ordering */
+
+	/* Quickly set the alpha channel of an RGBA or ARGB surface */
+	if ( SDL_MUSTLOCK(surface) ) {
+		if ( SDL_LockSurface(surface) < 0 ) {
+			return -1;
+		}
+	}
+	row = surface->h;
+	while (row--) {
+		col = surface->w;
+		buf = (Uint8 *)surface->pixels + row * surface->pitch + offset;
+		while(col--) {
+			*buf = value;
+			buf += 4;
+		}
+	}
+	if ( SDL_MUSTLOCK(surface) ) {
+		SDL_UnlockSurface(surface);
+	}
+	return 0;
+}
 
 /*
  * A function to calculate the intersection of two rectangles:
@@ -748,8 +795,13 @@
 		}
 	}
 	if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
-		alpha = surface->format->alpha;
-		SDL_SetAlpha(surface, 0, 0);
+		/* Copy over the alpha channel to RGBA if requested */
+		if ( format->Amask ) {
+			surface->flags &= ~SDL_SRCALPHA;
+		} else {
+			alpha = surface->format->alpha;
+			SDL_SetAlpha(surface, 0, 0);
+		}
 	}
 
 	/* Copy over the image data */
@@ -780,7 +832,11 @@
 		        SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK),
 				alpha);
 		}
-		SDL_SetAlpha(surface, aflags, alpha);
+		if ( format->Amask ) {
+			surface->flags |= SDL_SRCALPHA;
+		} else {
+			SDL_SetAlpha(surface, aflags, alpha);
+		}
 	}
 
 	/* We're ready to go! */