comparison src/video/SDL_blendline.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 ABS(_x) ((_x) < 0 ? -(_x) : (_x))
28
29 #define SWAP(_x, _y) do { int tmp; tmp = _x; _x = _y; _y = tmp; } while (0)
30
31 #define BRESENHAM(x0, y0, x1, y1, op) \
32 { \
33 int deltax, deltay, steep, error, xstep, ystep, x, y; \
34 \
35 deltax = ABS(x1 - x0); \
36 deltay = ABS(y1 - y0); \
37 steep = (deltay > deltax); \
38 if (steep) { \
39 SWAP(x0, y0); \
40 SWAP(x1, y1); \
41 SWAP(deltax, deltay); \
42 } \
43 error = (x1 - x0) / 2; \
44 y = y0; \
45 if (x0 > x1) { \
46 xstep = -1; \
47 } else { \
48 xstep = 1; \
49 } \
50 if (y0 < y1) { \
51 ystep = 1; \
52 } else { \
53 ystep = -1; \
54 } \
55 if (!steep) { \
56 for (x = x0; x != x1; x += xstep) { \
57 op(x, y); \
58 error -= deltay; \
59 if (error < 0) { \
60 y += ystep; \
61 error += deltax; \
62 } \
63 } \
64 } else { \
65 for (x = x0; x != x1; x += xstep) { \
66 op(y, x); \
67 error -= deltay; \
68 if (error < 0) { \
69 y += ystep; \
70 error += deltax; \
71 } \
72 } \
73 } \
74 }
75
76 #define MUL(_a, _b) (((Uint16)(_a)*(Uint16)(_b))/255)
77 #define SHIFTAND(_v, _s, _a) (((_v)>>(_s)) & _a)
78
79 #define SETPIXEL_MASK(x, y, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
80 do { \
81 type *pixel = (type *)(dst->pixels + y * dst->pitch + x * bpp); \
82 if (a) { \
83 *pixel = (r<<rshift) | (g<<gshift) | (b<<bshift); \
84 } \
85 } while (0)
86
87 #define SETPIXEL_BLEND(x, y, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
88 do { \
89 type *pixel = (type *)(dst->pixels + y * dst->pitch + x * bpp); \
90 Uint8 sr = MUL(inva, SHIFTAND(*pixel, rshift, rmask)) + (Uint16) r; \
91 Uint8 sg = MUL(inva, SHIFTAND(*pixel, gshift, gmask)) + (Uint16) g; \
92 Uint8 sb = MUL(inva, SHIFTAND(*pixel, bshift, bmask)) + (Uint16) b; \
93 *pixel = (sr<<rshift) | (sg<<gshift) | (sb<<bshift); \
94 } while (0)
95
96 #define SETPIXEL_ADD(x, y, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
97 do { \
98 type *pixel = (type *)(dst->pixels + y * dst->pitch + x * bpp); \
99 Uint16 sr = SHIFTAND(*pixel, rshift, rmask) + (Uint16) r; \
100 Uint16 sg = SHIFTAND(*pixel, gshift, gmask) + (Uint16) g; \
101 Uint16 sb = SHIFTAND(*pixel, bshift, bmask) + (Uint16) b; \
102 if (sr>rmask) sr = rmask; \
103 if (sg>gmask) sg = gmask; \
104 if (sb>bmask) sb = bmask; \
105 *pixel = (sr<<rshift) | (sg<<gshift) | (sb<<bshift); \
106 } while (0)
107
108 #define SETPIXEL_MOD(x, y, type, bpp, rshift, gshift, bshift, rmask, gmask, bmask) \
109 do { \
110 type *pixel = (type *)(dst->pixels + y * dst->pitch + x * bpp); \
111 Uint8 sr = MUL(SHIFTAND(*pixel, rshift, rmask), r); \
112 Uint8 sg = MUL(SHIFTAND(*pixel, gshift, gmask), g); \
113 Uint8 sb = MUL(SHIFTAND(*pixel, bshift, bmask), b); \
114 *pixel = (sr<<rshift) | (sg<<gshift) | (sb<<bshift); \
115 } while (0)
116
117
118 #define SETPIXEL15_MASK(x, y) SETPIXEL_MASK(x, y, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
119 #define SETPIXEL15_BLEND(x, y) SETPIXEL_BLEND(x, y, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
120 #define SETPIXEL15_ADD(x, y) SETPIXEL_ADD(x, y, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
121 #define SETPIXEL15_MOD(x, y) SETPIXEL_MOD(x, y, Uint16, 2, 10, 5, 0, 0x1f, 0x1f, 0x1f);
122
123 #define SETPIXEL16_MASK(x, y) SETPIXEL_MASK(x, y, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
124 #define SETPIXEL16_BLEND(x, y) SETPIXEL_BLEND(x, y, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
125 #define SETPIXEL16_ADD(x, y) SETPIXEL_ADD(x, y, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
126 #define SETPIXEL16_MOD(x, y) SETPIXEL_MOD(x, y, Uint16, 2, 11, 5, 0, 0x1f, 0x3f, 0x1f);
127
128 #define SETPIXEL32_MASK(x, y) SETPIXEL_MASK(x, y, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
129 #define SETPIXEL32_BLEND(x, y) SETPIXEL_BLEND(x, y, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
130 #define SETPIXEL32_ADD(x, y) SETPIXEL_ADD(x, y, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
131 #define SETPIXEL32_MOD(x, y) SETPIXEL_MOD(x, y, Uint32, 4, 16, 8, 0, 0xff, 0xff, 0xff);
27 132
28 int 133 int
29 SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, 134 SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
30 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) 135 int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
31 { 136 {
137 Uint8 inva = 0xff - a;
32 /* This function doesn't work on surfaces < 8 bpp */ 138 /* This function doesn't work on surfaces < 8 bpp */
33 if (dst->format->BitsPerPixel < 8) { 139 if (dst->format->BitsPerPixel < 8) {
34 SDL_SetError("SDL_BlendLine(): Unsupported surface format"); 140 SDL_SetError("SDL_BlendLine(): Unsupported surface format");
35 return (-1); 141 return (-1);
36 } 142 }
40 if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) { 146 if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
41 return (0); 147 return (0);
42 } 148 }
43 */ 149 */
44 150
45 SDL_Unsupported(); 151 if ((blendMode == SDL_BLENDMODE_BLEND)
46 return -1; 152 || (blendMode == SDL_BLENDMODE_ADD)) {
153 r = MUL(r, a);
154 g = MUL(g, a);
155 b = MUL(b, a);
156 }
157 switch (dst->format->BitsPerPixel) {
158 case 15:
159 switch (blendMode) {
160 case SDL_BLENDMODE_MASK:
161 BRESENHAM(x1, y1, x2, y2, SETPIXEL15_MASK);
162 break;
163 case SDL_BLENDMODE_BLEND:
164 BRESENHAM(x1, y1, x2, y2, SETPIXEL15_BLEND);
165 break;
166 case SDL_BLENDMODE_ADD:
167 BRESENHAM(x1, y1, x2, y2, SETPIXEL15_ADD);
168 break;
169 case SDL_BLENDMODE_MOD:
170 BRESENHAM(x1, y1, x2, y2, SETPIXEL15_MOD);
171 break;
172 }
173 break;
174 case 16:
175 switch (blendMode) {
176 case SDL_BLENDMODE_MASK:
177 BRESENHAM(x1, y1, x2, y2, SETPIXEL16_MASK);
178 break;
179 case SDL_BLENDMODE_BLEND:
180 BRESENHAM(x1, y1, x2, y2, SETPIXEL16_BLEND);
181 break;
182 case SDL_BLENDMODE_ADD:
183 BRESENHAM(x1, y1, x2, y2, SETPIXEL16_ADD);
184 break;
185 case SDL_BLENDMODE_MOD:
186 BRESENHAM(x1, y1, x2, y2, SETPIXEL16_MOD);
187 break;
188 }
189 break;
190 case 24:
191 case 32:
192 if (dst->format->BytesPerPixel != 4) {
193 SDL_Unsupported();
194 return -1;
195 }
196 switch (blendMode) {
197 case SDL_BLENDMODE_MASK:
198 BRESENHAM(x1, y1, x2, y2, SETPIXEL32_MASK);
199 break;
200 case SDL_BLENDMODE_BLEND:
201 BRESENHAM(x1, y1, x2, y2, SETPIXEL32_BLEND);
202 break;
203 case SDL_BLENDMODE_ADD:
204 BRESENHAM(x1, y1, x2, y2, SETPIXEL32_ADD);
205 break;
206 case SDL_BLENDMODE_MOD:
207 BRESENHAM(x1, y1, x2, y2, SETPIXEL32_MOD);
208 break;
209 }
210 break;
211 default:
212 SDL_Unsupported();
213 return -1;
214 }
215 return 0;
47 } 216 }
48 217
49 /* vi: set ts=4 sw=4 expandtab: */ 218 /* vi: set ts=4 sw=4 expandtab: */