comparison src/video/SDL_blendrect.c @ 2896:1ef2f1e75ff7

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.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 20 Dec 2008 23:19:20 +0000
parents 32e8bbba1e94
children e40448bc7727
comparison
equal deleted inserted replaced
2895:9328f53a0ca2 2896:1ef2f1e75ff7
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 #include "SDL_video.h" 24 #include "SDL_video.h"
25 #include "SDL_blit.h" 25 #include "SDL_blit.h"
26 26
27 #define MUL(_a, _b) (((Uint16)(_a)*(Uint16)(_b))/255)
28 #define SHIFTAND(_v, _s, _a) (((_v)>>(_s)) & (_a))
29
30 #define SETPIXEL_MASK(p, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
31 do { \
32 if (a) { \
33 p = (r<<rshift) | (g<<gshift) | (b<<bshift); \
34 } \
35 } while (0)
36
37 #define SETPIXEL_BLEND(p, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
38 do { \
39 Uint8 sr = MUL(inva, SHIFTAND(p, rshift, rmask)) + (Uint16) r; \
40 Uint8 sg = MUL(inva, SHIFTAND(p, gshift, gmask)) + (Uint16) g; \
41 Uint8 sb = MUL(inva, SHIFTAND(p, bshift, bmask)) + (Uint16) b; \
42 p = (sr<<rshift) | (sg<<gshift) | (sb<<bshift); \
43 } while (0)
44
45 #define SETPIXEL_ADD(p, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
46 do { \
47 Uint16 sr = SHIFTAND(p, rshift, rmask) + (Uint16) r; \
48 Uint16 sg = SHIFTAND(p, gshift, gmask) + (Uint16) g; \
49 Uint16 sb = SHIFTAND(p, bshift, bmask) + (Uint16) b; \
50 if (sr>rmask) sr = rmask; \
51 if (sg>gmask) sg = gmask; \
52 if (sb>bmask) sb = bmask; \
53 p = (sr<<rshift) | (sg<<gshift) | (sb<<bshift); \
54 } while (0)
55
56 #define SETPIXEL_MOD(p, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
57 do { \
58 Uint8 sr = MUL(SHIFTAND(p, rshift, rmask), r); \
59 Uint8 sg = MUL(SHIFTAND(p, gshift, gmask), g); \
60 Uint8 sb = MUL(SHIFTAND(p, bshift, bmask), b); \
61 p = (sr<<rshift) | (sg<<gshift) | (sb<<bshift); \
62 } while (0)
63
64
65 #define SETPIXEL15_MASK(p) SETPIXEL_MASK(p, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
66 #define SETPIXEL15_BLEND(p) SETPIXEL_BLEND(p, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
67 #define SETPIXEL15_ADD(p) SETPIXEL_ADD(p, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
68 #define SETPIXEL15_MOD(p) SETPIXEL_MOD(p, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
69
70 #define SETPIXEL16_MASK(p) SETPIXEL_MASK(p, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
71 #define SETPIXEL16_BLEND(p) SETPIXEL_BLEND(p, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
72 #define SETPIXEL16_ADD(p) SETPIXEL_ADD(p, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
73 #define SETPIXEL16_MOD(p) SETPIXEL_MOD(p, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
74
75 #define SETPIXEL32_MASK(p) SETPIXEL_MASK(p, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
76 #define SETPIXEL32_BLEND(p) SETPIXEL_BLEND(p, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
77 #define SETPIXEL32_ADD(p) SETPIXEL_ADD(p, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
78 #define SETPIXEL32_MOD(p) SETPIXEL_MOD(p, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
79
80 #define BLENDRECT(type, op) \
81 do { \
82 int y = dstrect->y; \
83 int h = dstrect->h; \
84 while (h--) { \
85 type *pixel = (type *)(dst->pixels + y * dst->pitch + dstrect->x * dst->format->BytesPerPixel); \
86 int w = dstrect->w; \
87 while (w--) { \
88 op(*pixel); \
89 pixel++; \
90 } \
91 y++; \
92 } \
93 } while (0)
27 94
28 int 95 int
29 SDL_BlendRect(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r, 96 SDL_BlendRect(SDL_Surface * dst, SDL_Rect * dstrect, int blendMode, Uint8 r,
30 Uint8 g, Uint8 b, Uint8 a) 97 Uint8 g, Uint8 b, Uint8 a)
31 { 98 {
99 Uint16 inva = 0xff - a;
32 /* This function doesn't work on surfaces < 8 bpp */ 100 /* This function doesn't work on surfaces < 8 bpp */
33 if (dst->format->BitsPerPixel < 8) { 101 if (dst->format->BitsPerPixel < 8) {
34 SDL_SetError("SDL_BlendRect(): Unsupported surface format"); 102 SDL_SetError("SDL_BlendRect(): Unsupported surface format");
35 return (-1); 103 return (-1);
36 } 104 }
43 } 111 }
44 } else { 112 } else {
45 dstrect = &dst->clip_rect; 113 dstrect = &dst->clip_rect;
46 } 114 }
47 115
48 SDL_Unsupported(); 116 if ((blendMode == SDL_BLENDMODE_BLEND)
117 || (blendMode == SDL_BLENDMODE_ADD)) {
118 r = MUL(r, a);
119 g = MUL(g, a);
120 b = MUL(b, a);
121 }
122 switch (dst->format->BitsPerPixel) {
123 case 15:
124 switch (blendMode) {
125 case SDL_BLENDMODE_MASK:
126 BLENDRECT(Uint16, SETPIXEL15_MASK);
127 break;
128 case SDL_BLENDMODE_BLEND:
129 BLENDRECT(Uint16, SETPIXEL15_BLEND);
130 break;
131 case SDL_BLENDMODE_ADD:
132 BLENDRECT(Uint16, SETPIXEL15_ADD);
133 break;
134 case SDL_BLENDMODE_MOD:
135 BLENDRECT(Uint16, SETPIXEL15_MOD);
136 break;
137 }
138 break;
139 case 16:
140 switch (blendMode) {
141 case SDL_BLENDMODE_MASK:
142 BLENDRECT(Uint16, SETPIXEL16_MASK);
143 break;
144 case SDL_BLENDMODE_BLEND:
145 BLENDRECT(Uint16, SETPIXEL16_BLEND);
146 break;
147 case SDL_BLENDMODE_ADD:
148 BLENDRECT(Uint16, SETPIXEL16_ADD);
149 break;
150 case SDL_BLENDMODE_MOD:
151 BLENDRECT(Uint16, SETPIXEL16_MOD);
152 break;
153 }
154 break;
155 case 24:
156 case 32:
157 if (dst->format->BytesPerPixel != 4) {
158 SDL_Unsupported();
159 return -1;
160 }
161 switch (blendMode) {
162 case SDL_BLENDMODE_MASK:
163 BLENDRECT(Uint32, SETPIXEL32_MASK);
164 break;
165 case SDL_BLENDMODE_BLEND:
166 BLENDRECT(Uint32, SETPIXEL32_BLEND);
167 break;
168 case SDL_BLENDMODE_ADD:
169 BLENDRECT(Uint32, SETPIXEL32_ADD);
170 break;
171 case SDL_BLENDMODE_MOD:
172 BLENDRECT(Uint32, SETPIXEL32_MOD);
173 break;
174 }
175 break;
176 default:
177 SDL_Unsupported();
178 return -1;
179 }
180 return 0;
49 return -1; 181 return -1;
50 } 182 }
51 183
52 /* vi: set ts=4 sw=4 expandtab: */ 184 /* vi: set ts=4 sw=4 expandtab: */