+sub unpackhash {
+ my ($template, $expr, @elements) = @_;
+ my @data = unpack $template, $expr;
+ my %map;
+ $map{$_} = shift @data for @elements;
+ return (\%map, @data);
+}
+
+local $_ = Data::StarCraft::Replay::_read(undef, \*STDIN, 633)
+ and my ($head, @headdata) = unpackhash("CVa3Va12Z28v2Z16Z24Ca26a38a*", $_, qw(
+ engine frames mag1 time mag2 name width height
+ unknown1 creator unknown2 map unknown3
+ ))
+ or die "Couldn't read replay header\n";
+
+$_ eq "\0\0\110" or warn sprintf(
+ "Mismatch in first header constant: %s\n",
+ join ",", map ord, split //, $_
+) for $head->{mag1};
+$_ eq "\10"x8 . "\0"x4 or warn sprintf(
+ "Mismatch in second header constant: %s\n",
+ join ",", map ord, split //, $_
+) for $head->{mag2};
+delete $head->{$_} for qw(mag1 mag2 unknown1 unknown2);
+
+my @playdata = unpack "a36"x12 . "V8C8", $headdata[0]
+ or die "Couldn't parse player data in replay header\n";
+
+my @player;
+push @player, unpackhash("x11Z25", shift @playdata, qw/name/) for 0 .. 11;
+$player[$_]->{color} = shift @playdata for 0 .. 7;
+$player[$_]->{index} = shift @playdata for 0 .. 7;
+
+printf "%s: %s\n", $_, $head->{$_} for qw(name creator);
+use Date::Format;
+printf "created: %s\n", time2str('%Y-%m-%d %X', $_) for $head->{time};
+printf "map: %s (%dx%d)\n", map $head->{$_}, qw(map width height);
+printf "frames: %s (%s)\n", $_, showtime($_) for $head->{frames};
+print "\n";
+
+if ($SHOWWARN) {
+ print Dumper $head;
+ print Dumper \@player;
+ #printf ":%s\n", join ",", map sprintf('%X', ord $_), split // for @headdata;
+ print "\n";
+}
+