This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
sdlgenblit.pl
executable file
·475 lines (435 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/perl -w
#
# A script to generate optimized C blitters for Simple DirectMedia Layer
# http://www.libsdl.org/
use warnings;
use strict;
my %file;
# The formats potentially supported by this script:
# SDL_PIXELFORMAT_RGB332
# SDL_PIXELFORMAT_RGB444
# SDL_PIXELFORMAT_RGB555
# SDL_PIXELFORMAT_ARGB4444
# SDL_PIXELFORMAT_ARGB1555
# SDL_PIXELFORMAT_RGB565
# SDL_PIXELFORMAT_RGB24
# SDL_PIXELFORMAT_BGR24
# SDL_PIXELFORMAT_RGB888
# SDL_PIXELFORMAT_BGR888
# SDL_PIXELFORMAT_ARGB8888
# SDL_PIXELFORMAT_RGBA8888
# SDL_PIXELFORMAT_ABGR8888
# SDL_PIXELFORMAT_BGRA8888
# SDL_PIXELFORMAT_ARGB2101010
# The formats we're actually creating blitters for:
my @src_formats = (
"RGB888",
"BGR888",
"ARGB8888",
"RGBA8888",
"ABGR8888",
"BGRA8888",
);
my @dst_formats = (
"RGB888",
"BGR888",
40
"ARGB8888",
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
);
my %format_size = (
"RGB888" => 4,
"BGR888" => 4,
"ARGB8888" => 4,
"RGBA8888" => 4,
"ABGR8888" => 4,
"BGRA8888" => 4,
);
my %format_type = (
"RGB888" => "Uint32",
"BGR888" => "Uint32",
"ARGB8888" => "Uint32",
"RGBA8888" => "Uint32",
"ABGR8888" => "Uint32",
"BGRA8888" => "Uint32",
);
my %get_rgba_string = (
"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;", "ARGB8888" => "_A = (Uint8)(_pixel >> 24); _R = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _B = (Uint8)_pixel;",
64
65
66
67
68
69
70
71
"RGBA8888" => "_R = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _B = (Uint8)(_pixel >> 8); _A = (Uint8)_pixel;",
"ABGR8888" => "_A = (Uint8)(_pixel >> 24); _B = (Uint8)(_pixel >> 16); _G = (Uint8)(_pixel >> 8); _R = (Uint8)_pixel;",
"BGRA8888" => "_B = (Uint8)(_pixel >> 24); _G = (Uint8)(_pixel >> 16); _R = (Uint8)(_pixel >> 8); _A = (Uint8)_pixel;",
);
my %set_rgba_string = (
"RGB888" => "_pixel = ((Uint32)_R << 16) | ((Uint32)_G << 8) | _B;",
"BGR888" => "_pixel = ((Uint32)_B << 16) | ((Uint32)_G << 8) | _R;",
72
73
74
75
"ARGB8888" => "_pixel = ((Uint32)_A << 24) | ((Uint32)_R << 16) | ((Uint32)_G << 8) | _B;",
"RGBA8888" => "_pixel = ((Uint32)_R << 24) | ((Uint32)_G << 16) | ((Uint32)_B << 8) | _A;",
"ABGR8888" => "_pixel = ((Uint32)_A << 24) | ((Uint32)_B << 16) | ((Uint32)_G << 8) | _R;",
"BGRA8888" => "_pixel = ((Uint32)_B << 24) | ((Uint32)_G << 16) | ((Uint32)_R << 8) | _A;",
76
77
78
79
80
81
82
83
);
sub open_file {
my $name = shift;
open(FILE, ">$name.new") || die "Cant' open $name.new: $!";
print FILE <<__EOF__;
/* DO NOT EDIT! This file is generated by sdlgenblit.pl */
/*
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
*/
#include "SDL_config.h"
/* *INDENT-OFF* */
__EOF__
}
sub close_file {
my $name = shift;
print FILE <<__EOF__;
/* *INDENT-ON* */
/* vi: set ts=4 sw=4 expandtab: */
__EOF__
close FILE;
if ( ! -f $name || system("cmp -s $name $name.new") != 0 ) {
rename("$name.new", "$name");
} else {
unlink("$name.new");
}
}
sub output_copydefs
{
print FILE <<__EOF__;
128
extern SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[];
129
130
131
132
133
134
135
136
137
138
139
140
141
142
__EOF__
}
sub output_copyfuncname
{
my $prefix = shift;
my $src = shift;
my $dst = shift;
my $modulate = shift;
my $blend = shift;
my $scale = shift;
my $args = shift;
my $suffix = shift;
143
print FILE "$prefix SDL_Blit_${src}_${dst}";
144
145
146
147
148
149
150
151
152
153
if ( $modulate ) {
print FILE "_Modulate";
}
if ( $blend ) {
print FILE "_Blend";
}
if ( $scale ) {
print FILE "_Scale";
}
if ( $args ) {
154
print FILE "(SDL_BlitInfo *info)";
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
}
print FILE "$suffix";
}
sub get_rgba
{
my $prefix = shift;
my $format = shift;
my $string = $get_rgba_string{$format};
$string =~ s/_/$prefix/g;
if ( $prefix ne "" ) {
print FILE <<__EOF__;
${prefix}pixel = *$prefix;
__EOF__
} else {
print FILE <<__EOF__;
pixel = *src;
__EOF__
}
print FILE <<__EOF__;
$string
__EOF__
}
sub set_rgba
{
my $prefix = shift;
my $format = shift;
my $string = $set_rgba_string{$format};
$string =~ s/_/$prefix/g;
print FILE <<__EOF__;
$string
*dst = ${prefix}pixel;
__EOF__
}
sub output_copycore
{
my $src = shift;
my $dst = shift;
my $modulate = shift;
my $blend = shift;
197
198
199
200
201
my $s = "";
my $d = "";
# Nice and easy...
if ( $src eq $dst && !$modulate && !$blend ) {
202
print FILE <<__EOF__;
203
*dst = *src;
204
__EOF__
205
206
return;
}
207
208
209
210
211
212
213
214
if ( $blend ) {
get_rgba("src", $src);
get_rgba("dst", $dst);
$s = "src";
$d = "dst";
} else {
get_rgba("", $src);
215
}
216
217
if ( $modulate ) {
218
print FILE <<__EOF__;
219
if (flags & SDL_COPY_MODULATE_COLOR) {
220
221
222
223
${s}R = (${s}R * modulateR) / 255;
${s}G = (${s}G * modulateG) / 255;
${s}B = (${s}B * modulateB) / 255;
}
224
if (flags & SDL_COPY_MODULATE_ALPHA) {
225
${s}A = (${s}A * modulateA) / 255;
226
227
228
229
230
}
__EOF__
}
if ( $blend ) {
print FILE <<__EOF__;
231
if (flags & (SDL_COPY_BLEND|SDL_COPY_ADD)) {
232
/* This goes away if we ever use premultiplied alpha */
233
234
235
236
237
if (${s}A < 255) {
${s}R = (${s}R * ${s}A) / 255;
${s}G = (${s}G * ${s}A) / 255;
${s}B = (${s}B * ${s}A) / 255;
}
238
}
239
switch (flags & (SDL_COPY_BLEND|SDL_COPY_ADD|SDL_COPY_MOD)) {
240
case SDL_COPY_BLEND:
241
242
243
${d}R = ${s}R + ((255 - ${s}A) * ${d}R) / 255;
${d}G = ${s}G + ((255 - ${s}A) * ${d}G) / 255;
${d}B = ${s}B + ((255 - ${s}A) * ${d}B) / 255;
244
break;
245
case SDL_COPY_ADD:
246
247
248
${d}R = ${s}R + ${d}R; if (${d}R > 255) ${d}R = 255;
${d}G = ${s}G + ${d}G; if (${d}G > 255) ${d}G = 255;
${d}B = ${s}B + ${d}B; if (${d}B > 255) ${d}B = 255;
249
break;
250
251
252
253
254
case SDL_COPY_MOD:
${d}R = (${s}R * ${d}R) / 255;
${d}G = (${s}G * ${d}G) / 255;
${d}B = (${s}B * ${d}B) / 255;
break;
255
256
257
}
__EOF__
}
258
259
260
261
262
if ( $blend ) {
set_rgba("dst", $dst);
} else {
set_rgba("", $dst);
}
263
264
265
266
267
268
269
270
271
272
}
sub output_copyfunc
{
my $src = shift;
my $dst = shift;
my $modulate = shift;
my $blend = shift;
my $scale = shift;
273
output_copyfuncname("static void", $src, $dst, $modulate, $blend, $scale, 1, "\n");
274
275
print FILE <<__EOF__;
{
276
277
278
__EOF__
if ( $modulate || $blend ) {
print FILE <<__EOF__;
279
const int flags = info->flags;
280
__EOF__
281
}
282
283
if ( $modulate ) {
print FILE <<__EOF__;
284
285
286
287
const Uint32 modulateR = info->r;
const Uint32 modulateG = info->g;
const Uint32 modulateB = info->b;
const Uint32 modulateA = info->a;
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
__EOF__
}
if ( $blend ) {
print FILE <<__EOF__;
Uint32 srcpixel;
Uint32 srcR, srcG, srcB, srcA;
Uint32 dstpixel;
Uint32 dstR, dstG, dstB, dstA;
__EOF__
} elsif ( $modulate || $src ne $dst ) {
print FILE <<__EOF__;
Uint32 pixel;
Uint32 R, G, B, A;
__EOF__
}
if ( $scale ) {
print FILE <<__EOF__;
int srcy, srcx;
int posy, posx;
int incy, incx;
srcy = 0;
posy = 0;
311
312
incy = (info->src_h << 16) / info->dst_h;
incx = (info->src_w << 16) / info->dst_w;
313
314
while (info->dst_h--) {
315
$format_type{$src} *src = 0;
316
317
$format_type{$dst} *dst = ($format_type{$dst} *)info->dst;
int n = info->dst_w;
318
319
320
321
322
323
324
325
326
327
328
329
srcx = -1;
posx = 0x10000L;
while (posy >= 0x10000L) {
++srcy;
posy -= 0x10000L;
}
while (n--) {
if (posx >= 0x10000L) {
while (posx >= 0x10000L) {
++srcx;
posx -= 0x10000L;
}
330
src = ($format_type{$src} *)(info->src + (srcy * info->src_pitch) + (srcx * $format_size{$src}));
331
332
333
334
__EOF__
print FILE <<__EOF__;
}
__EOF__
335
output_copycore($src, $dst, $modulate, $blend);
336
337
338
339
340
print FILE <<__EOF__;
posx += incx;
++dst;
}
posy += incy;
341
info->dst += info->dst_pitch;
342
343
344
345
346
}
__EOF__
} else {
print FILE <<__EOF__;
347
348
349
350
while (info->dst_h--) {
$format_type{$src} *src = ($format_type{$src} *)info->src;
$format_type{$dst} *dst = ($format_type{$dst} *)info->dst;
int n = info->dst_w;
351
352
while (n--) {
__EOF__
353
output_copycore($src, $dst, $modulate, $blend);
354
355
356
357
print FILE <<__EOF__;
++src;
++dst;
}
358
359
info->src += info->src_pitch;
info->dst += info->dst_pitch;
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
}
__EOF__
}
print FILE <<__EOF__;
}
__EOF__
}
sub output_copyfunc_h
{
}
sub output_copyinc
{
print FILE <<__EOF__;
#include "SDL_video.h"
377
378
#include "SDL_blit.h"
#include "SDL_blit_auto.h"
379
380
381
382
383
384
385
__EOF__
}
sub output_copyfunctable
{
print FILE <<__EOF__;
386
SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[] = {
387
388
389
390
391
392
393
394
__EOF__
for (my $i = 0; $i <= $#src_formats; ++$i) {
my $src = $src_formats[$i];
for (my $j = 0; $j <= $#dst_formats; ++$j) {
my $dst = $dst_formats[$j];
for (my $modulate = 0; $modulate <= 1; ++$modulate) {
for (my $blend = 0; $blend <= 1; ++$blend) {
for (my $scale = 0; $scale <= 1; ++$scale) {
395
if ( $modulate || $blend || $scale ) {
396
print FILE " { SDL_PIXELFORMAT_$src, SDL_PIXELFORMAT_$dst, ";
397
398
my $flags = "";
my $flag = "";
399
if ( $modulate ) {
400
401
402
403
404
405
$flag = "SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA";
if ( $flags eq "" ) {
$flags = $flag;
} else {
$flags = "$flags | $flag";
}
406
407
}
if ( $blend ) {
408
$flag = "SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD";
409
410
411
412
413
if ( $flags eq "" ) {
$flags = $flag;
} else {
$flags = "$flags | $flag";
}
414
415
}
if ( $scale ) {
416
417
418
419
420
421
422
423
424
$flag = "SDL_COPY_NEAREST";
if ( $flags eq "" ) {
$flags = $flag;
} else {
$flags = "$flags | $flag";
}
}
if ( $flags eq "" ) {
$flags = "0";
425
}
426
print FILE "($flags), SDL_CPU_ANY,";
427
428
429
430
431
432
433
434
output_copyfuncname("", $src_formats[$i], $dst_formats[$j], $modulate, $blend, $scale, 0, " },\n");
}
}
}
}
}
}
print FILE <<__EOF__;
435
{ 0, 0, 0, 0, NULL }
436
437
438
439
440
441
442
443
444
445
446
447
448
};
__EOF__
}
sub output_copyfunc_c
{
my $src = shift;
my $dst = shift;
for (my $modulate = 0; $modulate <= 1; ++$modulate) {
for (my $blend = 0; $blend <= 1; ++$blend) {
for (my $scale = 0; $scale <= 1; ++$scale) {
449
if ( $modulate || $blend || $scale ) {
450
451
452
453
454
455
456
output_copyfunc($src, $dst, $modulate, $blend, $scale);
}
}
}
}
}
457
open_file("SDL_blit_auto.h");
458
459
460
461
462
463
464
output_copydefs();
for (my $i = 0; $i <= $#src_formats; ++$i) {
for (my $j = 0; $j <= $#dst_formats; ++$j) {
output_copyfunc_h($src_formats[$i], $dst_formats[$j]);
}
}
print FILE "\n";
465
close_file("SDL_blit_auto.h");
466
467
open_file("SDL_blit_auto.c");
468
469
470
471
472
473
output_copyinc();
for (my $i = 0; $i <= $#src_formats; ++$i) {
for (my $j = 0; $j <= $#dst_formats; ++$j) {
output_copyfunc_c($src_formats[$i], $dst_formats[$j]);
}
}
474
output_copyfunctable();
475
close_file("SDL_blit_auto.c");