From 94f017e57e45fae89e35a4948fe7005bdf3f13ba Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 4 Nov 2013 00:44:55 +0100 Subject: [PATCH] rocksndiamonds-3.3.1.1 * version 3.3.1.1 released * added scripts directory to distribution package to enable building element definitions after editing artwork config source code files --- ChangeLog | 7 + build-scripts/create_element_defs.pl | 2621 ++++++++++++++++++++++++++ src/Makefile | 4 +- src/conftime.h | 2 +- src/main.h | 2 +- src/screens.c | 13 + 6 files changed, 2645 insertions(+), 4 deletions(-) create mode 100755 build-scripts/create_element_defs.pl diff --git a/ChangeLog b/ChangeLog index 89a2779f..7c0df045 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-11-04 + * version 3.3.1.1 released + +2013-11-03 + * added scripts directory to distribution package to enable building + element definitions after editing artwork config source code files + 2013-10-26 * added volume controls for sounds, loops and music to sound setup diff --git a/build-scripts/create_element_defs.pl b/build-scripts/create_element_defs.pl new file mode 100755 index 00000000..d935b3fe --- /dev/null +++ b/build-scripts/create_element_defs.pl @@ -0,0 +1,2621 @@ +#!/usr/bin/perl -w + +# ============================================================================= +# create_element_defs.pl +# ----------------------------------------------------------------------------- +# 2002-09-19 holger.schemel@mediaways.net +# ============================================================================= + +use strict; + + +# ============================================================================= +# C O N F I G U R A T I O N S E C T I O N +# ============================================================================= + +my $base_path = "."; +my $src_path = "$base_path/src"; + +if (-d "../src") # we're already inside "src" directory +{ + $src_path = "."; +} + + +# ----------------------------------------------------------------------------- +# global variables +# ----------------------------------------------------------------------------- + +my $filename_header_tmpl = "$src_path/header.tmpl"; + +my $filename_conf_gfx_h = 'conf_gfx.h'; +my $filename_conf_snd_h = 'conf_snd.h'; +my $filename_conf_mus_h = 'conf_mus.h'; +my $filename_conf_chr_c = 'conf_chr.c'; +my $filename_conf_chr_h = 'conf_chr.h'; +my $filename_conf_cus_c = 'conf_cus.c'; +my $filename_conf_cus_h = 'conf_cus.h'; +my $filename_conf_grp_c = 'conf_grp.c'; +my $filename_conf_grp_h = 'conf_grp.h'; +my $filename_conf_e2g_c = 'conf_e2g.c'; +my $filename_conf_esg_c = 'conf_esg.c'; +my $filename_conf_e2s_c = 'conf_e2s.c'; +my $filename_conf_fnt_c = 'conf_fnt.c'; +my $filename_conf_g2s_c = 'conf_g2s.c'; +my $filename_conf_g2m_c = 'conf_g2m.c'; +my $filename_conf_var_c = 'conf_var.c'; +my $filename_conf_act_c = 'conf_act.c'; + +my $text_auto = 'this file was automatically generated -- do not edit by hand'; +my $text_gfx_h = 'values for graphics configuration (normal elements)'; +my $text_snd_h = 'values for sounds configuration'; +my $text_mus_h = 'values for music configuration'; +my $text_chr_c = 'values for graphics configuration (character elements)'; +my $text_chr_h = 'values for elements configuration (character elements)'; +my $text_cus_c = 'values for graphics configuration (custom elements)'; +my $text_cus_h = 'values for elements configuration (custom elements)'; +my $text_grp_c = 'values for graphics configuration (group elements)'; +my $text_grp_h = 'values for elements configuration (group elements)'; +my $text_e2g_c = 'values for element/graphics mapping configuration (normal)'; +my $text_esg_c = 'values for element/graphics mapping configuration (special)'; +my $text_e2s_c = 'values for element/sounds mapping configuration'; +my $text_fnt_c = 'values for font/graphics mapping configuration'; +my $text_g2s_c = 'values for gamemode/sound mapping configuration'; +my $text_g2m_c = 'values for gamemode/music mapping configuration'; +my $text_var_c = 'values for image and layout parameter configuration'; +my $text_act_c = 'values for active states of elements and fonts'; + +my $num_custom_elements = 256; +my $num_group_elements = 32; + +my $char_skip = '---[SKIP]---'; + +my @chars = + ( + 'SPACE', + 'EXCLAM', + 'QUOTEDBL', + 'NUMBERSIGN', + 'DOLLAR', + 'PERCENT', + 'AMPERSAND', + 'APOSTROPHE', + 'PARENLEFT', + 'PARENRIGHT', + 'ASTERISK', + 'PLUS', + 'COMMA', + 'MINUS', + 'PERIOD', + 'SLASH', + + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'COLON', + 'SEMICOLON', + 'LESS', + 'EQUAL', + 'GREATER', + 'QUESTION', + + 'AT', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'BRACKETLEFT', + 'BACKSLASH', + 'BRACKETRIGHT', + 'ASCIICIRCUM', + 'UNDERSCORE', + + 'COPYRIGHT', + 'AUMLAUT', + 'OUMLAUT', + 'UUMLAUT', + 'DEGREE', + 'TRADEMARK', + 'CURSOR', + $char_skip, + $char_skip, + $char_skip, + $char_skip, + $char_skip, + $char_skip, + 'BUTTON', + 'UP', + 'DOWN', + ); + + +# ----------------------------------------------------------------------------- +# start main program +# ----------------------------------------------------------------------------- + +main(); +exit 0; + + +# ============================================================================= +# F U N C T I O N S +# ============================================================================= + +sub error +{ + my ($error_msg) = @_; + + print STDERR "ERROR: "; + print STDERR "$error_msg\n"; +} + +sub fail +{ + my ($error_msg) = @_; + + print STDERR "FATAL "; + error("$error_msg"); + + exit 1; +} + +sub contains_image_file +{ + my ($line) = @_; + + return ($line =~ /\".+\.pcx\"/ || + $line =~ /UNDEFINED_FILENAME/); +} + +sub contains_sound_file +{ + my ($line) = @_; + + return ($line =~ /\".+\.wav\"/ || + $line =~ /UNDEFINED_FILENAME/); +} + +sub contains_music_file +{ + my ($line) = @_; + + return ($line =~ /\".+\.wav\"/ || + $line =~ /\".+\.mod\"/ || + $line =~ /\".+\.mp3\"/ || + $line =~ /UNDEFINED_FILENAME/); +} + +sub print_file_header +{ + my ($filename, $comment) = @_; + my $filename_tmpl = 'xxxxxxxx.x'; + my $filename_text = $filename; + my $filename_def = uc($filename); + $filename_def =~ s/\./_/; + + $filename_text .= ' ' x (length($filename_tmpl) - length($filename_text)); + + open(FILE, "$filename_header_tmpl") || + fail("cannot open file '$filename_header_tmpl' for reading"); + + while () + { + s/$filename_tmpl/$filename_text/; + + print; + } + + close FILE; + + print "\n"; + print "/* ----- $text_auto ----- */\n"; + print "\n"; + print "#ifndef $filename_def\n"; + print "#define $filename_def\n"; + print "\n"; + print "/* $comment */\n"; + print "\n"; +} + +sub print_file_footer +{ + my ($filename) = @_; + my $filename_def = uc($filename); + $filename_def =~ s/\./_/; + + print "\n"; + print "#endif /* $filename_def */\n"; +} + +sub get_tabs +{ + my ($text, $max_num_tabs) = @_; + + my $num_tabs = $max_num_tabs - int(length($text) / 8); + + if ($num_tabs < 1) # at least one tab needed as separator + { + $num_tabs = 1; + } + + return "\t" x $num_tabs; +} + +sub print_graphics_list +{ + my $filename = "$src_path/conf_gfx.c"; + + print_file_header($filename_conf_gfx_h, $text_gfx_h); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + my $max_num_tabs = 7; + my $i = 0; + + while () + { + chomp; # cut trailing newline + + if (/^\#include "conf_chr.c"/) # dump list of character elements + { + foreach my $char (@chars) + { + my $prefix = $char; + + $prefix =~ s/^/#define IMG_CHAR_/; + + my $tabs = get_tabs($prefix, $max_num_tabs); + + if ($char ne $char_skip) + { + print "$prefix$tabs$i\n"; + + $i++; + } + + if (lc($char) eq 'space') + { + $prefix =~ s/$/_EDITOR/; + + my $tabs = get_tabs($prefix, $max_num_tabs); + + print "$prefix$tabs$i\n"; + + $i++; + } + } + + foreach my $char (@chars) + { + my $prefix = $char; + + $prefix =~ s/^/#define IMG_STEEL_CHAR_/; + + my $tabs = get_tabs($prefix, $max_num_tabs); + + if ($char ne $char_skip) + { + print "$prefix$tabs$i\n"; + + $i++; + } + + if (lc($char) eq 'space') + { + $prefix =~ s/$/_EDITOR/; + + my $tabs = get_tabs($prefix, $max_num_tabs); + + print "$prefix$tabs$i\n"; + + $i++; + } + } + } + + if (/^\#include "conf_cus.c"/) # dump list of custom elements + { + for (my $nr = 0; $nr < $num_custom_elements; $nr++) + { + my $line = sprintf("#define IMG_CUSTOM_%d", $nr + 1); + + my $tabs = get_tabs($line, $max_num_tabs); + + print "$line$tabs$i\n"; + + $i++; + + $line = sprintf("#define IMG_CUSTOM_%d_EDITOR", $nr + 1); + + $tabs = get_tabs($line, $max_num_tabs); + + print "$line$tabs$i\n"; + + $i++; + } + } + + if (/^\#include "conf_grp.c"/) # dump list of group elements + { + for (my $nr = 0; $nr < $num_group_elements; $nr++) + { + my $line = sprintf("#define IMG_GROUP_%d", $nr + 1); + + my $tabs = get_tabs($line, $max_num_tabs); + + print "$line$tabs$i\n"; + + $i++; + + $line = sprintf("#define IMG_GROUP_%d_EDITOR", $nr + 1); + + $tabs = get_tabs($line, $max_num_tabs); + + print "$line$tabs$i\n"; + + $i++; + } + } + + if (!contains_image_file($_)) # skip all lines without image file + { + next; + } + + s/(.*)/uc($1)/eg; # convert all characters to upper case + s/\./_/g; # replace all '.' with '_' + + s/^ \{ \"/#define IMG_/; # convert line + s/\",.*$//; # convert line + + # dirty hack for making "ABC[DEF]" work as a "special" suffix + s/([^_])\[/$1_/; + + # dirty hack for making "[default]" work as an element name + s/\[//; + s/\]//; + + my $tabs = get_tabs($_, $max_num_tabs); + + print "$_$tabs$i\n"; + + $i++; + } + + my $summary = '#define NUM_IMAGE_FILES'; + my $tabs = get_tabs($summary, $max_num_tabs); + + print "\n$summary$tabs$i\n"; + + close FILE; + + print_file_footer($filename_conf_gfx_h); +} + +sub print_sounds_list +{ + my %known_element = get_known_element_definitions(); + + my $filename = "$src_path/conf_snd.c"; + + print_file_header($filename_conf_snd_h, $text_snd_h); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + my $max_num_tabs = 7; + my $i = 0; + + while () + { + chomp; # cut trailing newline + + if (!contains_sound_file($_)) # skip all lines without sound file + { + next; + } + + if (/\[not used\]/ || + / TEST / || + /wav[^\}]*$/) # skip all lines without sound file + { + next; + } + + s/(.*)/uc($1)/eg; # convert all characters to upper case + s/\./_/g; # replace all '.' with '_' + + s/^ \{ \"//; + s/\",.*$//; + + my $sound = $_; + + if ($sound =~ /^\[.+\]/) + { + $sound =~ s/\[//; # element class sound; begin ... + $sound =~ s/\]//; # ... and end of definition token + $sound =~ s/^/CLASS_/; # add class identifier + } + + $sound = "SND_$sound"; + + my $define_text = "#define $sound"; + my $tabs = get_tabs($define_text, $max_num_tabs); + + print "$define_text$tabs$i\n"; + + $i++; + } + + my $summary = '#define NUM_SOUND_FILES'; + my $tabs = get_tabs($summary, $max_num_tabs); + + print "\n$summary$tabs$i\n"; + + close FILE; + + print_file_footer($filename_conf_snd_h); +} + +sub print_music_list +{ + my %known_prefix = get_known_music_prefix_definitions(); + + my $filename = "$src_path/conf_mus.c"; + + print_file_header($filename_conf_mus_h, $text_mus_h); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + my $max_num_tabs = 7; + my $i = 0; + + while () + { + chomp; # cut trailing newline + + if (!contains_music_file($_)) # skip all lines without music file + { + next; + } + + if (/\[not used\]/ || + / TEST / || + /wav[^\}]*$/) # skip all lines without music file + { + next; + } + + s/(.*)/uc($1)/eg; # convert all characters to upper case + s/\./_/g; # replace all '.' with '_' + + s/^ \{ \"//; + s/\",.*$//; + + my $music = $_; + + $music = "MUS_$music"; + + my $define_text = "#define $music"; + my $tabs = get_tabs($define_text, $max_num_tabs); + + print "$define_text$tabs$i\n"; + + $i++; + } + + my $summary = '#define NUM_MUSIC_FILES'; + my $tabs = get_tabs($summary, $max_num_tabs); + + print "\n$summary$tabs$i\n"; + + close FILE; + + print_file_footer($filename_conf_mus_h); +} + +sub print_chars_elements_list +{ + print_file_header($filename_conf_chr_h, $text_chr_h); + + my $i = 0; + + foreach my $char (@chars) + { + my $left = "#define EL_CHAR_$char"; + + my $tabs_left = get_tabs($left, 5); + + my $right = sprintf("(EL_CHAR_ASCII0 + %d)", $i + 32); + + if ($char ne $char_skip) + { + print "$left$tabs_left$right\n"; + } + + $i++; + } + + $i = 0; + + foreach my $char (@chars) + { + my $left = "#define EL_STEEL_CHAR_$char"; + + my $tabs_left = get_tabs($left, 5); + + my $right = sprintf("(EL_STEEL_CHAR_ASCII0 + %d)", $i + 32); + + if ($char ne $char_skip) + { + print "$left$tabs_left$right\n"; + } + + $i++; + } + + print_file_footer($filename_conf_chr_c); +} + +sub print_chars_graphics_list_line +{ + my ($token, $x, $y) = @_; + + my @extensions = + ( + '', + '.xpos', + '.ypos', + '.frames', + ); + + my $basename = ($token =~ /^steel_char/ ? 'RocksFontDC' : 'RocksFontEM' ); + + foreach my $ext (@extensions) + { + my $left = " \{ \"$token$ext\","; + + my $tabs_left = get_tabs($left, 6); + + my $right = ($ext eq '' ? $basename . '.pcx' : + $ext eq '.frames' ? '1' : '0'); + + if ($ext eq '.xpos') + { + $right = $x; + } + elsif ($ext eq '.ypos') + { + $right = $y; + } + + $right = "\"$right\""; + + my $tabs_right = get_tabs($right, 3); + + print "$left$tabs_left$right$tabs_right},\n"; + } +} + +sub print_chars_graphics_list +{ + print_file_header($filename_conf_chr_c, $text_chr_c); + + my $i = 0; + + foreach my $char (@chars) + { + if ($char ne $char_skip) + { + my $x = $i % 16; + my $y = int($i / 16); + + print_chars_graphics_list_line(lc("char_$char"), $x, $y); + } + + if (lc($char) eq 'space') + { + print_chars_graphics_list_line("char_space.EDITOR", 7, 4); + } + + if ($char ne $char_skip) + { + print "\n"; + } + + $i++; + } + + $i = 0; + + foreach my $char (@chars) + { + if ($char ne $char_skip) + { + my $x = $i % 16; + my $y = int($i / 16); + + print_chars_graphics_list_line(lc("steel_char_$char"), $x, $y); + } + + if (lc($char) eq 'space') + { + print_chars_graphics_list_line("steel_char_space.EDITOR", 7, 4); + } + + if ($char ne $char_skip) + { + print "\n"; + } + + $i++; + } + + print_file_footer($filename_conf_chr_c); +} + +sub print_custom_elements_list +{ + print_file_header($filename_conf_cus_h, $text_cus_h); + + for (my $i = 0; $i < $num_custom_elements; $i++) + { + my $left = sprintf("#define EL_CUSTOM_%d", $i + 1); + + my $tabs_left = get_tabs($left, 5); + + my $right = "(EL_CUSTOM_START + $i)"; + + print "$left$tabs_left$right\n"; + } + + print_file_footer($filename_conf_cus_c); +} + +sub print_group_elements_list +{ + print_file_header($filename_conf_grp_h, $text_grp_h); + + for (my $i = 0; $i < $num_group_elements; $i++) + { + my $left = sprintf("#define EL_GROUP_%d", $i + 1); + + my $tabs_left = get_tabs($left, 5); + + my $right = "(EL_GROUP_START + $i)"; + + print "$left$tabs_left$right\n"; + } + + print_file_footer($filename_conf_grp_c); +} + +sub print_custom_graphics_list +{ + my @extensions1 = + ( + '', + '.xpos', + '.ypos', + '.frames', + ); + my @extensions2 = + ( + '', + '.xpos', + '.ypos', + ); + + print_file_header($filename_conf_cus_c, $text_cus_c); + + for (my $i = 0; $i < $num_custom_elements; $i++) + { + foreach my $ext (@extensions1) + { + my $left = sprintf(" \{ \"custom_%d$ext\",", $i + 1); + + my $tabs_left = get_tabs($left, 6); + + # my $right = ($ext eq '' ? 'RocksElements.pcx' : + my $right = ($ext eq '' ? 'RocksCE.pcx' : + $ext eq '.frames' ? '1' : '0'); + + if ($ext eq '.xpos') + { + # $right = 7; + $right = int($i % 16); + } + elsif ($ext eq '.ypos') + { + # $right = 9; + $right = int($i / 16); + } + + $right = "\"$right\""; + + my $tabs_right = get_tabs($right, 3); + + print "$left$tabs_left$right$tabs_right},\n"; + } + + foreach my $ext (@extensions2) + { + my $left = sprintf(" \{ \"custom_%d.EDITOR$ext\",", $i + 1); + + my $tabs_left = get_tabs($left, 6); + + # my $right = ($ext eq '' ? 'RocksElements.pcx' : '0'); + my $right = ($ext eq '' ? 'RocksCE.pcx' : '0'); + + if ($ext eq '.xpos') + { + # $right = 15; + $right = int($i % 16) + 16; + } + elsif ($ext eq '.ypos') + { + # $right = 13; + $right = int($i / 16); + } + + $right = "\"$right\""; + + my $tabs_right = get_tabs($right, 3); + + print "$left$tabs_left$right$tabs_right},\n"; + } + + print "\n"; + } + + print_file_footer($filename_conf_cus_c); +} + +sub print_group_graphics_list +{ + my @extensions1 = + ( + '', + '.xpos', + '.ypos', + '.frames', + ); + my @extensions2 = + ( + '', + '.xpos', + '.ypos', + ); + + print_file_header($filename_conf_grp_c, $text_grp_c); + + for (my $i = 0; $i < $num_group_elements; $i++) + { + foreach my $ext (@extensions1) + { + my $left = sprintf(" \{ \"group_%d$ext\",", $i + 1); + + my $tabs_left = get_tabs($left, 6); + + # my $right = ($ext eq '' ? 'RocksDC.pcx' : + my $right = ($ext eq '' ? 'RocksCE.pcx' : + $ext eq '.frames' ? '1' : '0'); + + if ($ext eq '.xpos') + { + # $right = 4; + $right = int($i % 16); + } + elsif ($ext eq '.ypos') + { + # $right = 15; + $right = int($i / 16) + int($num_custom_elements / 16); + } + + $right = "\"$right\""; + + my $tabs_right = get_tabs($right, 3); + + print "$left$tabs_left$right$tabs_right},\n"; + } + + foreach my $ext (@extensions2) + { + my $left = sprintf(" \{ \"group_%d.EDITOR$ext\",", $i + 1); + + my $tabs_left = get_tabs($left, 6); + + # my $right = ($ext eq '' ? 'RocksDC.pcx' : '0'); + my $right = ($ext eq '' ? 'RocksCE.pcx' : '0'); + + if ($ext eq '.xpos') + { + # $right = 14; + $right = int($i % 16) + 16; + } + elsif ($ext eq '.ypos') + { + # $right = 15; + $right = int($i / 16) + int($num_custom_elements / 16); + } + + $right = "\"$right\""; + + my $tabs_right = get_tabs($right, 3); + + print "$left$tabs_left$right$tabs_right},\n"; + } + + print "\n"; + } + + print_file_footer($filename_conf_grp_c); +} + +sub get_known_element_definitions_ALTERNATIVE +{ + my %known_element = (); + + my $filename = "$src_path/main.h"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + while () + { + chomp; # cut trailing newline + + # process line with element definition + if (/^\#define (EL_[A-Z0-9_]+)\s/) + { + $known_element{$1} = 1; + + # print STDERR "known_element: '$1'\n"; + } + } + + close FILE; + + return %known_element; +} + +sub get_known_element_definitions +{ + my %known_element = (); + + my $filename = "$src_path/main.c"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + my $element_name = ''; + my $line_is_element_name = 0; + my $skip_line = 1; + + while () + { + chomp; # cut trailing newline + + if (/ELEMENT_INFO_START/) # keyword to start parsing file + { + $skip_line = 0; + next; + } + elsif (/ELEMENT_INFO_END/) # keyword to stop parsing file + { + last; + } + elsif ($skip_line) + { + next; + } + + if (/^\s+\{\s*$/) + { + $line_is_element_name = 1; + } + elsif ($line_is_element_name) + { + # process line with element name definition + if (/^\s+\"(.+)\",?\s*$/) + { + $element_name = 'EL_' . uc($1); + + # dirty hack for making "[default]" work as an element name + $element_name =~ s/\[//; + $element_name =~ s/\]//; + + # change '.' to '_' for elements like "dynamite.active" + $element_name =~ s/\./_/g; + + $known_element{$element_name} = 1; + + # printf STDERR "::: known element '$element_name'\n"; + } + + $line_is_element_name = 0; + } + } + + close FILE; + + return %known_element; +} + +sub get_known_element_class_definitions +{ + my %known_element_class = (); + + my $filename = "$src_path/main.c"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + my $element_name = ''; + my $element_class = ''; + my $line_is_element_name = 0; + my $line_is_element_class = 0; + my $skip_line = 1; + + while () + { + chomp; # cut trailing newline + + if (/ELEMENT_INFO_START/) # keyword to start parsing file + { + $skip_line = 0; + next; + } + elsif (/ELEMENT_INFO_END/) # keyword to stop parsing file + { + last; + } + elsif ($skip_line) + { + next; + } + + if (/^\s+\{\s*$/) + { + $line_is_element_name = 1; + } + elsif ($line_is_element_name) + { + # process line with element name definition + if (/^\s+\"(.+)\",?\s*$/) + { + $element_name = 'EL_' . uc($1); + + # dirty hack for making "[default]" work as an element name + $element_name =~ s/\[//; + $element_name =~ s/\]//; + + # change '.' to '_' for elements like "dynamite.active" + $element_name =~ s/\./_/g; + } + + $line_is_element_name = 0; + $line_is_element_class = 1; + } + elsif ($line_is_element_class) + { + # process line with element class definition + if (/^\s+\"(.+)\",?\s*$/) + { + $element_class = 'EL_CLASS_' . uc($1); + + if (!defined($known_element_class{$element_class})) + { + $known_element_class{$element_class} = $element_name; + } + + $known_element_class{$element_name} = $element_class; + + # print STDERR "known_element_class: '$element_name' => '$element_class'\n"; + } + + $line_is_element_class = 0; + } + } + + close FILE; + + return %known_element_class; +} + +sub get_known_action_definitions +{ + my %known_action = (); + + my $filename = "$src_path/main.h"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + while () + { + chomp; # cut trailing newline + + # process line with action definition + if (/^\#define ACTION_([A-Z0-9_]+)\s/) + { + $known_action{$1} = 1; + + # print STDERR "known_action: '$1'\n"; + } + } + + close FILE; + + return %known_action; +} + +sub get_known_special_arg_definitions +{ + my %known_special_arg = (); + + my $filename = "$src_path/main.h"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + while () + { + chomp; # cut trailing newline + + # process line with special arg definition + if (/^\#define GFX_SPECIAL_ARG_([A-Z0-9_]+)\s/) + { + if ($1 eq 'CRUMBLED') + { + next; + } + + $known_special_arg{$1} = 1; + + # print STDERR "known_special_arg: '$1'\n"; + } + } + + close FILE; + + return %known_special_arg; +} + +sub get_known_button_definitions +{ + my %known_button = (); + + my $filename = "$src_path/conf_gfx.h"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + while () + { + chomp; # cut trailing newline + + # process line with button definition + if (/^\#define (IMG_MENU_BUTTON[A-Z0-9_]*)\s/) + { + $known_button{$1} = 1; + + # print STDERR "known_button: '$1'\n"; + } + } + + close FILE; + + return %known_button; +} + +sub get_known_font_definitions +{ + my %known_font = (); + + my $filename = "$src_path/main.h"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + while () + { + chomp; # cut trailing newline + + # process line with font definition + if (/^\#define (FONT_[A-Z0-9_]+)\s/) + { + $known_font{$1} = 1; + + # print STDERR "known_font: '$1'\n"; + } + } + + close FILE; + + return %known_font; +} + +sub get_known_sound_prefix_definitions +{ + my %known_sound_prefix = ( 'background' => 1 ); + + return %known_sound_prefix; +} + +sub get_known_music_prefix_definitions +{ + my %known_music_prefix = (); + + my $filename = "$src_path/main.c"; + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + my $prefix_name = ''; + my $skip_line = 1; + + while () + { + chomp; # cut trailing newline + + if (/MusicPrefixInfo/) # keyword to start parsing file + { + $skip_line = 0; + next; + } + elsif (/NULL/ && !$skip_line) # keyword to stop parsing file + { + last; + } + elsif ($skip_line) + { + next; + } + + if (/^\s+{\s+\"(.+)\"/) + { + my $music_prefix = $1; + + $known_music_prefix{$music_prefix} = 1; + + # printf STDERR "::: known music prefix '$music_prefix'\n"; + } + } + + close FILE; + + return %known_music_prefix; +} + +sub print_element_to_graphic_entry +{ + my ($element, $action, $direction, $crumbled, $graphic) = @_; + + my $num_tabs = 5 - int((length($element) + 4 + 1) / 8); + my $tabs = "\t" x $num_tabs; + if ($tabs eq '') + { + $tabs = ' '; + } + + $crumbled = ($crumbled == 1 ? 'TRUE' : 'FALSE'); + + print " {\n"; + print " $element,$tabs$action, $direction, $crumbled,\n"; + print " $graphic\n"; + print " },\n"; +} + +sub print_element_to_special_graphic_entry +{ + my ($element, $special, $graphic) = @_; + + my $num_tabs = 6 - int((length($element) + 4 + 1) / 8); + my $tabs = "\t" x $num_tabs; + if ($tabs eq '') + { + $tabs = ' '; + } + + print " {\n"; + print " $element,$tabs$special,\n"; + print " $graphic\n"; + print " },\n"; +} + +sub print_font_to_graphic_entry +{ + my ($font, $special, $graphic) = @_; + + my $num_tabs = 6 - int((length($font) + 4 + 1) / 8); + my $tabs = "\t" x $num_tabs; + if ($tabs eq '') + { + $tabs = ' '; + } + + print " {\n"; + print " $font,$tabs$special,\n"; + print " $graphic\n"; + print " },\n"; +} + +sub print_element_to_sound_entry +{ + my ($element, $is_class, $action, $sound) = @_; + + my $element_plus_is_class = "$element, $is_class"; + + my $num_tabs = 6 - int((length($element_plus_is_class) + 4 + 1) / 8); + my $tabs = "\t" x $num_tabs; + if ($tabs eq '') + { + $tabs = ' '; + } + + print " {\n"; + print " $element_plus_is_class,$tabs$action,\n"; + print " $sound\n"; + print " },\n"; +} + +sub print_gamemode_to_sound_entry +{ + my ($gamemode, $sound) = @_; + + print " {\n"; + print " $gamemode,\n"; + print " $sound\n"; + print " },\n"; +} + +sub print_gamemode_to_music_entry +{ + my ($gamemode, $music) = @_; + + print " {\n"; + print " $gamemode,\n"; + print " $music\n"; + print " },\n"; +} + +sub print_image_config_var_entry +{ + my ($token, $var) = @_; + + print " {\n"; + print " $token,\n"; + print " $var\n"; + print " },\n"; +} + +sub print_active_state_entry +{ + my ($token, $token_active) = @_; + + print " {\n"; + print " $token,\n"; + print " $token_active\n"; + print " },\n"; +} + +sub print_element_to_graphic_list +{ + my %graphic_without_element = + ( + 'IMG_FLAMES_1_LEFT' => 1, + 'IMG_FLAMES_2_LEFT' => 1, + 'IMG_FLAMES_3_LEFT' => 1, + 'IMG_FLAMES_1_RIGHT' => 1, + 'IMG_FLAMES_2_RIGHT' => 1, + 'IMG_FLAMES_3_RIGHT' => 1, + 'IMG_FLAMES_1_UP' => 1, + 'IMG_FLAMES_2_UP' => 1, + 'IMG_FLAMES_3_UP' => 1, + 'IMG_FLAMES_1_DOWN' => 1, + 'IMG_FLAMES_2_DOWN' => 1, + 'IMG_FLAMES_3_DOWN' => 1, + 'IMG_TWINKLE_BLUE' => 1, + 'IMG_TWINKLE_WHITE' => 1, + ); + + my %additional_mappings = + ( + # file elements which are mapped to runtime elements when playing + + # 'EL_EM_KEY_1_FILE' => 'IMG_EM_KEY_1', + # 'EL_EM_KEY_2_FILE' => 'IMG_EM_KEY_2', + # 'EL_EM_KEY_3_FILE' => 'IMG_EM_KEY_3', + # 'EL_EM_KEY_4_FILE' => 'IMG_EM_KEY_4', + + # new elements which still have no graphic + # 'EL_DOOR_WHITE', => 'IMG_CHAR_QUESTION', + # 'EL_DOOR_WHITE_GRAY', => 'IMG_CHAR_QUESTION', + # 'EL_KEY_WHITE', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_RADIOACTIVITY', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_WHEELCHAIR', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_PARKING', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_ONEWAY', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_HEART', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_TRIANGLE', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_ROUND', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_EXIT', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_YINYANG', => 'IMG_CHAR_QUESTION', + # 'EL_SIGN_OTHER', => 'IMG_CHAR_QUESTION', + 'EL_SIGN_UNUSED_1', => 'IMG_CHAR_QUESTION', + 'EL_SIGN_UNUSED_2', => 'IMG_CHAR_QUESTION', + 'EL_DX_UNKNOWN_15', => 'IMG_CHAR_QUESTION', + 'EL_DX_UNKNOWN_42', => 'IMG_CHAR_QUESTION', + + # file elements with direction which is not defined + 'EL_BD_BUTTERFLY_LEFT' => 'IMG_BD_BUTTERFLY', + 'EL_BD_BUTTERFLY_RIGHT' => 'IMG_BD_BUTTERFLY', + 'EL_BD_BUTTERFLY_UP' => 'IMG_BD_BUTTERFLY', + 'EL_BD_BUTTERFLY_DOWN' => 'IMG_BD_BUTTERFLY', + 'EL_BD_FIREFLY_LEFT' => 'IMG_BD_FIREFLY', + 'EL_BD_FIREFLY_RIGHT' => 'IMG_BD_FIREFLY', + 'EL_BD_FIREFLY_UP' => 'IMG_BD_FIREFLY', + 'EL_BD_FIREFLY_DOWN' => 'IMG_BD_FIREFLY', + ); + + my @unknown_graphics = (); + my %known_element = get_known_element_definitions(); + my %known_action = get_known_action_definitions(); + my %known_special_arg = get_known_special_arg_definitions(); + my %known_direction = + ( + 'LEFT' => 1, + 'RIGHT' => 1, + 'UP' => 1, + 'DOWN' => 1, + 'UPLEFT' => 1, + 'UPRIGHT' => 1, + 'DOWNLEFT' => 1, + 'DOWNRIGHT' => 1, + ); + + # ---------- read graphic file definitions ---------- + + my $filename = "$src_path/conf_gfx.c"; + + print_file_header($filename_conf_e2g_c, $text_e2g_c); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + print "static struct\n"; + print "{\n"; + print " int element;\n"; + print " int action;\n"; + print " int direction;\n"; + print " boolean crumbled;\n"; + print "\n"; + print " int graphic;\n"; + print "}\n"; + print "element_to_graphic[] =\n"; + print "{\n"; + + while () + { + chomp; # cut trailing newline + + if (/NO_MORE_ELEMENT_IMAGES/) # keyword to stop parsing file + { + last; + } + + if (!contains_image_file($_)) # skip all lines without image file + { + next; + } + + s/^ \{ \"//; # cut all leading ... + s/\",.*$//; # ... and trailing garbage + + s/\[(\d+)\]/_$1/; # convert "[1]" to "_1" etc. + + s/\[//; # dirty hack for making "[default]" ... + s/\]//; # ... work as an element name + + my $token = $_; + + if ($token =~ /\.([^\.]+)$/ && defined($known_special_arg{$1})) + { + next; # skip all special definitions + } + + $token = uc($token); # convert all characters to upper case + + my $gfx_action_default = '-1'; + my $gfx_action = $gfx_action_default; + + my $gfx_direction_default = '-1'; + my $gfx_direction = $gfx_direction_default; + + my $gfx_crumbled = '0'; + + my $object = $token; + my $action = ''; + my $direction = ''; + my $crumbled = ''; + + if ($object =~ /^(.*)\.([A-Z0-9]+)$/ && $2 eq 'CRUMBLED') + { + $object = $1; + $crumbled = $2; + + $gfx_crumbled = '1'; + } + + if ($object =~ /^(.*)\.([A-Z0-9]+)$/ && defined($known_direction{$2})) + { + $object = $1; + $direction = $2; + + $gfx_direction = "MV_BIT_$direction"; + $gfx_direction_default = $gfx_direction; + } + + if ($object =~ /^(.*)\.([A-Z0-9_]+)$/ && defined($known_action{$2})) + { + $object = $1; + $action = $2; + + $gfx_action = "ACTION_$action"; + $gfx_action_default = $gfx_action; + } + + $token =~ s/\./_/g; + $object =~ s/\./_/g; # needed for "invisible_sand.active.digging" + + # print STDERR "'$token' => '$object', '$action', '$direction'\n"; + + my $full_element = "EL_$token"; + my $base_element = "EL_$object"; + + my $element = $base_element; + my $graphic = "IMG_$token"; + + my $element_without_crumbled = $full_element; + $element_without_crumbled =~ s/_$crumbled$//; + + my $element_without_direction = $element_without_crumbled; + $element_without_direction =~ s/_$direction$//; + + my $element_without_action = $element_without_direction; + $element_without_action =~ s/_$action$//; + + if (defined($known_element{$full_element})) + { + $element = $full_element; + + $gfx_action_default = '-1'; + $gfx_direction_default = '-1'; + } + + if ($element_without_action eq $element || $action eq '') + { + $element_without_action = ''; + } + + if ($element_without_direction eq $element || $direction eq '') + { + $element_without_direction = ''; + } + + if ($element_without_crumbled eq $element || $crumbled eq '') + { + $element_without_crumbled = ''; + } + + if (defined($graphic_without_element{$graphic})) + { + next; + } + + if (!defined($known_element{$element})) + { + # print STDERR "----- ERROR: unknown element '$element' -----\n"; + + push @unknown_graphics, $graphic; + + next; + } + + if (defined($known_element{$element})) + { + print_element_to_graphic_entry($element, + $gfx_action_default, + $gfx_direction_default, + $gfx_crumbled, + $graphic); + } + + if (defined($known_element{$element_without_action})) + { + print_element_to_graphic_entry($element_without_action, + $gfx_action, + '-1', + $gfx_crumbled, + $graphic); + } + + if (defined($known_element{$element_without_direction})) + { + print_element_to_graphic_entry($element_without_direction, + '-1', + $gfx_direction, + $gfx_crumbled, + $graphic); + } + + if (defined($known_element{$element_without_crumbled})) + { + print_element_to_graphic_entry($element_without_crumbled, + '-1', + '-1', + $gfx_crumbled, + $graphic); + } + } + + # dump list of additional elements + foreach my $element (sort keys %additional_mappings) + { + print_element_to_graphic_entry($element, '-1', '-1', '-1', + $additional_mappings{$element}); + } + + # dump list of character elements + foreach my $char (@chars) + { + my $element = "EL_CHAR_$char"; + my $graphic = "IMG_CHAR_$char"; + + if ($char ne $char_skip) + { + print_element_to_graphic_entry($element, '-1', '-1', '-1',$graphic); + } + } + foreach my $char (@chars) + { + my $element = "EL_STEEL_CHAR_$char"; + my $graphic = "IMG_STEEL_CHAR_$char"; + + if ($char ne $char_skip) + { + print_element_to_graphic_entry($element, '-1', '-1', '-1',$graphic); + } + } + + # dump list of custom elements + for (my $i = 0; $i < $num_custom_elements; $i++) + { + my $element = sprintf("EL_CUSTOM_%d", $i + 1); + my $graphic = sprintf("IMG_CUSTOM_%d", $i + 1); + + print_element_to_graphic_entry($element, '-1', '-1', '-1', $graphic); + } + + # dump list of group elements + for (my $i = 0; $i < $num_group_elements; $i++) + { + my $element = sprintf("EL_GROUP_%d", $i + 1); + my $graphic = sprintf("IMG_GROUP_%d", $i + 1); + + print_element_to_graphic_entry($element, '-1', '-1', '-1', $graphic); + } + + print_element_to_graphic_entry('-1', '-1', '-1', '-1', '-1'); + + print "};\n"; + + close FILE; + + if (scalar(@unknown_graphics) > 0) + { + print STDERR "-" x 79 . "\n"; + print STDERR "The following graphics cannot be associated with any element:\n"; + + foreach my $graphic (@unknown_graphics) + { + print STDERR "- $graphic\n"; + } + + print STDERR "-" x 79 . "\n"; + } + + print_file_footer($filename_conf_e2g_c); +} + +sub print_element_to_special_graphic_list +{ + my %graphic_without_element = + ( + 'IMG_GLOBAL_DOOR' => 1, + ); + + my %additional_mappings = + ( + # old elements which are mapped to other elements when playing + #'EL_BUG' => 'IMG_BUG_RIGHT', + #'EL_SPACESHIP' => 'IMG_SPACESHIP_RIGHT', + #'EL_PACMAN' => 'IMG_PACMAN_RIGHT', + ); + + my @elements_with_editor_graphic = + ( + 'char_space' + ); + + my @unknown_graphics = (); + my %known_element = get_known_element_definitions(); + my %known_special_arg = get_known_special_arg_definitions(); + + # ---------- read graphic file definitions ---------- + + my $filename = "$src_path/conf_gfx.c"; + + print_file_header($filename_conf_esg_c, $text_esg_c); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + print "static struct\n"; + print "{\n"; + print " int element;\n"; + print " int special;\n"; + print "\n"; + print " int graphic;\n"; + print "}\n"; + print "element_to_special_graphic[] =\n"; + print "{\n"; + + while () + { + chomp; # cut trailing newline + + if (/NO_MORE_ELEMENT_IMAGES/) # keyword to stop parsing file + { + last; + } + + if (!contains_image_file($_)) # skip all lines without image file + { + next; + } + + s/^ \{ \"//; # cut all leading ... + s/\",.*$//; # ... and trailing garbage + + my $token = $_; + my $object; + my $special; + + if ($token =~ /^font\./) # skip all font definitions + { + next; + } + + if ($token =~ /^background\./) # skip all background image definitions + { + next; + } + + if ($token =~ /^(.*)\.([^\.]+)$/ && + defined($known_special_arg{$2})) + { + $object = $1; + $special = "GFX_SPECIAL_ARG_" . $2; + } + else + { + next; # skip all default definitions + } + + $token =~ s/(.*)/uc($1)/eg; # convert all characters to upper case + $object =~ s/(.*)/uc($1)/eg; # convert all characters to upper case + + $token =~ s/\./_/g; + $object =~ s/\./_/g; + + # print STDERR "'$token' => '$object'\n"; + + my $element = "EL_$object"; + my $graphic = "IMG_$token"; + + if (defined($graphic_without_element{$graphic})) + { + next; + } + + if (!defined($known_element{$element})) + { + # print STDERR "----- ERROR: unknown element '$element' -----\n"; + + push @unknown_graphics, $graphic; + + next; + } + + print_element_to_special_graphic_entry($element, + $special, + $graphic); + } + + # dump list of additional elements + foreach my $element (sort keys %additional_mappings) + { + print_element_to_special_graphic_entry($element, + 'GFX_SPECIAL_ARG_EDITOR', + $additional_mappings{$element}); + print_element_to_special_graphic_entry($element, + 'GFX_SPECIAL_ARG_PREVIEW', + $additional_mappings{$element}); + } + + # dump list of custom element editor graphics + for (my $i = 0; $i < $num_custom_elements; $i++) + { + my $element = sprintf("EL_CUSTOM_%d", $i + 1); + my $graphic = sprintf("IMG_CUSTOM_%d_EDITOR", $i + 1); + + print_element_to_special_graphic_entry($element, + 'GFX_SPECIAL_ARG_EDITOR', + $graphic); + } + + # dump list of group element editor graphics + for (my $i = 0; $i < $num_group_elements; $i++) + { + my $element = sprintf("EL_GROUP_%d", $i + 1); + my $graphic = sprintf("IMG_GROUP_%d_EDITOR", $i + 1); + + print_element_to_special_graphic_entry($element, + 'GFX_SPECIAL_ARG_EDITOR', + $graphic); + } + + # dump other special editor graphics + foreach my $token (@elements_with_editor_graphic) + { + my $element = 'EL_' . uc($token); + my $graphic = 'IMG_' . uc($token) . '_EDITOR'; + + print_element_to_special_graphic_entry($element, + 'GFX_SPECIAL_ARG_EDITOR', + $graphic); + } + + print_element_to_special_graphic_entry('-1', '-1', '-1'); + + print "};\n"; + + close FILE; + + if (scalar(@unknown_graphics) > 0) + { + print STDERR "-" x 79 . "\n"; + print STDERR "The following graphics cannot be associated with any element:\n"; + + foreach my $graphic (@unknown_graphics) + { + print STDERR "- $graphic\n"; + } + + print STDERR "-" x 79 . "\n"; + } + + print_file_footer($filename_conf_esg_c); +} + +sub print_element_to_sound_list +{ + my %sound_without_action = + ( + 'SND_AMOEBA_TURNING_TO_GEM' => 1, + 'SND_AMOEBA_TURNING_TO_ROCK' => 1, + 'SND_BD_AMOEBA_TURNING_TO_GEM' => 1, + 'SND_BD_AMOEBA_TURNING_TO_ROCK' => 1, + + # no special case anymore after adding action ".splashing" + # 'SND_ACID_SPLASHING' => 1, + ); + + my @unknown_sounds = (); + my %known_element = get_known_element_definitions(); + my %known_element_class = get_known_element_class_definitions(); + my %known_action = get_known_action_definitions(); + + # ---------- read sound file definitions ---------- + + my $filename = "$src_path/conf_snd.c"; + + print_file_header($filename_conf_e2s_c, $text_e2s_c); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + print "static struct\n"; + print "{\n"; + print " int element;\n"; + print " boolean is_class;\n"; + print " int action;\n"; + print "\n"; + print " int sound;\n"; + print "}\n"; + print "element_to_sound[] =\n"; + print "{\n"; + + while () + { + chomp; # cut trailing newline + + if (/NO_MORE_ELEMENT_SOUNDS/) # keyword to stop parsing file + { + last; + } + + if (!contains_sound_file($_)) # skip all lines without sound file + { + next; + } + + s/^ \{ \"//; # cut all leading ... + s/\",.*$//; # ... and trailing garbage + + my $token = $_; + + $token = uc($token); # convert all characters to upper case + + my $snd_action_default = '-1'; + my $snd_action = $snd_action_default; + + my $object = $token; + my $action = ''; + + if ($object =~ /^(.*)\.([A-Z0-9_]+)$/ && defined($known_action{$2})) + { + $object = $1; + $action = $2; + + $snd_action = "ACTION_$action"; + $snd_action_default = $snd_action; + } + + $token =~ s/\./_/g; + $object =~ s/\./_/g; # needed for "invisible_sand.active.digging" + + if ($object =~ /^\[(.+)\]$/) + { + $object = 'CLASS_' . $1; + } + + # print STDERR "'$token' => '$object', '$action'\n"; + + my $full_element = "EL_$token"; + my $base_element = "EL_$object"; + + my $element = $base_element; + my $sound = $token; + + if ($sound =~ /^\[.+\]/) + { + $sound =~ s/\[//; # element class sound; begin ... + $sound =~ s/\]//; # ... and end of definition token + $sound =~ s/^/CLASS_/; # add class identifier + } + + $sound = "SND_$sound"; + + my $element_without_action = $full_element; + $element_without_action =~ s/_$action$//; + + my $element_class_without_action = $full_element; + $element_without_action =~ s/_$action$//; + + if (defined($known_element_class{$full_element})) + { + $element = $full_element; + + $snd_action_default = '-1'; + } + + if ($element_without_action eq $element || $action eq '') + { + $element_without_action = ''; + } + + if (defined($sound_without_action{$sound})) + { + next; + } + + if (!defined($known_element{$element}) && + !defined($known_element_class{$element})) + { + # print STDERR "----- ERROR: unknown element '$element' -----\n"; + + push @unknown_sounds, $sound; + + next; + } + + if (!($element =~ /_CLASS_/) && + defined($known_element{$element})) + { + print_element_to_sound_entry($element, "FALSE", + $snd_action_default, + $sound); + } + + if (!($element =~ /_CLASS_/) && + defined($known_element{$element_without_action})) + { + print_element_to_sound_entry($element_without_action, "FALSE", + $snd_action, + $sound); + } + + if ($element =~ /_CLASS_/ && + defined($known_element_class{$element})) + { + my $class_element = $known_element_class{$element}; + + print_element_to_sound_entry($class_element, "TRUE", + $snd_action_default, + $sound); + } + + if ($element =~ /_CLASS_/ && + defined($known_element_class{$element_without_action})) + { + my $class_element = $known_element_class{$element_without_action}; + + print_element_to_sound_entry($class_element, "TRUE", + $snd_action, + $sound); + } + } + + print_element_to_sound_entry('-1', '-1', '-1', '-1'); + + print "};\n"; + + close FILE; + + if (scalar(@unknown_sounds) > 0) + { + print STDERR "-" x 79 . "\n"; + print STDERR "The following sounds cannot be associated with any element or element class:\n"; + + foreach my $sound (@unknown_sounds) + { + print STDERR "- $sound\n"; + } + + print STDERR "-" x 79 . "\n"; + } + + print_file_footer($filename_conf_e2s_c); +} + +sub print_font_to_graphic_list +{ + my @unknown_graphics = (); + my %known_font = get_known_font_definitions(); + my %known_special_arg = get_known_special_arg_definitions(); + + # ---------- read graphic file definitions ---------- + + my $filename = "$src_path/conf_gfx.c"; + + print_file_header($filename_conf_fnt_c, $text_fnt_c); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + print "static struct\n"; + print "{\n"; + print " int font_nr;\n"; + print " int special;\n"; + print "\n"; + print " int graphic;\n"; + print "}\n"; + print "font_to_graphic[] =\n"; + print "{\n"; + + while () + { + chomp; # cut trailing newline + + if (!contains_image_file($_)) # skip all lines without image file + { + next; + } + + s/^ \{ \"//; # cut all leading ... + s/\",.*$//; # ... and trailing garbage + + my $token = $_; + my $font; + my $special; + my $graphic; + + if ($token =~ /^(font\..*)$/) + { + $font = $token; + $special = '-1'; + + if ($token =~ /^(.*)\.([^\.]+)$/ && + defined($known_special_arg{$2})) + { + $font = $1; + $special = "GFX_SPECIAL_ARG_" . $2; + } + } + else + { + next; # skip all non-font definitions + } + + $token =~ s/(.*)/uc($1)/eg; # convert all characters to upper case + $font =~ s/(.*)/uc($1)/eg; # convert all characters to upper case + + $token =~ s/\./_/g; + $font =~ s/\./_/g; + + # print STDERR "'$token' => '$font'\n"; + + $graphic = "IMG_$token"; + + if (!defined($known_font{$font})) + { + # print STDERR "----- ERROR: unknown font '$font' -----\n"; + + push @unknown_graphics, $graphic; + + next; + } + + print_font_to_graphic_entry($font, + $special, + $graphic); + } + + print_font_to_graphic_entry('-1', '-1', '-1'); + + print "};\n"; + + close FILE; + + if (scalar(@unknown_graphics) > 0) + { + print STDERR "-" x 79 . "\n"; + print STDERR "The following graphics cannot be associated with any font:\n"; + + foreach my $graphic (@unknown_graphics) + { + print STDERR "- $graphic\n"; + } + + print STDERR "-" x 79 . "\n"; + } + + print_file_footer($filename_conf_fnt_c); +} + +sub print_gamemode_to_sound_list +{ + my %known_prefix = get_known_sound_prefix_definitions(); + my %known_special_arg = get_known_special_arg_definitions(); + + # ---------- read music file definitions ---------- + + my $filename = "$src_path/conf_snd.c"; + + print_file_header($filename_conf_g2s_c, $text_g2s_c); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + print "static struct\n"; + print "{\n"; + print " int gamemode;\n"; + print "\n"; + print " int sound;\n"; + print "}\n"; + print "gamemode_to_sound[] =\n"; + print "{\n"; + + while () + { + chomp; # cut trailing newline + + if (!contains_sound_file($_)) # skip all lines without sound file + { + next; + } + + if (/\[not used\]/) + { + next; + } + + s/^ \{ \"//; # cut all leading ... + s/\",.*$//; # ... and trailing garbage + + my $token = $_; + my $gamemode = -1; + # my $level = -1; # ??? + + if (defined($known_prefix{$token})) + { + # no special arg defined + } + elsif ($token =~ /^(.*)\.([^\.]+)$/ && + defined($known_prefix{$1}) && + defined($known_special_arg{$2})) + { + $gamemode = "GFX_SPECIAL_ARG_" . $2; + } + else + { + next; + } + +# if ($token =~ /^(.*)\./ && +# !defined($known_prefix{$1})) +# { +# next; +# } +# +# if ($token =~ /^(.*)\.([^\.]+)$/ && +# defined($known_special_arg{$2})) +# { +# $gamemode = "GFX_SPECIAL_ARG_" . $2; +# } + + $token =~ s/(.*)/uc($1)/eg; # convert all characters to upper case + $token =~ s/\./_/g; + + my $sound = "SND_$token"; + + # print STDERR "'$token' => '$sound'\n"; + + print_gamemode_to_sound_entry($gamemode, $sound); + } + + print_gamemode_to_sound_entry('-1', '-1'); + + print "};\n"; + + close FILE; + + print_file_footer($filename_conf_g2s_c); +} + +sub print_gamemode_to_music_list +{ + my %known_prefix = get_known_music_prefix_definitions(); + my %known_special_arg = get_known_special_arg_definitions(); + + # ---------- read music file definitions ---------- + + my $filename = "$src_path/conf_mus.c"; + + print_file_header($filename_conf_g2m_c, $text_g2m_c); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + print "static struct\n"; + print "{\n"; + print " int gamemode;\n"; + print "\n"; + print " int music;\n"; + print "}\n"; + print "gamemode_to_music[] =\n"; + print "{\n"; + + while () + { + chomp; # cut trailing newline + + if (!contains_music_file($_)) # skip all lines without music file + { + next; + } + + s/^ \{ \"//; # cut all leading ... + s/\",.*$//; # ... and trailing garbage + + my $token = $_; + my $gamemode = -1; + + if (defined($known_prefix{$token})) + { + # no special arg defined + } + elsif ($token =~ /^(.*)\.([^\.]+)$/ && + defined($known_prefix{$1}) && + defined($known_special_arg{$2})) + { + $gamemode = "GFX_SPECIAL_ARG_" . $2; + } + else + { + next; + } + +# my $prefix = $token; +# $prefix =~ s/\..*$//; +# +## if ($token =~ /^(.*)\./ && +## !defined($known_prefix{$1})) +# if (!defined($known_prefix{$prefix})) +# { +# next; +# } +# +# if ($token =~ /^(.*)\.([^\.]+)$/ && +# defined($known_special_arg{$2})) +# { +# $gamemode = "GFX_SPECIAL_ARG_" . $2; +# } + + $token =~ s/(.*)/uc($1)/eg; # convert all characters to upper case + $token =~ s/\./_/g; + + my $music = "MUS_$token"; + + # print STDERR "'$token' => '$music'\n"; + + print_gamemode_to_music_entry($gamemode, $music); + } + + print_gamemode_to_music_entry('-1', '-1'); + + print "};\n"; + + close FILE; + + print_file_footer($filename_conf_g2m_c); +} + +sub print_image_config_vars +{ + # ---------- read graphic file definitions ---------- + + my $filename = "$src_path/conf_gfx.c"; + + print_file_header($filename_conf_var_c, $text_var_c); + + open(FILE, "$filename") || + fail("cannot open file '$filename' for reading"); + + print "struct TokenIntPtrInfo image_config_vars[] =\n"; + print "{\n"; + + my $start_parsing = 0; + + while () + { + chomp; # cut trailing newline + + if (/CONFIG_VARS_START/) # keyword to start parsing file + { + $start_parsing = 1; + } + + if (!$start_parsing) + { + next; + } + + if (/^\s*\{\s*\"([^\"]+)\"/) # config token found + { + my $token = $1; + my $var = $token; + + # --- some prefix replacements --- + + $var =~ s/^main\./menu.main./; + $var =~ s/^\[player\]\./game.player_/; + $var =~ s/^\[title_initial\]/title_initial_default/; + $var =~ s/^\[title\]/title_default/; + $var =~ s/^\[titlemessage_initial\]/titlemessage_initial_default/; + $var =~ s/^\[titlemessage\]/titlemessage_default/; + + if ($var =~ /^titlemessage.*(\d)/ || + $var =~ /^game.panel.key_(\d)/ || + $var =~ /^game.panel.inventory_first_(\d)/ || + $var =~ /^game.panel.inventory_last_(\d)/ || + $var =~ /^game.panel.conveyor_belt_(\d)\./ || + $var =~ /^game.panel.element_(\d)\./ || + $var =~ /^game.panel.graphic_(\d)\./ || + $var =~ /^game.panel.ce_score_(\d)\./) + { + my $number = $1; + my $array_pos = int($number) - 1; + $var =~ s/_$number/\[$array_pos\]/; + } + elsif ($var =~ /^game.panel.conveyor_belt_(\d)(_switch)/ || + $var =~ /^game.panel.element_(\d)(_count)/ || + $var =~ /^game.panel.ce_score_(\d)(_element)/) + { + my $number = $1; + my $suffix = $2; + my $array_pos = int($number) - 1; + $var =~ s/_$number$suffix/$suffix\[$array_pos\]/; + } + + # --- some suffix replacements --- + + $var =~ s/^(menu\.main\..*)\.chars$/$1.size/; + $var =~ s/^(game\.panel\..*)\.chars$/$1.size/; + $var =~ s/^(game\.panel\..*)\.tile_size$/$1.size/; + $var =~ s/\.digits$/.size/; + $var =~ s/\.element$/.id/; + $var =~ s/\.draw_order$/.sort_priority/; + + $var =~ s/\.font_[a-z]+$/.font_alt/; + $var =~ s/\.INFO\[([A-Z]+)\]$/_info\[GFX_SPECIAL_ARG_INFO_$1\]/; + $var =~ s/\.SETUP\[([A-Z0-9_]+)\]$/_setup\[GFX_SPECIAL_ARG_SETUP_$1\]/; + $var =~ s/\.([A-Z]+)$/\[GFX_SPECIAL_ARG_$1\]/; + $var =~ s/\.([A-Z]+)\./\[GFX_SPECIAL_ARG_$1\]./; + + if ($var =~ /^(menu.(enter|leave)_screen)(.[a-z_]+)$/) + { + $var = $1 . "[GFX_SPECIAL_ARG_DEFAULT]" . $3; + } + + if ($var =~ /^menu.(draw_[xy]offset|list_size)$/) + { + $var .= "[GFX_SPECIAL_ARG_DEFAULT]"; + } + + if ($var =~ /^(viewport.(playfield|door_[12]))(.[a-z_]+)$/) + { + $var = $1 . "[GFX_SPECIAL_ARG_DEFAULT]" . $3; + } + + print_image_config_var_entry("\"$token\"", "&$var"); + } + } + + print_image_config_var_entry('NULL', 'NULL'); + + print "};\n"; + + close FILE; + + print_file_footer($filename_conf_var_c); +} + +sub print_active_states +{ + # ---------- read graphic file definitions ---------- + + my %known_element = get_known_element_definitions(); + my %known_button = get_known_button_definitions(); + my %known_font = get_known_font_definitions(); + + print_file_header($filename_conf_act_c, $text_act_c); + + print "static struct\n"; + print "{\n"; + print " int element;\n"; + print " int element_active;\n"; + print "}\n"; + print "element_with_active_state[] =\n"; + print "{\n"; + + foreach my $element (sort keys %known_element) + { + my $element_active = $element . '_ACTIVE'; + + if (defined($known_element{$element_active})) + { + print_active_state_entry($element, $element_active); + } + } + + print_active_state_entry('-1', '-1'); + + print "};\n"; + + print "\n"; + print "\n"; + print "static struct\n"; + print "{\n"; + print " int button;\n"; + print " int button_active;\n"; + print "}\n"; + print "button_with_active_state[] =\n"; + print "{\n"; + + foreach my $button (sort keys %known_button) + { + my $button_active = $button . '_ACTIVE'; + + if (defined($known_button{$button_active})) + { + print_active_state_entry($button, $button_active); + } + } + + print_active_state_entry('-1', '-1'); + + print "};\n"; + + print "\n"; + print "\n"; + print "static struct\n"; + print "{\n"; + print " int font_nr;\n"; + print " int font_nr_active;\n"; + print "}\n"; + print "font_with_active_state[] =\n"; + print "{\n"; + + foreach my $font (sort keys %known_font) + { + my $font_active = $font . '_ACTIVE'; + + if (defined($known_font{$font_active})) + { + print_active_state_entry($font, $font_active); + } + } + + print_active_state_entry('-1', '-1'); + + print "};\n"; + + print_file_footer($filename_conf_act_c); +} + + +# ============================================================================= +# M A I N - P R O G R A M +# ============================================================================= + +sub main +{ + my $argc = scalar(@ARGV); + + if ($argc == 0 || $ARGV[0] eq '-h' || $ARGV[0] eq '--help') + { + print "Usage: $0 \n\n"; + print "Choose from the following list:\n"; + print "- '$filename_conf_gfx_h'\n"; + print "- '$filename_conf_snd_h'\n"; + print "- '$filename_conf_mus_h'\n"; + print "- '$filename_conf_chr_c'\n"; + print "- '$filename_conf_chr_h'\n"; + print "- '$filename_conf_cus_c'\n"; + print "- '$filename_conf_cus_h'\n"; + print "- '$filename_conf_grp_c'\n"; + print "- '$filename_conf_grp_h'\n"; + print "- '$filename_conf_e2g_c'\n"; + print "- '$filename_conf_esg_c'\n"; + print "- '$filename_conf_fnt_c'\n"; + print "- '$filename_conf_g2s_c'\n"; + print "- '$filename_conf_g2m_c'\n"; + print "- '$filename_conf_var_c'\n"; + print "- '$filename_conf_act_c'\n"; + + exit 1; + } + + if ($ARGV[0] eq $filename_conf_gfx_h) + { + print_graphics_list(); + } + elsif ($ARGV[0] eq $filename_conf_snd_h) + { + print_sounds_list(); + } + elsif ($ARGV[0] eq $filename_conf_mus_h) + { + print_music_list(); + } + elsif ($ARGV[0] eq $filename_conf_chr_c) + { + print_chars_graphics_list(); + } + elsif ($ARGV[0] eq $filename_conf_chr_h) + { + print_chars_elements_list(); + } + elsif ($ARGV[0] eq $filename_conf_cus_c) + { + print_custom_graphics_list(); + } + elsif ($ARGV[0] eq $filename_conf_cus_h) + { + print_custom_elements_list(); + } + elsif ($ARGV[0] eq $filename_conf_grp_c) + { + print_group_graphics_list(); + } + elsif ($ARGV[0] eq $filename_conf_grp_h) + { + print_group_elements_list(); + } + elsif ($ARGV[0] eq $filename_conf_e2g_c) + { + print_element_to_graphic_list(); + } + elsif ($ARGV[0] eq $filename_conf_esg_c) + { + print_element_to_special_graphic_list(); + } + elsif ($ARGV[0] eq $filename_conf_e2s_c) + { + print_element_to_sound_list(); + } + elsif ($ARGV[0] eq $filename_conf_fnt_c) + { + print_font_to_graphic_list(); + } + elsif ($ARGV[0] eq $filename_conf_g2s_c) + { + print_gamemode_to_sound_list(); + } + elsif ($ARGV[0] eq $filename_conf_g2m_c) + { + print_gamemode_to_music_list(); + } + elsif ($ARGV[0] eq $filename_conf_var_c) + { + print_image_config_vars(); + } + elsif ($ARGV[0] eq $filename_conf_act_c) + { + print_active_states(); + } + else + { + print "Unknown option '$ARGV[0]'.\n"; + + exit 1; + } + + exit 0; +} diff --git a/src/Makefile b/src/Makefile index ba627295..853c415b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -146,7 +146,7 @@ CONFIG_GAME_DIR = $(CONFIG_RO_GAME_DIR) $(CONFIG_RW_GAME_DIR) CONFIG_GAME = $(CONFIG_GAME_DIR) $(CONFIG_SCORE_ENTRIES) $(CONFIG_SPECIAL) CONFIG = $(CONFIG_GAME) $(JOYSTICK) -DEBUG = -DDEBUG -g +# DEBUG = -DDEBUG -g # PROFILING = $(PROFILING_FLAGS) # OPTIONS = $(DEBUG) -Wall # only for debugging purposes @@ -220,7 +220,7 @@ CNFS = conf_gfx.h \ conf_var.c \ conf_act.c -CNFS_CMD = ../Scripts/create_element_defs.pl +CNFS_CMD = ../build-scripts/create_element_defs.pl TIMESTAMP_FILE = conftime.h diff --git a/src/conftime.h b/src/conftime.h index 0b68beac..f0fbdec7 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2013-10-28 20:34" +#define COMPILE_DATE_STRING "2013-11-04 00:44" diff --git a/src/main.h b/src/main.h index c484b859..738e39b9 100644 --- a/src/main.h +++ b/src/main.h @@ -2070,7 +2070,7 @@ #define PROGRAM_TITLE_STRING "Rocks'n'Diamonds" #define PROGRAM_AUTHOR_STRING "Holger Schemel" -#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2010 by Holger Schemel" +#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2013 by Holger Schemel" #define PROGRAM_EMAIL_STRING "info@artsoft.org" #define PROGRAM_WEBSITE_STRING "http://www.artsoft.org/" #define PROGRAM_GAME_BY_STRING "A Game by Artsoft Entertainment" diff --git a/src/screens.c b/src/screens.c index b56ffe58..8c387852 100644 --- a/src/screens.c +++ b/src/screens.c @@ -2883,6 +2883,18 @@ void DrawInfoScreen_Program() "If you like it, send e-mail to:"); DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_3, PROGRAM_EMAIL_STRING); +#if 1 + DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + "More information and levels:"); + DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, + PROGRAM_WEBSITE_STRING); + DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_2, + "If you have created new levels,"); + DrawTextSCentered(ystart2 + 8 * ystep, FONT_TEXT_2, + "send them to me to include them!"); + DrawTextSCentered(ystart2 + 9 * ystep, FONT_TEXT_2, + ":-)"); +#else DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_2, "or SnailMail to:"); DrawTextSCentered(ystart2 + 4 * ystep + 0, FONT_TEXT_3, @@ -2903,6 +2915,7 @@ void DrawInfoScreen_Program() "send them to me to include them!"); DrawTextSCentered(ystart2 + 11 * ystep, FONT_TEXT_2, ":-)"); +#endif DrawTextSCentered(ybottom, FONT_TEXT_4, "Press any key or button for info menu"); -- 2.34.1