removed options to prevent initial rolling objects in native EM levels
[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          'steel_char_space'
1688          );
1689
1690     my @unknown_graphics = ();
1691     my %known_element     = get_known_element_definitions();
1692     my %known_special_arg = get_known_special_arg_definitions();
1693
1694     # ---------- read graphic file definitions ----------
1695
1696     my $filename = "$src_path/conf_gfx.c";
1697
1698     print_file_header($filename_conf_esg_c, $text_esg_c);
1699
1700     open(FILE, "$filename") ||
1701         fail("cannot open file '$filename' for reading");
1702
1703     print "static struct\n";
1704     print "{\n";
1705     print "  int element;\n";
1706     print "  int special;\n";
1707     print "\n";
1708     print "  int graphic;\n";
1709     print "}\n";
1710     print "element_to_special_graphic[] =\n";
1711     print "{\n";
1712
1713     while (<FILE>)
1714     {
1715         chomp;                          # cut trailing newline
1716
1717         if (/NO_MORE_ELEMENT_IMAGES/)   # keyword to stop parsing file
1718         {
1719             last;
1720         }
1721
1722         if (!contains_image_file($_))   # skip all lines without image file
1723         {
1724             next;
1725         }
1726
1727         s/^  \{ \"//;                   # cut all leading ...
1728         s/\",.*$//;                     # ... and trailing garbage
1729
1730         my $token = $_;
1731         my $object;
1732         my $special;
1733
1734         if ($token =~ /^font\./)        # skip all font definitions
1735         {
1736             next;
1737         }
1738
1739         if ($token =~ /^background\./)  # skip all background image definitions
1740         {
1741             next;
1742         }
1743
1744         if ($token =~ /^(.*)\.([^\.]+)$/ &&
1745             defined($known_special_arg{$2}))
1746         {
1747             $object = $1;
1748             $special = "GFX_SPECIAL_ARG_" . $2;
1749         }
1750         else
1751         {
1752             next;                       # skip all default definitions
1753         }
1754
1755         $token  =~ s/(.*)/uc($1)/eg;    # convert all characters to upper case
1756         $object =~ s/(.*)/uc($1)/eg;    # convert all characters to upper case
1757
1758         $token  =~ s/\./_/g;
1759         $object =~ s/\./_/g;
1760
1761         # print STDERR "'$token' => '$object'\n";
1762
1763         my $element = "EL_$object";
1764         my $graphic = "IMG_$token";
1765
1766         if (defined($graphic_without_element{$graphic}))
1767         {
1768             next;
1769         }
1770
1771         if (!defined($known_element{$element}))
1772         {
1773             # print STDERR "----- ERROR: unknown element '$element' -----\n";
1774
1775             push @unknown_graphics, $graphic;
1776
1777             next;
1778         }
1779
1780         print_element_to_special_graphic_entry($element,
1781                                                $special,
1782                                                $graphic);
1783     }
1784
1785     # dump list of additional elements
1786     foreach my $element (sort keys %additional_mappings)
1787     {
1788         print_element_to_special_graphic_entry($element,
1789                                                'GFX_SPECIAL_ARG_EDITOR',
1790                                                $additional_mappings{$element});
1791         print_element_to_special_graphic_entry($element,
1792                                                'GFX_SPECIAL_ARG_PREVIEW',
1793                                                $additional_mappings{$element});
1794     }
1795
1796     # dump list of custom element editor graphics
1797     for (my $i = 0; $i < $num_custom_elements; $i++)
1798     {
1799         my $element = sprintf("EL_CUSTOM_%d", $i + 1);
1800         my $graphic = sprintf("IMG_CUSTOM_%d_EDITOR", $i + 1);
1801
1802         print_element_to_special_graphic_entry($element,
1803                                                'GFX_SPECIAL_ARG_EDITOR',
1804                                                $graphic);
1805     }
1806
1807     # dump list of group element editor graphics
1808     for (my $i = 0; $i < $num_group_elements; $i++)
1809     {
1810         my $element = sprintf("EL_GROUP_%d", $i + 1);
1811         my $graphic = sprintf("IMG_GROUP_%d_EDITOR", $i + 1);
1812
1813         print_element_to_special_graphic_entry($element,
1814                                                'GFX_SPECIAL_ARG_EDITOR',
1815                                                $graphic);
1816     }
1817
1818     # dump other special editor graphics
1819     foreach my $token (@elements_with_editor_graphic)
1820     {
1821         my $element = 'EL_'  . uc($token);
1822         my $graphic = 'IMG_' . uc($token) . '_EDITOR';
1823
1824         print_element_to_special_graphic_entry($element,
1825                                                'GFX_SPECIAL_ARG_EDITOR',
1826                                                $graphic);
1827     }
1828
1829     print_element_to_special_graphic_entry('-1', '-1', '-1');
1830
1831     print "};\n";
1832
1833     close FILE;
1834
1835     if (scalar(@unknown_graphics) > 0)
1836     {
1837         print STDERR "-" x 79 . "\n";
1838         print STDERR "The following graphics cannot be associated with any element:\n";
1839
1840         foreach my $graphic (@unknown_graphics)
1841         {
1842             print STDERR "- $graphic\n";
1843         }
1844
1845         print STDERR "-" x 79 . "\n";
1846     }
1847
1848     print_file_footer($filename_conf_esg_c);
1849 }
1850
1851 sub print_element_to_sound_list
1852 {
1853     my %sound_without_action =
1854         (
1855          'SND_AMOEBA_TURNING_TO_GEM'            => 1,
1856          'SND_AMOEBA_TURNING_TO_ROCK'           => 1,
1857          'SND_BD_AMOEBA_TURNING_TO_GEM'         => 1,
1858          'SND_BD_AMOEBA_TURNING_TO_ROCK'        => 1,
1859
1860          # no special case anymore after adding action ".splashing"
1861          # 'SND_ACID_SPLASHING'                 => 1,
1862          );
1863
1864     my @unknown_sounds = ();
1865     my %known_element       = get_known_element_definitions();
1866     my %known_element_class = get_known_element_class_definitions();
1867     my %known_action        = get_known_action_definitions();
1868
1869     # ---------- read sound file definitions ----------
1870
1871     my $filename = "$src_path/conf_snd.c";
1872
1873     print_file_header($filename_conf_e2s_c, $text_e2s_c);
1874
1875     open(FILE, "$filename") ||
1876         fail("cannot open file '$filename' for reading");
1877
1878     print "static struct\n";
1879     print "{\n";
1880     print "  int element;\n";
1881     print "  boolean is_class;\n";
1882     print "  int action;\n";
1883     print "\n";
1884     print "  int sound;\n";
1885     print "}\n";
1886     print "element_to_sound[] =\n";
1887     print "{\n";
1888
1889     while (<FILE>)
1890     {
1891         chomp;                          # cut trailing newline
1892
1893         if (/NO_MORE_ELEMENT_SOUNDS/)   # keyword to stop parsing file
1894         {
1895             last;
1896         }
1897
1898         if (!contains_sound_file($_))   # skip all lines without sound file
1899         {
1900             next;
1901         }
1902
1903         s/^  \{ \"//;                   # cut all leading ...
1904         s/\",.*$//;                     # ... and trailing garbage
1905
1906         my $token = $_;
1907
1908         $token = uc($token);            # convert all characters to upper case
1909
1910         my $snd_action_default = '-1';
1911         my $snd_action = $snd_action_default;
1912
1913         my $object = $token;
1914         my $action = '';
1915
1916         if ($object =~ /^(.*)\.([A-Z0-9_]+)$/ && defined($known_action{$2}))
1917         {
1918             $object = $1;
1919             $action = $2;
1920
1921             $snd_action = "ACTION_$action";
1922             $snd_action_default = $snd_action;
1923         }
1924
1925         $token =~ s/\./_/g;
1926         $object =~ s/\./_/g;    # needed for "invisible_sand.active.digging"
1927
1928         if ($object =~ /^\[(.+)\]$/)
1929         {
1930             $object = 'CLASS_' . $1;
1931         }
1932
1933         # print STDERR "'$token' => '$object', '$action'\n";
1934
1935         my $full_element = "EL_$token";
1936         my $base_element = "EL_$object";
1937
1938         my $element = $base_element;
1939         my $sound = $token;
1940
1941         if ($sound =~ /^\[.+\]/)
1942         {
1943             $sound =~ s/\[//;           # element class sound; begin ...
1944             $sound =~ s/\]//;           # ... and end of definition token
1945             $sound =~ s/^/CLASS_/;      # add class identifier
1946         }
1947
1948         $sound = "SND_$sound";
1949
1950         my $element_without_action = $full_element;
1951         $element_without_action =~ s/_$action$//;
1952
1953         my $element_class_without_action = $full_element;
1954         $element_without_action =~ s/_$action$//;
1955
1956         if (defined($known_element_class{$full_element}))
1957         {
1958             $element = $full_element;
1959
1960             $snd_action_default = '-1';
1961         }
1962
1963         if ($element_without_action eq $element || $action eq '')
1964         {
1965             $element_without_action = '';
1966         }
1967
1968         if (defined($sound_without_action{$sound}))
1969         {
1970             next;
1971         }
1972
1973         if (!defined($known_element{$element}) &&
1974             !defined($known_element_class{$element}))
1975         {
1976             # print STDERR "----- ERROR: unknown element '$element' -----\n";
1977
1978             push @unknown_sounds, $sound;
1979
1980             next;
1981         }
1982
1983         if (!($element =~ /_CLASS_/) &&
1984             defined($known_element{$element}))
1985         {
1986             print_element_to_sound_entry($element, "FALSE",
1987                                          $snd_action_default,
1988                                          $sound);
1989         }
1990
1991         if (!($element =~ /_CLASS_/) &&
1992             defined($known_element{$element_without_action}))
1993         {
1994             print_element_to_sound_entry($element_without_action, "FALSE",
1995                                          $snd_action,
1996                                          $sound);
1997         }
1998
1999         if ($element =~ /_CLASS_/ &&
2000             defined($known_element_class{$element}))
2001         {
2002             my $class_element = $known_element_class{$element};
2003
2004             print_element_to_sound_entry($class_element, "TRUE",
2005                                          $snd_action_default,
2006                                          $sound);
2007         }
2008
2009         if ($element =~ /_CLASS_/ &&
2010             defined($known_element_class{$element_without_action}))
2011         {
2012             my $class_element = $known_element_class{$element_without_action};
2013
2014             print_element_to_sound_entry($class_element, "TRUE",
2015                                          $snd_action,
2016                                          $sound);
2017         }
2018     }
2019
2020     print_element_to_sound_entry('-1', '-1', '-1', '-1');
2021
2022     print "};\n";
2023
2024     close FILE;
2025
2026     if (scalar(@unknown_sounds) > 0)
2027     {
2028         print STDERR "-" x 79 . "\n";
2029         print STDERR "The following sounds cannot be associated with any element or element class:\n";
2030
2031         foreach my $sound (@unknown_sounds)
2032         {
2033             print STDERR "- $sound\n";
2034         }
2035
2036         print STDERR "-" x 79 . "\n";
2037     }
2038
2039     print_file_footer($filename_conf_e2s_c);
2040 }
2041
2042 sub print_font_to_graphic_list
2043 {
2044     my @unknown_graphics = ();
2045     my %known_font        = get_known_font_definitions();
2046     my %known_special_arg = get_known_special_arg_definitions();
2047
2048     # ---------- read graphic file definitions ----------
2049
2050     my $filename = "$src_path/conf_gfx.c";
2051
2052     print_file_header($filename_conf_fnt_c, $text_fnt_c);
2053
2054     open(FILE, "$filename") ||
2055         fail("cannot open file '$filename' for reading");
2056
2057     print "static struct\n";
2058     print "{\n";
2059     print "  int font_nr;\n";
2060     print "  int special;\n";
2061     print "\n";
2062     print "  int graphic;\n";
2063     print "}\n";
2064     print "font_to_graphic[] =\n";
2065     print "{\n";
2066
2067     while (<FILE>)
2068     {
2069         chomp;                          # cut trailing newline
2070
2071         if (!contains_image_file($_))   # skip all lines without image file
2072         {
2073             next;
2074         }
2075
2076         s/^  \{ \"//;                   # cut all leading ...
2077         s/\",.*$//;                     # ... and trailing garbage
2078
2079         my $token = $_;
2080         my $font;
2081         my $special;
2082         my $graphic;
2083
2084         if ($token =~ /^(font\..*)$/)
2085         {
2086             $font = $token;
2087             $special = '-1';
2088
2089             if ($token =~ /^(.*)\.([^\.]+)$/ &&
2090                 defined($known_special_arg{$2}))
2091             {
2092                 $font = $1;
2093                 $special = "GFX_SPECIAL_ARG_" . $2;
2094             }
2095         }
2096         else
2097         {
2098             next;                       # skip all non-font definitions
2099         }
2100
2101         $token =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2102         $font  =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2103
2104         $token =~ s/\./_/g;
2105         $font  =~ s/\./_/g;
2106
2107         # print STDERR "'$token' => '$font'\n";
2108
2109         $graphic = "IMG_$token";
2110
2111         if (!defined($known_font{$font}))
2112         {
2113             # print STDERR "----- ERROR: unknown font '$font' -----\n";
2114
2115             push @unknown_graphics, $graphic;
2116
2117             next;
2118         }
2119
2120         print_font_to_graphic_entry($font,
2121                                     $special,
2122                                     $graphic);
2123     }
2124
2125     print_font_to_graphic_entry('-1', '-1', '-1');
2126
2127     print "};\n";
2128
2129     close FILE;
2130
2131     if (scalar(@unknown_graphics) > 0)
2132     {
2133         print STDERR "-" x 79 . "\n";
2134         print STDERR "The following graphics cannot be associated with any font:\n";
2135
2136         foreach my $graphic (@unknown_graphics)
2137         {
2138             print STDERR "- $graphic\n";
2139         }
2140
2141         print STDERR "-" x 79 . "\n";
2142     }
2143
2144     print_file_footer($filename_conf_fnt_c);
2145 }
2146
2147 sub print_gamemode_to_sound_list
2148 {
2149     my %known_prefix = get_known_sound_prefix_definitions();
2150     my %known_special_arg = get_known_special_arg_definitions();
2151
2152     # ---------- read music file definitions ----------
2153
2154     my $filename = "$src_path/conf_snd.c";
2155
2156     print_file_header($filename_conf_g2s_c, $text_g2s_c);
2157
2158     open(FILE, "$filename") ||
2159         fail("cannot open file '$filename' for reading");
2160
2161     print "static struct\n";
2162     print "{\n";
2163     print "  int gamemode;\n";
2164     print "\n";
2165     print "  int sound;\n";
2166     print "}\n";
2167     print "gamemode_to_sound[] =\n";
2168     print "{\n";
2169
2170     while (<FILE>)
2171     {
2172         chomp;                          # cut trailing newline
2173
2174         if (!contains_sound_file($_))   # skip all lines without sound file
2175         {
2176             next;
2177         }
2178
2179         if (/\[not used\]/)
2180         {
2181             next;
2182         }
2183
2184         s/^  \{ \"//;                   # cut all leading ...
2185         s/\",.*$//;                     # ... and trailing garbage
2186
2187         my $token = $_;
2188         my $gamemode = -1;
2189         # my $level = -1;               # ???
2190
2191         if (defined($known_prefix{$token}))
2192         {
2193             # no special arg defined
2194         }
2195         elsif ($token =~ /^(.*)\.([^\.]+)$/ &&
2196                defined($known_prefix{$1}) &&
2197                defined($known_special_arg{$2}))
2198         {
2199             $gamemode = "GFX_SPECIAL_ARG_" . $2;
2200         }
2201         else
2202         {
2203             next;
2204         }
2205
2206 #       if ($token =~ /^(.*)\./ &&
2207 #           !defined($known_prefix{$1}))
2208 #       {
2209 #           next;
2210 #       }
2211 #
2212 #       if ($token =~ /^(.*)\.([^\.]+)$/ &&
2213 #           defined($known_special_arg{$2}))
2214 #       {
2215 #           $gamemode = "GFX_SPECIAL_ARG_" . $2;
2216 #       }
2217
2218         $token =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2219         $token =~ s/\./_/g;
2220
2221         my $sound = "SND_$token";
2222
2223         # print STDERR "'$token' => '$sound'\n";
2224
2225         print_gamemode_to_sound_entry($gamemode, $sound);
2226     }
2227
2228     print_gamemode_to_sound_entry('-1', '-1');
2229
2230     print "};\n";
2231
2232     close FILE;
2233
2234     print_file_footer($filename_conf_g2s_c);
2235 }
2236
2237 sub print_gamemode_to_music_list
2238 {
2239     my %known_prefix = get_known_music_prefix_definitions();
2240     my %known_special_arg = get_known_special_arg_definitions();
2241
2242     # ---------- read music file definitions ----------
2243
2244     my $filename = "$src_path/conf_mus.c";
2245
2246     print_file_header($filename_conf_g2m_c, $text_g2m_c);
2247
2248     open(FILE, "$filename") ||
2249         fail("cannot open file '$filename' for reading");
2250
2251     print "static struct\n";
2252     print "{\n";
2253     print "  int gamemode;\n";
2254     print "\n";
2255     print "  int music;\n";
2256     print "}\n";
2257     print "gamemode_to_music[] =\n";
2258     print "{\n";
2259
2260     while (<FILE>)
2261     {
2262         chomp;                          # cut trailing newline
2263
2264         if (!contains_music_file($_))   # skip all lines without music file
2265         {
2266             next;
2267         }
2268
2269         s/^  \{ \"//;                   # cut all leading ...
2270         s/\",.*$//;                     # ... and trailing garbage
2271
2272         my $token = $_;
2273         my $gamemode = -1;
2274
2275         if (defined($known_prefix{$token}))
2276         {
2277             # no special arg defined
2278         }
2279         elsif ($token =~ /^(.*)\.([^\.]+)$/ &&
2280                defined($known_prefix{$1}) &&
2281                defined($known_special_arg{$2}))
2282         {
2283             $gamemode = "GFX_SPECIAL_ARG_" . $2;
2284         }
2285         else
2286         {
2287             next;
2288         }
2289
2290 #       my $prefix = $token;
2291 #       $prefix =~ s/\..*$//;
2292 #
2293 ##      if ($token =~ /^(.*)\./ &&
2294 ##          !defined($known_prefix{$1}))
2295 #       if (!defined($known_prefix{$prefix}))
2296 #       {
2297 #           next;
2298 #       }
2299 #
2300 #       if ($token =~ /^(.*)\.([^\.]+)$/ &&
2301 #           defined($known_special_arg{$2}))
2302 #       {
2303 #           $gamemode = "GFX_SPECIAL_ARG_" . $2;
2304 #       }
2305
2306         $token =~ s/(.*)/uc($1)/eg;     # convert all characters to upper case
2307         $token =~ s/\./_/g;
2308
2309         my $music = "MUS_$token";
2310
2311         # print STDERR "'$token' => '$music'\n";
2312
2313         print_gamemode_to_music_entry($gamemode, $music);
2314     }
2315
2316     print_gamemode_to_music_entry('-1', '-1');
2317
2318     print "};\n";
2319
2320     close FILE;
2321
2322     print_file_footer($filename_conf_g2m_c);
2323 }
2324
2325 sub print_image_config_vars
2326 {
2327     # ---------- read graphic file definitions ----------
2328
2329     my $filename = "$src_path/conf_gfx.c";
2330
2331     print_file_header($filename_conf_var_c, $text_var_c);
2332
2333     open(FILE, "$filename") ||
2334         fail("cannot open file '$filename' for reading");
2335
2336     print "struct TokenIntPtrInfo image_config_vars[] =\n";
2337     print "{\n";
2338
2339     my $start_parsing = 0;
2340
2341     while (<FILE>)
2342     {
2343         chomp;                          # cut trailing newline
2344
2345         if (/CONFIG_VARS_START/)        # keyword to start parsing file
2346         {
2347             $start_parsing = 1;
2348         }
2349
2350         if (!$start_parsing)
2351         {
2352             next;
2353         }
2354
2355         if (/^\s*\{\s*\"([^\"]+)\"/)    # config token found
2356         {
2357             my $token = $1;
2358             my $var = $token;
2359
2360             # --- some prefix replacements ---
2361
2362             $var =~ s/^main\./menu.main./;
2363             $var =~ s/^setup\./menu.setup./;
2364             $var =~ s/^\[player\]\./game.player_/;
2365             $var =~ s/^\[title_initial\]/title_initial_default/;
2366             $var =~ s/^\[title\]/title_default/;
2367             $var =~ s/^\[titlescreen_initial\]/titlescreen_initial_default/;
2368             $var =~ s/^\[titlescreen\]/titlescreen_default/;
2369             $var =~ s/^\[titlemessage_initial\]/titlemessage_initial_default/;
2370             $var =~ s/^\[titlemessage\]/titlemessage_default/;
2371
2372             if ($var =~ /^titlescreen.*(\d)/ ||
2373                 $var =~ /^titlemessage.*(\d)/ ||
2374                 $var =~ /^game.panel.key_(\d)/ ||
2375                 $var =~ /^game.panel.inventory_first_(\d)/ ||
2376                 $var =~ /^game.panel.inventory_last_(\d)/ ||
2377                 $var =~ /^game.panel.conveyor_belt_(\d)\./ ||
2378                 $var =~ /^game.panel.element_(\d)\./ ||
2379                 $var =~ /^game.panel.graphic_(\d)\./ ||
2380                 $var =~ /^game.panel.ce_score_(\d)\./)
2381             {
2382                 my $number = $1;
2383                 my $array_pos = int($number) - 1;
2384                 $var =~ s/_$number/\[$array_pos\]/;
2385             }
2386             elsif ($var =~ /^game.panel.conveyor_belt_(\d)(_switch)/ ||
2387                    $var =~ /^game.panel.element_(\d)(_count)/ ||
2388                    $var =~ /^game.panel.ce_score_(\d)(_element)/)
2389             {
2390                 my $number = $1;
2391                 my $suffix = $2;
2392                 my $array_pos = int($number) - 1;
2393                 $var =~ s/_$number$suffix/$suffix\[$array_pos\]/;
2394             }
2395
2396             # --- some suffix replacements ---
2397
2398             $var =~ s/^(menu\.main\..*)\.chars$/$1.size/;
2399             $var =~ s/^(tape\.text\..*)\.chars$/$1.size/;
2400             $var =~ s/^(game\.panel\..*)\.chars$/$1.size/;
2401             $var =~ s/^(game\.panel\..*)\.tile_size$/$1.size/;
2402             $var =~ s/^(request\.button\..*)\.tile_size$/$1.size/;
2403             $var =~ s/\.digits$/.size/;
2404             $var =~ s/\.2nd_offset$/.offset2/;
2405             $var =~ s/\.2nd_xoffset$/.xoffset2/;
2406             $var =~ s/\.2nd_yoffset$/.yoffset2/;
2407             $var =~ s/\.element$/.id/;
2408             $var =~ s/\.draw_order$/.sort_priority/;
2409
2410             $var =~ s/\.font_[a-z]+$/.font_alt/;
2411             $var =~ s/\.INFO\[([A-Z]+)\](.*)$/_info\[GFX_SPECIAL_ARG_INFO_$1\]$2/;
2412             $var =~ s/\.SETUP\[([A-Z0-9_]+)\](.*)$/_setup\[GFX_SPECIAL_ARG_SETUP_$1\]$2/;
2413             $var =~ s/\.([A-Z]+)$/\[GFX_SPECIAL_ARG_$1\]/;
2414             $var =~ s/\.([A-Z]+)\./\[GFX_SPECIAL_ARG_$1\]./;
2415
2416             if ($var =~ /^(menu.(enter|leave|next)_screen)(.[a-z_]+)$/)
2417             {
2418                 $var = $1 . "[GFX_SPECIAL_ARG_DEFAULT]" . $3;
2419             }
2420
2421             if ($var =~ /^menu.(draw_[xy]offset|list_size)$/)
2422             {
2423                 $var .= "[GFX_SPECIAL_ARG_DEFAULT]";
2424             }
2425
2426             if ($var =~ /^(viewport.(window|playfield|door_[12]))(.[a-z_]+)$/)
2427             {
2428                 $var = $1 . "[GFX_SPECIAL_ARG_DEFAULT]" . $3;
2429             }
2430
2431             print_image_config_var_entry("\"$token\"", "&$var");
2432
2433             if ($var =~ /^(title)_default/ ||
2434                 $var =~ /^(title_initial)_default/ ||
2435                 $var =~ /^(titlescreen.*)\[\d\]/ ||
2436                 $var =~ /^(titlemessage.*)\[\d\]/)
2437             {
2438                 my $prefix = $1;
2439                 $var =~ s/^$prefix/${prefix}_first/;
2440
2441                 print_image_config_var_entry("\"$token\"", "&$var");
2442             }
2443         }
2444     }
2445
2446     print_image_config_var_entry('NULL', 'NULL');
2447
2448     print "};\n";
2449
2450     close FILE;
2451
2452     print_file_footer($filename_conf_var_c);
2453 }
2454
2455 sub print_active_states
2456 {
2457     # ---------- read graphic file definitions ----------
2458
2459     my %known_element = get_known_element_definitions();
2460     my %known_button  = get_known_button_definitions();
2461     my %known_font    = get_known_font_definitions();
2462
2463     print_file_header($filename_conf_act_c, $text_act_c);
2464
2465     print "static struct\n";
2466     print "{\n";
2467     print "  int element;\n";
2468     print "  int element_active;\n";
2469     print "}\n";
2470     print "element_with_active_state[] =\n";
2471     print "{\n";
2472
2473     foreach my $element (sort keys %known_element)
2474     {
2475         my $element_active = $element . '_ACTIVE';
2476
2477         if (defined($known_element{$element_active}))
2478         {
2479             print_active_state_entry($element, $element_active);
2480         }
2481     }
2482
2483     print_active_state_entry('-1', '-1');
2484
2485     print "};\n";
2486
2487     print "\n";
2488     print "\n";
2489     print "static struct\n";
2490     print "{\n";
2491     print "  int button;\n";
2492     print "  int button_active;\n";
2493     print "}\n";
2494     print "button_with_active_state[] =\n";
2495     print "{\n";
2496
2497     foreach my $button (sort keys %known_button)
2498     {
2499         my $button_active = $button . '_ACTIVE';
2500
2501         if (defined($known_button{$button_active}))
2502         {
2503             print_active_state_entry($button, $button_active);
2504         }
2505     }
2506
2507     print_active_state_entry('-1', '-1');
2508
2509     print "};\n";
2510
2511     print "\n";
2512     print "\n";
2513     print "static struct\n";
2514     print "{\n";
2515     print "  int font_nr;\n";
2516     print "  int font_nr_active;\n";
2517     print "}\n";
2518     print "font_with_active_state[] =\n";
2519     print "{\n";
2520
2521     foreach my $font (sort keys %known_font)
2522     {
2523         my $font_active = $font . '_ACTIVE';
2524
2525         if (defined($known_font{$font_active}))
2526         {
2527             print_active_state_entry($font, $font_active);
2528         }
2529     }
2530
2531     print_active_state_entry('-1', '-1');
2532
2533     print "};\n";
2534
2535     print_file_footer($filename_conf_act_c);
2536 }
2537
2538
2539 # =============================================================================
2540 # M A I N - P R O G R A M
2541 # =============================================================================
2542
2543 sub main
2544 {
2545     my $argc = scalar(@ARGV);
2546
2547     if ($argc == 0 || $ARGV[0] eq '-h' || $ARGV[0] eq '--help')
2548     {
2549         print "Usage: $0 <file>\n\n";
2550         print "Choose <file> from the following list:\n";
2551         print "- '$filename_conf_gfx_h'\n";
2552         print "- '$filename_conf_snd_h'\n";
2553         print "- '$filename_conf_mus_h'\n";
2554         print "- '$filename_conf_chr_c'\n";
2555         print "- '$filename_conf_chr_h'\n";
2556         print "- '$filename_conf_cus_c'\n";
2557         print "- '$filename_conf_cus_h'\n";
2558         print "- '$filename_conf_grp_c'\n";
2559         print "- '$filename_conf_grp_h'\n";
2560         print "- '$filename_conf_e2g_c'\n";
2561         print "- '$filename_conf_esg_c'\n";
2562         print "- '$filename_conf_fnt_c'\n";
2563         print "- '$filename_conf_g2s_c'\n";
2564         print "- '$filename_conf_g2m_c'\n";
2565         print "- '$filename_conf_var_c'\n";
2566         print "- '$filename_conf_act_c'\n";
2567
2568         exit 1;
2569     }
2570
2571     if ($ARGV[0] eq $filename_conf_gfx_h)
2572     {
2573         print_graphics_list();
2574     }
2575     elsif ($ARGV[0] eq $filename_conf_snd_h)
2576     {
2577         print_sounds_list();
2578     }
2579     elsif ($ARGV[0] eq $filename_conf_mus_h)
2580     {
2581         print_music_list();
2582     }
2583     elsif ($ARGV[0] eq $filename_conf_chr_c)
2584     {
2585         print_chars_graphics_list();
2586     }
2587     elsif ($ARGV[0] eq $filename_conf_chr_h)
2588     {
2589         print_chars_elements_list();
2590     }
2591     elsif ($ARGV[0] eq $filename_conf_cus_c)
2592     {
2593         print_custom_graphics_list();
2594     }
2595     elsif ($ARGV[0] eq $filename_conf_cus_h)
2596     {
2597         print_custom_elements_list();
2598     }
2599     elsif ($ARGV[0] eq $filename_conf_grp_c)
2600     {
2601         print_group_graphics_list();
2602     }
2603     elsif ($ARGV[0] eq $filename_conf_grp_h)
2604     {
2605         print_group_elements_list();
2606     }
2607     elsif ($ARGV[0] eq $filename_conf_e2g_c)
2608     {
2609         print_element_to_graphic_list();
2610     }
2611     elsif ($ARGV[0] eq $filename_conf_esg_c)
2612     {
2613         print_element_to_special_graphic_list();
2614     }
2615     elsif ($ARGV[0] eq $filename_conf_e2s_c)
2616     {
2617         print_element_to_sound_list();
2618     }
2619     elsif ($ARGV[0] eq $filename_conf_fnt_c)
2620     {
2621         print_font_to_graphic_list();
2622     }
2623     elsif ($ARGV[0] eq $filename_conf_g2s_c)
2624     {
2625         print_gamemode_to_sound_list();
2626     }
2627     elsif ($ARGV[0] eq $filename_conf_g2m_c)
2628     {
2629         print_gamemode_to_music_list();
2630     }
2631     elsif ($ARGV[0] eq $filename_conf_var_c)
2632     {
2633         print_image_config_vars();
2634     }
2635     elsif ($ARGV[0] eq $filename_conf_act_c)
2636     {
2637         print_active_states();
2638     }
2639     else
2640     {
2641         print "Unknown option '$ARGV[0]'.\n";
2642
2643         exit 1;
2644     }
2645
2646     exit 0;
2647 }