chiark / gitweb /
realtime: print all movpos positions on entering Run
[trains.git] / layout / plan-to-gui-data
1 #!/usr/bin/perl -w
2 #
3 # We make one set of xpms for every (segment,[movfeat])
4 # For each (segment,[movfeat]) there is one `off' bitmap, a mask.
5 # For (segment,nil) there are also `on' and `detect' pixmaps.
6 # For (segment,movfeat) there are `on' and `detect' XPMs for each posn.
7 # (The `on' and `detect' XPMs share the actual pixel data.)
8
9 use strict qw(vars);
10 use POSIX;
11 use IO::Handle;
12
13 #---------- general ----------
14
15 sub seteq ($$$) {
16     my ($r,$v,$w)= @_;
17     if (defined $$r) {
18         $$r eq $v or die "$v $$r $w ?";
19     } else {
20         $$r= $v;
21     }
22 }
23
24 #---------- word-reading (for pbm) ----------
25
26 our $txtrdbuf= '';
27
28 sub w () {
29     for (;;) {
30         if ($txtrdbuf =~ s/^\s*(\S+)\s?//) {
31 #print STDERR "w>$1<\n";
32             return $1;
33         }
34         $!=0; $txtrdbuf=<>;
35         die $! unless length $txtrdbuf;
36         $txtrdbuf='' if $txtrdbuf =~ m/^\s*\#/;
37     }
38 }
39
40 sub wn ($$) {
41     my ($wn);
42     $wn= w();
43     die "$wn ?" unless $wn =~ m/^(?:[1-9]\d*|0)$/;
44     die "$wn $_[0]..$_[1] ?" if $wn < $_[0] || $wn > $_[1];
45     return $wn;
46 }
47 sub wns ($$$) {
48     my (@wns);
49     while (@wns < $_[2]) { push @wns, wn($_[0],$_[1]); }
50     return @wns;
51 }
52
53 #---------- xpm data structure ----------
54
55 our(%xpmdata);
56 # $xpmdata{$style}{$namerhs}{X}{Min}
57 # $xpmdata{$style}{$namerhs}{X}{Max}
58 # $xpmdata{$style}{$namerhs}{Y}{Min}
59 # $xpmdata{$style}{$namerhs}{Y}{Max}
60 # $xpmdata{$style}{$namerhs}{Pixels}{$y}{$x}
61 # $xpmdata{$style}{$namerhs}{Holey}
62 # $xpminstance{$instancename}{Data}= $xpmname
63
64 sub xpmdata_setup ($$$) {
65     my ($style, $namerhs, $holey)=@_;
66     my ($xp,$xy);
67     die if $xpmdata{$style}{$namerhs};
68     $xp= $xpmdata{$style}{$namerhs}= {
69         Holey => $holey,
70         };
71 }
72
73 #---------- parse args ----------
74
75 our $gvarname= 'ui_plan_data';
76
77 die unless @ARGV;
78 die if $ARGV[0] =~ m/^\-/;
79 if ($ARGV[$#ARGV] =~ s/^\-g//) {
80     $gvarname= pop @ARGV;
81     $gvarname =~ s/\W/_/g;
82 }
83
84 #---------- read segcmap ----------
85
86 our (%datum_numbits,%datum_basebit);
87 # $datum_numbits{Segname} etc.
88
89 our (@segnum_name,%movfeats,%movfeat_prefix,%movfeat_configbits);
90 # $segnum_name[$segnum]= $segname;
91 # $movfeats{$segname}[$i]= $xpmname
92 # $movfeat_prefix{$xpmname}
93 # $movfeat_configbits{$xpmname}
94
95 xpmdata_setup('background','',1);
96
97 for (;;) {
98     $!=0; defined($_=<>) or die $!;
99 #print STDERR "p>$_<\n";
100     last if m/^E$/;
101     if (m/^B (\w+) (\d+) (\d+)$/) {
102         $datum_numbits{$1}= $2;
103         $datum_basebit{$1}= $3;
104     } elsif (m/^S ([0-9A-Z]+) (0x[0-9a-f]+)$/) {
105         seteq(\$segnum_name[hex $2], $1, "segnum $2");
106         xpmdata_setup("bitmap","m_$1",1);
107         xpmdata_setup("on","_$1",1);
108         xpmdata_setup("bitmap","e_$1",1);
109     } elsif (m/^F ([0-9A-Z]+) (0x[0-9a-f]+) ([A-Z]+) (0x[0-9a-f]+) (\d+)$/) {
110         my ($xpmname,$bitno,$namerhs);
111         seteq(\$segnum_name[hex $2], $1, "segnum $2 F $3");
112         push @{ $movfeats{$1} }, $3;
113         $xpmname= $1.'_'.$3;
114         $movfeat_prefix{$xpmname}= hex $4;
115         $movfeat_configbits{$xpmname}= $5;
116         xpmdata_setup("on","u_$xpmname",1);
117         xpmdata_setup("bitmap","m_$xpmname",1);
118         for ($bitno=0; $bitno<$movfeat_configbits{$xpmname}; $bitno++) {
119             $namerhs= "${xpmname}_${bitno}";
120             xpmdata_setup("on","_$namerhs",1);
121             xpmdata_setup("bitmap","e_$namerhs",1);
122         }
123     }
124 }
125
126 sub ang2pixchars ($) {
127     die if $datum_numbits{Angle} > 6;
128     die if $_[0] > 64;
129     return substr('0123456789'.
130                   'abcdefghijklmnopqrstuvwxyz'.
131                   'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
132                   '@#',
133                   $_[0], 1);
134 }                 
135
136 #---------- read input image ----------
137
138 our(%sz,%overall);
139 # $sz{X}
140 # $sz{Y}
141 # $overall{X|Y}{Min|Max}
142
143 sub xpm_sizes () {
144     my ($rr,$xp,$xy);
145 print STDERR "xpm_sizes\n";
146     foreach $rr (values %xpmdata) {
147         foreach $xp (values %$rr) {
148             foreach $xy (qw(X Y)) {
149                 $xp->{$xy}{Min}= $sz{$xy}-1;
150                 $xp->{$xy}{Max}= 0;
151             }
152         }
153     }
154     foreach $xy (qw(X Y)) {
155         $overall{$xy}{Min}= $sz{$xy}-1;
156         $overall{$xy}{Max}= 0;
157     }
158 }
159
160 #---------- read input pixels ----------
161
162 our(%p,$pp);
163 # $p{X}
164 # $p{Y}
165 # $p{Movpos}
166
167 sub xpmdata_pixel ($$$) {
168     my ($style,$namerhs,$pcharstr)=@_;
169     my ($xp,$pk,$xy,$was,$mima);
170 #printf STDERR "%s  %s %s \`%s'", $pp, $style, $namerhs, $pcharstr;
171     $xp= $xpmdata{$style}{$namerhs};
172     defined $xp or die "$pp: $style $namerhs ?";
173     foreach $xy (qw(X Y)) {
174         foreach $mima ($xp->{$xy}, $overall{$xy}) {
175             $mima->{Min}= $p{$xy} if $p{$xy} < $mima->{Min};
176             $mima->{Max}= $p{$xy} if $p{$xy} > $mima->{Max};
177         }
178     }
179     $was= $xp->{Pixels}{$p{Y}}{$p{X}};
180     if (!defined $pcharstr || (defined($was) && $was gt $pcharstr)) {
181 #print STDERR " already \`$was'\n";
182         return;
183     }
184 #    die "$pp $style $namerhs \`$pcharstr',\`$xp->{Pixels}{$p{Y}}{$p{X}}' ?"
185 #       
186     $xp->{Pixels}{$p{Y}}{$p{X}}= $pcharstr;
187 #print STDERR " set\n";
188 }
189
190 sub in_pixel ($) {
191     my ($pbytes) = @_;
192     my ($namerhs,$movfeat,%t,$xpmname,$segname,$datum,$k,$angstr,$bitno,$me);
193     $pp= "$ARGV $p{X} $p{Y}";
194     $datum= unpack 'V', $pbytes."\0";
195     foreach $k (keys %datum_numbits) {
196         $t{$k}= ($datum >> $datum_basebit{$k}) &
197             ((1 << $datum_numbits{$k}) - 1);
198     }
199 #printf(STDERR "%s 0x%08lx 0x%x 0x%x %d\n",$pp,$datum,
200 #       $t{Segnum},$t{Movfeatpos},$t{Edge});
201
202     if ($t{Edge}) {
203         xpmdata_pixel('background','',undef);
204     } elsif ($t{Segnum}) {
205         xpmdata_pixel('background','','!');
206     } else {
207         xpmdata_pixel('background','','=');
208     }
209     return unless $t{Segnum};
210
211     $segname= $segnum_name[$t{Segnum}];
212     defined $segname or die "$pp $t{Segnum} $datum";
213     $pp.= " $segname";
214
215     $angstr= ang2pixchars($t{Angle});
216
217     if (!$t{Movfeatpos}) {
218         $xpmname= $segname;
219         xpmdata_pixel("on","_$xpmname", $angstr)
220             unless $t{Edge};
221         xpmdata_pixel("bitmap", "e_${xpmname}", '*')
222             if $t{Edge};
223         xpmdata_pixel("bitmap", "m_${segname}", '*');
224     } else {
225         my ($found, $yes);
226         $found= undef;
227         foreach $movfeat (@{ $movfeats{$segname} }) {
228             $xpmname= $segname.'_'.$movfeat;
229             if (($t{Movfeatpos} & ~((1<< $movfeat_configbits{$xpmname})-1))
230                 == $movfeat_prefix{$xpmname}) {
231                 die "$pp $t{Movfeatpos} $found $movfeat"
232                     if defined $found;
233                 $found= $movfeat;
234             }
235         }
236         die "$pp $t{Movfeatpos}"
237             unless defined $found;
238         $xpmname= $segname.'_'.$found;
239         xpmdata_pixel("on", "u_${xpmname}",
240                       (($p{X} + $p{Y}) % 2) ? $angstr : '!')
241             unless $t{Edge};
242         xpmdata_pixel("bitmap", "m_${xpmname}", '*');
243         for ($bitno=0; $bitno < $movfeat_configbits{$xpmname}; $bitno++) {
244             $namerhs= "${xpmname}_${bitno}";
245             $yes= $p{Movpos} == $bitno;
246             xpmdata_pixel("on","_$namerhs", $yes ? $angstr : '!')
247                 unless $t{Edge};
248             xpmdata_pixel("bitmap","e_$namerhs", $yes ? '*' : ' ')
249                 if $t{Edge};
250         }
251     }
252 }
253
254 #---------- read input pixmaps
255
256 sub read_pixmap_header () {
257     my (@szn,$osz);
258     @szn= wns(1,32767,2);
259     if (exists $sz{X}) {
260         $osz= "$sz{X} $sz{Y}";
261         "@szn" eq "$osz" or die "$osz @szn ?";
262     } else {
263         ($sz{X},$sz{Y})= @szn;
264         xpm_sizes();
265     }
266     wn(1,65535)==255 or die;
267 }
268
269 for (;;) {
270     die "$txtrdbuf ?" if length $txtrdbuf;
271     $txtrdbuf= <>;
272     if (!defined $txtrdbuf) {
273         die $! unless ARGV->eof;
274         last;
275     }
276     w() eq 'P6' or die;
277     read_pixmap_header();
278     $ARGV =~ m/.*\.p([0-9a-f]+)\b/ or die "$ARGV ?";
279     $p{Movpos}= $1 eq 'f' ? '' : hex($1);
280     my ($pbytes,$x,$xsz);
281     $xsz= $sz{X};
282     for ($p{Y}=0; $p{Y}<$sz{Y}; $p{Y}++) {
283         printf STDERR "%s %d\r",$ARGV,$p{Y}
284             unless $p{Y} % 100;
285         for ($x=0; $x<$xsz; $x++) {
286             $!=0; read(ARGV, $pbytes, 3) == 3 or die $!;
287             next if $pbytes eq "\xff\xff\xff";
288             $p{X}= $x;
289             in_pixel($pbytes);
290         }
291     }
292 }
293
294 #---------- colourmaps ----------
295
296 our (%cmap,%stylecmaps);
297 # $stylecmaps{$style}= [ $cmapname,... ]
298 # $cmap{$cmapname}{$pixchars}= $xpm_data_string_rhs
299 # $cmap{$cmapname}{''}= [ string names for including in xpm ]
300 #                          (after cmapdata_output_all)
301 $cmap{''}= {}; # fixed colours
302
303 sub xpm_cmap ($$) {
304     my ($style,$cmapname) = @_;
305     die "$cmapname ?" if exists $cmap{$cmapname};
306     push @{ $stylecmaps{$style} }, $cmapname;
307     $cmap{$cmapname}= { };
308 }
309
310 sub xpm_cmap_entry ($$$) {
311     my ($cmapname,$pixchars,$rhs) = @_;
312     die "$cmapname ?" unless exists $cmap{$cmapname};
313     die "$cmapname $pixchars ?" if exists $cmap{$cmapname}{$pixchars};
314     $cmap{$cmapname}{$pixchars}= $rhs;
315 }
316
317 sub xpm_cmap_rgbpermil($@) {
318     my ($cmapname, @l) = @_;
319     my ($pixchars, @rgb);
320     die "$cmapname @l ?" if @l % 4;
321     while (@l) {
322         ($pixchars, @rgb)= @l[0..3];  @l = @l[4..$#l];
323         xpm_cmap_entry($cmapname, $pixchars,
324                        sprintf("c #%04x%04x%04x",
325                                map { floor($_ * 65.535 + 0.5) } @rgb));
326     }
327 }
328
329 sub xpm_cmap_fixedbitmap($$) {
330     my ($cmapname,$on) = @_;
331     xpm_cmap_entry($cmapname,' ','s space');
332     xpm_cmap_entry($cmapname,$on,'s mark');
333 }
334
335 sub angle_to_colour ($) {
336     my ($angle) = @_;
337     my ($s,$f,$u,$U,$d,$D,$R);
338     
339     $s= floor($angle);
340     $f= $angle - $s;
341   
342     $u= $f * 0.5;
343     $U= $u + 0.5;
344     $d= 0.5 - $u;
345     $D= $d + 0.5; 
346
347 #print STDERR "a>$u|$U|$d|$D|$s<\n";
348
349     $R= ([ $D, $U,  0 ],
350          [ $d,  1, $u ],
351          [  0, $D, $U ],
352          [ $u, $d,  1 ],
353          [ $U,  0, $D ],
354          [  1, $u, $d ])[$s];
355     $R->[1] *= 0.9;
356     $R->[2] *= 0.9;
357     return @$R;
358 }
359
360 sub xpm_cmap_angular($$$@) {
361     my ($cmapname, $invert, $alpha, @basergb) = @_;
362     my ($angnum,$angval,@permil,@angrgb,$i);
363     for ($angnum=0; $angnum<(1<<$datum_numbits{Angle}); $angnum++) {
364         $angval= 6.0 * ($angnum+0.0) / (1<<$datum_numbits{Angle});
365         $angval += 3.0 if $invert;
366         $angval -= 6.0 if $angval >= 6.0;
367         @angrgb= angle_to_colour($angval);
368         for ($i=0; $i<3; $i++) {
369 #print STDERR ">$cmapname|$i|$alpha|$angrgb[$i]|$basergb[$i]<\n";
370             $permil[$i]= $alpha * $angrgb[$i] +
371                          (1.0 - $alpha/1000.0) * $basergb[$i];
372         }
373         xpm_cmap_rgbpermil($cmapname, ang2pixchars($angnum), @permil);
374     }
375 }
376
377 sub cmaps_define () {
378     my ($style,$inv,$ondet);
379     my (@background, @projected, @off, @otherposn);
380
381     @background= qw(0 0 0);
382     @off= qw(500 500 500);
383     @otherposn= qw(150 150 150);
384     @projected= qw(5 5 5);
385     
386     xpm_cmap("background","background");
387     xpm_cmap_rgbpermil("background",
388                        ' ', @background,
389                        '=', @projected,
390                        '!', @off);
391
392     xpm_cmap("bitmap","bitmap");
393     xpm_cmap_fixedbitmap("bitmap",'*');
394     
395     foreach $inv (('','i')) {
396         foreach $ondet (qw(on det)) {
397             xpm_cmap("on","${inv}${ondet}");
398             xpm_cmap_rgbpermil("${inv}${ondet}",
399                                ' ', @background,
400                                '!', @otherposn);
401         }
402         xpm_cmap_angular("${inv}on", !!$inv, 450, qw(0 0 0));
403         xpm_cmap_angular("${inv}det",!!$inv, 450, qw(1000 1000 1000));
404     }
405 }
406
407 cmaps_define();
408
409 #---------- output ----------
410
411 sub cmapdata_output_all () {
412     my ($cmapname, $stuff, $cmap, $sname, $pixchars);
413
414     foreach $cmapname (sort keys %cmap) {
415         next unless length $cmapname;
416         $stuff= [ ];
417         $cmap= $cmap{$cmapname};
418         foreach $pixchars (sort keys %$cmap) {
419             $sname= "m_${cmapname}_". unpack "H*", $pixchars;
420             printf("static const char %s[]= \"%s %s\";\n",
421                    $sname, $pixchars, $cmap->{$pixchars})
422                 or die $!;
423             push @$stuff, $sname;
424         }
425         $cmap->{''}= $stuff;
426     }
427
428     my ($colour, $rhs);
429     $cmap= $cmap{''};
430     foreach $colour (sort keys %$cmap) {
431         $rhs= $cmap->{$colour};
432         $rhs =~ s/^c // or die "$colour $rhs ?";
433         printf("const char ui_plan_colour_%s[]= \"%s\";\n",
434                $colour, $rhs)
435             or die $!;
436     }
437 }
438
439 sub xpmdata_output_all () {
440     my ($style, $namerhs, $xp, $row, $pp, $xy, $pixel);
441     my ($y, $cmap_data, $header_data, $cmapname);
442     foreach $style (sort keys %xpmdata) {
443         foreach $namerhs (sort keys %{ $xpmdata{$style} }) {
444             $xp= $xpmdata{$style}{$namerhs};
445             $header_data= "";
446             foreach $xy (qw(X Y)) {
447                 $xp->{$xy}{Max}= $xp->{$xy}{Min} if
448                     $xp->{$xy}{Max} < $xp->{$xy}{Min};
449                 $header_data .= $xp->{$xy}{Max} - $xp->{$xy}{Min} + 1;
450                 $header_data .= " ";
451             }
452             for ($p{Y}=$xp->{Y}{Min}; $p{Y}<=$xp->{Y}{Max}; $p{Y}++) {
453                 printf "static const char d%04d_%s_%s[]= \"",
454                     $p{Y}, $style, $namerhs or die $!;
455                 $row= $xp->{Pixels}{$p{Y}};
456                 $pp= "$style $namerhs $p{X} $p{Y}";
457                 for ($p{X}=$xp->{X}{Min}; $p{X}<=$xp->{X}{Max}; $p{X}++) {
458                     $pixel= $row->{$p{X}};
459                     if (!defined $pixel) {
460                         die "$pp ?" if !$xp->{Holey};
461                         $pixel= ' ';
462                     }
463                     print $pixel or die $!;
464                 }
465                 print "\";\n" or die $!;
466             }
467 #printf STDERR "style >$style<\n";
468             foreach $cmapname (sort @{ $stylecmaps{$style} }) {
469                 $cmap_data= $cmap{$cmapname}{''};
470                 printf("static const char *p_%s_%s[]= {\n".
471                        "  \"%s%d 1\",\n",
472                        $cmapname, $namerhs,
473                        $header_data, scalar(@$cmap_data))
474                     or die $!;
475                 map { printf "  %s,\n", $_ or die $!; } @$cmap_data;
476                 for ($y=$xp->{Y}{Min}; $y<=$xp->{Y}{Max}; $y++) {
477                     printf "  d%04d_%s_%s,\n", $y, $style, $namerhs
478                         or die $!;
479                 }
480                 print("  0\n".
481                       "};\n")
482                     or die $!;
483             }
484         }
485     }
486 }
487
488 sub ppdr ($$$) {
489     my ($style,$cmap,$namerhs) = @_;
490     my ($xpmd);
491     $xpmd= $xpmdata{$style}{$namerhs};
492 defined $xpmd or die "$style $cmap $namerhs ?";
493     return sprintf("{ %d-%d,%d-%d, p_%s_%s }",
494                    (map { $xpmd->{$_}{Min}, $overall{$_}{Min} } qw(X Y)),
495                    $cmap, $namerhs);
496 }
497
498 sub ppdiondet ($) {
499     my ($dname) = @_;
500     return ("{ { ".ppdr('on',"on",$dname).", ".ppdr('on',"det",$dname)." },".
501             " { ".ppdr('on',"ion",$dname).", ".ppdr('on',"idet",$dname).
502             " } }");
503 }
504
505 our (@oodnames, %ood);
506 # $ood{$oodname}{Data}= $data_so_far
507 # $ood{$oodname}{ArrayDelim}= "\n" or ",\n" but for oodas only
508
509 sub oods ($$) {
510     my ($oodname, $data) = @_;
511     die "$oodname {{$data}} ?" if exists $ood{$oodname};
512     $ood{$oodname}{Data}= $data;
513     push @oodnames, $oodname;
514 }
515
516 sub ooda0 ($$) {
517     my ($oodname, $begin) = @_;
518     die "$oodname {{$begin}} ?" if exists $ood{$oodname};
519     $ood{$oodname}{Data}= $begin;
520     $ood{$oodname}{Data} .= "[]= {";
521     $ood{$oodname}{ArrayDelim}= "\n";
522     push @oodnames, $oodname;
523 }
524
525 sub ooda1 ($$) {
526     my ($oodname, $entry) = @_;
527     die "$oodname {{$entry}} ?" unless defined $ood{$oodname}{ArrayDelim};
528     $ood{$oodname}{Data} .= $ood{$oodname}{ArrayDelim};
529     $ood{$oodname}{Data} .= "  ".$entry;
530     $ood{$oodname}{ArrayDelim}= ",\n";
531 }
532
533 sub ood_output_all () {
534     my ($oodname, $ood);
535     foreach $oodname (reverse @oodnames) {
536         $ood= $ood{$oodname};
537         print $ood->{Data} or die $!;
538         if (defined $ood->{ArrayDelim}) {
539             print "\n};\n" or die $!;
540         }
541     }
542 }
543
544 sub plandata_output_all () {
545     my ($i, @segnames, $segname);
546     my (@movfeats, $movfeat, $dname, $xpmname, $n_posns, $code, $posn);
547     my ($n_movfeats, $style, $xpmd, $pedge, $me, $noppdr);
548
549     for ($i=1; $i<@segnum_name; $i++) {
550         $segname= $segnum_name[$i];
551         next unless defined $segname;
552         push @segnames, $segname;
553     }
554
555     oods('ui_plan_data',
556          "const PlanData $gvarname= {\n".
557          "  $overall{X}{Max}-$overall{X}{Min},".
558          "  $overall{Y}{Max}-$overall{Y}{Min},".
559          "  p_background_,\n".
560          "  ".scalar(@segnames).", segments\n".
561          "};\n");
562
563     ooda0('segments',
564           "static const PlanSegmentData segments");
565
566     foreach $segname (sort @segnames) {
567         @movfeats=
568             exists $movfeats{$segname} ? @{ $movfeats{$segname} } : ();
569         unshift @movfeats, '';
570
571         ooda0("mf_$segname",
572               "static const PlanSegmovfeatData mf_$segname");
573
574         ooda1("segments",
575               "{ \"$segname\", ".scalar(@movfeats).", mf_$segname }");
576
577         foreach $movfeat (sort @movfeats) {
578             if (!length $movfeat) {
579                 $xpmname= $segname;
580                 $n_posns= 1;
581                 $code= '0';
582             } else {
583                 $xpmname= "${segname}_${movfeat}";
584                 $n_posns= $movfeat_configbits{$xpmname};
585                 $code= "\"$movfeat\"";
586             }
587 #print STDERR ">$segname|$movfeat<\n";
588             $noppdr= "{-1,-1,0}";
589             ooda1("mf_$segname",
590                   "{ $code, ".ppdr('bitmap',"bitmap","m_$xpmname").", ".
591                   ($n_posns > 1 ? ppdiondet("u_$xpmname") :
592                    "{ { $noppdr, $noppdr }, { $noppdr, $noppdr } }").
593                   ", $n_posns, posns_$xpmname }");
594
595             ooda0("posns_$xpmname",
596                   "static const PlanPixmapOnData posns_$xpmname");
597             
598             for ($posn=0; $posn < $n_posns; $posn++) {
599                 if ($movfeat eq '') {
600                     $dname= $segname;
601                     $pedge= 'edge';
602                 } else {
603                     $dname= sprintf "%s_%s_%d", $segname, $movfeat, $posn;
604                     $pedge= 'pedge';
605                 }
606                 ooda1("posns_$xpmname",
607                       "{ ".ppdr('bitmap',"bitmap","e_$dname").",".
608                       " ".ppdiondet("_$dname")." }");
609             }
610         }
611     }
612 }
613
614 print "#include \"plan-data-format.h\"\n" or die $!;
615 print "/* region: $overall{X}{Min}..$overall{X}{Max}".
616                 " $overall{Y}{Min}..$overall{Y}{Max} */\n";
617 cmapdata_output_all();
618 xpmdata_output_all();
619 plandata_output_all();
620 ood_output_all();