1 package Games::Wormy::WormEdit;
7 use Parse::Binary::Nested qw(unpackf);
12 "WormEdit053\000LVL" => 53,
13 "WormEdit\34195\000LVL" => 95,
14 "WormEdit\34194\000LVL" => 94,
15 "WormEdit\34193\000LVL" => 93,
19 my ($self, $input, $override) = @_;
20 my ($id, $version) = (substr($input, 0, 15), ord substr($input, 15, 1));
21 my $fileversion = $MAGICID{$id}
22 or die "File does not match any known WormEdit level header\n";
25 warn "Override version $version to $override\n";
28 elsif ($version != $fileversion) {
29 warn "Unexpected version $version (expecting $fileversion)\n";
31 elsif ($version == 95) {
32 # auto-detect exact variant
33 if (ord substr($input, 70, 1) ~~ [1 .. 8]) {
34 # valid sprite length instead of description byte
35 # (which is usually a letter or nul)
38 elsif (ord substr($input, 147, 1) == 0) {
39 # nul of finish type is 2 bytes later (unlike first char of message)
42 warn "Ambiguous file version 95; guessing subversion $version\n";
45 $fileversion += 100 if $fileversion < 90; # 93..95 came before 50..53
51 description => 'C/a64x256',
60 map { (start => $_, end => $_) } [1,
83 levels => ['*', # levelcount->total actually
120 given ($fileversion) {
121 when (153) { } # current @FORMAT
122 $FORMAT[7] = 'C/a64'; # no reserved space after description
123 splice @{ $FORMAT[15] }, -2; # finish reserve
124 $FORMAT[-1]->[-1]->[0] = '32C'; # less objects
125 ref $_ and pop @$_ for @{ $FORMAT[11] }; # 9 moderefs
126 when ($version == 96) { }
127 ref $_ and pop @$_ for @{ $FORMAT[11] }; # only 8 moderefs (no ctf)
128 splice @FORMAT, 6, 2 if $version <= 94; # earlier version without description
130 splice @{ $FORMAT[7] }, 4, 2; # no race
131 splice @{ $FORMAT[13] }, 4, 2; # no enddata
132 splice @{ $FORMAT[-1] }, 1, 2; # no name
134 splice @FORMAT, 14, 2; # no hiname
135 $FORMAT[-1]->[0] = 64; # constant amount of levels
138 die "Cannot parse data for Wormedit $fileversion/$version\n";
142 # convert to an easily accessible hash
143 push @FORMAT, -trail => 'a*';
144 my $data = unpackf(\@FORMAT, $input);
145 warn "Trailing data left unparsed\n" if length delete $data->{-trail};
146 $data->{format} = 'WormEdit';
156 Games::Wormy::WormEdit - Read Wormy levelset from a wormedit file
160 my $levelset = Games::Wormy::WormEdit->read($filecontents);
161 print $levelset->{name};
165 Mischa POSLAWSKY <perl@shiar.org>