#!/usr/bin/perl -wT ###################################################################### # Artemis SNT file decoder, (C) 2015-2019 Nosey Nick Waterman, # https://noseynick.org/artemis/ # All wrong righted, all rights reserved. Licensed under thev GNU # Affero General Public License v3.0 https://www.gnu.org/licenses/agpl.txt # with Commons Clause https://commonsclause.com/ v1.0 ###################################################################### # # 1 1 1 M 1 1 B # A 1 1 1 S 1 F # D 1 A 1 1 1 1 1 1 F # A 1 1 1 S 1 F # 1 1 1 M 1 1 B # ###################################################################### # +++ consider Perl::Critic # +++ podchecker use 5.008; use strict; use warnings; # use diagnostics; our $VERSION = '2.01'; ###################################################################### =head1 NAME snt-dec.pl - decode Artemis *.snt files into deck plans =head1 SYNOPSIS snt-dec.pl [ --help | --man | --version ] snt-dec.pl [ -h | --html ] file.snt ... =head1 DESCRIPTION B will read *.snt files from Artemis Spaceship Bridge Simulator, and convert them into deck plans. =cut ###################################################################### # Stuff for handling command-line args ###################################################################### my (%opt, @opt); =head1 OPTIONS =over =item B<--help> Print brief help and exits. =item B<--man> Prints the manual page and exits. =item B<--version> Print some version information opt('help|?' => sub { pod2usage(-verbose => 1); }); opt('man' => sub { pod2usage(-verbose => 2); }); opt('version' => sub { die "This is $0 version $VERSION.\n"; }); =item B<-h> I, B<--html> I Output in HTML (based on I) instead of text =cut opt('html|h=s' => undef); ###################################################################### use Getopt::Long qw(:config gnu_getopt); use Pod::Usage; sub opt { my ($name, $def) = @_; push @opt, lc($name); if (defined ($def) && $name =~ /^(\w+|<>)/) { $opt{lc $1} = $def } } ###################################################################### # OK, let's rock! ###################################################################### GetOptions(\%opt, @opt) or pod2usage(); # print usage if opt error pod2usage("$0: No files given.") if ((@ARGV == 0) && (-t STDIN)); my %str = ( $opt{html} ? ( # Strings for --html mode: title => 'Artemis Ships - Deck Plans', h1 => 'Artemis Ships - Deck Plans', description => 'Artemis Ships - Deck Plans', style => "#plan { background: #000 url(back.jpg); border-collapse: collapse; \n" . " box-shadow: 5px 5px 5px 1px #ccc; }\n" . " #plan th { color: #fff; }\n" . " #plan td { width: 1em; height: 1em; }\n" . " #plan * { border: 0px; padding: 5px; }\n" . " .hall { background: #ccc; }\n" . " .beam { background: #ff0; }\n" . " .torp { background: #888; }\n" . " .sensors { background: #00c; }\n" . " .maneuvering{ background: #0c0; }\n" . " .impulse { background: #088; }\n" . " .drive { background: #4ff; }\n" . " .fore { background: #f00; }\n" . " .aft { background: #900; }\n" . " .port { color: #c00; }\n" . " .starboard { color: #090; }\n", top => "

This program reads " . "*.SNT files\n" . "from Artemis Spaceship Bridge Simulator and converts them into neat deck plans.

\n" . "

For more info, see the rest of my Artemis tools

\n\n" . "\n" . '' . '' . '' . '' . '' . '' . '' . '' . '' . "\n
Key:hallbeamtorpsensorsmaneuveringimpulsewarp / jump drivefore shieldsaft shields
\n\n" . "\n", bot => "
\n

\n" . "\n\n", port => 'Port', starboard => 'Starboard', line => '' . '', decks => ''.join('', map { "Deck $_" } 1..5) . '', lhs => '', sep => '', rhs => '', eol => '', -2 => ' ', # empty -1 => ' ', 0 => ' ', 1 => ' ', 2 => ' ', 3 => ' ', 4 => ' ', 5 => ' ', 6 => ' ', # fore shields 7 => ' ', # aft shields EOF => '', # (ab)used at EOF ) : ( # strings for default text mode: port => ' Port', starboard => ' Starboard', line => "+-----------------------"x6, decks => join('', '| ', map { " Deck $_ | " } 1..5), lhs => '| ', # left-hand side sep => ' | ', # separator between decks rhs => ' |', # right-hand-side eol => '', -2 => ' ', # empty -1 => ' #', # hallway 0 => ' B', # beam 1 => ' T', # torp 2 => ' S', # sensors 3 => ' M', # maneuvering 4 => ' I', # impulse 5 => ' D', # warp / jump drive 6 => ' F', # fore shields 7 => ' A', # aft shields EOF => '', # (ab)used at EOF ), ); if ($opt{html}) { open(HTML, $opt{html}) or die "Can't read $opt{html} : $!\n"; while () { if (/^\s*<(title|h1)>/ or /^\s*)) { print $str{style} // ''; } elsif (/\+\+\+/) { die "Don't know how to replace $_\n"; } print $_; } $opt{html} = join('', ); close HTML; } print $str{top} // '', "$str{line}\n$str{decks}$str{eol}\n$str{line}\n"; for my $fi (@ARGV) { snt($fi); } print "$str{decks}$str{eol}\n$str{line}\n", $str{bot}//'', $opt{html} // ''; sub snt { my $fi = shift; open (IN, $fi) or die "Can't open $fi: $!\n"; $fi =~ s|.*/||; # strip path $fi =~ s|\.snt$||i; # ... and suffix my %pre = ( 0 => $str{lhs}, 50 => "$str{rhs}$str{port}$str{eol}\n$str{lhs}", 100 => "$str{rhs}$str{eol}\n$str{lhs}", 150 => "$str{rhs} $fi$str{eol}\n$str{lhs}", 200 => "$str{rhs}$str{eol}\n$str{lhs}", 250 => "$str{rhs}$str{starboard}$str{eol}\n$str{line}\n", ); for (1 .. 24) { $pre{$_.0} //= $str{sep}; } my $n = 0; my $dat; for my $n ( 0..250 ) { read(IN, $dat, 32); my ( $x, $y, $z, $t, $u1, $u2, $u3, $u4) = unpack('f< f< f< l< l< l< l< l<', $dat); print $pre{$n++} // '', $str{$t//'EOF'} // $t; } close IN; } ###################################################################### 1; # In case we are use()d or require()d =back =head1 RETURN VALUE returns 0 on success, 1 for warnings, 2 for errors =head1 ERRORS Most errors are due to missing HTML template files, invalid HTML template, or broken SNT files. =head1 EXAMPLES ./snt-dec.pl Artemis/dat/*.snt =head1 FILES The B<--html> I option requires a template, which may have: +++

+++

+++CONTENT+++ ... each of which will be have the "+++" replaced by the content you'd expect :-) =head1 BUGS All wrongs righted, all rights reserved! =head1 SEE ALSO L L =head1 AUTHOR "Nosey" Nick Waterman of Nilex Eperl@noseynick.orgE L =head1 COPYRIGHT (C) Copyright 2018 Nilex - All wrongs righted, all rights reserved. =cut