#!/usr/bin/perl
#
# hugo2pdb: convert a Hugo HEX game file to a PDB format file
# suitable for installing on a Palm device for use with 
# Palm Hugo.
#
# Based on z2pdb.pl:
# Perl code by: Jonathan Ferro <jonrock@yahoo.com>
# Based on C code by: Alien Hunter <alien_hunter@hotmail.com>

$USAGE = <<__USAGE__;
Usage: hugo2pdb <HEX_file> [<pdb_file> <game_title> <blocksize>]
If no game title is specified, the name of the HEX file, with any
suffix removed, will be used instead.  In either case, the game title
will be truncated to 31 characters.  An optional blocksize (in kB)
may be specified.
__USAGE__

while (@ARGV && $ARGV[0] =~ /^-/) {
    $ARGV[0] eq '--' && do { shift; last; } ;
    $ARGV[0] eq '-h' && die $USAGE;
    die "unknown flag: $ARGV[0]\n" . $USAGE;
}

if (@ARGV < 1 || @ARGV > 4) {
    die $USAGE;
}

($hexfile, $pdbfile, $title, $reclen) = @ARGV;
if (! defined $reclen) {
    $reclen = 4096; # Use 4K chunk default
}
else {
    $reclen = $reclen * 1024;
}

if (! defined $pdbfile) {
    $pdbfile = $hexfile;
    $pdbfile .= ".pdb";
}

## Construct a title if none was given.
if (! defined $title) {
    $title = $hexfile;
    $title =~ s!^.*/!! ; # Remove leading directories (maximal match).
    $title =~ s/\.[^.]*//; # Strip off suffix, if any.
}

## Open appropriate files and check for errors.
open $hexfile, "$hexfile" 
    or die "Can't open $hexfile: $!\n";
binmode $hexfile;
open $pdbfile, ">$pdbfile"
    or die "Can't write to $pdbfile: $!\n";
binmode $pdbfile;

## Slurp in HEX file, counting the number of resulting records.
$records = 0;
while (read $hexfile, $buf, $reclen) {
    $hugodata .= $buf;
    $records++;
}

## Construct and write database header.
$pdbheader = pack "a31xn2N6a4a4N2n",
    $title, # Name of database
    0, # Database attributes
    32, # Version number--although we're using it for chunk size, in K
    0x34ac829f, # Creation date
    0x34ac829f, # Modification date
    0, # Last backup date
    0, # Modification number
    0, # App info area (nonexistent)
    0, # Sort info area (nonexistent)
    "Hugo", # Database type
    "HUGO", # Database creator ID
    0, # Unique ID seed
    0, # Next record list ID (unused?)
    $records # Number of records
    ;
print $pdbfile $pdbheader;

## Calculate offset of first record, using dummy record header for size.
$recheader = pack "NCx3";
$offset = length($pdbheader) + $records * length($recheader);

## Construct and write record headers.
for $rec (0 .. ($records - 1)) {
    $recheader = pack "NCx3",
        $rec * $reclen + $offset, # Record data offset
# Why was this setting BUSY|DIRTY?
#        0x60 # Record attributes (BUSY|DIRTY)
        0x00
;
    print $pdbfile $recheader;
}

## Finally, write the records themselves.
print $pdbfile $hugodata;
