version number set to 4.1.2.1
[rocksndiamonds.git] / build-scripts / create_element_defs.pl
1 #!/usr/bin/perl -w
2
3 # =============================================================================
4 # Rocks'n'Diamonds - McDuffin Strikes Back!
5 # -----------------------------------------------------------------------------
6 # (c) 1995-2014 by Artsoft Entertainment
7 #                  Holger Schemel
8 #                  info@artsoft.org
9 #                  http://www.artsoft.org/
10 # -----------------------------------------------------------------------------
11 # create_element_defs.pl
12 # =============================================================================
13
14 use strict;
15
16
17 # =============================================================================
18 # C O N F I G U R A T I O N   S E C T I O N
19 # =============================================================================
20
21 my $base_path = ".";
22 my $src_path = "$base_path/src";
23
24 if (-d "../src")        # we're already inside "src" directory
25 {
26     $src_path = ".";
27 }
28
29
30 # -----------------------------------------------------------------------------
31 # global variables
32 # -----------------------------------------------------------------------------
33
34 my $filename_header_tmpl = "$src_path/header.tmpl";
35
36 my $filename_conf_gfx_h = 'conf_gfx.h';
37 my $filename_conf_snd_h = 'conf_snd.h';
38 my $filename_conf_mus_h = 'conf_mus.h';
39 my $filename_conf_chr_c = 'conf_chr.c';
40 my $filename_conf_chr_h = 'conf_chr.h';
41 my $filename_conf_cus_c = 'conf_cus.c';
42 my $filename_conf_cus_h = 'conf_cus.h';
43 my $filename_conf_grp_c = 'conf_grp.c';
44 my $filename_conf_grp_h = 'conf_grp.h';
45 my $filename_conf_e2g_c = 'conf_e2g.c';
46 my $filename_conf_esg_c = 'conf_esg.c';
47 my $filename_conf_e2s_c = 'conf_e2s.c';
48 my $filename_conf_fnt_c = 'conf_fnt.c';
49 my $filename_conf_g2s_c = 'conf_g2s.c';
50 my $filename_conf_g2m_c = 'conf_g2m.c';
51 my $filename_conf_var_c = 'conf_var.c';
52 my $filename_conf_act_c = 'conf_act.c';
53
54 my $text_auto = 'this file was automatically generated -- do not edit by hand';
55 my $text_gfx_h = 'values for graphics configuration (normal elements)';
56 my $text_snd_h = 'values for sounds configuration';
57 my $text_mus_h = 'values for music configuration';
58 my $text_chr_c = 'values for graphics configuration (character elements)';
59 my $text_chr_h = 'values for elements configuration (character elements)';
60 my $text_cus_c = 'values for graphics configuration (custom elements)';
61 my $text_cus_h = 'values for elements configuration (custom elements)';
62 my $text_grp_c = 'values for graphics configuration (group elements)';
63 my $text_grp_h = 'values for elements configuration (group elements)';
64 my $text_e2g_c = 'values for element/graphics mapping configuration (normal)';
65 my $text_esg_c = 'values for element/graphics mapping configuration (special)';
66 my $text_e2s_c = 'values for element/sounds mapping configuration';
67 my $text_fnt_c = 'values for font/graphics mapping configuration';
68 my $text_g2s_c = 'values for gamemode/sound mapping configuration';
69 my $text_g2m_c = 'values for gamemode/music mapping configuration';
70 my $text_var_c = 'values for image and layout parameter configuration';
71 my $text_act_c = 'values for active states of elements and fonts';
72
73 my $num_custom_elements = 256;
74 my $num_group_elements = 32;
75
76 my $char_skip = '---[SKIP]---';
77
78 my @chars =
79     (
80      'SPACE',
81      'EXCLAM',
82      'QUOTEDBL',
83      'NUMBERSIGN',
84      'DOLLAR',
85      'PERCENT',
86      'AMPERSAND',
87      'APOSTROPHE',
88      'PARENLEFT',
89      'PARENRIGHT',
90      'ASTERISK',
91      'PLUS',
92      'COMMA',
93      'MINUS',
94      'PERIOD',
95      'SLASH',
96
97      '0',
98      '1',
99      '2',
100      '3',
101      '4',
102      '5',
103      '6',
104      '7',
105      '8',
106      '9',
107      'COLON',
108      'SEMICOLON',
109      'LESS',
110      'EQUAL',
111      'GREATER',
112      'QUESTION',
113
114      'AT',
115      'A',
116      'B',
117      'C',
118      'D',
119      'E',
120      'F',
121      'G',
122      'H',
123      'I',
124      'J',
125      'K',
126      'L',
127      'M',
128      'N',
129      'O',
130
131      'P',
132      'Q',
133      'R',
134      'S',
135      'T',
136      'U',
137      'V',
138      'W',
139      'X',
140      'Y',
141      'Z',
142      'BRACKETLEFT',
143      'BACKSLASH',
144      'BRACKETRIGHT',
145      'ASCIICIRCUM',
146      'UNDERSCORE',
147
148      'COPYRIGHT',
149      'AUMLAUT',
150      'OUMLAUT',
151      'UUMLAUT',
152      'DEGREE',
153      'TRADEMARK',
154      'CURSOR',
155      $char_skip,
156      $char_skip,
157      $char_skip,
158      $char_skip,
159      $char_skip,
160      $char_skip,
161      'BUTTON',
162      'UP',
163      'DOWN',
164      );
165
166
167 # -----------------------------------------------------------------------------
168 # start main program
169 # -----------------------------------------------------------------------------
170
171 main();
172 exit 0;
173
174
175 # =============================================================================
176 # F U N C T I O N S
177 # =============================================================================
178
179 sub error
180 {
181     my ($error_msg) = @_;
182
183     print STDERR "ERROR: ";
184     print STDERR "$error_msg\n";
185 }
186
187 sub fail
188 {
189     my ($error_msg) = @_;
190
191     print STDERR "FATAL ";
192     error("$error_msg");
193
194     exit 1;
195 }
196
197 sub contains_image_file
198 {
199     my ($line) = @_;
200
201     return ($line =~ /\".+\.png\"/ ||
202             $line =~ /UNDEFINED_FILENAME/);
203 }
204
205 sub contains_sound_file
206 {
207     my ($line) = @_;
208
209     return ($line =~ /\".+\.wav\"/ ||
210             $line =~ /UNDEFINED_FILENAME/);
211 }
212
213 sub contains_music_file
214 {
215     my ($line) = @_;
216
217     return ($line =~ /\".+\.wav\"/ ||
218             $line =~ /\".+\.mod\"/ ||
219             $line =~ /\".+\.mp3\"/ ||
220             $line =~ /UNDEFINED_FILENAME/);
221 }
222
223 sub print_file_header
224 {
225     my ($filename, $comment) = @_;
226     my $filename_tmpl = 'xxxxxxxx.x';
227     my $filename_text = $filename;
228     my $filename_def = uc($filename);
229     $filename_def =~ s/\./_/;
230
231     $filename_text .= ' ' x (length($filename_tmpl) - length($filename_text));
232
233     open(FILE, "$filename_header_tmpl") ||
234         fail("cannot open file '$filename_header_tmpl' for reading");
235
236     while (<FILE>)
237     {
238         s/$filename_tmpl/$filename_text/;
239
240         print;
241     }
242
243     close FILE;
244
245     print "\n";
246     print "// ------- $text_auto -------\n";
247     print "\n";
248     print "#ifndef $filename_def\n";
249     print "#define $filename_def\n";
250     print "\n";
251     print "// $comment\n";
252     print "\n";
253 }
254
255 sub print_file_footer
256 {
257     my ($filename) = @_;
258     my $filename_def = uc($filename);
259     $filename_def =~ s/\./_/;
260
261     print "\n";
262     print "#endif       // $filename_def\n";
263 }
264
265 sub get_tabs
266 {
267     my ($text, $max_num_tabs) = @_;
268
269     my $num_tabs = $max_num_tabs - int(length($text) / 8);
270
271     if ($num_tabs < 1)  # at least one tab needed as separator
272     {
273         $num_tabs = 1;
274     }
275
276     return "\t" x $num_tabs;
277 }
278
279 sub print_graphics_list
280 {
281     my $filename = "$src_path/conf_gfx.c";
282
283     print_file_header($filename_conf_gfx_h, $text_gfx_h);
284
285     open(FILE, "$filename") ||
286         fail("cannot open file '$filename' for reading");
287
288     my $max_num_tabs = 7;
289     my $i = 0;
290
291     while (<FILE>)
292     {
293         chomp;                          # cut trailing newline
294
295         if (/^\#include "conf_chr.c"/)  # dump list of character elements
296         {
297             foreach my $char (@chars)
298             {
299                 my $prefix = $char;
300
301                 $prefix =~ s/^/#define IMG_CHAR_/;
302
303                 my $tabs = get_tabs($prefix, $max_num_tabs);
304
305                 if ($char ne $char_skip)
306                 {
307                     print "$prefix$tabs$i\n";
308
309                     $i++;
310                 }
311
312                 if (lc($char) eq 'space')
313                 {
314                     $prefix =~ s/$/_EDITOR/;
315
316                     my $tabs = get_tabs($prefix, $max_num_tabs);
317
318                     print "$prefix$tabs$i\n";
319
320                     $i++;
321                 }
322             }
323
324             foreach my $char (@chars)
325             {
326                 my $prefix = $char;
327
328                 $prefix =~ s/^/#define IMG_STEEL_CHAR_/;
329
330                 my $tabs = get_tabs($prefix, $max_num_tabs);
331
332                 if ($char ne $char_skip)
333                 {
334                     print "$prefix$tabs$i\n";
335
336                     $i++;
337                 }
338
339                 if (lc($char) eq 'space')
340                 {
341                     $prefix =~ s/$/_EDITOR/;
342
343                     my $tabs = get_tabs($prefix, $max_num_tabs);
344
345                     print "$prefix$tabs$i\n";
346
347                     $i++;
348                 }
349             }
350         }
351
352         if (/^\#include "conf_cus.c"/)  # dump list of custom elements
353         {
354             for (my $nr = 0; $nr < $num_custom_elements; $nr++)
355             {
356                 my $line = sprintf("#define IMG_CUSTOM_%d", $nr + 1);
357
358                 my $tabs = get_tabs($line, $max_num_tabs);
359
360                 print "$line$tabs$i\n";
361
362                 $i++;
363
364                 $line = sprintf("#define IMG_CUSTOM_%d_EDITOR", $nr + 1);
365
366                 $tabs = get_tabs($line, $max_num_tabs);
367
368                 print "$line$tabs$i\n";
369
370                 $i++;
371             }
372         }
373
374         if (/^\#include "conf_grp.c"/)  # dump list of group elements
375         {
376             for (my $nr = 0; $nr < $num_group_elements; $nr++)
377             {
378                 my $line = sprintf("#define IMG_GROUP_%d", $nr + 1);
379
380                 my $tabs = get_tabs($line, $max_num_tabs);
381
382                 print "$line$tabs$i\n";
383
384                 $i++;
385
386                 $line = sprintf("#define IMG_GROUP_%d_EDITOR", $nr + 1);
387
388                 $tabs = get_tabs($line, $max_num_tabs);
389
390                 print "$line$tabs$i\n";
391
392                 $i++;
393             }
394         }
395
396         if (!contains_image_file($_))   # skip all lines without image file
397         {
398             next;
399         }
400
401         s/(.*)/uc($1)/eg;               # convert all characters to upper case
402         s/\./_/g;                       # replace all '.' with '_'
403
404         s/^  \{ \"/#define IMG_/;       # convert line
405         s/\",.*$//;                     # convert line
406
407         # dirty hack for making "ABC[DEF]" work as a "special" suffix
408         s/([^_])\[/$1_/;
409
410         # dirty hack for making "[default]" work as an element name
411         s/\[//;
412         s/\]//;
413
414         my $tabs = get_tabs($_, $max_num_tabs);
415
416         print "$_$tabs$i\n";
417
418         $i++;
419     }
420
421     my $summary = '#define NUM_IMAGE_FILES';
422     my $tabs = get_tabs($summary, $max_num_tabs);
423
424     print "\n$summary$tabs$i\n";
425
426     close FILE;
427
428     print_file_footer($filename_conf_gfx_h);
429 }
430
431 sub print_sounds_list
432 {
433     my %known_element = get_known_element_definitions();
434
435     my $filename = "$src_path/conf_snd.c";
436
437     print_file_header($filename_conf_snd_h, $text_snd_h);
438
439     open(FILE, "$filename") ||
440         fail("cannot open file '$filename' for reading");
441
442     my $max_num_tabs = 7;
443     my $i = 0;
444
445     while (<FILE>)
446     {
447         chomp;                          # cut trailing newline
448
449         if (!contains_sound_file($_))   # skip all lines without sound file
450         {
451             next;
452         }
453
454         if (/\[not used\]/ ||
455             / TEST / ||
456             /wav[^\}]*$/)               # skip all lines without sound file
457         {
458             next;
459         }
460
461         s/(.*)/uc($1)/eg;               # convert all characters to upper case
462         s/\./_/g;                       # replace all '.' with '_'
463
464         s/^  \{ \"//;
465         s/\",.*$//;
466
467         my $sound = $_;
468
469         if ($sound =~ /^\[.+\]/)
470         {
471             $sound =~ s/\[//;           # element class sound; begin ...
472             $sound =~ s/\]//;           # ... and end of definition token
473             $sound =~ s/^/CLASS_/;      # add class identifier
474         }
475
476         $sound = "SND_$sound";
477
478         my $define_text = "#define $sound";
479         my $tabs = get_tabs($define_text, $max_num_tabs);
480
481         print "$define_text$tabs$i\n";
482
483         $i++;
484     }
485
486     my $summary = '#define NUM_SOUND_FILES';
487     my $tabs = get_tabs($summary, $max_num_tabs);
488
489     print "\n$summary$tabs$i\n";
490
491     close FILE;
492
493     print_file_footer($filename_conf_snd_h);
494 }
495
496 sub print_music_list
497 {
498     my %known_prefix = get_known_music_prefix_definitions();
499
500     my $filename = "$src_path/conf_mus.c";
501
502     print_file_header($filename_conf_mus_h, $text_mus_h);
503
504     open(FILE, "$filename") ||
505         fail("cannot open file '$filename' for reading");
506
507     my $max_num_tabs = 7;
508     my $i = 0;
509
510     while (<FILE>)
511     {
512         chomp;                          # cut trailing newline
513
514         if (!contains_music_file($_))   # skip all lines without music file
515         {
516             next;
517         }
518
519         if (/\[not used\]/ ||
520             / TEST / ||
521             /wav[^\}]*$/)               # skip all lines without music file
522         {
523             next;
524         }
525
526         s/(.*)/uc($1)/eg;               # convert all characters to upper case
527         s/\./_/g;                       # replace all '.' with '_'
528
529         s/^  \{ \"//;
530         s/\",.*$//;
531
532         my $music = $_;
533
534         $music = "MUS_$music";
535
536         my $define_text = "#define $music";
537         my $tabs = get_tabs($define_text, $max_num_tabs);
538
539         print "$define_text$tabs$i\n";
540
541         $i++;
542     }
543
544     my $summary = '#define NUM_MUSIC_FILES';
545     my $tabs = get_tabs($summary, $max_num_tabs);
546
547     print "\n$summary$tabs$i\n";
548
549     close FILE;
550
551     print_file_footer($filename_conf_mus_h);
552 }
553
554 sub print_chars_elements_list
555 {
556     print_file_header($filename_conf_chr_h, $text_chr_h);
557
558     my $i = 0;
559
560     foreach my $char (@chars)
561     {
562         my $left = "#define EL_CHAR_$char";
563
564         my $tabs_left = get_tabs($left, 5);
565
566         my $right = sprintf("(EL_CHAR_ASCII0 + %d)", $i + 32);
567
568         if ($char ne $char_skip)
569         {
570             print "$left$tabs_left$right\n";
571         }
572
573         $i++;
574     }
575
576     $i = 0;
577
578     foreach my $char (@chars)
579     {
580         my $left = "#define EL_STEEL_CHAR_$char";
581
582         my $tabs_left = get_tabs($left, 5);
583
584         my $right = sprintf("(EL_STEEL_CHAR_ASCII0 + %d)", $i + 32);
585
586         if ($char ne $char_skip)
587         {
588             print "$left$tabs_left$right\n";
589         }
590
591         $i++;
592     }
593
594     print_file_footer($filename_conf_chr_c);
595 }
596
597 sub print_chars_graphics_list_line
598 {
599     my ($token, $x, $y) = @_;
600
601     my @extensions =
602         (
603          '',
604          '.xpos',
605          '.ypos',
606          '.frames',
607          );
608
609     my $basename = ($token =~ /^steel_char/ ? 'RocksFontDC' : 'RocksFontEM' );
610
611     foreach my $ext (@extensions)
612     {
613         my $left = "  \{ \"$token$ext\",";
614
615         my $tabs_left = get_tabs($left, 6);
616
617         my $right = ($ext eq '' ? $basename . '.png' :
618                      $ext eq '.frames' ? '1' : '0');
619
620         if ($ext eq '.xpos')
621         {
622             $right = $x;
623         }
624         elsif ($ext eq '.ypos')
625         {
626             $right = $y;
627         }
628
629         $right = "\"$right\"";
630
631         my $tabs_right = get_tabs($right, 3);
632
633         print "$left$tabs_left$right$tabs_right},\n";
634     }
635 }
636
637 sub print_chars_graphics_list
638 {
639     print_file_header($filename_conf_chr_c, $text_chr_c);
640
641     my $i = 0;
642
643     foreach my $char (@chars)
644     {
645         if ($char ne $char_skip)
646         {
647             my $x = $i % 16;
648             my $y = int($i / 16);
649
650             print_chars_graphics_list_line(lc("char_$char"), $x, $y);
651         }
652
653         if (lc($char) eq 'space')
654         {
655             print_chars_graphics_list_line("char_space.EDITOR", 7, 4);
656         }
657
658         if ($char ne $char_skip)
659         {
660             print "\n";
661         }
662
663         $i++;
664     }
665
666     $i = 0;
667
668     foreach my $char (@chars)
669     {
670         if ($char ne $char_skip)
671         {
672             my $x = $i % 16;
673             my $y = int($i / 16);
674
675             print_chars_graphics_list_line(lc("steel_char_$char"), $x, $y);
676         }
677
678         if (lc($char) eq 'space')
679         {
680             print_chars_graphics_list_line("steel_char_space.EDITOR", 7, 4);
681         }
682
683         if ($char ne $char_skip)
684         {
685             print "\n";
686         }
687
688         $i++;
689     }
690
691     print_file_footer($filename_conf_chr_c);
692 }
693
694 sub print_custom_elements_list
695 {
696     print_file_header($filename_conf_cus_h, $text_cus_h);
697
698     for (my $i = 0; $i < $num_custom_elements; $i++)
699     {
700         my $left = sprintf("#define EL_CUSTOM_%d", $i + 1);
701
702         my $tabs_left = get_tabs($left, 5);
703
704         my $right = "(EL_CUSTOM_START + $i)";
705
706         print "$left$tabs_left$right\n";
707     }
708
709     print_file_footer($filename_conf_cus_c);
710 }
711
712 sub print_group_elements_list
713 {
714     print_file_header($filename_conf_grp_h, $text_grp_h);
715
716     for (my $i = 0; $i < $num_group_elements; $i++)
717     {
718         my $left = sprintf("#define EL_GROUP_%d", $i + 1);
719
720         my $tabs_left = get_tabs($left, 5);
721
722         my $right = "(EL_GROUP_START + $i)";
723
724         print "$left$tabs_left$right\n";
725     }
726
727     print_file_footer($filename_conf_grp_c);
728 }
729
730 sub print_custom_graphics_list
731 {
732     my @extensions1 =
733         (
734          '',
735          '.xpos',
736          '.ypos',
737          '.frames',
738          );
739     my @extensions2 =
740         (
741          '',
742          '.xpos',
743          '.ypos',
744          );
745
746     print_file_header($filename_conf_cus_c, $text_cus_c);
747
748     for (my $i = 0; $i < $num_custom_elements; $i++)
749     {
750         foreach my $ext (@extensions1)
751         {
752             my $left = sprintf("  \{ \"custom_%d$ext\",", $i + 1);
753
754             my $tabs_left = get_tabs($left, 6);
755
756             # my $right = ($ext eq '' ? 'RocksElements.png' :
757             my $right = ($ext eq '' ? 'RocksCE.png' :
758                          $ext eq '.frames' ? '1' : '0');
759
760             if ($ext eq '.xpos')
761             {
762                 # $right = 7;
763                 $right = int($i % 16);
764             }
765             elsif ($ext eq '.ypos')
766             {
767                 # $right = 9;
768                 $right = int($i / 16);
769             }
770
771             $right = "\"$right\"";
772
773             my $tabs_right = get_tabs($right, 3);
774
775             print "$left$tabs_left$right$tabs_right},\n";
776         }
777
778         foreach my $ext (@extensions2)
779         {
780             my $left = sprintf("  \{ \"custom_%d.EDITOR$ext\",", $i + 1);
781
782             my $tabs_left = get_tabs($left, 6);
783
784             # my $right = ($ext eq '' ? 'RocksElements.png' : '0');
785             my $right = ($ext eq '' ? 'RocksCE.png' : '0');
786
787             if ($ext eq '.xpos')
788             {
789                 # $right = 15;
790                 $right = int($i % 16) + 16;
791             }
792             elsif ($ext eq '.ypos')
793             {
794                 # $right = 13;
795                 $right = int($i / 16);
796             }
797
798             $right = "\"$right\"";
799
800             my $tabs_right = get_tabs($right, 3);
801
802             print "$left$tabs_left$right$tabs_right},\n";
803         }
804
805         print "\n";
806     }
807
808     print_file_footer($filename_conf_cus_c);
809 }
810
811 sub print_group_graphics_list
812 {
813     my @extensions1 =
814         (
815          '',
816          '.xpos',
817          '.ypos',
818          '.frames',
819          );
820     my @extensions2 =
821         (
822          '',
823          '.xpos',
824          '.ypos',
825          );
826
827     print_file_header($filename_conf_grp_c, $text_grp_c);
828
829     for (my $i = 0; $i < $num_group_elements; $i++)
830     {
831         foreach my $ext (@extensions1)
832         {
833             my $left = sprintf("  \{ \"group_%d$ext\",", $i + 1);
834
835             my $tabs_left = get_tabs($left, 6);
836
837             # my $right = ($ext eq '' ? 'RocksDC.png' :
838             my $right = ($ext eq '' ? 'RocksCE.png' :
839                          $ext eq '.frames' ? '1' : '0');
840
841             if ($ext eq '.xpos')
842             {
843                 # $right = 4;
844                 $right = int($i % 16);
845             }
846             elsif ($ext eq '.ypos')
847             {
848                 # $right = 15;
849                 $right = int($i / 16) + int($num_custom_elements / 16);
850             }
851
852             $right = "\"$right\"";
853
854             my $tabs_right = get_tabs($right, 3);
855
856             print "$left$tabs_left$right$tabs_right},\n";
857         }
858
859         foreach my $ext (@extensions2)
860         {
861             my $left = sprintf("  \{ \"group_%d.EDITOR$ext\",", $i + 1);
862
863             my $tabs_left = get_tabs($left, 6);
864
865             # my $right = ($ext eq '' ? 'RocksDC.png' : '0');
866             my $right = ($ext eq '' ? 'RocksCE.png' : '0');
867
868             if ($ext eq '.xpos')
869             {
870                 # $right = 14;
871                 $right = int($i % 16) + 16;
872             }
873             elsif ($ext eq '.ypos')
874             {
875                 # $right = 15;
876                 $right = int($i / 16) + int($num_custom_elements / 16);
877             }
878
879             $right = "\"$right\"";
880
881             my $tabs_right = get_tabs($right, 3);
882
883             print "$left$tabs_left$right$tabs_right},\n";
884         }
885
886         print "\n";
887     }
888
889     print_file_footer($filename_conf_grp_c);
890 }
891
892 sub get_known_element_definitions_ALTERNATIVE
893 {
894     my %known_element = ();
895
896     my $filename = "$src_path/main.h";
897
898     open(FILE, "$filename") ||
899         fail("cannot open file '$filename' for reading");
900
901     while (<FILE>)
902     {
903         chomp;                          # cut trailing newline
904
905         # process line with element definition
906         if (/^\#define (EL_[A-Z0-9_]+)\s/)
907         {
908             $known_element{$1} = 1;
909
910             # print STDERR "known_element: '$1'\n";
911         }
912     }
913
914     close FILE;
915
916     return %known_element;
917 }
918
919 sub get_known_element_definitions
920 {
921     my %known_element = ();
922
923     my $filename = "$src_path/main.c";
924
925     open(FILE, "$filename") ||
926         fail("cannot open file '$filename' for reading");
927
928     my $element_name = '';
929     my $line_is_element_name = 0;
930     my $skip_line = 1;
931
932     while (<FILE>)
933     {
934         chomp;                          # cut trailing newline
935
936         if (/ELEMENT_INFO_START/)       # keyword to start parsing file
937         {
938             $skip_line = 0;
939             next;
940         }
941         elsif (/ELEMENT_INFO_END/)      # keyword to stop parsing file
942         {
943             last;
944         }
945         elsif ($skip_line)
946         {
947             next;
948         }
949
950         if (/^\s+\{\s*$/)
951         {
952             $line_is_element_name = 1;
953         }
954         elsif ($line_is_element_name)
955         {
956             # process line with element name definition
957             if (/^\s+\"(.+)\",?\s*$/)
958             {
959                 $element_name = 'EL_' . uc($1);
960
961                 # dirty hack for making "[default]" work as an element name
962                 $element_name =~ s/\[//;
963                 $element_name =~ s/\]//;
964
965                 # change '.' to '_' for elements like "dynamite.active"
966                 $element_name =~ s/\./_/g;
967
968                 $known_element{$element_name} = 1;
969
970                 # printf STDERR "::: known element '$element_name'\n";
971             }
972
973             $line_is_element_name = 0;
974         }
975     }
976
977     close FILE;
978
979     return %known_element;
980 }
981
982 sub get_known_element_class_definitions
983 {
984     my %known_element_class = ();
985
986     my $filename = "$src_path/main.c";
987
988     open(FILE, "$filename") ||
989         fail("cannot open file '$filename' for reading");
990
991     my $element_name = '';
992     my $element_class = '';
993     my $line_is_element_name = 0;
994     my $line_is_element_class = 0;
995     my $skip_line = 1;
996
997     while (<FILE>)
998     {
999         chomp;                          # cut trailing newline
1000
1001         if (/ELEMENT_INFO_START/)       # keyword to start parsing file
1002         {
1003             $skip_line = 0;
1004             next;
1005         }
1006         elsif (/ELEMENT_INFO_END/)      # keyword to stop parsing file
1007         {
1008             last;
1009         }
1010         elsif ($skip_line)
1011         {
1012             next;
1013         }
1014
1015         if (/^\s+\{\s*$/)
1016         {
1017             $line_is_element_name = 1;
1018         }
1019         elsif ($line_is_element_name)
1020         {
1021             # process line with element name definition
1022             if (/^\s+\"(.+)\",?\s*$/)
1023             {
1024                 $element_name = 'EL_' . uc($1);
1025
1026                 # dirty hack for making "[default]" work as an element name
1027                 $element_name =~ s/\[//;
1028                 $element_name =~ s/\]//;
1029
1030                 # change '.' to '_' for elements like "dynamite.active"
1031                 $element_name =~ s/\./_/g;
1032             }
1033
1034             $line_is_element_name = 0;
1035             $line_is_element_class = 1;
1036         }
1037         elsif ($line_is_element_class)
1038         {
1039             # process line with element class definition
1040             if (/^\s+\"(.+)\",?\s*$/)
1041             {
1042                 $element_class = 'EL_CLASS_' . uc($1);
1043
1044                 if (!defined($known_element_class{$element_class}))
1045                 {
1046                     $known_element_class{$element_class} = $element_name;
1047                 }
1048
1049                 $known_element_class{$element_name} = $element_class;
1050
1051                 # print STDERR "known_element_class: '$element_name' => '$element_class'\n";
1052             }
1053
1054             $line_is_element_class = 0;
1055         }
1056     }
1057
1058     close FILE;
1059
1060     return %known_element_class;
1061 }
1062
1063 sub get_known_action_definitions
1064 {
1065     my %known_action = ();
1066
1067     my $filename = "$src_path/main.h";
1068
1069     open(FILE, "$filename") ||
1070         fail("cannot open file '$filename' for reading");
1071
1072     while (<FILE>)
1073     {
1074         chomp;                          # cut trailing newline
1075
1076         # process line with action definition
1077         if (/^  ACTION_([A-Z0-9_]+)[, ]/)
1078         {
1079             $known_action{$1} = 1;
1080
1081             # print STDERR "known_action: '$1'\n";
1082         }
1083     }
1084
1085     close FILE;
1086
1087     return %known_action;
1088 }
1089
1090 sub get_known_special_arg_definitions
1091 {
1092     my %known_special_arg = ();
1093
1094     my $filename = "$src_path/main.h";
1095
1096     open(FILE, "$filename") ||
1097         fail("cannot open file '$filename' for reading");
1098
1099     while (<FILE>)
1100     {
1101         chomp;                          # cut trailing newline
1102
1103         # process line with special arg definition
1104         if (/^  GFX_SPECIAL_ARG_([A-Z0-9_]+)[, ]/)
1105         {
1106             if ($1 eq 'CRUMBLED')
1107             {
1108                 next;
1109             }
1110
1111             $known_special_arg{$1} = 1;
1112
1113             # print STDERR "known_special_arg: '$1'\n";
1114         }
1115     }
1116
1117     close FILE;
1118
1119     return %known_special_arg;
1120 }
1121
1122 sub get_known_button_definitions
1123 {
1124     my %known_button = ();
1125
1126     my $filename = "$src_path/conf_gfx.h";
1127
1128     open(FILE, "$filename") ||
1129         fail("cannot open file '$filename' for reading");
1130
1131     while (<FILE>)
1132     {
1133         chomp;                          # cut trailing newline
1134
1135         # process line with button definition
1136         if (/^\#define (IMG_MENU_BUTTON[A-Z0-9_]*)\s/)
1137         {
1138             $known_button{$1} = 1;
1139
1140             # print STDERR "known_button: '$1'\n";
1141         }
1142     }
1143
1144     close FILE;
1145
1146     return %known_button;
1147 }
1148
1149 sub get_known_font_definitions
1150 {
1151     my %known_font = ();
1152
1153     my $filename = "$src_path/main.h";
1154
1155     open(FILE, "$filename") ||
1156         fail("cannot open file '$filename' for reading");
1157
1158     while (<FILE>)
1159     {
1160         chomp;                          # cut trailing newline
1161
1162         # process line with font definition
1163         if (/^  (FONT_[A-Z0-9_]+)[, ]/)
1164         {
1165             $known_font{$1} = 1;
1166
1167             # print STDERR "known_font: '$1'\n";
1168         }
1169     }
1170
1171     close FILE;
1172
1173     return %known_font;
1174 }
1175
1176 sub get_known_sound_prefix_definitions
1177 {
1178     my %known_sound_prefix = ( 'background'     => 1 );
1179
1180     return %known_sound_prefix;
1181 }
1182
1183 sub get_known_music_prefix_definitions
1184 {
1185     my %known_music_prefix = ();
1186
1187     my $filename = "$src_path/main.c";
1188
1189     open(FILE, "$filename") ||
1190         fail("cannot open file '$filename' for reading");
1191
1192     my $prefix_name = '';
1193     my $skip_line = 1;
1194
1195     while (<FILE>)
1196     {
1197         chomp;                          # cut trailing newline
1198
1199         if (/MusicPrefixInfo/)          # keyword to start parsing file
1200         {
1201             $skip_line = 0;
1202             next;
1203         }
1204         elsif (/NULL/ && !$skip_line)   # keyword to stop parsing file
1205         {
1206             last;
1207         }
1208         elsif ($skip_line)
1209         {
1210             next;
1211         }
1212
1213         if (/^\s+{\s+\"(.+)\"/)
1214         {
1215             my $music_prefix = $1;
1216
1217             $known_music_prefix{$music_prefix} = 1;
1218
1219             # printf STDERR "::: known music prefix '$music_prefix'\n";
1220         }
1221     }
1222
1223     close FILE;
1224
1225     return %known_music_prefix;
1226 }
1227
1228 sub print_element_to_graphic_entry
1229 {
1230     my ($element, $action, $direction, $crumbled, $graphic) = @_;
1231
1232     my $num_tabs = 5 - int((length($element) + 4 + 1) / 8);
1233     my $tabs = "\t" x $num_tabs;
1234     if ($tabs eq '')
1235     {
1236         $tabs = ' ';
1237     }
1238
1239     $crumbled = ($crumbled == 1 ? 'TRUE' : 'FALSE');
1240
1241     print "  {\n";
1242     print "    $element,$tabs$action, $direction, $crumbled,\n";
1243     print "    $graphic\n";
1244     print "  },\n";
1245 }
1246
1247 sub print_element_to_special_graphic_entry
1248 {
1249     my ($element, $special, $graphic) = @_;
1250
1251     my $num_tabs = 6 - int((length($element) + 4 + 1) / 8);
1252     my $tabs = "\t" x $num_tabs;
1253     if ($tabs eq '')
1254     {
1255         $tabs = ' ';
1256     }
1257
1258     print "  {\n";
1259     print "    $element,$tabs$special,\n";
1260     print "    $graphic\n";
1261     print "  },\n";
1262 }
1263
1264 sub print_font_to_graphic_entry
1265 {
1266     my ($font, $special, $graphic) = @_;
1267
1268     my $num_tabs = 6 - int((length($font) + 4 + 1) / 8);
1269     my $tabs = "\t" x $num_tabs;
1270     if ($tabs eq '')
1271     {
1272         $tabs = ' ';
1273     }
1274
1275     print "  {\n";
1276     print "    $font,$tabs$special,\n";
1277     print "    $graphic\n";
1278     print "  },\n";
1279 }
1280
1281 sub print_element_to_sound_entry
1282 {
1283     my ($element, $is_class, $action, $sound) = @_;
1284
1285     my $element_plus_is_class = "$element, $is_class";
1286
1287     my $num_tabs = 6 - int((length($element_plus_is_class) + 4 + 1) / 8);
1288     my $tabs = "\t" x $num_tabs;
1289     if ($tabs eq '')
1290     {
1291         $tabs = ' ';
1292     }
1293
1294     print "  {\n";
1295     print "    $element_plus_is_class,$tabs$action,\n";
1296     print "    $sound\n";
1297     print "  },\n";
1298 }
1299
1300 sub print_gamemode_to_sound_entry
1301 {
1302     my ($gamemode, $sound) = @_;
1303
1304     print "  {\n";
1305     print "    $gamemode,\n";
1306     print "    $sound\n";
1307     print "  },\n";
1308 }
1309
1310 sub print_gamemode_to_music_entry
1311 {
1312     my ($gamemode, $music) = @_;
1313
1314     print "  {\n";
1315     print "    $gamemode,\n";
1316     print "    $music\n";
1317     print "  },\n";
1318 }
1319
1320 sub print_image_config_var_entry
1321 {
1322     my ($token, $var) = @_;
1323
1324     print "  {\n";
1325     print "    $token,\n";
1326     print "    $var\n";
1327     print "  },\n";
1328 }
1329
1330 sub print_active_state_entry
1331 {
1332     my ($token, $token_active) = @_;
1333
1334     print "  {\n";
1335     print "    $token,\n";
1336     print "    $token_active\n";
1337     print "  },\n";
1338 }
1339
1340 sub print_element_to_graphic_list
1341 {
1342     my %graphic_without_element =
1343         (
1344          'IMG_FLAMES_1_LEFT'            => 1,
1345          'IMG_FLAMES_2_LEFT'            => 1,
1346          'IMG_FLAMES_3_LEFT'            => 1,
1347          'IMG_FLAMES_1_RIGHT'           => 1,
1348          'IMG_FLAMES_2_RIGHT'           => 1,
1349          'IMG_FLAMES_3_RIGHT'           => 1,
1350          'IMG_FLAMES_1_UP'              => 1,
1351          'IMG_FLAMES_2_UP'              => 1,
1352          'IMG_FLAMES_3_UP'              => 1,
1353          'IMG_FLAMES_1_DOWN'            => 1,
1354          'IMG_FLAMES_2_DOWN'            => 1,
1355          'IMG_FLAMES_3_DOWN'            => 1,
1356          'IMG_TWINKLE_BLUE'             => 1,
1357          'IMG_TWINKLE_WHITE'            => 1,
1358          );
1359
1360     my %additional_mappings =
1361         (
1362          # file elements which are mapped to runtime elements when playing
1363
1364          # 'EL_EM_KEY_1_FILE'           => 'IMG_EM_KEY_1',
1365          # 'EL_EM_KEY_2_FILE'           => 'IMG_EM_KEY_2',
1366          # 'EL_EM_KEY_3_FILE'           => 'IMG_EM_KEY_3',
1367          # 'EL_EM_KEY_4_FILE'           => 'IMG_EM_KEY_4',
1368
1369          # new elements which still have no graphic
1370          # 'EL_DOOR_WHITE',             => 'IMG_CHAR_QUESTION',
1371          # 'EL_DOOR_WHITE_GRAY',        => 'IMG_CHAR_QUESTION',
1372          # 'EL_KEY_WHITE',              => 'IMG_CHAR_QUESTION',
1373          # 'EL_SIGN_RADIOACTIVITY',     => 'IMG_CHAR_QUESTION',
1374          # 'EL_SIGN_WHEELCHAIR',        => 'IMG_CHAR_QUESTION',
1375          # 'EL_SIGN_PARKING',           => 'IMG_CHAR_QUESTION',
1376          # 'EL_SIGN_ONEWAY',            => 'IMG_CHAR_QUESTION',
1377          # 'EL_SIGN_HEART',             => 'IMG_CHAR_QUESTION',
1378          # 'EL_SIGN_TRIANGLE',          => 'IMG_CHAR_QUESTION',
1379          # 'EL_SIGN_ROUND',             => 'IMG_CHAR_QUESTION',
1380          # 'EL_SIGN_EXIT',              => 'IMG_CHAR_QUESTION',
1381          # 'EL_SIGN_YINYANG',           => 'IMG_CHAR_QUESTION',
1382          # 'EL_SIGN_OTHER',             => 'IMG_CHAR_QUESTION',
1383          'EL_SIGN_UNUSED_1',            => 'IMG_CHAR_QUESTION',
1384          'EL_SIGN_UNUSED_2',            => 'IMG_CHAR_QUESTION',
1385          'EL_DX_UNKNOWN_15',            => 'IMG_CHAR_QUESTION',
1386          'EL_DX_UNKNOWN_42',            => 'IMG_CHAR_QUESTION',
1387
1388          # file elements with direction which is not defined
1389          'EL_BD_BUTTERFLY_LEFT'         => 'IMG_BD_BUTTERFLY',
1390          'EL_BD_BUTTERFLY_RIGHT'        => 'IMG_BD_BUTTERFLY',
1391          'EL_BD_BUTTERFLY_UP'           => 'IMG_BD_BUTTERFLY',
1392          'EL_BD_BUTTERFLY_DOWN'         => 'IMG_BD_BUTTERFLY',
1393          'EL_BD_FIREFLY_LEFT'           => 'IMG_BD_FIREFLY',
1394          'EL_BD_FIREFLY_RIGHT'          => 'IMG_BD_FIREFLY',
1395          'EL_BD_FIREFLY_UP'             => 'IMG_BD_FIREFLY',
1396          'EL_BD_FIREFLY_DOWN'           => 'IMG_BD_FIREFLY',
1397          );
1398
1399     my @unknown_graphics = ();
1400     my %known_element     = get_known_element_definitions();
1401     my %known_action      = get_known_action_definitions();
1402     my %known_special_arg = get_known_special_arg_definitions();
1403     my %known_direction =
1404         (
1405          'LEFT'         => 1,
1406          'RIGHT'        => 1,
1407          'UP'           => 1,
1408          'DOWN'         => 1,
1409          'UPLEFT'       => 1,
1410          'UPRIGHT'      => 1,
1411          'DOWNLEFT'     => 1,
1412          'DOWNRIGHT'    => 1,
1413          );
1414
1415     # ---------- read graphic file definitions ----------
1416
1417     my $filename = "$src_path/conf_gfx.c";
1418
1419     print_file_header($filename_conf_e2g_c, $text_e2g_c);
1420
1421     open(FILE, "$filename") ||
1422         fail("cannot open file '$filename' for reading");
1423
1424     print "static struct\n";
1425     print "{\n";
1426     print "  int element;\n";
1427     print "  int action;\n";
1428     print "  int direction;\n";
1429     print "  boolean crumbled;\n";
1430     print "\n";
1431     print "  int graphic;\n";
1432     print "}\n";
1433     print "element_to_graphic[] =\n";
1434     print "{\n";
1435
1436     while (<FILE>)
1437     {
1438         chomp;                          # cut trailing newline
1439
1440         if (/NO_MORE_ELEMENT_IMAGES/)   # keyword to stop parsing file
1441         {
1442             last;
1443         }
1444
1445         if (!contains_image_file($_))   # skip all lines without image file
1446         {
1447             next;
1448         }
1449
1450         s/^  \{ \"//;                   # cut all leading ...
1451         s/\",.*$//;                     # ... and trailing garbage
1452
1453         s/\[(\d+)\]/_$1/;               # convert "[1]" to "_1" etc.
1454
1455         s/\[//;                         # dirty hack for making "[default]" ...
1456         s/\]//;                         # ... work as an element name
1457
1458         my $token = $_;
1459
1460         if ($token =~ /\.([^\.]+)$/ && defined($known_special_arg{$1}))
1461         {
1462             next;                       # skip all special definitions
1463         }
1464
1465         $token = uc($token);            # convert all characters to upper case
1466
1467         my $gfx_action_default = '-1';
1468         my $gfx_action = $gfx_action_default;
1469
1470         my $gfx_direction_default = '-1';
1471         my $gfx_direction = $gfx_direction_default;
1472
1473         my $gfx_crumbled = '0';
1474
1475         my $object = $token;
1476         my $action = '';
1477         my $direction = '';
1478         my $crumbled = '';
1479
1480         if ($object =~ /^(.*)\.([A-Z0-9]+)$/ && $2 eq 'CRUMBLED')
1481         {
1482             $object = $1;
1483             $crumbled = $2;
1484
1485             $gfx_crumbled = '1';
1486         }
1487
1488         if ($object =~ /^(.*)\.([A-Z0-9]+)$/ && defined($known_direction{$2}))
1489         {
1490             $object = $1;
1491             $direction = $2;
1492
1493             $gfx_direction = "MV_BIT_$direction";
1494             $gfx_direction_default = $gfx_direction;
1495         }
1496
1497         if ($object =~ /^(.*)\.([A-Z0-9_]+)$/ && defined($known_action{$2}))
1498         {
1499             $object = $1;
1500             $action = $2;
1501
1502             $gfx_action = "ACTION_$action";
1503             $gfx_action_default = $gfx_action;
1504         }
1505
1506         $token =~ s/\./_/g;
1507         $object =~ s/\./_/g;    # needed for "invisible_sand.active.digging"
1508
1509         # print STDERR "'$token' => '$object', '$action', '$direction'\n";
1510
1511         my $full_element = "EL_$token";
1512         my $base_element = "EL_$object";
1513
1514         my $element = $base_element;
1515         my $graphic = "IMG_$token";
1516
1517         my $element_without_crumbled = $full_element;
1518         $element_without_crumbled =~ s/_$crumbled$//;
1519
1520         my $element_without_direction = $element_without_crumbled;
1521         $element_without_direction =~ s/_$direction$//;
1522
1523         my $element_without_action = $element_without_direction;
1524         $element_without_action =~ s/_$action$//;
1525
1526         if (defined($known_element{$full_element}))
1527         {
1528             $element = $full_element;
1529
1530             $gfx_action_default = '-1';
1531             $gfx_direction_default = '-1';
1532         }
1533
1534         if ($element_without_action eq $element || $action eq '')
1535         {
1536             $element_without_action = '';
1537         }
1538
1539         if ($element_without_direction eq $element || $direction eq '')
1540         {
1541             $element_without_direction = '';
1542         }
1543
1544         if ($element_without_crumbled eq $element || $crumbled eq '')
1545         {
1546             $element_without_crumbled = '';
1547         }
1548
1549         if (defined($graphic_without_element{$graphic}))
1550         {
1551             next;
1552         }
1553
1554         if (!defined($known_element{$element}))
1555         {
1556             # print STDERR "----- ERROR: unknown element '$element' -----\n";
1557
1558             push @unknown_graphics, $graphic;
1559
1560             next;
1561         }
1562
1563         if (defined($known_element{$element}))
1564         {
1565             print_element_to_graphic_entry($element,
1566                                            $gfx_action_default,
1567                                            $gfx_direction_default,
1568                                            $gfx_crumbled,
1569                                            $graphic);
1570         }
1571
1572         if (defined($known_element{$element_without_action}))
1573         {
1574             print_element_to_graphic_entry($element_without_action,
1575                                            $gfx_action,
1576                                            $gfx_direction,
1577                                            $gfx_crumbled,
1578                                            $graphic);
1579         }
1580
1581         if (defined($known_element{$element_without_direction}))
1582         {
1583             print_element_to_graphic_entry($element_without_direction,
1584                                            '-1',
1585                                            $gfx_direction,
1586                                            $gfx_crumbled,
1587                                            $graphic);
1588         }
1589
1590         if (defined($known_element{$element_without_crumbled}))
1591         {
1592             print_element_to_graphic_entry($element_without_crumbled,
1593                                            '-1',
1594                                            '-1',
1595                                            $gfx_crumbled,
1596                                            $graphic);
1597         }
1598     }
1599
1600     # dump list of additional elements
1601     foreach my $element (sort keys %additional_mappings)
1602     {
1603         print_element_to_graphic_entry($element, '-1', '-1', '-1',
1604                                        $additional_mappings{$element});
1605     }
1606
1607     # dump list of character elements
1608     foreach my $char (@chars)
1609     {
1610         my $element = "EL_CHAR_$char";
1611         my $graphic = "IMG_CHAR_$char";
1612
1613         if ($char ne $char_skip)
1614         {
1615             print_element_to_graphic_entry($element, '-1', '-1', '-1',$graphic);
1616         }
1617     }
1618     foreach my $char (@chars)
1619     {
1620         my $element = "EL_STEEL_CHAR_$char";
1621         my $graphic = "IMG_STEEL_CHAR_$char";
1622
1623         if ($char ne $char_skip)
1624         {
1625             print_element_to_graphic_entry($element, '-1', '-1', '-1',$graphic);
1626         }
1627     }
1628
1629     # dump list of custom elements
1630     for (my $i = 0; $i < $num_custom_elements; $i++)
1631     {
1632         my $element = sprintf("EL_CUSTOM_%d", $i + 1);
1633         my $graphic = sprintf("IMG_CUSTOM_%d", $i + 1);
1634
1635         print_element_to_graphic_entry($element, '-1', '-1', '-1', $graphic);
1636     }
1637
1638     # dump list of group elements
1639     for (my $i = 0; $i < $num_group_elements; $i++)
1640     {
1641         my $element = sprintf("EL_GROUP_%d", $i + 1);
1642         my $graphic = sprintf("IMG_GROUP_%d", $i + 1);
1643
1644         print_element_to_graphic_entry($element, '-1', '-1', '-1', $graphic);
1645     }
1646
1647     print_element_to_graphic_entry('-1', '-1', '-1', '-1', '-1');
1648
1649     print "};\n";
1650
1651     close FILE;
1652
1653     if (scalar(@unknown_graphics) > 0)
1654     {
1655         print STDERR "-" x 79 . "\n";
1656         print STDERR "The following graphics cannot be associated with any element:\n";
1657
1658         foreach my $graphic (@unknown_graphics)
1659         {
1660             print STDERR "- $graphic\n";
1661         }
1662
1663         print STDERR "-" x 79 . "\n";
1664     }
1665
1666     print_file_footer($filename_conf_e2g_c);
1667 }
1668
1669 sub print_element_to_special_graphic_list
1670 {
1671     my %graphic_without_element =
1672         (
1673          'IMG_GLOBAL_DOOR'              => 1,
1674          );
1675
1676     my %additional_mappings =
1677         (
1678          # old elements which are mapped to other elements when playing
1679          #'EL_BUG'                      => 'IMG_BUG_RIGHT',
1680          #'EL_SPACESHIP'                => 'IMG_SPACESHIP_RIGHT',
1681          #'EL_PACMAN'                   => 'IMG_PACMAN_RIGHT',
1682          );
1683
1684     my @elements_with_editor_graphic =
1685         (
1686          'char_space'
1687          );
1688
1689     my @unknown_graphics = ();
1690     my %known_element     = get_known_element_definitions();
1691     my %known_special_arg = get_known_special_arg_definitions();
1692
1693     # ---------- read graphic file definitions ----------
1694
1695     my $filename = "$src_path/conf_gfx.c";
1696
1697     print_file_header($filename_conf_esg_c, $text_esg_c);
1698
1699     open(FILE, "$filename") ||
1700         fail("cannot open file '$filename' for reading");
1701
1702     print "static struct\n";
1703     print "{\n";
1704     print "  int element;\n";
1705     print "  int special;\n";
1706     print "\n";
1707     print "  int graphic;\n";
1708     print "}\n";
1709     print "element_to_special_graphic[] =\n";
1710     print "{\n";
1711
1712     while (<FILE>)
1713     {
1714         chomp;                          # cut trailing newline
1715
1716         if (/NO_MORE_ELEMENT_IMAGES/)   # keyword to stop parsing file
1717         {
1718             last;
1719         }
1720
1721         if (!contains_image_file($_))   # skip all lines without image file
1722         {
1723             next;
1724         }
1725
1726         s/^  \{ \"//;                   # cut all leading ...
1727         s/\",.*$//;                     # ... and trailing garbage
1728
1729         my $token = $_;
1730         my $object;
1731         my $special;
1732
1733         if ($token =~ /^font\./)        # skip all font definitions
1734         {
1735             next;
1736         }
1737
1738         if ($token =~ /^background\./)  # skip all background image definitions
1739         {
1740             next;
1741         }
1742
1743         if ($token =~ /^(.*)\.([^\.]+)$/ &&
1744             defined($known_special_arg{$2}))
1745         {
1746             $object = $1;
1747             $special = "GFX_SPECIAL_ARG_" . $2;
1748         }
1749         else
1750         {
1751             next;                       # skip all default definitions
1752         }
1753
1754         $token  =~ s/(.*)/uc($1)/eg;    # convert all characters to upper case
1755         $object =~ s/(.*)/uc($1)/eg;    # convert all characters to upper case
1756
1757         $token  =~ s/\./_/g;
1758         $object =~ s/\./_/g;
1759
1760         # print STDERR "'$token' => '$object'\n";
1761
1762         my $element = "EL_$object";
1763         my $graphic = "IMG_$token";
1764
1765         if (defined($graphic_without_element{$graphic}))
1766         {
1767             next;
1768         }
1769
1770         if (!defined($known_element{$element}))
1771         {
1772             # print STDERR "----- ERROR: unknown element '$element' -----\n";
1773
1774             push @unknown_graphics, $graphic;
1775
1776             next;
1777         }
1778
1779         print_element_to_special_graphic_entry($element,
1780                                                $special,
1781                                                $graphic);
1782     }
1783
1784     # dump list of additional elements
1785     foreach my $element (sort keys %additional_mappings)
1786     {
1787         print_element_to_special_graphic_entry($element,
1788                                                'GFX_SPECIAL_ARG_EDITOR',
1789                                                $additional_mappings{$element});
1790         print_element_to_special_graphic_entry($element,
1791                                                'GFX_SPECIAL_ARG_PREVIEW',
1792                                                $additional_mappings{$element});
1793     }
1794
1795     # dump list of custom element editor graphics
1796     for (my $i = 0; $i < $num_custom_elements; $i++)
1797     {
1798         my $element = sprintf("EL_CUSTOM_%d", $i + 1);
1799         my $graphic = sprintf("IMG_CUSTOM_%d_EDITOR", $i + 1);
1800
1801         print_element_to_special_graphic_entry($element,
1802                                                'GFX_SPECIAL_ARG_EDITOR',
1803                                                $graphic);
1804     }
1805
1806     # dump list of group element editor graphics
1807     for (my $i = 0; $i < $num_group_elements; $i++)
1808     {
1809         my $element = sprintf("EL_GROUP_%d", $i + 1);
1810         my $graphic = sprintf("IMG_GROUP_%d_EDITOR", $i + 1);
1811
1812         print_element_to_special_graphic_entry($element,
1813                                                'GFX_SPECIAL_ARG_EDITOR',
1814                                                $graphic);
1815     }
1816
1817     # dump other special editor graphics
1818     foreach my $token (@elements_with_editor_graphic)
1819     {
1820         my $element = 'EL_'  . uc($token);
1821         my $graphic = 'IMG_' . uc($token) . '_EDITOR';
1822
1823         print_element_to_special_graphic_entry($element,
1824                                                'GFX_SPECIAL_ARG_EDITOR',
1825                                                $graphic);
1826     }
1827
1828     print_element_to_special_graphic_entry('-1', '-1', '-1');
1829
1830     print "};\n";
1831
1832     close FILE;
1833
1834     if (scalar(@unknown_graphics) > 0)
1835     {
1836         print STDERR "-" x 79 . "\n";
1837         print STDERR "The following graphics cannot be associated with any element:\n";
1838
1839         foreach my $graphic (@unknown_graphics)
1840         {
1841             print STDERR "- $graphic\n";
1842         }
1843
1844         print STDERR "-" x 79 . "\n";
1845     }
1846
1847     print_file_footer($filename_conf_esg_c);
1848 }
1849
1850 sub print_element_to_sound_list
1851 {
1852     my %sound_without_action =
1853         (
1854          'SND_AMOEBA_TURNING_TO_GEM'            => 1,
1855          'SND_AMOEBA_TURNING_TO_ROCK'           => 1,
1856          'SND_BD_AMOEBA_TURNING_TO_GEM'         => 1,
1857          'SND_BD_AMOEBA_TURNING_TO_ROCK'        => 1,
1858
1859          # no special case anymore after adding action ".splashing"
1860          # 'SND_ACID_SPLASHING'                 => 1,
1861          );
1862
1863     my @unknown_sounds = ();
1864     my %known_element       = get_known_element_definitions();
1865     my %known_element_class = get_known_element_class_definitions();
1866     my %known_action        = get_known_action_definitions();
1867
1868     # ---------- read sound file definitions ----------
1869
1870     my $filename = "$src_path/conf_snd.c";
1871
1872     print_file_header($filename_conf_e2s_c, $text_e2s_c);
1873
1874     open(FILE, "$filename") ||
1875         fail("cannot open file '$filename' for reading");
1876
1877     print "static struct\n";
1878     print "{\n";
1879     print "  int element;\n";
1880     print "  boolean is_class;\n";
1881     print "  int action;\n";
1882     print "\n";
1883     print "  int sound;\n";
1884     print "}\n";
1885     print "element_to_sound[] =\n";
1886     print "{\n";
1887
1888     while (<FILE>)
1889     {
1890         chomp;                          # cut trailing newline
1891
1892         if (/NO_MORE_ELEMENT_SOUNDS/)   # keyword to stop parsing file
1893         {
1894             last;
1895         }
1896
1897         if (!contains_sound_file($_))   # skip all lines without sound file
1898         {
1899             next;
1900         }
1901
1902         s/^  \{ \"//;                   # cut all leading ...
1903         s/\",.*$//;                     # ... and trailing garbage
1904
1905         my $token = $_;
1906
1907         $token = uc($token);            # convert all characters to upper case
1908
1909         my $snd_action_default = '-1';
1910         my $snd_action = $snd_action_default;
1911
1912         my $object = $token;
1913         my $action = '';
1914
1915         if ($object =~ /^(.*)\.([A-Z0-9_]+)$/ && defined($known_action{$2}))
1916         {
1917             $object = $1;
1918             $action = $2;
1919
1920             $snd_action = "ACTION_$action";
1921             $snd_action_default = $snd_action;
1922         }
1923
1924         $token =~ s/\./_/g;
1925         $object =~ s/\./_/g;    # needed for "invisible_sand.active.digging"
1926
1927         if ($object =~ /^\[(.+)\]$/)
1928         {
1929             $object = 'CLASS_' . $1;
1930         }
1931
1932         # print STDERR "'$token' => '$object', '$action'\n";
1933
1934         my $full_element = "EL_$token";
1935         my $base_element = "EL_$object";
1936
1937         my $element = $base_element;
1938         my $sound = $token;
1939
1940         if ($sound =~ /^\[.+\]/)
1941         {
1942             $sound =~ s/\[//;           # element class sound; begin ...
1943             $sound =~ s/\]//;           # ... and end of definition token
1944             $sound =~ s/^/CLASS_/;      # add class identifier
1945         }
1946
1947         $sound = "SND_$sound";
1948
1949         my $element_without_action = $full_element;
1950         $element_without_action =~ s/_$action$//;
1951
1952         my $element_class_without_action = $full_element;
1953         $element_without_action =~ s/_$action$//;
1954
1955         if (defined($known_element_class{$full_element}))
1956         {
1957             $element = $full_element;
1958
1959             $snd_action_default = '-1';
1960         }
1961
1962         if ($element_without_action eq $element || $action eq '')
1963         {
1964             $element_without_action = '';
1965         }
1966
1967         if (defined($sound_without_action{$sound}))
1968         {
1969             next;
1970         }
1971
1972         if (!defined($known_element{$element}) &&
1973             !defined($known_element_class{$element}))
1974         {
1975             # print STDERR "----- ERROR: unknown element '$element' -----\n";
1976
1977             push @unknown_sounds, $sound;
1978
1979             next;
1980         }
1981
1982         if (!($element =~ /_CLASS_/) &&
1983             defined($known_element{$element}))
1984         {
1985             print_element_to_sound_entry($element, "FALSE",
1986                                          $snd_action_default,
1987                                          $sound);
1988         }
1989
1990         if (!($element =~ /_CLASS_/) &&
1991             defined($known_element{$element_without_action}))
1992         {
1993             print_element_to_sound_entry($element_without_action, "FALSE",
1994                                          $snd_action,
1995                                          $sound);
1996         }
1997
1998         if ($element =~ /_CLASS_/ &&
1999             defined($known_element_class{$element}))
2000         {
2001             my $class_element = $known_element_class{$element};
2002
2003             print_element_to_sound_entry($class_element, "TRUE",
2004                                          $snd_action_default,
2005                                          $sound);
2006         }
2007
2008         if ($element =~ /_CLASS_/ &&
2009             defined($known_element_class{$element_without_action}))
2010         {
2011             my $class_element = $known_element_class{$element_without_action};
2012
2013             print_element_to_sound_entry($class_element, "TRUE",
2014                                          $snd_action,
2015                                          $sound);
2016         }
2017     }
2018
2019     print_element_to_sound_entry('-1', '-1', '-1', '-1');
2020
2021     print "};\n";
2022
2023     close FILE;
2024
2025     if (scalar(@unknown_sounds) > 0)
2026     {
2027         print STDERR "-" x 79 . "\n";
2028         print STDERR "The following sounds cannot be associated with any element or element class:\n";
2029
2030         foreach my $sound (@unknown_sounds)
2031         {
2032             print STDERR "- $sound\n";
2033         }
2034
2035         print STDERR "-" x 79 . "\n";
2036     }
2037
2038     print_file_footer($filename_conf_e2s_c);
2039 }
2040
2041 sub print_font_to_graphic_list
2042 {
2043     my @unknown_graphics = ();
2044     my %known_font        = get_known_font_definitions();
2045     my %known_special_arg = get_known_special_arg_definitions();
2046
2047     # ---------- read graphic file definitions ----------
2048
2049     my $filename = "$src_path/conf_gfx.c";
2050
2051     print_file_header($filename_conf_fnt_c, $text_fnt_c);
2052
2053     open(FILE, "$filename") ||
2054         fail("cannot open file '$filename' for reading");
2055
2056     print "static struct\n";
2057     print "{\n";
2058     print "  int font_nr;\n";
2059     print "  int special;\n";
2060     print "\n";
2061     print "  int graphic;\n";
2062     print "}\n";
2063     print "font_to_graphic[] =\n";
2064     print "{\n";
2065
2066     while (<FILE>)
2067     {
2068         chomp;                          # cut trailing newline
2069
2070         if (!contains_image_file($_))   # skip all lines without image file
2071         {
2072             next;
2073         }
2074
2075         s/^  \{ \"//;                   # cut all leading ...
2076         s/\",.*$//;                     # ... and trailing garbage
2077
2078         my $token = $_;
2079         my $font;
2080         my $special;
2081         my $graphic;
2082
2083         if ($token =~ /^(font\..*)$/)
2084         {
2085             $font = $token;
2086             $special = '-1';
2087
2088             if ($token =~ /^(.*)\.([^\.]+)$/ &&
2089                 defined($known_special_arg{$2}))
2090             {
2091                 $font = $1;
2092                 $special = "GFX_SPECIAL_ARG_" . $2;
2093             }
2094         }
2095         else
2096         {
2097             next;                       # skip all non-font definitions
2098         }
2099
2100         $token =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2101         $font  =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2102
2103         $token =~ s/\./_/g;
2104         $font  =~ s/\./_/g;
2105
2106         # print STDERR "'$token' => '$font'\n";
2107
2108         $graphic = "IMG_$token";
2109
2110         if (!defined($known_font{$font}))
2111         {
2112             # print STDERR "----- ERROR: unknown font '$font' -----\n";
2113
2114             push @unknown_graphics, $graphic;
2115
2116             next;
2117         }
2118
2119         print_font_to_graphic_entry($font,
2120                                     $special,
2121                                     $graphic);
2122     }
2123
2124     print_font_to_graphic_entry('-1', '-1', '-1');
2125
2126     print "};\n";
2127
2128     close FILE;
2129
2130     if (scalar(@unknown_graphics) > 0)
2131     {
2132         print STDERR "-" x 79 . "\n";
2133         print STDERR "The following graphics cannot be associated with any font:\n";
2134
2135         foreach my $graphic (@unknown_graphics)
2136         {
2137             print STDERR "- $graphic\n";
2138         }
2139
2140         print STDERR "-" x 79 . "\n";
2141     }
2142
2143     print_file_footer($filename_conf_fnt_c);
2144 }
2145
2146 sub print_gamemode_to_sound_list
2147 {
2148     my %known_prefix = get_known_sound_prefix_definitions();
2149     my %known_special_arg = get_known_special_arg_definitions();
2150
2151     # ---------- read music file definitions ----------
2152
2153     my $filename = "$src_path/conf_snd.c";
2154
2155     print_file_header($filename_conf_g2s_c, $text_g2s_c);
2156
2157     open(FILE, "$filename") ||
2158         fail("cannot open file '$filename' for reading");
2159
2160     print "static struct\n";
2161     print "{\n";
2162     print "  int gamemode;\n";
2163     print "\n";
2164     print "  int sound;\n";
2165     print "}\n";
2166     print "gamemode_to_sound[] =\n";
2167     print "{\n";
2168
2169     while (<FILE>)
2170     {
2171         chomp;                          # cut trailing newline
2172
2173         if (!contains_sound_file($_))   # skip all lines without sound file
2174         {
2175             next;
2176         }
2177
2178         if (/\[not used\]/)
2179         {
2180             next;
2181         }
2182
2183         s/^  \{ \"//;                   # cut all leading ...
2184         s/\",.*$//;                     # ... and trailing garbage
2185
2186         my $token = $_;
2187         my $gamemode = -1;
2188         # my $level = -1;               # ???
2189
2190         if (defined($known_prefix{$token}))
2191         {
2192             # no special arg defined
2193         }
2194         elsif ($token =~ /^(.*)\.([^\.]+)$/ &&
2195                defined($known_prefix{$1}) &&
2196                defined($known_special_arg{$2}))
2197         {
2198             $gamemode = "GFX_SPECIAL_ARG_" . $2;
2199         }
2200         else
2201         {
2202             next;
2203         }
2204
2205 #       if ($token =~ /^(.*)\./ &&
2206 #           !defined($known_prefix{$1}))
2207 #       {
2208 #           next;
2209 #       }
2210 #
2211 #       if ($token =~ /^(.*)\.([^\.]+)$/ &&
2212 #           defined($known_special_arg{$2}))
2213 #       {
2214 #           $gamemode = "GFX_SPECIAL_ARG_" . $2;
2215 #       }
2216
2217         $token =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2218         $token =~ s/\./_/g;
2219
2220         my $sound = "SND_$token";
2221
2222         # print STDERR "'$token' => '$sound'\n";
2223
2224         print_gamemode_to_sound_entry($gamemode, $sound);
2225     }
2226
2227     print_gamemode_to_sound_entry('-1', '-1');
2228
2229     print "};\n";
2230
2231     close FILE;
2232
2233     print_file_footer($filename_conf_g2s_c);
2234 }
2235
2236 sub print_gamemode_to_music_list
2237 {
2238     my %known_prefix = get_known_music_prefix_definitions();
2239     my %known_special_arg = get_known_special_arg_definitions();
2240
2241     # ---------- read music file definitions ----------
2242
2243     my $filename = "$src_path/conf_mus.c";
2244
2245     print_file_header($filename_conf_g2m_c, $text_g2m_c);
2246
2247     open(FILE, "$filename") ||
2248         fail("cannot open file '$filename' for reading");
2249
2250     print "static struct\n";
2251     print "{\n";
2252     print "  int gamemode;\n";
2253     print "\n";
2254     print "  int music;\n";
2255     print "}\n";
2256     print "gamemode_to_music[] =\n";
2257     print "{\n";
2258
2259     while (<FILE>)
2260     {
2261         chomp;                          # cut trailing newline
2262
2263         if (!contains_music_file($_))   # skip all lines without music file
2264         {
2265             next;
2266         }
2267
2268         s/^  \{ \"//;                   # cut all leading ...
2269         s/\",.*$//;                     # ... and trailing garbage
2270
2271         my $token = $_;
2272         my $gamemode = -1;
2273
2274         if (defined($known_prefix{$token}))
2275         {
2276             # no special arg defined
2277         }
2278         elsif ($token =~ /^(.*)\.([^\.]+)$/ &&
2279                defined($known_prefix{$1}) &&
2280                defined($known_special_arg{$2}))
2281         {
2282             $gamemode = "GFX_SPECIAL_ARG_" . $2;
2283         }
2284         else
2285         {
2286             next;
2287         }
2288
2289 #       my $prefix = $token;
2290 #       $prefix =~ s/\..*$//;
2291 #
2292 ##      if ($token =~ /^(.*)\./ &&
2293 ##          !defined($known_prefix{$1}))
2294 #       if (!defined($known_prefix{$prefix}))
2295 #       {
2296 #           next;
2297 #       }
2298 #
2299 #       if ($token =~ /^(.*)\.([^\.]+)$/ &&
2300 #           defined($known_special_arg{$2}))
2301 #       {
2302 #           $gamemode = "GFX_SPECIAL_ARG_" . $2;
2303 #       }
2304
2305         $token =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2306         $token =~ s/\./_/g;
2307
2308         my $music = "MUS_$token";
2309
2310         # print STDERR "'$token' => '$music'\n";
2311
2312         print_gamemode_to_music_entry($gamemode, $music);
2313     }
2314
2315     print_gamemode_to_music_entry('-1', '-1');
2316
2317     print "};\n";
2318
2319     close FILE;
2320
2321     print_file_footer($filename_conf_g2m_c);
2322 }
2323
2324 sub print_image_config_vars
2325 {
2326     # ---------- read graphic file definitions ----------
2327
2328     my $filename = "$src_path/conf_gfx.c";
2329
2330     print_file_header($filename_conf_var_c, $text_var_c);
2331
2332     open(FILE, "$filename") ||
2333         fail("cannot open file '$filename' for reading");
2334
2335     print "struct TokenIntPtrInfo image_config_vars[] =\n";
2336     print "{\n";
2337
2338     my $start_parsing = 0;
2339
2340     while (<FILE>)
2341     {
2342         chomp;                          # cut trailing newline
2343
2344         if (/CONFIG_VARS_START/)        # keyword to start parsing file
2345         {
2346             $start_parsing = 1;
2347         }
2348
2349         if (!$start_parsing)
2350         {
2351             next;
2352         }
2353
2354         if (/^\s*\{\s*\"([^\"]+)\"/)    # config token found
2355         {
2356             my $token = $1;
2357             my $var = $token;
2358
2359             # --- some prefix replacements ---
2360
2361             $var =~ s/^main\./menu.main./;
2362             $var =~ s/^\[player\]\./game.player_/;
2363             $var =~ s/^\[title_initial\]/title_initial_default/;
2364             $var =~ s/^\[title\]/title_default/;
2365             $var =~ s/^\[titlescreen_initial\]/titlescreen_initial_default/;
2366             $var =~ s/^\[titlescreen\]/titlescreen_default/;
2367             $var =~ s/^\[titlemessage_initial\]/titlemessage_initial_default/;
2368             $var =~ s/^\[titlemessage\]/titlemessage_default/;
2369
2370             if ($var =~ /^titlescreen.*(\d)/ ||
2371                 $var =~ /^titlemessage.*(\d)/ ||
2372                 $var =~ /^game.panel.key_(\d)/ ||
2373                 $var =~ /^game.panel.inventory_first_(\d)/ ||
2374                 $var =~ /^game.panel.inventory_last_(\d)/ ||
2375                 $var =~ /^game.panel.conveyor_belt_(\d)\./ ||
2376                 $var =~ /^game.panel.element_(\d)\./ ||
2377                 $var =~ /^game.panel.graphic_(\d)\./ ||
2378                 $var =~ /^game.panel.ce_score_(\d)\./)
2379             {
2380                 my $number = $1;
2381                 my $array_pos = int($number) - 1;
2382                 $var =~ s/_$number/\[$array_pos\]/;
2383             }
2384             elsif ($var =~ /^game.panel.conveyor_belt_(\d)(_switch)/ ||
2385                    $var =~ /^game.panel.element_(\d)(_count)/ ||
2386                    $var =~ /^game.panel.ce_score_(\d)(_element)/)
2387             {
2388                 my $number = $1;
2389                 my $suffix = $2;
2390                 my $array_pos = int($number) - 1;
2391                 $var =~ s/_$number$suffix/$suffix\[$array_pos\]/;
2392             }
2393
2394             # --- some suffix replacements ---
2395
2396             $var =~ s/^(menu\.main\..*)\.chars$/$1.size/;
2397             $var =~ s/^(tape\.text\..*)\.chars$/$1.size/;
2398             $var =~ s/^(game\.panel\..*)\.chars$/$1.size/;
2399             $var =~ s/^(game\.panel\..*)\.tile_size$/$1.size/;
2400             $var =~ s/^(request\.button\..*)\.tile_size$/$1.size/;
2401             $var =~ s/\.digits$/.size/;
2402             $var =~ s/\.2nd_offset$/.offset2/;
2403             $var =~ s/\.2nd_xoffset$/.xoffset2/;
2404             $var =~ s/\.2nd_yoffset$/.yoffset2/;
2405             $var =~ s/\.element$/.id/;
2406             $var =~ s/\.draw_order$/.sort_priority/;
2407
2408             $var =~ s/\.font_[a-z]+$/.font_alt/;
2409             $var =~ s/\.INFO\[([A-Z]+)\](.*)$/_info\[GFX_SPECIAL_ARG_INFO_$1\]$2/;
2410             $var =~ s/\.SETUP\[([A-Z0-9_]+)\](.*)$/_setup\[GFX_SPECIAL_ARG_SETUP_$1\]$2/;
2411             $var =~ s/\.([A-Z]+)$/\[GFX_SPECIAL_ARG_$1\]/;
2412             $var =~ s/\.([A-Z]+)\./\[GFX_SPECIAL_ARG_$1\]./;
2413
2414             if ($var =~ /^(menu.(enter|leave|next)_screen)(.[a-z_]+)$/)
2415             {
2416                 $var = $1 . "[GFX_SPECIAL_ARG_DEFAULT]" . $3;
2417             }
2418
2419             if ($var =~ /^menu.(draw_[xy]offset|list_size)$/)
2420             {
2421                 $var .= "[GFX_SPECIAL_ARG_DEFAULT]";
2422             }
2423
2424             if ($var =~ /^(viewport.(window|playfield|door_[12]))(.[a-z_]+)$/)
2425             {
2426                 $var = $1 . "[GFX_SPECIAL_ARG_DEFAULT]" . $3;
2427             }
2428
2429             print_image_config_var_entry("\"$token\"", "&$var");
2430
2431             if ($var =~ /^(title)_default/ ||
2432                 $var =~ /^(title_initial)_default/ ||
2433                 $var =~ /^(titlescreen.*)\[\d\]/ ||
2434                 $var =~ /^(titlemessage.*)\[\d\]/)
2435             {
2436                 my $prefix = $1;
2437                 $var =~ s/^$prefix/${prefix}_first/;
2438
2439                 print_image_config_var_entry("\"$token\"", "&$var");
2440             }
2441         }
2442     }
2443
2444     print_image_config_var_entry('NULL', 'NULL');
2445
2446     print "};\n";
2447
2448     close FILE;
2449
2450     print_file_footer($filename_conf_var_c);
2451 }
2452
2453 sub print_active_states
2454 {
2455     # ---------- read graphic file definitions ----------
2456
2457     my %known_element = get_known_element_definitions();
2458     my %known_button  = get_known_button_definitions();
2459     my %known_font    = get_known_font_definitions();
2460
2461     print_file_header($filename_conf_act_c, $text_act_c);
2462
2463     print "static struct\n";
2464     print "{\n";
2465     print "  int element;\n";
2466     print "  int element_active;\n";
2467     print "}\n";
2468     print "element_with_active_state[] =\n";
2469     print "{\n";
2470
2471     foreach my $element (sort keys %known_element)
2472     {
2473         my $element_active = $element . '_ACTIVE';
2474
2475         if (defined($known_element{$element_active}))
2476         {
2477             print_active_state_entry($element, $element_active);
2478         }
2479     }
2480
2481     print_active_state_entry('-1', '-1');
2482
2483     print "};\n";
2484
2485     print "\n";
2486     print "\n";
2487     print "static struct\n";
2488     print "{\n";
2489     print "  int button;\n";
2490     print "  int button_active;\n";
2491     print "}\n";
2492     print "button_with_active_state[] =\n";
2493     print "{\n";
2494
2495     foreach my $button (sort keys %known_button)
2496     {
2497         my $button_active = $button . '_ACTIVE';
2498
2499         if (defined($known_button{$button_active}))
2500         {
2501             print_active_state_entry($button, $button_active);
2502         }
2503     }
2504
2505     print_active_state_entry('-1', '-1');
2506
2507     print "};\n";
2508
2509     print "\n";
2510     print "\n";
2511     print "static struct\n";
2512     print "{\n";
2513     print "  int font_nr;\n";
2514     print "  int font_nr_active;\n";
2515     print "}\n";
2516     print "font_with_active_state[] =\n";
2517     print "{\n";
2518
2519     foreach my $font (sort keys %known_font)
2520     {
2521         my $font_active = $font . '_ACTIVE';
2522
2523         if (defined($known_font{$font_active}))
2524         {
2525             print_active_state_entry($font, $font_active);
2526         }
2527     }
2528
2529     print_active_state_entry('-1', '-1');
2530
2531     print "};\n";
2532
2533     print_file_footer($filename_conf_act_c);
2534 }
2535
2536
2537 # =============================================================================
2538 # M A I N - P R O G R A M
2539 # =============================================================================
2540
2541 sub main
2542 {
2543     my $argc = scalar(@ARGV);
2544
2545     if ($argc == 0 || $ARGV[0] eq '-h' || $ARGV[0] eq '--help')
2546     {
2547         print "Usage: $0 <file>\n\n";
2548         print "Choose <file> from the following list:\n";
2549         print "- '$filename_conf_gfx_h'\n";
2550         print "- '$filename_conf_snd_h'\n";
2551         print "- '$filename_conf_mus_h'\n";
2552         print "- '$filename_conf_chr_c'\n";
2553         print "- '$filename_conf_chr_h'\n";
2554         print "- '$filename_conf_cus_c'\n";
2555         print "- '$filename_conf_cus_h'\n";
2556         print "- '$filename_conf_grp_c'\n";
2557         print "- '$filename_conf_grp_h'\n";
2558         print "- '$filename_conf_e2g_c'\n";
2559         print "- '$filename_conf_esg_c'\n";
2560         print "- '$filename_conf_fnt_c'\n";
2561         print "- '$filename_conf_g2s_c'\n";
2562         print "- '$filename_conf_g2m_c'\n";
2563         print "- '$filename_conf_var_c'\n";
2564         print "- '$filename_conf_act_c'\n";
2565
2566         exit 1;
2567     }
2568
2569     if ($ARGV[0] eq $filename_conf_gfx_h)
2570     {
2571         print_graphics_list();
2572     }
2573     elsif ($ARGV[0] eq $filename_conf_snd_h)
2574     {
2575         print_sounds_list();
2576     }
2577     elsif ($ARGV[0] eq $filename_conf_mus_h)
2578     {
2579         print_music_list();
2580     }
2581     elsif ($ARGV[0] eq $filename_conf_chr_c)
2582     {
2583         print_chars_graphics_list();
2584     }
2585     elsif ($ARGV[0] eq $filename_conf_chr_h)
2586     {
2587         print_chars_elements_list();
2588     }
2589     elsif ($ARGV[0] eq $filename_conf_cus_c)
2590     {
2591         print_custom_graphics_list();
2592     }
2593     elsif ($ARGV[0] eq $filename_conf_cus_h)
2594     {
2595         print_custom_elements_list();
2596     }
2597     elsif ($ARGV[0] eq $filename_conf_grp_c)
2598     {
2599         print_group_graphics_list();
2600     }
2601     elsif ($ARGV[0] eq $filename_conf_grp_h)
2602     {
2603         print_group_elements_list();
2604     }
2605     elsif ($ARGV[0] eq $filename_conf_e2g_c)
2606     {
2607         print_element_to_graphic_list();
2608     }
2609     elsif ($ARGV[0] eq $filename_conf_esg_c)
2610     {
2611         print_element_to_special_graphic_list();
2612     }
2613     elsif ($ARGV[0] eq $filename_conf_e2s_c)
2614     {
2615         print_element_to_sound_list();
2616     }
2617     elsif ($ARGV[0] eq $filename_conf_fnt_c)
2618     {
2619         print_font_to_graphic_list();
2620     }
2621     elsif ($ARGV[0] eq $filename_conf_g2s_c)
2622     {
2623         print_gamemode_to_sound_list();
2624     }
2625     elsif ($ARGV[0] eq $filename_conf_g2m_c)
2626     {
2627         print_gamemode_to_music_list();
2628     }
2629     elsif ($ARGV[0] eq $filename_conf_var_c)
2630     {
2631         print_image_config_vars();
2632     }
2633     elsif ($ARGV[0] eq $filename_conf_act_c)
2634     {
2635         print_active_states();
2636     }
2637     else
2638     {
2639         print "Unknown option '$ARGV[0]'.\n";
2640
2641         exit 1;
2642     }
2643
2644     exit 0;
2645 }