From: Holger Schemel Date: Sat, 30 Aug 2014 08:53:58 +0000 (+0200) Subject: Merge branch 'master' into releases X-Git-Tag: 3.2.3^0 X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=commitdiff_plain;h=8cbfc8a88d2eeb5400bad0ff556af7486532188f;hp=b6764658a537d18821afe606350e26d95b6daff6 Merge branch 'master' into releases --- diff --git a/ChangeLog b/ChangeLog index 960d5063..4f8bd9d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,135 @@ +2007-01-05 + * version 3.2.3 released + +2007-01-04 + * fixed malloc/free bug when updating EMC artwork entries in level list + * added workaround (warning and request to quit the current game) when + changing elements cause endless recursion loop (which would otherwise + freeze the game, causing a crash-like program exit on some systems) + +2006-12-16 + * fixed nasty string overflow bug when entering too long envelope text + +2006-12-05 + * added feedback sounds for menu navigation "menu.item.activating" and + "menu.item.selecting" (for highlighting and executing menu entries) + +2006-12-03 + * improved "no scrolling when relocating" to also consider scroll delay + (meaning that the player is not automatically centered in this case; + this makes it possible to "invisibly" relocate the player to a region + of the level playfield which looks the same as the old level region) + * fixed bug with not recognizing "main.input.name.align" when active + +2006-12-02 + * fixed bug with displaying masked borders over title screens when + screen fading is disabled + +2006-11-25 + * fixed infinite loop / crash bug when killing the player while having + a CE with the setting "kill player X when explosion of " + * added special editor graphic for "char_space" to distinguish it from + "empty_space" when editing a level (in-game graphics still the same) + +2006-11-21 + * fixed nasty bug with initialization only done for the first player + +2006-11-19 + * small change to handle loading empty element/content list micro chunks + +2006-11-03 + * uploaded pre-release (test) version 3.2.3-0 binary and source code + +2006-11-01 + * some optimizations on startup speed by reducing initial text output + +2006-10-30 + * added caching of custom artwork information for faster startup times + +2006-10-29 + * fixed graphical bug when using fewer menu entries on level selection + screen than usual (with "menu.list_size.LEVELS" directive) + * fixed crash bug (Windows/SDL only) caused by BlitBitmap blitting from + the backbuffer to the backbuffer by error (with identical rectangle) + +2006-10-28 + * fixed bug when displaying titlescreen with size less than element tile + * fixed bug that caused elements with "change when digging " event + to change for _every_ digged element, not only those specified in + * fixed bug that caused impact style collision when dropping element one + tile over the player that can both fall down and smash players + * fixed bug that caused impact style collision when element changed to + falling/smashing element over the player immediately after movement + +2006-10-24 + * fixed bug that allowed making engine snapshots from the level editor + +2006-10-22 + * fixed bugs with player name and current level positions on main screen + +2006-10-20 + * added configuration directives for control of title screens: + - "title.fade_delay" for fading time + - "title.post_delay" for pause between screens (when not crossfading) + - "title.auto_delay" to automatically continue after some time + these settings can each be overridden by specifying them with titles: + - "titlescreen_initial_{1-5}.{fade_delay,post_delay,auto_delay}" + - "titlescreen_{1-5}.{fade_delay,post_delay,auto_delay}" + fading mode can also be specified: + - "titlescreen_initial_{1-5}.anim_mode: {fade,crossfade} + - "titlescreen_{1-5}.anim_mode: {fade,crossfade} + default is using normal fading for menues and initial title screens, + while using cross-fading for level set title screens + * fixed bug with background not drawn in Hall of Fame after game was won + +2006-10-18 + * added configuration directives for the remaining main menu items + +2006-10-17 + * added additional configuration directives for info screen draw offset: + menu.draw_{x,y}offset.INFO[{ELEMENTS,MUSIC,CREDITS,PROGRAM,LEVELSET}] + * added additional configuration directives for preview info text + * limited mouse wheel sensitive screen area to scrollable screen area + +2006-10-16 + * added highlighted menu text entries to menu navigation when selected + +2006-10-14 + * fixed bug that prevented player from correctly being created in the + top left corner by a custom element change in a level without player + * fixed bug that prevented player from being killed when indestructible, + non-walkable element is placed on player position by extended change + * added configurable menu button, text and input positions to main menu + +2006-10-13 + * added page fading effects for remaining info sub-screens + * fixed small bug that caused some delays when answering door request + +2006-10-12 + * added directives "border.draw_masked.*" for menu/playfield area and + door areas to display overlapping/masked borders from "global.border" + +2006-10-09 + * fixed bug with CE with move speed "not moving" not being animated + * when changing player artwork by CE action, reset animation frame + +2006-10-03 + * fixed bug with not unmapping main menu screen gadgets on other screens + * fixed bug with un-pausing a paused game by releasing still pressed key + * fixed bug with not redrawing screen when toggling to/from fullscreen + mode while fast reloading tape (without redrawing playfield contents) + * fixed bug with quick-saving tape snapshot despite answering with "no" + +2006-08-30 + * version number set to 3.2.3 + +2006-08-29 + * version 3.2.2 released + 2006-08-29 * fixed bug with redrawing screen in fullscreen mode after quick tape reloading when using the EMC game engine + * changed token names from "last_ce_[1-8]" to "prev_ce_[1-8]" 2006-08-28 * fixed bug in GameWon() when level contains no exit (like in Sokoban) diff --git a/src/conf_chr.c b/src/conf_chr.c index a3f0ed1b..a797319a 100644 --- a/src/conf_chr.c +++ b/src/conf_chr.c @@ -22,6 +22,10 @@ { "char_space.xpos", "0" }, { "char_space.ypos", "0" }, { "char_space.frames", "1" }, + { "char_space.EDITOR", "RocksFontEM.pcx" }, + { "char_space.EDITOR.xpos", "7" }, + { "char_space.EDITOR.ypos", "4" }, + { "char_space.EDITOR.frames", "1" }, { "char_exclam", "RocksFontEM.pcx" }, { "char_exclam.xpos", "1" }, diff --git a/src/conf_esg.c b/src/conf_esg.c index 26706901..29cba335 100644 --- a/src/conf_esg.c +++ b/src/conf_esg.c @@ -1511,6 +1511,10 @@ element_to_special_graphic[] = EL_GROUP_32, GFX_SPECIAL_ARG_EDITOR, IMG_GROUP_32_EDITOR }, + { + EL_CHAR_SPACE, GFX_SPECIAL_ARG_EDITOR, + IMG_CHAR_SPACE_EDITOR + }, { -1, -1, -1 diff --git a/src/conf_fnt.c b/src/conf_fnt.c index bc2f1d01..35d60b91 100644 --- a/src/conf_fnt.c +++ b/src/conf_fnt.c @@ -55,10 +55,18 @@ font_to_graphic[] = FONT_MENU_1, -1, IMG_FONT_MENU_1 }, + { + FONT_MENU_1_ACTIVE, -1, + IMG_FONT_MENU_1_ACTIVE + }, { FONT_MENU_2, -1, IMG_FONT_MENU_2 }, + { + FONT_MENU_2_ACTIVE, -1, + IMG_FONT_MENU_2_ACTIVE + }, { FONT_TEXT_1, -1, IMG_FONT_TEXT_1 diff --git a/src/conf_g2m.c b/src/conf_g2m.c index 1be3ed4f..447025c1 100644 --- a/src/conf_g2m.c +++ b/src/conf_g2m.c @@ -34,6 +34,10 @@ gamemode_to_music[] = GFX_SPECIAL_ARG_TITLE, MUS_BACKGROUND_TITLE }, + { + GFX_SPECIAL_ARG_MESSAGE, + MUS_BACKGROUND_MESSAGE + }, { GFX_SPECIAL_ARG_MAIN, MUS_BACKGROUND_MAIN diff --git a/src/conf_g2s.c b/src/conf_g2s.c index 059f8118..b4c9ff8f 100644 --- a/src/conf_g2s.c +++ b/src/conf_g2s.c @@ -30,6 +30,10 @@ gamemode_to_sound[] = GFX_SPECIAL_ARG_TITLE, SND_BACKGROUND_TITLE }, + { + GFX_SPECIAL_ARG_MESSAGE, + SND_BACKGROUND_MESSAGE + }, { GFX_SPECIAL_ARG_MAIN, SND_BACKGROUND_MAIN diff --git a/src/conf_gfx.c b/src/conf_gfx.c index b67f1f53..6a8faeec 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -60,6 +60,9 @@ struct ConfigTypeInfo image_config_suffix[] = { ".name", ARG_UNDEFINED, TYPE_STRING }, { ".scale_up_factor", ARG_UNDEFINED, TYPE_INTEGER }, { ".clone_from", ARG_UNDEFINED, TYPE_TOKEN }, + { ".fade_delay", ARG_UNDEFINED, TYPE_INTEGER }, + { ".post_delay", ARG_UNDEFINED, TYPE_INTEGER }, + { ".auto_delay", ARG_UNDEFINED, TYPE_INTEGER }, { NULL, NULL, 0 } }; @@ -4184,10 +4187,10 @@ struct ConfigInfo image_config[] = { "menu.button_next_level.clone_from", "menu.button_right" }, { "menu.button_next_level.active", "RocksDC.pcx" }, { "menu.button_next_level.active.clone_from", "menu.button_right.active" }, - { "menu.button_last_level", "RocksDC.pcx" }, - { "menu.button_last_level.clone_from", "menu.button_left" }, - { "menu.button_last_level.active", "RocksDC.pcx" }, - { "menu.button_last_level.active.clone_from", "menu.button_left.active" }, + { "menu.button_prev_level", "RocksDC.pcx" }, + { "menu.button_prev_level.clone_from", "menu.button_left" }, + { "menu.button_prev_level.active", "RocksDC.pcx" }, + { "menu.button_prev_level.active.clone_from", "menu.button_left.active" }, { "menu.scrollbar", "RocksDC.pcx" }, { "menu.scrollbar.xpos", "8" }, @@ -4235,11 +4238,21 @@ struct ConfigInfo image_config[] = { "font.menu_1.y", "320" }, { "font.menu_1.width", "32" }, { "font.menu_1.height", "32" }, + { "font.menu_1.active", "RocksFontBig.pcx" }, + { "font.menu_1.active.x", "0" }, + { "font.menu_1.active.y", "480" }, + { "font.menu_1.active.width", "32" }, + { "font.menu_1.active.height", "32" }, { "font.menu_2", "RocksFontMedium.pcx" }, { "font.menu_2.x", "0" }, { "font.menu_2.y", "320" }, { "font.menu_2.width", "16" }, { "font.menu_2.height", "32" }, + { "font.menu_2.active", "RocksFontMedium.pcx" }, + { "font.menu_2.active.x", "0" }, + { "font.menu_2.active.y", "480" }, + { "font.menu_2.active.width", "16" }, + { "font.menu_2.active.height", "32" }, { "font.text_1", "RocksFontSmall.pcx" }, { "font.text_1.x", "0" }, @@ -4487,14 +4500,9 @@ struct ConfigInfo image_config[] = { "background.envelope_4.anim_mode", "default" }, { "background.envelope_4.draw_masked", "false" }, - { "titlescreen_1", UNDEFINED_FILENAME }, - { "titlescreen_2", UNDEFINED_FILENAME }, - { "titlescreen_3", UNDEFINED_FILENAME }, - { "titlescreen_4", UNDEFINED_FILENAME }, - { "titlescreen_5", UNDEFINED_FILENAME }, - { "background", UNDEFINED_FILENAME }, { "background.TITLE", UNDEFINED_FILENAME }, + { "background.MESSAGE", UNDEFINED_FILENAME }, { "background.MAIN", UNDEFINED_FILENAME }, { "background.LEVELS", UNDEFINED_FILENAME }, { "background.SCORES", UNDEFINED_FILENAME }, @@ -4508,11 +4516,40 @@ struct ConfigInfo image_config[] = { "background.SETUP", UNDEFINED_FILENAME }, { "background.DOOR", UNDEFINED_FILENAME }, + { "titlescreen_initial_1", UNDEFINED_FILENAME }, + { "titlescreen_initial_2", UNDEFINED_FILENAME }, + { "titlescreen_initial_3", UNDEFINED_FILENAME }, + { "titlescreen_initial_4", UNDEFINED_FILENAME }, + { "titlescreen_initial_5", UNDEFINED_FILENAME }, + { "titlescreen_1", UNDEFINED_FILENAME }, + { "titlescreen_2", UNDEFINED_FILENAME }, + { "titlescreen_3", UNDEFINED_FILENAME }, + { "titlescreen_4", UNDEFINED_FILENAME }, + { "titlescreen_5", UNDEFINED_FILENAME }, + /* the following directives are not associated with an image, but probably make sense to be defined in "graphicsinfo.conf", too */ { "global.num_toons", "20" }, + { "border.draw_masked.TITLE", "false" }, + { "border.draw_masked.MAIN", "false" }, + { "border.draw_masked.LEVELS", "false" }, + { "border.draw_masked.SCORES", "false" }, + { "border.draw_masked.EDITOR", "false" }, + { "border.draw_masked.INFO", "false" }, + { "border.draw_masked.SETUP", "false" }, + { "border.draw_masked.PLAYING", "false" }, + { "border.draw_masked.DOOR", "false" }, + + { "title.fade_delay", "500" }, + { "title.post_delay", "250" }, + { "title.auto_delay", "-1" }, + + { "menu.fade_delay", "250" }, + { "menu.post_delay", "125" }, + { "menu.auto_delay", "-1" }, + { "menu.draw_xoffset", "0" }, { "menu.draw_yoffset", "0" }, { "menu.draw_xoffset.MAIN", "0" }, @@ -4525,6 +4562,16 @@ struct ConfigInfo image_config[] = { "menu.draw_yoffset.EDITOR", "0" }, { "menu.draw_xoffset.INFO", "0" }, { "menu.draw_yoffset.INFO", "0" }, + { "menu.draw_xoffset.INFO[ELEMENTS]", "0" }, + { "menu.draw_yoffset.INFO[ELEMENTS]", "0" }, + { "menu.draw_xoffset.INFO[MUSIC]", "0" }, + { "menu.draw_yoffset.INFO[MUSIC]", "0" }, + { "menu.draw_xoffset.INFO[CREDITS]", "0" }, + { "menu.draw_yoffset.INFO[CREDITS]", "0" }, + { "menu.draw_xoffset.INFO[PROGRAM]", "0" }, + { "menu.draw_yoffset.INFO[PROGRAM]", "0" }, + { "menu.draw_xoffset.INFO[LEVELSET]", "0" }, + { "menu.draw_yoffset.INFO[LEVELSET]", "0" }, { "menu.draw_xoffset.SETUP", "0" }, { "menu.draw_yoffset.SETUP", "0" }, @@ -4535,8 +4582,109 @@ struct ConfigInfo image_config[] = { "menu.list_size.SCORES", "-1" }, { "menu.list_size.INFO", "-1" }, - { "menu.fade_delay", "250" }, - { "menu.post_delay", "125" }, + { "main.button.name.x", "0" }, + { "main.button.name.y", "64" }, + { "main.button.levels.x", "0" }, + { "main.button.levels.y", "96" }, + { "main.button.scores.x", "0" }, + { "main.button.scores.y", "128" }, + { "main.button.editor.x", "0" }, + { "main.button.editor.y", "160" }, + { "main.button.info.x", "0" }, + { "main.button.info.y", "192" }, + { "main.button.game.x", "0" }, + { "main.button.game.y", "224" }, + { "main.button.setup.x", "0" }, + { "main.button.setup.y", "256" }, + { "main.button.quit.x", "0" }, + { "main.button.quit.y", "288" }, + + { "main.button.prev_level.x", "320" }, + { "main.button.prev_level.y", "96" }, + { "main.button.next_level.x", "448" }, + { "main.button.next_level.y", "96" }, + + { "main.text.name.x", "-1" }, + { "main.text.name.y", "-1" }, + { "main.text.name.width", "-1" }, + { "main.text.name.height", "-1" }, + { "main.text.name.align", "left" }, + { "main.text.levels.x", "-1" }, + { "main.text.levels.y", "-1" }, + { "main.text.levels.width", "-1" }, + { "main.text.levels.height", "-1" }, + { "main.text.levels.align", "left" }, + { "main.text.scores.x", "-1" }, + { "main.text.scores.y", "-1" }, + { "main.text.scores.width", "-1" }, + { "main.text.scores.height", "-1" }, + { "main.text.scores.align", "left" }, + { "main.text.editor.x", "-1" }, + { "main.text.editor.y", "-1" }, + { "main.text.editor.width", "-1" }, + { "main.text.editor.height", "-1" }, + { "main.text.editor.align", "left" }, + { "main.text.info.x", "-1" }, + { "main.text.info.y", "-1" }, + { "main.text.info.width", "-1" }, + { "main.text.info.height", "-1" }, + { "main.text.info.align", "left" }, + { "main.text.game.x", "-1" }, + { "main.text.game.y", "-1" }, + { "main.text.game.width", "-1" }, + { "main.text.game.height", "-1" }, + { "main.text.game.align", "left" }, + { "main.text.setup.x", "-1" }, + { "main.text.setup.y", "-1" }, + { "main.text.setup.width", "-1" }, + { "main.text.setup.height", "-1" }, + { "main.text.setup.align", "left" }, + { "main.text.quit.x", "-1" }, + { "main.text.quit.y", "-1" }, + { "main.text.quit.width", "-1" }, + { "main.text.quit.height", "-1" }, + { "main.text.quit.align", "left" }, + + { "main.text.current_level.x", "352" }, + { "main.text.current_level.y", "96" }, + { "main.text.current_level.align", "left" }, + { "main.text.first_level.x", "488" }, + { "main.text.first_level.y", "98" }, + { "main.text.first_level.align", "left" }, + { "main.text.last_level.x", "488" }, + { "main.text.last_level.y", "112" }, + { "main.text.last_level.align", "left" }, + { "main.text.level_info_1.x", "272" }, + { "main.text.level_info_1.y", "352" }, + { "main.text.level_info_1.align", "center" }, + { "main.text.level_info_2.x", "272" }, + { "main.text.level_info_2.y", "523" }, + { "main.text.level_info_2.align", "center" }, + { "main.text.title_1.x", "272" }, + { "main.text.title_1.y", "8" }, + { "main.text.title_1.align", "center" }, + { "main.text.title_2.x", "272" }, + { "main.text.title_2.y", "46" }, + { "main.text.title_2.align", "center" }, + { "main.text.title_3.x", "272" }, + { "main.text.title_3.y", "326" }, + { "main.text.title_3.align", "center" }, + + { "main.input.name.x", "-1" }, + { "main.input.name.y", "-1" }, + { "main.input.name.align", "left" }, + + { "preview.x", "272" }, + { "preview.y", "380" }, + { "preview.align", "center" }, + { "preview.xsize", "66" }, + { "preview.ysize", "34" }, + { "preview.xoffset", "0" }, + { "preview.yoffset", "0" }, + { "preview.tile_size", "4" }, + { "preview.step_offset", "1" }, + { "preview.step_delay", "50" }, + { "preview.anim_mode", "default" }, { "door_1.width", "-1" }, { "door_1.height", "-1" }, @@ -4550,14 +4698,6 @@ struct ConfigInfo image_config[] = { "door_2.step_delay", "10" }, { "door_2.anim_mode", "default" }, - { "preview.x", "148" }, - { "preview.y", "388" }, - { "preview.xsize", "66" }, - { "preview.ysize", "34" }, - { "preview.tile_size", "4" }, - { "preview.step_offset", "1" }, - { "preview.step_delay", "50" }, - { "game.panel.level.x", "37" }, { "game.panel.level.y", "20" }, { "game.panel.gems.x", "29" }, diff --git a/src/conf_gfx.h b/src/conf_gfx.h index 332c6ac0..f5c777a3 100644 --- a/src/conf_gfx.h +++ b/src/conf_gfx.h @@ -814,773 +814,782 @@ #define IMG_EMC_DRIPPER_EDITOR 793 #define IMG_EMC_DRIPPER_ACTIVE 794 #define IMG_CHAR_SPACE 795 -#define IMG_CHAR_EXCLAM 796 -#define IMG_CHAR_QUOTEDBL 797 -#define IMG_CHAR_NUMBERSIGN 798 -#define IMG_CHAR_DOLLAR 799 -#define IMG_CHAR_PERCENT 800 -#define IMG_CHAR_AMPERSAND 801 -#define IMG_CHAR_APOSTROPHE 802 -#define IMG_CHAR_PARENLEFT 803 -#define IMG_CHAR_PARENRIGHT 804 -#define IMG_CHAR_ASTERISK 805 -#define IMG_CHAR_PLUS 806 -#define IMG_CHAR_COMMA 807 -#define IMG_CHAR_MINUS 808 -#define IMG_CHAR_PERIOD 809 -#define IMG_CHAR_SLASH 810 -#define IMG_CHAR_0 811 -#define IMG_CHAR_1 812 -#define IMG_CHAR_2 813 -#define IMG_CHAR_3 814 -#define IMG_CHAR_4 815 -#define IMG_CHAR_5 816 -#define IMG_CHAR_6 817 -#define IMG_CHAR_7 818 -#define IMG_CHAR_8 819 -#define IMG_CHAR_9 820 -#define IMG_CHAR_COLON 821 -#define IMG_CHAR_SEMICOLON 822 -#define IMG_CHAR_LESS 823 -#define IMG_CHAR_EQUAL 824 -#define IMG_CHAR_GREATER 825 -#define IMG_CHAR_QUESTION 826 -#define IMG_CHAR_AT 827 -#define IMG_CHAR_A 828 -#define IMG_CHAR_B 829 -#define IMG_CHAR_C 830 -#define IMG_CHAR_D 831 -#define IMG_CHAR_E 832 -#define IMG_CHAR_F 833 -#define IMG_CHAR_G 834 -#define IMG_CHAR_H 835 -#define IMG_CHAR_I 836 -#define IMG_CHAR_J 837 -#define IMG_CHAR_K 838 -#define IMG_CHAR_L 839 -#define IMG_CHAR_M 840 -#define IMG_CHAR_N 841 -#define IMG_CHAR_O 842 -#define IMG_CHAR_P 843 -#define IMG_CHAR_Q 844 -#define IMG_CHAR_R 845 -#define IMG_CHAR_S 846 -#define IMG_CHAR_T 847 -#define IMG_CHAR_U 848 -#define IMG_CHAR_V 849 -#define IMG_CHAR_W 850 -#define IMG_CHAR_X 851 -#define IMG_CHAR_Y 852 -#define IMG_CHAR_Z 853 -#define IMG_CHAR_BRACKETLEFT 854 -#define IMG_CHAR_BACKSLASH 855 -#define IMG_CHAR_BRACKETRIGHT 856 -#define IMG_CHAR_ASCIICIRCUM 857 -#define IMG_CHAR_UNDERSCORE 858 -#define IMG_CHAR_COPYRIGHT 859 -#define IMG_CHAR_AUMLAUT 860 -#define IMG_CHAR_OUMLAUT 861 -#define IMG_CHAR_UUMLAUT 862 -#define IMG_CHAR_DEGREE 863 -#define IMG_CHAR_TRADEMARK 864 -#define IMG_CHAR_CURSOR 865 -#define IMG_CUSTOM_1 866 -#define IMG_CUSTOM_1_EDITOR 867 -#define IMG_CUSTOM_2 868 -#define IMG_CUSTOM_2_EDITOR 869 -#define IMG_CUSTOM_3 870 -#define IMG_CUSTOM_3_EDITOR 871 -#define IMG_CUSTOM_4 872 -#define IMG_CUSTOM_4_EDITOR 873 -#define IMG_CUSTOM_5 874 -#define IMG_CUSTOM_5_EDITOR 875 -#define IMG_CUSTOM_6 876 -#define IMG_CUSTOM_6_EDITOR 877 -#define IMG_CUSTOM_7 878 -#define IMG_CUSTOM_7_EDITOR 879 -#define IMG_CUSTOM_8 880 -#define IMG_CUSTOM_8_EDITOR 881 -#define IMG_CUSTOM_9 882 -#define IMG_CUSTOM_9_EDITOR 883 -#define IMG_CUSTOM_10 884 -#define IMG_CUSTOM_10_EDITOR 885 -#define IMG_CUSTOM_11 886 -#define IMG_CUSTOM_11_EDITOR 887 -#define IMG_CUSTOM_12 888 -#define IMG_CUSTOM_12_EDITOR 889 -#define IMG_CUSTOM_13 890 -#define IMG_CUSTOM_13_EDITOR 891 -#define IMG_CUSTOM_14 892 -#define IMG_CUSTOM_14_EDITOR 893 -#define IMG_CUSTOM_15 894 -#define IMG_CUSTOM_15_EDITOR 895 -#define IMG_CUSTOM_16 896 -#define IMG_CUSTOM_16_EDITOR 897 -#define IMG_CUSTOM_17 898 -#define IMG_CUSTOM_17_EDITOR 899 -#define IMG_CUSTOM_18 900 -#define IMG_CUSTOM_18_EDITOR 901 -#define IMG_CUSTOM_19 902 -#define IMG_CUSTOM_19_EDITOR 903 -#define IMG_CUSTOM_20 904 -#define IMG_CUSTOM_20_EDITOR 905 -#define IMG_CUSTOM_21 906 -#define IMG_CUSTOM_21_EDITOR 907 -#define IMG_CUSTOM_22 908 -#define IMG_CUSTOM_22_EDITOR 909 -#define IMG_CUSTOM_23 910 -#define IMG_CUSTOM_23_EDITOR 911 -#define IMG_CUSTOM_24 912 -#define IMG_CUSTOM_24_EDITOR 913 -#define IMG_CUSTOM_25 914 -#define IMG_CUSTOM_25_EDITOR 915 -#define IMG_CUSTOM_26 916 -#define IMG_CUSTOM_26_EDITOR 917 -#define IMG_CUSTOM_27 918 -#define IMG_CUSTOM_27_EDITOR 919 -#define IMG_CUSTOM_28 920 -#define IMG_CUSTOM_28_EDITOR 921 -#define IMG_CUSTOM_29 922 -#define IMG_CUSTOM_29_EDITOR 923 -#define IMG_CUSTOM_30 924 -#define IMG_CUSTOM_30_EDITOR 925 -#define IMG_CUSTOM_31 926 -#define IMG_CUSTOM_31_EDITOR 927 -#define IMG_CUSTOM_32 928 -#define IMG_CUSTOM_32_EDITOR 929 -#define IMG_CUSTOM_33 930 -#define IMG_CUSTOM_33_EDITOR 931 -#define IMG_CUSTOM_34 932 -#define IMG_CUSTOM_34_EDITOR 933 -#define IMG_CUSTOM_35 934 -#define IMG_CUSTOM_35_EDITOR 935 -#define IMG_CUSTOM_36 936 -#define IMG_CUSTOM_36_EDITOR 937 -#define IMG_CUSTOM_37 938 -#define IMG_CUSTOM_37_EDITOR 939 -#define IMG_CUSTOM_38 940 -#define IMG_CUSTOM_38_EDITOR 941 -#define IMG_CUSTOM_39 942 -#define IMG_CUSTOM_39_EDITOR 943 -#define IMG_CUSTOM_40 944 -#define IMG_CUSTOM_40_EDITOR 945 -#define IMG_CUSTOM_41 946 -#define IMG_CUSTOM_41_EDITOR 947 -#define IMG_CUSTOM_42 948 -#define IMG_CUSTOM_42_EDITOR 949 -#define IMG_CUSTOM_43 950 -#define IMG_CUSTOM_43_EDITOR 951 -#define IMG_CUSTOM_44 952 -#define IMG_CUSTOM_44_EDITOR 953 -#define IMG_CUSTOM_45 954 -#define IMG_CUSTOM_45_EDITOR 955 -#define IMG_CUSTOM_46 956 -#define IMG_CUSTOM_46_EDITOR 957 -#define IMG_CUSTOM_47 958 -#define IMG_CUSTOM_47_EDITOR 959 -#define IMG_CUSTOM_48 960 -#define IMG_CUSTOM_48_EDITOR 961 -#define IMG_CUSTOM_49 962 -#define IMG_CUSTOM_49_EDITOR 963 -#define IMG_CUSTOM_50 964 -#define IMG_CUSTOM_50_EDITOR 965 -#define IMG_CUSTOM_51 966 -#define IMG_CUSTOM_51_EDITOR 967 -#define IMG_CUSTOM_52 968 -#define IMG_CUSTOM_52_EDITOR 969 -#define IMG_CUSTOM_53 970 -#define IMG_CUSTOM_53_EDITOR 971 -#define IMG_CUSTOM_54 972 -#define IMG_CUSTOM_54_EDITOR 973 -#define IMG_CUSTOM_55 974 -#define IMG_CUSTOM_55_EDITOR 975 -#define IMG_CUSTOM_56 976 -#define IMG_CUSTOM_56_EDITOR 977 -#define IMG_CUSTOM_57 978 -#define IMG_CUSTOM_57_EDITOR 979 -#define IMG_CUSTOM_58 980 -#define IMG_CUSTOM_58_EDITOR 981 -#define IMG_CUSTOM_59 982 -#define IMG_CUSTOM_59_EDITOR 983 -#define IMG_CUSTOM_60 984 -#define IMG_CUSTOM_60_EDITOR 985 -#define IMG_CUSTOM_61 986 -#define IMG_CUSTOM_61_EDITOR 987 -#define IMG_CUSTOM_62 988 -#define IMG_CUSTOM_62_EDITOR 989 -#define IMG_CUSTOM_63 990 -#define IMG_CUSTOM_63_EDITOR 991 -#define IMG_CUSTOM_64 992 -#define IMG_CUSTOM_64_EDITOR 993 -#define IMG_CUSTOM_65 994 -#define IMG_CUSTOM_65_EDITOR 995 -#define IMG_CUSTOM_66 996 -#define IMG_CUSTOM_66_EDITOR 997 -#define IMG_CUSTOM_67 998 -#define IMG_CUSTOM_67_EDITOR 999 -#define IMG_CUSTOM_68 1000 -#define IMG_CUSTOM_68_EDITOR 1001 -#define IMG_CUSTOM_69 1002 -#define IMG_CUSTOM_69_EDITOR 1003 -#define IMG_CUSTOM_70 1004 -#define IMG_CUSTOM_70_EDITOR 1005 -#define IMG_CUSTOM_71 1006 -#define IMG_CUSTOM_71_EDITOR 1007 -#define IMG_CUSTOM_72 1008 -#define IMG_CUSTOM_72_EDITOR 1009 -#define IMG_CUSTOM_73 1010 -#define IMG_CUSTOM_73_EDITOR 1011 -#define IMG_CUSTOM_74 1012 -#define IMG_CUSTOM_74_EDITOR 1013 -#define IMG_CUSTOM_75 1014 -#define IMG_CUSTOM_75_EDITOR 1015 -#define IMG_CUSTOM_76 1016 -#define IMG_CUSTOM_76_EDITOR 1017 -#define IMG_CUSTOM_77 1018 -#define IMG_CUSTOM_77_EDITOR 1019 -#define IMG_CUSTOM_78 1020 -#define IMG_CUSTOM_78_EDITOR 1021 -#define IMG_CUSTOM_79 1022 -#define IMG_CUSTOM_79_EDITOR 1023 -#define IMG_CUSTOM_80 1024 -#define IMG_CUSTOM_80_EDITOR 1025 -#define IMG_CUSTOM_81 1026 -#define IMG_CUSTOM_81_EDITOR 1027 -#define IMG_CUSTOM_82 1028 -#define IMG_CUSTOM_82_EDITOR 1029 -#define IMG_CUSTOM_83 1030 -#define IMG_CUSTOM_83_EDITOR 1031 -#define IMG_CUSTOM_84 1032 -#define IMG_CUSTOM_84_EDITOR 1033 -#define IMG_CUSTOM_85 1034 -#define IMG_CUSTOM_85_EDITOR 1035 -#define IMG_CUSTOM_86 1036 -#define IMG_CUSTOM_86_EDITOR 1037 -#define IMG_CUSTOM_87 1038 -#define IMG_CUSTOM_87_EDITOR 1039 -#define IMG_CUSTOM_88 1040 -#define IMG_CUSTOM_88_EDITOR 1041 -#define IMG_CUSTOM_89 1042 -#define IMG_CUSTOM_89_EDITOR 1043 -#define IMG_CUSTOM_90 1044 -#define IMG_CUSTOM_90_EDITOR 1045 -#define IMG_CUSTOM_91 1046 -#define IMG_CUSTOM_91_EDITOR 1047 -#define IMG_CUSTOM_92 1048 -#define IMG_CUSTOM_92_EDITOR 1049 -#define IMG_CUSTOM_93 1050 -#define IMG_CUSTOM_93_EDITOR 1051 -#define IMG_CUSTOM_94 1052 -#define IMG_CUSTOM_94_EDITOR 1053 -#define IMG_CUSTOM_95 1054 -#define IMG_CUSTOM_95_EDITOR 1055 -#define IMG_CUSTOM_96 1056 -#define IMG_CUSTOM_96_EDITOR 1057 -#define IMG_CUSTOM_97 1058 -#define IMG_CUSTOM_97_EDITOR 1059 -#define IMG_CUSTOM_98 1060 -#define IMG_CUSTOM_98_EDITOR 1061 -#define IMG_CUSTOM_99 1062 -#define IMG_CUSTOM_99_EDITOR 1063 -#define IMG_CUSTOM_100 1064 -#define IMG_CUSTOM_100_EDITOR 1065 -#define IMG_CUSTOM_101 1066 -#define IMG_CUSTOM_101_EDITOR 1067 -#define IMG_CUSTOM_102 1068 -#define IMG_CUSTOM_102_EDITOR 1069 -#define IMG_CUSTOM_103 1070 -#define IMG_CUSTOM_103_EDITOR 1071 -#define IMG_CUSTOM_104 1072 -#define IMG_CUSTOM_104_EDITOR 1073 -#define IMG_CUSTOM_105 1074 -#define IMG_CUSTOM_105_EDITOR 1075 -#define IMG_CUSTOM_106 1076 -#define IMG_CUSTOM_106_EDITOR 1077 -#define IMG_CUSTOM_107 1078 -#define IMG_CUSTOM_107_EDITOR 1079 -#define IMG_CUSTOM_108 1080 -#define IMG_CUSTOM_108_EDITOR 1081 -#define IMG_CUSTOM_109 1082 -#define IMG_CUSTOM_109_EDITOR 1083 -#define IMG_CUSTOM_110 1084 -#define IMG_CUSTOM_110_EDITOR 1085 -#define IMG_CUSTOM_111 1086 -#define IMG_CUSTOM_111_EDITOR 1087 -#define IMG_CUSTOM_112 1088 -#define IMG_CUSTOM_112_EDITOR 1089 -#define IMG_CUSTOM_113 1090 -#define IMG_CUSTOM_113_EDITOR 1091 -#define IMG_CUSTOM_114 1092 -#define IMG_CUSTOM_114_EDITOR 1093 -#define IMG_CUSTOM_115 1094 -#define IMG_CUSTOM_115_EDITOR 1095 -#define IMG_CUSTOM_116 1096 -#define IMG_CUSTOM_116_EDITOR 1097 -#define IMG_CUSTOM_117 1098 -#define IMG_CUSTOM_117_EDITOR 1099 -#define IMG_CUSTOM_118 1100 -#define IMG_CUSTOM_118_EDITOR 1101 -#define IMG_CUSTOM_119 1102 -#define IMG_CUSTOM_119_EDITOR 1103 -#define IMG_CUSTOM_120 1104 -#define IMG_CUSTOM_120_EDITOR 1105 -#define IMG_CUSTOM_121 1106 -#define IMG_CUSTOM_121_EDITOR 1107 -#define IMG_CUSTOM_122 1108 -#define IMG_CUSTOM_122_EDITOR 1109 -#define IMG_CUSTOM_123 1110 -#define IMG_CUSTOM_123_EDITOR 1111 -#define IMG_CUSTOM_124 1112 -#define IMG_CUSTOM_124_EDITOR 1113 -#define IMG_CUSTOM_125 1114 -#define IMG_CUSTOM_125_EDITOR 1115 -#define IMG_CUSTOM_126 1116 -#define IMG_CUSTOM_126_EDITOR 1117 -#define IMG_CUSTOM_127 1118 -#define IMG_CUSTOM_127_EDITOR 1119 -#define IMG_CUSTOM_128 1120 -#define IMG_CUSTOM_128_EDITOR 1121 -#define IMG_CUSTOM_129 1122 -#define IMG_CUSTOM_129_EDITOR 1123 -#define IMG_CUSTOM_130 1124 -#define IMG_CUSTOM_130_EDITOR 1125 -#define IMG_CUSTOM_131 1126 -#define IMG_CUSTOM_131_EDITOR 1127 -#define IMG_CUSTOM_132 1128 -#define IMG_CUSTOM_132_EDITOR 1129 -#define IMG_CUSTOM_133 1130 -#define IMG_CUSTOM_133_EDITOR 1131 -#define IMG_CUSTOM_134 1132 -#define IMG_CUSTOM_134_EDITOR 1133 -#define IMG_CUSTOM_135 1134 -#define IMG_CUSTOM_135_EDITOR 1135 -#define IMG_CUSTOM_136 1136 -#define IMG_CUSTOM_136_EDITOR 1137 -#define IMG_CUSTOM_137 1138 -#define IMG_CUSTOM_137_EDITOR 1139 -#define IMG_CUSTOM_138 1140 -#define IMG_CUSTOM_138_EDITOR 1141 -#define IMG_CUSTOM_139 1142 -#define IMG_CUSTOM_139_EDITOR 1143 -#define IMG_CUSTOM_140 1144 -#define IMG_CUSTOM_140_EDITOR 1145 -#define IMG_CUSTOM_141 1146 -#define IMG_CUSTOM_141_EDITOR 1147 -#define IMG_CUSTOM_142 1148 -#define IMG_CUSTOM_142_EDITOR 1149 -#define IMG_CUSTOM_143 1150 -#define IMG_CUSTOM_143_EDITOR 1151 -#define IMG_CUSTOM_144 1152 -#define IMG_CUSTOM_144_EDITOR 1153 -#define IMG_CUSTOM_145 1154 -#define IMG_CUSTOM_145_EDITOR 1155 -#define IMG_CUSTOM_146 1156 -#define IMG_CUSTOM_146_EDITOR 1157 -#define IMG_CUSTOM_147 1158 -#define IMG_CUSTOM_147_EDITOR 1159 -#define IMG_CUSTOM_148 1160 -#define IMG_CUSTOM_148_EDITOR 1161 -#define IMG_CUSTOM_149 1162 -#define IMG_CUSTOM_149_EDITOR 1163 -#define IMG_CUSTOM_150 1164 -#define IMG_CUSTOM_150_EDITOR 1165 -#define IMG_CUSTOM_151 1166 -#define IMG_CUSTOM_151_EDITOR 1167 -#define IMG_CUSTOM_152 1168 -#define IMG_CUSTOM_152_EDITOR 1169 -#define IMG_CUSTOM_153 1170 -#define IMG_CUSTOM_153_EDITOR 1171 -#define IMG_CUSTOM_154 1172 -#define IMG_CUSTOM_154_EDITOR 1173 -#define IMG_CUSTOM_155 1174 -#define IMG_CUSTOM_155_EDITOR 1175 -#define IMG_CUSTOM_156 1176 -#define IMG_CUSTOM_156_EDITOR 1177 -#define IMG_CUSTOM_157 1178 -#define IMG_CUSTOM_157_EDITOR 1179 -#define IMG_CUSTOM_158 1180 -#define IMG_CUSTOM_158_EDITOR 1181 -#define IMG_CUSTOM_159 1182 -#define IMG_CUSTOM_159_EDITOR 1183 -#define IMG_CUSTOM_160 1184 -#define IMG_CUSTOM_160_EDITOR 1185 -#define IMG_CUSTOM_161 1186 -#define IMG_CUSTOM_161_EDITOR 1187 -#define IMG_CUSTOM_162 1188 -#define IMG_CUSTOM_162_EDITOR 1189 -#define IMG_CUSTOM_163 1190 -#define IMG_CUSTOM_163_EDITOR 1191 -#define IMG_CUSTOM_164 1192 -#define IMG_CUSTOM_164_EDITOR 1193 -#define IMG_CUSTOM_165 1194 -#define IMG_CUSTOM_165_EDITOR 1195 -#define IMG_CUSTOM_166 1196 -#define IMG_CUSTOM_166_EDITOR 1197 -#define IMG_CUSTOM_167 1198 -#define IMG_CUSTOM_167_EDITOR 1199 -#define IMG_CUSTOM_168 1200 -#define IMG_CUSTOM_168_EDITOR 1201 -#define IMG_CUSTOM_169 1202 -#define IMG_CUSTOM_169_EDITOR 1203 -#define IMG_CUSTOM_170 1204 -#define IMG_CUSTOM_170_EDITOR 1205 -#define IMG_CUSTOM_171 1206 -#define IMG_CUSTOM_171_EDITOR 1207 -#define IMG_CUSTOM_172 1208 -#define IMG_CUSTOM_172_EDITOR 1209 -#define IMG_CUSTOM_173 1210 -#define IMG_CUSTOM_173_EDITOR 1211 -#define IMG_CUSTOM_174 1212 -#define IMG_CUSTOM_174_EDITOR 1213 -#define IMG_CUSTOM_175 1214 -#define IMG_CUSTOM_175_EDITOR 1215 -#define IMG_CUSTOM_176 1216 -#define IMG_CUSTOM_176_EDITOR 1217 -#define IMG_CUSTOM_177 1218 -#define IMG_CUSTOM_177_EDITOR 1219 -#define IMG_CUSTOM_178 1220 -#define IMG_CUSTOM_178_EDITOR 1221 -#define IMG_CUSTOM_179 1222 -#define IMG_CUSTOM_179_EDITOR 1223 -#define IMG_CUSTOM_180 1224 -#define IMG_CUSTOM_180_EDITOR 1225 -#define IMG_CUSTOM_181 1226 -#define IMG_CUSTOM_181_EDITOR 1227 -#define IMG_CUSTOM_182 1228 -#define IMG_CUSTOM_182_EDITOR 1229 -#define IMG_CUSTOM_183 1230 -#define IMG_CUSTOM_183_EDITOR 1231 -#define IMG_CUSTOM_184 1232 -#define IMG_CUSTOM_184_EDITOR 1233 -#define IMG_CUSTOM_185 1234 -#define IMG_CUSTOM_185_EDITOR 1235 -#define IMG_CUSTOM_186 1236 -#define IMG_CUSTOM_186_EDITOR 1237 -#define IMG_CUSTOM_187 1238 -#define IMG_CUSTOM_187_EDITOR 1239 -#define IMG_CUSTOM_188 1240 -#define IMG_CUSTOM_188_EDITOR 1241 -#define IMG_CUSTOM_189 1242 -#define IMG_CUSTOM_189_EDITOR 1243 -#define IMG_CUSTOM_190 1244 -#define IMG_CUSTOM_190_EDITOR 1245 -#define IMG_CUSTOM_191 1246 -#define IMG_CUSTOM_191_EDITOR 1247 -#define IMG_CUSTOM_192 1248 -#define IMG_CUSTOM_192_EDITOR 1249 -#define IMG_CUSTOM_193 1250 -#define IMG_CUSTOM_193_EDITOR 1251 -#define IMG_CUSTOM_194 1252 -#define IMG_CUSTOM_194_EDITOR 1253 -#define IMG_CUSTOM_195 1254 -#define IMG_CUSTOM_195_EDITOR 1255 -#define IMG_CUSTOM_196 1256 -#define IMG_CUSTOM_196_EDITOR 1257 -#define IMG_CUSTOM_197 1258 -#define IMG_CUSTOM_197_EDITOR 1259 -#define IMG_CUSTOM_198 1260 -#define IMG_CUSTOM_198_EDITOR 1261 -#define IMG_CUSTOM_199 1262 -#define IMG_CUSTOM_199_EDITOR 1263 -#define IMG_CUSTOM_200 1264 -#define IMG_CUSTOM_200_EDITOR 1265 -#define IMG_CUSTOM_201 1266 -#define IMG_CUSTOM_201_EDITOR 1267 -#define IMG_CUSTOM_202 1268 -#define IMG_CUSTOM_202_EDITOR 1269 -#define IMG_CUSTOM_203 1270 -#define IMG_CUSTOM_203_EDITOR 1271 -#define IMG_CUSTOM_204 1272 -#define IMG_CUSTOM_204_EDITOR 1273 -#define IMG_CUSTOM_205 1274 -#define IMG_CUSTOM_205_EDITOR 1275 -#define IMG_CUSTOM_206 1276 -#define IMG_CUSTOM_206_EDITOR 1277 -#define IMG_CUSTOM_207 1278 -#define IMG_CUSTOM_207_EDITOR 1279 -#define IMG_CUSTOM_208 1280 -#define IMG_CUSTOM_208_EDITOR 1281 -#define IMG_CUSTOM_209 1282 -#define IMG_CUSTOM_209_EDITOR 1283 -#define IMG_CUSTOM_210 1284 -#define IMG_CUSTOM_210_EDITOR 1285 -#define IMG_CUSTOM_211 1286 -#define IMG_CUSTOM_211_EDITOR 1287 -#define IMG_CUSTOM_212 1288 -#define IMG_CUSTOM_212_EDITOR 1289 -#define IMG_CUSTOM_213 1290 -#define IMG_CUSTOM_213_EDITOR 1291 -#define IMG_CUSTOM_214 1292 -#define IMG_CUSTOM_214_EDITOR 1293 -#define IMG_CUSTOM_215 1294 -#define IMG_CUSTOM_215_EDITOR 1295 -#define IMG_CUSTOM_216 1296 -#define IMG_CUSTOM_216_EDITOR 1297 -#define IMG_CUSTOM_217 1298 -#define IMG_CUSTOM_217_EDITOR 1299 -#define IMG_CUSTOM_218 1300 -#define IMG_CUSTOM_218_EDITOR 1301 -#define IMG_CUSTOM_219 1302 -#define IMG_CUSTOM_219_EDITOR 1303 -#define IMG_CUSTOM_220 1304 -#define IMG_CUSTOM_220_EDITOR 1305 -#define IMG_CUSTOM_221 1306 -#define IMG_CUSTOM_221_EDITOR 1307 -#define IMG_CUSTOM_222 1308 -#define IMG_CUSTOM_222_EDITOR 1309 -#define IMG_CUSTOM_223 1310 -#define IMG_CUSTOM_223_EDITOR 1311 -#define IMG_CUSTOM_224 1312 -#define IMG_CUSTOM_224_EDITOR 1313 -#define IMG_CUSTOM_225 1314 -#define IMG_CUSTOM_225_EDITOR 1315 -#define IMG_CUSTOM_226 1316 -#define IMG_CUSTOM_226_EDITOR 1317 -#define IMG_CUSTOM_227 1318 -#define IMG_CUSTOM_227_EDITOR 1319 -#define IMG_CUSTOM_228 1320 -#define IMG_CUSTOM_228_EDITOR 1321 -#define IMG_CUSTOM_229 1322 -#define IMG_CUSTOM_229_EDITOR 1323 -#define IMG_CUSTOM_230 1324 -#define IMG_CUSTOM_230_EDITOR 1325 -#define IMG_CUSTOM_231 1326 -#define IMG_CUSTOM_231_EDITOR 1327 -#define IMG_CUSTOM_232 1328 -#define IMG_CUSTOM_232_EDITOR 1329 -#define IMG_CUSTOM_233 1330 -#define IMG_CUSTOM_233_EDITOR 1331 -#define IMG_CUSTOM_234 1332 -#define IMG_CUSTOM_234_EDITOR 1333 -#define IMG_CUSTOM_235 1334 -#define IMG_CUSTOM_235_EDITOR 1335 -#define IMG_CUSTOM_236 1336 -#define IMG_CUSTOM_236_EDITOR 1337 -#define IMG_CUSTOM_237 1338 -#define IMG_CUSTOM_237_EDITOR 1339 -#define IMG_CUSTOM_238 1340 -#define IMG_CUSTOM_238_EDITOR 1341 -#define IMG_CUSTOM_239 1342 -#define IMG_CUSTOM_239_EDITOR 1343 -#define IMG_CUSTOM_240 1344 -#define IMG_CUSTOM_240_EDITOR 1345 -#define IMG_CUSTOM_241 1346 -#define IMG_CUSTOM_241_EDITOR 1347 -#define IMG_CUSTOM_242 1348 -#define IMG_CUSTOM_242_EDITOR 1349 -#define IMG_CUSTOM_243 1350 -#define IMG_CUSTOM_243_EDITOR 1351 -#define IMG_CUSTOM_244 1352 -#define IMG_CUSTOM_244_EDITOR 1353 -#define IMG_CUSTOM_245 1354 -#define IMG_CUSTOM_245_EDITOR 1355 -#define IMG_CUSTOM_246 1356 -#define IMG_CUSTOM_246_EDITOR 1357 -#define IMG_CUSTOM_247 1358 -#define IMG_CUSTOM_247_EDITOR 1359 -#define IMG_CUSTOM_248 1360 -#define IMG_CUSTOM_248_EDITOR 1361 -#define IMG_CUSTOM_249 1362 -#define IMG_CUSTOM_249_EDITOR 1363 -#define IMG_CUSTOM_250 1364 -#define IMG_CUSTOM_250_EDITOR 1365 -#define IMG_CUSTOM_251 1366 -#define IMG_CUSTOM_251_EDITOR 1367 -#define IMG_CUSTOM_252 1368 -#define IMG_CUSTOM_252_EDITOR 1369 -#define IMG_CUSTOM_253 1370 -#define IMG_CUSTOM_253_EDITOR 1371 -#define IMG_CUSTOM_254 1372 -#define IMG_CUSTOM_254_EDITOR 1373 -#define IMG_CUSTOM_255 1374 -#define IMG_CUSTOM_255_EDITOR 1375 -#define IMG_CUSTOM_256 1376 -#define IMG_CUSTOM_256_EDITOR 1377 -#define IMG_GROUP_1 1378 -#define IMG_GROUP_1_EDITOR 1379 -#define IMG_GROUP_2 1380 -#define IMG_GROUP_2_EDITOR 1381 -#define IMG_GROUP_3 1382 -#define IMG_GROUP_3_EDITOR 1383 -#define IMG_GROUP_4 1384 -#define IMG_GROUP_4_EDITOR 1385 -#define IMG_GROUP_5 1386 -#define IMG_GROUP_5_EDITOR 1387 -#define IMG_GROUP_6 1388 -#define IMG_GROUP_6_EDITOR 1389 -#define IMG_GROUP_7 1390 -#define IMG_GROUP_7_EDITOR 1391 -#define IMG_GROUP_8 1392 -#define IMG_GROUP_8_EDITOR 1393 -#define IMG_GROUP_9 1394 -#define IMG_GROUP_9_EDITOR 1395 -#define IMG_GROUP_10 1396 -#define IMG_GROUP_10_EDITOR 1397 -#define IMG_GROUP_11 1398 -#define IMG_GROUP_11_EDITOR 1399 -#define IMG_GROUP_12 1400 -#define IMG_GROUP_12_EDITOR 1401 -#define IMG_GROUP_13 1402 -#define IMG_GROUP_13_EDITOR 1403 -#define IMG_GROUP_14 1404 -#define IMG_GROUP_14_EDITOR 1405 -#define IMG_GROUP_15 1406 -#define IMG_GROUP_15_EDITOR 1407 -#define IMG_GROUP_16 1408 -#define IMG_GROUP_16_EDITOR 1409 -#define IMG_GROUP_17 1410 -#define IMG_GROUP_17_EDITOR 1411 -#define IMG_GROUP_18 1412 -#define IMG_GROUP_18_EDITOR 1413 -#define IMG_GROUP_19 1414 -#define IMG_GROUP_19_EDITOR 1415 -#define IMG_GROUP_20 1416 -#define IMG_GROUP_20_EDITOR 1417 -#define IMG_GROUP_21 1418 -#define IMG_GROUP_21_EDITOR 1419 -#define IMG_GROUP_22 1420 -#define IMG_GROUP_22_EDITOR 1421 -#define IMG_GROUP_23 1422 -#define IMG_GROUP_23_EDITOR 1423 -#define IMG_GROUP_24 1424 -#define IMG_GROUP_24_EDITOR 1425 -#define IMG_GROUP_25 1426 -#define IMG_GROUP_25_EDITOR 1427 -#define IMG_GROUP_26 1428 -#define IMG_GROUP_26_EDITOR 1429 -#define IMG_GROUP_27 1430 -#define IMG_GROUP_27_EDITOR 1431 -#define IMG_GROUP_28 1432 -#define IMG_GROUP_28_EDITOR 1433 -#define IMG_GROUP_29 1434 -#define IMG_GROUP_29_EDITOR 1435 -#define IMG_GROUP_30 1436 -#define IMG_GROUP_30_EDITOR 1437 -#define IMG_GROUP_31 1438 -#define IMG_GROUP_31_EDITOR 1439 -#define IMG_GROUP_32 1440 -#define IMG_GROUP_32_EDITOR 1441 -#define IMG_EMC_OBJECT 1442 -#define IMG_EMC_SPRITE 1443 -#define IMG_TOON_1 1444 -#define IMG_TOON_2 1445 -#define IMG_TOON_3 1446 -#define IMG_TOON_4 1447 -#define IMG_TOON_5 1448 -#define IMG_TOON_6 1449 -#define IMG_TOON_7 1450 -#define IMG_TOON_8 1451 -#define IMG_TOON_9 1452 -#define IMG_TOON_10 1453 -#define IMG_TOON_11 1454 -#define IMG_TOON_12 1455 -#define IMG_TOON_13 1456 -#define IMG_TOON_14 1457 -#define IMG_TOON_15 1458 -#define IMG_TOON_16 1459 -#define IMG_TOON_17 1460 -#define IMG_TOON_18 1461 -#define IMG_TOON_19 1462 -#define IMG_TOON_20 1463 -#define IMG_MENU_CALIBRATE_RED 1464 -#define IMG_MENU_CALIBRATE_BLUE 1465 -#define IMG_MENU_CALIBRATE_YELLOW 1466 -#define IMG_MENU_BUTTON 1467 -#define IMG_MENU_BUTTON_ACTIVE 1468 -#define IMG_MENU_BUTTON_LEFT 1469 -#define IMG_MENU_BUTTON_LEFT_ACTIVE 1470 -#define IMG_MENU_BUTTON_RIGHT 1471 -#define IMG_MENU_BUTTON_RIGHT_ACTIVE 1472 -#define IMG_MENU_BUTTON_UP 1473 -#define IMG_MENU_BUTTON_UP_ACTIVE 1474 -#define IMG_MENU_BUTTON_DOWN 1475 -#define IMG_MENU_BUTTON_DOWN_ACTIVE 1476 -#define IMG_MENU_BUTTON_ENTER_MENU 1477 -#define IMG_MENU_BUTTON_ENTER_MENU_ACTIVE 1478 -#define IMG_MENU_BUTTON_LEAVE_MENU 1479 -#define IMG_MENU_BUTTON_LEAVE_MENU_ACTIVE 1480 -#define IMG_MENU_BUTTON_NEXT_LEVEL 1481 -#define IMG_MENU_BUTTON_NEXT_LEVEL_ACTIVE 1482 -#define IMG_MENU_BUTTON_LAST_LEVEL 1483 -#define IMG_MENU_BUTTON_LAST_LEVEL_ACTIVE 1484 -#define IMG_MENU_SCROLLBAR 1485 -#define IMG_MENU_SCROLLBAR_ACTIVE 1486 -#define IMG_FONT_INITIAL_1 1487 -#define IMG_FONT_INITIAL_2 1488 -#define IMG_FONT_INITIAL_3 1489 -#define IMG_FONT_INITIAL_4 1490 -#define IMG_FONT_TITLE_1 1491 -#define IMG_FONT_TITLE_2 1492 -#define IMG_FONT_MENU_1 1493 -#define IMG_FONT_MENU_2 1494 -#define IMG_FONT_TEXT_1 1495 -#define IMG_FONT_TEXT_1_LEVELS 1496 -#define IMG_FONT_TEXT_1_PREVIEW 1497 -#define IMG_FONT_TEXT_1_SCORES 1498 -#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1499 -#define IMG_FONT_TEXT_2 1500 -#define IMG_FONT_TEXT_2_LEVELS 1501 -#define IMG_FONT_TEXT_2_PREVIEW 1502 -#define IMG_FONT_TEXT_2_SCORES 1503 -#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1504 -#define IMG_FONT_TEXT_3 1505 -#define IMG_FONT_TEXT_3_LEVELS 1506 -#define IMG_FONT_TEXT_3_PREVIEW 1507 -#define IMG_FONT_TEXT_3_SCORES 1508 -#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1509 -#define IMG_FONT_TEXT_4 1510 -#define IMG_FONT_TEXT_4_LEVELS 1511 -#define IMG_FONT_TEXT_4_SCORES 1512 -#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1513 -#define IMG_FONT_ENVELOPE_1 1514 -#define IMG_FONT_ENVELOPE_2 1515 -#define IMG_FONT_ENVELOPE_3 1516 -#define IMG_FONT_ENVELOPE_4 1517 -#define IMG_FONT_INPUT_1 1518 -#define IMG_FONT_INPUT_1_MAIN 1519 -#define IMG_FONT_INPUT_1_ACTIVE 1520 -#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1521 -#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1522 -#define IMG_FONT_INPUT_2 1523 -#define IMG_FONT_INPUT_2_ACTIVE 1524 -#define IMG_FONT_OPTION_OFF 1525 -#define IMG_FONT_OPTION_ON 1526 -#define IMG_FONT_VALUE_1 1527 -#define IMG_FONT_VALUE_2 1528 -#define IMG_FONT_VALUE_OLD 1529 -#define IMG_FONT_LEVEL_NUMBER 1530 -#define IMG_FONT_TAPE_RECORDER 1531 -#define IMG_FONT_GAME_INFO 1532 -#define IMG_GLOBAL_BORDER 1533 -#define IMG_GLOBAL_DOOR 1534 -#define IMG_EDITOR_ELEMENT_BORDER 1535 -#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1536 -#define IMG_EDITOR_CASCADE_LIST 1537 -#define IMG_EDITOR_CASCADE_LIST_ACTIVE 1538 -#define IMG_BACKGROUND_ENVELOPE_1 1539 -#define IMG_BACKGROUND_ENVELOPE_2 1540 -#define IMG_BACKGROUND_ENVELOPE_3 1541 -#define IMG_BACKGROUND_ENVELOPE_4 1542 -#define IMG_TITLESCREEN_1 1543 -#define IMG_TITLESCREEN_2 1544 -#define IMG_TITLESCREEN_3 1545 -#define IMG_TITLESCREEN_4 1546 -#define IMG_TITLESCREEN_5 1547 -#define IMG_BACKGROUND 1548 -#define IMG_BACKGROUND_TITLE 1549 -#define IMG_BACKGROUND_MAIN 1550 -#define IMG_BACKGROUND_LEVELS 1551 -#define IMG_BACKGROUND_SCORES 1552 -#define IMG_BACKGROUND_EDITOR 1553 -#define IMG_BACKGROUND_INFO 1554 -#define IMG_BACKGROUND_INFO_ELEMENTS 1555 -#define IMG_BACKGROUND_INFO_MUSIC 1556 -#define IMG_BACKGROUND_INFO_CREDITS 1557 -#define IMG_BACKGROUND_INFO_PROGRAM 1558 -#define IMG_BACKGROUND_INFO_LEVELSET 1559 -#define IMG_BACKGROUND_SETUP 1560 -#define IMG_BACKGROUND_DOOR 1561 +#define IMG_CHAR_SPACE_EDITOR 796 +#define IMG_CHAR_EXCLAM 797 +#define IMG_CHAR_QUOTEDBL 798 +#define IMG_CHAR_NUMBERSIGN 799 +#define IMG_CHAR_DOLLAR 800 +#define IMG_CHAR_PERCENT 801 +#define IMG_CHAR_AMPERSAND 802 +#define IMG_CHAR_APOSTROPHE 803 +#define IMG_CHAR_PARENLEFT 804 +#define IMG_CHAR_PARENRIGHT 805 +#define IMG_CHAR_ASTERISK 806 +#define IMG_CHAR_PLUS 807 +#define IMG_CHAR_COMMA 808 +#define IMG_CHAR_MINUS 809 +#define IMG_CHAR_PERIOD 810 +#define IMG_CHAR_SLASH 811 +#define IMG_CHAR_0 812 +#define IMG_CHAR_1 813 +#define IMG_CHAR_2 814 +#define IMG_CHAR_3 815 +#define IMG_CHAR_4 816 +#define IMG_CHAR_5 817 +#define IMG_CHAR_6 818 +#define IMG_CHAR_7 819 +#define IMG_CHAR_8 820 +#define IMG_CHAR_9 821 +#define IMG_CHAR_COLON 822 +#define IMG_CHAR_SEMICOLON 823 +#define IMG_CHAR_LESS 824 +#define IMG_CHAR_EQUAL 825 +#define IMG_CHAR_GREATER 826 +#define IMG_CHAR_QUESTION 827 +#define IMG_CHAR_AT 828 +#define IMG_CHAR_A 829 +#define IMG_CHAR_B 830 +#define IMG_CHAR_C 831 +#define IMG_CHAR_D 832 +#define IMG_CHAR_E 833 +#define IMG_CHAR_F 834 +#define IMG_CHAR_G 835 +#define IMG_CHAR_H 836 +#define IMG_CHAR_I 837 +#define IMG_CHAR_J 838 +#define IMG_CHAR_K 839 +#define IMG_CHAR_L 840 +#define IMG_CHAR_M 841 +#define IMG_CHAR_N 842 +#define IMG_CHAR_O 843 +#define IMG_CHAR_P 844 +#define IMG_CHAR_Q 845 +#define IMG_CHAR_R 846 +#define IMG_CHAR_S 847 +#define IMG_CHAR_T 848 +#define IMG_CHAR_U 849 +#define IMG_CHAR_V 850 +#define IMG_CHAR_W 851 +#define IMG_CHAR_X 852 +#define IMG_CHAR_Y 853 +#define IMG_CHAR_Z 854 +#define IMG_CHAR_BRACKETLEFT 855 +#define IMG_CHAR_BACKSLASH 856 +#define IMG_CHAR_BRACKETRIGHT 857 +#define IMG_CHAR_ASCIICIRCUM 858 +#define IMG_CHAR_UNDERSCORE 859 +#define IMG_CHAR_COPYRIGHT 860 +#define IMG_CHAR_AUMLAUT 861 +#define IMG_CHAR_OUMLAUT 862 +#define IMG_CHAR_UUMLAUT 863 +#define IMG_CHAR_DEGREE 864 +#define IMG_CHAR_TRADEMARK 865 +#define IMG_CHAR_CURSOR 866 +#define IMG_CUSTOM_1 867 +#define IMG_CUSTOM_1_EDITOR 868 +#define IMG_CUSTOM_2 869 +#define IMG_CUSTOM_2_EDITOR 870 +#define IMG_CUSTOM_3 871 +#define IMG_CUSTOM_3_EDITOR 872 +#define IMG_CUSTOM_4 873 +#define IMG_CUSTOM_4_EDITOR 874 +#define IMG_CUSTOM_5 875 +#define IMG_CUSTOM_5_EDITOR 876 +#define IMG_CUSTOM_6 877 +#define IMG_CUSTOM_6_EDITOR 878 +#define IMG_CUSTOM_7 879 +#define IMG_CUSTOM_7_EDITOR 880 +#define IMG_CUSTOM_8 881 +#define IMG_CUSTOM_8_EDITOR 882 +#define IMG_CUSTOM_9 883 +#define IMG_CUSTOM_9_EDITOR 884 +#define IMG_CUSTOM_10 885 +#define IMG_CUSTOM_10_EDITOR 886 +#define IMG_CUSTOM_11 887 +#define IMG_CUSTOM_11_EDITOR 888 +#define IMG_CUSTOM_12 889 +#define IMG_CUSTOM_12_EDITOR 890 +#define IMG_CUSTOM_13 891 +#define IMG_CUSTOM_13_EDITOR 892 +#define IMG_CUSTOM_14 893 +#define IMG_CUSTOM_14_EDITOR 894 +#define IMG_CUSTOM_15 895 +#define IMG_CUSTOM_15_EDITOR 896 +#define IMG_CUSTOM_16 897 +#define IMG_CUSTOM_16_EDITOR 898 +#define IMG_CUSTOM_17 899 +#define IMG_CUSTOM_17_EDITOR 900 +#define IMG_CUSTOM_18 901 +#define IMG_CUSTOM_18_EDITOR 902 +#define IMG_CUSTOM_19 903 +#define IMG_CUSTOM_19_EDITOR 904 +#define IMG_CUSTOM_20 905 +#define IMG_CUSTOM_20_EDITOR 906 +#define IMG_CUSTOM_21 907 +#define IMG_CUSTOM_21_EDITOR 908 +#define IMG_CUSTOM_22 909 +#define IMG_CUSTOM_22_EDITOR 910 +#define IMG_CUSTOM_23 911 +#define IMG_CUSTOM_23_EDITOR 912 +#define IMG_CUSTOM_24 913 +#define IMG_CUSTOM_24_EDITOR 914 +#define IMG_CUSTOM_25 915 +#define IMG_CUSTOM_25_EDITOR 916 +#define IMG_CUSTOM_26 917 +#define IMG_CUSTOM_26_EDITOR 918 +#define IMG_CUSTOM_27 919 +#define IMG_CUSTOM_27_EDITOR 920 +#define IMG_CUSTOM_28 921 +#define IMG_CUSTOM_28_EDITOR 922 +#define IMG_CUSTOM_29 923 +#define IMG_CUSTOM_29_EDITOR 924 +#define IMG_CUSTOM_30 925 +#define IMG_CUSTOM_30_EDITOR 926 +#define IMG_CUSTOM_31 927 +#define IMG_CUSTOM_31_EDITOR 928 +#define IMG_CUSTOM_32 929 +#define IMG_CUSTOM_32_EDITOR 930 +#define IMG_CUSTOM_33 931 +#define IMG_CUSTOM_33_EDITOR 932 +#define IMG_CUSTOM_34 933 +#define IMG_CUSTOM_34_EDITOR 934 +#define IMG_CUSTOM_35 935 +#define IMG_CUSTOM_35_EDITOR 936 +#define IMG_CUSTOM_36 937 +#define IMG_CUSTOM_36_EDITOR 938 +#define IMG_CUSTOM_37 939 +#define IMG_CUSTOM_37_EDITOR 940 +#define IMG_CUSTOM_38 941 +#define IMG_CUSTOM_38_EDITOR 942 +#define IMG_CUSTOM_39 943 +#define IMG_CUSTOM_39_EDITOR 944 +#define IMG_CUSTOM_40 945 +#define IMG_CUSTOM_40_EDITOR 946 +#define IMG_CUSTOM_41 947 +#define IMG_CUSTOM_41_EDITOR 948 +#define IMG_CUSTOM_42 949 +#define IMG_CUSTOM_42_EDITOR 950 +#define IMG_CUSTOM_43 951 +#define IMG_CUSTOM_43_EDITOR 952 +#define IMG_CUSTOM_44 953 +#define IMG_CUSTOM_44_EDITOR 954 +#define IMG_CUSTOM_45 955 +#define IMG_CUSTOM_45_EDITOR 956 +#define IMG_CUSTOM_46 957 +#define IMG_CUSTOM_46_EDITOR 958 +#define IMG_CUSTOM_47 959 +#define IMG_CUSTOM_47_EDITOR 960 +#define IMG_CUSTOM_48 961 +#define IMG_CUSTOM_48_EDITOR 962 +#define IMG_CUSTOM_49 963 +#define IMG_CUSTOM_49_EDITOR 964 +#define IMG_CUSTOM_50 965 +#define IMG_CUSTOM_50_EDITOR 966 +#define IMG_CUSTOM_51 967 +#define IMG_CUSTOM_51_EDITOR 968 +#define IMG_CUSTOM_52 969 +#define IMG_CUSTOM_52_EDITOR 970 +#define IMG_CUSTOM_53 971 +#define IMG_CUSTOM_53_EDITOR 972 +#define IMG_CUSTOM_54 973 +#define IMG_CUSTOM_54_EDITOR 974 +#define IMG_CUSTOM_55 975 +#define IMG_CUSTOM_55_EDITOR 976 +#define IMG_CUSTOM_56 977 +#define IMG_CUSTOM_56_EDITOR 978 +#define IMG_CUSTOM_57 979 +#define IMG_CUSTOM_57_EDITOR 980 +#define IMG_CUSTOM_58 981 +#define IMG_CUSTOM_58_EDITOR 982 +#define IMG_CUSTOM_59 983 +#define IMG_CUSTOM_59_EDITOR 984 +#define IMG_CUSTOM_60 985 +#define IMG_CUSTOM_60_EDITOR 986 +#define IMG_CUSTOM_61 987 +#define IMG_CUSTOM_61_EDITOR 988 +#define IMG_CUSTOM_62 989 +#define IMG_CUSTOM_62_EDITOR 990 +#define IMG_CUSTOM_63 991 +#define IMG_CUSTOM_63_EDITOR 992 +#define IMG_CUSTOM_64 993 +#define IMG_CUSTOM_64_EDITOR 994 +#define IMG_CUSTOM_65 995 +#define IMG_CUSTOM_65_EDITOR 996 +#define IMG_CUSTOM_66 997 +#define IMG_CUSTOM_66_EDITOR 998 +#define IMG_CUSTOM_67 999 +#define IMG_CUSTOM_67_EDITOR 1000 +#define IMG_CUSTOM_68 1001 +#define IMG_CUSTOM_68_EDITOR 1002 +#define IMG_CUSTOM_69 1003 +#define IMG_CUSTOM_69_EDITOR 1004 +#define IMG_CUSTOM_70 1005 +#define IMG_CUSTOM_70_EDITOR 1006 +#define IMG_CUSTOM_71 1007 +#define IMG_CUSTOM_71_EDITOR 1008 +#define IMG_CUSTOM_72 1009 +#define IMG_CUSTOM_72_EDITOR 1010 +#define IMG_CUSTOM_73 1011 +#define IMG_CUSTOM_73_EDITOR 1012 +#define IMG_CUSTOM_74 1013 +#define IMG_CUSTOM_74_EDITOR 1014 +#define IMG_CUSTOM_75 1015 +#define IMG_CUSTOM_75_EDITOR 1016 +#define IMG_CUSTOM_76 1017 +#define IMG_CUSTOM_76_EDITOR 1018 +#define IMG_CUSTOM_77 1019 +#define IMG_CUSTOM_77_EDITOR 1020 +#define IMG_CUSTOM_78 1021 +#define IMG_CUSTOM_78_EDITOR 1022 +#define IMG_CUSTOM_79 1023 +#define IMG_CUSTOM_79_EDITOR 1024 +#define IMG_CUSTOM_80 1025 +#define IMG_CUSTOM_80_EDITOR 1026 +#define IMG_CUSTOM_81 1027 +#define IMG_CUSTOM_81_EDITOR 1028 +#define IMG_CUSTOM_82 1029 +#define IMG_CUSTOM_82_EDITOR 1030 +#define IMG_CUSTOM_83 1031 +#define IMG_CUSTOM_83_EDITOR 1032 +#define IMG_CUSTOM_84 1033 +#define IMG_CUSTOM_84_EDITOR 1034 +#define IMG_CUSTOM_85 1035 +#define IMG_CUSTOM_85_EDITOR 1036 +#define IMG_CUSTOM_86 1037 +#define IMG_CUSTOM_86_EDITOR 1038 +#define IMG_CUSTOM_87 1039 +#define IMG_CUSTOM_87_EDITOR 1040 +#define IMG_CUSTOM_88 1041 +#define IMG_CUSTOM_88_EDITOR 1042 +#define IMG_CUSTOM_89 1043 +#define IMG_CUSTOM_89_EDITOR 1044 +#define IMG_CUSTOM_90 1045 +#define IMG_CUSTOM_90_EDITOR 1046 +#define IMG_CUSTOM_91 1047 +#define IMG_CUSTOM_91_EDITOR 1048 +#define IMG_CUSTOM_92 1049 +#define IMG_CUSTOM_92_EDITOR 1050 +#define IMG_CUSTOM_93 1051 +#define IMG_CUSTOM_93_EDITOR 1052 +#define IMG_CUSTOM_94 1053 +#define IMG_CUSTOM_94_EDITOR 1054 +#define IMG_CUSTOM_95 1055 +#define IMG_CUSTOM_95_EDITOR 1056 +#define IMG_CUSTOM_96 1057 +#define IMG_CUSTOM_96_EDITOR 1058 +#define IMG_CUSTOM_97 1059 +#define IMG_CUSTOM_97_EDITOR 1060 +#define IMG_CUSTOM_98 1061 +#define IMG_CUSTOM_98_EDITOR 1062 +#define IMG_CUSTOM_99 1063 +#define IMG_CUSTOM_99_EDITOR 1064 +#define IMG_CUSTOM_100 1065 +#define IMG_CUSTOM_100_EDITOR 1066 +#define IMG_CUSTOM_101 1067 +#define IMG_CUSTOM_101_EDITOR 1068 +#define IMG_CUSTOM_102 1069 +#define IMG_CUSTOM_102_EDITOR 1070 +#define IMG_CUSTOM_103 1071 +#define IMG_CUSTOM_103_EDITOR 1072 +#define IMG_CUSTOM_104 1073 +#define IMG_CUSTOM_104_EDITOR 1074 +#define IMG_CUSTOM_105 1075 +#define IMG_CUSTOM_105_EDITOR 1076 +#define IMG_CUSTOM_106 1077 +#define IMG_CUSTOM_106_EDITOR 1078 +#define IMG_CUSTOM_107 1079 +#define IMG_CUSTOM_107_EDITOR 1080 +#define IMG_CUSTOM_108 1081 +#define IMG_CUSTOM_108_EDITOR 1082 +#define IMG_CUSTOM_109 1083 +#define IMG_CUSTOM_109_EDITOR 1084 +#define IMG_CUSTOM_110 1085 +#define IMG_CUSTOM_110_EDITOR 1086 +#define IMG_CUSTOM_111 1087 +#define IMG_CUSTOM_111_EDITOR 1088 +#define IMG_CUSTOM_112 1089 +#define IMG_CUSTOM_112_EDITOR 1090 +#define IMG_CUSTOM_113 1091 +#define IMG_CUSTOM_113_EDITOR 1092 +#define IMG_CUSTOM_114 1093 +#define IMG_CUSTOM_114_EDITOR 1094 +#define IMG_CUSTOM_115 1095 +#define IMG_CUSTOM_115_EDITOR 1096 +#define IMG_CUSTOM_116 1097 +#define IMG_CUSTOM_116_EDITOR 1098 +#define IMG_CUSTOM_117 1099 +#define IMG_CUSTOM_117_EDITOR 1100 +#define IMG_CUSTOM_118 1101 +#define IMG_CUSTOM_118_EDITOR 1102 +#define IMG_CUSTOM_119 1103 +#define IMG_CUSTOM_119_EDITOR 1104 +#define IMG_CUSTOM_120 1105 +#define IMG_CUSTOM_120_EDITOR 1106 +#define IMG_CUSTOM_121 1107 +#define IMG_CUSTOM_121_EDITOR 1108 +#define IMG_CUSTOM_122 1109 +#define IMG_CUSTOM_122_EDITOR 1110 +#define IMG_CUSTOM_123 1111 +#define IMG_CUSTOM_123_EDITOR 1112 +#define IMG_CUSTOM_124 1113 +#define IMG_CUSTOM_124_EDITOR 1114 +#define IMG_CUSTOM_125 1115 +#define IMG_CUSTOM_125_EDITOR 1116 +#define IMG_CUSTOM_126 1117 +#define IMG_CUSTOM_126_EDITOR 1118 +#define IMG_CUSTOM_127 1119 +#define IMG_CUSTOM_127_EDITOR 1120 +#define IMG_CUSTOM_128 1121 +#define IMG_CUSTOM_128_EDITOR 1122 +#define IMG_CUSTOM_129 1123 +#define IMG_CUSTOM_129_EDITOR 1124 +#define IMG_CUSTOM_130 1125 +#define IMG_CUSTOM_130_EDITOR 1126 +#define IMG_CUSTOM_131 1127 +#define IMG_CUSTOM_131_EDITOR 1128 +#define IMG_CUSTOM_132 1129 +#define IMG_CUSTOM_132_EDITOR 1130 +#define IMG_CUSTOM_133 1131 +#define IMG_CUSTOM_133_EDITOR 1132 +#define IMG_CUSTOM_134 1133 +#define IMG_CUSTOM_134_EDITOR 1134 +#define IMG_CUSTOM_135 1135 +#define IMG_CUSTOM_135_EDITOR 1136 +#define IMG_CUSTOM_136 1137 +#define IMG_CUSTOM_136_EDITOR 1138 +#define IMG_CUSTOM_137 1139 +#define IMG_CUSTOM_137_EDITOR 1140 +#define IMG_CUSTOM_138 1141 +#define IMG_CUSTOM_138_EDITOR 1142 +#define IMG_CUSTOM_139 1143 +#define IMG_CUSTOM_139_EDITOR 1144 +#define IMG_CUSTOM_140 1145 +#define IMG_CUSTOM_140_EDITOR 1146 +#define IMG_CUSTOM_141 1147 +#define IMG_CUSTOM_141_EDITOR 1148 +#define IMG_CUSTOM_142 1149 +#define IMG_CUSTOM_142_EDITOR 1150 +#define IMG_CUSTOM_143 1151 +#define IMG_CUSTOM_143_EDITOR 1152 +#define IMG_CUSTOM_144 1153 +#define IMG_CUSTOM_144_EDITOR 1154 +#define IMG_CUSTOM_145 1155 +#define IMG_CUSTOM_145_EDITOR 1156 +#define IMG_CUSTOM_146 1157 +#define IMG_CUSTOM_146_EDITOR 1158 +#define IMG_CUSTOM_147 1159 +#define IMG_CUSTOM_147_EDITOR 1160 +#define IMG_CUSTOM_148 1161 +#define IMG_CUSTOM_148_EDITOR 1162 +#define IMG_CUSTOM_149 1163 +#define IMG_CUSTOM_149_EDITOR 1164 +#define IMG_CUSTOM_150 1165 +#define IMG_CUSTOM_150_EDITOR 1166 +#define IMG_CUSTOM_151 1167 +#define IMG_CUSTOM_151_EDITOR 1168 +#define IMG_CUSTOM_152 1169 +#define IMG_CUSTOM_152_EDITOR 1170 +#define IMG_CUSTOM_153 1171 +#define IMG_CUSTOM_153_EDITOR 1172 +#define IMG_CUSTOM_154 1173 +#define IMG_CUSTOM_154_EDITOR 1174 +#define IMG_CUSTOM_155 1175 +#define IMG_CUSTOM_155_EDITOR 1176 +#define IMG_CUSTOM_156 1177 +#define IMG_CUSTOM_156_EDITOR 1178 +#define IMG_CUSTOM_157 1179 +#define IMG_CUSTOM_157_EDITOR 1180 +#define IMG_CUSTOM_158 1181 +#define IMG_CUSTOM_158_EDITOR 1182 +#define IMG_CUSTOM_159 1183 +#define IMG_CUSTOM_159_EDITOR 1184 +#define IMG_CUSTOM_160 1185 +#define IMG_CUSTOM_160_EDITOR 1186 +#define IMG_CUSTOM_161 1187 +#define IMG_CUSTOM_161_EDITOR 1188 +#define IMG_CUSTOM_162 1189 +#define IMG_CUSTOM_162_EDITOR 1190 +#define IMG_CUSTOM_163 1191 +#define IMG_CUSTOM_163_EDITOR 1192 +#define IMG_CUSTOM_164 1193 +#define IMG_CUSTOM_164_EDITOR 1194 +#define IMG_CUSTOM_165 1195 +#define IMG_CUSTOM_165_EDITOR 1196 +#define IMG_CUSTOM_166 1197 +#define IMG_CUSTOM_166_EDITOR 1198 +#define IMG_CUSTOM_167 1199 +#define IMG_CUSTOM_167_EDITOR 1200 +#define IMG_CUSTOM_168 1201 +#define IMG_CUSTOM_168_EDITOR 1202 +#define IMG_CUSTOM_169 1203 +#define IMG_CUSTOM_169_EDITOR 1204 +#define IMG_CUSTOM_170 1205 +#define IMG_CUSTOM_170_EDITOR 1206 +#define IMG_CUSTOM_171 1207 +#define IMG_CUSTOM_171_EDITOR 1208 +#define IMG_CUSTOM_172 1209 +#define IMG_CUSTOM_172_EDITOR 1210 +#define IMG_CUSTOM_173 1211 +#define IMG_CUSTOM_173_EDITOR 1212 +#define IMG_CUSTOM_174 1213 +#define IMG_CUSTOM_174_EDITOR 1214 +#define IMG_CUSTOM_175 1215 +#define IMG_CUSTOM_175_EDITOR 1216 +#define IMG_CUSTOM_176 1217 +#define IMG_CUSTOM_176_EDITOR 1218 +#define IMG_CUSTOM_177 1219 +#define IMG_CUSTOM_177_EDITOR 1220 +#define IMG_CUSTOM_178 1221 +#define IMG_CUSTOM_178_EDITOR 1222 +#define IMG_CUSTOM_179 1223 +#define IMG_CUSTOM_179_EDITOR 1224 +#define IMG_CUSTOM_180 1225 +#define IMG_CUSTOM_180_EDITOR 1226 +#define IMG_CUSTOM_181 1227 +#define IMG_CUSTOM_181_EDITOR 1228 +#define IMG_CUSTOM_182 1229 +#define IMG_CUSTOM_182_EDITOR 1230 +#define IMG_CUSTOM_183 1231 +#define IMG_CUSTOM_183_EDITOR 1232 +#define IMG_CUSTOM_184 1233 +#define IMG_CUSTOM_184_EDITOR 1234 +#define IMG_CUSTOM_185 1235 +#define IMG_CUSTOM_185_EDITOR 1236 +#define IMG_CUSTOM_186 1237 +#define IMG_CUSTOM_186_EDITOR 1238 +#define IMG_CUSTOM_187 1239 +#define IMG_CUSTOM_187_EDITOR 1240 +#define IMG_CUSTOM_188 1241 +#define IMG_CUSTOM_188_EDITOR 1242 +#define IMG_CUSTOM_189 1243 +#define IMG_CUSTOM_189_EDITOR 1244 +#define IMG_CUSTOM_190 1245 +#define IMG_CUSTOM_190_EDITOR 1246 +#define IMG_CUSTOM_191 1247 +#define IMG_CUSTOM_191_EDITOR 1248 +#define IMG_CUSTOM_192 1249 +#define IMG_CUSTOM_192_EDITOR 1250 +#define IMG_CUSTOM_193 1251 +#define IMG_CUSTOM_193_EDITOR 1252 +#define IMG_CUSTOM_194 1253 +#define IMG_CUSTOM_194_EDITOR 1254 +#define IMG_CUSTOM_195 1255 +#define IMG_CUSTOM_195_EDITOR 1256 +#define IMG_CUSTOM_196 1257 +#define IMG_CUSTOM_196_EDITOR 1258 +#define IMG_CUSTOM_197 1259 +#define IMG_CUSTOM_197_EDITOR 1260 +#define IMG_CUSTOM_198 1261 +#define IMG_CUSTOM_198_EDITOR 1262 +#define IMG_CUSTOM_199 1263 +#define IMG_CUSTOM_199_EDITOR 1264 +#define IMG_CUSTOM_200 1265 +#define IMG_CUSTOM_200_EDITOR 1266 +#define IMG_CUSTOM_201 1267 +#define IMG_CUSTOM_201_EDITOR 1268 +#define IMG_CUSTOM_202 1269 +#define IMG_CUSTOM_202_EDITOR 1270 +#define IMG_CUSTOM_203 1271 +#define IMG_CUSTOM_203_EDITOR 1272 +#define IMG_CUSTOM_204 1273 +#define IMG_CUSTOM_204_EDITOR 1274 +#define IMG_CUSTOM_205 1275 +#define IMG_CUSTOM_205_EDITOR 1276 +#define IMG_CUSTOM_206 1277 +#define IMG_CUSTOM_206_EDITOR 1278 +#define IMG_CUSTOM_207 1279 +#define IMG_CUSTOM_207_EDITOR 1280 +#define IMG_CUSTOM_208 1281 +#define IMG_CUSTOM_208_EDITOR 1282 +#define IMG_CUSTOM_209 1283 +#define IMG_CUSTOM_209_EDITOR 1284 +#define IMG_CUSTOM_210 1285 +#define IMG_CUSTOM_210_EDITOR 1286 +#define IMG_CUSTOM_211 1287 +#define IMG_CUSTOM_211_EDITOR 1288 +#define IMG_CUSTOM_212 1289 +#define IMG_CUSTOM_212_EDITOR 1290 +#define IMG_CUSTOM_213 1291 +#define IMG_CUSTOM_213_EDITOR 1292 +#define IMG_CUSTOM_214 1293 +#define IMG_CUSTOM_214_EDITOR 1294 +#define IMG_CUSTOM_215 1295 +#define IMG_CUSTOM_215_EDITOR 1296 +#define IMG_CUSTOM_216 1297 +#define IMG_CUSTOM_216_EDITOR 1298 +#define IMG_CUSTOM_217 1299 +#define IMG_CUSTOM_217_EDITOR 1300 +#define IMG_CUSTOM_218 1301 +#define IMG_CUSTOM_218_EDITOR 1302 +#define IMG_CUSTOM_219 1303 +#define IMG_CUSTOM_219_EDITOR 1304 +#define IMG_CUSTOM_220 1305 +#define IMG_CUSTOM_220_EDITOR 1306 +#define IMG_CUSTOM_221 1307 +#define IMG_CUSTOM_221_EDITOR 1308 +#define IMG_CUSTOM_222 1309 +#define IMG_CUSTOM_222_EDITOR 1310 +#define IMG_CUSTOM_223 1311 +#define IMG_CUSTOM_223_EDITOR 1312 +#define IMG_CUSTOM_224 1313 +#define IMG_CUSTOM_224_EDITOR 1314 +#define IMG_CUSTOM_225 1315 +#define IMG_CUSTOM_225_EDITOR 1316 +#define IMG_CUSTOM_226 1317 +#define IMG_CUSTOM_226_EDITOR 1318 +#define IMG_CUSTOM_227 1319 +#define IMG_CUSTOM_227_EDITOR 1320 +#define IMG_CUSTOM_228 1321 +#define IMG_CUSTOM_228_EDITOR 1322 +#define IMG_CUSTOM_229 1323 +#define IMG_CUSTOM_229_EDITOR 1324 +#define IMG_CUSTOM_230 1325 +#define IMG_CUSTOM_230_EDITOR 1326 +#define IMG_CUSTOM_231 1327 +#define IMG_CUSTOM_231_EDITOR 1328 +#define IMG_CUSTOM_232 1329 +#define IMG_CUSTOM_232_EDITOR 1330 +#define IMG_CUSTOM_233 1331 +#define IMG_CUSTOM_233_EDITOR 1332 +#define IMG_CUSTOM_234 1333 +#define IMG_CUSTOM_234_EDITOR 1334 +#define IMG_CUSTOM_235 1335 +#define IMG_CUSTOM_235_EDITOR 1336 +#define IMG_CUSTOM_236 1337 +#define IMG_CUSTOM_236_EDITOR 1338 +#define IMG_CUSTOM_237 1339 +#define IMG_CUSTOM_237_EDITOR 1340 +#define IMG_CUSTOM_238 1341 +#define IMG_CUSTOM_238_EDITOR 1342 +#define IMG_CUSTOM_239 1343 +#define IMG_CUSTOM_239_EDITOR 1344 +#define IMG_CUSTOM_240 1345 +#define IMG_CUSTOM_240_EDITOR 1346 +#define IMG_CUSTOM_241 1347 +#define IMG_CUSTOM_241_EDITOR 1348 +#define IMG_CUSTOM_242 1349 +#define IMG_CUSTOM_242_EDITOR 1350 +#define IMG_CUSTOM_243 1351 +#define IMG_CUSTOM_243_EDITOR 1352 +#define IMG_CUSTOM_244 1353 +#define IMG_CUSTOM_244_EDITOR 1354 +#define IMG_CUSTOM_245 1355 +#define IMG_CUSTOM_245_EDITOR 1356 +#define IMG_CUSTOM_246 1357 +#define IMG_CUSTOM_246_EDITOR 1358 +#define IMG_CUSTOM_247 1359 +#define IMG_CUSTOM_247_EDITOR 1360 +#define IMG_CUSTOM_248 1361 +#define IMG_CUSTOM_248_EDITOR 1362 +#define IMG_CUSTOM_249 1363 +#define IMG_CUSTOM_249_EDITOR 1364 +#define IMG_CUSTOM_250 1365 +#define IMG_CUSTOM_250_EDITOR 1366 +#define IMG_CUSTOM_251 1367 +#define IMG_CUSTOM_251_EDITOR 1368 +#define IMG_CUSTOM_252 1369 +#define IMG_CUSTOM_252_EDITOR 1370 +#define IMG_CUSTOM_253 1371 +#define IMG_CUSTOM_253_EDITOR 1372 +#define IMG_CUSTOM_254 1373 +#define IMG_CUSTOM_254_EDITOR 1374 +#define IMG_CUSTOM_255 1375 +#define IMG_CUSTOM_255_EDITOR 1376 +#define IMG_CUSTOM_256 1377 +#define IMG_CUSTOM_256_EDITOR 1378 +#define IMG_GROUP_1 1379 +#define IMG_GROUP_1_EDITOR 1380 +#define IMG_GROUP_2 1381 +#define IMG_GROUP_2_EDITOR 1382 +#define IMG_GROUP_3 1383 +#define IMG_GROUP_3_EDITOR 1384 +#define IMG_GROUP_4 1385 +#define IMG_GROUP_4_EDITOR 1386 +#define IMG_GROUP_5 1387 +#define IMG_GROUP_5_EDITOR 1388 +#define IMG_GROUP_6 1389 +#define IMG_GROUP_6_EDITOR 1390 +#define IMG_GROUP_7 1391 +#define IMG_GROUP_7_EDITOR 1392 +#define IMG_GROUP_8 1393 +#define IMG_GROUP_8_EDITOR 1394 +#define IMG_GROUP_9 1395 +#define IMG_GROUP_9_EDITOR 1396 +#define IMG_GROUP_10 1397 +#define IMG_GROUP_10_EDITOR 1398 +#define IMG_GROUP_11 1399 +#define IMG_GROUP_11_EDITOR 1400 +#define IMG_GROUP_12 1401 +#define IMG_GROUP_12_EDITOR 1402 +#define IMG_GROUP_13 1403 +#define IMG_GROUP_13_EDITOR 1404 +#define IMG_GROUP_14 1405 +#define IMG_GROUP_14_EDITOR 1406 +#define IMG_GROUP_15 1407 +#define IMG_GROUP_15_EDITOR 1408 +#define IMG_GROUP_16 1409 +#define IMG_GROUP_16_EDITOR 1410 +#define IMG_GROUP_17 1411 +#define IMG_GROUP_17_EDITOR 1412 +#define IMG_GROUP_18 1413 +#define IMG_GROUP_18_EDITOR 1414 +#define IMG_GROUP_19 1415 +#define IMG_GROUP_19_EDITOR 1416 +#define IMG_GROUP_20 1417 +#define IMG_GROUP_20_EDITOR 1418 +#define IMG_GROUP_21 1419 +#define IMG_GROUP_21_EDITOR 1420 +#define IMG_GROUP_22 1421 +#define IMG_GROUP_22_EDITOR 1422 +#define IMG_GROUP_23 1423 +#define IMG_GROUP_23_EDITOR 1424 +#define IMG_GROUP_24 1425 +#define IMG_GROUP_24_EDITOR 1426 +#define IMG_GROUP_25 1427 +#define IMG_GROUP_25_EDITOR 1428 +#define IMG_GROUP_26 1429 +#define IMG_GROUP_26_EDITOR 1430 +#define IMG_GROUP_27 1431 +#define IMG_GROUP_27_EDITOR 1432 +#define IMG_GROUP_28 1433 +#define IMG_GROUP_28_EDITOR 1434 +#define IMG_GROUP_29 1435 +#define IMG_GROUP_29_EDITOR 1436 +#define IMG_GROUP_30 1437 +#define IMG_GROUP_30_EDITOR 1438 +#define IMG_GROUP_31 1439 +#define IMG_GROUP_31_EDITOR 1440 +#define IMG_GROUP_32 1441 +#define IMG_GROUP_32_EDITOR 1442 +#define IMG_EMC_OBJECT 1443 +#define IMG_EMC_SPRITE 1444 +#define IMG_TOON_1 1445 +#define IMG_TOON_2 1446 +#define IMG_TOON_3 1447 +#define IMG_TOON_4 1448 +#define IMG_TOON_5 1449 +#define IMG_TOON_6 1450 +#define IMG_TOON_7 1451 +#define IMG_TOON_8 1452 +#define IMG_TOON_9 1453 +#define IMG_TOON_10 1454 +#define IMG_TOON_11 1455 +#define IMG_TOON_12 1456 +#define IMG_TOON_13 1457 +#define IMG_TOON_14 1458 +#define IMG_TOON_15 1459 +#define IMG_TOON_16 1460 +#define IMG_TOON_17 1461 +#define IMG_TOON_18 1462 +#define IMG_TOON_19 1463 +#define IMG_TOON_20 1464 +#define IMG_MENU_CALIBRATE_RED 1465 +#define IMG_MENU_CALIBRATE_BLUE 1466 +#define IMG_MENU_CALIBRATE_YELLOW 1467 +#define IMG_MENU_BUTTON 1468 +#define IMG_MENU_BUTTON_ACTIVE 1469 +#define IMG_MENU_BUTTON_LEFT 1470 +#define IMG_MENU_BUTTON_LEFT_ACTIVE 1471 +#define IMG_MENU_BUTTON_RIGHT 1472 +#define IMG_MENU_BUTTON_RIGHT_ACTIVE 1473 +#define IMG_MENU_BUTTON_UP 1474 +#define IMG_MENU_BUTTON_UP_ACTIVE 1475 +#define IMG_MENU_BUTTON_DOWN 1476 +#define IMG_MENU_BUTTON_DOWN_ACTIVE 1477 +#define IMG_MENU_BUTTON_ENTER_MENU 1478 +#define IMG_MENU_BUTTON_ENTER_MENU_ACTIVE 1479 +#define IMG_MENU_BUTTON_LEAVE_MENU 1480 +#define IMG_MENU_BUTTON_LEAVE_MENU_ACTIVE 1481 +#define IMG_MENU_BUTTON_NEXT_LEVEL 1482 +#define IMG_MENU_BUTTON_NEXT_LEVEL_ACTIVE 1483 +#define IMG_MENU_BUTTON_PREV_LEVEL 1484 +#define IMG_MENU_BUTTON_PREV_LEVEL_ACTIVE 1485 +#define IMG_MENU_SCROLLBAR 1486 +#define IMG_MENU_SCROLLBAR_ACTIVE 1487 +#define IMG_FONT_INITIAL_1 1488 +#define IMG_FONT_INITIAL_2 1489 +#define IMG_FONT_INITIAL_3 1490 +#define IMG_FONT_INITIAL_4 1491 +#define IMG_FONT_TITLE_1 1492 +#define IMG_FONT_TITLE_2 1493 +#define IMG_FONT_MENU_1 1494 +#define IMG_FONT_MENU_1_ACTIVE 1495 +#define IMG_FONT_MENU_2 1496 +#define IMG_FONT_MENU_2_ACTIVE 1497 +#define IMG_FONT_TEXT_1 1498 +#define IMG_FONT_TEXT_1_LEVELS 1499 +#define IMG_FONT_TEXT_1_PREVIEW 1500 +#define IMG_FONT_TEXT_1_SCORES 1501 +#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1502 +#define IMG_FONT_TEXT_2 1503 +#define IMG_FONT_TEXT_2_LEVELS 1504 +#define IMG_FONT_TEXT_2_PREVIEW 1505 +#define IMG_FONT_TEXT_2_SCORES 1506 +#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1507 +#define IMG_FONT_TEXT_3 1508 +#define IMG_FONT_TEXT_3_LEVELS 1509 +#define IMG_FONT_TEXT_3_PREVIEW 1510 +#define IMG_FONT_TEXT_3_SCORES 1511 +#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1512 +#define IMG_FONT_TEXT_4 1513 +#define IMG_FONT_TEXT_4_LEVELS 1514 +#define IMG_FONT_TEXT_4_SCORES 1515 +#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1516 +#define IMG_FONT_ENVELOPE_1 1517 +#define IMG_FONT_ENVELOPE_2 1518 +#define IMG_FONT_ENVELOPE_3 1519 +#define IMG_FONT_ENVELOPE_4 1520 +#define IMG_FONT_INPUT_1 1521 +#define IMG_FONT_INPUT_1_MAIN 1522 +#define IMG_FONT_INPUT_1_ACTIVE 1523 +#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1524 +#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1525 +#define IMG_FONT_INPUT_2 1526 +#define IMG_FONT_INPUT_2_ACTIVE 1527 +#define IMG_FONT_OPTION_OFF 1528 +#define IMG_FONT_OPTION_ON 1529 +#define IMG_FONT_VALUE_1 1530 +#define IMG_FONT_VALUE_2 1531 +#define IMG_FONT_VALUE_OLD 1532 +#define IMG_FONT_LEVEL_NUMBER 1533 +#define IMG_FONT_TAPE_RECORDER 1534 +#define IMG_FONT_GAME_INFO 1535 +#define IMG_GLOBAL_BORDER 1536 +#define IMG_GLOBAL_DOOR 1537 +#define IMG_EDITOR_ELEMENT_BORDER 1538 +#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1539 +#define IMG_EDITOR_CASCADE_LIST 1540 +#define IMG_EDITOR_CASCADE_LIST_ACTIVE 1541 +#define IMG_BACKGROUND_ENVELOPE_1 1542 +#define IMG_BACKGROUND_ENVELOPE_2 1543 +#define IMG_BACKGROUND_ENVELOPE_3 1544 +#define IMG_BACKGROUND_ENVELOPE_4 1545 +#define IMG_BACKGROUND 1546 +#define IMG_BACKGROUND_TITLE 1547 +#define IMG_BACKGROUND_MESSAGE 1548 +#define IMG_BACKGROUND_MAIN 1549 +#define IMG_BACKGROUND_LEVELS 1550 +#define IMG_BACKGROUND_SCORES 1551 +#define IMG_BACKGROUND_EDITOR 1552 +#define IMG_BACKGROUND_INFO 1553 +#define IMG_BACKGROUND_INFO_ELEMENTS 1554 +#define IMG_BACKGROUND_INFO_MUSIC 1555 +#define IMG_BACKGROUND_INFO_CREDITS 1556 +#define IMG_BACKGROUND_INFO_PROGRAM 1557 +#define IMG_BACKGROUND_INFO_LEVELSET 1558 +#define IMG_BACKGROUND_SETUP 1559 +#define IMG_BACKGROUND_DOOR 1560 +#define IMG_TITLESCREEN_INITIAL_1 1561 +#define IMG_TITLESCREEN_INITIAL_2 1562 +#define IMG_TITLESCREEN_INITIAL_3 1563 +#define IMG_TITLESCREEN_INITIAL_4 1564 +#define IMG_TITLESCREEN_INITIAL_5 1565 +#define IMG_TITLESCREEN_1 1566 +#define IMG_TITLESCREEN_2 1567 +#define IMG_TITLESCREEN_3 1568 +#define IMG_TITLESCREEN_4 1569 +#define IMG_TITLESCREEN_5 1570 -#define NUM_IMAGE_FILES 1562 +#define NUM_IMAGE_FILES 1571 #endif /* CONF_GFX_H */ diff --git a/src/conf_mus.c b/src/conf_mus.c index 83404171..2d2cd8a9 100644 --- a/src/conf_mus.c +++ b/src/conf_mus.c @@ -30,6 +30,7 @@ struct ConfigInfo music_config[] = { { "background", UNDEFINED_FILENAME }, { "background.TITLE", UNDEFINED_FILENAME }, + { "background.MESSAGE", UNDEFINED_FILENAME }, { "background.MAIN", UNDEFINED_FILENAME }, { "background.LEVELS", UNDEFINED_FILENAME }, { "background.SCORES", UNDEFINED_FILENAME }, diff --git a/src/conf_mus.h b/src/conf_mus.h index 8fce300c..6c7f9352 100644 --- a/src/conf_mus.h +++ b/src/conf_mus.h @@ -20,13 +20,14 @@ #define MUS_BACKGROUND 0 #define MUS_BACKGROUND_TITLE 1 -#define MUS_BACKGROUND_MAIN 2 -#define MUS_BACKGROUND_LEVELS 3 -#define MUS_BACKGROUND_SCORES 4 -#define MUS_BACKGROUND_EDITOR 5 -#define MUS_BACKGROUND_INFO 6 -#define MUS_BACKGROUND_SETUP 7 +#define MUS_BACKGROUND_MESSAGE 2 +#define MUS_BACKGROUND_MAIN 3 +#define MUS_BACKGROUND_LEVELS 4 +#define MUS_BACKGROUND_SCORES 5 +#define MUS_BACKGROUND_EDITOR 6 +#define MUS_BACKGROUND_INFO 7 +#define MUS_BACKGROUND_SETUP 8 -#define NUM_MUSIC_FILES 8 +#define NUM_MUSIC_FILES 9 #endif /* CONF_MUS_H */ diff --git a/src/conf_snd.c b/src/conf_snd.c index 1c3ce29a..01696a0f 100644 --- a/src/conf_snd.c +++ b/src/conf_snd.c @@ -240,7 +240,12 @@ struct ConfigInfo sound_config[] = { "door.opening", "oeffnen.wav" }, { "door.closing", "oeffnen.wav" }, + /* sounds for menu actions */ + { "menu.item.activating", "empty.wav" }, + { "menu.item.selecting", "base.wav" }, + { "background.TITLE", UNDEFINED_FILENAME }, + { "background.MESSAGE", UNDEFINED_FILENAME }, { "background.MAIN", UNDEFINED_FILENAME }, { "background.LEVELS", UNDEFINED_FILENAME }, { "background.SCORES", "halloffame.wav" }, diff --git a/src/conf_snd.h b/src/conf_snd.h index 3c2fa46d..164c2a91 100644 --- a/src/conf_snd.h +++ b/src/conf_snd.h @@ -200,14 +200,17 @@ #define SND_GAME_SOKOBAN_SOLVING 179 #define SND_DOOR_OPENING 180 #define SND_DOOR_CLOSING 181 -#define SND_BACKGROUND_TITLE 182 -#define SND_BACKGROUND_MAIN 183 -#define SND_BACKGROUND_LEVELS 184 -#define SND_BACKGROUND_SCORES 185 -#define SND_BACKGROUND_EDITOR 186 -#define SND_BACKGROUND_INFO 187 -#define SND_BACKGROUND_SETUP 188 +#define SND_MENU_ITEM_ACTIVATING 182 +#define SND_MENU_ITEM_SELECTING 183 +#define SND_BACKGROUND_TITLE 184 +#define SND_BACKGROUND_MESSAGE 185 +#define SND_BACKGROUND_MAIN 186 +#define SND_BACKGROUND_LEVELS 187 +#define SND_BACKGROUND_SCORES 188 +#define SND_BACKGROUND_EDITOR 189 +#define SND_BACKGROUND_INFO 190 +#define SND_BACKGROUND_SETUP 191 -#define NUM_SOUND_FILES 189 +#define NUM_SOUND_FILES 192 #endif /* CONF_SND_H */ diff --git a/src/conftime.h b/src/conftime.h index 78c8fc41..a0dcbff6 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2006-08-29 23:29]" +#define COMPILE_DATE_STRING "[2007-01-05 13:11]" diff --git a/src/editor.c b/src/editor.c index 2a7a8e4e..7ace5ece 100644 --- a/src/editor.c +++ b/src/editor.c @@ -2413,8 +2413,13 @@ static struct ED_SCROLLBAR_XPOS, ED_SCROLLBAR_YPOS, SX + ED_SCROLL_HORIZONTAL_XPOS, SY + ED_SCROLL_HORIZONTAL_YPOS, ED_SCROLL_HORIZONTAL_XSIZE, ED_SCROLL_HORIZONTAL_YSIZE, +#if 1 + SX, SY, + SXSIZE, SYSIZE, +#else 0, 0, SX + SXSIZE + SX, WIN_YSIZE, +#endif GD_TYPE_SCROLLBAR_HORIZONTAL, GADGET_ID_SCROLL_HORIZONTAL, "scroll level editing area horizontally" @@ -2423,8 +2428,13 @@ static struct ED_SCROLLBAR_XPOS, ED_SCROLLBAR_YPOS, SX + ED_SCROLL_VERTICAL_XPOS, SY + ED_SCROLL_VERTICAL_YPOS, ED_SCROLL_VERTICAL_XSIZE, ED_SCROLL_VERTICAL_YSIZE, +#if 1 + SX, SY, + SXSIZE, SYSIZE, +#else 0, 0, SX + SXSIZE + SX, WIN_YSIZE, +#endif GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_VERTICAL, "scroll level editing area vertically" @@ -2433,8 +2443,13 @@ static struct ED_SCROLLBAR2_XPOS, ED_SCROLLBAR2_YPOS, DX + ED_SCROLL2_VERTICAL_XPOS, DY + ED_SCROLL2_VERTICAL_YPOS, ED_SCROLL2_VERTICAL_XSIZE, ED_SCROLL2_VERTICAL_YSIZE, +#if 1 + DX, DY, + DXSIZE, DYSIZE, +#else SX + SXSIZE + SX, 0, WIN_XSIZE - (SX + SXSIZE + SX), WIN_YSIZE, +#endif GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_LIST_VERTICAL, "scroll element list vertically" @@ -6761,7 +6776,11 @@ void DrawLevelEd() ReinitializeElementList(); /* update dynamic level element list */ ReinitializeElementListButtons(); /* custom element may look different */ +#if 1 + UnmapAllGadgets(); +#else UnmapTapeButtons(); +#endif MapControlButtons(); DrawEditModeWindow(); @@ -7281,7 +7300,7 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1; return DrawTextFromFile(sx, sy, filename, font_nr, max_chars_per_line, - max_lines_per_screen); + max_lines_per_screen, TRUE); } static void DrawPropertiesTabulatorGadgets() @@ -9062,7 +9081,14 @@ static void HandleTextAreaGadgets(struct GadgetInfo *gi) { int type_id = gi->custom_type_id; +#if 1 + strncpy(textarea_info[type_id].value, gi->textarea.value, + MAX_ENVELOPE_TEXT_LEN); + textarea_info[type_id].value[MAX_ENVELOPE_TEXT_LEN] = '\0'; +#else + /* !!! BUGGY !!! MAX_ENVELOPE_TEXT_LEN != MAX_GADGET_TEXTSIZE !!! */ strcpy(textarea_info[type_id].value, gi->textarea.value); +#endif level.changed = TRUE; } diff --git a/src/events.c b/src/events.c index 65b06803..7ea4356b 100644 --- a/src/events.c +++ b/src/events.c @@ -127,7 +127,7 @@ void EventLoop(void) while (NextValidEvent(&event)) { - switch(event.type) + switch (event.type) { case EVENT_BUTTONPRESS: case EVENT_BUTTONRELEASE: @@ -194,7 +194,7 @@ void EventLoop(void) void HandleOtherEvents(Event *event) { - switch(event->type) + switch (event->type) { case EVENT_EXPOSE: HandleExposeEvent((ExposeEvent *) event); @@ -238,7 +238,7 @@ void ClearEventQueue() NextEvent(&event); - switch(event.type) + switch (event.type) { case EVENT_BUTTONRELEASE: button_status = MB_RELEASED; @@ -281,7 +281,7 @@ void SleepWhileUnmapped() NextEvent(&event); - switch(event.type) + switch (event.type) { case EVENT_BUTTONRELEASE: button_status = MB_RELEASED; @@ -667,8 +667,18 @@ void HandleKey(Key key, int key_status) element_dropped[pnr] = FALSE; } } +#if 1 + else if (tape.recording && tape.pausing) + { + /* prevent key release events from un-pausing a paused game */ + if (key_status == KEY_PRESSED && + (key_action & KEY_ACTION)) + TapeTogglePause(TAPE_TOGGLE_MANUAL); + } +#else else if (tape.recording && tape.pausing && (key_action & KEY_ACTION)) TapeTogglePause(TAPE_TOGGLE_MANUAL); +#endif } } else @@ -701,6 +711,9 @@ void HandleKey(Key key, int key_status) ToggleFullscreenIfNeeded(); + if (game_status == GAME_MODE_SETUP) + RedrawSetupScreenAfterFullscreenToggle(); + return; } @@ -768,7 +781,7 @@ void HandleKey(Key key, int key_status) key = KSYM_UNDEFINED; } - switch(game_status) + switch (game_status) { case GAME_MODE_PSEUDO_TYPENAME: HandleTypeName(0, key); @@ -780,7 +793,7 @@ void HandleKey(Key key, int key_status) case GAME_MODE_SETUP: case GAME_MODE_INFO: case GAME_MODE_SCORES: - switch(key) + switch (key) { case KSYM_space: case KSYM_Return: @@ -851,7 +864,7 @@ void HandleKey(Key key, int key_status) case GAME_MODE_PLAYING: { - switch(key) + switch (key) { case KSYM_Escape: RequestQuitGame(setup.ask_on_escape); @@ -1016,7 +1029,7 @@ void HandleJoystick() int dx = (left ? -1 : right ? 1 : 0); int dy = (up ? -1 : down ? 1 : 0); - switch(game_status) + switch (game_status) { case GAME_MODE_TITLE: case GAME_MODE_MAIN: diff --git a/src/files.c b/src/files.c index deff36d6..55645441 100644 --- a/src/files.c +++ b/src/files.c @@ -1249,7 +1249,11 @@ static void setEventFlagsFromEventBits(struct ElementChangeInfo *change) { int i; - /* important: only change event flag if corresponding event bit is set */ + /* important: only change event flag if corresponding event bit is set + (this is because all xx_event_bits[] values are loaded separately, + and all xx_event_bits[] values are set back to zero before loading + another value xx_event_bits[x] (each value representing 32 flags)) */ + for (i = 0; i < NUM_CHANGE_EVENTS; i++) if (xx_event_bits[CH_EVENT_BITFIELD_NR(i)] & CH_EVENT_BIT(i)) change->has_event[i] = TRUE; @@ -1259,7 +1263,11 @@ static void setEventBitsFromEventFlags(struct ElementChangeInfo *change) { int i; - /* important: only change event bit if corresponding event flag is set */ + /* in contrast to the above function setEventFlagsFromEventBits(), it + would also be possible to set all bits in xx_event_bits[] to 0 or 1 + depending on the corresponding change->has_event[i] values here, as + all xx_event_bits[] values are reset in resetEventBits() before */ + for (i = 0; i < NUM_CHANGE_EVENTS; i++) if (change->has_event[i]) xx_event_bits[CH_EVENT_BITFIELD_NR(i)] |= CH_EVENT_BIT(i); @@ -1446,7 +1454,11 @@ void setElementChangePages(struct ElementInfo *ei, int change_pages) void setElementChangeInfoToDefaults(struct ElementChangeInfo *change) { xx_change = *change; /* copy change data into temporary buffer */ + +#if 0 + /* (not needed; set by setConfigToDefaultsFromConfigList()) */ xx_num_contents = 1; +#endif setConfigToDefaultsFromConfigList(chunk_config_CUSX_change); @@ -2032,12 +2044,12 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) STEPSIZE_NORMAL); for (i = 0; i < MAX_PLAYERS; i++) - level->initial_player_stepsize[0] = initial_player_stepsize; + level->initial_player_stepsize[i] = initial_player_stepsize; initial_player_gravity = (getFile8Bit(file) == 1 ? TRUE : FALSE); for (i = 0; i < MAX_PLAYERS; i++) - level->initial_player_gravity[0] = initial_player_gravity; + level->initial_player_gravity[i] = initial_player_gravity; level->encoding_16bit_field = (getFile8Bit(file) == 1 ? TRUE : FALSE); level->em_slippery_gems = (getFile8Bit(file) == 1 ? TRUE : FALSE); @@ -2606,7 +2618,21 @@ static int LoadLevel_MicroChunk(FILE *file, struct LevelFileConfigInfo *conf, num_entities = max_num_entities; } - *(int *)(conf[i].num_entities) = num_entities; + if (num_entities == 0 && (data_type == TYPE_ELEMENT_LIST || + data_type == TYPE_CONTENT_LIST)) + { + /* for element and content lists, zero entities are not allowed */ + Error(ERR_WARN, "found empty list of entities for element %d", + element); + + /* do not set "num_entities" here to prevent reading behind buffer */ + + *(int *)(conf[i].num_entities) = 1; /* at least one is required */ + } + else + { + *(int *)(conf[i].num_entities) = num_entities; + } element_found = TRUE; @@ -5120,8 +5146,11 @@ static int SaveLevel_CUSX(FILE *file, struct LevelInfo *level, int element) /* set default description string for this specific element */ strcpy(xx_default_description, getDefaultElementDescription(ei)); - /* set (fixed) number of content areas (may have been overwritten earlier) */ +#if 0 + /* set (fixed) number of content areas (may be wrong by broken level file) */ + /* (this is now directly corrected for broken level files after loading) */ xx_num_contents = 1; +#endif for (i = 0; chunk_config_CUSX_base[i].data_type != -1; i++) chunk_size += SaveLevel_MicroChunk(file, &chunk_config_CUSX_base[i], FALSE); @@ -5276,6 +5305,25 @@ void SaveLevelTemplate() SaveLevelFromFilename(&level, filename); } +boolean SaveLevelChecked(int nr) +{ + char *filename = getDefaultLevelFilename(nr); + boolean new_level = !fileExists(filename); + boolean level_saved = FALSE; + + if (new_level || Request("Save this level and kill the old ?", REQ_ASK)) + { + SaveLevel(nr); + + if (new_level) + Request("Level saved !", REQ_CONFIRM); + + level_saved = TRUE; + } + + return level_saved; +} + void DumpLevel(struct LevelInfo *level) { if (level->no_valid_file) @@ -5704,7 +5752,9 @@ void SaveTape(int nr) { char *filename = getTapeFilename(nr); FILE *file; +#if 0 boolean new_tape = TRUE; +#endif int num_participating_players = 0; int info_chunk_size; int body_chunk_size; @@ -5712,6 +5762,7 @@ void SaveTape(int nr) InitTapeDirectory(leveldir_current->subdir); +#if 0 /* if a tape still exists, ask to overwrite it */ if (fileExists(filename)) { @@ -5719,6 +5770,7 @@ void SaveTape(int nr) if (!Request("Replace old tape ?", REQ_ASK)) return; } +#endif if (!(file = fopen(filename, MODE_WRITE))) { @@ -5758,8 +5810,29 @@ void SaveTape(int nr) tape.changed = FALSE; +#if 0 if (new_tape) Request("Tape saved !", REQ_CONFIRM); +#endif +} + +boolean SaveTapeChecked(int nr) +{ + char *filename = getTapeFilename(nr); + boolean new_tape = !fileExists(filename); + boolean tape_saved = FALSE; + + if (new_tape || Request("Replace old tape ?", REQ_ASK)) + { + SaveTape(nr); + + if (new_tape) + Request("Tape saved !", REQ_CONFIRM); + + tape_saved = TRUE; + } + + return tape_saved; } void DumpTape(struct TapeInfo *tape) @@ -6575,6 +6648,18 @@ static void LoadSpecialMenuDesignSettingsFromFilename(char *filename) menu.list_size[i] = get_integer_from_string(list_size); } + /* special case: initialize with default values that may be overwritten */ + for (i = 0; i < NUM_SPECIAL_GFX_INFO_ARGS; i++) + { + char *value_x = getHashEntry(setup_file_hash, "menu.draw_xoffset.INFO"); + char *value_y = getHashEntry(setup_file_hash, "menu.draw_yoffset.INFO"); + + if (value_x != NULL) + menu.draw_xoffset_info[i] = get_integer_from_string(value_x); + if (value_y != NULL) + menu.draw_yoffset_info[i] = get_integer_from_string(value_y); + } + /* read (and overwrite with) values that may be specified in config file */ for (i = 0; image_config_vars[i].token != NULL; i++) { diff --git a/src/files.h b/src/files.h index a3781bed..41939ac2 100644 --- a/src/files.h +++ b/src/files.h @@ -39,6 +39,7 @@ void LoadLevelTemplate(int); void SaveLevel(int); void SaveLevelTemplate(); void DumpLevel(struct LevelInfo *); +boolean SaveLevelChecked(int); void CopyNativeLevel_RND_to_Native(struct LevelInfo *); void CopyNativeLevel_Native_to_RND(struct LevelInfo *); @@ -48,6 +49,7 @@ void LoadTape(int); void LoadSolutionTape(int); void SaveTape(int); void DumpTape(struct TapeInfo *); +boolean SaveTapeChecked(int); void LoadScore(int); void SaveScore(int); diff --git a/src/game.c b/src/game.c index d8eb7353..00a1a090 100644 --- a/src/game.c +++ b/src/game.c @@ -53,6 +53,12 @@ #define USE_UFAST_PLAYER_EXIT_BUGFIX (USE_NEW_STUFF * 1) +#define USE_GFX_RESET_ONLY_WHEN_MOVING (USE_NEW_STUFF * 1) +#define USE_GFX_RESET_PLAYER_ARTWORK (USE_NEW_STUFF * 1) + +#define USE_FIX_KILLED_BY_NON_WALKABLE (USE_NEW_STUFF * 1) +#define USE_FIX_IMPACT_COLLISION (USE_NEW_STUFF * 1) + /* for DigField() */ #define DF_NO_PUSH 0 @@ -115,8 +121,9 @@ /* values for delayed check of falling and moving elements and for collision */ #define CHECK_DELAY_MOVING 3 -#define CHECK_DELAY_FALLING 3 +#define CHECK_DELAY_FALLING CHECK_DELAY_MOVING #define CHECK_DELAY_COLLISION 2 +#define CHECK_DELAY_IMPACT CHECK_DELAY_COLLISION /* values for initial player move delay (initial delay counter value) */ #define INITIAL_MOVE_DELAY_OFF -1 @@ -372,6 +379,33 @@ static int getInvisibleFromInvisibleActiveElement(int); static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS]; +/* for detection of endless loops, caused by custom element programming */ +/* (using "MAX_PLAYFIELD_WIDTH" here is just a rough approximation...) */ +#define MAX_ELEMENT_CHANGE_RECURSION_DEPTH (MAX_PLAYFIELD_WIDTH) + +#define RECURSION_LOOP_DETECTION_START(e, rc) \ +{ \ + if (recursion_loop_detected) \ + return (rc); \ + \ + if (recursion_loop_depth > MAX_ELEMENT_CHANGE_RECURSION_DEPTH) \ + { \ + recursion_loop_detected = TRUE; \ + recursion_loop_element = (e); \ + } \ + \ + recursion_loop_depth++; \ +} + +#define RECURSION_LOOP_DETECTION_END() \ +{ \ + recursion_loop_depth--; \ +} + +static int recursion_loop_depth; +static boolean recursion_loop_detected; +static boolean recursion_loop_element; + /* ------------------------------------------------------------------------- */ /* definition of elements that automatically change to other elements after */ @@ -1779,6 +1813,11 @@ static void InitGameEngine() EL_EMPTY); } } + + /* ---------- initialize recursion detection ------------------------------ */ + recursion_loop_depth = 0; + recursion_loop_detected = FALSE; + recursion_loop_element = EL_UNDEFINED; } int get_num_special_action(int element, int action_first, int action_last) @@ -1838,6 +1877,7 @@ void InitGame() player->present = FALSE; player->active = FALSE; + player->killed = FALSE; player->action = 0; player->effective_action = 0; @@ -1929,8 +1969,10 @@ void InitGame() player->drop_delay = 0; player->drop_pressed_delay = 0; - player->last_jx = player->last_jy = 0; - player->jx = player->jy = 0; + player->last_jx = -1; + player->last_jy = -1; + player->jx = -1; + player->jy = -1; player->shield_normal_time_left = 0; player->shield_deadly_time_left = 0; @@ -2030,6 +2072,7 @@ void InitGame() WasJustMoving[x][y] = 0; WasJustFalling[x][y] = 0; CheckCollision[x][y] = 0; + CheckImpact[x][y] = 0; Stop[x][y] = FALSE; Pushed[x][y] = FALSE; @@ -2445,6 +2488,13 @@ void InitGame() } } +#if 1 + UnmapAllGadgets(); + + MapGameButtons(); + MapTapeButtons(); +#endif + game.restart_level = FALSE; } @@ -2474,7 +2524,7 @@ void InitMovDir(int x, int y) { MV_LEFT, MV_RIGHT, MV_UP, MV_DOWN } }; - switch(element) + switch (element) { case EL_BUG_RIGHT: case EL_BUG_UP: @@ -2717,35 +2767,38 @@ void GameWon() DrawGameValue_Score(score); } - if (ExitX >= 0 && ExitY >= 0) /* local player has left the level */ + if (level.game_engine_type == GAME_ENGINE_TYPE_RND) { - /* close exit door after last player */ - if (AllPlayersGone && - (Feld[ExitX][ExitY] == EL_EXIT_OPEN || - Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN)) + if (ExitX >= 0 && ExitY >= 0) /* local player has left the level */ { - int element = Feld[ExitX][ExitY]; + /* close exit door after last player */ + if (AllPlayersGone && + (Feld[ExitX][ExitY] == EL_EXIT_OPEN || + Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN)) + { + int element = Feld[ExitX][ExitY]; - Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : - EL_SP_EXIT_CLOSING); + Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING : + EL_SP_EXIT_CLOSING); - PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); - } - - /* player disappears */ - DrawLevelField(ExitX, ExitY); - } + PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING); + } - for (i = 0; i < MAX_PLAYERS; i++) - { - struct PlayerInfo *player = &stored_player[i]; + /* player disappears */ + DrawLevelField(ExitX, ExitY); + } - if (player->present) + for (i = 0; i < MAX_PLAYERS; i++) { - RemovePlayer(player); + struct PlayerInfo *player = &stored_player[i]; - /* player disappears */ - DrawLevelField(player->jx, player->jy); + if (player->present) + { + RemovePlayer(player); + + /* player disappears */ + DrawLevelField(player->jx, player->jy); + } } } @@ -2793,7 +2846,11 @@ void GameEnd() TapeStop(); #endif +#if 1 + SaveTapeChecked(tape.level_nr); /* ask to save tape */ +#else SaveTape(tape.level_nr); /* ask to save tape */ +#endif } if (level_editor_test_game) @@ -2913,10 +2970,9 @@ int NewHiScore() return position; } -inline static int getElementMoveStepsize(int x, int y) +inline static int getElementMoveStepsizeExt(int x, int y, int direction) { int element = Feld[x][y]; - int direction = MovDir[x][y]; int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0); int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); int horiz_move = (dx != 0); @@ -2936,6 +2992,11 @@ inline static int getElementMoveStepsize(int x, int y) return step; } +inline static int getElementMoveStepsize(int x, int y) +{ + return getElementMoveStepsizeExt(x, y, MovDir[x][y]); +} + void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir) { if (player->GfxAction != action || player->GfxDir != dir) @@ -2996,18 +3057,51 @@ void InitMovingField(int x, int y, int direction) int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0); int newx = x + dx; int newy = y + dy; + boolean is_moving_before, is_moving_after; +#if 0 + boolean continues_moving = (WasJustMoving[x][y] && direction == MovDir[x][y]); +#endif + + /* check if element was/is moving or being moved before/after mode change */ +#if 1 + is_moving_before = WasJustMoving[x][y]; +#else + is_moving_before = (getElementMoveStepsizeExt(x, y, MovDir[x][y]) != 0); +#endif + is_moving_after = (getElementMoveStepsizeExt(x, y, direction) != 0); - if (!WasJustMoving[x][y] || direction != MovDir[x][y]) + /* reset animation only for moving elements which change direction of moving + or which just started or stopped moving + (else CEs with property "can move" / "not moving" are reset each frame) */ +#if USE_GFX_RESET_ONLY_WHEN_MOVING +#if 1 + if (is_moving_before != is_moving_after || + direction != MovDir[x][y]) ResetGfxAnimation(x, y); +#else + if ((is_moving_before || is_moving_after) && !continues_moving) + ResetGfxAnimation(x, y); +#endif +#else + if (!continues_moving) + ResetGfxAnimation(x, y); +#endif MovDir[x][y] = direction; GfxDir[x][y] = direction; + +#if USE_GFX_RESET_ONLY_WHEN_MOVING + GfxAction[x][y] = (!is_moving_after ? ACTION_WAITING : + direction == MV_DOWN && CAN_FALL(element) ? + ACTION_FALLING : ACTION_MOVING); +#else GfxAction[x][y] = (direction == MV_DOWN && CAN_FALL(element) ? ACTION_FALLING : ACTION_MOVING); +#endif /* this is needed for CEs with property "can move" / "not moving" */ - if (getElementMoveStepsize(x, y) != 0) /* moving or being moved */ + if (is_moving_after) { if (Feld[newx][newy] == EL_EMPTY) Feld[newx][newy] = EL_BLOCKED; @@ -3266,8 +3360,8 @@ static void setScreenCenteredToAllPlayers(int *sx, int *sy) *sy = (sy1 + sy2) / 2; } -void DrawRelocateScreen(int x, int y, int move_dir, boolean center_screen, - boolean quick_relocation) +void DrawRelocateScreen(int old_x, int old_y, int x, int y, int move_dir, + boolean center_screen, boolean quick_relocation) { boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); @@ -3280,13 +3374,39 @@ void DrawRelocateScreen(int x, int y, int move_dir, boolean center_screen, if (!IN_VIS_FIELD(SCREENX(x), SCREENY(y)) || center_screen) { - scroll_x = (x < SBX_Left + MIDPOSX ? SBX_Left : - x > SBX_Right + MIDPOSX ? SBX_Right : - x - MIDPOSX); + if (center_screen) + { + scroll_x = (x < SBX_Left + MIDPOSX ? SBX_Left : + x > SBX_Right + MIDPOSX ? SBX_Right : + x - MIDPOSX); + + scroll_y = (y < SBY_Upper + MIDPOSY ? SBY_Upper : + y > SBY_Lower + MIDPOSY ? SBY_Lower : + y - MIDPOSY); + } + else + { + /* quick relocation (without scrolling), but do not center screen */ - scroll_y = (y < SBY_Upper + MIDPOSY ? SBY_Upper : - y > SBY_Lower + MIDPOSY ? SBY_Lower : - y - MIDPOSY); + int center_scroll_x = (old_x < SBX_Left + MIDPOSX ? SBX_Left : + old_x > SBX_Right + MIDPOSX ? SBX_Right : + old_x - MIDPOSX); + + int center_scroll_y = (old_y < SBY_Upper + MIDPOSY ? SBY_Upper : + old_y > SBY_Lower + MIDPOSY ? SBY_Lower : + old_y - MIDPOSY); + + int offset_x = x + (scroll_x - center_scroll_x); + int offset_y = y + (scroll_y - center_scroll_y); + + scroll_x = (offset_x < SBX_Left + MIDPOSX ? SBX_Left : + offset_x > SBX_Right + MIDPOSX ? SBX_Right : + offset_x - MIDPOSX); + + scroll_y = (offset_y < SBY_Upper + MIDPOSY ? SBY_Upper : + offset_y > SBY_Lower + MIDPOSY ? SBY_Lower : + offset_y - MIDPOSY); + } } else { @@ -3433,8 +3553,8 @@ void RelocatePlayer(int jx, int jy, int el_player_raw) } /* only visually relocate centered player */ - DrawRelocateScreen(player->jx, player->jy, player->MovDir, FALSE, - level.instant_relocation); + DrawRelocateScreen(old_jx, old_jy, player->jx, player->jy, player->MovDir, + FALSE, level.instant_relocation); TestIfPlayerTouchesBadThing(jx, jy); TestIfPlayerTouchesCustomElement(jx, jy); @@ -3867,7 +3987,7 @@ void Bang(int x, int y) } } - switch(element) + switch (element) { case EL_BUG: case EL_SPACESHIP: @@ -5579,9 +5699,14 @@ void StartMoving(int x, int y) Store[x][y] = EL_ACID; } - else if ((game.engine_version >= VERSION_IDENT(3,1,0,0) && + else if ( +#if USE_FIX_IMPACT_COLLISION + (game.engine_version >= VERSION_IDENT(3,1,0,0) && + CheckImpact[x][y] && !IS_FREE(x, y + 1)) || +#else + (game.engine_version >= VERSION_IDENT(3,1,0,0) && CheckCollision[x][y] && !IS_FREE(x, y + 1)) || - +#endif (game.engine_version >= VERSION_IDENT(3,0,7,0) && CAN_FALL(element) && WasJustFalling[x][y] && (Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1))) || @@ -5601,6 +5726,7 @@ void StartMoving(int x, int y) simply not covered here... :-/ ) */ CheckCollision[x][y] = 0; + CheckImpact[x][y] = 0; Impact(x, y); } @@ -6545,6 +6671,11 @@ void ContinueMoving(int x, int y) if ((!CAN_FALL(element) || direction == MV_DOWN) && check_collision_again) CheckCollision[newx][newy] = CHECK_DELAY_COLLISION; + +#if USE_FIX_IMPACT_COLLISION + if (CAN_FALL(element) && direction == MV_DOWN && check_collision_again) + CheckImpact[newx][newy] = CHECK_DELAY_IMPACT; +#endif } if (DONT_TOUCH(element)) /* object may be nasty to player or others */ @@ -6612,7 +6743,7 @@ void ContinueMoving(int x, int y) if (IS_CUSTOM_ELEMENT(element) && ei->move_enter_element != EL_EMPTY && IS_EQUAL_OR_IN_GROUP(stored_new, ei->move_enter_element)) CheckElementChangeBySide(newx, newy, element, stored_new, CE_DIGGING_X, - MV_DIR_OPPOSITE(direction)); + MV_DIR_OPPOSITE(direction)); } int AmoebeNachbarNr(int ax, int ay) @@ -7219,7 +7350,7 @@ static void CloseAllOpenTimegates() } } -void EdelsteinFunkeln(int x, int y) +void DrawTwinkleOnField(int x, int y) { if (!IN_SCR_FIELD(SCREENX(x), SCREENY(y)) || IS_MOVING(x, y)) return; @@ -7662,7 +7793,7 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) /* ---------- execute action -------------------------------------------- */ - switch(action_type) + switch (action_type) { case CA_NO_ACTION: { @@ -7890,6 +8021,11 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) (level.use_artwork_element[i] ? level.artwork_element[i] : stored_player[i].element_nr); +#if USE_GFX_RESET_PLAYER_ARTWORK + if (stored_player[i].artwork_element != artwork_element) + stored_player[i].Frame = 0; +#endif + stored_player[i].artwork_element = artwork_element; SetPlayerWaiting(&stored_player[i], FALSE); @@ -7997,6 +8133,7 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change) #if USE_NEW_CUSTOM_VALUE int last_ce_value = CustomValue[x][y]; #endif + boolean player_explosion_protected = PLAYER_EXPLOSION_PROTECTED(x, y); boolean new_element_is_player = ELEM_IS_PLAYER(new_element); boolean add_player_onto_element = (new_element_is_player && #if USE_CODE_THAT_BREAKS_SNAKE_BITE @@ -8060,6 +8197,15 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change) /* check if element under the player changes from accessible to unaccessible (needed for special case of dropping element which then changes) */ /* (must be checked after creating new element for walkable group elements) */ +#if USE_FIX_KILLED_BY_NON_WALKABLE + if (IS_PLAYER(x, y) && !player_explosion_protected && + IS_ACCESSIBLE(old_element) && !IS_ACCESSIBLE(new_element)) + { + Bang(x, y); + + return; + } +#else if (IS_PLAYER(x, y) && !PLAYER_EXPLOSION_PROTECTED(x, y) && IS_ACCESSIBLE(old_element) && !IS_ACCESSIBLE(new_element)) { @@ -8067,6 +8213,7 @@ static void CreateFieldExt(int x, int y, int element, boolean is_change) return; } +#endif #endif /* "ChangeCount" not set yet to allow "entered by player" change one time */ @@ -8463,6 +8610,14 @@ static boolean CheckTriggeredElementChangeExt(int trigger_x, int trigger_y, if (!(trigger_events[trigger_element][trigger_event])) return FALSE; +#if 0 + printf("::: CheckTriggeredElementChangeExt %d ... [%d, %d, %d, '%s']\n", + trigger_event, recursion_loop_depth, recursion_loop_detected, + recursion_loop_element, EL_NAME(recursion_loop_element)); +#endif + + RECURSION_LOOP_DETECTION_START(trigger_element, FALSE); + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) { int element = EL_CUSTOM_START + i; @@ -8531,6 +8686,8 @@ static boolean CheckTriggeredElementChangeExt(int trigger_x, int trigger_y, } } + RECURSION_LOOP_DETECTION_END(); + return change_done_any; } @@ -8569,14 +8726,30 @@ static boolean CheckElementChangeExt(int x, int y, return FALSE; #endif +#if 0 + printf("::: CheckElementChangeExt %d ... [%d, %d, %d, '%s']\n", + trigger_event, recursion_loop_depth, recursion_loop_detected, + recursion_loop_element, EL_NAME(recursion_loop_element)); +#endif + + RECURSION_LOOP_DETECTION_START(trigger_element, FALSE); + for (p = 0; p < element_info[element].num_change_pages; p++) { struct ElementChangeInfo *change = &element_info[element].change_page[p]; + /* check trigger element for all events where the element that is checked + for changing interacts with a directly adjacent element -- this is + different to element changes that affect other elements to change on the + whole playfield (which is handeld by CheckTriggeredElementChangeExt()) */ boolean check_trigger_element = (trigger_event == CE_TOUCHING_X || trigger_event == CE_HITTING_X || - trigger_event == CE_HIT_BY_X); + trigger_event == CE_HIT_BY_X || +#if 1 + /* this one was forgotten until 3.2.3 */ + trigger_event == CE_DIGGING_X); +#endif if (change->can_change_or_has_action && change->has_event[trigger_event] && @@ -8640,6 +8813,8 @@ static boolean CheckElementChangeExt(int x, int y, } } + RECURSION_LOOP_DETECTION_END(); + return change_done; } @@ -9041,6 +9216,25 @@ void GameActions() byte tape_action[MAX_PLAYERS]; int i; + /* detect endless loops, caused by custom element programming */ + if (recursion_loop_detected && recursion_loop_depth == 0) + { + char *message = getStringCat3("Internal Error ! Element ", + EL_NAME(recursion_loop_element), + " caused endless loop ! Quit the game ?"); + + Error(ERR_WARN, "element '%s' caused endless loop in game engine", + EL_NAME(recursion_loop_element)); + + RequestQuitGameExt(FALSE, level_editor_test_game, message); + + recursion_loop_detected = FALSE; /* if game should be continued */ + + free(message); + + return; + } + if (game.restart_level) StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE); @@ -9244,7 +9438,7 @@ void GameActions_RND() game.centered_player_nr = game.centered_player_nr_next; game.set_centered_player = FALSE; - DrawRelocateScreen(sx, sy, MV_NONE, TRUE, setup.quick_switch); + DrawRelocateScreen(0, 0, sx, sy, MV_NONE, TRUE, setup.quick_switch); DrawGameDoorValues(); } @@ -9350,6 +9544,8 @@ void GameActions_RND() WasJustFalling[x][y]--; if (CheckCollision[x][y] > 0) CheckCollision[x][y]--; + if (CheckImpact[x][y] > 0) + CheckImpact[x][y]--; GfxFrame[x][y]++; @@ -9434,7 +9630,7 @@ void GameActions_RND() DrawLevelGraphicAnimationIfNeeded(x, y, graphic); if (IS_GEM(element) || element == EL_SP_INFOTRON) - EdelsteinFunkeln(x, y); + DrawTwinkleOnField(x, y); } else if ((element == EL_ACID || element == EL_EXIT_OPEN || @@ -10961,6 +11157,23 @@ void KillPlayer(struct PlayerInfo *player) if (!player->active) return; + /* the following code was introduced to prevent an infinite loop when calling + -> Bang() + -> CheckTriggeredElementChangeExt() + -> ExecuteCustomElementAction() + -> KillPlayer() + -> (infinitely repeating the above sequence of function calls) + which occurs when killing the player while having a CE with the setting + "kill player X when explosion of "; the solution using a new + field "player->killed" was chosen for backwards compatibility, although + clever use of the fields "player->active" etc. would probably also work */ +#if 1 + if (player->killed) + return; +#endif + + player->killed = TRUE; + /* remove accessible field at the player's position */ Feld[jx][jy] = EL_EMPTY; @@ -11986,7 +12199,13 @@ boolean DropElement(struct PlayerInfo *player) nexty = dropy + GET_DY_FROM_DIR(move_direction); ChangeCount[dropx][dropy] = 0; /* allow at least one more change */ + +#if USE_FIX_IMPACT_COLLISION + /* do not cause impact style collision by dropping elements that can fall */ + CheckCollision[dropx][dropy] = CHECK_DELAY_COLLISION; +#else CheckCollision[dropx][dropy] = CHECK_DELAY_COLLISION; +#endif } player->drop_delay = GET_NEW_DROP_DELAY(drop_element); @@ -12313,7 +12532,7 @@ void RaiseScore(int value) void RaiseScoreElement(int element) { - switch(element) + switch (element) { case EL_EMERALD: case EL_BD_DIAMOND: @@ -12390,13 +12609,9 @@ void RaiseScoreElement(int element) } } -void RequestQuitGame(boolean ask_if_really_quit) +void RequestQuitGameExt(boolean skip_request, boolean quick_quit, char *message) { - if (AllPlayersGone || - !ask_if_really_quit || - level_editor_test_game || - Request("Do you really want to quit the game ?", - REQ_ASK | REQ_STAY_CLOSED)) + if (skip_request || Request(message, REQ_ASK | REQ_STAY_CLOSED)) { #if defined(NETWORK_AVALIABLE) if (options.network) @@ -12404,7 +12619,7 @@ void RequestQuitGame(boolean ask_if_really_quit) else #endif { - if (!ask_if_really_quit || level_editor_test_game) + if (quick_quit) { game_status = GAME_MODE_MAIN; @@ -12420,7 +12635,7 @@ void RequestQuitGame(boolean ask_if_really_quit) } } } - else + else /* continue playing the game */ { if (tape.playing && tape.deactivate_display) TapeDeactivateDisplayOff(TRUE); @@ -12432,6 +12647,15 @@ void RequestQuitGame(boolean ask_if_really_quit) } } +void RequestQuitGame(boolean ask_if_really_quit) +{ + boolean quick_quit = (!ask_if_really_quit || level_editor_test_game); + boolean skip_request = AllPlayersGone || quick_quit; + + RequestQuitGameExt(skip_request, quick_quit, + "Do you really want to quit the game ?"); +} + /* ------------------------------------------------------------------------- */ /* random generator functions */ @@ -12612,6 +12836,9 @@ void SaveEngineSnapshot() { FreeEngineSnapshot(); /* free previous snapshot, if needed */ + if (level_editor_test_game) /* do not save snapshots from editor */ + return; + /* copy some special values to a structure better suited for the snapshot */ SaveEngineSnapshotValues_RND(); @@ -12665,6 +12892,7 @@ void SaveEngineSnapshot() SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(WasJustMoving)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(WasJustFalling)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(CheckCollision)); + SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(CheckImpact)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Stop)); SaveEngineSnapshotBuffer(ARGS_ADDRESS_AND_SIZEOF(Pushed)); diff --git a/src/game.h b/src/game.h index 45323679..cf5d2c28 100644 --- a/src/game.h +++ b/src/game.h @@ -96,6 +96,7 @@ struct PlayerInfo boolean present; /* player present in level playfield */ boolean connected; /* player connected (locally or via network) */ boolean active; /* player present and connected */ + boolean killed; /* player maybe present/active, but killed */ int index_nr; /* player number (0 to 3) */ int index_bit; /* player number bit (1 << 0 to 1 << 3) */ @@ -240,6 +241,8 @@ void PlayLevelSound_EM(int, int, int, int); void RaiseScore(int); void RaiseScoreElement(int); + +void RequestQuitGameExt(boolean, boolean, char *); void RequestQuitGame(boolean); unsigned int InitEngineRandom_RND(long); diff --git a/src/init.c b/src/init.c index eb6b0374..ba94035e 100644 --- a/src/init.c +++ b/src/init.c @@ -104,6 +104,8 @@ void InitGadgets() CreateToolButtons(); CreateScreenGadgets(); + InitGadgetsSoundCallback(PlaySoundActivating, PlaySoundSelecting); + gadgets_initialized = TRUE; } @@ -165,7 +167,7 @@ static int getFontBitmapID(int font_nr) { int special = -1; - if (game_status >= GAME_MODE_MAIN && game_status <= GAME_MODE_PSEUDO_PREVIEW) + if (game_status >= GAME_MODE_TITLE && game_status <= GAME_MODE_PSEUDO_PREVIEW) special = game_status; else if (game_status == GAME_MODE_PSEUDO_TYPENAME) special = GFX_SPECIAL_ARG_MAIN; @@ -250,7 +252,7 @@ void InitFontGraphicInfo() } } - /* initialize special element/graphic mapping from dynamic configuration */ + /* initialize special font/graphic mapping from dynamic configuration */ for (i = 0; i < num_property_mappings; i++) { int font_nr = property_mapping[i].base_index - MAX_NUM_ELEMENTS; @@ -268,6 +270,54 @@ void InitFontGraphicInfo() } } + /* reset non-redefined ".active" font graphics if normal font is redefined */ + /* (this different treatment is needed because normal and active fonts are + independently defined ("active" is not a property of font definitions!) */ + for (i = 0; i < NUM_FONTS; i++) + { + int font_nr_base = i; + int font_nr_active = FONT_ACTIVE(font_nr_base); + + /* check only those fonts with exist as normal and ".active" variant */ + if (font_nr_base != font_nr_active) + { + int base_graphic = font_info[font_nr_base].graphic; + int active_graphic = font_info[font_nr_active].graphic; + boolean base_redefined = + getImageListEntryFromImageID(base_graphic)->redefined; + boolean active_redefined = + getImageListEntryFromImageID(active_graphic)->redefined; + + /* if the base font ("font.menu_1", for example) has been redefined, + but not the active font ("font.menu_1.active", for example), do not + use an existing (in this case considered obsolete) active font + anymore, but use the automatically determined default font */ + if (base_redefined && !active_redefined) + font_info[font_nr_active].graphic = base_graphic; + + /* now also check each "special" font (which may be the same as above) */ + for (j = 0; j < NUM_SPECIAL_GFX_ARGS; j++) + { + int base_graphic = font_info[font_nr_base].special_graphic[j]; + int active_graphic = font_info[font_nr_active].special_graphic[j]; + boolean base_redefined = + getImageListEntryFromImageID(base_graphic)->redefined; + boolean active_redefined = + getImageListEntryFromImageID(active_graphic)->redefined; + + /* same as above, but check special graphic definitions, for example: + redefined "font.menu_1.MAIN" invalidates "font.menu_1.active.MAIN" */ + if (base_redefined && !active_redefined) + { + font_info[font_nr_active].special_graphic[j] = + font_info[font_nr_base].special_graphic[j]; + font_info[font_nr_active].special_bitmap_id[j] = + font_info[font_nr_base].special_bitmap_id[j]; + } + } + } + } + /* ---------- initialize font bitmap array ---------- */ if (font_bitmap_info != NULL) @@ -901,13 +951,13 @@ static void set_graphic_parameters(int graphic) graphic_info[graphic].bitmap = src_bitmap; - /* start with reliable default values */ + /* always start with reliable default values */ graphic_info[graphic].src_image_width = 0; graphic_info[graphic].src_image_height = 0; graphic_info[graphic].src_x = 0; graphic_info[graphic].src_y = 0; - graphic_info[graphic].width = TILEX; - graphic_info[graphic].height = TILEY; + graphic_info[graphic].width = TILEX; /* default for element graphics */ + graphic_info[graphic].height = TILEY; /* default for element graphics */ graphic_info[graphic].offset_x = 0; /* one or both of these values ... */ graphic_info[graphic].offset_y = 0; /* ... will be corrected later */ graphic_info[graphic].offset2_x = 0; /* one or both of these values ... */ @@ -922,6 +972,26 @@ static void set_graphic_parameters(int graphic) graphic_info[graphic].anim_delay_random = 0; graphic_info[graphic].post_delay_fixed = 0; graphic_info[graphic].post_delay_random = 0; + graphic_info[graphic].fade_delay = -1; + graphic_info[graphic].post_delay = -1; + graphic_info[graphic].auto_delay = -1; + +#if 1 + /* optional zoom factor for scaling up the image to a larger size */ + if (parameter[GFX_ARG_SCALE_UP_FACTOR] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].scale_up_factor = parameter[GFX_ARG_SCALE_UP_FACTOR]; + if (graphic_info[graphic].scale_up_factor < 1) + graphic_info[graphic].scale_up_factor = 1; /* no scaling */ +#endif + +#if 1 + if (graphic_info[graphic].use_image_size) + { + /* set new default bitmap size (with scaling, but without small images) */ + graphic_info[graphic].width = get_scaled_graphic_width(graphic); + graphic_info[graphic].height = get_scaled_graphic_height(graphic); + } +#endif /* optional x and y tile position of animation frame sequence */ if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE) @@ -941,11 +1011,13 @@ static void set_graphic_parameters(int graphic) if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE) graphic_info[graphic].height = parameter[GFX_ARG_HEIGHT]; +#if 0 /* optional zoom factor for scaling up the image to a larger size */ if (parameter[GFX_ARG_SCALE_UP_FACTOR] != ARG_UNDEFINED_VALUE) graphic_info[graphic].scale_up_factor = parameter[GFX_ARG_SCALE_UP_FACTOR]; if (graphic_info[graphic].scale_up_factor < 1) graphic_info[graphic].scale_up_factor = 1; /* no scaling */ +#endif if (src_bitmap) { @@ -1087,6 +1159,14 @@ static void set_graphic_parameters(int graphic) /* optional graphic for cloning all graphics settings */ if (parameter[GFX_ARG_CLONE_FROM] != ARG_UNDEFINED_VALUE) graphic_info[graphic].clone_from = parameter[GFX_ARG_CLONE_FROM]; + + /* optional settings for drawing title screens */ + if (parameter[GFX_ARG_FADE_DELAY] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].fade_delay = parameter[GFX_ARG_FADE_DELAY]; + if (parameter[GFX_ARG_POST_DELAY] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].post_delay = parameter[GFX_ARG_POST_DELAY]; + if (parameter[GFX_ARG_AUTO_DELAY] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].auto_delay = parameter[GFX_ARG_AUTO_DELAY]; } static void set_cloned_graphic_parameters(int graphic) @@ -1142,10 +1222,61 @@ static void InitGraphicInfo() GC copy_clipmask_gc = None; #endif + /* use image size as default values for width and height for these images */ + static int full_size_graphics[] = + { + IMG_GLOBAL_BORDER, + IMG_GLOBAL_DOOR, + + IMG_BACKGROUND_ENVELOPE_1, + IMG_BACKGROUND_ENVELOPE_2, + IMG_BACKGROUND_ENVELOPE_3, + IMG_BACKGROUND_ENVELOPE_4, + + IMG_BACKGROUND, + IMG_BACKGROUND_TITLE, + IMG_BACKGROUND_MESSAGE, + IMG_BACKGROUND_MAIN, + IMG_BACKGROUND_LEVELS, + IMG_BACKGROUND_SCORES, + IMG_BACKGROUND_EDITOR, + IMG_BACKGROUND_INFO, + IMG_BACKGROUND_INFO_ELEMENTS, + IMG_BACKGROUND_INFO_MUSIC, + IMG_BACKGROUND_INFO_CREDITS, + IMG_BACKGROUND_INFO_PROGRAM, + IMG_BACKGROUND_INFO_LEVELSET, + IMG_BACKGROUND_SETUP, + IMG_BACKGROUND_DOOR, + + IMG_TITLESCREEN_INITIAL_1, + IMG_TITLESCREEN_INITIAL_2, + IMG_TITLESCREEN_INITIAL_3, + IMG_TITLESCREEN_INITIAL_4, + IMG_TITLESCREEN_INITIAL_5, + IMG_TITLESCREEN_1, + IMG_TITLESCREEN_2, + IMG_TITLESCREEN_3, + IMG_TITLESCREEN_4, + IMG_TITLESCREEN_5, + + -1 + }; + checked_free(graphic_info); graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); +#if 1 + /* initialize "use_image_size" flag with default value */ + for (i = 0; i < num_images; i++) + graphic_info[i].use_image_size = FALSE; + + /* initialize "use_image_size" flag from static configuration above */ + for (i = 0; full_size_graphics[i] != -1; i++) + graphic_info[full_size_graphics[i]].use_image_size = TRUE; +#endif + #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) if (clipmasks_initialized) { @@ -1175,6 +1306,7 @@ static void InitGraphicInfo() { Bitmap *src_bitmap; int src_x, src_y; + int width, height; int first_frame, last_frame; int src_bitmap_width, src_bitmap_height; @@ -1183,6 +1315,10 @@ static void InitGraphicInfo() if (graphic_info[i].bitmap == NULL) continue; /* skip check for optional images that are undefined */ + /* get image size (this can differ from the standard element tile size!) */ + width = graphic_info[i].width; + height = graphic_info[i].height; + /* get final bitmap size (with scaling, but without small images) */ src_bitmap_width = graphic_info[i].src_image_width; src_bitmap_height = graphic_info[i].src_image_height; @@ -1192,9 +1328,15 @@ static void InitGraphicInfo() first_frame = 0; getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y); +#if 1 + /* this avoids calculating wrong start position for out-of-bounds frame */ + src_x = graphic_info[i].src_x; + src_y = graphic_info[i].src_y; +#endif + if (src_x < 0 || src_y < 0 || - src_x + TILEX > src_bitmap_width || - src_y + TILEY > src_bitmap_height) + src_x + width > src_bitmap_width || + src_y + height > src_bitmap_height) { Error(ERR_RETURN_LINE, "-"); Error(ERR_RETURN, "warning: error found in config file:"); @@ -1221,8 +1363,8 @@ static void InitGraphicInfo() getGraphicSource(i, last_frame, &src_bitmap, &src_x, &src_y); if (src_x < 0 || src_y < 0 || - src_x + TILEX > src_bitmap_width || - src_y + TILEY > src_bitmap_height) + src_x + width > src_bitmap_width || + src_y + height > src_bitmap_height) { Error(ERR_RETURN_LINE, "-"); Error(ERR_RETURN, "warning: error found in config file:"); @@ -4433,11 +4575,15 @@ void InitGfx() font_height = getFontHeight(FC_RED); +#if 1 + DrawInitText(getWindowTitleString(), 20, FC_YELLOW); +#else DrawInitText(getProgramInitString(), 20, FC_YELLOW); +#endif DrawInitText(PROGRAM_COPYRIGHT_STRING, 50, FC_RED); DrawInitText(PROGRAM_WEBSITE_STRING, WIN_YSIZE - 20 - font_height, FC_RED); - DrawInitText("Loading graphics:", 120, FC_GREEN); + DrawInitText("Loading graphics", 120, FC_GREEN); } void RedrawBackground() @@ -4452,7 +4598,6 @@ void InitGfxBackground() { int x, y; - drawto = backbuffer; fieldbuffer = bitmap_db_field; SetDrawtoField(DRAW_BACKBUFFER); @@ -4767,8 +4912,7 @@ void OpenAll() InitJoysticks(); InitVideoDisplay(); - InitVideoBuffer(&backbuffer, &window, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, - setup.fullscreen); + InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); InitEventFilter(FilterMouseMotionEvents); @@ -4777,8 +4921,11 @@ void OpenAll() InitGfx(); + // debug_print_timestamp(0, "INIT"); InitLevelInfo(); + // debug_print_timestamp(0, "TIME InitLevelInfo: "); InitLevelArtworkInfo(); + // debug_print_timestamp(0, "TIME InitLevelArtworkInfo: "); InitImages(); /* needs to know current level directory */ InitSound(NULL); /* needs to know current level directory */ diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index 7c140cbe..23c51d36 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -32,6 +32,17 @@ static struct GadgetInfo *last_info_gi = NULL; static int next_free_gadget_id = 1; static boolean gadget_id_wrapped = FALSE; +static void (*PlayGadgetSoundActivating)(void) = NULL; +static void (*PlayGadgetSoundSelecting)(void) = NULL; + + +void InitGadgetsSoundCallback(void (*activating_function)(void), + void (*selecting_function)(void)) +{ + PlayGadgetSoundActivating = activating_function; + PlayGadgetSoundSelecting = selecting_function; +} + static struct GadgetInfo *getGadgetInfoFromGadgetID(int id) { struct GadgetInfo *gi = gadget_list_first_entry; @@ -731,7 +742,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) case GDI_INFO_TEXT: { - int max_textsize = MAX_INFO_TEXTSIZE - 1; + int max_textsize = MAX_INFO_TEXTSIZE; char *text = va_arg(ap, char *); if (text != NULL) @@ -815,7 +826,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) int max_textsize = MAX_GADGET_TEXTSIZE; if (gi->textinput.size) - max_textsize = MIN(gi->textinput.size, MAX_GADGET_TEXTSIZE - 1); + max_textsize = MIN(gi->textinput.size, MAX_GADGET_TEXTSIZE); strncpy(gi->textinput.value, va_arg(ap, char *), max_textsize); strcpy(gi->textinput.last_value, gi->textinput.value); @@ -833,7 +844,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) case GDI_TEXT_SIZE: { int tag_value = va_arg(ap, int); - int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1); + int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE); gi->textinput.size = max_textsize; gi->textinput.value[max_textsize] = '\0'; @@ -1783,6 +1794,8 @@ boolean HandleGadgets(int mx, int my, int button) if (gadget_pressed) { + PlayGadgetSoundActivating(); + if (gi->type == GD_TYPE_CHECK_BUTTON) { gi->checked = !gi->checked; @@ -1979,10 +1992,10 @@ boolean HandleGadgets(int mx, int my, int button) static void insertCharIntoTextArea(struct GadgetInfo *gi, char c) { - char text[MAX_GADGET_TEXTSIZE]; + char text[MAX_GADGET_TEXTSIZE + 1]; int cursor_position = gi->textarea.cursor_position; - if (strlen(gi->textarea.value) == MAX_GADGET_TEXTSIZE) /* no space left */ + if (strlen(gi->textarea.value) >= MAX_GADGET_TEXTSIZE) /* no space left */ return; strcpy(text, gi->textarea.value); @@ -2043,7 +2056,7 @@ boolean HandleGadgetsKeyInput(Key key) } else if (gi->type & GD_TYPE_TEXT_INPUT) /* only valid for text input */ { - char text[MAX_GADGET_TEXTSIZE]; + char text[MAX_GADGET_TEXTSIZE + 1]; int text_length = strlen(gi->textinput.value); int cursor_pos = gi->textinput.cursor_position; char letter = getCharFromKey(key); @@ -2090,7 +2103,7 @@ boolean HandleGadgetsKeyInput(Key key) } else if (gi->type & GD_TYPE_TEXT_AREA) /* only valid for text area */ { - char text[MAX_GADGET_TEXTSIZE]; + char text[MAX_GADGET_TEXTSIZE + 1]; int text_length = strlen(gi->textarea.value); int area_ysize = gi->textarea.ysize; int cursor_x_pref = gi->textarea.cursor_x_preferred; diff --git a/src/libgame/gadgets.h b/src/libgame/gadgets.h index 7f352a87..43125d66 100644 --- a/src/libgame/gadgets.h +++ b/src/libgame/gadgets.h @@ -150,14 +150,14 @@ struct GadgetDrawingArea struct GadgetTextButton { - char value[MAX_GADGET_TEXTSIZE]; /* text written on the button */ + char value[MAX_GADGET_TEXTSIZE + 1]; /* text written on the button */ int size; /* maximal size of button text */ }; struct GadgetTextInput { - char value[MAX_GADGET_TEXTSIZE]; /* text string in input field */ - char last_value[MAX_GADGET_TEXTSIZE]; /* last text string in input field */ + char value[MAX_GADGET_TEXTSIZE + 1]; /* text string in input field */ + char last_value[MAX_GADGET_TEXTSIZE + 1];/* last text string in input field */ int cursor_position; /* actual text cursor position */ int number_value; /* integer value, if numeric */ int number_min; /* minimal allowed numeric value */ @@ -167,8 +167,8 @@ struct GadgetTextInput struct GadgetTextArea { - char value[MAX_GADGET_TEXTSIZE]; /* text string in input field */ - char last_value[MAX_GADGET_TEXTSIZE]; /* last text string in input field */ + char value[MAX_GADGET_TEXTSIZE + 1]; /* text string in input field */ + char last_value[MAX_GADGET_TEXTSIZE + 1];/* last text string in input field */ int cursor_position; /* actual text cursor position */ int cursor_x; /* actual x cursor position */ int cursor_y; /* actual y cursor position */ @@ -221,7 +221,7 @@ struct GadgetInfo int id; /* internal gadget identifier */ int custom_id; /* custom gadget identifier */ int custom_type_id; /* custom gadget type identifier */ - char info_text[MAX_INFO_TEXTSIZE]; /* short popup info text */ + char info_text[MAX_INFO_TEXTSIZE + 1];/* short popup info text */ int x, y; /* gadget position */ int width, height; /* gadget size */ unsigned int type; /* type (button, text input, ...) */ @@ -251,6 +251,10 @@ struct GadgetInfo struct GadgetInfo *next; /* next list entry */ }; + +void InitGadgetsSoundCallback(void (*activating_function)(void), + void (*selecting_function)(void)); + struct GadgetInfo *CreateGadget(int, ...); void FreeGadget(struct GadgetInfo *); diff --git a/src/libgame/misc.c b/src/libgame/misc.c index ae54541f..f9b8b257 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -498,36 +498,45 @@ char *getBasePath(char *filename) /* various string functions */ /* ------------------------------------------------------------------------- */ -char *getPath2(char *path1, char *path2) +char *getStringCat2WithSeparator(char *s1, char *s2, char *sep) { - char *sep = STRING_PATH_SEPARATOR; - char *complete_path = checked_malloc(strlen(path1) + 1 + - strlen(path2) + 1); + char *complete_string = checked_malloc(strlen(s1) + strlen(sep) + + strlen(s2) + 1); - sprintf(complete_path, "%s%s%s", path1, sep, path2); + sprintf(complete_string, "%s%s%s", s1, sep, s2); - return complete_path; + return complete_string; } -char *getPath3(char *path1, char *path2, char *path3) +char *getStringCat3WithSeparator(char *s1, char *s2, char *s3, char *sep) { - char *sep = STRING_PATH_SEPARATOR; - char *complete_path = checked_malloc(strlen(path1) + 1 + - strlen(path2) + 1 + - strlen(path3) + 1); + char *complete_string = checked_malloc(strlen(s1) + strlen(sep) + + strlen(s2) + strlen(sep) + + strlen(s3) + 1); - sprintf(complete_path, "%s%s%s%s%s", path1, sep, path2, sep, path3); + sprintf(complete_string, "%s%s%s%s%s", s1, sep, s2, sep, s3); - return complete_path; + return complete_string; } char *getStringCat2(char *s1, char *s2) { - char *complete_string = checked_malloc(strlen(s1) + strlen(s2) + 1); + return getStringCat2WithSeparator(s1, s2, ""); +} - sprintf(complete_string, "%s%s", s1, s2); +char *getStringCat3(char *s1, char *s2, char *s3) +{ + return getStringCat3WithSeparator(s1, s2, s3, ""); +} - return complete_string; +char *getPath2(char *path1, char *path2) +{ + return getStringCat2WithSeparator(path1, path2, STRING_PATH_SEPARATOR); +} + +char *getPath3(char *path1, char *path2, char *path3) +{ + return getStringCat3WithSeparator(path1, path2, path3, STRING_PATH_SEPARATOR); } char *getStringCopy(char *s) @@ -1761,6 +1770,12 @@ int get_parameter_value(char *value_raw, char *suffix, int type) strEqual(value, "up") ? MV_UP : strEqual(value, "down") ? MV_DOWN : MV_NONE); } + else if (strEqual(suffix, ".align")) + { + result = (strEqual(value, "left") ? ALIGN_LEFT : + strEqual(value, "right") ? ALIGN_RIGHT : + strEqual(value, "center") ? ALIGN_CENTER : ALIGN_DEFAULT); + } else if (strEqual(suffix, ".anim_mode")) { result = (string_has_parameter(value, "none") ? ANIM_NONE : @@ -1774,6 +1789,9 @@ int get_parameter_value(char *value_raw, char *suffix, int type) string_has_parameter(value, "ce_delay") ? ANIM_CE_DELAY : string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL : string_has_parameter(value, "vertical") ? ANIM_VERTICAL : + string_has_parameter(value, "centered") ? ANIM_CENTERED : + string_has_parameter(value, "fade") ? ANIM_FADE : + string_has_parameter(value, "crossfade") ? ANIM_CROSSFADE : ANIM_DEFAULT); if (string_has_parameter(value, "reverse")) @@ -2472,7 +2490,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info) char *filename_base = UNDEFINED_FILENAME, *filename_local; int i, j; - DrawInitText("Loading artwork config:", 120, FC_GREEN); + DrawInitText("Loading artwork config", 120, FC_GREEN); DrawInitText(ARTWORKINFO_FILENAME(artwork_info->type), 150, FC_YELLOW); /* always start with reliable default values */ @@ -2549,9 +2567,9 @@ static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info, { char *init_text[] = { - "Loading graphics:", - "Loading sounds:", - "Loading music:" + "Loading graphics", + "Loading sounds", + "Loading music" }; ListNode *node; @@ -2769,6 +2787,8 @@ void NotifyUserAboutErrorFile() /* the following is only for debugging purpose and normally not used */ /* ------------------------------------------------------------------------- */ +#if DEBUG + #define DEBUG_NUM_TIMESTAMPS 3 void debug_print_timestamp(int counter_nr, char *message) @@ -2781,10 +2801,10 @@ void debug_print_timestamp(int counter_nr, char *message) counter[counter_nr][0] = Counter(); if (message) - printf("%s %.2f seconds\n", message, + printf("%s %.3f seconds\n", message, (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000); - counter[counter_nr][1] = Counter(); + counter[counter_nr][1] = counter[counter_nr][0]; } void debug_print_parent_only(char *format, ...) @@ -2803,3 +2823,4 @@ void debug_print_parent_only(char *format, ...) printf("\n"); } } +#endif diff --git a/src/libgame/misc.h b/src/libgame/misc.h index 009350c0..a42a7584 100644 --- a/src/libgame/misc.h +++ b/src/libgame/misc.h @@ -94,9 +94,12 @@ char *getBasePath(char *); char *getBaseName(char *); char *getBaseNamePtr(char *); +char *getStringCat2WithSeparator(char *, char *, char *); +char *getStringCat3WithSeparator(char *, char *, char *, char *); +char *getStringCat2(char *, char *); +char *getStringCat3(char *, char *, char *); char *getPath2(char *, char *); char *getPath3(char *, char *, char*); -char *getStringCat2(char *, char *); char *getStringCopy(char *); char *getStringToLower(char *); void setString(char **, char *); diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index d06cca94..6ac1229f 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -35,12 +35,12 @@ static int fullscreen_yoffset; static int video_xoffset; static int video_yoffset; -static void setFullscreenParameters() +static void setFullscreenParameters(char *fullscreen_mode_string) { struct ScreenModeInfo *fullscreen_mode; int i; - fullscreen_mode = get_screen_mode_from_string(setup.fullscreen_mode); + fullscreen_mode = get_screen_mode_from_string(fullscreen_mode_string); if (fullscreen_mode == NULL) return; @@ -240,7 +240,7 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) if (fullscreen && !video.fullscreen_enabled && video.fullscreen_available) { - setFullscreenParameters(); + setFullscreenParameters(setup.fullscreen_mode); video_xoffset = fullscreen_xoffset; video_yoffset = fullscreen_yoffset; @@ -255,6 +255,7 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) /* do not try it again */ video.fullscreen_available = FALSE; + success = FALSE; } else @@ -262,6 +263,8 @@ boolean SDLSetVideoMode(DrawBuffer **backbuffer, boolean fullscreen) (*backbuffer)->surface = new_surface; video.fullscreen_enabled = TRUE; + video.fullscreen_mode_current = setup.fullscreen_mode; + success = TRUE; } } @@ -383,7 +386,8 @@ void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y, int width, int height, } void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, - int fade_mode, int fade_delay, int post_delay) + int fade_mode, int fade_delay, int post_delay, + void (*draw_border_function)(void)) { static boolean initialization_needed = TRUE; static SDL_Surface *surface_source = NULL; @@ -497,6 +501,9 @@ void SDLFadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, SDL_SetAlpha(surface_target, SDL_SRCALPHA, alpha_final); SDL_BlitSurface(surface_target, &src_rect, surface_screen, &dst_rect); + if (draw_border_function != NULL) + draw_border_function(); + #if 1 /* only update the region of the screen that is affected from fading */ SDL_UpdateRect(surface_screen, dst_x, dst_y, width, height); diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index 625b89e6..5ab0461d 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -354,7 +354,8 @@ void SDLCreateBitmapContent(Bitmap *, int, int, int); void SDLFreeBitmapPointers(Bitmap *); void SDLCopyArea(Bitmap *, Bitmap *, int, int, int, int, int, int, int); void SDLFillRectangle(Bitmap *, int, int, int, int, Uint32); -void SDLFadeRectangle(Bitmap *, int, int, int, int, int, int, int); +void SDLFadeRectangle(Bitmap *, int, int, int, int, int, int, int, + void (*draw_border_function)(void)); void SDLDrawSimpleLine(Bitmap *, int, int, int, int, Uint32); void SDLDrawLine(Bitmap *, int, int, int, int, Uint32); Pixel SDLGetPixel(Bitmap *, int, int); diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 4f004494..3cd7bf0f 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -86,12 +86,18 @@ static char *levelclass_desc[NUM_LEVELCLASS_DESC] = #define MAX_COOKIE_LEN 256 + static void setTreeInfoToDefaults(TreeInfo *, int); +static TreeInfo *getTreeInfoCopy(TreeInfo *ti); static int compareTreeInfoEntries(const void *, const void *); static int token_value_position = TOKEN_VALUE_POSITION_DEFAULT; static int token_comment_position = TOKEN_COMMENT_POSITION_DEFAULT; +static SetupFileHash *artworkinfo_cache_old = NULL; +static SetupFileHash *artworkinfo_cache_new = NULL; +static boolean use_artworkinfo_cache = TRUE; + /* ------------------------------------------------------------------------- */ /* file functions */ @@ -155,6 +161,16 @@ static char *getLevelSetupDir(char *level_subdir) return levelsetup_dir; } +static char *getCacheDir() +{ + static char *cache_dir = NULL; + + if (cache_dir == NULL) + cache_dir = getPath2(getUserGameDataDir(), CACHE_DIRECTORY); + + return cache_dir; +} + static char *getLevelDirFromTreeInfo(TreeInfo *node) { static char *level_dir = NULL; @@ -482,6 +498,35 @@ char *getLevelSetInfoFilename() return NULL; } +char *getLevelSetMessageFilename() +{ + static char *filename = NULL; + char *basenames[] = + { + "MESSAGE", + "MESSAGE.TXT", + "MESSAGE.txt", + "Message", + "Message.txt", + "message", + "message.txt", + + NULL + }; + int i; + + for (i = 0; basenames[i] != NULL; i++) + { + checked_free(filename); + filename = getPath2(getCurrentLevelDir(), basenames[i]); + + if (fileExists(filename)) + return filename; + } + + return NULL; +} + static char *getCorrectedArtworkBasename(char *basename) { char *basename_corrected = basename; @@ -794,7 +839,7 @@ void InitUserLevelDirectory(char *level_subdir) { createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE); - createDirectory(getUserLevelDir(level_subdir), "user level",PERMS_PRIVATE); + createDirectory(getUserLevelDir(level_subdir), "user level", PERMS_PRIVATE); SaveUserLevelInfo(); } @@ -804,7 +849,13 @@ void InitLevelSetupDirectory(char *level_subdir) { createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); createDirectory(getLevelSetupDir(NULL), "main level setup", PERMS_PRIVATE); - createDirectory(getLevelSetupDir(level_subdir), "level setup",PERMS_PRIVATE); + createDirectory(getLevelSetupDir(level_subdir), "level setup", PERMS_PRIVATE); +} + +void InitCacheDirectory() +{ + createDirectory(getUserGameDataDir(), "user data", PERMS_PRIVATE); + createDirectory(getCacheDir(), "cache data", PERMS_PRIVATE); } @@ -959,9 +1010,13 @@ TreeInfo *cloneTreeNode(TreeInfo **node_top, TreeInfo *node_parent, return cloneTreeNode(node_top, node_parent, node->next, skip_sets_without_levels); +#if 1 + node_new = getTreeInfoCopy(node); /* copy complete node */ +#else node_new = newTreeInfo(); *node_new = *node; /* copy complete node */ +#endif node_new->node_top = node_top; /* correct top node link */ node_new->node_parent = node_parent; /* correct parent node link */ @@ -1652,7 +1707,11 @@ static void *loadSetupFileData(char *filename, boolean use_hash) /* find end of token to determine start of value */ for (line_ptr = token; *line_ptr; line_ptr++) { +#if 1 + if (*line_ptr == ':' || *line_ptr == '=') +#else if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':') +#endif { *line_ptr = '\0'; /* terminate token string */ value = line_ptr + 1; /* set beginning of value */ @@ -1661,6 +1720,11 @@ static void *loadSetupFileData(char *filename, boolean use_hash) } } + /* cut trailing whitespaces from token */ + for (line_ptr = &token[strlen(token)]; line_ptr >= token; line_ptr--) + if ((*line_ptr == ' ' || *line_ptr == '\t') && *(line_ptr + 1) == '\0') + *line_ptr = '\0'; + /* cut leading whitespaces from value */ for (; *value; value++) if (*value != ' ' && *value != '\t') @@ -1704,6 +1768,27 @@ static void *loadSetupFileData(char *filename, boolean use_hash) return setup_file_data; } +void saveSetupFileHash(SetupFileHash *hash, char *filename) +{ + FILE *file; + + if (!(file = fopen(filename, MODE_WRITE))) + { + Error(ERR_WARN, "cannot write configuration file '%s'", filename); + + return; + } + + BEGIN_HASH_ITERATION(hash, itr) + { + fprintf(file, "%s\n", getFormattedSetupEntry(HASH_ITERATION_TOKEN(itr), + HASH_ITERATION_VALUE(itr))); + } + END_HASH_ITERATION(hash, itr) + + fclose(file); +} + SetupFileList *loadSetupFileList(char *filename) { return (SetupFileList *)loadSetupFileData(filename, FALSE); @@ -1787,6 +1872,24 @@ static struct TokenInfo levelinfo_tokens[] = { TYPE_BOOLEAN, &ldi.skip_levels, "skip_levels" } }; +static struct TokenInfo artworkinfo_tokens[] = +{ + /* artwork directory info */ + { TYPE_STRING, &ldi.identifier, "identifier" }, + { TYPE_STRING, &ldi.subdir, "subdir" }, + { TYPE_STRING, &ldi.name, "name" }, + { TYPE_STRING, &ldi.name_sorting, "name_sorting" }, + { TYPE_STRING, &ldi.author, "author" }, + { TYPE_INTEGER, &ldi.sort_priority, "sort_priority" }, + { TYPE_STRING, &ldi.basepath, "basepath" }, + { TYPE_STRING, &ldi.fullpath, "fullpath" }, + { TYPE_BOOLEAN, &ldi.in_user_dir, "in_user_dir" }, + { TYPE_INTEGER, &ldi.color, "color" }, + { TYPE_STRING, &ldi.class_desc, "class_desc" }, + + { -1, NULL, NULL }, +}; + static void setTreeInfoToDefaults(TreeInfo *ti, int type) { ti->type = type; @@ -1919,8 +2022,73 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ti, TreeInfo *parent) } } +static TreeInfo *getTreeInfoCopy(TreeInfo *ti) +{ + TreeInfo *ti_copy = newTreeInfo(); + + /* copy all values from the original structure */ + + ti_copy->type = ti->type; + + ti_copy->node_top = ti->node_top; + ti_copy->node_parent = ti->node_parent; + ti_copy->node_group = ti->node_group; + ti_copy->next = ti->next; + + ti_copy->cl_first = ti->cl_first; + ti_copy->cl_cursor = ti->cl_cursor; + + ti_copy->subdir = getStringCopy(ti->subdir); + ti_copy->fullpath = getStringCopy(ti->fullpath); + ti_copy->basepath = getStringCopy(ti->basepath); + ti_copy->identifier = getStringCopy(ti->identifier); + ti_copy->name = getStringCopy(ti->name); + ti_copy->name_sorting = getStringCopy(ti->name_sorting); + ti_copy->author = getStringCopy(ti->author); + ti_copy->imported_from = getStringCopy(ti->imported_from); + ti_copy->imported_by = getStringCopy(ti->imported_by); + + ti_copy->graphics_set_ecs = getStringCopy(ti->graphics_set_ecs); + ti_copy->graphics_set_aga = getStringCopy(ti->graphics_set_aga); + ti_copy->graphics_set = getStringCopy(ti->graphics_set); + ti_copy->sounds_set = getStringCopy(ti->sounds_set); + ti_copy->music_set = getStringCopy(ti->music_set); + ti_copy->graphics_path = getStringCopy(ti->graphics_path); + ti_copy->sounds_path = getStringCopy(ti->sounds_path); + ti_copy->music_path = getStringCopy(ti->music_path); + + ti_copy->level_filename = getStringCopy(ti->level_filename); + ti_copy->level_filetype = getStringCopy(ti->level_filetype); + + ti_copy->levels = ti->levels; + ti_copy->first_level = ti->first_level; + ti_copy->last_level = ti->last_level; + ti_copy->sort_priority = ti->sort_priority; + + ti_copy->latest_engine = ti->latest_engine; + + ti_copy->level_group = ti->level_group; + ti_copy->parent_link = ti->parent_link; + ti_copy->in_user_dir = ti->in_user_dir; + ti_copy->user_defined = ti->user_defined; + ti_copy->readonly = ti->readonly; + ti_copy->handicap = ti->handicap; + ti_copy->skip_levels = ti->skip_levels; + + ti_copy->color = ti->color; + ti_copy->class_desc = getStringCopy(ti->class_desc); + ti_copy->handicap_level = ti->handicap_level; + + ti_copy->infotext = getStringCopy(ti->infotext); + + return ti_copy; +} + static void freeTreeInfo(TreeInfo *ti) { + if (ti == NULL) + return; + checked_free(ti->subdir); checked_free(ti->fullpath); checked_free(ti->basepath); @@ -1952,6 +2120,8 @@ static void freeTreeInfo(TreeInfo *ti) checked_free(ti->level_filename); checked_free(ti->level_filetype); } + + checked_free(ti); } void setSetupInfo(struct TokenInfo *token_info, @@ -2059,6 +2229,221 @@ static void createParentTreeInfoNode(TreeInfo *node_parent) pushTreeInfo(&node_parent->node_group, ti_new); } + +/* -------------------------------------------------------------------------- */ +/* functions for handling level and custom artwork info cache */ +/* -------------------------------------------------------------------------- */ + +static void LoadArtworkInfoCache() +{ + InitCacheDirectory(); + + if (artworkinfo_cache_old == NULL) + { + char *filename = getPath2(getCacheDir(), ARTWORKINFO_CACHE_FILE); + + /* try to load artwork info hash from already existing cache file */ + artworkinfo_cache_old = loadSetupFileHash(filename); + + /* if no artwork info cache file was found, start with empty hash */ + if (artworkinfo_cache_old == NULL) + artworkinfo_cache_old = newSetupFileHash(); + + free(filename); + } + + if (artworkinfo_cache_new == NULL) + artworkinfo_cache_new = newSetupFileHash(); +} + +static void SaveArtworkInfoCache() +{ + char *filename = getPath2(getCacheDir(), ARTWORKINFO_CACHE_FILE); + + InitCacheDirectory(); + + saveSetupFileHash(artworkinfo_cache_new, filename); + + free(filename); +} + +static char *getCacheTokenPrefix(char *prefix1, char *prefix2) +{ + static char *prefix = NULL; + + checked_free(prefix); + + prefix = getStringCat2WithSeparator(prefix1, prefix2, "."); + + return prefix; +} + +/* (identical to above function, but separate string buffer needed -- nasty) */ +static char *getCacheToken(char *prefix, char *suffix) +{ + static char *token = NULL; + + checked_free(token); + + token = getStringCat2WithSeparator(prefix, suffix, "."); + + return token; +} + +static char *getFileTimestamp(char *filename) +{ + struct stat file_status; + + if (stat(filename, &file_status) != 0) /* cannot stat file */ + return getStringCopy(i_to_a(0)); + + return getStringCopy(i_to_a(file_status.st_mtime)); +} + +static boolean modifiedFileTimestamp(char *filename, char *timestamp_string) +{ + struct stat file_status; + + if (timestamp_string == NULL) + return TRUE; + + if (stat(filename, &file_status) != 0) /* cannot stat file */ + return TRUE; + + return (file_status.st_mtime != atoi(timestamp_string)); +} + +static TreeInfo *getArtworkInfoCacheEntry(LevelDirTree *level_node, int type) +{ + char *identifier = level_node->subdir; + char *type_string = ARTWORK_DIRECTORY(type); + char *token_prefix = getCacheTokenPrefix(type_string, identifier); + char *token_main = getCacheToken(token_prefix, "CACHED"); + char *cache_entry = getHashEntry(artworkinfo_cache_old, token_main); + boolean cached = (cache_entry != NULL && strEqual(cache_entry, "true")); + TreeInfo *artwork_info = NULL; + + if (!use_artworkinfo_cache) + return NULL; + + if (cached) + { + int i; + + artwork_info = newTreeInfo(); + setTreeInfoToDefaults(artwork_info, type); + + /* set all structure fields according to the token/value pairs */ + ldi = *artwork_info; + for (i = 0; artworkinfo_tokens[i].type != -1; i++) + { + char *token = getCacheToken(token_prefix, artworkinfo_tokens[i].text); + char *value = getHashEntry(artworkinfo_cache_old, token); + + setSetupInfo(artworkinfo_tokens, i, value); + + /* check if cache entry for this item is invalid or incomplete */ + if (value == NULL) + { +#if 1 + printf("::: - WARNING: cache entry '%s' invalid\n", token); +#endif + + cached = FALSE; + } + } + *artwork_info = ldi; + } + + if (cached) + { + char *filename_levelinfo = getPath2(getLevelDirFromTreeInfo(level_node), + LEVELINFO_FILENAME); + char *filename_artworkinfo = getPath2(getSetupArtworkDir(artwork_info), + ARTWORKINFO_FILENAME(type)); + + /* check if corresponding "levelinfo.conf" file has changed */ + token_main = getCacheToken(token_prefix, "TIMESTAMP_LEVELINFO"); + cache_entry = getHashEntry(artworkinfo_cache_old, token_main); + + if (modifiedFileTimestamp(filename_levelinfo, cache_entry)) + cached = FALSE; + + /* check if corresponding ".conf" file has changed */ + token_main = getCacheToken(token_prefix, "TIMESTAMP_ARTWORKINFO"); + cache_entry = getHashEntry(artworkinfo_cache_old, token_main); + + if (modifiedFileTimestamp(filename_artworkinfo, cache_entry)) + cached = FALSE; + +#if 0 + if (!cached) + printf("::: '%s': INVALIDATED FROM CACHE BY TIMESTAMP\n", identifier); +#endif + + checked_free(filename_levelinfo); + checked_free(filename_artworkinfo); + } + + if (!cached && artwork_info != NULL) + { + freeTreeInfo(artwork_info); + + return NULL; + } + + return artwork_info; +} + +static void setArtworkInfoCacheEntry(TreeInfo *artwork_info, + LevelDirTree *level_node, int type) +{ + char *identifier = level_node->subdir; + char *type_string = ARTWORK_DIRECTORY(type); + char *token_prefix = getCacheTokenPrefix(type_string, identifier); + char *token_main = getCacheToken(token_prefix, "CACHED"); + boolean set_cache_timestamps = TRUE; + int i; + + setHashEntry(artworkinfo_cache_new, token_main, "true"); + + if (set_cache_timestamps) + { + char *filename_levelinfo = getPath2(getLevelDirFromTreeInfo(level_node), + LEVELINFO_FILENAME); + char *filename_artworkinfo = getPath2(getSetupArtworkDir(artwork_info), + ARTWORKINFO_FILENAME(type)); + char *timestamp_levelinfo = getFileTimestamp(filename_levelinfo); + char *timestamp_artworkinfo = getFileTimestamp(filename_artworkinfo); + + token_main = getCacheToken(token_prefix, "TIMESTAMP_LEVELINFO"); + setHashEntry(artworkinfo_cache_new, token_main, timestamp_levelinfo); + + token_main = getCacheToken(token_prefix, "TIMESTAMP_ARTWORKINFO"); + setHashEntry(artworkinfo_cache_new, token_main, timestamp_artworkinfo); + + checked_free(filename_levelinfo); + checked_free(filename_artworkinfo); + checked_free(timestamp_levelinfo); + checked_free(timestamp_artworkinfo); + } + + ldi = *artwork_info; + for (i = 0; artworkinfo_tokens[i].type != -1; i++) + { + char *token = getCacheToken(token_prefix, artworkinfo_tokens[i].text); + char *value = getSetupValue(artworkinfo_tokens[i].type, + artworkinfo_tokens[i].value); + if (value != NULL) + setHashEntry(artworkinfo_cache_new, token, value); + } +} + + +/* -------------------------------------------------------------------------- */ +/* functions for loading level info and custom artwork info */ +/* -------------------------------------------------------------------------- */ + /* forward declaration for recursive call by "LoadLevelInfoFromLevelDir()" */ static void LoadLevelInfoFromLevelDir(TreeInfo **, TreeInfo *, char *); @@ -2116,8 +2501,6 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, if (strEqual(leveldir_new->name, ANONYMOUS_NAME)) setString(&leveldir_new->name, leveldir_new->subdir); - DrawInitText(leveldir_new->name, 150, FC_YELLOW); - if (leveldir_new->identifier == NULL) leveldir_new->identifier = getStringCopy(leveldir_new->subdir); @@ -2168,6 +2551,13 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, (leveldir_new->user_defined || !leveldir_new->handicap ? leveldir_new->last_level : leveldir_new->first_level); +#if 1 + if (leveldir_new->level_group) + DrawInitText(leveldir_new->name, 150, FC_YELLOW); +#else + DrawInitText(leveldir_new->name, 150, FC_YELLOW); +#endif + #if 0 /* !!! don't skip sets without levels (else artwork base sets are missing) */ #if 1 @@ -2193,7 +2583,7 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, /* create node to link back to current level directory */ createParentTreeInfoNode(leveldir_new); - /* step into sub-directory and look for more level series */ + /* recursively step into sub-directory and look for more level series */ LoadLevelInfoFromLevelDir(&leveldir_new->node_group, leveldir_new, directory_path); } @@ -2281,7 +2671,7 @@ void LoadLevelInfo() { InitUserLevelDirectory(getLoginName()); - DrawInitText("Loading level series:", 120, FC_GREEN); + DrawInitText("Loading level series", 120, FC_GREEN); LoadLevelInfoFromLevelDir(&leveldir_first, NULL, options.level_directory); LoadLevelInfoFromLevelDir(&leveldir_first, NULL, getUserLevelDir(NULL)); @@ -2381,10 +2771,6 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, if (strEqual(artwork_new->name, ANONYMOUS_NAME)) setString(&artwork_new->name, artwork_new->subdir); -#if 0 - DrawInitText(artwork_new->name, 150, FC_YELLOW); -#endif - if (artwork_new->identifier == NULL) artwork_new->identifier = getStringCopy(artwork_new->subdir); @@ -2441,7 +2827,9 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, setString(&artwork_new->name_sorting, artwork_new->name); } +#if 0 DrawInitText(artwork_new->name, 150, FC_YELLOW); +#endif pushTreeInfo(node_first, artwork_new); @@ -2531,7 +2919,9 @@ static TreeInfo *getDummyArtworkInfo(int type) void LoadArtworkInfo() { - DrawInitText("Looking for custom artwork:", 120, FC_GREEN); + LoadArtworkInfoCache(); + + DrawInitText("Looking for custom artwork", 120, FC_GREEN); LoadArtworkInfoFromArtworkDir(&artwork.gfx_first, NULL, options.graphics_directory, @@ -2610,6 +3000,8 @@ void LoadArtworkInfo() void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, LevelDirTree *level_node) { + int type = (*artwork_node)->type; + /* recursively check all level directories for artwork sub-directories */ while (level_node) @@ -2617,30 +3009,46 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, /* check all tree entries for artwork, but skip parent link entries */ if (!level_node->parent_link) { - TreeInfo *topnode_last = *artwork_node; - char *path = getPath2(getLevelDirFromTreeInfo(level_node), - ARTWORK_DIRECTORY((*artwork_node)->type)); - - LoadArtworkInfoFromArtworkDir(artwork_node, NULL, path, - (*artwork_node)->type); + TreeInfo *artwork_new = getArtworkInfoCacheEntry(level_node, type); + boolean cached = (artwork_new != NULL); - if (topnode_last != *artwork_node) + if (cached) { - free((*artwork_node)->identifier); - free((*artwork_node)->name); - free((*artwork_node)->name_sorting); + pushTreeInfo(artwork_node, artwork_new); + } + else + { + TreeInfo *topnode_last = *artwork_node; + char *path = getPath2(getLevelDirFromTreeInfo(level_node), + ARTWORK_DIRECTORY(type)); - (*artwork_node)->identifier = getStringCopy(level_node->subdir); - (*artwork_node)->name = getStringCopy(level_node->name); - (*artwork_node)->name_sorting = getStringCopy(level_node->name); + LoadArtworkInfoFromArtworkDir(artwork_node, NULL, path, type); - (*artwork_node)->sort_priority = level_node->sort_priority; - (*artwork_node)->color = LEVELCOLOR((*artwork_node)); + if (topnode_last != *artwork_node) /* check for newly added node */ + { + artwork_new = *artwork_node; + + setString(&artwork_new->identifier, level_node->subdir); + setString(&artwork_new->name, level_node->name); + setString(&artwork_new->name_sorting, level_node->name_sorting); + + artwork_new->sort_priority = level_node->sort_priority; + artwork_new->color = LEVELCOLOR(artwork_new); + } + + free(path); } - free(path); + /* insert artwork info (from old cache or filesystem) into new cache */ + if (artwork_new != NULL) + setArtworkInfoCacheEntry(artwork_new, level_node, type); } +#if 1 + if (level_node->level_group) + DrawInitText(level_node->name, 150, FC_YELLOW); +#endif + if (level_node->node_group != NULL) LoadArtworkInfoFromLevelInfo(artwork_node, level_node->node_group); @@ -2650,12 +3058,14 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, void LoadLevelArtworkInfo() { - DrawInitText("Looking for custom level artwork:", 120, FC_GREEN); + DrawInitText("Looking for custom level artwork", 120, FC_GREEN); LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first_all); LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first_all); LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first_all); + SaveArtworkInfoCache(); + /* needed for reloading level artwork not known at ealier stage */ if (!strEqual(artwork.gfx_current_identifier, setup.graphics_set)) @@ -2795,6 +3205,9 @@ char *getSetupValue(int type, void *value) break; case TYPE_STRING: + if (*(char **)value == NULL) + return NULL; + strcpy(value_string, *(char **)value); break; diff --git a/src/libgame/setup.h b/src/libgame/setup.h index 55440806..6dc15e9c 100644 --- a/src/libgame/setup.h +++ b/src/libgame/setup.h @@ -230,6 +230,7 @@ char *getEditorSetupFilename(void); char *getHelpAnimFilename(void); char *getHelpTextFilename(void); char *getLevelSetInfoFilename(void); +char *getLevelSetMessageFilename(void); char *getImageFilename(char *); char *getCustomImageFilename(char *); char *getCustomSoundFilename(char *); diff --git a/src/libgame/sound.c b/src/libgame/sound.c index be88d8e1..a01ce29d 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -1792,7 +1792,7 @@ void LoadCustomMusic_NoConf(void) } if (draw_init_text) - DrawInitText("Loading music:", 120, FC_GREEN); + DrawInitText("Loading music", 120, FC_GREEN); while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */ { diff --git a/src/libgame/system.c b/src/libgame/system.c index f3696277..7d0099f4 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -245,7 +245,10 @@ void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask) if (background_bitmap_tile == NULL) /* empty background requested */ return; - if (mask == REDRAW_FIELD) + if (mask == REDRAW_ALL) + DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile, + 0, 0, video.width, video.height); + else if (mask == REDRAW_FIELD) DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile, gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize); @@ -257,13 +260,20 @@ void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask) } } +void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile) +{ + SetBackgroundBitmap(background_bitmap_tile, REDRAW_ALL); +} + void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile) { + SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */ SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD); } void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile) { + SetBackgroundBitmap(NULL, REDRAW_ALL); /* !!! FIX THIS !!! */ SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1); } @@ -321,8 +331,7 @@ void CloseVideoDisplay(void) #endif } -void InitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window, - int width, int height, int depth, boolean fullscreen) +void InitVideoBuffer(int width, int height, int depth, boolean fullscreen) { video.width = width; video.height = height; @@ -334,10 +343,12 @@ void InitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window, video.fullscreen_mode_current = NULL; #if defined(TARGET_SDL) - SDLInitVideoBuffer(backbuffer, window, fullscreen); + SDLInitVideoBuffer(&backbuffer, &window, fullscreen); #else - X11InitVideoBuffer(backbuffer, window); + X11InitVideoBuffer(&backbuffer, &window); #endif + + drawto = backbuffer; } Bitmap *CreateBitmapStruct(void) @@ -424,13 +435,16 @@ inline static boolean CheckDrawingArea(int x, int y, int width, int height, if (draw_mask & REDRAW_ALL) return TRUE; - if ((draw_mask & REDRAW_FIELD) && x < gfx.real_sx + gfx.full_sxsize) + if ((draw_mask & REDRAW_FIELD) && + x >= gfx.real_sx && x < gfx.real_sx + gfx.full_sxsize) return TRUE; - if ((draw_mask & REDRAW_DOOR_1) && x >= gfx.dx && y < gfx.dy + gfx.dysize) + if ((draw_mask & REDRAW_DOOR_1) && + x >= gfx.dx && y < gfx.dy + gfx.dysize) return TRUE; - if ((draw_mask & REDRAW_DOOR_2) && x >= gfx.dx && y >= gfx.vy) + if ((draw_mask & REDRAW_DOOR_2) && + x >= gfx.dx && y >= gfx.vy) return TRUE; return FALSE; @@ -459,14 +473,15 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap, } void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, - int fade_mode, int fade_delay, int post_delay) + int fade_mode, int fade_delay, int post_delay, + void (*draw_border_function)(void)) { #if defined(TARGET_SDL) SDLFadeRectangle(bitmap_cross, x, y, width, height, - fade_mode, fade_delay, post_delay); + fade_mode, fade_delay, post_delay, draw_border_function); #else X11FadeRectangle(bitmap_cross, x, y, width, height, - fade_mode, fade_delay, post_delay); + fade_mode, fade_delay, post_delay, draw_border_function); #endif } diff --git a/src/libgame/system.h b/src/libgame/system.h index 99d7c59d..2d10c7b1 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -194,10 +194,23 @@ /* values for special (non game element) animation modes */ #define ANIM_HORIZONTAL (1 << 10) #define ANIM_VERTICAL (1 << 11) -#define ANIM_STATIC_PANEL (1 << 12) +#define ANIM_CENTERED (1 << 12) +#define ANIM_STATIC_PANEL (1 << 13) +#define ANIM_FADE (1 << 14) +#define ANIM_CROSSFADE (1 << 15) #define ANIM_DEFAULT ANIM_LOOP +/* values for text alignment */ +#define ALIGN_LEFT (1 << 0) +#define ALIGN_RIGHT (1 << 1) +#define ALIGN_CENTER (1 << 2) + +#define ALIGN_DEFAULT ALIGN_LEFT + +#define ALIGNED_XPOS(x,w,a) ((a) == ALIGN_CENTER ? (x) - (w) / 2 : \ + (a) == ALIGN_RIGHT ? (x) - (w) : (x)) + /* values for redraw_mask */ #define REDRAW_NONE (0) #define REDRAW_ALL (1 << 0) @@ -299,6 +312,7 @@ #define TAPES_DIRECTORY "tapes" #define SCORES_DIRECTORY "scores" #define DOCS_DIRECTORY "docs" +#define CACHE_DIRECTORY "cache" #if !defined(PLATFORM_MSDOS) #define GFX_CLASSIC_SUBDIR "gfx_classic" @@ -323,6 +337,7 @@ #define GRAPHICSINFO_FILENAME "graphicsinfo.conf" #define SOUNDSINFO_FILENAME "soundsinfo.conf" #define MUSICINFO_FILENAME "musicinfo.conf" +#define ARTWORKINFO_CACHE_FILE "artworkinfo.cache" #define LEVELFILE_EXTENSION "level" #define TAPEFILE_EXTENSION "tape" #define SCOREFILE_EXTENSION "score" @@ -338,6 +353,7 @@ #define GRAPHICSINFO_FILENAME "gfxinfo.cnf" #define SOUNDSINFO_FILENAME "sndinfo.cnf" #define MUSICINFO_FILENAME "musinfo.cnf" +#define ARTWORKINFO_CACHE_FILE "artinfo.cac" #define LEVELFILE_EXTENSION "lvl" #define TAPEFILE_EXTENSION "tap" #define SCOREFILE_EXTENSION "sco" @@ -984,6 +1000,12 @@ struct XY int x, y; }; +struct Rect +{ + int x, y; + int width, height; +}; + /* ========================================================================= */ /* exported variables */ @@ -1037,17 +1059,19 @@ void InitGfxDoor2Info(int, int, int, int); void InitGfxScrollbufferInfo(int, int); void SetDrawDeactivationMask(int); void SetDrawBackgroundMask(int); +void SetWindowBackgroundBitmap(Bitmap *); void SetMainBackgroundBitmap(Bitmap *); void SetDoorBackgroundBitmap(Bitmap *); void InitVideoDisplay(void); void CloseVideoDisplay(void); -void InitVideoBuffer(DrawBuffer **,DrawWindow **, int,int,int, boolean); +void InitVideoBuffer(int, int, int, boolean); Bitmap *CreateBitmapStruct(void); Bitmap *CreateBitmap(int, int, int); void FreeBitmap(Bitmap *); void BlitBitmap(Bitmap *, Bitmap *, int, int, int, int, int, int); -void FadeRectangle(Bitmap *bitmap, int, int, int, int, int, int, int); +void FadeRectangle(Bitmap *bitmap, int, int, int, int, int, int, int, + void (*draw_border_function)(void)); void FillRectangle(Bitmap *, int, int, int, int, Pixel); void ClearRectangle(Bitmap *, int, int, int, int); void ClearRectangleOnBackground(Bitmap *, int, int, int, int); diff --git a/src/libgame/text.c b/src/libgame/text.c index bfd2a7c4..83be1dfc 100644 --- a/src/libgame/text.c +++ b/src/libgame/text.c @@ -156,12 +156,12 @@ int getTextWidth(char *text, int font_nr) return (text != NULL ? strlen(text) * getFontWidth(font_nr) : 0); } -static char getFontCharPosition(int font_nr, char c) +static int getFontCharPosition(int font_nr, char c) { int font_bitmap_id = gfx.select_font_function(font_nr); struct FontBitmapInfo *font = &gfx.font_bitmap_info[font_bitmap_id]; boolean default_font = (font->num_chars == DEFAULT_NUM_CHARS_PER_FONT); - int font_pos = c - 32; + int font_pos = (unsigned char)c - 32; /* map some special characters to their ascii values in default font */ if (default_font) @@ -187,14 +187,20 @@ void getFontCharSource(int font_nr, char c, Bitmap **bitmap, int *x, int *y) void DrawInitText(char *text, int ypos, int font_nr) { - if (window && + if (window != NULL && gfx.num_fonts > 0 && gfx.font_bitmap_info[font_nr].bitmap != NULL) { - ClearRectangle(window, 0, ypos, video.width, getFontHeight(font_nr)); - DrawTextExt(window, (video.width - getTextWidth(text, font_nr)) / 2, ypos, - text, font_nr, BLIT_OPAQUE); - FlushDisplay(); + int x = (video.width - getTextWidth(text, font_nr)) / 2; + int y = ypos; + int width = video.width; + int height = getFontHeight(font_nr); + + ClearRectangle(drawto, 0, y, width, height); + DrawTextExt(drawto, x, y, text, font_nr, BLIT_OPAQUE); + + /* this makes things significantly faster than directly drawing to window */ + BlitBitmap(drawto, window, 0, y, width, height, 0, y); } } @@ -240,6 +246,18 @@ void DrawTextSCentered(int y, int font_nr, char *text) gfx.sy + y, text, font_nr); } +void DrawTextSAligned(int x, int y, char *text, int font_nr, int align) +{ + DrawText(gfx.sx + ALIGNED_XPOS(x, getTextWidth(text, font_nr), align), + gfx.sx + y, text, font_nr); +} + +void DrawTextAligned(int x, int y, char *text, int font_nr, int align) +{ + DrawText(ALIGNED_XPOS(x, getTextWidth(text, font_nr), align), + y, text, font_nr); +} + void DrawText(int x, int y, char *text, int font_nr) { int mask_mode = BLIT_OPAQUE; @@ -258,8 +276,12 @@ void DrawText(int x, int y, char *text, int font_nr) void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text, int font_nr, int mask_mode) { +#if 1 + struct FontBitmapInfo *font = getFontBitmapInfo(font_nr); +#else int font_bitmap_id = gfx.select_font_function(font_nr); struct FontBitmapInfo *font = &gfx.font_bitmap_info[font_bitmap_id]; +#endif int font_width = getFontWidth(font_nr); int font_height = getFontHeight(font_nr); #if 0 @@ -287,7 +309,7 @@ void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text, char c = *text_ptr++; if (c == '\n') - c = ' '; /* print space instaed of newline */ + c = ' '; /* print space instead of newline */ getFontCharSource(font_nr, c, &src_bitmap, &src_x, &src_y); @@ -501,7 +523,7 @@ void DrawTextWrapped(int x, int y, char *text, int font_nr, int line_length, } int DrawTextFromFile(int x, int y, char *filename, int font_nr, - int line_length, int max_lines) + int line_length, int max_lines, boolean rewrap) { int font_height = getFontHeight(font_nr); char line[MAX_LINE_LEN]; @@ -552,10 +574,41 @@ int DrawTextFromFile(int x, int y, char *filename, int font_nr, while (*line_ptr && current_line < max_lines) { +#if 1 + boolean buffer_filled; + + if (rewrap) + { + buffer_filled = RenderLineToBuffer(&line_ptr, + buffer, &buffer_len, + last_line_was_empty, + line_length); + } + else + { + if (strlen(line_ptr) <= line_length) + { + buffer_len = strlen(line_ptr); + strcpy(buffer, line_ptr); + } + else + { + buffer_len = line_length; + strncpy(buffer, line_ptr, line_length); + } + + buffer[buffer_len] = '\0'; + line_ptr += buffer_len; + + buffer_filled = TRUE; + } +#else boolean buffer_filled = RenderLineToBuffer(&line_ptr, buffer, &buffer_len, last_line_was_empty, line_length); +#endif + if (buffer_filled) { DrawText(x, y + current_line * font_height, buffer, font_nr); diff --git a/src/libgame/text.h b/src/libgame/text.h index f49346e4..f21ffdbf 100644 --- a/src/libgame/text.h +++ b/src/libgame/text.h @@ -68,11 +68,13 @@ void DrawTextF(int, int, int, char *, ...); void DrawTextFCentered(int, int, char *, ...); void DrawTextS(int, int, int, char *); void DrawTextSCentered(int, int, char *); +void DrawTextSAligned(int, int, char *, int, int); +void DrawTextAligned(int, int, char *, int, int); void DrawText(int, int, char *, int); void DrawTextExt(DrawBuffer *, int, int, char *, int, int); void DrawTextToTextArea(int, int, char *, int, int, int, int, int); boolean RenderLineToBuffer(char **, char *, int *, boolean, int); void DrawTextWrapped(int, int, char *, int, int, int); -int DrawTextFromFile(int, int, char *, int, int, int); +int DrawTextFromFile(int, int, char *, int, int, int, boolean); #endif /* TEXT_H */ diff --git a/src/libgame/toons.c b/src/libgame/toons.c index c5f1ff39..bbbd8833 100644 --- a/src/libgame/toons.c +++ b/src/libgame/toons.c @@ -308,7 +308,6 @@ void HandleAnimation(int mode) static boolean anim_restart = TRUE; static boolean reset_delay = TRUE; static int toon_nr = 0; - int draw_mode; if (!setup.toons || screen_info.num_toons == 0) return; @@ -335,15 +334,22 @@ void HandleAnimation(int mode) break; case ANIM_STOP: - redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER); + if (anim_running) + { +#if 1 + int draw_mode; + + redraw_mask |= (REDRAW_FIELD | REDRAW_FROM_BACKBUFFER); - /* Redraw background even when in direct drawing mode */ - draw_mode = setup.direct_draw; - setup.direct_draw = FALSE; - screen_info.update_function(); - setup.direct_draw = draw_mode; + /* Redraw background even when in direct drawing mode */ + draw_mode = setup.direct_draw; + setup.direct_draw = FALSE; + screen_info.update_function(); + setup.direct_draw = draw_mode; +#endif - anim_running = FALSE; + anim_running = FALSE; + } return; diff --git a/src/libgame/x11.c b/src/libgame/x11.c index a9f23431..2bbf76d5 100644 --- a/src/libgame/x11.c +++ b/src/libgame/x11.c @@ -363,14 +363,18 @@ void X11FillRectangle(Bitmap *bitmap, int x, int y, } void X11FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height, - int fade_mode, int fade_delay, int post_delay) + int fade_mode, int fade_delay, int post_delay, + void (*draw_border_function)(void)) { /* fading currently not supported -- simply copy backbuffer to screen */ if (fade_mode == FADE_MODE_FADE_OUT) - X11FillRectangle(window, x, y, width, height, BLACK_PIXEL); - else - X11CopyArea(backbuffer, window, x, y, width, height, 0, 0, BLIT_OPAQUE); + X11FillRectangle(backbuffer, x, y, width, height, BLACK_PIXEL); + + if (draw_border_function != NULL) + draw_border_function(); + + X11CopyArea(backbuffer, window, x, y, width, height, 0, 0, BLIT_OPAQUE); /* as we currently cannot use the fade delay, also do not use post delay */ } diff --git a/src/libgame/x11.h b/src/libgame/x11.h index 0e2ba46e..28e8f5e8 100644 --- a/src/libgame/x11.h +++ b/src/libgame/x11.h @@ -339,7 +339,8 @@ void X11CreateBitmapContent(Bitmap *, int, int, int); void X11FreeBitmapPointers(Bitmap *); void X11CopyArea(Bitmap *, Bitmap *, int, int, int, int, int, int, int); void X11FillRectangle(Bitmap *, int, int, int, int, Pixel); -void X11FadeRectangle(Bitmap *, int, int, int, int, int, int, int); +void X11FadeRectangle(Bitmap *, int, int, int, int, int, int, int, + void (*draw_border_function)(void)); void X11DrawSimpleLine(Bitmap *, int, int, int, int, Pixel); Pixel X11GetPixel(Bitmap *, int, int); Pixel X11GetPixelFromRGB(unsigned int, unsigned int, unsigned int); diff --git a/src/main.c b/src/main.c index 25bdd22b..3b1eb05e 100644 --- a/src/main.c +++ b/src/main.c @@ -59,6 +59,7 @@ short ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short CheckCollision[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +short CheckImpact[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short AmoebaCnt[MAX_NUM_AMOEBA]; short AmoebaCnt2[MAX_NUM_AMOEBA]; @@ -104,6 +105,8 @@ struct TapeInfo tape; struct SetupInfo setup; struct GameInfo game; struct GlobalInfo global; +struct BorderInfo border; +struct TitleInfo title; struct MenuInfo menu; struct DoorInfo door_1, door_2; struct PreviewInfo preview; @@ -4615,92 +4618,224 @@ struct ElementDirectionInfo element_direction_info[NUM_DIRECTIONS_FULL + 1] = struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1 + 1] = { - { ".[DEFAULT]", GAME_MODE_DEFAULT, }, - { ".TITLE", GAME_MODE_TITLE, }, - { ".MAIN", GAME_MODE_MAIN, }, - { ".LEVELS", GAME_MODE_LEVELS }, - { ".SCORES", GAME_MODE_SCORES, }, - { ".EDITOR", GAME_MODE_EDITOR, }, - { ".INFO", GAME_MODE_INFO, }, - { ".SETUP", GAME_MODE_SETUP, }, - { ".PLAYING", GAME_MODE_PLAYING, }, - { ".DOOR", GAME_MODE_PSEUDO_DOOR, }, - { ".PREVIEW", GAME_MODE_PSEUDO_PREVIEW, }, - { ".CRUMBLED", GAME_MODE_PSEUDO_CRUMBLED, }, + { ".[DEFAULT]", GFX_SPECIAL_ARG_DEFAULT, }, + { ".TITLE", GFX_SPECIAL_ARG_TITLE, }, + { ".MESSAGE", GFX_SPECIAL_ARG_MESSAGE, }, + { ".MAIN", GFX_SPECIAL_ARG_MAIN, }, + { ".LEVELS", GFX_SPECIAL_ARG_LEVELS }, + { ".SCORES", GFX_SPECIAL_ARG_SCORES, }, + { ".EDITOR", GFX_SPECIAL_ARG_EDITOR, }, + { ".INFO", GFX_SPECIAL_ARG_INFO, }, + { ".SETUP", GFX_SPECIAL_ARG_SETUP, }, + { ".PLAYING", GFX_SPECIAL_ARG_PLAYING, }, + { ".DOOR", GFX_SPECIAL_ARG_DOOR, }, + { ".PREVIEW", GFX_SPECIAL_ARG_PREVIEW, }, + { ".CRUMBLED", GFX_SPECIAL_ARG_CRUMBLED, }, /* empty suffix always matches -- check as last entry in InitMusicInfo() */ - { "", GAME_MODE_DEFAULT, }, + { "", GFX_SPECIAL_ARG_DEFAULT, }, { NULL, 0, } }; struct TokenIntPtrInfo image_config_vars[] = { - { "global.num_toons", &global.num_toons }, + { "global.num_toons", &global.num_toons }, - { "menu.draw_xoffset", &menu.draw_xoffset[GFX_SPECIAL_ARG_DEFAULT] }, - { "menu.draw_yoffset", &menu.draw_yoffset[GFX_SPECIAL_ARG_DEFAULT] }, - { "menu.draw_xoffset.MAIN", &menu.draw_xoffset[GFX_SPECIAL_ARG_MAIN] }, - { "menu.draw_yoffset.MAIN", &menu.draw_yoffset[GFX_SPECIAL_ARG_MAIN] }, - { "menu.draw_xoffset.LEVELS", &menu.draw_xoffset[GFX_SPECIAL_ARG_LEVELS] }, - { "menu.draw_yoffset.LEVELS", &menu.draw_yoffset[GFX_SPECIAL_ARG_LEVELS] }, - { "menu.draw_xoffset.SCORES", &menu.draw_xoffset[GFX_SPECIAL_ARG_SCORES] }, - { "menu.draw_yoffset.SCORES", &menu.draw_yoffset[GFX_SPECIAL_ARG_SCORES] }, - { "menu.draw_xoffset.EDITOR", &menu.draw_xoffset[GFX_SPECIAL_ARG_EDITOR] }, - { "menu.draw_yoffset.EDITOR", &menu.draw_yoffset[GFX_SPECIAL_ARG_EDITOR] }, - { "menu.draw_xoffset.INFO", &menu.draw_xoffset[GFX_SPECIAL_ARG_INFO] }, - { "menu.draw_yoffset.INFO", &menu.draw_yoffset[GFX_SPECIAL_ARG_INFO] }, - { "menu.draw_xoffset.SETUP", &menu.draw_xoffset[GFX_SPECIAL_ARG_SETUP] }, - { "menu.draw_yoffset.SETUP", &menu.draw_yoffset[GFX_SPECIAL_ARG_SETUP] }, + { "border.draw_masked.TITLE", &border.draw_masked[GFX_SPECIAL_ARG_TITLE] }, + { "border.draw_masked.MAIN", &border.draw_masked[GFX_SPECIAL_ARG_MAIN] }, + { "border.draw_masked.LEVELS", &border.draw_masked[GFX_SPECIAL_ARG_LEVELS] }, + { "border.draw_masked.SCORES", &border.draw_masked[GFX_SPECIAL_ARG_SCORES] }, + { "border.draw_masked.EDITOR", &border.draw_masked[GFX_SPECIAL_ARG_EDITOR] }, + { "border.draw_masked.INFO", &border.draw_masked[GFX_SPECIAL_ARG_INFO] }, + { "border.draw_masked.SETUP", &border.draw_masked[GFX_SPECIAL_ARG_SETUP] }, + { "border.draw_masked.PLAYING",&border.draw_masked[GFX_SPECIAL_ARG_PLAYING] }, + { "border.draw_masked.DOOR", &border.draw_masked[GFX_SPECIAL_ARG_DOOR] }, - { "menu.scrollbar_xoffset", &menu.scrollbar_xoffset }, + { "title.fade_delay", &title.fade_delay }, + { "title.post_delay", &title.post_delay }, + { "title.auto_delay", &title.auto_delay }, - { "menu.list_size", &menu.list_size[GFX_SPECIAL_ARG_DEFAULT] }, - { "menu.list_size.LEVELS", &menu.list_size[GFX_SPECIAL_ARG_LEVELS] }, - { "menu.list_size.SCORES", &menu.list_size[GFX_SPECIAL_ARG_SCORES] }, - { "menu.list_size.INFO", &menu.list_size[GFX_SPECIAL_ARG_INFO] }, + { "menu.fade_delay", &menu.fade_delay }, + { "menu.post_delay", &menu.post_delay }, + { "menu.auto_delay", &menu.auto_delay }, - { "menu.fade_delay", &menu.fade_delay }, - { "menu.post_delay", &menu.post_delay }, + { "menu.draw_xoffset", &menu.draw_xoffset[GFX_SPECIAL_ARG_DEFAULT] }, + { "menu.draw_yoffset", &menu.draw_yoffset[GFX_SPECIAL_ARG_DEFAULT] }, + { "menu.draw_xoffset.MAIN", &menu.draw_xoffset[GFX_SPECIAL_ARG_MAIN] }, + { "menu.draw_yoffset.MAIN", &menu.draw_yoffset[GFX_SPECIAL_ARG_MAIN] }, + { "menu.draw_xoffset.LEVELS", &menu.draw_xoffset[GFX_SPECIAL_ARG_LEVELS] }, + { "menu.draw_yoffset.LEVELS", &menu.draw_yoffset[GFX_SPECIAL_ARG_LEVELS] }, + { "menu.draw_xoffset.SCORES", &menu.draw_xoffset[GFX_SPECIAL_ARG_SCORES] }, + { "menu.draw_yoffset.SCORES", &menu.draw_yoffset[GFX_SPECIAL_ARG_SCORES] }, + { "menu.draw_xoffset.EDITOR", &menu.draw_xoffset[GFX_SPECIAL_ARG_EDITOR] }, + { "menu.draw_yoffset.EDITOR", &menu.draw_yoffset[GFX_SPECIAL_ARG_EDITOR] }, + { "menu.draw_xoffset.INFO", &menu.draw_xoffset[GFX_SPECIAL_ARG_INFO] }, + { "menu.draw_yoffset.INFO", &menu.draw_yoffset[GFX_SPECIAL_ARG_INFO] }, + { "menu.draw_xoffset.INFO[ELEMENTS]", + &menu.draw_xoffset_info[GFX_SPECIAL_ARG_INFO_ELEMENTS] }, + { "menu.draw_yoffset.INFO[ELEMENTS]", + &menu.draw_yoffset_info[GFX_SPECIAL_ARG_INFO_ELEMENTS] }, + { "menu.draw_xoffset.INFO[MUSIC]", + &menu.draw_xoffset_info[GFX_SPECIAL_ARG_INFO_MUSIC] }, + { "menu.draw_yoffset.INFO[MUSIC]", + &menu.draw_yoffset_info[GFX_SPECIAL_ARG_INFO_MUSIC] }, + { "menu.draw_xoffset.INFO[CREDITS]", + &menu.draw_xoffset_info[GFX_SPECIAL_ARG_INFO_CREDITS] }, + { "menu.draw_yoffset.INFO[CREDITS]", + &menu.draw_yoffset_info[GFX_SPECIAL_ARG_INFO_CREDITS] }, + { "menu.draw_xoffset.INFO[PROGRAM]", + &menu.draw_xoffset_info[GFX_SPECIAL_ARG_INFO_PROGRAM] }, + { "menu.draw_yoffset.INFO[PROGRAM]", + &menu.draw_yoffset_info[GFX_SPECIAL_ARG_INFO_PROGRAM] }, + { "menu.draw_xoffset.INFO[LEVELSET]", + &menu.draw_xoffset_info[GFX_SPECIAL_ARG_INFO_LEVELSET] }, + { "menu.draw_yoffset.INFO[LEVELSET]", + &menu.draw_yoffset_info[GFX_SPECIAL_ARG_INFO_LEVELSET] }, + { "menu.draw_xoffset.SETUP", &menu.draw_xoffset[GFX_SPECIAL_ARG_SETUP] }, + { "menu.draw_yoffset.SETUP", &menu.draw_yoffset[GFX_SPECIAL_ARG_SETUP] }, - { "door_1.width", &door_1.width }, - { "door_1.height", &door_1.height }, - { "door_1.step_offset", &door_1.step_offset }, - { "door_1.step_delay", &door_1.step_delay }, - { "door_1.anim_mode", &door_1.anim_mode }, - { "door_2.width", &door_2.width }, - { "door_2.height", &door_2.height }, - { "door_2.step_offset", &door_2.step_offset }, - { "door_2.step_delay", &door_2.step_delay }, - { "door_2.anim_mode", &door_2.anim_mode }, + { "menu.scrollbar_xoffset", &menu.scrollbar_xoffset }, - { "preview.x", &preview.x }, - { "preview.y", &preview.y }, - { "preview.xsize", &preview.xsize }, - { "preview.ysize", &preview.ysize }, - { "preview.tile_size", &preview.tile_size }, - { "preview.step_offset", &preview.step_offset }, - { "preview.step_delay", &preview.step_delay }, + { "menu.list_size", &menu.list_size[GFX_SPECIAL_ARG_DEFAULT] }, + { "menu.list_size.LEVELS", &menu.list_size[GFX_SPECIAL_ARG_LEVELS] }, + { "menu.list_size.SCORES", &menu.list_size[GFX_SPECIAL_ARG_SCORES] }, + { "menu.list_size.INFO", &menu.list_size[GFX_SPECIAL_ARG_INFO] }, - { "game.panel.level.x", &game.panel.level.x }, - { "game.panel.level.y", &game.panel.level.y }, - { "game.panel.gems.x", &game.panel.gems.x }, - { "game.panel.gems.y", &game.panel.gems.y }, - { "game.panel.inventory.x", &game.panel.inventory.x }, - { "game.panel.inventory.y", &game.panel.inventory.y }, - { "game.panel.keys.x", &game.panel.keys.x }, - { "game.panel.keys.y", &game.panel.keys.y }, - { "game.panel.score.x", &game.panel.score.x }, - { "game.panel.score.y", &game.panel.score.y }, - { "game.panel.time.x", &game.panel.time.x }, - { "game.panel.time.y", &game.panel.time.y }, + { "main.button.name.x", &menu.main.button.name.x }, + { "main.button.name.y", &menu.main.button.name.y }, + { "main.button.levels.x", &menu.main.button.levels.x }, + { "main.button.levels.y", &menu.main.button.levels.y }, + { "main.button.scores.x", &menu.main.button.scores.x }, + { "main.button.scores.y", &menu.main.button.scores.y }, + { "main.button.editor.x", &menu.main.button.editor.x }, + { "main.button.editor.y", &menu.main.button.editor.y }, + { "main.button.info.x", &menu.main.button.info.x }, + { "main.button.info.y", &menu.main.button.info.y }, + { "main.button.game.x", &menu.main.button.game.x }, + { "main.button.game.y", &menu.main.button.game.y }, + { "main.button.setup.x", &menu.main.button.setup.x }, + { "main.button.setup.y", &menu.main.button.setup.y }, + { "main.button.quit.x", &menu.main.button.quit.x }, + { "main.button.quit.y", &menu.main.button.quit.y }, - { "[player].boring_delay_fixed", &game.player_boring_delay_fixed }, - { "[player].boring_delay_random", &game.player_boring_delay_random }, - { "[player].sleeping_delay_fixed", &game.player_sleeping_delay_fixed }, - { "[player].sleeping_delay_random", &game.player_sleeping_delay_random }, + { "main.button.prev_level.x", &menu.main.button.prev_level.x }, + { "main.button.prev_level.y", &menu.main.button.prev_level.y }, + { "main.button.next_level.x", &menu.main.button.next_level.x }, + { "main.button.next_level.y", &menu.main.button.next_level.y }, - { NULL, NULL, } + { "main.text.name.x", &menu.main.text.name.x }, + { "main.text.name.y", &menu.main.text.name.y }, + { "main.text.name.width", &menu.main.text.name.width }, + { "main.text.name.height", &menu.main.text.name.height }, + { "main.text.name.align", &menu.main.text.name.align }, + { "main.text.levels.x", &menu.main.text.levels.x }, + { "main.text.levels.y", &menu.main.text.levels.y }, + { "main.text.levels.width", &menu.main.text.levels.width }, + { "main.text.levels.height", &menu.main.text.levels.height }, + { "main.text.levels.align", &menu.main.text.levels.align }, + { "main.text.scores.x", &menu.main.text.scores.x }, + { "main.text.scores.y", &menu.main.text.scores.y }, + { "main.text.scores.width", &menu.main.text.scores.width }, + { "main.text.scores.height", &menu.main.text.scores.height }, + { "main.text.scores.align", &menu.main.text.scores.align }, + { "main.text.editor.x", &menu.main.text.editor.x }, + { "main.text.editor.y", &menu.main.text.editor.y }, + { "main.text.editor.width", &menu.main.text.editor.width }, + { "main.text.editor.height", &menu.main.text.editor.height }, + { "main.text.editor.align", &menu.main.text.editor.align }, + { "main.text.info.x", &menu.main.text.info.x }, + { "main.text.info.y", &menu.main.text.info.y }, + { "main.text.info.width", &menu.main.text.info.width }, + { "main.text.info.height", &menu.main.text.info.height }, + { "main.text.info.align", &menu.main.text.info.align }, + { "main.text.game.x", &menu.main.text.game.x }, + { "main.text.game.y", &menu.main.text.game.y }, + { "main.text.game.width", &menu.main.text.game.width }, + { "main.text.game.height", &menu.main.text.game.height }, + { "main.text.game.align", &menu.main.text.game.align }, + { "main.text.setup.x", &menu.main.text.setup.x }, + { "main.text.setup.y", &menu.main.text.setup.y }, + { "main.text.setup.width", &menu.main.text.setup.width }, + { "main.text.setup.height", &menu.main.text.setup.height }, + { "main.text.setup.align", &menu.main.text.setup.align }, + { "main.text.quit.x", &menu.main.text.quit.x }, + { "main.text.quit.y", &menu.main.text.quit.y }, + { "main.text.quit.width", &menu.main.text.quit.width }, + { "main.text.quit.height", &menu.main.text.quit.height }, + { "main.text.quit.align", &menu.main.text.quit.align }, + + { "main.text.current_level.x", &menu.main.text.current_level.x }, + { "main.text.current_level.y", &menu.main.text.current_level.y }, + { "main.text.current_level.align", &menu.main.text.current_level.align }, + { "main.text.first_level.x", &menu.main.text.first_level.x }, + { "main.text.first_level.y", &menu.main.text.first_level.y }, + { "main.text.first_level.align", &menu.main.text.first_level.align }, + { "main.text.last_level.x", &menu.main.text.last_level.x }, + { "main.text.last_level.y", &menu.main.text.last_level.y }, + { "main.text.last_level.align", &menu.main.text.last_level.align }, + { "main.text.level_info_1.x", &menu.main.text.level_info_1.x }, + { "main.text.level_info_1.y", &menu.main.text.level_info_1.y }, + { "main.text.level_info_1.align", &menu.main.text.level_info_1.align }, + { "main.text.level_info_2.x", &menu.main.text.level_info_2.x }, + { "main.text.level_info_2.y", &menu.main.text.level_info_2.y }, + { "main.text.level_info_2.align", &menu.main.text.level_info_2.align }, + { "main.text.title_1.x", &menu.main.text.title_1.x }, + { "main.text.title_1.y", &menu.main.text.title_1.y }, + { "main.text.title_1.align", &menu.main.text.title_1.align }, + { "main.text.title_2.x", &menu.main.text.title_2.x }, + { "main.text.title_2.y", &menu.main.text.title_2.y }, + { "main.text.title_2.align", &menu.main.text.title_2.align }, + { "main.text.title_3.x", &menu.main.text.title_3.x }, + { "main.text.title_3.y", &menu.main.text.title_3.y }, + { "main.text.title_3.align", &menu.main.text.title_3.align }, + + { "main.input.name.x", &menu.main.input.name.x }, + { "main.input.name.y", &menu.main.input.name.y }, + { "main.input.name.align", &menu.main.input.name.align }, + + { "preview.x", &preview.x }, + { "preview.y", &preview.y }, + { "preview.align", &preview.align }, + { "preview.xsize", &preview.xsize }, + { "preview.ysize", &preview.ysize }, + { "preview.xoffset", &preview.xoffset }, + { "preview.yoffset", &preview.yoffset }, + { "preview.tile_size", &preview.tile_size }, + { "preview.step_offset", &preview.step_offset }, + { "preview.step_delay", &preview.step_delay }, + { "preview.anim_mode", &preview.anim_mode }, + + { "door_1.width", &door_1.width }, + { "door_1.height", &door_1.height }, + { "door_1.step_offset", &door_1.step_offset }, + { "door_1.step_delay", &door_1.step_delay }, + { "door_1.anim_mode", &door_1.anim_mode }, + { "door_2.width", &door_2.width }, + { "door_2.height", &door_2.height }, + { "door_2.step_offset", &door_2.step_offset }, + { "door_2.step_delay", &door_2.step_delay }, + { "door_2.anim_mode", &door_2.anim_mode }, + + { "game.panel.level.x", &game.panel.level.x }, + { "game.panel.level.y", &game.panel.level.y }, + { "game.panel.gems.x", &game.panel.gems.x }, + { "game.panel.gems.y", &game.panel.gems.y }, + { "game.panel.inventory.x", &game.panel.inventory.x }, + { "game.panel.inventory.y", &game.panel.inventory.y }, + { "game.panel.keys.x", &game.panel.keys.x }, + { "game.panel.keys.y", &game.panel.keys.y }, + { "game.panel.score.x", &game.panel.score.x }, + { "game.panel.score.y", &game.panel.score.y }, + { "game.panel.time.x", &game.panel.time.x }, + { "game.panel.time.y", &game.panel.time.y }, + + { "[player].boring_delay_fixed", &game.player_boring_delay_fixed }, + { "[player].boring_delay_random", &game.player_boring_delay_random }, + { "[player].sleeping_delay_fixed", &game.player_sleeping_delay_fixed }, + { "[player].sleeping_delay_random", &game.player_sleeping_delay_random }, + + { NULL, NULL, } }; @@ -4709,7 +4844,8 @@ struct TokenIntPtrInfo image_config_vars[] = /* ------------------------------------------------------------------------- */ /* Important: When one entry is a prefix of another entry, the longer entry - must come first, because the dynamic configuration does prefix matching! */ + must come first, because the dynamic configuration does prefix matching! + (These definitions must match the corresponding definitions in "main.h"!) */ struct FontInfo font_info[NUM_FONTS + 1] = { @@ -4719,6 +4855,8 @@ struct FontInfo font_info[NUM_FONTS + 1] = { "font.initial_4" }, { "font.title_1" }, { "font.title_2" }, + { "font.menu_1.active" }, + { "font.menu_2.active" }, { "font.menu_1" }, { "font.menu_2" }, { "font.text_1.active" }, diff --git a/src/main.h b/src/main.h index 893d8d8f..b8430daa 100644 --- a/src/main.h +++ b/src/main.h @@ -1586,18 +1586,30 @@ /* values for special image configuration suffixes (must match game mode) */ #define GFX_SPECIAL_ARG_DEFAULT 0 #define GFX_SPECIAL_ARG_TITLE 1 -#define GFX_SPECIAL_ARG_MAIN 2 -#define GFX_SPECIAL_ARG_LEVELS 3 -#define GFX_SPECIAL_ARG_SCORES 4 -#define GFX_SPECIAL_ARG_EDITOR 5 -#define GFX_SPECIAL_ARG_INFO 6 -#define GFX_SPECIAL_ARG_SETUP 7 -#define GFX_SPECIAL_ARG_PLAYING 8 -#define GFX_SPECIAL_ARG_DOOR 9 -#define GFX_SPECIAL_ARG_PREVIEW 10 -#define GFX_SPECIAL_ARG_CRUMBLED 11 - -#define NUM_SPECIAL_GFX_ARGS 12 +#define GFX_SPECIAL_ARG_MESSAGE 2 +#define GFX_SPECIAL_ARG_MAIN 3 +#define GFX_SPECIAL_ARG_LEVELS 4 +#define GFX_SPECIAL_ARG_SCORES 5 +#define GFX_SPECIAL_ARG_EDITOR 6 +#define GFX_SPECIAL_ARG_INFO 7 +#define GFX_SPECIAL_ARG_SETUP 8 +#define GFX_SPECIAL_ARG_PLAYING 9 +#define GFX_SPECIAL_ARG_DOOR 10 +#define GFX_SPECIAL_ARG_PREVIEW 11 +#define GFX_SPECIAL_ARG_CRUMBLED 12 + +#define NUM_SPECIAL_GFX_ARGS 13 + +/* these additional definitions are currently only used for draw offsets */ +#define GFX_SPECIAL_ARG_INFO_MAIN 0 +#define GFX_SPECIAL_ARG_INFO_TITLE 1 +#define GFX_SPECIAL_ARG_INFO_ELEMENTS 2 +#define GFX_SPECIAL_ARG_INFO_MUSIC 3 +#define GFX_SPECIAL_ARG_INFO_CREDITS 4 +#define GFX_SPECIAL_ARG_INFO_PROGRAM 5 +#define GFX_SPECIAL_ARG_INFO_LEVELSET 6 + +#define NUM_SPECIAL_GFX_INFO_ARGS 7 /* values for image configuration suffixes */ @@ -1640,8 +1652,11 @@ #define GFX_ARG_NAME 36 #define GFX_ARG_SCALE_UP_FACTOR 37 #define GFX_ARG_CLONE_FROM 38 +#define GFX_ARG_FADE_DELAY 39 +#define GFX_ARG_POST_DELAY 40 +#define GFX_ARG_AUTO_DELAY 41 -#define NUM_GFX_ARGS 39 +#define NUM_GFX_ARGS 42 /* values for sound configuration suffixes */ @@ -1658,61 +1673,77 @@ #define NUM_MUS_ARGS 1 -/* values for font configuration */ +/* values for font configuration (definitions must match those from main.c) */ #define FONT_INITIAL_1 0 #define FONT_INITIAL_2 1 #define FONT_INITIAL_3 2 #define FONT_INITIAL_4 3 #define FONT_TITLE_1 4 #define FONT_TITLE_2 5 -#define FONT_MENU_1 6 -#define FONT_MENU_2 7 -#define FONT_TEXT_1_ACTIVE 8 -#define FONT_TEXT_2_ACTIVE 9 -#define FONT_TEXT_3_ACTIVE 10 -#define FONT_TEXT_4_ACTIVE 11 -#define FONT_TEXT_1 12 -#define FONT_TEXT_2 13 -#define FONT_TEXT_3 14 -#define FONT_TEXT_4 15 -#define FONT_ENVELOPE_1 16 -#define FONT_ENVELOPE_2 17 -#define FONT_ENVELOPE_3 18 -#define FONT_ENVELOPE_4 19 -#define FONT_INPUT_1_ACTIVE 20 -#define FONT_INPUT_2_ACTIVE 21 -#define FONT_INPUT_1 22 -#define FONT_INPUT_2 23 -#define FONT_OPTION_OFF 24 -#define FONT_OPTION_ON 25 -#define FONT_VALUE_1 26 -#define FONT_VALUE_2 27 -#define FONT_VALUE_OLD 28 -#define FONT_LEVEL_NUMBER_ACTIVE 29 -#define FONT_LEVEL_NUMBER 30 -#define FONT_TAPE_RECORDER 31 -#define FONT_GAME_INFO 32 - -#define NUM_FONTS 33 +#define FONT_MENU_1_ACTIVE 6 +#define FONT_MENU_2_ACTIVE 7 +#define FONT_MENU_1 8 +#define FONT_MENU_2 9 +#define FONT_TEXT_1_ACTIVE 10 +#define FONT_TEXT_2_ACTIVE 11 +#define FONT_TEXT_3_ACTIVE 12 +#define FONT_TEXT_4_ACTIVE 13 +#define FONT_TEXT_1 14 +#define FONT_TEXT_2 15 +#define FONT_TEXT_3 16 +#define FONT_TEXT_4 17 +#define FONT_ENVELOPE_1 18 +#define FONT_ENVELOPE_2 19 +#define FONT_ENVELOPE_3 20 +#define FONT_ENVELOPE_4 21 +#define FONT_INPUT_1_ACTIVE 22 +#define FONT_INPUT_2_ACTIVE 23 +#define FONT_INPUT_1 24 +#define FONT_INPUT_2 25 +#define FONT_OPTION_OFF 26 +#define FONT_OPTION_ON 27 +#define FONT_VALUE_1 28 +#define FONT_VALUE_2 29 +#define FONT_VALUE_OLD 30 +#define FONT_LEVEL_NUMBER_ACTIVE 31 +#define FONT_LEVEL_NUMBER 32 +#define FONT_TAPE_RECORDER 33 +#define FONT_GAME_INFO 34 + +#define NUM_FONTS 35 #define NUM_INITIAL_FONTS 4 +#define FONT_ACTIVE(f) \ + ((f) == FONT_MENU_1 ? FONT_MENU_1_ACTIVE : \ + (f) == FONT_MENU_2 ? FONT_MENU_2_ACTIVE : \ + (f) == FONT_TEXT_1 ? FONT_TEXT_1_ACTIVE : \ + (f) == FONT_TEXT_2 ? FONT_TEXT_2_ACTIVE : \ + (f) == FONT_TEXT_3 ? FONT_TEXT_3_ACTIVE : \ + (f) == FONT_TEXT_4 ? FONT_TEXT_4_ACTIVE : \ + (f) == FONT_INPUT_1 ? FONT_INPUT_1_ACTIVE : \ + (f) == FONT_INPUT_2 ? FONT_INPUT_2_ACTIVE : \ + (f) == FONT_LEVEL_NUMBER ? FONT_LEVEL_NUMBER_ACTIVE : \ + (f)) + + /* values for game_status (must match special image configuration suffixes) */ #define GAME_MODE_DEFAULT 0 #define GAME_MODE_TITLE 1 -#define GAME_MODE_MAIN 2 -#define GAME_MODE_LEVELS 3 -#define GAME_MODE_SCORES 4 -#define GAME_MODE_EDITOR 5 -#define GAME_MODE_INFO 6 -#define GAME_MODE_SETUP 7 -#define GAME_MODE_PLAYING 8 -#define GAME_MODE_PSEUDO_DOOR 9 -#define GAME_MODE_PSEUDO_PREVIEW 10 -#define GAME_MODE_PSEUDO_CRUMBLED 11 +#define GAME_MODE_MESSAGE 2 +#define GAME_MODE_MAIN 3 +#define GAME_MODE_LEVELS 4 +#define GAME_MODE_SCORES 5 +#define GAME_MODE_EDITOR 6 +#define GAME_MODE_INFO 7 +#define GAME_MODE_SETUP 8 +#define GAME_MODE_PLAYING 9 +#define GAME_MODE_PSEUDO_DOOR 10 +#define GAME_MODE_PSEUDO_PREVIEW 11 +#define GAME_MODE_PSEUDO_CRUMBLED 12 /* there are no special config file suffixes for these modes */ -#define GAME_MODE_PSEUDO_TYPENAME 12 -#define GAME_MODE_QUIT 13 +#define GAME_MODE_PSEUDO_TYPENAME 13 +#define GAME_MODE_QUIT 14 /* special definitions currently only used for custom artwork configuration */ #define MUSIC_PREFIX_BACKGROUND 0 @@ -1727,7 +1758,7 @@ /* program information and versioning definitions */ #define PROGRAM_VERSION_MAJOR 3 #define PROGRAM_VERSION_MINOR 2 -#define PROGRAM_VERSION_PATCH 2 +#define PROGRAM_VERSION_PATCH 3 #define PROGRAM_VERSION_BUILD 0 #define PROGRAM_TITLE_STRING "Rocks'n'Diamonds" @@ -1735,6 +1766,7 @@ #define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2006 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" #define ICON_TITLE_STRING PROGRAM_TITLE_STRING #define COOKIE_PREFIX "ROCKSNDIAMONDS" @@ -1815,10 +1847,83 @@ #define NUM_ENGINE_TYPES 3 +struct BorderInfo +{ + int draw_masked[NUM_SPECIAL_GFX_ARGS]; +}; + +struct MenuPosInfo +{ + int x, y; + int width, height; + int align; +}; + +struct MenuMainButtonInfo +{ + struct MenuPosInfo name; + struct MenuPosInfo levels; + struct MenuPosInfo scores; + struct MenuPosInfo editor; + struct MenuPosInfo info; + struct MenuPosInfo game; + struct MenuPosInfo setup; + struct MenuPosInfo quit; + + struct MenuPosInfo prev_level; + struct MenuPosInfo next_level; +}; + +struct MenuMainTextInfo +{ + struct MenuPosInfo name; + struct MenuPosInfo levels; + struct MenuPosInfo scores; + struct MenuPosInfo editor; + struct MenuPosInfo info; + struct MenuPosInfo game; + struct MenuPosInfo setup; + struct MenuPosInfo quit; + + struct MenuPosInfo current_level; + struct MenuPosInfo first_level; + struct MenuPosInfo last_level; + struct MenuPosInfo level_info_1; + struct MenuPosInfo level_info_2; + struct MenuPosInfo title_1; + struct MenuPosInfo title_2; + struct MenuPosInfo title_3; +}; + +struct MenuMainInputInfo +{ + struct MenuPosInfo name; +}; + +struct MenuMainInfo +{ + struct MenuMainButtonInfo button; + struct MenuMainTextInfo text; + struct MenuMainInputInfo input; +}; + +struct TitleInfo +{ + int fade_delay; + int post_delay; + int auto_delay; + + int fade_delay_final; + int post_delay_final; + int auto_delay_final; +}; + struct MenuInfo { int draw_xoffset[NUM_SPECIAL_GFX_ARGS]; int draw_yoffset[NUM_SPECIAL_GFX_ARGS]; + int draw_xoffset_info[NUM_SPECIAL_GFX_INFO_ARGS]; + int draw_yoffset_info[NUM_SPECIAL_GFX_INFO_ARGS]; int scrollbar_xoffset; @@ -1826,9 +1931,12 @@ struct MenuInfo int fade_delay; int post_delay; + int auto_delay; int sound[NUM_SPECIAL_GFX_ARGS]; int music[NUM_SPECIAL_GFX_ARGS]; + + struct MenuMainInfo main; }; struct DoorInfo @@ -1843,10 +1951,13 @@ struct DoorInfo struct PreviewInfo { int x, y; + int align; int xsize, ysize; + int xoffset, yoffset; int tile_size; int step_offset; int step_delay; + int anim_mode; }; struct HiScore @@ -2250,6 +2361,12 @@ struct GraphicInfo int draw_masked; /* optional setting for drawing envelope gfx */ + int fade_delay; /* optional setting for drawing title screens */ + int post_delay; /* optional setting for drawing title screens */ + int auto_delay; /* optional setting for drawing title screens */ + + boolean use_image_size; /* use image size as default width and height */ + #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) Pixmap clip_mask; /* single-graphic-only clip mask for X11 */ GC clip_gc; /* single-graphic-only clip gc for X11 */ @@ -2364,6 +2481,7 @@ extern short ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short CheckCollision[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +extern short CheckImpact[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short AmoebaCnt[MAX_NUM_AMOEBA]; extern short AmoebaCnt2[MAX_NUM_AMOEBA]; @@ -2407,6 +2525,8 @@ extern struct LevelInfo level, level_template; extern struct HiScore highscore[]; extern struct TapeInfo tape; extern struct GlobalInfo global; +extern struct BorderInfo border; +extern struct TitleInfo title; extern struct MenuInfo menu; extern struct DoorInfo door_1, door_2; extern struct PreviewInfo preview; diff --git a/src/netserv.c b/src/netserv.c index 4e65cf3d..a62cae02 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -740,7 +740,7 @@ void NetworkServer(int port, int serveronly) break; } - switch(buffer[1]) + switch (buffer[1]) { case OP_PLAYER_NAME: Handle_OP_PLAYER_NAME(player, len); diff --git a/src/network.c b/src/network.c index 412d2bd8..f2f1ea28 100644 --- a/src/network.c +++ b/src/network.c @@ -626,7 +626,7 @@ static void HandleNetworkingMessages() nread -= 4 + message_length; memmove(readbuffer, readbuffer + 4 + message_length, nread); - switch(buffer[1]) + switch (buffer[1]) { case OP_BAD_PROTOCOL_VERSION: Handle_OP_BAD_PROTOCOL_VERSION(); diff --git a/src/screens.c b/src/screens.c index 09e02969..c78cfd13 100644 --- a/src/screens.c +++ b/src/screens.c @@ -72,9 +72,9 @@ #define MAX_MENU_TEXT_LENGTH_MEDIUM (MAX_MENU_TEXT_LENGTH_BIG * 2) /* buttons and scrollbars identifiers */ -#define SCREEN_CTRL_ID_LAST_LEVEL 0 +#define SCREEN_CTRL_ID_PREV_LEVEL 0 #define SCREEN_CTRL_ID_NEXT_LEVEL 1 -#define SCREEN_CTRL_ID_LAST_PLAYER 2 +#define SCREEN_CTRL_ID_PREV_PLAYER 2 #define SCREEN_CTRL_ID_NEXT_PLAYER 3 #define SCREEN_CTRL_ID_SCROLL_UP 4 #define SCREEN_CTRL_ID_SCROLL_DOWN 5 @@ -115,6 +115,18 @@ #define SC_BORDER_SIZE 14 +/* other useful macro definitions */ +#define BUTTON_GRAPHIC_ACTIVE(g) \ + (g == IMG_MENU_BUTTON_LEFT ? IMG_MENU_BUTTON_LEFT_ACTIVE : \ + g == IMG_MENU_BUTTON_RIGHT ? IMG_MENU_BUTTON_RIGHT_ACTIVE : \ + g == IMG_MENU_BUTTON_UP ? IMG_MENU_BUTTON_UP_ACTIVE : \ + g == IMG_MENU_BUTTON_DOWN ? IMG_MENU_BUTTON_DOWN_ACTIVE : \ + g == IMG_MENU_BUTTON_LEAVE_MENU ? IMG_MENU_BUTTON_LEAVE_MENU_ACTIVE : \ + g == IMG_MENU_BUTTON_ENTER_MENU ? IMG_MENU_BUTTON_ENTER_MENU_ACTIVE : \ + g == IMG_MENU_BUTTON_PREV_LEVEL ? IMG_MENU_BUTTON_PREV_LEVEL_ACTIVE : \ + g == IMG_MENU_BUTTON_NEXT_LEVEL ? IMG_MENU_BUTTON_NEXT_LEVEL_ACTIVE : \ + IMG_MENU_BUTTON_ACTIVE) + /* forward declarations of internal functions */ static void HandleScreenGadgets(struct GadgetInfo *); @@ -128,9 +140,10 @@ static void HandleChooseTree(int, int, int, int, int, TreeInfo **); static void DrawChooseLevel(void); static void DrawInfoScreen(void); +static void DrawAndFadeInInfoScreen(int); static void DrawSetupScreen(void); -static void DrawInfoScreenExt(int); +static void DrawInfoScreenExt(int, int); static void DrawInfoScreen_NotAvailable(char *, char *); static void DrawInfoScreen_HelpAnim(int, int, boolean); static void DrawInfoScreen_HelpText(int, int, int, int); @@ -145,19 +158,40 @@ static void MapScreenMenuGadgets(int); static void MapScreenTreeGadgets(TreeInfo *); static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS]; + +static boolean show_titlescreen_initial = TRUE; + static int setup_mode = SETUP_MODE_MAIN; static int info_mode = INFO_MODE_MAIN; static TreeInfo *screen_modes = NULL; static TreeInfo *screen_mode_current = NULL; -#define DRAW_OFFSET_MODE(x) (x >= GAME_MODE_MAIN && \ - x <= GAME_MODE_SETUP ? x : \ - x == GAME_MODE_PSEUDO_TYPENAME ? \ +#define DRAW_MODE(s) ((s) >= GAME_MODE_MAIN && \ + (s) <= GAME_MODE_SETUP ? (s) : \ + (s) == GAME_MODE_PSEUDO_TYPENAME ? \ GAME_MODE_MAIN : GAME_MODE_DEFAULT) -#define mSX (SX + menu.draw_xoffset[DRAW_OFFSET_MODE(game_status)]) -#define mSY (SY + menu.draw_yoffset[DRAW_OFFSET_MODE(game_status)]) +#define DRAW_MODE_INFO(i) ((i) >= INFO_MODE_ELEMENTS && \ + (i) <= INFO_MODE_LEVELSET ? (i) : \ + INFO_MODE_MAIN) + +#define DRAW_XOFFSET_INFO(i) (DRAW_MODE_INFO(i) == INFO_MODE_MAIN ? \ + menu.draw_xoffset[GAME_MODE_INFO] : \ + menu.draw_xoffset_info[DRAW_MODE_INFO(i)]) +#define DRAW_YOFFSET_INFO(i) (DRAW_MODE_INFO(i) == INFO_MODE_MAIN ? \ + menu.draw_yoffset[GAME_MODE_INFO] : \ + menu.draw_yoffset_info[DRAW_MODE_INFO(i)]) + +#define DRAW_XOFFSET(s) ((s) == GAME_MODE_INFO ? \ + DRAW_XOFFSET_INFO(info_mode) : \ + menu.draw_xoffset[DRAW_MODE(s)]) +#define DRAW_YOFFSET(s) ((s) == GAME_MODE_INFO ? \ + DRAW_YOFFSET_INFO(info_mode) : \ + menu.draw_yoffset[DRAW_MODE(s)]) + +#define mSX (SX + DRAW_XOFFSET(game_status)) +#define mSY (SY + DRAW_YOFFSET(game_status)) #define NUM_MENU_ENTRIES_ON_SCREEN (menu.list_size[game_status] > 2 ? \ menu.list_size[game_status] : \ @@ -169,56 +203,407 @@ static Bitmap *scrollbar_bitmap[NUM_SCROLLBAR_BITMAPS]; #endif -static void drawCursorExt(int xpos, int ypos, int color, int g) +#define MAIN_CONTROL_NAME 0 +#define MAIN_CONTROL_LEVELS 1 +#define MAIN_CONTROL_SCORES 2 +#define MAIN_CONTROL_EDITOR 3 +#define MAIN_CONTROL_INFO 4 +#define MAIN_CONTROL_GAME 5 +#define MAIN_CONTROL_SETUP 6 +#define MAIN_CONTROL_QUIT 7 +#define MAIN_CONTROL_PREV_LEVEL 8 +#define MAIN_CONTROL_NEXT_LEVEL 9 +#define MAIN_CONTROL_CURRENT_LEVEL 10 +#define MAIN_CONTROL_FIRST_LEVEL 11 +#define MAIN_CONTROL_LAST_LEVEL 12 +#define MAIN_CONTROL_LEVEL_INFO_1 13 +#define MAIN_CONTROL_LEVEL_INFO_2 14 +#define MAIN_CONTROL_TITLE_1 15 +#define MAIN_CONTROL_TITLE_2 16 +#define MAIN_CONTROL_TITLE_3 17 + +static char main_text_name[10]; +static char main_text_current_level[10]; +static char main_text_first_level[10]; +static char main_text_last_level[10]; +static char main_input_name[MAX_PLAYER_NAME_LEN + 1]; + +struct MainControlInfo +{ + int nr; + + struct MenuPosInfo *pos_button; + int button_graphic; + + struct MenuPosInfo *pos_text; + char *text; + int font_text; + + struct MenuPosInfo *pos_input; + char *input; + int font_input; +}; + +static struct MainControlInfo main_controls[] = +{ + { + MAIN_CONTROL_NAME, + &menu.main.button.name, IMG_MENU_BUTTON, + &menu.main.text.name, main_text_name, FONT_MENU_1, + &menu.main.input.name, main_input_name, FONT_INPUT_1, + }, + { + MAIN_CONTROL_LEVELS, + &menu.main.button.levels, IMG_MENU_BUTTON_ENTER_MENU, + &menu.main.text.levels, "Levelset", FONT_MENU_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_SCORES, + &menu.main.button.scores, IMG_MENU_BUTTON, + &menu.main.text.scores, "Hall Of Fame", FONT_MENU_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_EDITOR, + &menu.main.button.editor, IMG_MENU_BUTTON, + &menu.main.text.editor, "Level Creator", FONT_MENU_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_INFO, + &menu.main.button.info, IMG_MENU_BUTTON_ENTER_MENU, + &menu.main.text.info, "Info Screen", FONT_MENU_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_GAME, + &menu.main.button.game, IMG_MENU_BUTTON, + &menu.main.text.game, "Start Game", FONT_MENU_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_SETUP, + &menu.main.button.setup, IMG_MENU_BUTTON_ENTER_MENU, + &menu.main.text.setup, "Setup", FONT_MENU_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_QUIT, + &menu.main.button.quit, IMG_MENU_BUTTON, + &menu.main.text.quit, "Quit", FONT_MENU_1, + NULL, NULL, -1, + }, +#if 0 + /* (these two buttons are real gadgets) */ + { + MAIN_CONTROL_PREV_LEVEL, + &menu.main.button.prev_level, IMG_MENU_BUTTON_PREV_LEVEL, + NULL, NULL, -1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_NEXT_LEVEL, + &menu.main.button.next_level, IMG_MENU_BUTTON_NEXT_LEVEL, + NULL, NULL, -1, + NULL, NULL, -1, + }, +#endif + { + MAIN_CONTROL_CURRENT_LEVEL, + NULL, -1, + &menu.main.text.current_level, main_text_current_level,FONT_VALUE_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_FIRST_LEVEL, + NULL, -1, + &menu.main.text.first_level, main_text_first_level, FONT_TEXT_3, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_LAST_LEVEL, + NULL, -1, + &menu.main.text.last_level, main_text_last_level, FONT_TEXT_3, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_LEVEL_INFO_1, + NULL, -1, + &menu.main.text.level_info_1, NULL, -1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_LEVEL_INFO_2, + NULL, -1, + &menu.main.text.level_info_2, NULL, -1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_TITLE_1, + NULL, -1, + &menu.main.text.title_1, PROGRAM_TITLE_STRING, FONT_TITLE_1, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_TITLE_2, + NULL, -1, + &menu.main.text.title_2, PROGRAM_COPYRIGHT_STRING, FONT_TITLE_2, + NULL, NULL, -1, + }, + { + MAIN_CONTROL_TITLE_3, + NULL, -1, + &menu.main.text.title_3, PROGRAM_GAME_BY_STRING, FONT_TITLE_2, + NULL, NULL, -1, + }, + + { + -1, + NULL, -1, + NULL, NULL, -1, + NULL, NULL, -1, + } +}; + + +static void InitializeMainControls() +{ + boolean local_team_mode = (!options.network && setup.team_mode); + int i; + + /* set main control text values to dynamically determined values */ + sprintf(main_text_name, "%s", local_team_mode ? "Team:" : "Name:"); + sprintf(main_text_current_level, "%s", int2str(level_nr, 3)); + sprintf(main_text_first_level, "%03d", leveldir_current->first_level); + sprintf(main_text_last_level, "%03d", leveldir_current->last_level); + sprintf(main_input_name, "%s", setup.player_name); + + /* set main control screen positions to dynamically determined values */ + for (i = 0; main_controls[i].nr != -1; i++) + { + struct MainControlInfo *mci = &main_controls[i]; + int nr = mci->nr; + struct MenuPosInfo *pos_button = mci->pos_button; + struct MenuPosInfo *pos_text = mci->pos_text; + struct MenuPosInfo *pos_input = mci->pos_input; + char *text = mci->text; + char *input = mci->input; + int button_graphic = mci->button_graphic; + int font_text = mci->font_text; + int font_input = mci->font_input; + + int font_text_width = (font_text != -1 ? getFontWidth(font_text) : 0); + int font_text_height = (font_text != -1 ? getFontHeight(font_text) : 0); + int font_input_width = (font_input != -1 ? getFontWidth(font_input) : 0); + int font_input_height = (font_input != -1 ? getFontHeight(font_input) : 0); + int text_chars = (text != NULL ? strlen(text) : 0); + int input_chars = (input != NULL ? strlen(input) : 0); + + int button_width = + (button_graphic != -1 ? graphic_info[button_graphic].width : 0); + int button_height = + (button_graphic != -1 ? graphic_info[button_graphic].height : 0); + int text_width = font_text_width * text_chars; + int text_height = font_text_height; + int input_width = font_input_width * input_chars; + int input_height = font_input_height; + + if (nr == MAIN_CONTROL_NAME) + { +#if 0 + if (menu.main.input.name.x == -1) + menu.main.input.name.x = menu.main.text.name.x + text_width; + if (menu.main.input.name.y == -1) + menu.main.input.name.y = menu.main.text.name.y; +#endif + + menu.main.input.name.width = font_input_width * MAX_PLAYER_NAME_LEN; + menu.main.input.name.height = font_input_height; + } + + if (pos_button != NULL) + { + if (pos_button->width == 0) + pos_button->width = button_width; + if (pos_button->height == 0) + pos_button->height = button_height; + } + + if (pos_text != NULL) + { + /* calculate width for non-clickable text -- needed for text alignment */ + boolean calculate_text_width = (pos_button == NULL && text != NULL); + + if (pos_text->x == -1 && pos_button != NULL) + pos_text->x = pos_button->x + pos_button->width; + if (pos_text->y == -1 && pos_button != NULL) + pos_text->y = pos_button->y; + + if (pos_text->width == -1 || calculate_text_width) + pos_text->width = text_width; + if (pos_text->height == -1) + pos_text->height = text_height; + } + + if (pos_input != NULL) + { + if (pos_input->x == -1 && pos_text != NULL) + pos_input->x = pos_text->x + pos_text->width; + if (pos_input->y == -1 && pos_text != NULL) + pos_input->y = pos_text->y; + + if (pos_input->width == -1) + pos_input->width = input_width; + if (pos_input->height == -1) + pos_input->height = input_height; + } + } +} + +static void DrawCursorAndText_Main_Ext(int nr, boolean active_text, + boolean active_input) +{ + int i; + + for (i = 0; main_controls[i].nr != -1; i++) + { + struct MainControlInfo *mci = &main_controls[i]; + + if (mci->nr == nr || nr == -1) + { + struct MenuPosInfo *pos_button = mci->pos_button; + struct MenuPosInfo *pos_text = mci->pos_text; + struct MenuPosInfo *pos_input = mci->pos_input; + char *text = mci->text; + char *input = mci->input; + int button_graphic = mci->button_graphic; + int font_text = mci->font_text; + int font_input = mci->font_input; + + if (active_text) + { + button_graphic = BUTTON_GRAPHIC_ACTIVE(button_graphic); + font_text = FONT_ACTIVE(font_text); + } + + if (active_input) + { + font_input = FONT_ACTIVE(font_input); + } + + if (pos_button != NULL) + { + struct MenuPosInfo *pos = pos_button; + int x = mSX + pos->x; + int y = mSY + pos->y; + + DrawBackgroundForGraphic(x, y, pos->width, pos->height, button_graphic); + DrawGraphicThruMaskExt(drawto, x, y, button_graphic, 0); + } + + if (pos_text != NULL && text != NULL) + { + struct MenuPosInfo *pos = pos_text; + int x = mSX + ALIGNED_XPOS(pos->x, pos->width, pos->align); + int y = mSY + pos->y; + + DrawBackgroundForFont(x, y, pos->width, pos->height, font_text); + DrawText(x, y, text, font_text); + } + + if (pos_input != NULL && input != NULL) + { + struct MenuPosInfo *pos = pos_input; + int x = mSX + ALIGNED_XPOS(pos->x, pos->width, pos->align); + int y = mSY + pos->y; + + DrawBackgroundForFont(x, y, pos->width, pos->height, font_input); + DrawText(x, y, input, font_input); + } + } + } +} + +static void DrawCursorAndText_Main(int nr, boolean active_text) +{ + DrawCursorAndText_Main_Ext(nr, active_text, FALSE); +} + +#if 0 +static void DrawCursorAndText_Main_Input(int nr, boolean active_text) +{ + DrawCursorAndText_Main_Ext(nr, active_text, TRUE); +} +#endif + +static struct MainControlInfo *getMainControlInfo(int nr) +{ + int i; + + for (i = 0; main_controls[i].nr != -1; i++) + if (main_controls[i].nr == nr) + return &main_controls[i]; + + return NULL; +} + +static boolean insideMenuPosRect(struct MenuPosInfo *rect, int x, int y) +{ + if (rect == NULL) + return FALSE; + + int rect_x = ALIGNED_XPOS(rect->x, rect->width, rect->align); + int rect_y = rect->y; + + return (x >= rect_x && x < rect_x + rect->width && + y >= rect_y && y < rect_y + rect->height); +} + +static void drawCursorExt(int xpos, int ypos, boolean active, int graphic) { static int cursor_array[SCR_FIELDY]; + int x = mSX + TILEX * xpos; + int y = mSY + TILEY * (MENU_SCREEN_START_YPOS + ypos); if (xpos == 0) { - if (g != 0) - cursor_array[ypos] = g; + if (graphic != -1) + cursor_array[ypos] = graphic; else - g = cursor_array[ypos]; + graphic = cursor_array[ypos]; } - if (color == FC_RED) - g = (g == IMG_MENU_BUTTON_LEFT ? IMG_MENU_BUTTON_LEFT_ACTIVE : - g == IMG_MENU_BUTTON_RIGHT ? IMG_MENU_BUTTON_RIGHT_ACTIVE : - g == IMG_MENU_BUTTON_LEAVE_MENU ? IMG_MENU_BUTTON_LEAVE_MENU_ACTIVE : - g == IMG_MENU_BUTTON_ENTER_MENU ? IMG_MENU_BUTTON_ENTER_MENU_ACTIVE : - g == IMG_MENU_BUTTON_LAST_LEVEL ? IMG_MENU_BUTTON_LAST_LEVEL_ACTIVE : - g == IMG_MENU_BUTTON_NEXT_LEVEL ? IMG_MENU_BUTTON_NEXT_LEVEL_ACTIVE : - IMG_MENU_BUTTON_ACTIVE); - - ypos += MENU_SCREEN_START_YPOS; + if (active) + graphic = BUTTON_GRAPHIC_ACTIVE(graphic); - DrawBackground(mSX + xpos * TILEX, mSY + ypos * TILEY, TILEX, TILEY); - DrawGraphicThruMaskExt(drawto, mSX + xpos * TILEX, mSY + ypos * TILEY, g, 0); + DrawBackgroundForGraphic(x, y, TILEX, TILEY, graphic); + DrawGraphicThruMaskExt(drawto, x, y, graphic, 0); } static void initCursor(int ypos, int graphic) { - drawCursorExt(0, ypos, FC_BLUE, graphic); + drawCursorExt(0, ypos, FALSE, graphic); } -static void drawCursor(int ypos, int color) +static void drawCursor(int ypos, boolean active) { - drawCursorExt(0, ypos, color, 0); + drawCursorExt(0, ypos, active, -1); } static void drawCursorXY(int xpos, int ypos, int graphic) { - drawCursorExt(xpos, ypos, -1, graphic); + drawCursorExt(xpos, ypos, FALSE, graphic); } -static void drawChooseTreeCursor(int ypos, int color) +static void drawChooseTreeCursor(int ypos, boolean active) { int last_game_status = game_status; /* save current game status */ /* force LEVELS draw offset on artwork setup screen */ game_status = GAME_MODE_LEVELS; - drawCursorExt(0, ypos, color, 0); + drawCursorExt(0, ypos, active, -1); game_status = last_game_status; /* restore current game status */ } @@ -229,33 +614,56 @@ void DrawHeadline() DrawTextSCentered(MENU_TITLE2_YPOS, FONT_TITLE_2, PROGRAM_COPYRIGHT_STRING); } -static int getLastLevelButtonPos() +#if 0 +static int getPrevlevelButtonPos() { return 10; } static int getCurrentLevelTextPos() { - return (getLastLevelButtonPos() + 1); + return (getPrevlevelButtonPos() + 1); } static int getNextLevelButtonPos() { - return getLastLevelButtonPos() + 3 + 1; + return getPrevlevelButtonPos() + 3 + 1; } static int getLevelRangeTextPos() { return getNextLevelButtonPos() + 1; } +#endif + +static int getTitleScreenGraphic() +{ + return (show_titlescreen_initial ? IMG_TITLESCREEN_INITIAL_1 : + IMG_TITLESCREEN_1); +} + +int effectiveGameStatus() +{ + if (game_status == GAME_MODE_INFO && info_mode == INFO_MODE_TITLE) + return GAME_MODE_TITLE; + + return game_status; +} void DrawTitleScreenImage(int nr) { - int graphic = IMG_TITLESCREEN_1 + nr; + int graphic = getTitleScreenGraphic() + nr; Bitmap *bitmap = graphic_info[graphic].bitmap; +#if 1 + int width = graphic_info[graphic].width; + int height = graphic_info[graphic].height; + int src_x = graphic_info[graphic].src_x; + int src_y = graphic_info[graphic].src_y; +#else int width = graphic_info[graphic].src_image_width; int height = graphic_info[graphic].src_image_height; int src_x = 0, src_y = 0; +#endif int dst_x, dst_y; if (bitmap == NULL) @@ -286,6 +694,54 @@ void DrawTitleScreenImage(int nr) BlitBitmap(bitmap, drawto, src_x, src_y, width, height, dst_x, dst_y); redraw_mask = REDRAW_ALL; + + /* reset fading control values to default config settings */ + title.fade_delay_final = title.fade_delay; + title.post_delay_final = title.post_delay; + title.auto_delay_final = title.auto_delay; + + /* override default settings with image config settings, if defined */ + if (graphic_info[graphic].fade_delay > -1) + title.fade_delay_final = graphic_info[graphic].fade_delay; + if (graphic_info[graphic].post_delay > -1) + title.post_delay_final = graphic_info[graphic].post_delay; + if (graphic_info[graphic].auto_delay > -1) + title.auto_delay_final = graphic_info[graphic].auto_delay; +} + +void DrawTitleScreenMessage(char *filename) +{ + int font_nr = FONT_TEXT_1; + int font_width; + int font_height; + int pad_x = 16; + int pad_y = 32; + int sx = pad_x; + int sy = pad_y; + int max_chars_per_line; + int max_lines_per_screen; + int last_game_status = game_status; /* save current game status */ + + if (filename == NULL) + return; + + SetDrawBackgroundMask(REDRAW_ALL); + SetWindowBackgroundImageIfDefined(IMG_BACKGROUND_MESSAGE); + + ClearRectangleOnBackground(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE); + + /* force MESSAGE font on title message screen */ + game_status = GAME_MODE_MESSAGE; + + font_width = getFontWidth(font_nr); + font_height = getFontHeight(font_nr); + max_chars_per_line = (WIN_XSIZE - 2 * pad_x) / font_width; + max_lines_per_screen = (WIN_YSIZE - pad_y) / font_height - 1; + + DrawTextFromFile(sx, sy, filename, font_nr, max_chars_per_line, + max_lines_per_screen, FALSE); + + game_status = last_game_status; /* restore current game status */ } void DrawTitleScreen() @@ -303,10 +759,14 @@ void DrawMainMenuExt(int redraw_mask, boolean do_fading) { static LevelDirTree *leveldir_last_valid = NULL; boolean levelset_has_changed = FALSE; - char *name_text = (!options.network && setup.team_mode ? "Team:" : "Name:"); - char *level_text = "Levelset"; +#if 0 + boolean local_team_mode = (!options.network && setup.team_mode); + char *name_text = (local_team_mode ? "Team:" : "Name:"); int name_width, level_width; +#endif +#if 0 int i; +#endif UnmapAllGadgets(); FadeSoundsAndMusic(); @@ -354,10 +814,14 @@ void DrawMainMenuExt(int redraw_mask, boolean do_fading) #endif if (setup.show_titlescreen && - levelset_has_changed && - graphic_info[IMG_TITLESCREEN_1].bitmap != NULL) + ((levelset_has_changed && + (graphic_info[IMG_TITLESCREEN_1].bitmap != NULL || + getLevelSetMessageFilename() != NULL)) || + (show_titlescreen_initial && + graphic_info[IMG_TITLESCREEN_INITIAL_1].bitmap != NULL))) { game_status = GAME_MODE_TITLE; + DrawTitleScreen(); return; @@ -372,10 +836,41 @@ void DrawMainMenuExt(int redraw_mask, boolean do_fading) SetMainBackgroundImage(IMG_BACKGROUND_MAIN); ClearWindow(); +#if 1 + InitializeMainControls(); + +#if 1 + DrawCursorAndText_Main(-1, FALSE); +#else + for (i = 0; main_controls[i].nr != -1; i++) + { + struct MenuPosInfo *pos_button = main_controls[i].pos_button; + struct MenuPosInfo *pos_text = main_controls[i].pos_text; + struct MenuPosInfo *pos_input = main_controls[i].pos_input; + char *text = main_controls[i].text; + char *input = main_controls[i].input; + int button_graphic = main_controls[i].button_graphic; + int font_text = main_controls[i].font_text; + int font_input = main_controls[i].font_input; + + if (pos_button != NULL) + DrawGraphicThruMaskExt(drawto, mSX + pos_button->x, mSY + pos_button->y, + button_graphic, 0); + + if (pos_text != NULL && text != NULL) + DrawText(mSX + pos_text->x, mSY + pos_text->y, text, font_text); + + if (pos_input != NULL && input != NULL) + DrawText(mSX + pos_input->x, mSY + pos_input->y, input, font_input); + } +#endif + +#else + DrawHeadline(); DrawText(mSX + 32, mSY + 2 * 32, name_text, FONT_MENU_1); - DrawText(mSX + 32, mSY + 3 * 32, level_text, FONT_MENU_1); + DrawText(mSX + 32, mSY + 3 * 32, "Levelset", FONT_MENU_1); DrawText(mSX + 32, mSY + 4 * 32, "Hall Of Fame", FONT_MENU_1); DrawText(mSX + 32, mSY + 5 * 32, "Level Creator", FONT_MENU_1); DrawText(mSX + 32, mSY + 6 * 32, "Info Screen", FONT_MENU_1); @@ -393,17 +888,15 @@ void DrawMainMenuExt(int redraw_mask, boolean do_fading) DrawText(mSX + getCurrentLevelTextPos() * 32, mSY + 3 * 32, int2str(level_nr, 3), FONT_VALUE_1); - DrawPreviewLevel(TRUE); - { int text_height = getFontHeight(FONT_TEXT_3); - int xpos = getLevelRangeTextPos() * 32; - int ypos2 = -SY + 3 * 32 + 16; + int xpos = getLevelRangeTextPos() * 32 + 8; + int ypos2 = 3 * 32 + 16; int ypos1 = ypos2 - text_height; - DrawTextF(mSX + xpos, mSY + ypos1, FONT_TEXT_3, + DrawTextF(mSX - SX + xpos, mSY - SY + ypos1, FONT_TEXT_3, "%03d", leveldir_current->first_level); - DrawTextF(mSX + xpos, mSY + ypos2, FONT_TEXT_3, + DrawTextF(mSX - SX + xpos, mSY - SY + ypos2, FONT_TEXT_3, "%03d", leveldir_current->last_level); } @@ -411,7 +904,10 @@ void DrawMainMenuExt(int redraw_mask, boolean do_fading) initCursor(i, (i == 1 || i == 4 || i == 6 ? IMG_MENU_BUTTON_ENTER_MENU : IMG_MENU_BUTTON)); - DrawTextSCentered(326, FONT_TITLE_2, "A Game by Artsoft Entertainment"); + DrawTextSCentered(326, FONT_TITLE_2, PROGRAM_GAME_BY_STRING); +#endif + + DrawPreviewLevel(TRUE); HandleMainMenu(0, 0, 0, 0, MB_MENU_INITIALIZE); @@ -431,6 +927,8 @@ void DrawMainMenuExt(int redraw_mask, boolean do_fading) MapTapeButtons(); MapScreenMenuGadgets(SCREEN_MASK_MAIN); + DrawMaskedBorder(REDRAW_ALL); + if (do_fading) FadeIn(redraw_mask); else @@ -484,23 +982,37 @@ static void gotoTopLevelDir() void HandleTitleScreen(int mx, int my, int dx, int dy, int button) { + static unsigned long title_delay = 0; static int title_nr = 0; + static boolean showing_message = FALSE; + char *filename = getLevelSetMessageFilename(); boolean return_to_main_menu = FALSE; boolean use_fading_main_menu = TRUE; - boolean use_cross_fading = TRUE; + boolean use_cross_fading = !show_titlescreen_initial; /* default */ + boolean no_title_info = (graphic_info[IMG_TITLESCREEN_1].bitmap == NULL && + filename == NULL); if (button == MB_MENU_INITIALIZE) { int last_game_status = game_status; /* save current game status */ + + title_delay = 0; title_nr = 0; + showing_message = FALSE; + + if (show_titlescreen_initial && + graphic_info[IMG_TITLESCREEN_INITIAL_1].bitmap == NULL) + show_titlescreen_initial = FALSE; if (game_status == GAME_MODE_INFO) { - if (graphic_info[IMG_TITLESCREEN_1].bitmap == NULL) + if (no_title_info) { DrawInfoScreen_NotAvailable("Title screen information:", "No title screen for this level set."); + title.auto_delay_final = -1; + return; } @@ -517,35 +1029,73 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) game_status = last_game_status; /* restore current game status */ - DrawTitleScreenImage(title_nr); + if (graphic_info[getTitleScreenGraphic()].bitmap != NULL) + { + DrawTitleScreenImage(title_nr); + } + else + { + DrawTitleScreenMessage(filename); + + showing_message = TRUE; + + title.fade_delay_final = title.fade_delay; + title.post_delay_final = title.post_delay; + title.auto_delay_final = -1; + } FadeIn(REDRAW_ALL); + DelayReached(&title_delay, 0); /* reset delay counter */ + return; } - else if (button == MB_MENU_LEAVE) + + if (title.auto_delay_final > -1 && + DelayReached(&title_delay, title.auto_delay_final)) + button = MB_MENU_CHOICE; + + if (button == MB_MENU_LEAVE) { return_to_main_menu = TRUE; use_fading_main_menu = FALSE; } else if (button == MB_MENU_CHOICE) { - if (game_status == GAME_MODE_INFO && - graphic_info[IMG_TITLESCREEN_1].bitmap == NULL) + int anim_mode; + + if (game_status == GAME_MODE_INFO && no_title_info) { + FadeOut(REDRAW_FIELD); + info_mode = INFO_MODE_MAIN; - DrawInfoScreen(); + DrawAndFadeInInfoScreen(REDRAW_FIELD); return; } title_nr++; + if (show_titlescreen_initial && + (title_nr >= MAX_NUM_TITLE_SCREENS || + graphic_info[IMG_TITLESCREEN_INITIAL_1 + title_nr].bitmap == NULL)) + { + show_titlescreen_initial = FALSE; + + title_nr = 0; /* restart with title screens for current level set */ + } + + anim_mode = graphic_info[getTitleScreenGraphic() + title_nr].anim_mode; + + use_cross_fading = (anim_mode == ANIM_FADE ? FALSE : + anim_mode == ANIM_CROSSFADE ? TRUE : + use_cross_fading); + if (!use_cross_fading) FadeOut(REDRAW_ALL); if (title_nr < MAX_NUM_TITLE_SCREENS && - graphic_info[IMG_TITLESCREEN_1 + title_nr].bitmap != NULL) + graphic_info[getTitleScreenGraphic() + title_nr].bitmap != NULL) { if (use_cross_fading) FadeCrossSaveBackbuffer(); @@ -556,6 +1106,24 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) FadeCross(REDRAW_ALL); else FadeIn(REDRAW_ALL); + + DelayReached(&title_delay, 0); /* reset delay counter */ + } + else if (!showing_message && filename != NULL) + { + if (use_cross_fading) + FadeCrossSaveBackbuffer(); + + DrawTitleScreenMessage(filename); + + if (use_cross_fading) + FadeCross(REDRAW_ALL); + else + FadeIn(REDRAW_ALL); + + DelayReached(&title_delay, 0); /* reset delay counter */ + + showing_message = TRUE; } else { @@ -569,6 +1137,8 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) if (return_to_main_menu) { + show_titlescreen_initial = FALSE; + RedrawBackground(); if (game_status == GAME_MODE_INFO) @@ -576,7 +1146,7 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) OpenDoor(DOOR_CLOSE_1 | DOOR_CLOSE_2 | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); info_mode = INFO_MODE_MAIN; - DrawInfoScreenExt(use_fading_main_menu); + DrawInfoScreenExt(REDRAW_ALL, use_fading_main_menu); } else /* default: return to main menu */ { @@ -614,23 +1184,170 @@ void HandleMainMenu_SelectLevel(int step, int direction) if (new_level_nr != old_level_nr) { + struct MainControlInfo *mci= getMainControlInfo(MAIN_CONTROL_CURRENT_LEVEL); + + PlaySound(SND_MENU_ITEM_SELECTING); + level_nr = new_level_nr; +#if 1 + DrawText(mSX + mci->pos_text->x, mSY + mci->pos_text->y, + int2str(level_nr, 3), mci->font_text); +#else DrawText(mSX + 11 * 32, mSY + 3 * 32, int2str(level_nr, 3), FONT_VALUE_1); +#endif LoadLevel(level_nr); DrawPreviewLevel(TRUE); - TapeErase(); - LoadTape(level_nr); - DrawCompleteVideoDisplay(); + TapeErase(); + LoadTape(level_nr); + DrawCompleteVideoDisplay(); + + /* needed because DrawPreviewLevel() takes some time */ + BackToFront(); + SyncDisplay(); + } +} + +#if 1 + +void HandleMainMenu(int mx, int my, int dx, int dy, int button) +{ + static int choice = MAIN_CONTROL_GAME; + int pos = choice; + int i; + + if (button == MB_MENU_INITIALIZE) + { + DrawCursorAndText_Main(choice, TRUE); + + return; + } + + if (mx || my) /* mouse input */ + { + pos = -1; + + for (i = 0; main_controls[i].nr != -1; i++) + { + if (insideMenuPosRect(main_controls[i].pos_button, mx - mSX, my - mSY) || + insideMenuPosRect(main_controls[i].pos_text, mx - mSX, my - mSY) || + insideMenuPosRect(main_controls[i].pos_input, mx - mSX, my - mSY)) + { + pos = main_controls[i].nr; + + break; + } + } + } + else if (dx || dy) /* keyboard input */ + { + if (dx > 0 && (choice == MAIN_CONTROL_INFO || + choice == MAIN_CONTROL_SETUP)) + button = MB_MENU_CHOICE; + else if (dy) + pos = choice + dy; + } + + if (pos == MAIN_CONTROL_LEVELS && dx != 0 && button) + { + HandleMainMenu_SelectLevel(1, dx < 0 ? -1 : +1); + } + else if (pos >= MAIN_CONTROL_NAME && pos <= MAIN_CONTROL_QUIT) + { + if (button) + { + if (pos != choice) + { + PlaySound(SND_MENU_ITEM_ACTIVATING); + + DrawCursorAndText_Main(choice, FALSE); + DrawCursorAndText_Main(pos, TRUE); + + choice = pos; + } + } + else + { + PlaySound(SND_MENU_ITEM_SELECTING); + + if (pos == MAIN_CONTROL_NAME) + { + game_status = GAME_MODE_PSEUDO_TYPENAME; + + HandleTypeName(strlen(setup.player_name), 0); + } + else if (pos == MAIN_CONTROL_LEVELS) + { + if (leveldir_first) + { + game_status = GAME_MODE_LEVELS; + + SaveLevelSetup_LastSeries(); + SaveLevelSetup_SeriesInfo(); + +#if 0 + gotoTopLevelDir(); +#endif + + DrawChooseLevel(); + } + } + else if (pos == MAIN_CONTROL_SCORES) + { + game_status = GAME_MODE_SCORES; + + DrawHallOfFame(-1); + } + else if (pos == MAIN_CONTROL_EDITOR) + { + if (leveldir_current->readonly && + !strEqual(setup.player_name, "Artsoft")) + Request("This level is read only !", REQ_CONFIRM); + + game_status = GAME_MODE_EDITOR; + + DrawLevelEd(); + } + else if (pos == MAIN_CONTROL_INFO) + { + game_status = GAME_MODE_INFO; + info_mode = INFO_MODE_MAIN; + + DrawInfoScreen(); + } + else if (pos == MAIN_CONTROL_GAME) + { + StartGameActions(options.network, setup.autorecord, NEW_RANDOMIZE); + } + else if (pos == MAIN_CONTROL_SETUP) + { + game_status = GAME_MODE_SETUP; + setup_mode = SETUP_MODE_MAIN; + + DrawSetupScreen(); + } + else if (pos == MAIN_CONTROL_QUIT) + { + SaveLevelSetup_LastSeries(); + SaveLevelSetup_SeriesInfo(); + + if (Request("Do you really want to quit ?", REQ_ASK | REQ_STAY_CLOSED)) + game_status = GAME_MODE_QUIT; + } + } + } - /* needed because DrawPreviewLevel() takes some time */ - BackToFront(); - SyncDisplay(); + if (game_status == GAME_MODE_MAIN) + { + DrawPreviewLevel(FALSE); + DoAnimation(); } } +#else + void HandleMainMenu(int mx, int my, int dx, int dy, int button) { static int choice = 5; @@ -639,7 +1356,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) if (button == MB_MENU_INITIALIZE) { - drawCursor(choice, FC_RED); + drawCursor(choice, TRUE); + return; } @@ -672,8 +1390,9 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) { if (y != choice) { - drawCursor(y, FC_RED); - drawCursor(choice, FC_BLUE); + drawCursor(choice, FALSE); + drawCursor(y, TRUE); + choice = y; } } @@ -747,6 +1466,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } } +#endif + /* ========================================================================= */ /* info screen functions */ @@ -811,7 +1532,22 @@ static struct TokenInfo info_info_main[] = { 0, NULL, NULL } }; -static void DrawInfoScreen_Main(boolean do_fading) +static void DrawCursorAndText_Info(int pos, boolean active) +{ + int xpos = MENU_SCREEN_START_XPOS; + int ypos = MENU_SCREEN_START_YPOS + pos; + int font_nr = FONT_MENU_1; + + if (active) + font_nr = FONT_ACTIVE(font_nr); + + DrawText(mSX + xpos * 32, mSY + ypos * 32, info_info[pos].text, font_nr); + + if (info_info[pos].type & ~TYPE_SKIP_ENTRY) + drawCursor(pos, active); +} + +static void DrawInfoScreen_Main(int redraw_mask, boolean do_fading) { int i; @@ -827,11 +1563,11 @@ static void DrawInfoScreen_Main(boolean do_fading) for (i = 0; info_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++) { +#if 0 int xpos = MENU_SCREEN_START_XPOS; int ypos = MENU_SCREEN_START_YPOS + i; int font_nr = FONT_MENU_1; - - DrawText(mSX + xpos * 32, mSY + ypos * 32, info_info[i].text, font_nr); +#endif if (info_info[i].type & (TYPE_ENTER_MENU|TYPE_ENTER_LIST)) initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); @@ -840,6 +1576,12 @@ static void DrawInfoScreen_Main(boolean do_fading) else if (info_info[i].type & ~TYPE_SKIP_ENTRY) initCursor(i, IMG_MENU_BUTTON); +#if 1 + DrawCursorAndText_Info(i, FALSE); +#else + DrawText(mSX + xpos * 32, mSY + ypos * 32, info_info[i].text, font_nr); +#endif + num_info_info++; } @@ -848,8 +1590,10 @@ static void DrawInfoScreen_Main(boolean do_fading) PlayMenuSound(); PlayMenuMusic(); + DrawMaskedBorder(REDRAW_ALL); + if (do_fading) - FadeIn(REDRAW_ALL); + FadeIn(redraw_mask); else BackToFront(); @@ -871,7 +1615,12 @@ void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button) choice++; choice_store[info_mode] = choice; - drawCursor(choice, FC_RED); +#if 1 + DrawCursorAndText_Info(choice, TRUE); +#else + drawCursor(choice, TRUE); +#endif + return; } else if (button == MB_MENU_LEAVE) @@ -883,6 +1632,7 @@ void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button) void (*menu_callback_function)(void) = info_info[y].value; menu_callback_function(); + break; /* absolutely needed because function changes 'info_info'! */ } } @@ -922,13 +1672,23 @@ void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button) { if (y != choice) { - drawCursor(y, FC_RED); - drawCursor(choice, FC_BLUE); + PlaySound(SND_MENU_ITEM_ACTIVATING); + +#if 1 + DrawCursorAndText_Info(choice, FALSE); + DrawCursorAndText_Info(y, TRUE); +#else + drawCursor(choice, FALSE); + drawCursor(y, TRUE); +#endif + choice = choice_store[info_mode] = y; } } else if (!(info_info[y].type & TYPE_GHOSTED)) { + PlaySound(SND_MENU_ITEM_SELECTING); + if (info_info[y].type & TYPE_ENTER_OR_LEAVE) { void (*menu_callback_function)(void) = info_info[choice].value; @@ -941,20 +1701,24 @@ void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button) void DrawInfoScreen_NotAvailable(char *text_title, char *text_error) { - int ystart = 150; + int ystart1 = 100; + int ystart2 = 150; int ybottom = SYSIZE - 20; SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_LEVELSET); + FadeOut(REDRAW_FIELD); + ClearWindow(); DrawHeadline(); - DrawTextSCentered(100, FONT_TEXT_1, text_title); + DrawTextSCentered(ystart1, FONT_TEXT_1, text_title); + DrawTextSCentered(ystart2, FONT_TEXT_2, text_error); DrawTextSCentered(ybottom, FONT_TEXT_4, "Press any key or button for info menu"); - DrawTextSCentered(ystart, FONT_TEXT_2, text_error); + FadeIn(REDRAW_FIELD); } void DrawInfoScreen_HelpAnim(int start, int max_anims, boolean init) @@ -1131,12 +1895,15 @@ void DrawInfoScreen_Elements() { SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_ELEMENTS); + FadeOut(REDRAW_FIELD); + LoadHelpAnimInfo(); LoadHelpTextInfo(); HandleInfoScreen_Elements(MB_MENU_INITIALIZE); - FadeToFront(); + FadeIn(REDRAW_FIELD); + InitAnimation(); } @@ -1147,7 +1914,6 @@ void HandleInfoScreen_Elements(int button) static int num_pages; static int page; int anims_per_page = MAX_INFO_ELEMENTS_ON_SCREEN; - int button_released = !button; int i; if (button == MB_MENU_INITIALIZE) @@ -1155,6 +1921,7 @@ void HandleInfoScreen_Elements(int button) boolean new_element = TRUE; num_anims = 0; + for (i = 0; helpanim_info[i].element != HELPANIM_LIST_END; i++) { if (helpanim_info[i].element == HELPANIM_LIST_NEXT) @@ -1169,30 +1936,43 @@ void HandleInfoScreen_Elements(int button) num_pages = (num_anims + anims_per_page - 1) / anims_per_page; page = 0; } - else if (button == MB_MENU_LEAVE) + + if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + info_mode = INFO_MODE_MAIN; DrawInfoScreen(); return; } - - if (button_released || button == MB_MENU_INITIALIZE) + else if (button == MB_MENU_CHOICE || button == MB_MENU_INITIALIZE) { if (button != MB_MENU_INITIALIZE) + { + PlaySound(SND_MENU_ITEM_SELECTING); + page++; + } if (page >= num_pages) { FadeSoundsAndMusic(); + FadeOut(REDRAW_FIELD); info_mode = INFO_MODE_MAIN; - DrawInfoScreen(); + DrawAndFadeInInfoScreen(REDRAW_FIELD); return; } + if (button != MB_MENU_INITIALIZE) + FadeCrossSaveBackbuffer(); + DrawInfoScreen_HelpAnim(page * anims_per_page, num_anims, TRUE); + + if (button != MB_MENU_INITIALIZE) + FadeCross(REDRAW_FIELD); } else { @@ -1208,12 +1988,16 @@ void DrawInfoScreen_Music() { SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_MUSIC); + FadeOut(REDRAW_FIELD); + ClearWindow(); DrawHeadline(); LoadMusicInfo(); HandleInfoScreen_Music(MB_MENU_INITIALIZE); + + FadeIn(REDRAW_FIELD); } void HandleInfoScreen_Music(int button) @@ -1221,7 +2005,6 @@ void HandleInfoScreen_Music(int button) static struct MusicFileInfo *list = NULL; int ystart = 150, dy = 30; int ybottom = SYSIZE - 20; - int button_released = !button; if (button == MB_MENU_INITIALIZE) { @@ -1242,26 +2025,37 @@ void HandleInfoScreen_Music(int button) return; } } - else if (button == MB_MENU_LEAVE) + + if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + + FadeSoundsAndMusic(); + info_mode = INFO_MODE_MAIN; DrawInfoScreen(); return; } - - if (button_released || button == MB_MENU_INITIALIZE) + else if (button == MB_MENU_CHOICE || button == MB_MENU_INITIALIZE) { int y = 0; if (button != MB_MENU_INITIALIZE) + { + PlaySound(SND_MENU_ITEM_SELECTING); + if (list != NULL) list = list->next; + } if (list == NULL) { + FadeSoundsAndMusic(); + FadeOut(REDRAW_FIELD); + info_mode = INFO_MODE_MAIN; - DrawInfoScreen(); + DrawAndFadeInInfoScreen(REDRAW_FIELD); return; } @@ -1346,6 +2140,9 @@ static boolean DrawInfoScreen_CreditsScreen(int screen_nr) int ystart = 150, ystep = 30; int ybottom = SYSIZE - 20; + if (screen_nr > 8) + return FALSE; + ClearWindow(); DrawHeadline(); @@ -1500,10 +2297,12 @@ static boolean DrawInfoScreen_CreditsScreen(int screen_nr) DrawTextSCentered(ystart + 4 * ystep, FONT_TEXT_3, "since 1995"); } +#if 0 else { return FALSE; } +#endif DrawTextSCentered(ybottom, FONT_TEXT_4, "Press any key or button for next page"); @@ -1517,7 +2316,11 @@ void DrawInfoScreen_Credits() FadeSoundsAndMusic(); + FadeOut(REDRAW_FIELD); + HandleInfoScreen_Credits(MB_MENU_INITIALIZE); + + FadeIn(REDRAW_FIELD); } void HandleInfoScreen_Credits(int button) @@ -1532,6 +2335,8 @@ void HandleInfoScreen_Credits(int button) } else if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -1541,6 +2346,8 @@ void HandleInfoScreen_Credits(int button) { boolean show_screen; + PlaySound(SND_MENU_ITEM_SELECTING); + screen_nr++; FadeCrossSaveBackbuffer(); @@ -1554,9 +2361,10 @@ void HandleInfoScreen_Credits(int button) else { FadeSoundsAndMusic(); + FadeOut(REDRAW_FIELD); info_mode = INFO_MODE_MAIN; - DrawInfoScreen(); + DrawAndFadeInInfoScreen(REDRAW_FIELD); } } else @@ -1572,6 +2380,8 @@ void DrawInfoScreen_Program() SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_PROGRAM); + FadeOut(REDRAW_FIELD); + ClearWindow(); DrawHeadline(); @@ -1606,26 +2416,30 @@ void DrawInfoScreen_Program() DrawTextSCentered(ybottom, FONT_TEXT_4, "Press any key or button for info menu"); + + FadeIn(REDRAW_FIELD); } void HandleInfoScreen_Program(int button) { - int button_released = !button; - if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + info_mode = INFO_MODE_MAIN; DrawInfoScreen(); return; } - - if (button_released) + else if (button == MB_MENU_CHOICE) { + PlaySound(SND_MENU_ITEM_SELECTING); + FadeSoundsAndMusic(); + FadeOut(REDRAW_FIELD); info_mode = INFO_MODE_MAIN; - DrawInfoScreen(); + DrawAndFadeInInfoScreen(REDRAW_FIELD); } else { @@ -1650,6 +2464,8 @@ void DrawInfoScreen_LevelSet() SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_LEVELSET); + FadeOut(REDRAW_FIELD); + ClearWindow(); DrawHeadline(); @@ -1660,30 +2476,34 @@ void DrawInfoScreen_LevelSet() if (filename != NULL) DrawTextFromFile(sx, sy, filename, font_nr, max_chars_per_line, - max_lines_per_screen); + max_lines_per_screen, TRUE); else DrawTextSCentered(ystart, FONT_TEXT_2, "No information for this level set."); + + FadeIn(REDRAW_FIELD); } void HandleInfoScreen_LevelSet(int button) { - int button_released = !button; - if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + info_mode = INFO_MODE_MAIN; DrawInfoScreen(); return; } - - if (button_released) + else if (button == MB_MENU_CHOICE) { + PlaySound(SND_MENU_ITEM_SELECTING); + FadeSoundsAndMusic(); + FadeOut(REDRAW_FIELD); info_mode = INFO_MODE_MAIN; - DrawInfoScreen(); + DrawAndFadeInInfoScreen(REDRAW_FIELD); } else { @@ -1691,7 +2511,7 @@ void HandleInfoScreen_LevelSet(int button) } } -static void DrawInfoScreenExt(boolean do_fading) +static void DrawInfoScreenExt(int redraw_mask, boolean do_fading) { SetMainBackgroundImage(IMG_BACKGROUND_INFO); @@ -1708,7 +2528,7 @@ static void DrawInfoScreenExt(boolean do_fading) else if (info_mode == INFO_MODE_LEVELSET) DrawInfoScreen_LevelSet(); else - DrawInfoScreen_Main(do_fading); + DrawInfoScreen_Main(redraw_mask, do_fading); if (info_mode != INFO_MODE_MAIN && info_mode != INFO_MODE_TITLE && @@ -1719,9 +2539,14 @@ static void DrawInfoScreenExt(boolean do_fading) } } +void DrawAndFadeInInfoScreen(int redraw_mask) +{ + DrawInfoScreenExt(redraw_mask, TRUE); +} + void DrawInfoScreen() { - DrawInfoScreenExt(0); + DrawInfoScreenExt(REDRAW_ALL, FALSE); } void HandleInfoScreen(int mx, int my, int dx, int dy, int button) @@ -1751,18 +2576,37 @@ void HandleInfoScreen(int mx, int my, int dx, int dy, int button) void HandleTypeName(int newxpos, Key key) { + struct MainControlInfo *mci = getMainControlInfo(MAIN_CONTROL_NAME); +#if 1 + struct MenuPosInfo *pos = mci->pos_input; + int startx = mSX + ALIGNED_XPOS(pos->x, pos->width, pos->align); + int starty = mSY + pos->y; +#endif +#if 1 + static int xpos = 0; +#else static int xpos = 0, ypos = 2; - int font_width = getFontWidth(FONT_INPUT_1_ACTIVE); +#endif + int font_nr = mci->font_input; + int font_active_nr = FONT_ACTIVE(font_nr); + int font_width = getFontWidth(font_active_nr); +#if 1 +#if 0 + int startx = mSX + mci->pos_input->x; + int starty = mSY + mci->pos_input->y; +#endif +#else int name_width = getFontWidth(FONT_MENU_1) * strlen("Name:"); int startx = mSX + 32 + name_width; int starty = mSY + ypos * 32; +#endif if (newxpos) { xpos = newxpos; - DrawText(startx, starty, setup.player_name, FONT_INPUT_1_ACTIVE); - DrawText(startx + xpos * font_width, starty, "_", FONT_INPUT_1_ACTIVE); + DrawText(startx, starty, setup.player_name, font_active_nr); + DrawText(startx + xpos * font_width, starty, "_", font_active_nr); return; } @@ -1780,24 +2624,27 @@ void HandleTypeName(int newxpos, Key key) setup.player_name[xpos] = ascii; setup.player_name[xpos + 1] = 0; + xpos++; - DrawText(startx, starty, setup.player_name, FONT_INPUT_1_ACTIVE); - DrawText(startx + xpos * font_width, starty, "_", FONT_INPUT_1_ACTIVE); + DrawText(startx, starty, setup.player_name, font_active_nr); + DrawText(startx + xpos * font_width, starty, "_", font_active_nr); } else if ((key == KSYM_Delete || key == KSYM_BackSpace) && xpos > 0) { xpos--; + setup.player_name[xpos] = 0; - DrawText(startx + xpos * font_width, starty, "_ ", FONT_INPUT_1_ACTIVE); + DrawText(startx + xpos * font_width, starty, "_ ", font_active_nr); } else if (key == KSYM_Return && xpos > 0) { - DrawText(startx, starty, setup.player_name, FONT_INPUT_1); - DrawText(startx + xpos * font_width, starty, " ", FONT_INPUT_1_ACTIVE); + DrawText(startx, starty, setup.player_name, font_nr); + DrawText(startx + xpos * font_width, starty, " ", font_active_nr); SaveSetup(); + game_status = GAME_MODE_MAIN; } } @@ -1860,10 +2707,17 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, /* force LEVELS font on artwork setup screen */ game_status = GAME_MODE_LEVELS; +#if 1 + /* clear tree list area, but not title or scrollbar */ + DrawBackground(mSX, mSY + MENU_SCREEN_START_YPOS * 32, + SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset, + NUM_MENU_ENTRIES_ON_SCREEN * 32); +#else /* clear tree list area, but not title or scrollbar */ DrawBackground(mSX, mSY + MENU_SCREEN_START_YPOS * 32, SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset, MAX_MENU_ENTRIES_ON_SCREEN * 32); +#endif for (i = 0; i < num_page_entries; i++) { @@ -1907,6 +2761,7 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) TreeInfo *node, *node_first; int x, last_redraw_mask = redraw_mask; int ypos = MENU_TITLE2_YPOS; + int font_nr = FONT_TITLE_2; if (ti->type != TREE_TYPE_LEVEL_DIR) return; @@ -1914,16 +2769,16 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) node_first = getTreeInfoFirstGroupEntry(ti); node = getTreeInfoFromPos(node_first, entry_pos); - DrawBackground(SX, SY + ypos, SXSIZE, getFontHeight(FONT_TITLE_2)); + DrawBackgroundForFont(SX, SY + ypos, SXSIZE, getFontHeight(font_nr), font_nr); if (node->parent_link) - DrawTextFCentered(ypos, FONT_TITLE_2, "leave group \"%s\"", + DrawTextFCentered(ypos, font_nr, "leave group \"%s\"", node->class_desc); else if (node->level_group) - DrawTextFCentered(ypos, FONT_TITLE_2, "enter group \"%s\"", + DrawTextFCentered(ypos, font_nr, "enter group \"%s\"", node->class_desc); else if (ti->type == TREE_TYPE_LEVEL_DIR) - DrawTextFCentered(ypos, FONT_TITLE_2, "%3d levels (%s)", + DrawTextFCentered(ypos, font_nr, "%3d levels (%s)", node->levels, node->class_desc); /* let BackToFront() redraw only what is needed */ @@ -1982,12 +2837,14 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, drawChooseTreeList(ti->cl_first, num_page_entries, ti); drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti); - drawChooseTreeCursor(ti->cl_cursor, FC_RED); + drawChooseTreeCursor(ti->cl_cursor, TRUE); return; } else if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + if (ti->node_parent) { *ti_ptr = ti->node_parent; @@ -2050,7 +2907,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, drawChooseTreeList(ti->cl_first, num_page_entries, ti); drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti); - drawChooseTreeCursor(ti->cl_cursor, FC_RED); + drawChooseTreeCursor(ti->cl_cursor, TRUE); + AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL, ti->cl_first, ti); } @@ -2064,7 +2922,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, drawChooseTreeList(ti->cl_first, num_page_entries, ti); drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti); - drawChooseTreeCursor(ti->cl_cursor, FC_RED); + drawChooseTreeCursor(ti->cl_cursor, TRUE); + AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL, ti->cl_first, ti); } @@ -2086,6 +2945,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, if (node_cursor->node_group) { + PlaySound(SND_MENU_ITEM_SELECTING); + node_cursor->cl_first = ti->cl_first; node_cursor->cl_cursor = ti->cl_cursor; *ti_ptr = node_cursor->node_group; @@ -2096,6 +2957,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, } else if (dx == -1 && ti->node_parent) { + PlaySound(SND_MENU_ITEM_SELECTING); + *ti_ptr = ti->node_parent; DrawChooseTree(ti_ptr); @@ -2111,9 +2974,12 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, { if (y != ti->cl_cursor) { - drawChooseTreeCursor(y, FC_RED); - drawChooseTreeCursor(ti->cl_cursor, FC_BLUE); + PlaySound(SND_MENU_ITEM_ACTIVATING); + + drawChooseTreeCursor(ti->cl_cursor, FALSE); + drawChooseTreeCursor(y, TRUE); drawChooseTreeInfo(ti->cl_first + y, ti); + ti->cl_cursor = y; } } @@ -2122,6 +2988,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, TreeInfo *node_first, *node_cursor; int entry_pos = ti->cl_first + y; + PlaySound(SND_MENU_ITEM_SELECTING); + node_first = getTreeInfoFirstGroupEntry(ti); node_cursor = getTreeInfoFromPos(node_first, entry_pos); @@ -2190,6 +3058,15 @@ void DrawHallOfFame(int highlight_position) { UnmapAllGadgets(); FadeSoundsAndMusic(); + + /* (this is needed when called from GameEnd() after winning a game) */ + KeyboardAutoRepeatOn(); + ActivateJoystick(); + + /* (this is needed when called from GameEnd() after winning a game) */ + SetDrawDeactivationMask(REDRAW_NONE); + SetDrawBackgroundMask(REDRAW_FIELD); + CloseDoor(DOOR_CLOSE_2); if (highlight_position < 0) @@ -2286,6 +3163,8 @@ void HandleHallOfFame(int mx, int my, int dx, int dy, int button) } else if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + FadeSound(SND_BACKGROUND_SCORES); game_status = GAME_MODE_MAIN; @@ -2294,6 +3173,8 @@ void HandleHallOfFame(int mx, int my, int dx, int dy, int button) } else if (button == MB_MENU_CHOICE) { + PlaySound(SND_MENU_ITEM_SELECTING); + FadeSound(SND_BACKGROUND_SCORES); FadeOut(REDRAW_FIELD); @@ -2603,6 +3484,26 @@ static struct TokenInfo setup_info_artwork[] = { 0, NULL, NULL } }; +static struct TokenInfo setup_info_input[] = +{ + { TYPE_SWITCH, NULL, "Player:" }, + { TYPE_SWITCH, NULL, "Device:" }, + { TYPE_ENTER_MENU, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_LEAVE_MENU, execSetupMain, "Back" }, + + { 0, NULL, NULL } +}; + static struct TokenInfo setup_info_shortcut_1[] = { { TYPE_KEYTEXT, NULL, "Quick Save Game to Tape:", }, @@ -2651,7 +3552,7 @@ static Key getSetupKey() NextEvent(&event); - switch(event.type) + switch (event.type) { case EVENT_KEYPRESS: { @@ -2819,6 +3720,24 @@ static void changeSetupValue(int pos) drawSetupValue(pos); } +static void DrawCursorAndText_Setup(int pos, boolean active) +{ + int xpos = MENU_SCREEN_START_XPOS; + int ypos = MENU_SCREEN_START_YPOS + pos; + int font_nr = getSetupTextFont(setup_info[pos].type); + + if (setup_info == setup_info_input) + font_nr = FONT_MENU_1; + + if (active) + font_nr = FONT_ACTIVE(font_nr); + + DrawText(mSX + xpos * 32, mSY + ypos * 32, setup_info[pos].text, font_nr); + + if (setup_info[pos].type & ~TYPE_SKIP_ENTRY) + drawCursor(pos, active); +} + static void DrawSetupScreen_Generic() { char *title_string = NULL; @@ -2876,9 +3795,12 @@ static void DrawSetupScreen_Generic() for (i = 0; setup_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++) { void *value_ptr = setup_info[i].value; +#if 1 +#else int xpos = MENU_SCREEN_START_XPOS; int ypos = MENU_SCREEN_START_YPOS + i; int font_nr; +#endif /* set some entries to "unchangeable" according to other variables */ if ((value_ptr == &setup.sound_simple && !audio.sound_available) || @@ -2888,10 +3810,6 @@ static void DrawSetupScreen_Generic() (value_ptr == &screen_mode_text && !video.fullscreen_available)) setup_info[i].type |= TYPE_GHOSTED; - font_nr = getSetupTextFont(setup_info[i].type); - - DrawText(mSX + xpos * 32, mSY + ypos * 32, setup_info[i].text, font_nr); - if (setup_info[i].type & (TYPE_ENTER_MENU|TYPE_ENTER_LIST)) initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); else if (setup_info[i].type & (TYPE_LEAVE_MENU|TYPE_LEAVE_LIST)) @@ -2899,6 +3817,14 @@ static void DrawSetupScreen_Generic() else if (setup_info[i].type & ~TYPE_SKIP_ENTRY) initCursor(i, IMG_MENU_BUTTON); +#if 1 + DrawCursorAndText_Setup(i, FALSE); +#else + font_nr = getSetupTextFont(setup_info[i].type); + + DrawText(mSX + xpos * 32, mSY + ypos * 32, setup_info[i].text, font_nr); +#endif + if (setup_info[i].type & TYPE_VALUE) drawSetupValue(i); @@ -2930,12 +3856,18 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button) choice++; choice_store[setup_mode] = choice; - drawCursor(choice, FC_RED); +#if 1 + DrawCursorAndText_Setup(choice, TRUE); +#else + drawCursor(choice, TRUE); +#endif return; } else if (button == MB_MENU_LEAVE) { + PlaySound(SND_MENU_ITEM_SELECTING); + for (y = 0; y < num_setup_info; y++) { if (setup_info[y].type & TYPE_LEAVE_MENU) @@ -2981,13 +3913,23 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button) { if (y != choice && setup_info[y].type & ~TYPE_SKIP_ENTRY) { - drawCursor(y, FC_RED); - drawCursor(choice, FC_BLUE); + PlaySound(SND_MENU_ITEM_ACTIVATING); + +#if 1 + DrawCursorAndText_Setup(choice, FALSE); + DrawCursorAndText_Setup(y, TRUE); +#else + drawCursor(choice, FALSE); + drawCursor(y, TRUE); +#endif + choice = choice_store[setup_mode] = y; } } else if (!(setup_info[y].type & TYPE_GHOSTED)) { + PlaySound(SND_MENU_ITEM_SELECTING); + /* when selecting key headline, execute function for key value change */ if (setup_info[y].type & TYPE_KEYTEXT && setup_info[y + 1].type & TYPE_KEY) @@ -3015,10 +3957,31 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button) void DrawSetupScreen_Input() { +#if 1 + int i; +#endif + ClearWindow(); +#if 1 + setup_info = setup_info_input; +#endif + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Setup Input"); +#if 1 + for (i = 0; setup_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++) + { + if (setup_info[i].type & (TYPE_ENTER_MENU|TYPE_ENTER_LIST)) + initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); + else if (setup_info[i].type & (TYPE_LEAVE_MENU|TYPE_LEAVE_LIST)) + initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU); + else if (setup_info[i].type & ~TYPE_SKIP_ENTRY) + initCursor(i, IMG_MENU_BUTTON); + + DrawCursorAndText_Setup(i, FALSE); + } +#else initCursor(0, IMG_MENU_BUTTON); initCursor(1, IMG_MENU_BUTTON); initCursor(2, IMG_MENU_BUTTON_ENTER_MENU); @@ -3027,6 +3990,7 @@ void DrawSetupScreen_Input() DrawText(mSX + 32, mSY + 2 * 32, "Player:", FONT_MENU_1); DrawText(mSX + 32, mSY + 3 * 32, "Device:", FONT_MENU_1); DrawText(mSX + 32, mSY + 15 * 32, "Back", FONT_MENU_1); +#endif #if 0 DeactivateJoystickForCalibration(); @@ -3069,7 +4033,7 @@ static void setJoystickDeviceToNr(char *device_name, int device_nr) strlen(device_name)); } -static void drawPlayerSetupInputInfo(int player_nr) +static void drawPlayerSetupInputInfo(int player_nr, boolean active) { int i; static struct SetupKeyboardInfo custom_key; @@ -3093,6 +4057,7 @@ static void drawPlayerSetupInputInfo(int player_nr) "Joystick3", "Joystick4" }; + int text_font_nr = (active ? FONT_MENU_1_ACTIVE : FONT_MENU_1); InitJoysticks(); @@ -3113,19 +4078,21 @@ static void drawPlayerSetupInputInfo(int player_nr) int font_nr = (joystick.fd[player_nr] < 0 ? FONT_VALUE_OLD : FONT_VALUE_1); DrawText(mSX + 8 * 32, mSY + 3 * 32, text, font_nr); - DrawText(mSX + 32, mSY + 4 * 32, "Calibrate", FONT_MENU_1); + DrawText(mSX + 32, mSY + 4 * 32, "Calibrate", text_font_nr); } else { DrawText(mSX + 8 * 32, mSY + 3 * 32, "Keyboard ", FONT_VALUE_1); - DrawText(mSX + 1 * 32, mSY + 4 * 32, "Customize", FONT_MENU_1); + DrawText(mSX + 1 * 32, mSY + 4 * 32, "Customize", text_font_nr); } DrawText(mSX + 32, mSY + 5 * 32, "Actual Settings:", FONT_MENU_1); + drawCursorXY(1, 4, IMG_MENU_BUTTON_LEFT); drawCursorXY(1, 5, IMG_MENU_BUTTON_RIGHT); drawCursorXY(1, 6, IMG_MENU_BUTTON_UP); drawCursorXY(1, 7, IMG_MENU_BUTTON_DOWN); + DrawText(mSX + 2 * 32, mSY + 6 * 32, ":", FONT_VALUE_OLD); DrawText(mSX + 2 * 32, mSY + 7 * 32, ":", FONT_VALUE_OLD); DrawText(mSX + 2 * 32, mSY + 8 * 32, ":", FONT_VALUE_OLD); @@ -3163,7 +4130,7 @@ void HandleSetupScreen_Input_Player(int step, int direction) { input_player_nr = new_player_nr; - drawPlayerSetupInputInfo(input_player_nr); + drawPlayerSetupInputInfo(input_player_nr, FALSE); } } @@ -3179,8 +4146,13 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button) if (button == MB_MENU_INITIALIZE) { - drawPlayerSetupInputInfo(input_player_nr); - drawCursor(choice, FC_RED); + drawPlayerSetupInputInfo(input_player_nr, (choice == 2)); + +#if 1 + DrawCursorAndText_Setup(choice, TRUE); +#else + drawCursor(choice, TRUE); +#endif return; } @@ -3225,8 +4197,16 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button) { if (y != choice) { - drawCursor(y, FC_RED); - drawCursor(choice, FC_BLUE); +#if 1 + DrawCursorAndText_Setup(choice, FALSE); + DrawCursorAndText_Setup(y, TRUE); + + drawPlayerSetupInputInfo(input_player_nr, (y == 2)); +#else + drawCursor(choice, FALSE); + drawCursor(y, TRUE); +#endif + choice = y; } } @@ -3254,7 +4234,7 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button) setJoystickDeviceToNr(device_name, new_device_nr); } - drawPlayerSetupInputInfo(input_player_nr); + drawPlayerSetupInputInfo(input_player_nr, FALSE); } else if (y == 2) { @@ -3323,7 +4303,7 @@ void CustomizeKeyboard(int player_nr) NextEvent(&event); - switch(event.type) + switch (event.type) { case EVENT_KEYPRESS: { @@ -3473,10 +4453,10 @@ static boolean CalibrateJoystickMain(int player_nr) NextEvent(&event); - switch(event.type) + switch (event.type) { case EVENT_KEYPRESS: - switch(GetEventKey((KeyEvent *)&event, TRUE)) + switch (GetEventKey((KeyEvent *)&event, TRUE)) { case KSYM_Return: if (check_remaining == 0) @@ -3641,6 +4621,12 @@ void DrawSetupScreen() PlayMenuMusic(); } +void RedrawSetupScreenAfterFullscreenToggle() +{ + if (setup_mode == SETUP_MODE_GRAPHICS) + DrawSetupScreen(); +} + void HandleSetupScreen(int mx, int my, int dx, int dy, int button) { if (setup_mode == SETUP_MODE_INPUT) @@ -3677,8 +4663,19 @@ static void getScreenMenuButtonPos(int *x, int *y, int gadget_id) { switch (gadget_id) { - case SCREEN_CTRL_ID_LAST_LEVEL: - *x = mSX + TILEX * getLastLevelButtonPos(); +#if 1 + case SCREEN_CTRL_ID_PREV_LEVEL: + *x = mSX + menu.main.button.prev_level.x; + *y = mSY + menu.main.button.prev_level.y; + break; + + case SCREEN_CTRL_ID_NEXT_LEVEL: + *x = mSX + menu.main.button.next_level.x; + *y = mSY + menu.main.button.next_level.y; + break; +#else + case SCREEN_CTRL_ID_PREV_LEVEL: + *x = mSX + TILEX * getPrevlevelButtonPos(); *y = mSY + TILEY * (MENU_SCREEN_START_YPOS + 1); break; @@ -3686,8 +4683,9 @@ static void getScreenMenuButtonPos(int *x, int *y, int gadget_id) *x = mSX + TILEX * getNextLevelButtonPos(); *y = mSY + TILEY * (MENU_SCREEN_START_YPOS + 1); break; +#endif - case SCREEN_CTRL_ID_LAST_PLAYER: + case SCREEN_CTRL_ID_PREV_PLAYER: *x = mSX + TILEX * 10; *y = mSY + TILEY * MENU_SCREEN_START_YPOS; break; @@ -3712,9 +4710,9 @@ static struct } menubutton_info[NUM_SCREEN_MENUBUTTONS] = { { - IMG_MENU_BUTTON_LAST_LEVEL, IMG_MENU_BUTTON_LAST_LEVEL_ACTIVE, + IMG_MENU_BUTTON_PREV_LEVEL, IMG_MENU_BUTTON_PREV_LEVEL_ACTIVE, getScreenMenuButtonPos, - SCREEN_CTRL_ID_LAST_LEVEL, + SCREEN_CTRL_ID_PREV_LEVEL, SCREEN_MASK_MAIN, "last level" }, @@ -3728,7 +4726,7 @@ static struct { IMG_MENU_BUTTON_LEFT, IMG_MENU_BUTTON_LEFT_ACTIVE, getScreenMenuButtonPos, - SCREEN_CTRL_ID_LAST_PLAYER, + SCREEN_CTRL_ID_PREV_PLAYER, SCREEN_MASK_INPUT, "last player" }, @@ -3962,10 +4960,17 @@ static void CreateScreenScrollbars() GDI_SCROLLBAR_ITEMS_MAX, items_max, GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible, GDI_SCROLLBAR_ITEM_POSITION, item_position, +#if 1 + GDI_WHEEL_AREA_X, SX, + GDI_WHEEL_AREA_Y, SY, + GDI_WHEEL_AREA_WIDTH, SXSIZE, + GDI_WHEEL_AREA_HEIGHT, SYSIZE, +#else GDI_WHEEL_AREA_X, 0, GDI_WHEEL_AREA_Y, 0, GDI_WHEEL_AREA_WIDTH, WIN_XSIZE, GDI_WHEEL_AREA_HEIGHT, WIN_YSIZE, +#endif GDI_STATE, GD_BUTTON_UNPRESSED, GDI_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1, gd_y1, GDI_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2, gd_y2, @@ -4069,7 +5074,7 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) switch (id) { - case SCREEN_CTRL_ID_LAST_LEVEL: + case SCREEN_CTRL_ID_PREV_LEVEL: HandleMainMenu_SelectLevel(step, -1); break; @@ -4077,7 +5082,7 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) HandleMainMenu_SelectLevel(step, +1); break; - case SCREEN_CTRL_ID_LAST_PLAYER: + case SCREEN_CTRL_ID_PREV_PLAYER: HandleSetupScreen_Input_Player(step, -1); break; diff --git a/src/screens.h b/src/screens.h index 6f8cb1fb..e08e1be4 100644 --- a/src/screens.h +++ b/src/screens.h @@ -21,11 +21,15 @@ #define SCROLL_PAGE (2 * SCR_FIELDY) +int effectiveGameStatus(); + void DrawMainMenuExt(int, boolean); void DrawAndFadeInMainMenu(int); void DrawMainMenu(void); void DrawHallOfFame(int); +void RedrawSetupScreenAfterFullscreenToggle(); + void HandleTitleScreen(int, int, int, int, int); void HandleMainMenu(int, int, int, int, int); void HandleChooseLevel(int, int, int, int, int); diff --git a/src/tape.c b/src/tape.c index eb03967a..1aaabf55 100644 --- a/src/tape.c +++ b/src/tape.c @@ -919,11 +919,14 @@ void TapeQuickSave() TapeHaltRecording(); /* prepare tape for saving on-the-fly */ if (TAPE_IS_EMPTY(tape)) + { Request("No tape that can be saved !", REQ_CONFIRM); - else - SaveTape(tape.level_nr); - SaveEngineSnapshot(); + return; + } + + if (SaveTapeChecked(tape.level_nr)) + SaveEngineSnapshot(); } void TapeQuickLoad() @@ -954,6 +957,8 @@ void TapeQuickLoad() LoadEngineSnapshot(); + DrawCompleteVideoDisplay(); + tape.playing = TRUE; tape.pausing = TRUE; @@ -1234,6 +1239,7 @@ void CreateTapeButtons() GDI_STATE, GD_BUTTON_UNPRESSED, GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y, GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y, + GDI_DIRECT_DRAW, FALSE, GDI_EVENT_MASK, GD_EVENT_RELEASED, GDI_CALLBACK_ACTION, HandleTapeButtons, GDI_END); @@ -1296,18 +1302,22 @@ static void HandleTapeButtons(struct GadgetInfo *gi) { case TAPE_CTRL_ID_EJECT: TapeStop(); + if (TAPE_IS_EMPTY(tape)) { LoadTape(level_nr); + if (TAPE_IS_EMPTY(tape)) Request("No tape for this level !", REQ_CONFIRM); } else { if (tape.changed) - SaveTape(tape.level_nr); + SaveTapeChecked(tape.level_nr); + TapeErase(); } + DrawCompleteVideoDisplay(); break; @@ -1325,6 +1335,7 @@ static void HandleTapeButtons(struct GadgetInfo *gi) } else if (tape.recording) TapeSingleStep(); + break; case TAPE_CTRL_ID_STOP: diff --git a/src/tools.c b/src/tools.c index 7a2fd3e2..c85d5924 100644 --- a/src/tools.c +++ b/src/tools.c @@ -19,6 +19,7 @@ #include "cartoons.h" #include "network.h" #include "tape.h" +#include "screens.h" /* select level set with EMC X11 graphics before activating EM GFX debugging */ @@ -194,6 +195,72 @@ void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height) BlitBitmap(drawto, window, x, y, width, height, x, y); } +void DrawMaskedBorder_Rect(int x, int y, int width, int height) +{ + Bitmap *bitmap = graphic_info[IMG_GLOBAL_BORDER].bitmap; + + SetClipOrigin(bitmap, bitmap->stored_clip_gc, 0, 0); + BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y); +} + +void DrawMaskedBorder_FIELD() +{ + if (game_status >= GAME_MODE_TITLE && + game_status <= GAME_MODE_PLAYING && + border.draw_masked[game_status]) + DrawMaskedBorder_Rect(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); +} + +void DrawMaskedBorder_DOOR_1() +{ + if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] && + (game_status != GAME_MODE_EDITOR || + border.draw_masked[GFX_SPECIAL_ARG_EDITOR])) + DrawMaskedBorder_Rect(DX, DY, DXSIZE, DYSIZE); +} + +void DrawMaskedBorder_DOOR_2() +{ + if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] && + game_status != GAME_MODE_EDITOR) + DrawMaskedBorder_Rect(VX, VY, VXSIZE, VYSIZE); +} + +void DrawMaskedBorder_DOOR_3() +{ + /* currently not available */ +} + +void DrawMaskedBorder_ALL() +{ + DrawMaskedBorder_FIELD(); + DrawMaskedBorder_DOOR_1(); + DrawMaskedBorder_DOOR_2(); + DrawMaskedBorder_DOOR_3(); +} + +void DrawMaskedBorder(int redraw_mask) +{ + /* do not draw masked screen borders when displaying title screens */ + if (effectiveGameStatus() == GAME_MODE_TITLE || + effectiveGameStatus() == GAME_MODE_MESSAGE) + return; + + if (redraw_mask & REDRAW_ALL) + DrawMaskedBorder_ALL(); + else + { + if (redraw_mask & REDRAW_FIELD) + DrawMaskedBorder_FIELD(); + if (redraw_mask & REDRAW_DOOR_1) + DrawMaskedBorder_DOOR_1(); + if (redraw_mask & REDRAW_DOOR_2) + DrawMaskedBorder_DOOR_2(); + if (redraw_mask & REDRAW_DOOR_3) + DrawMaskedBorder_DOOR_3(); + } +} + void BackToFront() { int x,y; @@ -211,6 +278,11 @@ void BackToFront() if (redraw_mask == REDRAW_NONE) return; + if (redraw_mask & REDRAW_TILES && + game_status == GAME_MODE_PLAYING && + border.draw_masked[GAME_MODE_PLAYING]) + redraw_mask |= REDRAW_FIELD; + if (global.fps_slowdown && game_status == GAME_MODE_PLAYING) { static boolean last_frame_skipped = FALSE; @@ -248,6 +320,14 @@ void BackToFront() SyncDisplay(); + /* prevent drawing masked border to backbuffer when using playfield buffer */ + if (game_status != GAME_MODE_PLAYING || + redraw_mask & REDRAW_FROM_BACKBUFFER || + buffer == backbuffer) + DrawMaskedBorder(redraw_mask); + else + DrawMaskedBorder(redraw_mask & REDRAW_DOORS); + if (redraw_mask & REDRAW_ALL) { BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); @@ -278,7 +358,23 @@ void BackToFront() ABS(ScreenMovPos) == ScrollStepSize || redraw_tiles > REDRAWTILES_THRESHOLD) { - BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY); + if (border.draw_masked[GAME_MODE_PLAYING]) + { + if (buffer != backbuffer) + { + /* copy playfield buffer to backbuffer to add masked border */ + BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY); + DrawMaskedBorder(REDRAW_FIELD); + } + + BlitBitmap(backbuffer, window, + REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, + REAL_SX, REAL_SY); + } + else + { + BlitBitmap(buffer, window, fx, fy, SXSIZE, SYSIZE, SX, SY); + } #if 0 #ifdef DEBUG @@ -426,10 +522,10 @@ void FadeToFront() void FadeExt(int fade_mask, int fade_mode) { + void (*draw_border_function)(void) = NULL; Bitmap *bitmap = (fade_mode == FADE_MODE_CROSSFADE ? bitmap_db_cross : NULL); - int fade_delay = menu.fade_delay; - int post_delay = (fade_mode == FADE_MODE_FADE_OUT ? menu.post_delay : 0); int x, y, width, height; + int fade_delay, post_delay; if (fade_mask & REDRAW_FIELD) { @@ -437,6 +533,11 @@ void FadeExt(int fade_mask, int fade_mode) y = REAL_SY; width = FULL_SXSIZE; height = FULL_SYSIZE; + + fade_delay = menu.fade_delay; + post_delay = (fade_mode == FADE_MODE_FADE_OUT ? menu.post_delay : 0); + + draw_border_function = DrawMaskedBorder_FIELD; } else /* REDRAW_ALL */ { @@ -444,6 +545,9 @@ void FadeExt(int fade_mask, int fade_mode) y = 0; width = WIN_XSIZE; height = WIN_YSIZE; + + fade_delay = title.fade_delay_final; + post_delay = (fade_mode == FADE_MODE_FADE_OUT ? title.post_delay_final : 0); } redraw_mask |= fade_mask; @@ -458,7 +562,8 @@ void FadeExt(int fade_mask, int fade_mode) return; } - FadeRectangle(bitmap, x, y, width, height, fade_mode, fade_delay, post_delay); + FadeRectangle(bitmap, x, y, width, height, fade_mode, fade_delay, post_delay, + draw_border_function); redraw_mask &= ~fade_mask; } @@ -483,10 +588,16 @@ void FadeCrossSaveBackbuffer() BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); } +void SetWindowBackgroundImageIfDefined(int graphic) +{ + if (graphic_info[graphic].bitmap) + SetWindowBackgroundBitmap(graphic_info[graphic].bitmap); +} + void SetMainBackgroundImageIfDefined(int graphic) { if (graphic_info[graphic].bitmap) - SetMainBackgroundImage(graphic); + SetMainBackgroundBitmap(graphic_info[graphic].bitmap); } void SetMainBackgroundImage(int graphic) @@ -513,21 +624,46 @@ void SetPanelBackground() SetDoorBackgroundBitmap(bitmap_db_panel); } -void DrawBackground(int dst_x, int dst_y, int width, int height) +void DrawBackground(int x, int y, int width, int height) { -#if 1 - ClearRectangleOnBackground(drawto, dst_x, dst_y, width, height); + /* !!! "drawto" might still point to playfield buffer here (see below) !!! */ + /* (when entering hall of fame after playing) */ +#if 0 + ClearRectangleOnBackground(drawto, x, y, width, height); #else - ClearRectangleOnBackground(backbuffer, dst_x, dst_y, width, height); + ClearRectangleOnBackground(backbuffer, x, y, width, height); #endif redraw_mask |= REDRAW_FIELD; } +void DrawBackgroundForFont(int x, int y, int width, int height, int font_nr) +{ + struct FontBitmapInfo *font = getFontBitmapInfo(font_nr); + + if (font->bitmap == NULL) + return; + + DrawBackground(x, y, width, height); +} + +void DrawBackgroundForGraphic(int x, int y, int width, int height, int graphic) +{ + struct GraphicInfo *g = &graphic_info[graphic]; + + if (g->bitmap == NULL) + return; + + DrawBackground(x, y, width, height); +} + void ClearWindow() { + /* !!! "drawto" might still point to playfield buffer here (see above) !!! */ + /* (when entering hall of fame after playing) */ DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); + /* !!! maybe this should be done before clearing the background !!! */ if (setup.soft_scrolling && game_status == GAME_MODE_PLAYING) { ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE); @@ -1561,8 +1697,6 @@ void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y) static void DrawPreviewLevelExt(int from_x, int from_y) { boolean show_level_border = (BorderElement != EL_EMPTY); - int dst_x = preview.x; - int dst_y = preview.y; int level_xsize = lev_fieldx + (show_level_border ? 2 : 0); int level_ysize = lev_fieldy + (show_level_border ? 2 : 0); int tile_size = preview.tile_size; @@ -1570,6 +1704,8 @@ static void DrawPreviewLevelExt(int from_x, int from_y) int preview_height = preview.ysize * tile_size; int real_preview_xsize = MIN(level_xsize, preview.xsize); int real_preview_ysize = MIN(level_ysize, preview.ysize); + int dst_x = SX + ALIGNED_XPOS(preview.x, preview_width, preview.align); + int dst_y = SY + preview.y; int x, y; DrawBackground(dst_x, dst_y, preview_width, preview_height); @@ -1603,8 +1739,24 @@ static void DrawPreviewLevelExt(int from_x, int from_y) #define MICROLABEL_IMPORTED_BY_HEAD 6 #define MICROLABEL_IMPORTED_BY 7 +static int getMaxTextLength(struct MenuPosInfo *pos, int font_nr) +{ + int max_text_width = SXSIZE; + int font_width = getFontWidth(font_nr); + + if (pos->align == ALIGN_CENTER) + max_text_width = (pos->x < SXSIZE / 2 ? pos->x * 2 : (SXSIZE - pos->x) * 2); + else if (pos->align == ALIGN_RIGHT) + max_text_width = pos->x; + else + max_text_width = SXSIZE - pos->x; + + return max_text_width / font_width; +} + static void DrawPreviewLevelLabelExt(int mode) { + struct MenuPosInfo *pos = &menu.main.text.level_info_2; char label_text[MAX_OUTPUT_LINESIZE + 1]; int max_len_label_text; int font_nr = FONT_TEXT_2; @@ -1615,7 +1767,11 @@ static void DrawPreviewLevelLabelExt(int mode) mode == MICROLABEL_IMPORTED_BY_HEAD) font_nr = FONT_TEXT_3; +#if 1 + max_len_label_text = getMaxTextLength(pos, font_nr); +#else max_len_label_text = SXSIZE / getFontWidth(font_nr); +#endif for (i = 0; i < max_len_label_text; i++) label_text[i] = ' '; @@ -1623,10 +1779,14 @@ static void DrawPreviewLevelLabelExt(int mode) if (strlen(label_text) > 0) { +#if 1 + DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align); +#else int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2; int lypos = MICROLABEL2_YPOS; DrawText(lxpos, lypos, label_text, font_nr); +#endif } strncpy(label_text, @@ -1642,10 +1802,14 @@ static void DrawPreviewLevelLabelExt(int mode) if (strlen(label_text) > 0) { +#if 1 + DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align); +#else int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2; int lypos = MICROLABEL2_YPOS; DrawText(lxpos, lypos, label_text, font_nr); +#endif } redraw_mask |= REDRAW_MICROLEVEL; @@ -1668,7 +1832,20 @@ void DrawPreviewLevel(boolean restart) if (restart) { - from_x = from_y = 0; + from_x = 0; + from_y = 0; + + if (preview.anim_mode == ANIM_CENTERED) + { + if (level_xsize > preview.xsize) + from_x = (level_xsize - preview.xsize) / 2; + if (level_ysize > preview.ysize) + from_y = (level_ysize - preview.ysize) / 2; + } + + from_x += preview.xoffset; + from_y += preview.yoffset; + scroll_direction = MV_RIGHT; label_state = 1; label_counter = 0; @@ -1682,18 +1859,30 @@ void DrawPreviewLevel(boolean restart) if (leveldir_current->name) { + struct MenuPosInfo *pos = &menu.main.text.level_info_1; char label_text[MAX_OUTPUT_LINESIZE + 1]; int font_nr = FONT_TEXT_1; +#if 1 + int max_len_label_text = getMaxTextLength(pos, font_nr); +#else int max_len_label_text = SXSIZE / getFontWidth(font_nr); +#endif +#if 0 + int text_width; int lxpos, lypos; +#endif strncpy(label_text, leveldir_current->name, max_len_label_text); label_text[max_len_label_text] = '\0'; +#if 1 + DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align); +#else lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2; lypos = SY + MICROLABEL1_YPOS; DrawText(lxpos, lypos, label_text, font_nr); +#endif } game_status = last_game_status; /* restore current game status */ @@ -1702,7 +1891,8 @@ void DrawPreviewLevel(boolean restart) } /* scroll preview level, if needed */ - if ((level_xsize > preview.xsize || level_ysize > preview.ysize) && + if (preview.anim_mode != ANIM_NONE && + (level_xsize > preview.xsize || level_ysize > preview.ysize) && DelayReached(&scroll_delay, scroll_delay_value)) { switch (scroll_direction) @@ -2439,7 +2629,7 @@ boolean Request(char *text, unsigned int req_state) NextEvent(&event); - switch(event.type) + switch (event.type) { case EVENT_BUTTONPRESS: case EVENT_BUTTONRELEASE: @@ -2471,7 +2661,7 @@ boolean Request(char *text, unsigned int req_state) /* this sets 'request_gadget_id' */ HandleGadgets(mx, my, button_status); - switch(request_gadget_id) + switch (request_gadget_id) { case TOOL_CTRL_ID_YES: result = TRUE; @@ -2504,7 +2694,7 @@ boolean Request(char *text, unsigned int req_state) } case EVENT_KEYPRESS: - switch(GetEventKey((KeyEvent *)&event, TRUE)) + switch (GetEventKey((KeyEvent *)&event, TRUE)) { case KSYM_Return: result = 1; @@ -2542,8 +2732,13 @@ boolean Request(char *text, unsigned int req_state) DoAnimation(); +#if 1 + if (!PendingEvent()) /* delay only if no pending events */ + Delay(10); +#else /* don't eat all CPU time */ Delay(10); +#endif } if (game_status != GAME_MODE_MAIN) @@ -3093,6 +3288,7 @@ void CreateToolButtons() GDI_DECORATION_POSITION, deco_xpos, deco_ypos, GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY, GDI_DECORATION_SHIFTING, 1, 1, + GDI_DIRECT_DRAW, FALSE, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_ACTION, HandleToolButtons, GDI_END); @@ -5172,7 +5368,7 @@ int map_direction_EM_to_RND(int direction) int get_next_element(int element) { - switch(element) + switch (element) { case EL_QUICKSAND_FILLING: return EL_QUICKSAND_FULL; case EL_QUICKSAND_EMPTYING: return EL_QUICKSAND_EMPTY; @@ -5997,28 +6193,67 @@ void PlayMenuMusic() if (music == MUS_UNDEFINED) return; + if (!setup.sound_music) + return; + PlayMusic(music); } +void PlaySoundActivating() +{ +#if 0 + PlaySound(SND_MENU_ITEM_ACTIVATING); +#endif +} + +void PlaySoundSelecting() +{ +#if 0 + PlaySound(SND_MENU_ITEM_SELECTING); +#endif +} + void ToggleFullscreenIfNeeded() { + boolean change_fullscreen = (setup.fullscreen != + video.fullscreen_enabled); + boolean change_fullscreen_mode = (video.fullscreen_enabled && + !strEqual(setup.fullscreen_mode, + video.fullscreen_mode_current)); + + if (!video.fullscreen_available) + return; + +#if 1 + if (change_fullscreen || change_fullscreen_mode) +#else if (setup.fullscreen != video.fullscreen_enabled || setup.fullscreen_mode != video.fullscreen_mode_current) +#endif { Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); /* save backbuffer content which gets lost when toggling fullscreen mode */ BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); +#if 1 + if (change_fullscreen_mode) +#else if (setup.fullscreen && video.fullscreen_enabled) +#endif { - /* keep fullscreen mode, but change screen mode */ + /* keep fullscreen, but change fullscreen mode (screen resolution) */ +#if 1 + /* (this is now set in sdl.c) */ +#else video.fullscreen_mode_current = setup.fullscreen_mode; - video.fullscreen_enabled = FALSE; +#endif + video.fullscreen_enabled = FALSE; /* force new fullscreen mode */ } /* toggle fullscreen */ ChangeVideoModeIfNeeded(setup.fullscreen); + setup.fullscreen = video.fullscreen_enabled; /* restore backbuffer content from temporary backbuffer backup bitmap */ @@ -6026,6 +6261,11 @@ void ToggleFullscreenIfNeeded() FreeBitmap(tmp_backbuffer); +#if 1 + /* update visible window/screen */ + BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); +#else redraw_mask = REDRAW_ALL; +#endif } } diff --git a/src/tools.h b/src/tools.h index 7a29b910..1c26b6d6 100644 --- a/src/tools.h +++ b/src/tools.h @@ -62,6 +62,13 @@ void DumpTile(int, int); +void DrawMaskedBorder_FIELD(); +void DrawMaskedBorder_DOOR_1(); +void DrawMaskedBorder_DOOR_2(); +void DrawMaskedBorder_DOOR_3(); +void DrawMaskedBorder_ALL(); +void DrawMaskedBorder(int); + void SetDrawtoField(int); void RedrawPlayfield(boolean, int, int, int, int); void BackToFront(); @@ -73,11 +80,14 @@ void FadeCross(int); void FadeCrossSaveBackbuffer(); void ClearWindow(); +void SetWindowBackgroundImageIfDefined(int); void SetMainBackgroundImageIfDefined(int); void SetMainBackgroundImage(int); void SetDoorBackgroundImage(int); void SetPanelBackground(); void DrawBackground(int, int, int, int); +void DrawBackgroundForFont(int, int, int, int, int); +void DrawBackgroundForGraphic(int, int, int, int, int); void MarkTileDirty(int, int); void SetBorderElement(); @@ -169,6 +179,8 @@ void PlayMenuSound(); void PlayMenuSoundStereo(int, int); void PlayMenuSoundIfLoop(); void PlayMenuMusic(); +void PlaySoundActivating(); +void PlaySoundSelecting(); void ToggleFullscreenIfNeeded();