Mercurial > sdl-ios-xcode
annotate src/video/SDL_blit_A.c @ 532:058d47b7a3b4
Return an error with color fills on less than 8 bpp surfaces.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 15 Oct 2002 05:22:50 +0000 |
parents | f6ffac90895c |
children | 5bb080d35049 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
1
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 #include <stdio.h> | |
29 | |
30 #include "SDL_types.h" | |
31 #include "SDL_video.h" | |
32 #include "SDL_blit.h" | |
33 | |
34 /* Functions to perform alpha blended blitting */ | |
35 | |
36 /* N->1 blending with per-surface alpha */ | |
37 static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info) | |
38 { | |
39 int width = info->d_width; | |
40 int height = info->d_height; | |
41 Uint8 *src = info->s_pixels; | |
42 int srcskip = info->s_skip; | |
43 Uint8 *dst = info->d_pixels; | |
44 int dstskip = info->d_skip; | |
45 Uint8 *palmap = info->table; | |
46 SDL_PixelFormat *srcfmt = info->src; | |
47 SDL_PixelFormat *dstfmt = info->dst; | |
48 int srcbpp = srcfmt->BytesPerPixel; | |
49 | |
50 const unsigned A = srcfmt->alpha; | |
51 | |
52 while ( height-- ) { | |
53 DUFFS_LOOP4( | |
54 { | |
55 Uint32 pixel; | |
56 unsigned sR; | |
57 unsigned sG; | |
58 unsigned sB; | |
59 unsigned dR; | |
60 unsigned dG; | |
61 unsigned dB; | |
62 DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); | |
63 dR = dstfmt->palette->colors[*dst].r; | |
64 dG = dstfmt->palette->colors[*dst].g; | |
65 dB = dstfmt->palette->colors[*dst].b; | |
66 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
67 dR &= 0xff; | |
68 dG &= 0xff; | |
69 dB &= 0xff; | |
70 /* Pack RGB into 8bit pixel */ | |
71 if ( palmap == NULL ) { | |
72 *dst =((dR>>5)<<(3+2))| | |
73 ((dG>>5)<<(2))| | |
74 ((dB>>6)<<(0)); | |
75 } else { | |
76 *dst = palmap[((dR>>5)<<(3+2))| | |
77 ((dG>>5)<<(2)) | | |
78 ((dB>>6)<<(0))]; | |
79 } | |
80 dst++; | |
81 src += srcbpp; | |
82 }, | |
83 width); | |
84 src += srcskip; | |
85 dst += dstskip; | |
86 } | |
87 } | |
88 | |
89 /* N->1 blending with pixel alpha */ | |
90 static void BlitNto1PixelAlpha(SDL_BlitInfo *info) | |
91 { | |
92 int width = info->d_width; | |
93 int height = info->d_height; | |
94 Uint8 *src = info->s_pixels; | |
95 int srcskip = info->s_skip; | |
96 Uint8 *dst = info->d_pixels; | |
97 int dstskip = info->d_skip; | |
98 Uint8 *palmap = info->table; | |
99 SDL_PixelFormat *srcfmt = info->src; | |
100 SDL_PixelFormat *dstfmt = info->dst; | |
101 int srcbpp = srcfmt->BytesPerPixel; | |
102 | |
103 /* FIXME: fix alpha bit field expansion here too? */ | |
104 while ( height-- ) { | |
105 DUFFS_LOOP4( | |
106 { | |
107 Uint32 pixel; | |
108 unsigned sR; | |
109 unsigned sG; | |
110 unsigned sB; | |
111 unsigned sA; | |
112 unsigned dR; | |
113 unsigned dG; | |
114 unsigned dB; | |
115 DISEMBLE_RGBA(src,srcbpp,srcfmt,pixel,sR,sG,sB,sA); | |
116 dR = dstfmt->palette->colors[*dst].r; | |
117 dG = dstfmt->palette->colors[*dst].g; | |
118 dB = dstfmt->palette->colors[*dst].b; | |
119 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
120 dR &= 0xff; | |
121 dG &= 0xff; | |
122 dB &= 0xff; | |
123 /* Pack RGB into 8bit pixel */ | |
124 if ( palmap == NULL ) { | |
125 *dst =((dR>>5)<<(3+2))| | |
126 ((dG>>5)<<(2))| | |
127 ((dB>>6)<<(0)); | |
128 } else { | |
129 *dst = palmap[((dR>>5)<<(3+2))| | |
130 ((dG>>5)<<(2)) | | |
131 ((dB>>6)<<(0)) ]; | |
132 } | |
133 dst++; | |
134 src += srcbpp; | |
135 }, | |
136 width); | |
137 src += srcskip; | |
138 dst += dstskip; | |
139 } | |
140 } | |
141 | |
142 /* colorkeyed N->1 blending with per-surface alpha */ | |
143 static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info) | |
144 { | |
145 int width = info->d_width; | |
146 int height = info->d_height; | |
147 Uint8 *src = info->s_pixels; | |
148 int srcskip = info->s_skip; | |
149 Uint8 *dst = info->d_pixels; | |
150 int dstskip = info->d_skip; | |
151 Uint8 *palmap = info->table; | |
152 SDL_PixelFormat *srcfmt = info->src; | |
153 SDL_PixelFormat *dstfmt = info->dst; | |
154 int srcbpp = srcfmt->BytesPerPixel; | |
155 Uint32 ckey = srcfmt->colorkey; | |
156 | |
157 const int A = srcfmt->alpha; | |
158 | |
159 while ( height-- ) { | |
160 DUFFS_LOOP( | |
161 { | |
162 Uint32 pixel; | |
163 unsigned sR; | |
164 unsigned sG; | |
165 unsigned sB; | |
166 unsigned dR; | |
167 unsigned dG; | |
168 unsigned dB; | |
169 DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); | |
170 if ( pixel != ckey ) { | |
171 dR = dstfmt->palette->colors[*dst].r; | |
172 dG = dstfmt->palette->colors[*dst].g; | |
173 dB = dstfmt->palette->colors[*dst].b; | |
174 ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); | |
175 dR &= 0xff; | |
176 dG &= 0xff; | |
177 dB &= 0xff; | |
178 /* Pack RGB into 8bit pixel */ | |
179 if ( palmap == NULL ) { | |
180 *dst =((dR>>5)<<(3+2))| | |
181 ((dG>>5)<<(2)) | | |
182 ((dB>>6)<<(0)); | |
183 } else { | |
184 *dst = palmap[((dR>>5)<<(3+2))| | |
185 ((dG>>5)<<(2)) | | |
186 ((dB>>6)<<(0)) ]; | |
187 } | |
188 } | |
189 dst++; | |
190 src += srcbpp; | |
191 }, | |
192 width); | |
193 src += srcskip; | |
194 dst += dstskip; | |
195 } | |
196 } | |
197 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
198 /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
199 static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info) |
0 | 200 { |
201 int width = info->d_width; | |
202 int height = info->d_height; | |
203 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
204 int srcskip = info->s_skip >> 2; | |
205 Uint32 *dstp = (Uint32 *)info->d_pixels; | |
206 int dstskip = info->d_skip >> 2; | |
207 | |
208 while(height--) { | |
209 DUFFS_LOOP4({ | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
210 Uint32 s = *srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
211 Uint32 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
212 *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
213 + (s & d & 0x00010101)) | 0xff000000; |
0 | 214 }, width); |
215 srcp += srcskip; | |
216 dstp += dstskip; | |
217 } | |
218 } | |
219 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
220 /* fast RGB888->(A)RGB888 blending with surface alpha */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
221 static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
222 { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
223 unsigned alpha = info->src->alpha; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
224 if(alpha == 128) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
225 BlitRGBtoRGBSurfaceAlpha128(info); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
226 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
227 int width = info->d_width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
228 int height = info->d_height; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
229 Uint32 *srcp = (Uint32 *)info->s_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
230 int srcskip = info->s_skip >> 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
231 Uint32 *dstp = (Uint32 *)info->d_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
232 int dstskip = info->d_skip >> 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
233 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
234 while(height--) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
235 DUFFS_LOOP4({ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
236 Uint32 s; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
237 Uint32 d; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
238 Uint32 s1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
239 Uint32 d1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
240 s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
241 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
242 s1 = s & 0xff00ff; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
243 d1 = d & 0xff00ff; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
244 d1 = (d1 + ((s1 - d1) * alpha >> 8)) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
245 & 0xff00ff; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
246 s &= 0xff00; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
247 d &= 0xff00; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
248 d = (d + ((s - d) * alpha >> 8)) & 0xff00; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
249 *dstp = d1 | d | 0xff000000; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
250 ++srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
251 ++dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
252 }, width); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
253 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
254 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
255 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
256 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
257 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
258 |
0 | 259 /* fast ARGB888->(A)RGB888 blending with pixel alpha */ |
260 static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) | |
261 { | |
262 int width = info->d_width; | |
263 int height = info->d_height; | |
264 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
265 int srcskip = info->s_skip >> 2; | |
266 Uint32 *dstp = (Uint32 *)info->d_pixels; | |
267 int dstskip = info->d_skip >> 2; | |
268 | |
269 while(height--) { | |
270 DUFFS_LOOP4({ | |
271 Uint32 dalpha; | |
272 Uint32 d; | |
273 Uint32 s1; | |
274 Uint32 d1; | |
275 Uint32 s = *srcp; | |
276 Uint32 alpha = s >> 24; | |
277 /* FIXME: Here we special-case opaque alpha since the | |
278 compositioning used (>>8 instead of /255) doesn't handle | |
279 it correctly. Also special-case alpha=0 for speed? | |
280 Benchmark this! */ | |
281 if(alpha == SDL_ALPHA_OPAQUE) { | |
282 *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); | |
283 } else { | |
284 /* | |
285 * take out the middle component (green), and process | |
286 * the other two in parallel. One multiply less. | |
287 */ | |
288 d = *dstp; | |
289 dalpha = d & 0xff000000; | |
290 s1 = s & 0xff00ff; | |
291 d1 = d & 0xff00ff; | |
292 d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; | |
293 s &= 0xff00; | |
294 d &= 0xff00; | |
295 d = (d + ((s - d) * alpha >> 8)) & 0xff00; | |
296 *dstp = d1 | d | dalpha; | |
297 } | |
298 ++srcp; | |
299 ++dstp; | |
300 }, width); | |
301 srcp += srcskip; | |
302 dstp += dstskip; | |
303 } | |
304 } | |
305 | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
306 /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
307 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
308 /* blend a single 16 bit pixel at 50% */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
309 #define BLEND16_50(d, s, mask) \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
310 ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
311 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
312 /* blend two 16 bit pixels at 50% */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
313 #define BLEND2x16_50(d, s, mask) \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
314 (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
315 + (s & d & (~(mask | mask << 16)))) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
316 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
317 static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask) |
0 | 318 { |
319 int width = info->d_width; | |
320 int height = info->d_height; | |
321 Uint16 *srcp = (Uint16 *)info->s_pixels; | |
322 int srcskip = info->s_skip >> 1; | |
323 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
324 int dstskip = info->d_skip >> 1; | |
325 | |
326 while(height--) { | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
327 if(((unsigned long)srcp ^ (unsigned long)dstp) & 2) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
328 /* |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
329 * Source and destination not aligned, pipeline it. |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
330 * This is mostly a win for big blits but no loss for |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
331 * small ones |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
332 */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
333 Uint32 prev_sw; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
334 int w = width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
335 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
336 /* handle odd destination */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
337 if((unsigned long)dstp & 2) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
338 Uint16 d = *dstp, s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
339 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
340 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
341 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
342 w--; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
343 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
344 srcp++; /* srcp is now 32-bit aligned */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
345 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
346 /* bootstrap pipeline with first halfword */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
347 prev_sw = ((Uint32 *)srcp)[-1]; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
348 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
349 while(w > 1) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
350 Uint32 sw, dw, s; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
351 sw = *(Uint32 *)srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
352 dw = *(Uint32 *)dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
353 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
354 s = (prev_sw << 16) + (sw >> 16); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
355 else |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
356 s = (prev_sw >> 16) + (sw << 16); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
357 prev_sw = sw; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
358 *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
359 dstp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
360 srcp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
361 w -= 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
362 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
363 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
364 /* final pixel if any */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
365 if(w) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
366 Uint16 d = *dstp, s; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
367 if(SDL_BYTEORDER == SDL_BIG_ENDIAN) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
368 s = prev_sw; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
369 else |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
370 s = prev_sw >> 16; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
371 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
372 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
373 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
374 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
375 srcp += srcskip - 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
376 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
377 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
378 /* source and destination are aligned */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
379 int w = width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
380 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
381 /* first odd pixel? */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
382 if((unsigned long)srcp & 2) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
383 Uint16 d = *dstp, s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
384 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
385 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
386 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
387 w--; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
388 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
389 /* srcp and dstp are now 32-bit aligned */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
390 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
391 while(w > 1) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
392 Uint32 sw = *(Uint32 *)srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
393 Uint32 dw = *(Uint32 *)dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
394 *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
395 srcp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
396 dstp += 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
397 w -= 2; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
398 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
399 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
400 /* last odd pixel? */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
401 if(w) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
402 Uint16 d = *dstp, s = *srcp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
403 *dstp = BLEND16_50(d, s, mask); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
404 srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
405 dstp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
406 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
407 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
408 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
409 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
410 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
411 } |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
412 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
413 /* fast RGB565->RGB565 blending with surface alpha */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
414 static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
415 { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
416 unsigned alpha = info->src->alpha; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
417 if(alpha == 128) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
418 Blit16to16SurfaceAlpha128(info, 0xf7de); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
419 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
420 int width = info->d_width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
421 int height = info->d_height; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
422 Uint16 *srcp = (Uint16 *)info->s_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
423 int srcskip = info->s_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
424 Uint16 *dstp = (Uint16 *)info->d_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
425 int dstskip = info->d_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
426 alpha >>= 3; /* downscale alpha to 5 bits */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
427 |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
428 while(height--) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
429 DUFFS_LOOP4({ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
430 Uint32 s = *srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
431 Uint32 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
432 /* |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
433 * shift out the middle component (green) to |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
434 * the high 16 bits, and process all three RGB |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
435 * components at the same time. |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
436 */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
437 s = (s | s << 16) & 0x07e0f81f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
438 d = (d | d << 16) & 0x07e0f81f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
439 d += (s - d) * alpha >> 5; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
440 d &= 0x07e0f81f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
441 *dstp++ = d | d >> 16; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
442 }, width); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
443 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
444 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
445 } |
0 | 446 } |
447 } | |
448 | |
449 /* fast RGB555->RGB555 blending with surface alpha */ | |
450 static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) | |
451 { | |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
452 unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
453 if(alpha == 128) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
454 Blit16to16SurfaceAlpha128(info, 0xfbde); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
455 } else { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
456 int width = info->d_width; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
457 int height = info->d_height; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
458 Uint16 *srcp = (Uint16 *)info->s_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
459 int srcskip = info->s_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
460 Uint16 *dstp = (Uint16 *)info->d_pixels; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
461 int dstskip = info->d_skip >> 1; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
462 alpha >>= 3; /* downscale alpha to 5 bits */ |
0 | 463 |
1
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
464 while(height--) { |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
465 DUFFS_LOOP4({ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
466 Uint32 s = *srcp++; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
467 Uint32 d = *dstp; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
468 /* |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
469 * shift out the middle component (green) to |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
470 * the high 16 bits, and process all three RGB |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
471 * components at the same time. |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
472 */ |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
473 s = (s | s << 16) & 0x03e07c1f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
474 d = (d | d << 16) & 0x03e07c1f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
475 d += (s - d) * alpha >> 5; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
476 d &= 0x03e07c1f; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
477 *dstp++ = d | d >> 16; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
478 }, width); |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
479 srcp += srcskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
480 dstp += dstskip; |
cf2af46e9e2a
Changes since SDL 1.2.0 release
Sam Lantinga <slouken@lokigames.com>
parents:
0
diff
changeset
|
481 } |
0 | 482 } |
483 } | |
484 | |
485 /* fast ARGB8888->RGB565 blending with pixel alpha */ | |
486 static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) | |
487 { | |
488 int width = info->d_width; | |
489 int height = info->d_height; | |
490 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
491 int srcskip = info->s_skip >> 2; | |
492 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
493 int dstskip = info->d_skip >> 1; | |
494 | |
495 while(height--) { | |
496 DUFFS_LOOP4({ | |
497 Uint32 s = *srcp; | |
498 unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ | |
499 /* FIXME: Here we special-case opaque alpha since the | |
500 compositioning used (>>8 instead of /255) doesn't handle | |
501 it correctly. Also special-case alpha=0 for speed? | |
502 Benchmark this! */ | |
503 if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { | |
504 *dstp = (s >> 8 & 0xf800) + (s >> 5 & 0x7e0) | |
505 + (s >> 3 & 0x1f); | |
506 } else { | |
507 Uint32 d = *dstp; | |
508 /* | |
509 * convert source and destination to G0RAB65565 | |
510 * and blend all components at the same time | |
511 */ | |
512 s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) | |
513 + (s >> 3 & 0x1f); | |
514 d = (d | d << 16) & 0x07e0f81f; | |
515 d += (s - d) * alpha >> 5; | |
516 d &= 0x07e0f81f; | |
517 *dstp = d | d >> 16; | |
518 } | |
519 srcp++; | |
520 dstp++; | |
521 }, width); | |
522 srcp += srcskip; | |
523 dstp += dstskip; | |
524 } | |
525 } | |
526 | |
527 /* fast ARGB8888->RGB555 blending with pixel alpha */ | |
528 static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info) | |
529 { | |
530 int width = info->d_width; | |
531 int height = info->d_height; | |
532 Uint32 *srcp = (Uint32 *)info->s_pixels; | |
533 int srcskip = info->s_skip >> 2; | |
534 Uint16 *dstp = (Uint16 *)info->d_pixels; | |
535 int dstskip = info->d_skip >> 1; | |
536 | |
537 while(height--) { | |
538 DUFFS_LOOP4({ | |
539 unsigned alpha; | |
540 Uint32 s = *srcp; | |
541 alpha = s >> 27; /* downscale alpha to 5 bits */ | |
542 /* FIXME: Here we special-case opaque alpha since the | |
543 compositioning used (>>8 instead of /255) doesn't handle | |
544 it correctly. Also special-case alpha=0 for speed? | |
545 Benchmark this! */ | |
546 if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { | |
547 *dstp = (s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) | |
548 + (s >> 3 & 0x1f); | |
549 } else { | |
550 Uint32 d = *dstp; | |
551 /* | |
552 * convert source and destination to G0RAB65565 | |
553 * and blend all components at the same time | |
554 */ | |
555 s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) | |
556 + (s >> 3 & 0x1f); | |
557 d = (d | d << 16) & 0x03e07c1f; | |
558 d += (s - d) * alpha >> 5; | |
559 d &= 0x03e07c1f; | |
560 *dstp = d | d >> 16; | |
561 } | |
562 srcp++; | |
563 dstp++; | |
564 }, width); | |
565 srcp += srcskip; | |
566 dstp += dstskip; | |
567 } | |
568 } | |
569 | |
570 /* General (slow) N->N blending with per-surface alpha */ | |
571 static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info) | |
572 { | |
573 int width = info->d_width; | |
574 int height = info->d_height; | |
575 Uint8 *src = info->s_pixels; | |
576 int srcskip = info->s_skip; | |
577 Uint8 *dst = info->d_pixels; | |
578 int dstskip = info->d_skip; | |
579 SDL_PixelFormat *srcfmt = info->src; | |
580 SDL_PixelFormat *dstfmt = info->dst; | |
581 int srcbpp = srcfmt->BytesPerPixel; | |
582 int dstbpp = dstfmt->BytesPerPixel; | |
583 unsigned sA = srcfmt->alpha; | |
584 unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; | |
585 | |
586 while ( height-- ) { | |
587 DUFFS_LOOP4( | |
588 { | |
589 Uint32 pixel; | |
590 unsigned sR; | |
591 unsigned sG; | |
592 unsigned sB; | |
593 unsigned dR; | |
594 unsigned dG; | |
595 unsigned dB; | |
596 DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); | |
597 DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); | |
598 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
599 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); | |
600 src += srcbpp; | |
601 dst += dstbpp; | |
602 }, | |
603 width); | |
604 src += srcskip; | |
605 dst += dstskip; | |
606 } | |
607 } | |
608 | |
609 /* General (slow) colorkeyed N->N blending with per-surface alpha */ | |
610 static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info) | |
611 { | |
612 int width = info->d_width; | |
613 int height = info->d_height; | |
614 Uint8 *src = info->s_pixels; | |
615 int srcskip = info->s_skip; | |
616 Uint8 *dst = info->d_pixels; | |
617 int dstskip = info->d_skip; | |
618 SDL_PixelFormat *srcfmt = info->src; | |
619 SDL_PixelFormat *dstfmt = info->dst; | |
620 Uint32 ckey = srcfmt->colorkey; | |
621 int srcbpp = srcfmt->BytesPerPixel; | |
622 int dstbpp = dstfmt->BytesPerPixel; | |
623 unsigned sA = srcfmt->alpha; | |
624 unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; | |
625 | |
626 while ( height-- ) { | |
627 DUFFS_LOOP4( | |
628 { | |
629 Uint32 pixel; | |
630 unsigned sR; | |
631 unsigned sG; | |
632 unsigned sB; | |
633 unsigned dR; | |
634 unsigned dG; | |
635 unsigned dB; | |
636 RETRIEVE_RGB_PIXEL(src, srcbpp, pixel); | |
637 if(pixel != ckey) { | |
638 RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB); | |
639 DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); | |
640 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
641 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); | |
642 } | |
643 src += srcbpp; | |
644 dst += dstbpp; | |
645 }, | |
646 width); | |
647 src += srcskip; | |
648 dst += dstskip; | |
649 } | |
650 } | |
651 | |
652 /* General (slow) N->N blending with pixel alpha */ | |
653 static void BlitNtoNPixelAlpha(SDL_BlitInfo *info) | |
654 { | |
655 int width = info->d_width; | |
656 int height = info->d_height; | |
657 Uint8 *src = info->s_pixels; | |
658 int srcskip = info->s_skip; | |
659 Uint8 *dst = info->d_pixels; | |
660 int dstskip = info->d_skip; | |
661 SDL_PixelFormat *srcfmt = info->src; | |
662 SDL_PixelFormat *dstfmt = info->dst; | |
663 | |
664 int srcbpp; | |
665 int dstbpp; | |
666 | |
667 /* Set up some basic variables */ | |
668 srcbpp = srcfmt->BytesPerPixel; | |
669 dstbpp = dstfmt->BytesPerPixel; | |
670 | |
671 /* FIXME: for 8bpp source alpha, this doesn't get opaque values | |
672 quite right. for <8bpp source alpha, it gets them very wrong | |
673 (check all macros!) | |
674 It is unclear whether there is a good general solution that doesn't | |
675 need a branch (or a divide). */ | |
676 while ( height-- ) { | |
677 DUFFS_LOOP4( | |
678 { | |
679 Uint32 pixel; | |
680 unsigned sR; | |
681 unsigned sG; | |
682 unsigned sB; | |
683 unsigned dR; | |
684 unsigned dG; | |
685 unsigned dB; | |
686 unsigned sA; | |
687 unsigned dA; | |
688 DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA); | |
689 DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); | |
690 ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); | |
691 ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); | |
692 src += srcbpp; | |
693 dst += dstbpp; | |
694 }, | |
695 width); | |
696 src += srcskip; | |
697 dst += dstskip; | |
698 } | |
699 } | |
700 | |
701 | |
702 SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index) | |
703 { | |
704 SDL_PixelFormat *sf = surface->format; | |
705 SDL_PixelFormat *df = surface->map->dst->format; | |
706 | |
707 if(sf->Amask == 0) { | |
708 if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { | |
709 if(df->BytesPerPixel == 1) | |
710 return BlitNto1SurfaceAlphaKey; | |
711 else | |
712 return BlitNtoNSurfaceAlphaKey; | |
713 } else { | |
714 /* Per-surface alpha blits */ | |
715 switch(df->BytesPerPixel) { | |
716 case 1: | |
717 return BlitNto1SurfaceAlpha; | |
718 | |
719 case 2: | |
720 if(surface->map->identity) { | |
721 if(df->Gmask == 0x7e0) | |
722 return Blit565to565SurfaceAlpha; | |
723 else if(df->Gmask == 0x3e0) | |
724 return Blit555to555SurfaceAlpha; | |
725 } | |
726 return BlitNtoNSurfaceAlpha; | |
727 | |
728 case 4: | |
729 if(sf->Rmask == df->Rmask | |
730 && sf->Gmask == df->Gmask | |
731 && sf->Bmask == df->Bmask | |
732 && (sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff | |
733 && sf->BytesPerPixel == 4) | |
734 return BlitRGBtoRGBSurfaceAlpha; | |
735 else | |
736 return BlitNtoNSurfaceAlpha; | |
737 | |
738 case 3: | |
739 default: | |
740 return BlitNtoNSurfaceAlpha; | |
741 } | |
742 } | |
743 } else { | |
744 /* Per-pixel alpha blits */ | |
745 switch(df->BytesPerPixel) { | |
746 case 1: | |
747 return BlitNto1PixelAlpha; | |
748 | |
749 case 2: | |
750 if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 | |
751 && sf->Gmask == 0xff00 | |
752 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) | |
753 || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { | |
754 if(df->Gmask == 0x7e0) | |
755 return BlitARGBto565PixelAlpha; | |
756 else if(df->Gmask == 0x3e0) | |
757 return BlitARGBto555PixelAlpha; | |
758 } | |
759 return BlitNtoNPixelAlpha; | |
760 | |
761 case 4: | |
762 if(sf->Amask == 0xff000000 | |
763 && sf->Rmask == df->Rmask | |
764 && sf->Gmask == df->Gmask | |
765 && sf->Bmask == df->Bmask | |
766 && sf->BytesPerPixel == 4) | |
767 return BlitRGBtoRGBPixelAlpha; | |
768 return BlitNtoNPixelAlpha; | |
769 | |
770 case 3: | |
771 default: | |
772 return BlitNtoNPixelAlpha; | |
773 } | |
774 } | |
775 } | |
776 |