gen_desc.pl 4.29 KB
#!/usr/bin/perl -w

die "Usage: gen_desc.pl <thumbnail RGBA16 image in SGI format> <title IA16 image in SGI format> <title file(GB code)> <metadata> <isbn file> <crid file> <oadid file> <output desc file>\n" unless $#ARGV==7;

%meta = (
    "eeprom" => 0,
    "flash" => 0,
    "sram" => 0,
    "cpak" => 0,
    "romBase" => 0xb0000000,
    "tvType" => 1,
    "memSize" => 0x00400000,
    "errataAddress" => 0,
    "errataSize" => 0,
    "address" => 0x807c0000,
    "auxCount" => 0,
);


for (split /,/, $ARGV[3]) {
    ($key, $value) = split /=/;
    $meta{$key} = $value =~ /^0/ ? oct($value):$value if defined $value;
}

$root = $ENV{ROOT};
`$root/usr/sbin/rgb2c -F -f RGBA -s 16 -m texThumb $ARGV[0] > thumb.h`;
`$root/usr/sbin/rgb2c -F -f IA -s 16 -m texTitle $ARGV[1] > title.h`;

sub write_short {
    my $f = shift;
    my $val = shift;
    printf $f "%c", (hex($val)&0xFF00) >> 8;
    printf $f "%c", (hex($val)&0x00FF);
}

sub write_long {
    my $f = shift;
    my $val = shift;
    printf $f (pack "N", $val);
}

sub block_round {
    my $val = int(shift);
    return (($val + 16383) & ~(16383));
}

sub write_bin {
    my $ifn = shift;
    my $ofn = shift;
    open(OUT_DATA,">$ofn");
    binmode(OUT_DATA);
    open(IN_FILE, "<$ifn");
    while (<IN_FILE>) {
        if (/^\s+0x/) {
            @pixel = split /,\s*/;
            foreach $rgba (@pixel) {
                $rgba =~ s/^\s*//;
                write_short(OUT_DATA, $rgba); 
            }
        }
    }
    close IN_FILE;
    close OUT_DATA;
}

write_bin("thumb.h", "thumb.bin");
`gzip -c -9 -n thumb.bin | dd bs=10 skip=1 of=thumb.gz 2>/dev/null`;
$size = `stat thumb.gz`;
$size =~ /(.*Size: )(\d+)/;
$thumb_size = $2;
$thumb_size_h = sprintf ("%x", $2);

write_bin("title.h", "title.bin");
`gzip -c -9 -n title.bin | dd bs=10 skip=1 of=title.gz 2>/dev/null`;
$size = `stat title.gz`;
$size =~ /(.*Size: )(\d+)/;
$title_size = $2;
$title_size_h = sprintf ("%x", $2);

open(OUT_DESC,">$ARGV[7]");
binmode(OUT_DESC);
$address = $meta{'address'};

# EEPROM
$size = $meta{'eeprom'}*128;
write_long(OUT_DESC, $size ? $address : 0);
write_long(OUT_DESC, $size);
$address += block_round($size);

# Flash
$size = $meta{'flash'}*128;
write_long(OUT_DESC, $size ? $address : 0);
write_long(OUT_DESC, $size);
$address += $size;

# SRAM
$size = $meta{'sram'}*128;
write_long(OUT_DESC, $size ? $address : 0);
write_long(OUT_DESC, $size);
$address += $size;

# Cont Pak
$size = $meta{'cpak'} ? 32768 : 0;
for ($i = 0; $i < $meta{'cpak'}; ++$i) {
    write_long(OUT_DESC, $address);
    $address += $size;
}
for (; $i < 4; ++$i) {
    write_long(OUT_DESC, 0);
}
write_long(OUT_DESC, $size);

# Launch parameters
write_long(OUT_DESC, $meta{'romBase'});
write_long(OUT_DESC, $meta{'tvType'});
write_long(OUT_DESC, $meta{'memSize'});
write_long(OUT_DESC, $meta{'errataSize'});
write_long(OUT_DESC, $meta{'errataAddress'});
write_long(OUT_DESC, (0x43414d00 | $meta{'auxCount'}));
write_short(OUT_DESC, $thumb_size_h);
write_short(OUT_DESC, $title_size_h);
close OUT_DESC;

###write out thumb.gz 
`dd bs=1 seek=72 if=thumb.gz of=$ARGV[7] 2>/dev/null`;

###write out title.gz   
$seek_size = 72+$thumb_size;
`dd bs=1 seek=$seek_size if=title.gz of=$ARGV[7] 2>/dev/null`;

###write out title  
$seek_size = 72+$thumb_size+$title_size;
`dd bs=1 seek=$seek_size if=$ARGV[2] of=$ARGV[7] 2>/dev/null`;
###write out terminating byte for title string 
open(OUT_DESC,">>$ARGV[7]");
binmode(OUT_DESC);
printf OUT_DESC "\0";

###write out ISBN number with terminating byte
open(ISBN, "<$ARGV[4]");
while ($line=<ISBN>) {
    $line =~ s/\s$//;
    printf OUT_DESC "%s", $line;
}
printf OUT_DESC "\0";
###write out CRID number with terminating byte
open(CRID, "<$ARGV[5]");
while ($line=<CRID>) {
    $line =~ s/\s$//;
    printf OUT_DESC "%s", $line;
}
printf OUT_DESC "\0";
###write out OADID number with terminating byte
open(OADID, "<$ARGV[6]");
while ($line=<OADID>) {
    $line =~ s/\s$//;
    printf OUT_DESC "%s", $line;
}
printf OUT_DESC "\0";
close OUT_DESC;

$size = `stat $ARGV[7]`;
$size =~ /(.*Size: )(\d+)/;
if (int($2)>10240) {
    printf STDOUT "ERROR: %s size %d greater than 10K\n", $ARGV[7], $2;
} else {
    open(OUT_DESC,">>$ARGV[7]");
    binmode(OUT_DESC);
    for ($i=0; $i<(10240-int($2)); $i++) {
        printf OUT_DESC "%c", 0; 
    }
    close OUT_DESC;
}
`rm thumb.gz thumb.h thumb.bin title.gz title.h title.bin`;