From ddd58a300bd5996f69a8ec41d1fd140fe7a46f18 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 27 Apr 2007 01:16:42 +0200 Subject: [PATCH] rnd-20070427-1-src * added "busy" animation when initializing program and loading artwork * added initialization profiling for program startup (debugging only) --- ChangeLog | 4 + src/conf_gfx.c | 15 ++- src/conf_gfx.h | 111 +++++++++--------- src/conf_var.c | 16 +++ src/conftime.h | 2 +- src/files.c | 142 ++++++++++++++--------- src/files.h | 3 +- src/init.c | 269 ++++++++++++++++++++++++++++++++++++++----- src/libgame/misc.c | 54 ++++++--- src/libgame/sdl.c | 6 + src/libgame/setup.c | 12 ++ src/libgame/system.c | 21 ++++ src/libgame/system.h | 13 ++- src/libgame/text.c | 20 +++- src/libgame/text.h | 2 + src/main.c | 1 + src/main.h | 6 + 17 files changed, 531 insertions(+), 166 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0cc72e05..3908154e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ 2007-04-26 + * added "busy" animation when initializing program and loading artwork + * added initialization profiling for program startup (debugging only) + +2007-04-25 * fixed(?) very strange bug apparently triggered by memset() when code was cross-compiled with MinGW cross-compiler for Windows XP platform (this only happened when using SDL.dll also self-compiled with MinGW) diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 0ea0ef86..751876b5 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -4932,6 +4932,15 @@ struct ConfigInfo image_config[] = { "global.border", "RocksScreen.pcx" }, { "global.door", "RocksDoor.pcx" }, + { "global.busy", "RocksBusy.pcx" }, + { "global.busy.x", "0" }, + { "global.busy.y", "0" }, + { "global.busy.width", "32" }, + { "global.busy.height", "32" }, + { "global.busy.frames", "28" }, + { "global.busy.frames_per_line", "7" }, + { "global.busy.delay", "2" }, + { "editor.element_border", "RocksElements.pcx" }, { "editor.element_border.xpos", "0" }, { "editor.element_border.ypos", "0" }, @@ -5275,6 +5284,11 @@ struct ConfigInfo image_config[] = { "border.draw_masked_when_fading", "true" }, + { "init.busy.x", "336" }, + { "init.busy.y", "280" }, + { "init.busy.align", "center" }, + { "init.busy.valign", "middle" }, + { "menu.enter_menu.fade_mode", "none" }, { "menu.enter_menu.fade_delay", "250" }, { "menu.enter_menu.post_delay", "125" }, @@ -6314,7 +6328,6 @@ struct ConfigInfo image_config[] = { "game.button.sound_simple.y", "245" }, { "game.forced_scroll_delay_value", "-1" }, - { "game.use_native_emc_graphics_engine", "false" }, { "[player].boring_delay_fixed", "1000" }, diff --git a/src/conf_gfx.h b/src/conf_gfx.h index 08b38be3..61e5a223 100644 --- a/src/conf_gfx.h +++ b/src/conf_gfx.h @@ -1754,61 +1754,62 @@ #define IMG_FONT_INFO_LEVELSET 1733 #define IMG_GLOBAL_BORDER 1734 #define IMG_GLOBAL_DOOR 1735 -#define IMG_EDITOR_ELEMENT_BORDER 1736 -#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1737 -#define IMG_EDITOR_CASCADE_LIST 1738 -#define IMG_EDITOR_CASCADE_LIST_ACTIVE 1739 -#define IMG_BACKGROUND 1740 -#define IMG_BACKGROUND_TITLE_INITIAL 1741 -#define IMG_BACKGROUND_TITLE 1742 -#define IMG_BACKGROUND_MAIN 1743 -#define IMG_BACKGROUND_LEVELS 1744 -#define IMG_BACKGROUND_SCORES 1745 -#define IMG_BACKGROUND_EDITOR 1746 -#define IMG_BACKGROUND_INFO 1747 -#define IMG_BACKGROUND_INFO_ELEMENTS 1748 -#define IMG_BACKGROUND_INFO_MUSIC 1749 -#define IMG_BACKGROUND_INFO_CREDITS 1750 -#define IMG_BACKGROUND_INFO_PROGRAM 1751 -#define IMG_BACKGROUND_INFO_VERSION 1752 -#define IMG_BACKGROUND_INFO_LEVELSET 1753 -#define IMG_BACKGROUND_SETUP 1754 -#define IMG_BACKGROUND_DOOR 1755 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_1 1756 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_2 1757 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_3 1758 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_4 1759 -#define IMG_BACKGROUND_TITLESCREEN_INITIAL_5 1760 -#define IMG_BACKGROUND_TITLESCREEN_1 1761 -#define IMG_BACKGROUND_TITLESCREEN_2 1762 -#define IMG_BACKGROUND_TITLESCREEN_3 1763 -#define IMG_BACKGROUND_TITLESCREEN_4 1764 -#define IMG_BACKGROUND_TITLESCREEN_5 1765 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_1 1766 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_2 1767 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_3 1768 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_4 1769 -#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_5 1770 -#define IMG_BACKGROUND_TITLEMESSAGE_1 1771 -#define IMG_BACKGROUND_TITLEMESSAGE_2 1772 -#define IMG_BACKGROUND_TITLEMESSAGE_3 1773 -#define IMG_BACKGROUND_TITLEMESSAGE_4 1774 -#define IMG_BACKGROUND_TITLEMESSAGE_5 1775 -#define IMG_BACKGROUND_ENVELOPE_1 1776 -#define IMG_BACKGROUND_ENVELOPE_2 1777 -#define IMG_BACKGROUND_ENVELOPE_3 1778 -#define IMG_BACKGROUND_ENVELOPE_4 1779 -#define IMG_TITLESCREEN_INITIAL_1 1780 -#define IMG_TITLESCREEN_INITIAL_2 1781 -#define IMG_TITLESCREEN_INITIAL_3 1782 -#define IMG_TITLESCREEN_INITIAL_4 1783 -#define IMG_TITLESCREEN_INITIAL_5 1784 -#define IMG_TITLESCREEN_1 1785 -#define IMG_TITLESCREEN_2 1786 -#define IMG_TITLESCREEN_3 1787 -#define IMG_TITLESCREEN_4 1788 -#define IMG_TITLESCREEN_5 1789 +#define IMG_GLOBAL_BUSY 1736 +#define IMG_EDITOR_ELEMENT_BORDER 1737 +#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1738 +#define IMG_EDITOR_CASCADE_LIST 1739 +#define IMG_EDITOR_CASCADE_LIST_ACTIVE 1740 +#define IMG_BACKGROUND 1741 +#define IMG_BACKGROUND_TITLE_INITIAL 1742 +#define IMG_BACKGROUND_TITLE 1743 +#define IMG_BACKGROUND_MAIN 1744 +#define IMG_BACKGROUND_LEVELS 1745 +#define IMG_BACKGROUND_SCORES 1746 +#define IMG_BACKGROUND_EDITOR 1747 +#define IMG_BACKGROUND_INFO 1748 +#define IMG_BACKGROUND_INFO_ELEMENTS 1749 +#define IMG_BACKGROUND_INFO_MUSIC 1750 +#define IMG_BACKGROUND_INFO_CREDITS 1751 +#define IMG_BACKGROUND_INFO_PROGRAM 1752 +#define IMG_BACKGROUND_INFO_VERSION 1753 +#define IMG_BACKGROUND_INFO_LEVELSET 1754 +#define IMG_BACKGROUND_SETUP 1755 +#define IMG_BACKGROUND_DOOR 1756 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_1 1757 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_2 1758 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_3 1759 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_4 1760 +#define IMG_BACKGROUND_TITLESCREEN_INITIAL_5 1761 +#define IMG_BACKGROUND_TITLESCREEN_1 1762 +#define IMG_BACKGROUND_TITLESCREEN_2 1763 +#define IMG_BACKGROUND_TITLESCREEN_3 1764 +#define IMG_BACKGROUND_TITLESCREEN_4 1765 +#define IMG_BACKGROUND_TITLESCREEN_5 1766 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_1 1767 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_2 1768 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_3 1769 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_4 1770 +#define IMG_BACKGROUND_TITLEMESSAGE_INITIAL_5 1771 +#define IMG_BACKGROUND_TITLEMESSAGE_1 1772 +#define IMG_BACKGROUND_TITLEMESSAGE_2 1773 +#define IMG_BACKGROUND_TITLEMESSAGE_3 1774 +#define IMG_BACKGROUND_TITLEMESSAGE_4 1775 +#define IMG_BACKGROUND_TITLEMESSAGE_5 1776 +#define IMG_BACKGROUND_ENVELOPE_1 1777 +#define IMG_BACKGROUND_ENVELOPE_2 1778 +#define IMG_BACKGROUND_ENVELOPE_3 1779 +#define IMG_BACKGROUND_ENVELOPE_4 1780 +#define IMG_TITLESCREEN_INITIAL_1 1781 +#define IMG_TITLESCREEN_INITIAL_2 1782 +#define IMG_TITLESCREEN_INITIAL_3 1783 +#define IMG_TITLESCREEN_INITIAL_4 1784 +#define IMG_TITLESCREEN_INITIAL_5 1785 +#define IMG_TITLESCREEN_1 1786 +#define IMG_TITLESCREEN_2 1787 +#define IMG_TITLESCREEN_3 1788 +#define IMG_TITLESCREEN_4 1789 +#define IMG_TITLESCREEN_5 1790 -#define NUM_IMAGE_FILES 1790 +#define NUM_IMAGE_FILES 1791 #endif /* CONF_GFX_H */ diff --git a/src/conf_var.c b/src/conf_var.c index dbe6c460..8afe89ad 100644 --- a/src/conf_var.c +++ b/src/conf_var.c @@ -964,6 +964,22 @@ struct TokenIntPtrInfo image_config_vars[] = "border.draw_masked_when_fading", &border.draw_masked_when_fading }, + { + "init.busy.x", + &init.busy.x + }, + { + "init.busy.y", + &init.busy.y + }, + { + "init.busy.align", + &init.busy.align + }, + { + "init.busy.valign", + &init.busy.valign + }, { "menu.enter_menu.fade_mode", &menu.enter_menu.fade_mode diff --git a/src/conftime.h b/src/conftime.h index b97818ad..10441561 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2007-04-25 23:54" +#define COMPILE_DATE_STRING "2007-04-27 01:16" diff --git a/src/files.c b/src/files.c index 9a27a0d6..636878f1 100644 --- a/src/files.c +++ b/src/files.c @@ -8698,7 +8698,84 @@ static int get_token_parameter_value(char *token, char *value_raw) return get_parameter_value(value_raw, suffix, TYPE_INTEGER); } -static void LoadSpecialMenuDesignSettingsFromFilename(char *filename) +void InitMenuDesignSettings_Static() +{ + static SetupFileHash *image_config_hash = NULL; + int i; + + if (image_config_hash == NULL) + { + image_config_hash = newSetupFileHash(); + + for (i = 0; image_config[i].token != NULL; i++) + setHashEntry(image_config_hash, + image_config[i].token, + image_config[i].value); + } + +#if 1 + /* always start with reliable default values from static default config */ + for (i = 0; image_config_vars[i].token != NULL; i++) + { + char *value = getHashEntry(image_config_hash, image_config_vars[i].token); + + if (value != NULL) + *image_config_vars[i].value = + get_token_parameter_value(image_config_vars[i].token, value); + } +#else + /* always start with reliable default values from static default config */ + for (i = 0; image_config_vars[i].token != NULL; i++) + for (j = 0; image_config[j].token != NULL; j++) + if (strEqual(image_config_vars[i].token, image_config[j].token)) + *image_config_vars[i].value = + get_token_parameter_value(image_config_vars[i].token, + image_config[j].value); +#endif +} + +static void InitMenuDesignSettings_SpecialPreProcessing() +{ + int i; + + /* the following initializes hierarchical values from static configuration */ + + /* special case: initialize "ARG_DEFAULT" values in static default config */ + /* (e.g., initialize "[titlemessage].fade_mode" from "[title].fade_mode") */ + titlemessage_initial_default.fade_mode = title_initial_default.fade_mode; + titlemessage_initial_default.fade_delay = title_initial_default.fade_delay; + titlemessage_initial_default.post_delay = title_initial_default.post_delay; + titlemessage_initial_default.auto_delay = title_initial_default.auto_delay; + titlemessage_default.fade_mode = title_default.fade_mode; + titlemessage_default.fade_delay = title_default.fade_delay; + titlemessage_default.post_delay = title_default.post_delay; + titlemessage_default.auto_delay = title_default.auto_delay; + + /* special case: initialize "ARG_DEFAULT" values in static default config */ + /* (e.g., init "titlemessage_1.fade_mode" from "[titlemessage].fade_mode") */ + for (i = 0; i < MAX_NUM_TITLE_MESSAGES; i++) + { + titlemessage_initial[i] = titlemessage_initial_default; + titlemessage[i] = titlemessage_default; + } + + /* special case: initialize "ARG_DEFAULT" values in static default config */ + /* (eg, init "menu.enter_screen.SCORES.xyz" from "menu.enter_screen.xyz") */ + for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++) + { + menu.enter_screen[i] = menu.enter_screen[GFX_SPECIAL_ARG_DEFAULT]; + menu.leave_screen[i] = menu.leave_screen[GFX_SPECIAL_ARG_DEFAULT]; + } +} + +static void InitMenuDesignSettings_SpecialPostProcessing() +{ + /* special case: initialize later added SETUP list size from LEVELS value */ + if (menu.list_size[GAME_MODE_SETUP] == -1) + menu.list_size[GAME_MODE_SETUP] = menu.list_size[GAME_MODE_LEVELS]; +} + +static void LoadMenuDesignSettingsFromFilename(char *filename) { static struct TitleMessageInfo tmi; static struct TokenInfo titlemessage_tokens[] = @@ -8739,7 +8816,7 @@ static void LoadSpecialMenuDesignSettingsFromFilename(char *filename) int i, j, k; #if 0 - printf("LoadSpecialMenuDesignSettings from file '%s' ...\n", filename); + printf("LoadMenuDesignSettings from file '%s' ...\n", filename); #endif if ((setup_file_hash = loadSetupFileHash(filename)) == NULL) @@ -8872,61 +8949,12 @@ static void LoadSpecialMenuDesignSettingsFromFilename(char *filename) freeSetupFileHash(setup_file_hash); } -static void LoadSpecialMenuDesignSettings_SpecialPreProcessing() -{ - int i; - - /* the following initializes hierarchical values from static configuration */ - - /* special case: initialize "ARG_DEFAULT" values in static default config */ - /* (e.g., initialize "[titlemessage].fade_mode" from "[title].fade_mode") */ - titlemessage_initial_default.fade_mode = title_initial_default.fade_mode; - titlemessage_initial_default.fade_delay = title_initial_default.fade_delay; - titlemessage_initial_default.post_delay = title_initial_default.post_delay; - titlemessage_initial_default.auto_delay = title_initial_default.auto_delay; - titlemessage_default.fade_mode = title_default.fade_mode; - titlemessage_default.fade_delay = title_default.fade_delay; - titlemessage_default.post_delay = title_default.post_delay; - titlemessage_default.auto_delay = title_default.auto_delay; - - /* special case: initialize "ARG_DEFAULT" values in static default config */ - /* (e.g., init "titlemessage_1.fade_mode" from "[titlemessage].fade_mode") */ - for (i = 0; i < MAX_NUM_TITLE_MESSAGES; i++) - { - titlemessage_initial[i] = titlemessage_initial_default; - titlemessage[i] = titlemessage_default; - } - - /* special case: initialize "ARG_DEFAULT" values in static default config */ - /* (eg, init "menu.enter_screen.SCORES.xyz" from "menu.enter_screen.xyz") */ - for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++) - { - menu.enter_screen[i] = menu.enter_screen[GFX_SPECIAL_ARG_DEFAULT]; - menu.leave_screen[i] = menu.leave_screen[GFX_SPECIAL_ARG_DEFAULT]; - } -} - -static void LoadSpecialMenuDesignSettings_SpecialPostProcessing() -{ - /* special case: initialize later added SETUP list size from LEVELS value */ - if (menu.list_size[GAME_MODE_SETUP] == -1) - menu.list_size[GAME_MODE_SETUP] = menu.list_size[GAME_MODE_LEVELS]; -} - -void LoadSpecialMenuDesignSettings() +void LoadMenuDesignSettings() { char *filename_base = UNDEFINED_FILENAME, *filename_local; - int i, j; - - /* always start with reliable default values from static default config */ - for (i = 0; image_config_vars[i].token != NULL; i++) - for (j = 0; image_config[j].token != NULL; j++) - if (strEqual(image_config_vars[i].token, image_config[j].token)) - *image_config_vars[i].value = - get_token_parameter_value(image_config_vars[i].token, - image_config[j].value); - LoadSpecialMenuDesignSettings_SpecialPreProcessing(); + InitMenuDesignSettings_Static(); + InitMenuDesignSettings_SpecialPreProcessing(); if (!SETUP_OVERRIDE_ARTWORK(setup, ARTWORK_TYPE_GRAPHICS)) { @@ -8934,15 +8962,15 @@ void LoadSpecialMenuDesignSettings() filename_base = getCustomArtworkLevelConfigFilename(ARTWORK_TYPE_GRAPHICS); if (fileExists(filename_base)) - LoadSpecialMenuDesignSettingsFromFilename(filename_base); + LoadMenuDesignSettingsFromFilename(filename_base); } filename_local = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS); if (filename_local != NULL && !strEqual(filename_base, filename_local)) - LoadSpecialMenuDesignSettingsFromFilename(filename_local); + LoadMenuDesignSettingsFromFilename(filename_local); - LoadSpecialMenuDesignSettings_SpecialPostProcessing(); + InitMenuDesignSettings_SpecialPostProcessing(); } void LoadUserDefinedEditorElementList(int **elements, int *num_elements) diff --git a/src/files.h b/src/files.h index 41939ac2..51509f8c 100644 --- a/src/files.h +++ b/src/files.h @@ -61,7 +61,8 @@ void LoadSetup_EditorCascade(); void SaveSetup_EditorCascade(); void LoadCustomElementDescriptions(); -void LoadSpecialMenuDesignSettings(); +void InitMenuDesignSettings_Static(); +void LoadMenuDesignSettings(); void LoadUserDefinedEditorElementList(int **, int *); void LoadMusicInfo(); void LoadHelpAnimInfo(); diff --git a/src/init.c b/src/init.c index 5a2ff12a..9f4b7f9e 100644 --- a/src/init.c +++ b/src/init.c @@ -36,9 +36,14 @@ #define CONFIG_TOKEN_FONT_INITIAL "font.initial" +#define CONFIG_TOKEN_GLOBAL_BUSY "global.busy" + +#define DEBUG_PRINT_INIT_TIMESTAMPS TRUE +#define DEBUG_PRINT_INIT_TIMESTAMPS_DEPTH 5 static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS]; +static struct GraphicInfo anim_initial; static int copy_properties[][5] = { @@ -83,6 +88,94 @@ static int copy_properties[][5] = } }; + +static void print_init_timestamp(char *message) +{ +#if DEBUG +#if DEBUG_PRINT_INIT_TIMESTAMPS + static char *last_message = NULL; + static int counter_nr = 0; + int max_depth = DEBUG_PRINT_INIT_TIMESTAMPS_DEPTH; + + if (strEqualPrefix(message, "INIT")) + { + if (counter_nr + 1 < max_depth) + { + debug_print_timestamp(counter_nr, NULL); + debug_print_timestamp(counter_nr, message); + } + + counter_nr++; + + debug_print_timestamp(counter_nr, NULL); + } + else if (strEqualPrefix(message, "DONE")) + { + counter_nr--; + + if (counter_nr + 1 < max_depth) + { + last_message = &message[4]; + + debug_print_timestamp(counter_nr, message); + } + } + else if (!strEqualPrefix(message, "TIME") || + !strEqualSuffix(message, last_message)) + { + if (counter_nr < max_depth) + debug_print_timestamp(counter_nr, message); + } +#endif +#endif +} + +void DrawInitAnim() +{ + struct GraphicInfo *graphic_info_last = graphic_info; + int graphic = 0; + static unsigned long action_delay = 0; + unsigned long action_delay_value = GameFrameDelay; + int sync_frame = FrameCounter; + int x, y; + + if (anim_initial.bitmap == NULL || window == NULL) + return; + + if (!DelayReached(&action_delay, action_delay_value)) + return; + +#if 0 + { + static unsigned long last_counter = -1; + unsigned long current_counter = Counter(); + unsigned long delay = current_counter - last_counter; + + if (last_counter != -1 && delay > action_delay_value + 5) + printf("::: DrawInitAnim: DELAY TOO LONG: %ld\n", delay); + + last_counter = current_counter; + } +#endif + + anim_initial.anim_mode = ANIM_LOOP; + anim_initial.anim_start_frame = 0; + anim_initial.offset_x = anim_initial.width; + anim_initial.offset_y = 0; + + x = WIN_XSIZE / 2 - TILESIZE / 2; + y = WIN_YSIZE / 2 - TILESIZE / 2; + + graphic_info = &anim_initial; + + if (sync_frame % anim_initial.anim_delay == 0) + DrawGraphicAnimationExt(window, x, y, graphic, sync_frame, NO_MASKING); + + graphic_info = graphic_info_last; + + FrameCounter++; +} + void FreeGadgets() { FreeLevelEditorGadgets(); @@ -462,6 +555,8 @@ void InitElementGraphicInfo() } } + UPDATE_BUSY_STATE(); + /* initialize normal element/graphic mapping from static configuration */ for (i = 0; element_to_graphic[i].element > -1; i++) { @@ -646,6 +741,8 @@ void InitElementGraphicInfo() } } + UPDATE_BUSY_STATE(); + /* adjust graphics with 2nd tile for movement according to direction (do this before correcting '-1' values to minimize calculations) */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) @@ -705,6 +802,8 @@ void InitElementGraphicInfo() } } + UPDATE_BUSY_STATE(); + /* now set all '-1' values to element specific default values */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -856,6 +955,8 @@ void InitElementGraphicInfo() } } + UPDATE_BUSY_STATE(); + #if 0 /* !!! THIS ALSO CLEARS SPECIAL FLAGS (AND IS NOT NEEDED ANYWAY) !!! */ /* set animation mode to "none" for each graphic with only 1 frame */ @@ -1309,6 +1410,8 @@ static void set_graphic_parameters(int graphic) graphic_info[graphic].valign = parameter[GFX_ARG_VALIGN]; if (parameter[GFX_ARG_SORT_PRIORITY] != ARG_UNDEFINED_VALUE) graphic_info[graphic].sort_priority = parameter[GFX_ARG_SORT_PRIORITY]; + + UPDATE_BUSY_STATE(); } static void set_cloned_graphic_parameters(int graphic) @@ -1939,21 +2042,36 @@ static void InitMusicInfo() static void ReinitializeGraphics() { + print_init_timestamp("INIT ReinitializeGraphics"); + InitGraphicInfo(); /* graphic properties mapping */ + print_init_timestamp("TIME InitGraphicInfo"); InitElementGraphicInfo(); /* element game graphic mapping */ + print_init_timestamp("TIME InitElementGraphicInfo"); InitElementSpecialGraphicInfo(); /* element special graphic mapping */ + print_init_timestamp("TIME InitElementSpecialGraphicInfo"); InitElementSmallImages(); /* scale elements to all needed sizes */ + print_init_timestamp("TIME InitElementSmallImages"); InitScaledImages(); /* scale all other images, if needed */ + print_init_timestamp("TIME InitScaledImages"); InitFontGraphicInfo(); /* initialize text drawing functions */ + print_init_timestamp("TIME InitFontGraphicInfo"); InitGraphicInfo_EM(); /* graphic mapping for EM engine */ + print_init_timestamp("TIME InitGraphicInfo_EM"); SetMainBackgroundImage(IMG_BACKGROUND); + print_init_timestamp("TIME SetMainBackgroundImage"); SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); + print_init_timestamp("TIME SetDoorBackgroundImage"); InitGadgets(); + print_init_timestamp("TIME InitGadgets"); InitToons(); + print_init_timestamp("TIME InitToons"); + + print_init_timestamp("DONE ReinitializeGraphics"); } static void ReinitializeSounds() @@ -4876,6 +4994,7 @@ static void InitMixer() void InitGfx() { char *filename_font_initial = NULL; + char *filename_anim_initial = NULL; Bitmap *bitmap_font_initial = NULL; int font_height; int i, j; @@ -4902,7 +5021,7 @@ void InitGfx() font_initial[j].src_y = atoi(image_config[i].value); else if (strEqual(&image_config[i].token[len_font_token], ".width")) font_initial[j].width = atoi(image_config[i].value); - else if (strEqual(&image_config[i].token[len_font_token],".height")) + else if (strEqual(&image_config[i].token[len_font_token], ".height")) font_initial[j].height = atoi(image_config[i].value); } } @@ -4949,6 +5068,44 @@ void InitGfx() DrawInitText(PROGRAM_WEBSITE_STRING, WIN_YSIZE - 20 - font_height, FC_RED); DrawInitText("Loading graphics", 120, FC_GREEN); + +#if 1 + /* determine settings for busy animation (when displaying startup messages) */ + for (i = 0; image_config[i].token != NULL; i++) + { + char *anim_token = CONFIG_TOKEN_GLOBAL_BUSY; + int len_anim_token = strlen(anim_token); + + if (strEqual(image_config[i].token, anim_token)) + filename_anim_initial = image_config[i].value; + else if (strlen(image_config[i].token) > len_anim_token && + strncmp(image_config[i].token, anim_token, len_anim_token) == 0) + { + if (strEqual(&image_config[i].token[len_anim_token], ".x")) + anim_initial.src_x = atoi(image_config[i].value); + else if (strEqual(&image_config[i].token[len_anim_token], ".y")) + anim_initial.src_y = atoi(image_config[i].value); + else if (strEqual(&image_config[i].token[len_anim_token], ".width")) + anim_initial.width = atoi(image_config[i].value); + else if (strEqual(&image_config[i].token[len_anim_token], ".height")) + anim_initial.height = atoi(image_config[i].value); + else if (strEqual(&image_config[i].token[len_anim_token], ".frames")) + anim_initial.anim_frames = atoi(image_config[i].value); + else if (strEqual(&image_config[i].token[len_anim_token], + ".frames_per_line")) + anim_initial.anim_frames_per_line = atoi(image_config[i].value); + else if (strEqual(&image_config[i].token[len_anim_token], ".delay")) + anim_initial.anim_delay = atoi(image_config[i].value); + } + } + + if (filename_anim_initial == NULL) /* should not happen */ + Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_GLOBAL_BUSY); + + anim_initial.bitmap = LoadCustomImage(filename_anim_initial); + + InitGfxDrawBusyAnimFunction(DrawInitAnim); +#endif } void RedrawBackground() @@ -4996,6 +5153,8 @@ void InitLevelArtworkInfo() static void InitImages() { + print_init_timestamp("INIT InitImages"); + setLevelArtworkDir(artwork.gfx_first); #if 0 @@ -5007,16 +5166,35 @@ static void InitImages() leveldir_current->graphics_path); #endif + UPDATE_BUSY_STATE(); + ReloadCustomImages(); + print_init_timestamp("TIME ReloadCustomImages"); + + UPDATE_BUSY_STATE(); LoadCustomElementDescriptions(); - LoadSpecialMenuDesignSettings(); + print_init_timestamp("TIME LoadCustomElementDescriptions"); + + UPDATE_BUSY_STATE(); + + LoadMenuDesignSettings(); + print_init_timestamp("TIME LoadMenuDesignSettings"); + + UPDATE_BUSY_STATE(); ReinitializeGraphics(); + print_init_timestamp("TIME ReinitializeGraphics"); + + UPDATE_BUSY_STATE(); + + print_init_timestamp("DONE InitImages"); } static void InitSound(char *identifier) { + print_init_timestamp("INIT InitSound"); + if (identifier == NULL) identifier = artwork.snd_current->identifier; @@ -5024,11 +5202,18 @@ static void InitSound(char *identifier) setLevelArtworkDir(artwork.snd_first); InitReloadCustomSounds(identifier); + print_init_timestamp("TIME InitReloadCustomSounds"); + ReinitializeSounds(); + print_init_timestamp("TIME ReinitializeSounds"); + + print_init_timestamp("DONE InitSound"); } static void InitMusic(char *identifier) { + print_init_timestamp("INIT InitMusic"); + if (identifier == NULL) identifier = artwork.mus_current->identifier; @@ -5036,7 +5221,12 @@ static void InitMusic(char *identifier) setLevelArtworkDir(artwork.mus_first); InitReloadCustomMusic(identifier); + print_init_timestamp("TIME InitReloadCustomMusic"); + ReinitializeMusic(); + print_init_timestamp("TIME ReinitializeMusic"); + + print_init_timestamp("DONE InitMusic"); } void InitNetworkServer() @@ -5183,7 +5373,7 @@ void ReloadCustomArtwork(int force_reload) boolean force_reload_gfx = (force_reload & (1 << ARTWORK_TYPE_GRAPHICS)); boolean force_reload_snd = (force_reload & (1 << ARTWORK_TYPE_SOUNDS)); boolean force_reload_mus = (force_reload & (1 << ARTWORK_TYPE_MUSIC)); - boolean redraw_screen = FALSE; + boolean reload_needed; force_reload_gfx |= AdjustGraphicsForEMC(); @@ -5191,6 +5381,18 @@ void ReloadCustomArtwork(int force_reload) snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS); mus_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_MUSIC); + reload_needed = (gfx_new_identifier != NULL || force_reload_gfx || + snd_new_identifier != NULL || force_reload_snd || + mus_new_identifier != NULL || force_reload_mus); + + if (!reload_needed) + return; + + print_init_timestamp("INIT ReloadCustomArtwork"); + + ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); + print_init_timestamp("TIME ClearRectangle"); + if (gfx_new_identifier != NULL || force_reload_gfx) { #if 0 @@ -5201,51 +5403,41 @@ void ReloadCustomArtwork(int force_reload) leveldir_current->graphics_set); #endif - ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); - InitImages(); - - redraw_screen = TRUE; + print_init_timestamp("TIME InitImages"); } if (snd_new_identifier != NULL || force_reload_snd) { - ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); - InitSound(snd_new_identifier); - - redraw_screen = TRUE; + print_init_timestamp("TIME InitSound"); } if (mus_new_identifier != NULL || force_reload_mus) { - ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); - InitMusic(mus_new_identifier); - - redraw_screen = TRUE; + print_init_timestamp("TIME InitMusic"); } - if (redraw_screen) - { - RedrawBackground(); + RedrawBackground(); - /* force redraw of (open or closed) door graphics */ - SetDoorState(DOOR_OPEN_ALL); - CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); + /* force redraw of (open or closed) door graphics */ + SetDoorState(DOOR_OPEN_ALL); + CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); #if 1 #if 1 - FadeSetEnterScreen(); - // FadeSkipNextFadeOut(); - // FadeSetDisabled(); + FadeSetEnterScreen(); + // FadeSkipNextFadeOut(); + // FadeSetDisabled(); #else - FadeSkipNext(); + FadeSkipNext(); #endif #else - fading = fading_none; + fading = fading_none; #endif - } + + print_init_timestamp("DONE ReloadCustomArtwork"); } void KeyboardAutoRepeatOffUnlessAutoplay() @@ -5261,6 +5453,8 @@ void KeyboardAutoRepeatOffUnlessAutoplay() void OpenAll() { + print_init_timestamp("INIT OpenAll"); + InitGlobal(); /* initialize some global variables */ if (options.execute_command) @@ -5292,6 +5486,8 @@ void OpenAll() InitJoysticks(); + print_init_timestamp("TIME [pre-video]"); + InitVideoDisplay(); InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); @@ -5300,17 +5496,26 @@ void OpenAll() InitElementPropertiesStatic(); InitElementPropertiesEngine(GAME_VERSION_ACTUAL); + print_init_timestamp("TIME [post-video]"); + InitGfx(); - // debug_print_timestamp(0, "INIT"); + print_init_timestamp("TIME InitGfx"); + InitLevelInfo(); - // debug_print_timestamp(0, "TIME InitLevelInfo: "); + print_init_timestamp("TIME InitLevelInfo"); + InitLevelArtworkInfo(); - // debug_print_timestamp(0, "TIME InitLevelArtworkInfo: "); + print_init_timestamp("TIME InitLevelArtworkInfo"); InitImages(); /* needs to know current level directory */ + print_init_timestamp("TIME InitImages"); + InitSound(NULL); /* needs to know current level directory */ + print_init_timestamp("TIME InitSound"); + InitMusic(NULL); /* needs to know current level directory */ + print_init_timestamp("TIME InitMusic"); InitGfxBackground(); @@ -5340,6 +5545,10 @@ void OpenAll() fading = fading_none; #endif + print_init_timestamp("TIME [post-artwork]"); + + print_init_timestamp("DONE OpenAll"); + DrawMainMenu(); InitNetworkServer(); diff --git a/src/libgame/misc.c b/src/libgame/misc.c index f94cc376..bfb2164e 100644 --- a/src/libgame/misc.c +++ b/src/libgame/misc.c @@ -2915,7 +2915,7 @@ void NotifyUserAboutErrorFile() #if DEBUG -#define DEBUG_NUM_TIMESTAMPS 3 +#define DEBUG_NUM_TIMESTAMPS 5 #define DEBUG_TIME_IN_MICROSECONDS 0 #if DEBUG_TIME_IN_MICROSECONDS @@ -2939,35 +2939,53 @@ static double Counter_Microseconds() } #endif +char *debug_print_timestamp_get_padding(int padding_size) +{ + static char *padding = NULL; + int max_padding_size = 100; + + if (padding == NULL) + { + padding = checked_calloc(max_padding_size + 1); + memset(padding, ' ', max_padding_size); + } + + return &padding[MAX(0, max_padding_size - padding_size)]; +} + void debug_print_timestamp(int counter_nr, char *message) { -#if DEBUG_TIME_IN_MICROSECONDS - static double counter[DEBUG_NUM_TIMESTAMPS][2]; + int indent_size = 8; + int padding_size = 40; + float timestamp_interval; - if (counter_nr >= DEBUG_NUM_TIMESTAMPS) + if (counter_nr < 0) + Error(ERR_EXIT, "debugging: invalid negative counter"); + else if (counter_nr >= DEBUG_NUM_TIMESTAMPS) Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c"); - counter[counter_nr][0] = Counter_Microseconds(); - - if (message) - printf("%s %.3f ms\n", message, - (counter[counter_nr][0] - counter[counter_nr][1]) / 1000); +#if DEBUG_TIME_IN_MICROSECONDS + static double counter[DEBUG_NUM_TIMESTAMPS][2]; + char *unit = "ms"; - counter[counter_nr][1] = counter[counter_nr][0]; + counter[counter_nr][0] = Counter_Microseconds(); #else static long counter[DEBUG_NUM_TIMESTAMPS][2]; - - if (counter_nr >= DEBUG_NUM_TIMESTAMPS) - Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c"); + char *unit = "s"; counter[counter_nr][0] = Counter(); +#endif - if (message) - printf("%s %.3f s\n", message, - (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000); - + timestamp_interval = counter[counter_nr][0] - counter[counter_nr][1]; counter[counter_nr][1] = counter[counter_nr][0]; -#endif + + if (message) + printf("%s%s%s %.3f %s\n", + debug_print_timestamp_get_padding(counter_nr * indent_size), + message, + debug_print_timestamp_get_padding(padding_size - strlen(message)), + timestamp_interval / 1000, + unit); } void debug_print_parent_only(char *format, ...) diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c index 4d9c5462..66320a5b 100644 --- a/src/libgame/sdl.c +++ b/src/libgame/sdl.c @@ -1636,6 +1636,8 @@ Bitmap *SDLLoadImage(char *filename) return NULL; } + UPDATE_BUSY_STATE(); + /* create native non-transparent surface for current image */ if ((new_bitmap->surface = SDL_DisplayFormat(sdl_image_tmp)) == NULL) { @@ -1644,6 +1646,8 @@ Bitmap *SDLLoadImage(char *filename) return NULL; } + UPDATE_BUSY_STATE(); + /* create native transparent surface for current image */ SDL_SetColorKey(sdl_image_tmp, SDL_SRCCOLORKEY, SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00)); @@ -1654,6 +1658,8 @@ Bitmap *SDLLoadImage(char *filename) return NULL; } + UPDATE_BUSY_STATE(); + /* free temporary surface */ SDL_FreeSurface(sdl_image_tmp); diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 7e621f43..3ff14a1c 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -2920,8 +2920,10 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, char *level_directory, char *directory_name) { +#if 0 static unsigned long progress_delay = 0; unsigned long progress_delay_value = 100; /* (in milliseconds) */ +#endif char *directory_path = getPath2(level_directory, directory_name); char *filename = getPath2(directory_path, LEVELINFO_FILENAME); SetupFileHash *setup_file_hash; @@ -3022,9 +3024,14 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, leveldir_new->last_level : leveldir_new->first_level); #if 1 +#if 1 + DrawInitTextExt(leveldir_new->name, 150, FC_YELLOW, + leveldir_new->level_group); +#else if (leveldir_new->level_group || DelayReached(&progress_delay, progress_delay_value)) DrawInitText(leveldir_new->name, 150, FC_YELLOW); +#endif #else DrawInitText(leveldir_new->name, 150, FC_YELLOW); #endif @@ -3471,8 +3478,10 @@ void LoadArtworkInfo() void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, LevelDirTree *level_node) { +#if 0 static unsigned long progress_delay = 0; unsigned long progress_delay_value = 100; /* (in milliseconds) */ +#endif int type = (*artwork_node)->type; /* recursively check all level directories for artwork sub-directories */ @@ -3518,6 +3527,9 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, } #if 1 + DrawInitTextExt(level_node->name, 150, FC_YELLOW, + level_node->level_group); +#else if (level_node->level_group || DelayReached(&progress_delay, progress_delay_value)) DrawInitText(level_node->name, 150, FC_YELLOW); diff --git a/src/libgame/system.c b/src/libgame/system.c index c77567a9..e94949d4 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -196,6 +196,11 @@ void InitGfxScrollbufferInfo(int scrollbuffer_width, int scrollbuffer_height) gfx.scrollbuffer_height = scrollbuffer_height; } +void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)) +{ + gfx.draw_busy_anim_function = draw_busy_anim_function; +} + void SetDrawDeactivationMask(int draw_deactivation_mask) { gfx.draw_deactivation_mask = draw_deactivation_mask; @@ -889,35 +894,47 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor, width_32 = width_1 / 32; height_32 = height_1 / 32; + UPDATE_BUSY_STATE(); + /* get image with 1/2 of normal size (for use in the level editor) */ if (zoom_factor != 2) tmp_bitmap_2 = ZoomBitmap(tmp_bitmap_1, width_1 / 2, height_1 / 2); else tmp_bitmap_2 = old_bitmap; + UPDATE_BUSY_STATE(); + /* get image with 1/4 of normal size (for use in the level editor) */ if (zoom_factor != 4) tmp_bitmap_4 = ZoomBitmap(tmp_bitmap_2, width_2 / 2, height_2 / 2); else tmp_bitmap_4 = old_bitmap; + UPDATE_BUSY_STATE(); + /* get image with 1/8 of normal size (for use on the preview screen) */ if (zoom_factor != 8) tmp_bitmap_8 = ZoomBitmap(tmp_bitmap_4, width_4 / 2, height_4 / 2); else tmp_bitmap_8 = old_bitmap; + UPDATE_BUSY_STATE(); + /* get image with 1/16 of normal size (for use on the preview screen) */ if (zoom_factor != 16) tmp_bitmap_16 = ZoomBitmap(tmp_bitmap_8, width_8 / 2, height_8 / 2); else tmp_bitmap_16 = old_bitmap; + UPDATE_BUSY_STATE(); + /* get image with 1/32 of normal size (for use on the preview screen) */ if (zoom_factor != 32) tmp_bitmap_32 = ZoomBitmap(tmp_bitmap_16, width_16 / 2, height_16 / 2); else tmp_bitmap_32 = old_bitmap; + + UPDATE_BUSY_STATE(); } #if 0 @@ -965,6 +982,8 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor, 7 * width_1 / 8, height_1); BlitBitmap(tmp_bitmap_32, new_bitmap, 0, 0, width_1 / 32, height_1 / 32, 15 * width_1 / 16, height_1); + + UPDATE_BUSY_STATE(); } else { @@ -1036,6 +1055,8 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor, } #endif + UPDATE_BUSY_STATE(); + FreeBitmap(new_bitmap); /* this actually frees the _old_ bitmap now */ } diff --git a/src/libgame/system.h b/src/libgame/system.h index 4d3ca648..5d26341f 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -48,8 +48,8 @@ #define FULLSCREEN_NOT_AVAILABLE FALSE #define FULLSCREEN_AVAILABLE TRUE -#define CREATE_SPECIAL_EDITION TRUE -#define CREATE_SPECIAL_EDITION_RND_JUE TRUE +#define CREATE_SPECIAL_EDITION FALSE +#define CREATE_SPECIAL_EDITION_RND_JUE FALSE /* default input keys */ #define DEFAULT_KEY_LEFT KSYM_Left @@ -585,6 +585,12 @@ (type) == ARTWORK_TYPE_MUSIC ? \ options.music_directory : "") +#define UPDATE_BUSY_STATE() \ +{ \ + if (gfx.draw_busy_anim_function != NULL) \ + gfx.draw_busy_anim_function(); \ +} + /* type definitions */ typedef int (*EventFilter)(const Event *); @@ -725,6 +731,8 @@ struct GfxInfo int (*get_font_from_token_function)(char *); int anim_random_frame; + + void (*draw_busy_anim_function)(void); }; struct JoystickInfo @@ -1123,6 +1131,7 @@ void InitGfxFieldInfo(int, int, int, int, int, int, int, int, Bitmap *); void InitGfxDoor1Info(int, int, int, int); void InitGfxDoor2Info(int, int, int, int); void InitGfxScrollbufferInfo(int, int); +void InitGfxDrawBusyAnimFunction(void (*draw_busy_anim_function)(void)); void SetDrawDeactivationMask(int); void SetDrawBackgroundMask(int); void SetWindowBackgroundBitmap(Bitmap *); diff --git a/src/libgame/text.c b/src/libgame/text.c index d5d67cda..f5e9c066 100644 --- a/src/libgame/text.c +++ b/src/libgame/text.c @@ -192,8 +192,16 @@ void getFontCharSource(int font_nr, char c, Bitmap **bitmap, int *x, int *y) /* simple text drawing functions */ /* ========================================================================= */ -void DrawInitText(char *text, int ypos, int font_nr) +void DrawInitTextExt(char *text, int ypos, int font_nr, boolean force) { + static unsigned long progress_delay = 0; + unsigned long progress_delay_value = 100; /* (in milliseconds) */ + + UPDATE_BUSY_STATE(); + + if (!force && !DelayReached(&progress_delay, progress_delay_value)) + return; + if (window != NULL && gfx.num_fonts > 0 && gfx.font_bitmap_info[font_nr].bitmap != NULL) @@ -211,6 +219,16 @@ void DrawInitText(char *text, int ypos, int font_nr) } } +void DrawInitText(char *text, int ypos, int font_nr) +{ + DrawInitTextExt(text, ypos, font_nr, TRUE); +} + +void DrawInitTextIfNeeded(char *text, int ypos, int font_nr) +{ + DrawInitTextExt(text, ypos, font_nr, FALSE); +} + void DrawTextF(int x, int y, int font_nr, char *format, ...) { char buffer[MAX_OUTPUT_LINESIZE + 1]; diff --git a/src/libgame/text.h b/src/libgame/text.h index 0f770ba7..146648a3 100644 --- a/src/libgame/text.h +++ b/src/libgame/text.h @@ -74,6 +74,8 @@ int getTextWidth(char *, int); void getFontCharSource(int, char, Bitmap **, int *, int *); void DrawInitText(char *, int, int); +void DrawInitTextIfNeeded(char *, int, int); +void DrawInitTextExt(char *, int, int, boolean); void DrawTextF(int, int, int, char *, ...); void DrawTextFCentered(int, int, char *, ...); void DrawTextS(int, int, int, char *); diff --git a/src/main.c b/src/main.c index 77446322..5813fbd6 100644 --- a/src/main.c +++ b/src/main.c @@ -118,6 +118,7 @@ struct TitleMessageInfo titlemessage_initial[MAX_NUM_TITLE_MESSAGES]; struct TitleMessageInfo titlemessage_default; struct TitleMessageInfo titlemessage[MAX_NUM_TITLE_MESSAGES]; struct TitleMessageInfo readme; +struct InitInfo init; struct MenuInfo menu; struct DoorInfo door_1, door_2; struct PreviewInfo preview; diff --git a/src/main.h b/src/main.h index 223013de..bc09a36d 100644 --- a/src/main.h +++ b/src/main.h @@ -2130,6 +2130,11 @@ struct TitleMessageInfo int auto_delay; }; +struct InitInfo +{ + struct MenuPosInfo busy; +}; + struct MenuInfo { int draw_xoffset[NUM_SPECIAL_GFX_ARGS]; @@ -2771,6 +2776,7 @@ extern struct TitleMessageInfo titlemessage_initial[]; extern struct TitleMessageInfo titlemessage_default; extern struct TitleMessageInfo titlemessage[]; extern struct TitleMessageInfo readme; +extern struct InitInfo init; extern struct MenuInfo menu; extern struct DoorInfo door_1, door_2; extern struct PreviewInfo preview; -- 2.34.1