Removed the NDS hack for ARGB1555 surfaces, since it's a general problem; added full color expansion for 16 bpp packed pixels.
authorSam Lantinga <slouken@libsdl.org>
Mon, 07 Mar 2011 01:34:38 -0800
changeset 5439 3a778c6c0269
parent 5438 b705640cb34a
child 5440 810b064d41fe
Removed the NDS hack for ARGB1555 surfaces, since it's a general problem; added full color expansion for 16 bpp packed pixels.
src/video/SDL_RLEaccel.c
src/video/SDL_blit.h
src/video/SDL_blit_A.c
src/video/SDL_blit_N.c
src/video/SDL_pixels.c
--- a/src/video/SDL_RLEaccel.c	Mon Mar 07 00:30:05 2011 -0800
+++ b/src/video/SDL_RLEaccel.c	Mon Mar 07 01:34:38 2011 -0800
@@ -893,9 +893,6 @@
         unsigned r, g, b;
         RGB_FROM_PIXEL(*src, sfmt, r, g, b);
         PIXEL_FROM_RGB(*d, dfmt, r, g, b);
-#ifdef __NDS__
-		*d |= NDS_BIT15;
-#endif
         src++;
         d++;
     }
@@ -953,7 +950,7 @@
         Uint16 pix;
         RGBA_FROM_8888(*src, sfmt, r, g, b, a);
         PIXEL_FROM_RGB(pix, dfmt, r, g, b);
-        *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0) | NDS_BIT15;
+        *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0);
         src++;
         d++;
     }
--- a/src/video/SDL_blit.h	Mon Mar 07 00:30:05 2011 -0800
+++ b/src/video/SDL_blit.h	Mon Mar 07 01:34:38 2011 -0800
@@ -28,6 +28,9 @@
 #include "SDL_endian.h"
 #include "SDL_surface.h"
 
+/* Table to do pixel byte expansion */
+extern Uint8* SDL_expand_byte[9];
+
 /* SDL blit copy flags */
 #define SDL_COPY_MODULATE_COLOR     0x00000001
 #define SDL_COPY_MODULATE_ALPHA     0x00000002
@@ -114,35 +117,24 @@
 #define DECLARE_ALIGNED(t,v,a)  t v
 #endif
 
-/* The Nintendo surfaces are special. Bit 15 is the transparency
- * bit. It must be set for the pixel to be displayed. By setting that
- * value to 0 for other platforms, their compiler should optimize it
- * out. */
-#ifdef __NDS__
-#define NDS_BIT15 0x8000
-#else
-#define NDS_BIT15 0
-#endif
-
 /* Load pixel of the specified format from a buffer and get its R-G-B values */
-/* FIXME: rescale values to 0..255 here? */
 #define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)				\
 {									\
-	r = (((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss); 		\
-	g = (((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss); 		\
-	b = (((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss); 		\
+	r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
+	g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
+	b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
 }
 #define RGB_FROM_RGB565(Pixel, r, g, b)					\
 {									\
-	r = (((Pixel&0xF800)>>11)<<3);		 			\
-	g = (((Pixel&0x07E0)>>5)<<2); 					\
-	b = ((Pixel&0x001F)<<3); 					\
+	r = SDL_expand_byte[3][((Pixel&0xF800)>>11)];		 			\
+	g = SDL_expand_byte[2][((Pixel&0x07E0)>>5)]; 					\
+	b = SDL_expand_byte[3][(Pixel&0x001F)]; 					\
 }
 #define RGB_FROM_RGB555(Pixel, r, g, b)					\
 {									\
-	r = (((Pixel&0x7C00)>>10)<<3);		 			\
-	g = (((Pixel&0x03E0)>>5)<<3); 					\
-	b = ((Pixel&0x001F)<<3); 					\
+	r = SDL_expand_byte[3][((Pixel&0x7C00)>>10)];		 			\
+	g = SDL_expand_byte[3][((Pixel&0x03E0)>>5)]; 					\
+	b = SDL_expand_byte[3][(Pixel&0x001F)]; 					\
 }
 #define RGB_FROM_RGB888(Pixel, r, g, b)					\
 {									\
@@ -217,7 +209,8 @@
 {									\
 	Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|				\
 		((g>>fmt->Gloss)<<fmt->Gshift)|				\
-		((b>>fmt->Bloss)<<fmt->Bshift);				\
+		((b>>fmt->Bloss)<<fmt->Bshift)|
+        fmt->Amask;				\
 }
 #define RGB565_FROM_RGB(Pixel, r, g, b)					\
 {									\
@@ -254,7 +247,7 @@
 			Uint16 Pixel;					\
 									\
 			PIXEL_FROM_RGB(Pixel, fmt, r, g, b);		\
-			*((Uint16 *)(buf)) = Pixel | NDS_BIT15;		\
+			*((Uint16 *)(buf)) = Pixel;		\
 		}							\
 		break;							\
 									\
@@ -284,10 +277,10 @@
 /* FIXME: Should we rescale alpha into 0..255 here? */
 #define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a)				\
 {									\
-	r = ((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss; 		\
-	g = ((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss; 		\
-	b = ((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss; 		\
-	a = ((Pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss;	 	\
+	r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
+	g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
+	b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
+	a = SDL_expand_byte[fmt->Aloss][((Pixel&fmt->Amask)>>fmt->Ashift)]; \
 }
 #define RGBA_FROM_8888(Pixel, fmt, r, g, b, a)	\
 {						\
@@ -375,7 +368,7 @@
 			Uint16 Pixel;					\
 									\
 			PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a);	\
-			*((Uint16 *)(buf)) = Pixel | NDS_BIT15;		\
+			*((Uint16 *)(buf)) = Pixel;		\
 		}							\
 		break;							\
 									\
--- a/src/video/SDL_blit_A.c	Mon Mar 07 00:30:05 2011 -0800
+++ b/src/video/SDL_blit_A.c	Mon Mar 07 01:34:38 2011 -0800
@@ -97,7 +97,6 @@
     SDL_PixelFormat *dstfmt = info->dst_fmt;
     int srcbpp = srcfmt->BytesPerPixel;
 
-    /* FIXME: fix alpha bit field expansion here too? */
     while (height--) {
 	    /* *INDENT-OFF* */
 	    DUFFS_LOOP4(
@@ -2082,11 +2081,6 @@
     srcbpp = srcfmt->BytesPerPixel;
     dstbpp = dstfmt->BytesPerPixel;
 
-    /* FIXME: for 8bpp source alpha, this doesn't get opaque values
-       quite right. for <8bpp source alpha, it gets them very wrong
-       (check all macros!)
-       It is unclear whether there is a good general solution that doesn't
-       need a branch (or a divide). */
     while (height--) {
 	    /* *INDENT-OFF* */
 	    DUFFS_LOOP4(
--- a/src/video/SDL_blit_N.c	Mon Mar 07 00:30:05 2011 -0800
+++ b/src/video/SDL_blit_N.c	Mon Mar 07 01:34:38 2011 -0800
@@ -2123,7 +2123,6 @@
     int dstbpp = dstfmt->BytesPerPixel;
     int c;
 
-    /* FIXME: should map alpha to [0..255] correctly! */
     while (height--) {
         for (c = width; c; --c) {
             Uint32 Pixel;
@@ -2305,7 +2304,6 @@
     dstbpp = dstfmt->BytesPerPixel;
     ckey &= rgbmask;
 
-    /* FIXME: should map alpha to [0..255] correctly! */
     while (height--) {
 		/* *INDENT-OFF* */
 		DUFFS_LOOP(
--- a/src/video/SDL_pixels.c	Mon Mar 07 00:30:05 2011 -0800
+++ b/src/video/SDL_pixels.c	Mon Mar 07 01:34:38 2011 -0800
@@ -31,6 +31,56 @@
 #include "SDL_RLEaccel_c.h"
 
 
+/* Lookup tables to expand partial bytes to the full 0..255 range */
+
+static Uint8 lookup_0[] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
+};
+
+static Uint8 lookup_1[] = {
+0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255
+};
+
+static Uint8 lookup_2[] = {
+0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255
+};
+
+static Uint8 lookup_3[] = {
+0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255
+};
+
+static Uint8 lookup_4[] = {
+0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
+};
+
+static Uint8 lookup_5[] = {
+0, 36, 72, 109, 145, 182, 218, 255
+};
+
+static Uint8 lookup_6[] = {
+0, 85, 170, 255
+};
+
+static Uint8 lookup_7[] = {
+0, 255
+};
+
+static Uint8 lookup_8[] = {
+255
+};
+
+Uint8* SDL_expand_byte[9] = {
+    lookup_0,
+    lookup_1,
+    lookup_2,
+    lookup_3,
+    lookup_4,
+    lookup_5,
+    lookup_6,
+    lookup_7,
+    lookup_8
+};
+
 /* Helper functions */
 
 const char*
@@ -758,21 +808,13 @@
            Uint8 * b)
 {
     if (format->palette == NULL) {
-        /*
-         * This makes sure that the result is mapped to the
-         * interval [0..255], and the maximum value for each
-         * component is 255. This is important to make sure
-         * that white is indeed reported as (255, 255, 255).
-         * This only works for RGB bit fields at least 4 bit
-         * wide, which is almost always the case.
-         */
         unsigned v;
         v = (pixel & format->Rmask) >> format->Rshift;
-        *r = (v << format->Rloss) + (v >> (8 - (format->Rloss << 1)));
+        *r = SDL_expand_byte[format->Rloss][v];
         v = (pixel & format->Gmask) >> format->Gshift;
-        *g = (v << format->Gloss) + (v >> (8 - (format->Gloss << 1)));
+        *g = SDL_expand_byte[format->Gloss][v];
         v = (pixel & format->Bmask) >> format->Bshift;
-        *b = (v << format->Bloss) + (v >> (8 - (format->Bloss << 1)));
+        *b = SDL_expand_byte[format->Bloss][v];
     } else {
         if (pixel < format->palette->ncolors) {
             *r = format->palette->colors[pixel].r;
@@ -789,28 +831,15 @@
             Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
 {
     if (format->palette == NULL) {
-        /*
-         * This makes sure that the result is mapped to the
-         * interval [0..255], and the maximum value for each
-         * component is 255. This is important to make sure
-         * that white is indeed reported as (255, 255, 255),
-         * and that opaque alpha is 255.
-         * This only works for RGB bit fields at least 4 bit
-         * wide, which is almost always the case.
-         */
         unsigned v;
         v = (pixel & format->Rmask) >> format->Rshift;
-        *r = (v << format->Rloss) + (v >> (8 - (format->Rloss << 1)));
+        *r = SDL_expand_byte[format->Rloss][v];
         v = (pixel & format->Gmask) >> format->Gshift;
-        *g = (v << format->Gloss) + (v >> (8 - (format->Gloss << 1)));
+        *g = SDL_expand_byte[format->Gloss][v];
         v = (pixel & format->Bmask) >> format->Bshift;
-        *b = (v << format->Bloss) + (v >> (8 - (format->Bloss << 1)));
-        if (format->Amask) {
-            v = (pixel & format->Amask) >> format->Ashift;
-            *a = (v << format->Aloss) + (v >> (8 - (format->Aloss << 1)));
-        } else {
-            *a = SDL_ALPHA_OPAQUE;
-        }
+        *b = SDL_expand_byte[format->Bloss][v];
+        v = (pixel & format->Amask) >> format->Ashift;
+        *a = SDL_expand_byte[format->Aloss][v];
     } else {
         if (pixel < format->palette->ncolors) {
             *r = format->palette->colors[pixel].r;