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