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