-#!/usr/bin/perl
+#!/usr/bin/perl -w
# input file:
# lines, with one canonical subsegment specification (csss) each
# (need not be unique)
# output:
# lines:
-# <csss> <green> <blue> <stuff which will be ignored...>
+#
+# C <csss> <green> <blue>
# where <csss> is N/[MP] (see informat.txt) and <green> and <blue>
# contain no whitespace and are suitable for inserting like this
# into the PostScript output:
# ...code to compute and stack red in range [0,1>...
# <green> <blue> setrgbcolor
#
+# S <segname> 0x<segnum>
+# F <segname> 0x<segnum> <featname> 0x<prefix> <configbits> <maxconfig>
+# where (1<<configbits)-1 are the bits for the config
+# and ~((1<<configbits)-1) are the bits for the prefix
+# and maxconfig is the maximum configuration number used by the layout
+#
+# # comments for debugging segcmapassign etc.
+# E
+# final line, always present
+#
# Encoding is as follows (bits from MSbit to LSbit):
#
# RED
# 6 bits moveable feature and position
# each moveable feature has an unambiguous prefix
# the remainder of the bits are the position of that feature
-# the feature all-bits-1 (0b1111111) is for fixed track
+# the feature all-bits-1 (0b111111) is for fixed track
# (so every moveable feature prefix must contain at least one 0)
#
# BLUE
# 8 bits segment main
+use strict;
+use IO::Handle;
+
+our ($seg,$movfeat,$movconf,$si,$fi);
+our (%seg);
+
+while (<>) {
+ m,^(\w*)/([A-Za-z_]*)(\d*)$, or die;
+ ($seg,$movfeat,$movconf)=($1,$2,$3);
+ if (!length $seg) {
+ printf("C /%s%s 0 0\n",
+ $seg, $movfeat, $movconf)
+ or die $!;
+ next;
+ }
+ die if length $movconf && !length $movfeat;
+ exists $seg{$seg}{Num};
+ $si= $seg{$seg};
+ if (length $movfeat) {
+ exists $si->{Feat}{$movfeat}{Max};
+ $fi= $si->{Feat}{$movfeat};
+ $fi->{Max}=0 unless exists $fi->{Max};
+ $fi->{Max}=$movconf unless $fi->{Max} >= $movconf;
+ }
+}
+
+sub cssnmap ($$$$) {
+ my ($seg,$movfeatconf,$segnum,$posinfo) = @_;
+ my ($green,$blue);
+ $green= (($segnum >> 8) & 0x03)<<6;
+ $green |= $posinfo;
+ $blue= $segnum & 0xff;
+ printf("C %s/%s %.10f %.10f\n".
+ "# %s/%s 0x%x 0x%x\n",
+ $seg,$movfeatconf,
+ $green/255, $blue/255,
+ $seg,$movfeatconf,
+ $green, $blue)
+ or die $!;
+}
+
+our ($segnum) = 1;
+
+our ($conf,$posbit,$posbiti,$nextfree);
+
+foreach $seg (sort keys %seg) {
+ $si= $seg{$seg};
+ $si->{Num}= $segnum++;
+ die if $si->{Num} >= 1024;
+ $nextfree= 0;
+ printf("S %s 0x%x\n",
+ $seg, $si->{Num})
+ or die $!;
+ cssnmap($seg,'', $si->{Num}, 0x3f);
+ foreach $movfeat (sort {
+ $si->{Feat}{$b}{Max} <=> $si->{Feat}{$a}{Max};
+ } keys %{ $si->{Feat} }) {
+ $fi= $si->{Feat}{$movfeat};
+ for ($posbit=1,$posbiti=0;
+ $posbit<=$fi->{Max};
+ $posbit<<=1,$posbiti++) { }
+ $fi->{Prefix}= $nextfree;
+ $fi->{ConfigMask}= $posbit-1;
+ $fi->{ConfigBits}= $posbiti;
+ $nextfree += $posbit;
+ printf("F %s 0x%x %s 0x%x %d 0x%x\n",
+ $seg, $si->{Num},
+ $movfeat, $fi->{Prefix}, $fi->{ConfigBits}, $fi->{Max});
+ foreach ($conf=0; $conf<=$fi->{Max}; $conf++) {
+ cssnmap($seg, $movfeat.$conf, $si->{Num}, $fi->{Prefix}+$conf);
+ }
+ }
+ die "too many $seg" if $nextfree > 0x03f;
+}
+
+STDIN->error and die $!;
+print "E\n" or die $!;