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