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 54393a778c6c0269
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
     1.1 --- a/src/video/SDL_RLEaccel.c	Mon Mar 07 00:30:05 2011 -0800
     1.2 +++ b/src/video/SDL_RLEaccel.c	Mon Mar 07 01:34:38 2011 -0800
     1.3 @@ -893,9 +893,6 @@
     1.4          unsigned r, g, b;
     1.5          RGB_FROM_PIXEL(*src, sfmt, r, g, b);
     1.6          PIXEL_FROM_RGB(*d, dfmt, r, g, b);
     1.7 -#ifdef __NDS__
     1.8 -		*d |= NDS_BIT15;
     1.9 -#endif
    1.10          src++;
    1.11          d++;
    1.12      }
    1.13 @@ -953,7 +950,7 @@
    1.14          Uint16 pix;
    1.15          RGBA_FROM_8888(*src, sfmt, r, g, b, a);
    1.16          PIXEL_FROM_RGB(pix, dfmt, r, g, b);
    1.17 -        *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0) | NDS_BIT15;
    1.18 +        *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0);
    1.19          src++;
    1.20          d++;
    1.21      }
     2.1 --- a/src/video/SDL_blit.h	Mon Mar 07 00:30:05 2011 -0800
     2.2 +++ b/src/video/SDL_blit.h	Mon Mar 07 01:34:38 2011 -0800
     2.3 @@ -28,6 +28,9 @@
     2.4  #include "SDL_endian.h"
     2.5  #include "SDL_surface.h"
     2.6  
     2.7 +/* Table to do pixel byte expansion */
     2.8 +extern Uint8* SDL_expand_byte[9];
     2.9 +
    2.10  /* SDL blit copy flags */
    2.11  #define SDL_COPY_MODULATE_COLOR     0x00000001
    2.12  #define SDL_COPY_MODULATE_ALPHA     0x00000002
    2.13 @@ -114,35 +117,24 @@
    2.14  #define DECLARE_ALIGNED(t,v,a)  t v
    2.15  #endif
    2.16  
    2.17 -/* The Nintendo surfaces are special. Bit 15 is the transparency
    2.18 - * bit. It must be set for the pixel to be displayed. By setting that
    2.19 - * value to 0 for other platforms, their compiler should optimize it
    2.20 - * out. */
    2.21 -#ifdef __NDS__
    2.22 -#define NDS_BIT15 0x8000
    2.23 -#else
    2.24 -#define NDS_BIT15 0
    2.25 -#endif
    2.26 -
    2.27  /* Load pixel of the specified format from a buffer and get its R-G-B values */
    2.28 -/* FIXME: rescale values to 0..255 here? */
    2.29  #define RGB_FROM_PIXEL(Pixel, fmt, r, g, b)				\
    2.30  {									\
    2.31 -	r = (((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss); 		\
    2.32 -	g = (((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss); 		\
    2.33 -	b = (((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss); 		\
    2.34 +	r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
    2.35 +	g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
    2.36 +	b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
    2.37  }
    2.38  #define RGB_FROM_RGB565(Pixel, r, g, b)					\
    2.39  {									\
    2.40 -	r = (((Pixel&0xF800)>>11)<<3);		 			\
    2.41 -	g = (((Pixel&0x07E0)>>5)<<2); 					\
    2.42 -	b = ((Pixel&0x001F)<<3); 					\
    2.43 +	r = SDL_expand_byte[3][((Pixel&0xF800)>>11)];		 			\
    2.44 +	g = SDL_expand_byte[2][((Pixel&0x07E0)>>5)]; 					\
    2.45 +	b = SDL_expand_byte[3][(Pixel&0x001F)]; 					\
    2.46  }
    2.47  #define RGB_FROM_RGB555(Pixel, r, g, b)					\
    2.48  {									\
    2.49 -	r = (((Pixel&0x7C00)>>10)<<3);		 			\
    2.50 -	g = (((Pixel&0x03E0)>>5)<<3); 					\
    2.51 -	b = ((Pixel&0x001F)<<3); 					\
    2.52 +	r = SDL_expand_byte[3][((Pixel&0x7C00)>>10)];		 			\
    2.53 +	g = SDL_expand_byte[3][((Pixel&0x03E0)>>5)]; 					\
    2.54 +	b = SDL_expand_byte[3][(Pixel&0x001F)]; 					\
    2.55  }
    2.56  #define RGB_FROM_RGB888(Pixel, r, g, b)					\
    2.57  {									\
    2.58 @@ -217,7 +209,8 @@
    2.59  {									\
    2.60  	Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|				\
    2.61  		((g>>fmt->Gloss)<<fmt->Gshift)|				\
    2.62 -		((b>>fmt->Bloss)<<fmt->Bshift);				\
    2.63 +		((b>>fmt->Bloss)<<fmt->Bshift)|
    2.64 +        fmt->Amask;				\
    2.65  }
    2.66  #define RGB565_FROM_RGB(Pixel, r, g, b)					\
    2.67  {									\
    2.68 @@ -254,7 +247,7 @@
    2.69  			Uint16 Pixel;					\
    2.70  									\
    2.71  			PIXEL_FROM_RGB(Pixel, fmt, r, g, b);		\
    2.72 -			*((Uint16 *)(buf)) = Pixel | NDS_BIT15;		\
    2.73 +			*((Uint16 *)(buf)) = Pixel;		\
    2.74  		}							\
    2.75  		break;							\
    2.76  									\
    2.77 @@ -284,10 +277,10 @@
    2.78  /* FIXME: Should we rescale alpha into 0..255 here? */
    2.79  #define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a)				\
    2.80  {									\
    2.81 -	r = ((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss; 		\
    2.82 -	g = ((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss; 		\
    2.83 -	b = ((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss; 		\
    2.84 -	a = ((Pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss;	 	\
    2.85 +	r = SDL_expand_byte[fmt->Rloss][((Pixel&fmt->Rmask)>>fmt->Rshift)]; \
    2.86 +	g = SDL_expand_byte[fmt->Gloss][((Pixel&fmt->Gmask)>>fmt->Gshift)]; \
    2.87 +	b = SDL_expand_byte[fmt->Bloss][((Pixel&fmt->Bmask)>>fmt->Bshift)]; \
    2.88 +	a = SDL_expand_byte[fmt->Aloss][((Pixel&fmt->Amask)>>fmt->Ashift)]; \
    2.89  }
    2.90  #define RGBA_FROM_8888(Pixel, fmt, r, g, b, a)	\
    2.91  {						\
    2.92 @@ -375,7 +368,7 @@
    2.93  			Uint16 Pixel;					\
    2.94  									\
    2.95  			PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a);	\
    2.96 -			*((Uint16 *)(buf)) = Pixel | NDS_BIT15;		\
    2.97 +			*((Uint16 *)(buf)) = Pixel;		\
    2.98  		}							\
    2.99  		break;							\
   2.100  									\
     3.1 --- a/src/video/SDL_blit_A.c	Mon Mar 07 00:30:05 2011 -0800
     3.2 +++ b/src/video/SDL_blit_A.c	Mon Mar 07 01:34:38 2011 -0800
     3.3 @@ -97,7 +97,6 @@
     3.4      SDL_PixelFormat *dstfmt = info->dst_fmt;
     3.5      int srcbpp = srcfmt->BytesPerPixel;
     3.6  
     3.7 -    /* FIXME: fix alpha bit field expansion here too? */
     3.8      while (height--) {
     3.9  	    /* *INDENT-OFF* */
    3.10  	    DUFFS_LOOP4(
    3.11 @@ -2082,11 +2081,6 @@
    3.12      srcbpp = srcfmt->BytesPerPixel;
    3.13      dstbpp = dstfmt->BytesPerPixel;
    3.14  
    3.15 -    /* FIXME: for 8bpp source alpha, this doesn't get opaque values
    3.16 -       quite right. for <8bpp source alpha, it gets them very wrong
    3.17 -       (check all macros!)
    3.18 -       It is unclear whether there is a good general solution that doesn't
    3.19 -       need a branch (or a divide). */
    3.20      while (height--) {
    3.21  	    /* *INDENT-OFF* */
    3.22  	    DUFFS_LOOP4(
     4.1 --- a/src/video/SDL_blit_N.c	Mon Mar 07 00:30:05 2011 -0800
     4.2 +++ b/src/video/SDL_blit_N.c	Mon Mar 07 01:34:38 2011 -0800
     4.3 @@ -2123,7 +2123,6 @@
     4.4      int dstbpp = dstfmt->BytesPerPixel;
     4.5      int c;
     4.6  
     4.7 -    /* FIXME: should map alpha to [0..255] correctly! */
     4.8      while (height--) {
     4.9          for (c = width; c; --c) {
    4.10              Uint32 Pixel;
    4.11 @@ -2305,7 +2304,6 @@
    4.12      dstbpp = dstfmt->BytesPerPixel;
    4.13      ckey &= rgbmask;
    4.14  
    4.15 -    /* FIXME: should map alpha to [0..255] correctly! */
    4.16      while (height--) {
    4.17  		/* *INDENT-OFF* */
    4.18  		DUFFS_LOOP(
     5.1 --- a/src/video/SDL_pixels.c	Mon Mar 07 00:30:05 2011 -0800
     5.2 +++ b/src/video/SDL_pixels.c	Mon Mar 07 01:34:38 2011 -0800
     5.3 @@ -31,6 +31,56 @@
     5.4  #include "SDL_RLEaccel_c.h"
     5.5  
     5.6  
     5.7 +/* Lookup tables to expand partial bytes to the full 0..255 range */
     5.8 +
     5.9 +static Uint8 lookup_0[] = {
    5.10 +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
    5.11 +};
    5.12 +
    5.13 +static Uint8 lookup_1[] = {
    5.14 +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
    5.15 +};
    5.16 +
    5.17 +static Uint8 lookup_2[] = {
    5.18 +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
    5.19 +};
    5.20 +
    5.21 +static Uint8 lookup_3[] = {
    5.22 +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
    5.23 +};
    5.24 +
    5.25 +static Uint8 lookup_4[] = {
    5.26 +0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
    5.27 +};
    5.28 +
    5.29 +static Uint8 lookup_5[] = {
    5.30 +0, 36, 72, 109, 145, 182, 218, 255
    5.31 +};
    5.32 +
    5.33 +static Uint8 lookup_6[] = {
    5.34 +0, 85, 170, 255
    5.35 +};
    5.36 +
    5.37 +static Uint8 lookup_7[] = {
    5.38 +0, 255
    5.39 +};
    5.40 +
    5.41 +static Uint8 lookup_8[] = {
    5.42 +255
    5.43 +};
    5.44 +
    5.45 +Uint8* SDL_expand_byte[9] = {
    5.46 +    lookup_0,
    5.47 +    lookup_1,
    5.48 +    lookup_2,
    5.49 +    lookup_3,
    5.50 +    lookup_4,
    5.51 +    lookup_5,
    5.52 +    lookup_6,
    5.53 +    lookup_7,
    5.54 +    lookup_8
    5.55 +};
    5.56 +
    5.57  /* Helper functions */
    5.58  
    5.59  const char*
    5.60 @@ -758,21 +808,13 @@
    5.61             Uint8 * b)
    5.62  {
    5.63      if (format->palette == NULL) {
    5.64 -        /*
    5.65 -         * This makes sure that the result is mapped to the
    5.66 -         * interval [0..255], and the maximum value for each
    5.67 -         * component is 255. This is important to make sure
    5.68 -         * that white is indeed reported as (255, 255, 255).
    5.69 -         * This only works for RGB bit fields at least 4 bit
    5.70 -         * wide, which is almost always the case.
    5.71 -         */
    5.72          unsigned v;
    5.73          v = (pixel & format->Rmask) >> format->Rshift;
    5.74 -        *r = (v << format->Rloss) + (v >> (8 - (format->Rloss << 1)));
    5.75 +        *r = SDL_expand_byte[format->Rloss][v];
    5.76          v = (pixel & format->Gmask) >> format->Gshift;
    5.77 -        *g = (v << format->Gloss) + (v >> (8 - (format->Gloss << 1)));
    5.78 +        *g = SDL_expand_byte[format->Gloss][v];
    5.79          v = (pixel & format->Bmask) >> format->Bshift;
    5.80 -        *b = (v << format->Bloss) + (v >> (8 - (format->Bloss << 1)));
    5.81 +        *b = SDL_expand_byte[format->Bloss][v];
    5.82      } else {
    5.83          if (pixel < format->palette->ncolors) {
    5.84              *r = format->palette->colors[pixel].r;
    5.85 @@ -789,28 +831,15 @@
    5.86              Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a)
    5.87  {
    5.88      if (format->palette == NULL) {
    5.89 -        /*
    5.90 -         * This makes sure that the result is mapped to the
    5.91 -         * interval [0..255], and the maximum value for each
    5.92 -         * component is 255. This is important to make sure
    5.93 -         * that white is indeed reported as (255, 255, 255),
    5.94 -         * and that opaque alpha is 255.
    5.95 -         * This only works for RGB bit fields at least 4 bit
    5.96 -         * wide, which is almost always the case.
    5.97 -         */
    5.98          unsigned v;
    5.99          v = (pixel & format->Rmask) >> format->Rshift;
   5.100 -        *r = (v << format->Rloss) + (v >> (8 - (format->Rloss << 1)));
   5.101 +        *r = SDL_expand_byte[format->Rloss][v];
   5.102          v = (pixel & format->Gmask) >> format->Gshift;
   5.103 -        *g = (v << format->Gloss) + (v >> (8 - (format->Gloss << 1)));
   5.104 +        *g = SDL_expand_byte[format->Gloss][v];
   5.105          v = (pixel & format->Bmask) >> format->Bshift;
   5.106 -        *b = (v << format->Bloss) + (v >> (8 - (format->Bloss << 1)));
   5.107 -        if (format->Amask) {
   5.108 -            v = (pixel & format->Amask) >> format->Ashift;
   5.109 -            *a = (v << format->Aloss) + (v >> (8 - (format->Aloss << 1)));
   5.110 -        } else {
   5.111 -            *a = SDL_ALPHA_OPAQUE;
   5.112 -        }
   5.113 +        *b = SDL_expand_byte[format->Bloss][v];
   5.114 +        v = (pixel & format->Amask) >> format->Ashift;
   5.115 +        *a = SDL_expand_byte[format->Aloss][v];
   5.116      } else {
   5.117          if (pixel < format->palette->ncolors) {
   5.118              *r = format->palette->colors[pixel].r;