# HG changeset patch # User Sam Lantinga # Date 1229815160 0 # Node ID 1ef2f1e75ff7c30925760dca6cebf3ae80eee7ca # Parent 9328f53a0ca2bbcc5ddc934c1de76a2ddf1268cd Date: Sat, 20 Dec 2008 23:25:19 +0100 From: Couriersud Subject: 32 & 16 bit versions of blendrect and blendline attached are 32, 16 and 15 bit versions of the blendrect and blendline functionality. There was an issue with the bresenham alg. in drawline which I also fixed. diff -r 9328f53a0ca2 -r 1ef2f1e75ff7 src/video/SDL_blendline.c --- a/src/video/SDL_blendline.c Sat Dec 20 23:10:20 2008 +0000 +++ b/src/video/SDL_blendline.c Sat Dec 20 23:19:20 2008 +0000 @@ -24,11 +24,117 @@ #include "SDL_video.h" #include "SDL_blit.h" +#define ABS(_x) ((_x) < 0 ? -(_x) : (_x)) + +#define SWAP(_x, _y) do { int tmp; tmp = _x; _x = _y; _y = tmp; } while (0) + +#define BRESENHAM(x0, y0, x1, y1, op) \ +{ \ + int deltax, deltay, steep, error, xstep, ystep, x, y; \ + \ + deltax = ABS(x1 - x0); \ + deltay = ABS(y1 - y0); \ + steep = (deltay > deltax); \ + if (steep) { \ + SWAP(x0, y0); \ + SWAP(x1, y1); \ + SWAP(deltax, deltay); \ + } \ + error = (x1 - x0) / 2; \ + y = y0; \ + if (x0 > x1) { \ + xstep = -1; \ + } else { \ + xstep = 1; \ + } \ + if (y0 < y1) { \ + ystep = 1; \ + } else { \ + ystep = -1; \ + } \ + if (!steep) { \ + for (x = x0; x != x1; x += xstep) { \ + op(x, y); \ + error -= deltay; \ + if (error < 0) { \ + y += ystep; \ + error += deltax; \ + } \ + } \ + } else { \ + for (x = x0; x != x1; x += xstep) { \ + op(y, x); \ + error -= deltay; \ + if (error < 0) { \ + y += ystep; \ + error += deltax; \ + } \ + } \ + } \ +} + +#define MUL(_a, _b) (((Uint16)(_a)*(Uint16)(_b))/255) +#define SHIFTAND(_v, _s, _a) (((_v)>>(_s)) & _a) + +#define SETPIXEL_MASK(x, y, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \ +do { \ + type *pixel = (type *)(dst->pixels + y * dst->pitch + x * bpp); \ + if (a) { \ + *pixel = (r<pixels + y * dst->pitch + x * bpp); \ + Uint8 sr = MUL(inva, SHIFTAND(*pixel, rshift, rmask)) + (Uint16) r; \ + Uint8 sg = MUL(inva, SHIFTAND(*pixel, gshift, gmask)) + (Uint16) g; \ + Uint8 sb = MUL(inva, SHIFTAND(*pixel, bshift, bmask)) + (Uint16) b; \ + *pixel = (sr<pixels + y * dst->pitch + x * bpp); \ + Uint16 sr = SHIFTAND(*pixel, rshift, rmask) + (Uint16) r; \ + Uint16 sg = SHIFTAND(*pixel, gshift, gmask) + (Uint16) g; \ + Uint16 sb = SHIFTAND(*pixel, bshift, bmask) + (Uint16) b; \ + if (sr>rmask) sr = rmask; \ + if (sg>gmask) sg = gmask; \ + if (sb>bmask) sb = bmask; \ + *pixel = (sr<pixels + y * dst->pitch + x * bpp); \ + Uint8 sr = MUL(SHIFTAND(*pixel, rshift, rmask), r); \ + Uint8 sg = MUL(SHIFTAND(*pixel, gshift, gmask), g); \ + Uint8 sb = MUL(SHIFTAND(*pixel, bshift, bmask), b); \ + *pixel = (sr<format->BitsPerPixel < 8) { SDL_SetError("SDL_BlendLine(): Unsupported surface format"); @@ -42,8 +148,71 @@ } */ - SDL_Unsupported(); - return -1; + if ((blendMode == SDL_BLENDMODE_BLEND) + || (blendMode == SDL_BLENDMODE_ADD)) { + r = MUL(r, a); + g = MUL(g, a); + b = MUL(b, a); + } + switch (dst->format->BitsPerPixel) { + case 15: + switch (blendMode) { + case SDL_BLENDMODE_MASK: + BRESENHAM(x1, y1, x2, y2, SETPIXEL15_MASK); + break; + case SDL_BLENDMODE_BLEND: + BRESENHAM(x1, y1, x2, y2, SETPIXEL15_BLEND); + break; + case SDL_BLENDMODE_ADD: + BRESENHAM(x1, y1, x2, y2, SETPIXEL15_ADD); + break; + case SDL_BLENDMODE_MOD: + BRESENHAM(x1, y1, x2, y2, SETPIXEL15_MOD); + break; + } + break; + case 16: + switch (blendMode) { + case SDL_BLENDMODE_MASK: + BRESENHAM(x1, y1, x2, y2, SETPIXEL16_MASK); + break; + case SDL_BLENDMODE_BLEND: + BRESENHAM(x1, y1, x2, y2, SETPIXEL16_BLEND); + break; + case SDL_BLENDMODE_ADD: + BRESENHAM(x1, y1, x2, y2, SETPIXEL16_ADD); + break; + case SDL_BLENDMODE_MOD: + BRESENHAM(x1, y1, x2, y2, SETPIXEL16_MOD); + break; + } + break; + case 24: + case 32: + if (dst->format->BytesPerPixel != 4) { + SDL_Unsupported(); + return -1; + } + switch (blendMode) { + case SDL_BLENDMODE_MASK: + BRESENHAM(x1, y1, x2, y2, SETPIXEL32_MASK); + break; + case SDL_BLENDMODE_BLEND: + BRESENHAM(x1, y1, x2, y2, SETPIXEL32_BLEND); + break; + case SDL_BLENDMODE_ADD: + BRESENHAM(x1, y1, x2, y2, SETPIXEL32_ADD); + break; + case SDL_BLENDMODE_MOD: + BRESENHAM(x1, y1, x2, y2, SETPIXEL32_MOD); + break; + } + break; + default: + SDL_Unsupported(); + return -1; + } + return 0; } /* vi: set ts=4 sw=4 expandtab: */ diff -r 9328f53a0ca2 -r 1ef2f1e75ff7 src/video/SDL_blendrect.c --- a/src/video/SDL_blendrect.c Sat Dec 20 23:10:20 2008 +0000 +++ b/src/video/SDL_blendrect.c Sat Dec 20 23:19:20 2008 +0000 @@ -24,11 +24,79 @@ #include "SDL_video.h" #include "SDL_blit.h" +#define MUL(_a, _b) (((Uint16)(_a)*(Uint16)(_b))/255) +#define SHIFTAND(_v, _s, _a) (((_v)>>(_s)) & (_a)) + +#define SETPIXEL_MASK(p, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \ +do { \ + if (a) { \ + p = (r<rmask) sr = rmask; \ + if (sg>gmask) sg = gmask; \ + if (sb>bmask) sb = bmask; \ + p = (sr<y; \ + int h = dstrect->h; \ + while (h--) { \ + type *pixel = (type *)(dst->pixels + y * dst->pitch + dstrect->x * dst->format->BytesPerPixel); \ + int w = dstrect->w; \ + while (w--) { \ + op(*pixel); \ + pixel++; \ + } \ + y++; \ + } \ +} while (0) int SDL_BlendRect(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { + Uint16 inva = 0xff - a; /* This function doesn't work on surfaces < 8 bpp */ if (dst->format->BitsPerPixel < 8) { SDL_SetError("SDL_BlendRect(): Unsupported surface format"); @@ -45,7 +113,71 @@ dstrect = &dst->clip_rect; } - SDL_Unsupported(); + if ((blendMode == SDL_BLENDMODE_BLEND) + || (blendMode == SDL_BLENDMODE_ADD)) { + r = MUL(r, a); + g = MUL(g, a); + b = MUL(b, a); + } + switch (dst->format->BitsPerPixel) { + case 15: + switch (blendMode) { + case SDL_BLENDMODE_MASK: + BLENDRECT(Uint16, SETPIXEL15_MASK); + break; + case SDL_BLENDMODE_BLEND: + BLENDRECT(Uint16, SETPIXEL15_BLEND); + break; + case SDL_BLENDMODE_ADD: + BLENDRECT(Uint16, SETPIXEL15_ADD); + break; + case SDL_BLENDMODE_MOD: + BLENDRECT(Uint16, SETPIXEL15_MOD); + break; + } + break; + case 16: + switch (blendMode) { + case SDL_BLENDMODE_MASK: + BLENDRECT(Uint16, SETPIXEL16_MASK); + break; + case SDL_BLENDMODE_BLEND: + BLENDRECT(Uint16, SETPIXEL16_BLEND); + break; + case SDL_BLENDMODE_ADD: + BLENDRECT(Uint16, SETPIXEL16_ADD); + break; + case SDL_BLENDMODE_MOD: + BLENDRECT(Uint16, SETPIXEL16_MOD); + break; + } + break; + case 24: + case 32: + if (dst->format->BytesPerPixel != 4) { + SDL_Unsupported(); + return -1; + } + switch (blendMode) { + case SDL_BLENDMODE_MASK: + BLENDRECT(Uint32, SETPIXEL32_MASK); + break; + case SDL_BLENDMODE_BLEND: + BLENDRECT(Uint32, SETPIXEL32_BLEND); + break; + case SDL_BLENDMODE_ADD: + BLENDRECT(Uint32, SETPIXEL32_ADD); + break; + case SDL_BLENDMODE_MOD: + BLENDRECT(Uint32, SETPIXEL32_MOD); + break; + } + break; + default: + SDL_Unsupported(); + return -1; + } + return 0; return -1; } diff -r 9328f53a0ca2 -r 1ef2f1e75ff7 src/video/SDL_drawline.c --- a/src/video/SDL_drawline.c Sat Dec 20 23:10:20 2008 +0000 +++ b/src/video/SDL_drawline.c Sat Dec 20 23:19:20 2008 +0000 @@ -24,9 +24,9 @@ #include "SDL_video.h" #include "SDL_blit.h" -#define ABS(x) (x < 0 ? -x : x) +#define ABS(_x) ((_x) < 0 ? -(_x) : (_x)) -#define SWAP(x, y) (x ^= y ^= x ^= y) +#define SWAP(_x, _y) do { int tmp; tmp = _x; _x = _y; _y = tmp; } while (0) #define BRESENHAM(x0, y0, x1, y1, op, color) \ { \ @@ -34,16 +34,16 @@ \ deltax = ABS(x1 - x0); \ deltay = ABS(y1 - y0); \ - steep = deltay > deltax; \ - error = deltax / 2; \ + steep = (deltay > deltax); \ if (steep) { \ SWAP(x0, y0); \ SWAP(x1, y1); \ + SWAP(deltax, deltay); \ } \ + error = (x1 - x0) / 2; \ y = y0; \ if (x0 > x1) { \ xstep = -1; \ - deltax = -deltax; \ } else { \ xstep = 1; \ } \ @@ -57,7 +57,7 @@ op(x, y, color); \ error -= deltay; \ if (error < 0) { \ - y = y + ystep; \ + y += ystep; \ error += deltax; \ } \ } \ @@ -66,7 +66,7 @@ op(y, x, color); \ error -= deltay; \ if (error < 0) { \ - y = y + ystep; \ + y += ystep; \ error += deltax; \ } \ } \