--- /dev/null
+#!/usr/bin/perl -w
+
+use strict qw(vars);
+
+#---------- general ----------
+
+sub seteq ($$$) {
+ my ($r,$v,$w)= @_;
+ if (defined $$r) {
+ $$r eq $v or die "$v $$r $w ?";
+ } else {
+ $$r= $v;
+ }
+}
+
+#---------- word-reading (for pbm) ----------
+
+sub w () {
+ our ($lb);
+ $lb='' if !defined $lb;
+ for (;;) {
+ if ($lb =~ s/^\s*(\S+)\s*//) {
+#print STDERR "w>$1<\n";
+ return $1;
+ }
+ $!=0; $lb=<>;
+ die $! unless length $lb;
+ $lb='' if $lb =~ m/^\s*\#/;
+ }
+}
+
+sub wn ($$) {
+ my ($wn);
+ $wn= w();
+ die "$wn ?" unless $wn =~ m/^(?:[1-9]\d*|0)$/;
+ die "$wn $_[0]..$_[1] ?" if $wn < $_[0] || $wn > $_[1];
+ return $wn;
+}
+sub wns ($$$) {
+ my (@wns);
+ while (@wns < $_[2]) { push @wns, wn($_[0],$_[1]); }
+ return @wns;
+}
+
+#---------- xpm data structure ----------
+
+our(%xpm);
+# $xpm{$xpmname}{X}{Min}
+# $xpm{$xpmname}{X}{Max}
+# $xpm{$xpmname}{Y}{Min}
+# $xpm{$xpmname}{Y}{Max}
+# $xpm{$xpmname}{Holey}
+# $xpm{$xpmname}{Pixels}{$x}{$y}
+
+sub xpm_setup ($$$) {
+ my ($xpmname, $partial, $holey)=@_;
+ my ($xp,$xy);
+ die if $xpm{$xpmname};
+ $xp= $xpm{$xpmname}= { Holey => $holey };
+ if (!$partial) {
+ foreach $xy (qw(X Y)) { $xp->{$xy}{Min}= 0; }
+ }
+}
+
+#---------- read segcmap ----------
+
+our (%datum_numbits,%datum_basebit);
+# $datum_numbits{Movfeatpos} etc.
+
+our (@segnum_name,%movfeats,%movfeat_prefix,%movfeat_configbits);
+# $segnum_name[$segnum]= $segname;
+# $movfeats{$segname}[$i]= $xpmname
+# $movfeat_prefix{$xpmname}
+# $movfeat_configbits{$xpmname}
+
+xpm_setup(Background,0);
+
+for (;;) {
+ $!=0; defined($_=<>) or die $!;
+#print STDERR "p>$_<\n";
+ last if m/^E$/;
+ if (m/^B (\w+) (\d+) (\d+)$/) {
+ $datum_numbits{$1}= $2;
+ $datum_basebit{$1}= $3;
+ } elsif (m/^S ([0-9A-Z]+) (0x[0-9a-f]+)$/) {
+ seteq(\$segnum_name[hex $2], $1, "segnum $2");
+ xpm_setup($1,1);
+ } elsif (m/^F ([0-9A-Z]+) (0x[0-9a-f]+) ([A-Z]+) (0x[0-9a-f]+) (\d+)$/) {
+ my ($xpmname);
+ seteq(\$segnum_name[hex $2], $1, "segnum $2 F $3");
+ push @{ $movfeats{$1} }, $3;
+ $xpmname= $1.'_'.$3;
+ $movfeat_prefix{$xpmname}= hex $4;
+ $movfeat_configbits{$xpmname}= $5;
+ xpm_setup($xpmname,1);
+ }
+}
+die if $datum_numbits{Angle} > 7;
+
+#---------- read input image ----------
+
+our(%sz);
+# $sz{X}
+# $sz{Y}
+
+sub xpm_sizes () {
+ my ($xp,$xy);
+ foreach $xp (values %xpm) {
+ foreach $xy (qw(X Y)) {
+#print STDERR "xpms>$xpmname|$xy<\n";
+ if (defined $xp->{$xy}{Min}) {
+ $xp->{$xy}{Max}= $sz{$xy};
+ } else {
+ $xp->{$xy}{Min}= $sz{$xy};
+ $xp->{$xy}{Max}= 0;
+ }
+ }
+ }
+}
+
+w() eq 'P3' or die;
+($sz{X},$sz{Y})=wns(1,32767,2);
+wn(1,65535)==255 or die;
+
+xpm_sizes();
+
+#---------- read input pixels ----------
+
+our(%p,$pp);
+# $p{X}
+# $p{Y}
+
+sub xpm_pixel ($$) {
+ my ($xpmname,$pcharstr)=@_;
+ my ($xp,$pk,$xy);
+ $xp= $xpm{$xpmname};
+ defined $xp or die "$pp $xpmname ?";
+#print STDERR "pk>",join('|',keys(%{$xpm{$xpmname}})),"<\n";
+#print STDERR "pk>",join('|',keys(%{$xpm{$xpmname}{X}})),"<\n";
+ foreach $xy (qw(X Y)) {
+#print STDERR "xpmp>$pp|$xpmname|$xy<\n";
+ $xp->{$xy}{Min}= $p{$xy} if $p{$xy} < $xp->{$xy}{Min};
+ $xp->{$xy}{Max}= $p{$xy} if $p{$xy} > $xp->{$xy}{Max};
+ }
+ die "$pp ?" if defined $xp->{Pixels}{$p{X}}{$p{Y}};
+ $xp->{Pixels}{$p{X}}{$p{Y}}= $pcharstr;
+}
+
+sub in_pixel () {
+ my ($movfeat,%t,$xpmname,$segname,$datum,$k);
+ my ($datum_r,$datum_g,$datum_b);
+ $pp= "$p{X} $p{Y}";
+ ($datum_r,$datum_g,$datum_b)= wns(0,255,3);
+ $datum= $datum_r + ($datum_g<<8) + ($datum_b<<16);
+ foreach $k (keys %datum_numbits) {
+ $t{$k}= ($datum >> $datum_basebit{$k}) &
+ ((1 << $datum_numbits{$k}) - 1);
+ }
+ if ($datum == 0xffffffff or $t{Edge}) {
+ xpm_pixel('Background','-');
+ return;
+ } elsif (!$t{Segnum}) {
+ xpm_pixel('Background','?');
+ return;
+ } else {
+ xpm_pixel('Background','!');
+ }
+ $segname= $segnum_name[$t{Segnum}];
+ defined $segname or die "$pp $t{Segnum}";
+ $pp.= " $segname";
+
+ if (!$t{Movfeatpos}) {
+ $xpmname= $segname;
+ } else {
+ my ($found);
+ $found= undef;
+ foreach $movfeat (@{ $movfeats{$segname} }) {
+ $xpmname= $segname.'_'.$movfeat;
+ if (($t{Movfeatpos} & ~((1<< $movfeat_configbits{$xpmname})-1))
+ == $movfeat_prefix{$xpmname}) {
+ die "$pp $t{Movfeatpos} $found $movfeat"
+ if defined $found;
+ $found= $movfeat;
+ }
+ }
+ die "$pp $t{Movfeatpos}"
+ unless defined $found;
+ fixme need off, on for each pos and detect for each pos
+ }
+ xpm_pixel($xpmname, sprintf("\\x%02x", $t{Angle} + 0x80));
+ fixme actually need off, on and detect;
+}
+
+for ($p{Y}=0; $p{Y}<$sz{Y}; $p{Y}++) {
+ printf STDERR "%d\r",$p{Y};
+ for ($p{X}=0; $p{X}<$sz{X}; $p{X}++) {
+ in_pixel();
+ }
+}
+
+#---------- output ----------
+
+sub xpm_output_all () {
+ my ($xpmname, $xp);
+ foreach $xpmname (keys %xpm) {
+ $xp= $xpm{$xpmname};
+ foreach $xy (qw(X Y)) {
+ $xp->{$xy}{Max}= $xp->{$xy}{Min} if
+ $xp->{$xy}{Max} < $xp->{$xy}{Min};
+ }
+ for ($p{Y}=$xp->{Y}{Min}; $p{Y}<=$xp->{Y}{Max}; $p{Y}++) {
+ print " \"" or die $!;
+ for ($p{X}=$xp->{X}{Min}; $p{X}<=$xp->{X}{Max}; $p{X}++) {
+ $pp= "$xpmname $p{X} $p{Y}";
+ $pixel= $xp->{Pixels}{$p{X}}{$p->{Y}};
+ if (!defined $pixel) {
+ die "$xpmname" if !$p->{Holey};
+ $pixel= ' ';
+ }
+ fixme finish here;
# output:
# lines:
#
+# B <datumpart> <numbits> <bottombit>
+# ((1u << numbits) - 1) << bottombit is the mask for datumpart
+# datumpart may be Segnum Movfeatpos Edge Angle
+# B lines are right at the start
+#
# C <csss> 0x<datum> <angle-bits>
# where <csss> is N/[M] (see informat.txt) and <datum>
# is the hex value of the datum (see segcmap.h)
read_segcmap_h();
+sub pf { printf @_ or die $!; }
+
+pf("B Segnum %d %d\n", $bits{Segnum}, 24-$bits{Movfeatpos}-$bits{Segnum});
+pf("B Movfeatpos %d %d\n", $bits{Movfeatpos}, 24-$bits{Movfeatpos});
+pf("B Edge %d %d\n", 1, $bits{Angle});
+pf("B Angle %d %d\n", $bits{Angle}, 0);
+
sub cssnmap ($$$$) {
my ($seg,$movfeat,$segnum,$posinfo) = @_;
my ($datum);
$datum=
($posinfo << (24 - $bits{Movfeatpos})) |
($segnum << (24 - $bits{Movfeatpos} - $bits{Segnum}));
- printf("C %s/%s 0x%06x %d\n",
- $seg, $movfeat, $datum, $bits{Angle})
- or die $!;
+ pf("C %s/%s 0x%06x %d\n",
+ $seg, $movfeat, $datum, $bits{Angle});
}
while (<>) {
$si->{Num}= $segnum++;
die if $si->{Num} >= 1 << $bits{Segnum};
$abovenext= 1 << $bits{Movfeatpos};
- printf("S %s 0x%x\n",
- $seg, $si->{Num})
- or die $!;
+ pf("S %s 0x%x\n",
+ $seg, $si->{Num});
cssnmap($seg,'', $si->{Num}, 0x00);
foreach $movfeat (sort {
$si->{Feat}{$b}{Max} <=> $si->{Feat}{$a}{Max};
$fi->{Prefix}= $abovenext;
$fi->{ConfigMask}= $posbit-1;
$fi->{ConfigBits}= $posbiti;
- printf("F %s 0x%x %s 0x%x %d\n",
- $seg, $si->{Num},
- $movfeat, $fi->{Prefix}, $fi->{ConfigBits});
+ pf("F %s 0x%x %s 0x%x %d\n",
+ $seg, $si->{Num},
+ $movfeat, $fi->{Prefix}, $fi->{ConfigBits});
cssnmap($seg, $movfeat, $si->{Num}, $fi->{Prefix});
}
}