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