X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=b2b93715e3cee12b0aaac719781a5843af10ecfd;hb=be2e24a2d66019f5f8e02bc340cd22ac2f9d693c;hp=bbf62e674f8dd9cb60416716ea11d4cf4628dd62;hpb=4cd59cef0737229da365e385a8762e681a5e471f;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index bbf62e67..b2b93715 100644 --- a/src/init.c +++ b/src/init.c @@ -34,11 +34,26 @@ #define CONFIG_TOKEN_FONT_INITIAL "font.initial" +#define CONFIG_TOKEN_GLOBAL_BUSY_INITIAL "global.busy_initial" #define CONFIG_TOKEN_GLOBAL_BUSY "global.busy" +#define CONFIG_TOKEN_GLOBAL_BUSY_PLAYFIELD "global.busy_playfield" +#define CONFIG_TOKEN_BACKGROUND_LOADING_INITIAL "background.LOADING_INITIAL" +#define CONFIG_TOKEN_BACKGROUND_LOADING "background.LOADING" + +#define INITIAL_IMG_GLOBAL_BUSY_INITIAL 0 +#define INITIAL_IMG_GLOBAL_BUSY 1 +#define INITIAL_IMG_GLOBAL_BUSY_PLAYFIELD 2 + +#define NUM_INITIAL_IMAGES_BUSY 3 + +#define INITIAL_IMG_BACKGROUND_LOADING_INITIAL 3 +#define INITIAL_IMG_BACKGROUND_LOADING 4 + +#define NUM_INITIAL_IMAGES 5 static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS]; -static struct GraphicInfo anim_initial; +static struct GraphicInfo image_initial[NUM_INITIAL_IMAGES]; static int copy_properties[][5] = { @@ -93,10 +108,36 @@ static int copy_properties[][5] = static int get_graphic_parameter_value(char *, char *, int); -static void DrawInitAnim(void) +static void SetLoadingBackgroundImage(void) { struct GraphicInfo *graphic_info_last = graphic_info; - int graphic = 0; + int background_image = (game_status_last_screen == -1 ? + INITIAL_IMG_BACKGROUND_LOADING_INITIAL : + INITIAL_IMG_BACKGROUND_LOADING); + + graphic_info = image_initial; + + SetDrawDeactivationMask(REDRAW_NONE); + SetDrawBackgroundMask(REDRAW_ALL); + + SetWindowBackgroundImage(background_image); + + graphic_info = graphic_info_last; +} + +static void DrawInitAnim(boolean only_when_loading) +{ + struct GraphicInfo *graphic_info_last = graphic_info; + int graphic = (game_status_last_screen == -1 ? + INITIAL_IMG_GLOBAL_BUSY_INITIAL : + game_status == GAME_MODE_LOADING ? + INITIAL_IMG_GLOBAL_BUSY : + INITIAL_IMG_GLOBAL_BUSY_PLAYFIELD); + struct MenuPosInfo *busy = (game_status_last_screen == -1 ? + &init_last.busy_initial : + game_status == GAME_MODE_LOADING ? + &init_last.busy : + &init_last.busy_playfield); static unsigned int action_delay = 0; unsigned int action_delay_value = GameFrameDelay; int sync_frame = FrameCounter; @@ -105,26 +146,26 @@ static void DrawInitAnim(void) // prevent OS (Windows) from complaining about program not responding CheckQuitEvent(); - if (game_status != GAME_MODE_LOADING) + if (game_status != GAME_MODE_LOADING && only_when_loading) return; - if (anim_initial.bitmap == NULL || window == NULL) + if (image_initial[graphic].bitmap == NULL || window == NULL) return; if (!DelayReached(&action_delay, action_delay_value)) return; - if (init_last.busy.x == -1) - init_last.busy.x = WIN_XSIZE / 2; - if (init_last.busy.y == -1) - init_last.busy.y = WIN_YSIZE / 2; + if (busy->x == -1) + busy->x = (game_status == GAME_MODE_LOADING ? WIN_XSIZE / 2 : SXSIZE / 2); + if (busy->y == -1) + busy->y = (game_status == GAME_MODE_LOADING ? WIN_YSIZE / 2 : SYSIZE / 2); - x = ALIGNED_TEXT_XPOS(&init_last.busy); - y = ALIGNED_TEXT_YPOS(&init_last.busy); + x = (game_status == GAME_MODE_LOADING ? 0 : SX) + ALIGNED_TEXT_XPOS(busy); + y = (game_status == GAME_MODE_LOADING ? 0 : SY) + ALIGNED_TEXT_YPOS(busy); - graphic_info = &anim_initial; // graphic == 0 => anim_initial + graphic_info = image_initial; - if (sync_frame % anim_initial.anim_delay == 0) + if (sync_frame % image_initial[graphic].anim_delay == 0) { Bitmap *src_bitmap; int src_x, src_y; @@ -132,8 +173,12 @@ static void DrawInitAnim(void) int height = graphic_info[graphic].height; int frame = getGraphicAnimationFrame(graphic, sync_frame); + ClearRectangleOnBackground(drawto, x, y, width, height); + getFixedGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y); - BlitBitmap(src_bitmap, window, src_x, src_y, width, height, x, y); + BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, width, height, x, y); + + BlitBitmap(drawto, window, x, y, width, height, x, y); } graphic_info = graphic_info_last; @@ -333,6 +378,8 @@ static int getFontBitmapID(int font_nr) special = game_status; else if (game_status == GAME_MODE_PSEUDO_TYPENAME) special = GFX_SPECIAL_ARG_MAIN; + else if (game_status == GAME_MODE_PSEUDO_TYPENAMES) + special = GFX_SPECIAL_ARG_NAMES; if (special != -1) return font_info[font_nr].special_bitmap_id[special]; @@ -650,15 +697,14 @@ static void InitGlobalAnimGraphicInfo(void) } #if 0 - printf("::: InitGlobalAnimGraphicInfo\n"); - for (i = 0; i < NUM_GLOBAL_ANIMS; i++) for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++) for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++) if (global_anim_info[i].graphic[j][k] != IMG_UNDEFINED && graphic_info[global_anim_info[i].graphic[j][k]].bitmap != NULL) - printf("::: - anim %d, part %d, mode %d => %d\n", - i, j, k, global_anim_info[i].graphic[j][k]); + Debug("init:InitGlobalAnimGraphicInfo", + "anim %d, part %d, mode %d => %d", + i, j, k, global_anim_info[i].graphic[j][k]); #endif } @@ -700,14 +746,13 @@ static void InitGlobalAnimSoundInfo(void) } #if 0 - printf("::: InitGlobalAnimSoundInfo\n"); - for (i = 0; i < NUM_GLOBAL_ANIMS; i++) for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++) for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++) if (global_anim_info[i].sound[j][k] != SND_UNDEFINED) - printf("::: - anim %d, part %d, mode %d => %d\n", - i, j, k, global_anim_info[i].sound[j][k]); + Debug("init:InitGlobalAnimSoundInfo", + "anim %d, part %d, mode %d => %d", + i, j, k, global_anim_info[i].sound[j][k]); #endif } @@ -749,14 +794,13 @@ static void InitGlobalAnimMusicInfo(void) } #if 0 - printf("::: InitGlobalAnimMusicInfo\n"); - for (i = 0; i < NUM_GLOBAL_ANIMS; i++) for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++) for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++) if (global_anim_info[i].music[j][k] != MUS_UNDEFINED) - printf("::: - anim %d, part %d, mode %d => %d\n", - i, j, k, global_anim_info[i].music[j][k]); + Debug("init:InitGlobalAnimMusicInfo", + "anim %d, part %d, mode %d => %d", + i, j, k, global_anim_info[i].music[j][k]); #endif } @@ -1658,7 +1702,7 @@ static void set_cloned_graphic_parameters(int graphic) Warn("custom graphic rejected for this element/action"); if (graphic == fallback_graphic) - Error(ERR_EXIT, "no fallback graphic available"); + Fail("no fallback graphic available"); Warn("fallback done to 'char_exclam' for this graphic"); Warn("---"); @@ -1695,12 +1739,16 @@ static void InitGraphicInfo(void) IMG_BACKGROUND_REQUEST, IMG_BACKGROUND, + IMG_BACKGROUND_LOADING_INITIAL, + IMG_BACKGROUND_LOADING, IMG_BACKGROUND_TITLE_INITIAL, IMG_BACKGROUND_TITLE, IMG_BACKGROUND_MAIN, + IMG_BACKGROUND_NAMES, IMG_BACKGROUND_LEVELS, IMG_BACKGROUND_LEVELNR, IMG_BACKGROUND_SCORES, + IMG_BACKGROUND_SCOREINFO, IMG_BACKGROUND_EDITOR, IMG_BACKGROUND_INFO, IMG_BACKGROUND_INFO_ELEMENTS, @@ -1811,7 +1859,7 @@ static void InitGraphicInfo(void) Warn("custom graphic rejected for this element/action"); if (i == fallback_graphic) - Error(ERR_EXIT, "no fallback graphic available"); + Fail("no fallback graphic available"); Warn("fallback done to 'char_exclam' for this graphic"); Warn("---"); @@ -1842,7 +1890,7 @@ static void InitGraphicInfo(void) Warn("custom graphic rejected for this element/action"); if (i == fallback_graphic) - Error(ERR_EXIT, "no fallback graphic available"); + Fail("no fallback graphic available"); Warn("fallback done to 'char_exclam' for this graphic"); Warn("---"); @@ -1882,7 +1930,20 @@ static void InitGraphicCompatibilityInfo(void) // process all images which default to same image as "global.door" if (strEqual(fi->default_filename, fi_global_door->default_filename)) { - // printf("::: special treatment needed for token '%s'\n", fi->token); + // skip all images that are cloned from images that default to same + // image as "global.door", but that are redefined to something else + if (graphic_info[i].clone_from != -1) + { + int cloned_graphic = graphic_info[i].clone_from; + + if (getImageListEntryFromImageID(cloned_graphic)->redefined) + continue; + } + +#if 0 + Debug("init:InitGraphicCompatibilityInfo", + "special treatment needed for token '%s'", fi->token); +#endif graphic_info[i].bitmaps = graphic_info[IMG_GLOBAL_DOOR].bitmaps; graphic_info[i].bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; @@ -2233,6 +2294,13 @@ static void InitMusicInfo(void) } } + +static void InitGameInfoFromArtworkInfo(void) +{ + // special case: store initial value of custom artwork setting + game.use_masked_elements_initial = game.use_masked_elements; +} + static void ReinitializeGraphics(void) { print_timestamp_init("ReinitializeGraphics"); @@ -2266,16 +2334,13 @@ static void ReinitializeGraphics(void) InitGraphicCompatibilityInfo(); print_timestamp_time("InitGraphicCompatibilityInfo"); - SetMainBackgroundImage(IMG_BACKGROUND); - print_timestamp_time("SetMainBackgroundImage"); - SetDoorBackgroundImage(IMG_BACKGROUND_DOOR); - print_timestamp_time("SetDoorBackgroundImage"); - InitGadgets(); print_timestamp_time("InitGadgets"); InitDoors(); print_timestamp_time("InitDoors"); + InitGameInfoFromArtworkInfo(); + print_timestamp_done("ReinitializeGraphics"); } @@ -2997,6 +3062,22 @@ void InitElementPropertiesStatic(void) static int ep_walkable_over[] = { EL_EMPTY_SPACE, + EL_EMPTY_SPACE_1, + EL_EMPTY_SPACE_2, + EL_EMPTY_SPACE_3, + EL_EMPTY_SPACE_4, + EL_EMPTY_SPACE_5, + EL_EMPTY_SPACE_6, + EL_EMPTY_SPACE_7, + EL_EMPTY_SPACE_8, + EL_EMPTY_SPACE_9, + EL_EMPTY_SPACE_10, + EL_EMPTY_SPACE_11, + EL_EMPTY_SPACE_12, + EL_EMPTY_SPACE_13, + EL_EMPTY_SPACE_14, + EL_EMPTY_SPACE_15, + EL_EMPTY_SPACE_16, EL_SP_EMPTY_SPACE, EL_SOKOBAN_FIELD_EMPTY, EL_EXIT_OPEN, @@ -3294,6 +3375,29 @@ void InitElementPropertiesStatic(void) -1 }; + static int ep_empty_space[] = + { + EL_EMPTY_SPACE, + EL_EMPTY_SPACE_1, + EL_EMPTY_SPACE_2, + EL_EMPTY_SPACE_3, + EL_EMPTY_SPACE_4, + EL_EMPTY_SPACE_5, + EL_EMPTY_SPACE_6, + EL_EMPTY_SPACE_7, + EL_EMPTY_SPACE_8, + EL_EMPTY_SPACE_9, + EL_EMPTY_SPACE_10, + EL_EMPTY_SPACE_11, + EL_EMPTY_SPACE_12, + EL_EMPTY_SPACE_13, + EL_EMPTY_SPACE_14, + EL_EMPTY_SPACE_15, + EL_EMPTY_SPACE_16, + + -1 + }; + static int ep_player[] = { EL_PLAYER_1, @@ -4096,6 +4200,22 @@ void InitElementPropertiesStatic(void) static int ep_inactive[] = { EL_EMPTY, + EL_EMPTY_SPACE_1, + EL_EMPTY_SPACE_2, + EL_EMPTY_SPACE_3, + EL_EMPTY_SPACE_4, + EL_EMPTY_SPACE_5, + EL_EMPTY_SPACE_6, + EL_EMPTY_SPACE_7, + EL_EMPTY_SPACE_8, + EL_EMPTY_SPACE_9, + EL_EMPTY_SPACE_10, + EL_EMPTY_SPACE_11, + EL_EMPTY_SPACE_12, + EL_EMPTY_SPACE_13, + EL_EMPTY_SPACE_14, + EL_EMPTY_SPACE_15, + EL_EMPTY_SPACE_16, EL_SAND, EL_WALL, EL_BD_WALL, @@ -4345,6 +4465,7 @@ void InitElementPropertiesStatic(void) EL_INTERNAL_CASCADE_STEEL_CHARS_ACTIVE, EL_INTERNAL_CASCADE_CE_ACTIVE, EL_INTERNAL_CASCADE_GE_ACTIVE, + EL_INTERNAL_CASCADE_ES_ACTIVE, EL_INTERNAL_CASCADE_REF_ACTIVE, EL_INTERNAL_CASCADE_USER_ACTIVE, EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE, @@ -4368,6 +4489,7 @@ void InitElementPropertiesStatic(void) EL_INTERNAL_CASCADE_STEEL_CHARS, EL_INTERNAL_CASCADE_CE, EL_INTERNAL_CASCADE_GE, + EL_INTERNAL_CASCADE_ES, EL_INTERNAL_CASCADE_REF, EL_INTERNAL_CASCADE_USER, EL_INTERNAL_CASCADE_DYNAMIC, @@ -4425,6 +4547,7 @@ void InitElementPropertiesStatic(void) { ep_can_explode, EP_CAN_EXPLODE }, { ep_gravity_reachable, EP_GRAVITY_REACHABLE }, + { ep_empty_space, EP_EMPTY_SPACE }, { ep_player, EP_PLAYER }, { ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL }, { ep_can_pass_dc_magic_wall, EP_CAN_PASS_DC_MAGIC_WALL }, @@ -4661,7 +4784,7 @@ void InitElementPropertiesEngine(int engine_version) i == EL_BLACK_ORB)); // ---------- COULD_MOVE_INTO_ACID ---------------------------------------- - SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (ELEM_IS_PLAYER(i) || + SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (IS_PLAYER_ELEMENT(i) || CAN_MOVE(i) || IS_CUSTOM_ELEMENT(i))); @@ -4686,7 +4809,7 @@ void InitElementPropertiesEngine(int engine_version) // ---------- CAN_BE_CLONED_BY_ANDROID ------------------------------------ for (j = 0; j < level.num_android_clone_elements; j++) SET_PROPERTY(i, EP_CAN_BE_CLONED_BY_ANDROID, - (i != EL_EMPTY && + (!IS_EMPTY(i) && IS_EQUAL_OR_IN_GROUP(i, level.android_clone_element[j]))); // ---------- CAN_CHANGE -------------------------------------------------- @@ -4782,7 +4905,7 @@ static void InitGlobal(void) { // check if element_name_info entry defined for each element in "main.h" if (i < MAX_NUM_ELEMENTS && element_name_info[i].token_name == NULL) - Error(ERR_EXIT, "undefined 'element_name_info' entry for element %d", i); + Fail("undefined 'element_name_info' entry for element %d", i); element_info[i].token_name = element_name_info[i].token_name; element_info[i].class_name = element_name_info[i].class_name; @@ -4794,11 +4917,14 @@ static void InitGlobal(void) // check if global_anim_name_info defined for each entry in "main.h" if (i < NUM_GLOBAL_ANIM_TOKENS && global_anim_name_info[i].token_name == NULL) - Error(ERR_EXIT, "undefined 'global_anim_name_info' entry for anim %d", i); + Fail("undefined 'global_anim_name_info' entry for anim %d", i); global_anim_info[i].token_name = global_anim_name_info[i].token_name; } + // create hash to store URLs for global animations + anim_url_hash = newSetupFileHash(); + // create hash from image config list image_config_hash = newSetupFileHash(); for (i = 0; image_config[i].token != NULL; i++) @@ -4900,7 +5026,10 @@ static void InitGlobal(void) global.autoplay_leveldir = NULL; global.patchtapes_leveldir = NULL; global.convert_leveldir = NULL; - global.create_images_dir = NULL; + global.dumplevel_leveldir = NULL; + global.dumptape_leveldir = NULL; + global.create_sketch_images_dir = NULL; + global.create_collect_images_dir = NULL; global.frames_per_second = 0; global.show_frames_per_second = FALSE; @@ -4909,6 +5038,8 @@ static void InitGlobal(void) global.anim_status = global.anim_status_next = GAME_MODE_LOADING; global.use_envelope_request = FALSE; + + global.user_names = NULL; } static void Execute_Command(char *command) @@ -5010,39 +5141,70 @@ static void Execute_Command(char *command) { char *filename = &command[11]; - if (!fileExists(filename)) - Error(ERR_EXIT, "cannot open file '%s'", filename); + if (fileExists(filename)) + { + LoadLevelFromFilename(&level, filename); + DumpLevel(&level); - LoadLevelFromFilename(&level, filename); - DumpLevel(&level); + exit(0); + } - exit(0); + char *leveldir = getStringCopy(filename); // read command parameters + char *level_nr = strchr(leveldir, ' '); + + if (level_nr == NULL) + Fail("cannot open file '%s'", filename); + + *level_nr++ = '\0'; + + global.dumplevel_leveldir = leveldir; + global.dumplevel_level_nr = atoi(level_nr); + + program.headless = TRUE; } else if (strPrefix(command, "dump tape ")) { char *filename = &command[10]; - if (!fileExists(filename)) - Error(ERR_EXIT, "cannot open file '%s'", filename); + if (fileExists(filename)) + { + LoadTapeFromFilename(filename); + DumpTape(&tape); + + exit(0); + } + + char *leveldir = getStringCopy(filename); // read command parameters + char *level_nr = strchr(leveldir, ' '); - LoadTapeFromFilename(filename); - DumpTape(&tape); + if (level_nr == NULL) + Fail("cannot open file '%s'", filename); - exit(0); + *level_nr++ = '\0'; + + global.dumptape_leveldir = leveldir; + global.dumptape_level_nr = atoi(level_nr); + + program.headless = TRUE; } else if (strPrefix(command, "autoplay ") || strPrefix(command, "autoffwd ") || strPrefix(command, "autowarp ") || strPrefix(command, "autotest ") || + strPrefix(command, "autosave ") || + strPrefix(command, "autoupload ") || strPrefix(command, "autofix ")) { - char *str_ptr = getStringCopy(&command[8]); // read command parameters + char *arg_ptr = strchr(command, ' '); + char *str_ptr = getStringCopy(arg_ptr); // read command parameters global.autoplay_mode = (strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY : strPrefix(command, "autoffwd") ? AUTOPLAY_MODE_FFWD : strPrefix(command, "autowarp") ? AUTOPLAY_MODE_WARP : strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST : + strPrefix(command, "autosave") ? AUTOPLAY_MODE_SAVE : + strPrefix(command, "autoupload") ? AUTOPLAY_MODE_UPLOAD : strPrefix(command, "autofix") ? AUTOPLAY_MODE_FIX : AUTOPLAY_MODE_NONE); @@ -5090,7 +5252,7 @@ static void Execute_Command(char *command) str_ptr++; if (*str_ptr == '\0') - Error(ERR_EXIT, "cannot find MODE in command '%s'", command); + Fail("cannot find MODE in command '%s'", command); global.patchtapes_mode = str_ptr; // store patch mode @@ -5135,7 +5297,7 @@ static void Execute_Command(char *command) if (strEqual(global.patchtapes_mode, "help")) global.patchtapes_leveldir = UNDEFINED_LEVELSET; else - Error(ERR_EXIT, "cannot find LEVELDIR in command '%s'", command); + Fail("cannot find LEVELDIR in command '%s'", command); } program.headless = TRUE; @@ -5156,13 +5318,21 @@ static void Execute_Command(char *command) program.headless = TRUE; } - else if (strPrefix(command, "create images ")) + else if (strPrefix(command, "create sketch images ")) + { + global.create_sketch_images_dir = getStringCopy(&command[21]); + + if (access(global.create_sketch_images_dir, W_OK) != 0) + Fail("image target directory '%s' not found or not writable", + global.create_sketch_images_dir); + } + else if (strPrefix(command, "create collect image ")) { - global.create_images_dir = getStringCopy(&command[14]); + global.create_collect_images_dir = getStringCopy(&command[21]); - if (access(global.create_images_dir, W_OK) != 0) - Error(ERR_EXIT, "image target directory '%s' not found or not writable", - global.create_images_dir); + if (access(global.create_collect_images_dir, W_OK) != 0) + Fail("image target directory '%s' not found or not writable", + global.create_collect_images_dir); } else if (strPrefix(command, "create CE image ")) { @@ -5172,7 +5342,7 @@ static void Execute_Command(char *command) } else { - Error(ERR_EXIT_HELP, "unrecognized command '%s'", command); + FailWithHelp("unrecognized command '%s'", command); } // disable networking if any valid command was recognized @@ -5181,8 +5351,10 @@ static void Execute_Command(char *command) static void InitSetup(void) { + LoadUserNames(); // global user names + LoadUserSetup(); // global user number + LoadSetup(); // global setup info - LoadSetup_AutoSetup(); // global auto setup info // set some options from setup file @@ -5197,7 +5369,11 @@ static void InitGameInfo(void) { game.restart_level = FALSE; game.restart_game_message = NULL; + game.request_active = FALSE; + game.request_active_or_moving = FALSE; + + game.use_masked_elements_initial = FALSE; } static void InitPlayerInfo(void) @@ -5424,9 +5600,24 @@ static void InitGfx(void) { struct GraphicInfo *graphic_info_last = graphic_info; char *filename_font_initial = NULL; - char *filename_anim_initial = NULL; + char *filename_image_initial[NUM_INITIAL_IMAGES] = { NULL }; + char *image_token[NUM_INITIAL_IMAGES] = + { + CONFIG_TOKEN_GLOBAL_BUSY_INITIAL, + CONFIG_TOKEN_GLOBAL_BUSY, + CONFIG_TOKEN_GLOBAL_BUSY_PLAYFIELD, + CONFIG_TOKEN_BACKGROUND_LOADING_INITIAL, + CONFIG_TOKEN_BACKGROUND_LOADING + }; + struct MenuPosInfo *init_busy[NUM_INITIAL_IMAGES_BUSY] = + { + &init.busy_initial, + &init.busy, + &init.busy_playfield + }; Bitmap *bitmap_font_initial = NULL; - int i, j; + int parameter[NUM_INITIAL_IMAGES][NUM_GFX_ARGS]; + int i, j, k; // determine settings for initial font (for displaying startup messages) for (i = 0; image_config[i].token != NULL; i++) @@ -5440,7 +5631,9 @@ static void InitGfx(void) len_font_token = strlen(font_token); if (strEqual(image_config[i].token, font_token)) + { filename_font_initial = image_config[i].value; + } else if (strlen(image_config[i].token) > len_font_token && strncmp(image_config[i].token, font_token, len_font_token) == 0) { @@ -5463,12 +5656,14 @@ static void InitGfx(void) } if (filename_font_initial == NULL) // should not happen - Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL); + Fail("cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL); InitGfxBuffers(); InitGfxCustomArtworkInfo(); InitGfxOtherSettings(); + InitGfxTileSizeInfo(TILESIZE, TILESIZE); + bitmap_font_initial = LoadCustomImage(filename_font_initial); for (j = 0; j < NUM_INITIAL_FONTS; j++) @@ -5478,19 +5673,19 @@ static void InitGfx(void) DrawProgramInfo(); - DrawInitText("Loading graphics", 120, FC_GREEN); + DrawInitTextHead("Loading graphics"); - // initialize settings for busy animation with default values - int parameter[NUM_GFX_ARGS]; - for (i = 0; i < NUM_GFX_ARGS; i++) - parameter[i] = get_graphic_parameter_value(image_config_suffix[i].value, - image_config_suffix[i].token, - image_config_suffix[i].type); + InitMenuDesignSettings_Static(); - char *anim_token = CONFIG_TOKEN_GLOBAL_BUSY; - int len_anim_token = strlen(anim_token); + // initialize settings for initial images with default values + for (i = 0; i < NUM_INITIAL_IMAGES; i++) + for (j = 0; j < NUM_GFX_ARGS; j++) + parameter[i][j] = + get_graphic_parameter_value(image_config_suffix[j].value, + image_config_suffix[j].token, + image_config_suffix[j].type); - // read settings for busy animation from default custom artwork config + // read settings for initial images from default custom artwork config char *gfx_config_filename = getPath3(options.graphics_directory, GFX_DEFAULT_SUBDIR, GRAPHICSINFO_FILENAME); @@ -5501,74 +5696,99 @@ static void InitGfx(void) if (setup_file_hash) { - char *filename = getHashEntry(setup_file_hash, anim_token); - - if (filename) + for (i = 0; i < NUM_INITIAL_IMAGES; i++) { - filename_anim_initial = getStringCopy(filename); + char *filename = getHashEntry(setup_file_hash, image_token[i]); - for (j = 0; image_config_suffix[j].token != NULL; j++) + if (filename) { - int type = image_config_suffix[j].type; - char *suffix = image_config_suffix[j].token; - char *token = getStringCat2(anim_token, suffix); - char *value = getHashEntry(setup_file_hash, token); + filename_image_initial[i] = getStringCopy(filename); - checked_free(token); + for (j = 0; image_config_suffix[j].token != NULL; j++) + { + int type = image_config_suffix[j].type; + char *suffix = image_config_suffix[j].token; + char *token = getStringCat2(image_token[i], suffix); + char *value = getHashEntry(setup_file_hash, token); + + checked_free(token); - if (value) - parameter[j] = get_graphic_parameter_value(value, suffix, type); + if (value) + parameter[i][j] = + get_graphic_parameter_value(value, suffix, type); + } } } + // read values from custom graphics config file + InitMenuDesignSettings_FromHash(setup_file_hash, FALSE); + freeSetupFileHash(setup_file_hash); } } - if (filename_anim_initial == NULL) + for (i = 0; i < NUM_INITIAL_IMAGES; i++) { - // read settings for busy animation from static default artwork config - for (i = 0; image_config[i].token != NULL; i++) + if (filename_image_initial[i] == NULL) { - if (strEqual(image_config[i].token, anim_token)) - filename_anim_initial = getStringCopy(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) + int len_token = strlen(image_token[i]); + + // read settings for initial images from static default artwork config + for (j = 0; image_config[j].token != NULL; j++) { - for (j = 0; image_config_suffix[j].token != NULL; j++) + if (strEqual(image_config[j].token, image_token[i])) + { + filename_image_initial[i] = getStringCopy(image_config[j].value); + } + else if (strlen(image_config[j].token) > len_token && + strncmp(image_config[j].token, image_token[i], len_token) == 0) { - if (strEqual(&image_config[i].token[len_anim_token], - image_config_suffix[j].token)) - parameter[j] = - get_graphic_parameter_value(image_config[i].value, - image_config_suffix[j].token, - image_config_suffix[j].type); + for (k = 0; image_config_suffix[k].token != NULL; k++) + { + if (strEqual(&image_config[j].token[len_token], + image_config_suffix[k].token)) + parameter[i][k] = + get_graphic_parameter_value(image_config[j].value, + image_config_suffix[k].token, + image_config_suffix[k].type); + } } } } } - if (filename_anim_initial == NULL) // should not happen - Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_GLOBAL_BUSY); + for (i = 0; i < NUM_INITIAL_IMAGES; i++) + { + if (filename_image_initial[i] == NULL) // should not happen + Fail("cannot get filename for '%s'", image_token[i]); - anim_initial.bitmaps = - checked_calloc(sizeof(Bitmap *) * NUM_IMG_BITMAP_POINTERS); + image_initial[i].bitmaps = + checked_calloc(sizeof(Bitmap *) * NUM_IMG_BITMAP_POINTERS); - anim_initial.bitmaps[IMG_BITMAP_STANDARD] = - LoadCustomImage(filename_anim_initial); + if (!strEqual(filename_image_initial[i], UNDEFINED_FILENAME)) + image_initial[i].bitmaps[IMG_BITMAP_STANDARD] = + LoadCustomImage(filename_image_initial[i]); - checked_free(filename_anim_initial); + checked_free(filename_image_initial[i]); + } - graphic_info = &anim_initial; // graphic == 0 => anim_initial + graphic_info = image_initial; // graphic == 0 => image_initial - set_graphic_parameters_ext(0, parameter, anim_initial.bitmaps); + for (i = 0; i < NUM_INITIAL_IMAGES; i++) + set_graphic_parameters_ext(i, parameter[i], image_initial[i].bitmaps); graphic_info = graphic_info_last; - init.busy.width = anim_initial.width; - init.busy.height = anim_initial.height; + for (i = 0; i < NUM_INITIAL_IMAGES_BUSY; i++) + { + // set image size for busy animations + init_busy[i]->width = image_initial[i].width; + init_busy[i]->height = image_initial[i].height; + } - InitMenuDesignSettings_Static(); + SetLoadingBackgroundImage(); + + ClearRectangleOnBackground(window, 0, 0, WIN_XSIZE, WIN_YSIZE); InitGfxDrawBusyAnimFunction(DrawInitAnim); InitGfxDrawGlobalAnimFunction(DrawGlobalAnimations); @@ -5621,36 +5841,36 @@ static void InitImages(void) print_timestamp_init("InitImages"); #if 0 - printf("::: leveldir_current->identifier == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier); - printf("::: leveldir_current->graphics_path == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path); - printf("::: leveldir_current->graphics_set == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set); - printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n", - leveldir_current == NULL ? "[NULL]" : LEVELDIR_ARTWORK_SET(leveldir_current, ARTWORK_TYPE_GRAPHICS)); + Debug("init:InitImages", "leveldir_current->identifier == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier); + Debug("init:InitImages", "leveldir_current->graphics_path == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path); + Debug("init:InitImages", "leveldir_current->graphics_set == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set); + Debug("init:InitImages", "getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'", + leveldir_current == NULL ? "[NULL]" : LEVELDIR_ARTWORK_SET(leveldir_current, ARTWORK_TYPE_GRAPHICS)); #endif setLevelArtworkDir(artwork.gfx_first); #if 0 - printf("::: leveldir_current->identifier == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier); - printf("::: leveldir_current->graphics_path == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path); - printf("::: leveldir_current->graphics_set == '%s'\n", + Debug("init:InitImages", "leveldir_current->identifier == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier); + Debug("init:InitImages", "leveldir_current->graphics_path == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path); + Debug("init:InitImages", "leveldir_current->graphics_set == '%s'", leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set); - printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n", - leveldir_current == NULL ? "[NULL]" : LEVELDIR_ARTWORK_SET(leveldir_current, ARTWORK_TYPE_GRAPHICS)); + Debug("init:InitImages", "getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'", + leveldir_current == NULL ? "[NULL]" : LEVELDIR_ARTWORK_SET(leveldir_current, ARTWORK_TYPE_GRAPHICS)); #endif #if 0 - printf("::: InitImages for '%s' ['%s', '%s'] ['%s', '%s']\n", - leveldir_current->identifier, - artwork.gfx_current_identifier, - artwork.gfx_current->identifier, - leveldir_current->graphics_set, - leveldir_current->graphics_path); + Debug("init:InitImages", "InitImages for '%s' ['%s', '%s'] ['%s', '%s']", + leveldir_current->identifier, + artwork.gfx_current_identifier, + artwork.gfx_current->identifier, + leveldir_current->graphics_set, + leveldir_current->graphics_path); #endif UPDATE_BUSY_STATE(); @@ -5809,22 +6029,27 @@ static boolean CheckArtworkTypeForRedefinedCustomElements(int type) setLevelArtworkDir(ARTWORK_FIRST_NODE(artwork, type)); #if 0 - printf("::: leveldir_current->identifier == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier); - printf("::: leveldir_current->graphics_path == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path); - printf("::: leveldir_current->graphics_set == '%s'\n", - leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set); - printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n", - leveldir_current == NULL ? "[NULL]" : - LEVELDIR_ARTWORK_SET(leveldir_current, type)); + Debug("init:CheckArtworkTypeForRedefinedCustomElements", + "leveldir_current->identifier == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier); + Debug("init:CheckArtworkTypeForRedefinedCustomElements", + "leveldir_current->graphics_path == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path); + Debug("init:CheckArtworkTypeForRedefinedCustomElements", + "leveldir_current->graphics_set == '%s'", + leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set); + Debug("init:CheckArtworkTypeForRedefinedCustomElements", + "getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'", + leveldir_current == NULL ? "[NULL]" : + LEVELDIR_ARTWORK_SET(leveldir_current, type)); #endif // first look for special artwork configured in level series config filename_base = getCustomArtworkLevelConfigFilename(type); #if 0 - printf("::: filename_base == '%s'\n", filename_base); + Debug("init:CheckArtworkTypeForRedefinedCustomElements", + "filename_base == '%s'", filename_base); #endif if (fileExists(filename_base)) @@ -5833,14 +6058,16 @@ static boolean CheckArtworkTypeForRedefinedCustomElements(int type) filename_local = getCustomArtworkConfigFilename(type); #if 0 - printf("::: filename_local == '%s'\n", filename_local); + Debug("init:CheckArtworkTypeForRedefinedCustomElements", + "filename_local == '%s'", filename_local); #endif if (filename_local != NULL && !strEqual(filename_base, filename_local)) redefined_ce_found |= CheckArtworkConfigForCustomElements(filename_local); #if 0 - printf("::: redefined_ce_found == %d\n", redefined_ce_found); + Debug("init:CheckArtworkTypeForRedefinedCustomElements", + "redefined_ce_found == %d", redefined_ce_found); #endif return redefined_ce_found; @@ -5865,7 +6092,8 @@ static void InitOverrideArtwork(void) CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_MUSIC)); #if 0 - printf("::: redefined_ce_found == %d\n", redefined_ce_found); + Debug("init:InitOverrideArtwork", "redefined_ce_found == %d", + redefined_ce_found); #endif if (redefined_ce_found) @@ -5884,18 +6112,19 @@ static void InitOverrideArtwork(void) } #if 0 - printf("::: => %d, %d, %d\n", - gfx.override_level_graphics, - gfx.override_level_sounds, - gfx.override_level_music); + Debug("init:InitOverrideArtwork", "%d, %d, %d", + gfx.override_level_graphics, + gfx.override_level_sounds, + gfx.override_level_music); #endif } static char *getNewArtworkIdentifier(int type) { - static char *leveldir_current_identifier[3] = { NULL, NULL, NULL }; + static char *last_leveldir_identifier[3] = { NULL, NULL, NULL }; + static char *last_artwork_identifier[3] = { NULL, NULL, NULL }; static boolean last_override_level_artwork[3] = { FALSE, FALSE, FALSE }; - static boolean last_has_level_artwork_set[3] = { FALSE, FALSE, FALSE }; + static boolean last_has_custom_artwork_set[3] = { FALSE, FALSE, FALSE }; static boolean initialized[3] = { FALSE, FALSE, FALSE }; TreeInfo *artwork_first_node = ARTWORK_FIRST_NODE(artwork, type); boolean setup_override_artwork = GFX_OVERRIDE_ARTWORK(type); @@ -5904,6 +6133,9 @@ static char *getNewArtworkIdentifier(int type) // !!! setLevelArtworkDir() should be moved to an earlier stage !!! char *leveldir_artwork_set = setLevelArtworkDir(artwork_first_node); boolean has_level_artwork_set = (leveldir_artwork_set != NULL); + TreeInfo *custom_artwork_set = + getTreeInfoFromIdentifier(artwork_first_node, leveldir_identifier); + boolean has_custom_artwork_set = (custom_artwork_set != NULL); char *artwork_current_identifier; char *artwork_new_identifier = NULL; // default: nothing has changed @@ -5921,24 +6153,23 @@ static char *getNewArtworkIdentifier(int type) if (setup_override_artwork) artwork_current_identifier = setup_artwork_set; - else if (leveldir_artwork_set != NULL) + else if (has_level_artwork_set) artwork_current_identifier = leveldir_artwork_set; - else if (getTreeInfoFromIdentifier(artwork_first_node, leveldir_identifier)) + else if (has_custom_artwork_set) artwork_current_identifier = leveldir_identifier; else artwork_current_identifier = setup_artwork_set; - /* 2nd step: check if it is really needed to reload artwork set ------------------------------------------------------------ */ // ---------- reload if level set and also artwork set has changed ---------- - if (leveldir_current_identifier[type] != leveldir_identifier && - (last_has_level_artwork_set[type] || has_level_artwork_set)) + if (last_leveldir_identifier[type] != leveldir_identifier && + (last_has_custom_artwork_set[type] || has_custom_artwork_set)) artwork_new_identifier = artwork_current_identifier; - leveldir_current_identifier[type] = leveldir_identifier; - last_has_level_artwork_set[type] = has_level_artwork_set; + last_leveldir_identifier[type] = leveldir_identifier; + last_has_custom_artwork_set[type] = has_custom_artwork_set; // ---------- reload if "override artwork" setting has changed -------------- if (last_override_level_artwork[type] != setup_override_artwork) @@ -5947,11 +6178,13 @@ static char *getNewArtworkIdentifier(int type) last_override_level_artwork[type] = setup_override_artwork; // ---------- reload if current artwork identifier has changed -------------- - if (!strEqual(ARTWORK_CURRENT_IDENTIFIER(artwork, type), - artwork_current_identifier)) + if (!strEqual(last_artwork_identifier[type], artwork_current_identifier)) artwork_new_identifier = artwork_current_identifier; - *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type))= artwork_current_identifier; + // (we cannot compare string pointers here, so copy string content itself) + setString(&last_artwork_identifier[type], artwork_current_identifier); + + *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type)) = artwork_current_identifier; // ---------- do not reload directly after starting ------------------------- if (!initialized[type]) @@ -5975,8 +6208,8 @@ void ReloadCustomArtwork(int force_reload) InitOverrideArtwork(); - force_reload_gfx |= AdjustGraphicsForEMC(); - force_reload_snd |= AdjustSoundsForEMC(); + AdjustGraphicsForEMC(); + AdjustSoundsForEMC(); gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS); snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS); @@ -5995,19 +6228,24 @@ void ReloadCustomArtwork(int force_reload) FadeOut(REDRAW_ALL); - ClearRectangle(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE); - print_timestamp_time("ClearRectangle"); + SetLoadingBackgroundImage(); + + ClearRectangleOnBackground(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE); + print_timestamp_time("ClearRectangleOnBackground"); FadeIn(REDRAW_ALL); + UPDATE_BUSY_STATE(); + if (gfx_new_identifier != NULL || force_reload_gfx) { #if 0 - printf("RELOADING GRAPHICS '%s' -> '%s' ['%s', '%s']\n", - artwork.gfx_current_identifier, - gfx_new_identifier, - artwork.gfx_current->identifier, - leveldir_current->graphics_set); + Debug("init:ReloadCustomArtwork", + "RELOADING GRAPHICS '%s' -> '%s' ['%s', '%s']", + artwork.gfx_current_identifier, + gfx_new_identifier, + artwork.gfx_current->identifier, + leveldir_current->graphics_set); #endif InitImages(); @@ -6030,8 +6268,6 @@ void ReloadCustomArtwork(int force_reload) SetGameStatus(last_game_status); // restore current game status - init_last = init; // switch to new busy animation - FadeOut(REDRAW_ALL); RedrawGlobalBorder(); @@ -6133,14 +6369,16 @@ void OpenAll(void) InitGlobal(); // initialize some global variables + InitRND(NEW_RANDOMIZE); + InitSimpleRandom(NEW_RANDOMIZE); + InitBetterRandom(NEW_RANDOMIZE); + print_timestamp_time("[init global stuff]"); InitSetup(); print_timestamp_time("[init setup/config stuff (1)]"); - InitScoresInfo(); - if (options.execute_command) Execute_Command(options.execute_command); @@ -6170,9 +6408,6 @@ void OpenAll(void) InitMixer(); print_timestamp_time("[init setup/config stuff (6)]"); - InitRND(NEW_RANDOMIZE); - InitSimpleRandom(NEW_RANDOMIZE); - InitJoysticks(); print_timestamp_time("[init setup/config stuff]"); @@ -6237,11 +6472,26 @@ void OpenAll(void) ConvertLevels(); return; } - else if (global.create_images_dir) + else if (global.dumplevel_leveldir) + { + DumpLevels(); + return; + } + else if (global.dumptape_leveldir) + { + DumpTapes(); + return; + } + else if (global.create_sketch_images_dir) { CreateLevelSketchImages(); return; } + else if (global.create_collect_images_dir) + { + CreateCollectElementImages(); + return; + } InitNetworkServer(); @@ -6255,6 +6505,9 @@ void OpenAll(void) print_timestamp_done("OpenAll"); + if (setup.ask_for_remaining_tapes) + setup.ask_for_uploading_tapes = TRUE; + DrawMainMenu(); #if 0 @@ -6276,8 +6529,44 @@ void OpenAll(void) #endif } +static boolean WaitForApiThreads(void) +{ + unsigned int thread_delay = 0; + unsigned int thread_delay_value = 10000; + + if (program.api_thread_count == 0) + return TRUE; + + // deactivate global animations (not accessible in game state "loading") + setup.toons = FALSE; + + // set game state to "loading" to be able to show busy animation + SetGameStatus(GAME_MODE_LOADING); + + ResetDelayCounter(&thread_delay); + + // wait for threads to finish (and fail on timeout) + while (program.api_thread_count > 0) + { + if (DelayReached(&thread_delay, thread_delay_value)) + { + Error("failed waiting for threads - TIMEOUT"); + + return FALSE; + } + + UPDATE_BUSY_STATE(); + + Delay(20); + } + + return TRUE; +} + void CloseAllAndExit(int exit_value) { + WaitForApiThreads(); + StopSounds(); FreeAllSounds(); FreeAllMusic(); @@ -6293,8 +6582,8 @@ void CloseAllAndExit(int exit_value) // using SDL_WaitThread() // // Code used with SDL 1.2: - // if (network_server) // terminate network server - // SDL_KillThread(server_thread); + // if (network.server_thread) // terminate network server + // SDL_KillThread(network.server_thread); CloseVideoDisplay(); ClosePlatformDependentStuff();