#!/usr/bin/env perl use strict; use warnings; use 5.010; use lib 'lib'; # make runnable for simple cases use Data::Dumper; use Getopt::Long 2.33 qw(HelpMessage :config bundling); use Games::Wormy::TICalcLevels; use Games::Wormy::WormEdit; our $VERSION = '1.05'; GetOptions(\my %opt, 'raw|r', # full output 'version=i', # force version ) or HelpMessage(-exitval => 2); my @OBJTYPE = ('none', 'line', 'fat line', 'bar', 'circle'); my @ENDTYPE = ('none', 'message', 'small message'); sub objsummary { my ($objects) = @_; my @objtypes = map { $_->{type} } @$objects; my %count; $count{$_}++ for @objtypes; return (@objtypes > 1 && keys %count == 1 && 'all ') . join(', ', map { $OBJTYPE[$_] ? $OBJTYPE[$_] . ($count{$_} > 1 && 's') : $_ } sort keys %count ); } # read and parse all input data my $data; local $/; my $rawdata = readline; if (substr($rawdata, 0, 11) eq "**TI86**\032\012\000") { # compiled calculator file $data = Games::Wormy::TICalcLevels->read($rawdata, $opt{version}); } elsif (substr($rawdata, 0, 8) eq 'WormEdit') { # original wormedit source $data = Games::Wormy::WormEdit->read($rawdata, $opt{version}); } else { die "Unrecognised file type\n"; } # output with user-preferred formatting if ($opt{raw}) { # full data in yaml (human-readable) formatting require YAML; local $YAML::CompressSeries; $YAML::CompressSeries = 0; my $yml = "# Wormy levelset\n" . YAML::Dump($data); # inline format of short hashes $yml =~ s{ ^(\ *) - \n # array indicator ((?:\1\ \ [a-z0-9]{1,5}:\ *\d+\n)+) # simple hash declaration (?!\1\ ) # no further children }[ my ($indent, $value) = ($1, $2); chop $value; $value =~ s/^ +//gm; $value =~ s/\n/, /g; "$indent- {$value}\n"; ]egmx; print $yml; } else { print $data->{name}; print " ($data->{description})" if defined $data->{description}; print "\n"; printf "File version: %s\n", "$data->{format} v$data->{version}"; printf "Defaults: %s\n", join('; ', $data->{sprite} ? 'sprite ' . scalar @{ $data->{sprite} } : (), defined $data->{hiname} ? 'hiscore by ' . $data->{hiname} : (), ); my $startnr = 0; for my $variant (qw/single peaworm multi race ctf/) { my $count = $data->{levelcount}->{$variant}; defined $count or next; print "\n"; printf '%s (%s)', ucfirst $variant, $count; $count or next; print ":"; for (0 .. $count - 1) { my $level = $data->{levels}->[$_ + $startnr]; printf("\n- %-22s%4s:%3s+%2s%3s %3sx%-3s%s", $level->{id} || $level->{name} || '#'.($_+1), @$level{qw/size bsize growth/}, $variant eq 'single' && "x$level->{peas}", @$level{qw/width height/}, join(';', map {" $_"} grep {$_} @{$level->{objects}} && sprintf('%2d object%s (%s)', scalar @{$level->{objects}}, @{$level->{objects}} != 1 && 's', objsummary($level->{objects}), ), $level->{sprite} && @{$level->{sprite}} && sprintf('sprite %d', scalar @{$level->{sprite}}, ), $level->{balls} && @{$level->{balls}} && sprintf('%d bounc%s', scalar @{$level->{balls}}, @{$level->{balls}} == 1 ? 'y' : 'ies', ), ), ); } $startnr += $count; print "\n"; printf("-- %-21s%4s: %s (%s)\n", '(ending)', defined $data->{finish}->{code} ? length $data->{finish}->{code} : '?', defined $data->{finish}->{type} ? $ENDTYPE[$data->{finish}->{type}] || 'unknown' : 'code', $data->{finish}->{message} // '?', ) if $variant eq 'single'; } print "\n"; } __END__ =head1 NAME parse-wormedit - Wormy level data parser =head1 SYNOPSIS parse-wormedit [--raw] =head1 DESCRIPTION Reads Wormy levels (either original WormEdit source or compiled TI-86 string) from STDIN or given file, and outputs contents, summarised or in full. =head1 AUTHOR Mischa POSLAWSKY =head1 LICENSE GPL version 3.