Mercurial > sdl-ios-xcode
comparison src/video/sdlgenblit.pl @ 1985:8055185ae4ed
Added source color and alpha modulation support.
Added perl script to generate optimized render copy functions.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 28 Aug 2006 03:17:39 +0000 |
parents | |
children | 5b5f5de5433f |
comparison
equal
deleted
inserted
replaced
1984:b910bcabec26 | 1985:8055185ae4ed |
---|---|
1 #!/usr/bin/perl -w | |
2 # | |
3 # A script to generate optimized C blitters for Simple DirectMedia Layer | |
4 # http://www.libsdl.org/ | |
5 | |
6 use warnings; | |
7 use strict; | |
8 | |
9 my %file; | |
10 | |
11 # The formats potentially supported by this script: | |
12 # SDL_PIXELFORMAT_INDEX8 | |
13 # SDL_PIXELFORMAT_RGB332 | |
14 # SDL_PIXELFORMAT_RGB444 | |
15 # SDL_PIXELFORMAT_RGB555 | |
16 # SDL_PIXELFORMAT_ARGB4444 | |
17 # SDL_PIXELFORMAT_ARGB1555 | |
18 # SDL_PIXELFORMAT_RGB565 | |
19 # SDL_PIXELFORMAT_RGB24 | |
20 # SDL_PIXELFORMAT_BGR24 | |
21 # SDL_PIXELFORMAT_RGB888 | |
22 # SDL_PIXELFORMAT_BGR888 | |
23 # SDL_PIXELFORMAT_ARGB8888 | |
24 # SDL_PIXELFORMAT_RGBA8888 | |
25 # SDL_PIXELFORMAT_ABGR8888 | |
26 # SDL_PIXELFORMAT_BGRA8888 | |
27 # SDL_PIXELFORMAT_ARGB2101010 | |
28 | |
29 # The formats we're actually creating blitters for: | |
30 my @src_formats = ( | |
31 "RGB888", | |
32 "BGR888", | |
33 "ARGB8888", | |
34 "RGBA8888", | |
35 "ABGR8888", | |
36 "BGRA8888", | |
37 ); | |
38 my @dst_formats = ( | |
39 "RGB888", | |
40 "BGR888", | |
41 ); | |
42 | |
43 my %format_size = ( | |
44 "RGB888" => 4, | |
45 "BGR888" => 4, | |
46 "ARGB8888" => 4, | |
47 "RGBA8888" => 4, | |
48 "ABGR8888" => 4, | |
49 "BGRA8888" => 4, | |
50 ); | |
51 | |
52 my %format_type = ( | |
53 "RGB888" => "Uint32", | |
54 "BGR888" => "Uint32", | |
55 "ARGB8888" => "Uint32", | |
56 "RGBA8888" => "Uint32", | |
57 "ABGR8888" => "Uint32", | |
58 "BGRA8888" => "Uint32", | |
59 ); | |
60 | |
61 my %get_rgba_string = ( | |
62 "RGB888" => "_R = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _B = (Uint8)_pixel; _A = 0xFF;", | |
63 "BGR888" => "_B = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _R = (Uint8)_pixel; _A = 0xFF;", | |
64 "ARGB8888" => "_A = (Uint8)(_pixel >> 24); _R = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _B = (Uint8)_pixel;", | |
65 "RGBA8888" => "_R = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _B = (Uint8)(_pixel >> 8); _A = (Uint8)_pixel;", | |
66 "ABGR8888" => "_A = (Uint8)(_pixel >> 24); _B = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _R = (Uint8)_pixel;", | |
67 "BGRA8888" => "_B = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _R = (Uint8)(_pixel >> 8); _A = (Uint8)_pixel;", | |
68 ); | |
69 | |
70 my %set_rgba_string = ( | |
71 "RGB888" => "_pixel = ((Uint32)_R << 16) | ((Uint32)_G << 8) | _B;", | |
72 "BGR888" => "_pixel = ((Uint32)_B << 16) | ((Uint32)_G << 8) | _R;", | |
73 ); | |
74 | |
75 sub open_file { | |
76 my $name = shift; | |
77 open(FILE, ">$name.new") || die "Cant' open $name.new: $!"; | |
78 print FILE <<__EOF__; | |
79 /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ | |
80 /* | |
81 SDL - Simple DirectMedia Layer | |
82 Copyright (C) 1997-2006 Sam Lantinga | |
83 | |
84 This library is free software; you can redistribute it and/or | |
85 modify it under the terms of the GNU Lesser General Public | |
86 License as published by the Free Software Foundation; either | |
87 version 2.1 of the License, or (at your option) any later version. | |
88 | |
89 This library is distributed in the hope that it will be useful, | |
90 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
91 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
92 Lesser General Public License for more details. | |
93 | |
94 You should have received a copy of the GNU Lesser General Public | |
95 License along with this library; if not, write to the Free Software | |
96 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
97 | |
98 Sam Lantinga | |
99 slouken\@libsdl.org | |
100 */ | |
101 #include "SDL_config.h" | |
102 | |
103 /* *INDENT-OFF* */ | |
104 | |
105 __EOF__ | |
106 } | |
107 | |
108 sub close_file { | |
109 my $name = shift; | |
110 print FILE <<__EOF__; | |
111 /* *INDENT-ON* */ | |
112 | |
113 /* vi: set ts=4 sw=4 expandtab: */ | |
114 __EOF__ | |
115 close FILE; | |
116 if ( ! -f $name || system("cmp -s $name $name.new") != 0 ) { | |
117 rename("$name.new", "$name"); | |
118 } else { | |
119 unlink("$name.new"); | |
120 } | |
121 } | |
122 | |
123 sub output_copydefs | |
124 { | |
125 print FILE <<__EOF__; | |
126 #define SDL_RENDERCOPY_MODULATE_COLOR 0x0001 | |
127 #define SDL_RENDERCOPY_MODULATE_ALPHA 0x0002 | |
128 #define SDL_RENDERCOPY_BLEND 0x0010 | |
129 #define SDL_RENDERCOPY_ADD 0x0020 | |
130 #define SDL_RENDERCOPY_MOD 0x0040 | |
131 #define SDL_RENDERCOPY_NEAREST 0x0100 | |
132 | |
133 typedef struct { | |
134 void *src; | |
135 int src_w, src_h; | |
136 int src_pitch; | |
137 void *dst; | |
138 int dst_w, dst_h; | |
139 int dst_pitch; | |
140 void *aux_data; | |
141 int flags; | |
142 Uint8 r, g, b, a; | |
143 } SDL_RenderCopyData; | |
144 | |
145 typedef int (*SDL_RenderCopyFunc)(SDL_RenderCopyData *data); | |
146 | |
147 extern SDL_RenderCopyFunc SDLCALL SDL_GetRenderCopyFunc(Uint32 src_format, Uint32 dst_format, int modMode, int blendMode, int scaleMode); | |
148 | |
149 __EOF__ | |
150 } | |
151 | |
152 sub output_copyfuncname | |
153 { | |
154 my $prefix = shift; | |
155 my $src = shift; | |
156 my $dst = shift; | |
157 my $modulate = shift; | |
158 my $blend = shift; | |
159 my $scale = shift; | |
160 my $args = shift; | |
161 my $suffix = shift; | |
162 | |
163 print FILE "$prefix SDL_RenderCopy_${src}_${dst}"; | |
164 if ( $modulate ) { | |
165 print FILE "_Modulate"; | |
166 } | |
167 if ( $blend ) { | |
168 print FILE "_Blend"; | |
169 } | |
170 if ( $scale ) { | |
171 print FILE "_Scale"; | |
172 } | |
173 if ( $args ) { | |
174 print FILE "(SDL_RenderCopyData *data)"; | |
175 } | |
176 print FILE "$suffix"; | |
177 } | |
178 | |
179 sub get_rgba | |
180 { | |
181 my $prefix = shift; | |
182 my $format = shift; | |
183 my $string = $get_rgba_string{$format}; | |
184 $string =~ s/_/$prefix/g; | |
185 if ( $prefix ne "" ) { | |
186 print FILE <<__EOF__; | |
187 ${prefix}pixel = *$prefix; | |
188 __EOF__ | |
189 } else { | |
190 print FILE <<__EOF__; | |
191 pixel = *src; | |
192 __EOF__ | |
193 } | |
194 print FILE <<__EOF__; | |
195 $string | |
196 __EOF__ | |
197 } | |
198 | |
199 sub set_rgba | |
200 { | |
201 my $prefix = shift; | |
202 my $format = shift; | |
203 my $string = $set_rgba_string{$format}; | |
204 $string =~ s/_/$prefix/g; | |
205 print FILE <<__EOF__; | |
206 $string | |
207 *dst = ${prefix}pixel; | |
208 __EOF__ | |
209 } | |
210 | |
211 sub output_copycore | |
212 { | |
213 my $src = shift; | |
214 my $dst = shift; | |
215 my $modulate = shift; | |
216 my $blend = shift; | |
217 if ( $modulate ) { | |
218 print FILE <<__EOF__; | |
219 if (flags & SDL_RENDERCOPY_MODULATE_COLOR) { | |
220 ${src}R = (${src}R * modulateR) / 255; | |
221 ${src}G = (${src}G * modulateG) / 255; | |
222 ${src}B = (${src}B * modulateB) / 255; | |
223 } | |
224 __EOF__ | |
225 } | |
226 if ( $modulate && $blend ) { | |
227 print FILE <<__EOF__; | |
228 if (flags & SDL_RENDERCOPY_MODULATE_ALPHA) { | |
229 ${src}A = (${src}A * modulateA) / 255; | |
230 } | |
231 __EOF__ | |
232 } | |
233 if ( $blend ) { | |
234 print FILE <<__EOF__; | |
235 if (flags & (SDL_RENDERCOPY_BLEND|SDL_RENDERCOPY_ADD)) { | |
236 /* This goes away if we ever use premultiplied alpha */ | |
237 ${src}R = (${src}R * ${src}A) / 255; | |
238 ${src}G = (${src}G * ${src}A) / 255; | |
239 ${src}B = (${src}B * ${src}A) / 255; | |
240 } | |
241 switch (flags & (SDL_RENDERCOPY_BLEND|SDL_RENDERCOPY_ADD|SDL_RENDERCOPY_MOD)) { | |
242 case SDL_RENDERCOPY_BLEND: | |
243 ${dst}R = ${src}R + ((255 - ${src}A) * ${dst}R) / 255; | |
244 ${dst}G = ${src}G + ((255 - ${src}A) * ${dst}G) / 255; | |
245 ${dst}B = ${src}B + ((255 - ${src}A) * ${dst}B) / 255; | |
246 break; | |
247 case SDL_RENDERCOPY_ADD: | |
248 ${dst}R = ${src}R + ${dst}R; if (${dst}R > 255) ${dst}R = 255; | |
249 ${dst}G = ${src}G + ${dst}G; if (${dst}G > 255) ${dst}G = 255; | |
250 ${dst}B = ${src}B + ${dst}B; if (${dst}B > 255) ${dst}B = 255; | |
251 break; | |
252 case SDL_RENDERCOPY_MOD: | |
253 ${dst}R = (${src}R * ${dst}R) / 255; | |
254 ${dst}G = (${src}G * ${dst}G) / 255; | |
255 ${dst}B = (${src}B * ${dst}B) / 255; | |
256 break; | |
257 } | |
258 __EOF__ | |
259 } | |
260 } | |
261 | |
262 sub output_copyfunc | |
263 { | |
264 my $src = shift; | |
265 my $dst = shift; | |
266 my $modulate = shift; | |
267 my $blend = shift; | |
268 my $scale = shift; | |
269 | |
270 output_copyfuncname("int", $src, $dst, $modulate, $blend, $scale, 1, "\n"); | |
271 print FILE <<__EOF__; | |
272 { | |
273 const int flags = data->flags; | |
274 __EOF__ | |
275 if ( $modulate ) { | |
276 print FILE <<__EOF__; | |
277 const Uint32 modulateR = data->r; | |
278 const Uint32 modulateG = data->g; | |
279 const Uint32 modulateB = data->b; | |
280 const Uint32 modulateA = data->a; | |
281 __EOF__ | |
282 } | |
283 if ( $blend ) { | |
284 print FILE <<__EOF__; | |
285 Uint32 srcpixel; | |
286 Uint32 srcR, srcG, srcB, srcA; | |
287 Uint32 dstpixel; | |
288 Uint32 dstR, dstG, dstB, dstA; | |
289 __EOF__ | |
290 } elsif ( $modulate || $src ne $dst ) { | |
291 print FILE <<__EOF__; | |
292 Uint32 pixel; | |
293 Uint32 R, G, B, A; | |
294 __EOF__ | |
295 } | |
296 if ( $scale ) { | |
297 print FILE <<__EOF__; | |
298 int srcy, srcx; | |
299 int posy, posx; | |
300 int incy, incx; | |
301 | |
302 srcy = 0; | |
303 posy = 0; | |
304 incy = (data->src_h << 16) / data->dst_h; | |
305 incx = (data->src_w << 16) / data->dst_w; | |
306 | |
307 while (data->dst_h--) { | |
308 $format_type{$src} *src; | |
309 $format_type{$dst} *dst = ($format_type{$dst} *)data->dst; | |
310 int n = data->dst_w; | |
311 srcx = -1; | |
312 posx = 0x10000L; | |
313 while (posy >= 0x10000L) { | |
314 ++srcy; | |
315 posy -= 0x10000L; | |
316 } | |
317 while (n--) { | |
318 if (posx >= 0x10000L) { | |
319 while (posx >= 0x10000L) { | |
320 ++srcx; | |
321 posx -= 0x10000L; | |
322 } | |
323 src = ($format_type{$src} *)(data->src + (srcy * data->src_pitch) + (srcx * $format_size{$src})); | |
324 __EOF__ | |
325 print FILE <<__EOF__; | |
326 } | |
327 __EOF__ | |
328 if ( $blend ) { | |
329 get_rgba("src", $src); | |
330 get_rgba("dst", $dst); | |
331 output_copycore("src", "dst", $modulate, $blend); | |
332 set_rgba("dst", $dst); | |
333 } elsif ( $modulate || $src ne $dst ) { | |
334 get_rgba("", $src); | |
335 output_copycore("", "", $modulate, $blend); | |
336 set_rgba("", $dst); | |
337 } else { | |
338 print FILE <<__EOF__; | |
339 *dst = *src; | |
340 __EOF__ | |
341 } | |
342 print FILE <<__EOF__; | |
343 posx += incx; | |
344 ++dst; | |
345 } | |
346 posy += incy; | |
347 data->dst += data->dst_pitch; | |
348 } | |
349 __EOF__ | |
350 } else { | |
351 print FILE <<__EOF__; | |
352 | |
353 while (data->dst_h--) { | |
354 $format_type{$src} *src = ($format_type{$src} *)data->src; | |
355 $format_type{$dst} *dst = ($format_type{$dst} *)data->dst; | |
356 int n = data->dst_w; | |
357 while (n--) { | |
358 __EOF__ | |
359 if ( $blend ) { | |
360 get_rgba("src", $src); | |
361 get_rgba("dst", $dst); | |
362 output_copycore("src", "dst", $modulate, $blend); | |
363 set_rgba("dst", $dst); | |
364 } elsif ( $modulate || $src ne $dst ) { | |
365 get_rgba("", $src); | |
366 output_copycore("", "", $modulate, $blend); | |
367 set_rgba("", $dst); | |
368 } else { | |
369 print FILE <<__EOF__; | |
370 *dst = *src; | |
371 __EOF__ | |
372 } | |
373 print FILE <<__EOF__; | |
374 ++src; | |
375 ++dst; | |
376 } | |
377 data->src += data->src_pitch; | |
378 data->dst += data->dst_pitch; | |
379 } | |
380 __EOF__ | |
381 } | |
382 print FILE <<__EOF__; | |
383 return 0; | |
384 } | |
385 | |
386 __EOF__ | |
387 } | |
388 | |
389 sub output_copyfunc_h | |
390 { | |
391 my $src = shift; | |
392 my $dst = shift; | |
393 for (my $modulate = 0; $modulate <= 1; ++$modulate) { | |
394 for (my $blend = 0; $blend <= 1; ++$blend) { | |
395 for (my $scale = 0; $scale <= 1; ++$scale) { | |
396 if ( $modulate != 0 || $blend != 0 || $scale != 0 || $src ne $dst ) { | |
397 output_copyfuncname("extern int SDLCALL", $src, $dst, $modulate, $blend, $scale, 1, ";\n"); | |
398 } | |
399 } | |
400 } | |
401 } | |
402 } | |
403 | |
404 sub output_copyinc | |
405 { | |
406 print FILE <<__EOF__; | |
407 #include "SDL_video.h" | |
408 #include "SDL_rendercopy.h" | |
409 | |
410 __EOF__ | |
411 } | |
412 | |
413 sub output_copyfunctable | |
414 { | |
415 print FILE <<__EOF__; | |
416 static struct { | |
417 Uint32 src_format; | |
418 Uint32 dst_format; | |
419 int modMode; | |
420 int blendMode; | |
421 int scaleMode; | |
422 SDL_RenderCopyFunc func; | |
423 } SDL_RenderCopyFuncTable[] = { | |
424 __EOF__ | |
425 for (my $i = 0; $i <= $#src_formats; ++$i) { | |
426 my $src = $src_formats[$i]; | |
427 for (my $j = 0; $j <= $#dst_formats; ++$j) { | |
428 my $dst = $dst_formats[$j]; | |
429 for (my $modulate = 0; $modulate <= 1; ++$modulate) { | |
430 for (my $blend = 0; $blend <= 1; ++$blend) { | |
431 for (my $scale = 0; $scale <= 1; ++$scale) { | |
432 if ( $modulate != 0 || $blend != 0 || $scale != 0 || $src ne $dst ) { | |
433 print FILE " { SDL_PIXELFORMAT_$src, SDL_PIXELFORMAT_$dst, "; | |
434 if ( $modulate ) { | |
435 print FILE "(SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA), "; | |
436 } else { | |
437 print FILE "0, "; | |
438 } | |
439 if ( $blend ) { | |
440 print FILE "(SDL_TEXTUREBLENDMODE_MASK | SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD | SDL_TEXTUREBLENDMODE_MOD), "; | |
441 } else { | |
442 print FILE "0, "; | |
443 } | |
444 if ( $scale ) { | |
445 print FILE "SDL_TEXTURESCALEMODE_FAST, "; | |
446 } else { | |
447 print FILE "0, "; | |
448 } | |
449 output_copyfuncname("", $src_formats[$i], $dst_formats[$j], $modulate, $blend, $scale, 0, " },\n"); | |
450 } | |
451 } | |
452 } | |
453 } | |
454 } | |
455 } | |
456 print FILE <<__EOF__; | |
457 }; | |
458 | |
459 SDL_RenderCopyFunc SDL_GetRenderCopyFunc(Uint32 src_format, Uint32 dst_format, int modMode, int blendMode, int scaleMode) | |
460 { | |
461 int i; | |
462 | |
463 for (i = 0; i < SDL_arraysize(SDL_RenderCopyFuncTable); ++i) { | |
464 if (src_format != SDL_RenderCopyFuncTable[i].src_format) { | |
465 continue; | |
466 } | |
467 if (dst_format != SDL_RenderCopyFuncTable[i].dst_format) { | |
468 continue; | |
469 } | |
470 if ((modMode & SDL_RenderCopyFuncTable[i].modMode) != modMode) { | |
471 continue; | |
472 } | |
473 if ((blendMode & SDL_RenderCopyFuncTable[i].blendMode) != blendMode) { | |
474 continue; | |
475 } | |
476 if ((scaleMode & SDL_RenderCopyFuncTable[i].scaleMode) != scaleMode) { | |
477 continue; | |
478 } | |
479 return SDL_RenderCopyFuncTable[i].func; | |
480 } | |
481 return NULL; | |
482 } | |
483 | |
484 __EOF__ | |
485 } | |
486 | |
487 sub output_copyfunc_c | |
488 { | |
489 my $src = shift; | |
490 my $dst = shift; | |
491 | |
492 for (my $modulate = 0; $modulate <= 1; ++$modulate) { | |
493 for (my $blend = 0; $blend <= 1; ++$blend) { | |
494 for (my $scale = 0; $scale <= 1; ++$scale) { | |
495 if ( $modulate != 0 || $blend != 0 || $scale != 0 || $src ne $dst ) { | |
496 output_copyfunc($src, $dst, $modulate, $blend, $scale); | |
497 } | |
498 } | |
499 } | |
500 } | |
501 } | |
502 | |
503 open_file("SDL_rendercopy.h"); | |
504 output_copydefs(); | |
505 for (my $i = 0; $i <= $#src_formats; ++$i) { | |
506 for (my $j = 0; $j <= $#dst_formats; ++$j) { | |
507 output_copyfunc_h($src_formats[$i], $dst_formats[$j]); | |
508 } | |
509 } | |
510 print FILE "\n"; | |
511 close_file("SDL_rendercopy.h"); | |
512 | |
513 open_file("SDL_rendercopy.c"); | |
514 output_copyinc(); | |
515 output_copyfunctable(); | |
516 for (my $i = 0; $i <= $#src_formats; ++$i) { | |
517 for (my $j = 0; $j <= $#dst_formats; ++$j) { | |
518 output_copyfunc_c($src_formats[$i], $dst_formats[$j]); | |
519 } | |
520 } | |
521 close_file("SDL_rendercopy.c"); |