Mercurial > sdl-ios-xcode
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: */ |