From 817d1df33982d9cce23c3875390e5246e72ce96f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 7 Mar 2011 01:34:38 -0800 Subject: [PATCH] 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 | 5 +-- src/video/SDL_blit.h | 47 +++++++++------------- src/video/SDL_blit_A.c | 6 --- src/video/SDL_blit_N.c | 2 - src/video/SDL_pixels.c | 87 ++++++++++++++++++++++++++-------------- 5 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/video/SDL_RLEaccel.c b/src/video/SDL_RLEaccel.c index 374fc2c21..91a487e00 100644 --- a/src/video/SDL_RLEaccel.c +++ b/src/video/SDL_RLEaccel.c @@ -893,9 +893,6 @@ copy_opaque_16(void *dst, Uint32 * src, int n, 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 @@ copy_transl_555(void *dst, Uint32 * src, int n, 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++; } diff --git a/src/video/SDL_blit.h b/src/video/SDL_blit.h index 21bc6ce6b..4fcc5854d 100644 --- a/src/video/SDL_blit.h +++ b/src/video/SDL_blit.h @@ -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 @@ extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface * surface); #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)<Rloss); \ - g = (((Pixel&fmt->Gmask)>>fmt->Gshift)<Gloss); \ - b = (((Pixel&fmt->Bmask)>>fmt->Bshift)<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 @@ do { \ { \ Pixel = ((r>>fmt->Rloss)<Rshift)| \ ((g>>fmt->Gloss)<Gshift)| \ - ((b>>fmt->Bloss)<Bshift); \ + ((b>>fmt->Bloss)<Bshift)| + fmt->Amask; \ } #define RGB565_FROM_RGB(Pixel, r, g, b) \ { \ @@ -254,7 +247,7 @@ do { \ Uint16 Pixel; \ \ PIXEL_FROM_RGB(Pixel, fmt, r, g, b); \ - *((Uint16 *)(buf)) = Pixel | NDS_BIT15; \ + *((Uint16 *)(buf)) = Pixel; \ } \ break; \ \ @@ -284,10 +277,10 @@ do { \ /* 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)<Rloss; \ - g = ((Pixel&fmt->Gmask)>>fmt->Gshift)<Gloss; \ - b = ((Pixel&fmt->Bmask)>>fmt->Bshift)<Bloss; \ - a = ((Pixel&fmt->Amask)>>fmt->Ashift)<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 @@ do { \ Uint16 Pixel; \ \ PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \ - *((Uint16 *)(buf)) = Pixel | NDS_BIT15; \ + *((Uint16 *)(buf)) = Pixel; \ } \ break; \ \ diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index d6e039e9b..91f8d84eb 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -97,7 +97,6 @@ BlitNto1PixelAlpha(SDL_BlitInfo * info) 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 @@ BlitNtoNPixelAlpha(SDL_BlitInfo * info) 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( diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index 413d74e11..c7278d122 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -2123,7 +2123,6 @@ BlitNtoNCopyAlpha(SDL_BlitInfo * info) 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 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) dstbpp = dstfmt->BytesPerPixel; ckey &= rgbmask; - /* FIXME: should map alpha to [0..255] correctly! */ while (height--) { /* *INDENT-OFF* */ DUFFS_LOOP( diff --git a/src/video/SDL_pixels.c b/src/video/SDL_pixels.c index 61ef60388..a6490795b 100644 --- a/src/video/SDL_pixels.c +++ b/src/video/SDL_pixels.c @@ -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 @@ SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * format, Uint8 * r, Uint8 * g, 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 @@ SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format, 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;