#!/usr/bin/perl -w

use strict;

my $Outfile;

# Process command line arguments
if ( $ARGV[0] =~ /^-o/i ) {
   if ( $ARGV[0] =~ /^-o$/i ) {
      $Outfile = $ARGV[1];
   } else {
      $ARGV[0] =~ /(?<=-o)(.*)/i;
      $Outfile = $1;
   }
}

unless ( $Outfile ) {
   die "Usage: $0 -o <output file>\n\n";
}

open( OUTFILE, ">$Outfile" ) or die "\nError: Couldn't open OUTPUT file $Outfile: $!";

print "Generating $Outfile...\n";

# Generate optimized functions
for ( my $Rot = 0; $Rot <= 270; $Rot += 270) {
   print OUTFILE "#define ROT $Rot\n\n";
   for ( my $Bitdepth = 16; $Bitdepth <= 32; $Bitdepth += 8 ) {
      print OUTFILE "// " . $Bitdepth . "-bit rendering functions.\n";
      print OUTFILE "#define BPP $Bitdepth\n\n";
      for ( my $Function = 0; $Function < 8; $Function++ ) {
         if ( ($Function & 3) == 0) {
            print OUTFILE "#define ISOPAQUE " . ($Function & 4) / 4 . "\n";
         }
         print OUTFILE "#define XFLIP " . ($Function & 1) . "\n";
         print OUTFILE "#define YFLIP " . ($Function & 2) / 2 . "\n";
         print OUTFILE "#define DOCLIP 0\n";
         print OUTFILE "#include \"toa_gp9001_render.h\"\n";
         print OUTFILE "#undef DOCLIP\n";
         print OUTFILE "#define DOCLIP 1\n";
         print OUTFILE "#include \"toa_gp9001_render.h\"\n";
         print OUTFILE "#undef DOCLIP\n";
         print OUTFILE "#undef YFLIP\n";
         print OUTFILE "#undef XFLIP\n\n";
         if ( ($Function & 3) == 3) {
            print OUTFILE "#undef ISOPAQUE\n\n";
         }
      }
      print OUTFILE "#undef BPP\n\n";
   }
   print OUTFILE "#undef ROT\n\n";
}

# Create table with functions addresses
print OUTFILE "// Table with all function addresses.\n";
print OUTFILE "static RenderTileFunction RenderTileFunctionTable[] = {\n";
for ( my $Rot = 0; $Rot <= 270; $Rot += 270) {
   for ( my $Bitdepth = 16; $Bitdepth <= 32; $Bitdepth += 8 ) {
      my $FunctionName = "&RenderTile" . $Bitdepth . "_ROT" . "$Rot";
      for ( my $Function = 0; $Function < 16; $Function++ ) {
         if ( ($Function & 3) == 0) {
            print OUTFILE "\t";
         }
         print OUTFILE "$FunctionName";
         if ( ($Function & 3) == 0 ) {
            print OUTFILE "_NOFLIP"
         } else {
            if ( ($Function & 3) == 1 ) {
               print OUTFILE "_FLIPX"
            } else {
               if ( ($Function & 3) == 2 ) {
                  print OUTFILE "_FLIPY"
               } else {
                  print OUTFILE "_FLIPXY"
               }
            }
         }
         if ( ($Function & 4) == 0 ) {
            print OUTFILE "_NOCLIP"
         } else {
            print OUTFILE "_CLIP"
         }
         if ( ($Function & 8) == 0 ) {
            print OUTFILE "_TRANS"
         } else {
            print OUTFILE "_OPAQUE"
         }
         print OUTFILE ", ";
         if ( ($Function & 3) == 3) {
            print OUTFILE "\n";
         }
      }
   }
}
print OUTFILE "};\n\n";

print OUTFILE "static RenderTileFunction* RenderTile_ROT0[3] = {\n\t&RenderTileFunctionTable[0],\n\t&RenderTileFunctionTable[16],\n\t&RenderTileFunctionTable[32]\n};\n";
print OUTFILE "static RenderTileFunction* RenderTile_ROT270[3] = {\n\t&RenderTileFunctionTable[48],\n\t&RenderTileFunctionTable[64],\n\t&RenderTileFunctionTable[80]\n};\n";

close( OUTFILE );

