X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Finit.c;h=114b177fb1578c19f30248069d85bf6a23acb350;hp=3ab46d0f1b2b54e31265149df4209e1dcc6b3016;hb=5e195517fdcbad3043eff72d91399f6a5e604d8b;hpb=12a8fd3a64d6bee5ca5f5b89e4a00b49d78bbd2c diff --git a/src/init.c b/src/init.c index 3ab46d0f..114b177f 100644 --- a/src/init.c +++ b/src/init.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // init.c // ============================================================================ @@ -77,6 +77,11 @@ static int copy_properties[][5] = EL_MOLE_LEFT, EL_MOLE_RIGHT, EL_MOLE_UP, EL_MOLE_DOWN }, + { + EL_SPRING, + EL_SPRING_LEFT, EL_SPRING_RIGHT, + EL_SPRING_LEFT, EL_SPRING_RIGHT, // (to match array size) + }, { -1, -1, -1, -1, -1 @@ -275,6 +280,19 @@ static void InitBitmapPointers(void) void InitImageTextures(void) { + static int texture_graphics[] = + { + IMG_GFX_REQUEST_BUTTON_TOUCH_YES, + IMG_GFX_REQUEST_BUTTON_TOUCH_NO, + IMG_GFX_REQUEST_BUTTON_TOUCH_CONFIRM, + IMG_GFX_GAME_BUTTON_TOUCH_STOP, + IMG_GFX_GAME_BUTTON_TOUCH_PAUSE, + IMG_MENU_BUTTON_TOUCH_BACK, + IMG_MENU_BUTTON_TOUCH_NEXT, + IMG_MENU_BUTTON_TOUCH_BACK2, + IMG_MENU_BUTTON_TOUCH_NEXT2, + -1 + }; int i, j, k; FreeAllImageTextures(); @@ -300,24 +318,10 @@ void InitImageTextures(void) } } } -} -#if 1 -// !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! -void SetBitmaps_EM(Bitmap **em_bitmap) -{ - em_bitmap[0] = graphic_info[IMG_EMC_OBJECT].bitmap; - em_bitmap[1] = graphic_info[IMG_EMC_SPRITE].bitmap; + for (i = 0; texture_graphics[i] > -1; i++) + CreateImageTextures(texture_graphics[i]); } -#endif - -#if 0 -// !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! -void SetBitmaps_SP(Bitmap **sp_bitmap) -{ - *sp_bitmap = graphic_info[IMG_SP_OBJECTS].bitmap; -} -#endif static int getFontBitmapID(int font_nr) { @@ -329,6 +333,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]; @@ -646,15 +652,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 } @@ -696,14 +701,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 } @@ -745,14 +749,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 } @@ -1220,13 +1223,13 @@ static int get_graphic_parameter_value(char *value_raw, char *suffix, int type) if (value == NULL) { - Error(ERR_INFO_LINE, "-"); - Error(ERR_INFO, "warning: error found in config file:"); - Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename()); - Error(ERR_INFO, "error: invalid element token '%s'", value_raw); - Error(ERR_INFO, "custom graphic rejected for this element/action"); - Error(ERR_INFO, "fallback done to undefined element for this graphic"); - Error(ERR_INFO_LINE, "-"); + Warn("---"); + Warn("error found in config file:"); + Warn("- config file: '%s'", getImageConfigFilename()); + Warn("error: invalid element token '%s'", value_raw); + Warn("custom graphic rejected for this element/action"); + Warn("fallback done to undefined element for this graphic"); + Warn("---"); } return (value != NULL ? atoi(value) : EL_UNDEFINED); @@ -1238,13 +1241,13 @@ static int get_graphic_parameter_value(char *value_raw, char *suffix, int type) if (value == NULL) { - Error(ERR_INFO_LINE, "-"); - Error(ERR_INFO, "warning: error found in config file:"); - Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename()); - Error(ERR_INFO, "error: invalid graphic token '%s'", value_raw); - Error(ERR_INFO, "custom graphic rejected for this element/action"); - Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic"); - Error(ERR_INFO_LINE, "-"); + Warn("---"); + Warn("error found in config file:"); + Warn("- config file: '%s'", getImageConfigFilename()); + Warn("error: invalid graphic token '%s'", value_raw); + Warn("custom graphic rejected for this element/action"); + Warn("fallback done to 'char_exclam' for this graphic"); + Warn("---"); } return (value != NULL ? atoi(value) : fallback_graphic); @@ -1297,12 +1300,15 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, g->clone_from = -1; // do not use clone graphic g->init_delay_fixed = 0; g->init_delay_random = 0; + g->init_delay_action = -1; g->anim_delay_fixed = 0; g->anim_delay_random = 0; + g->anim_delay_action = -1; g->post_delay_fixed = 0; g->post_delay_random = 0; - g->init_event = ANIM_EVENT_DEFAULT; - g->anim_event = ANIM_EVENT_DEFAULT; + g->post_delay_action = -1; + g->init_event = ANIM_EVENT_UNDEFINED; + g->anim_event = ANIM_EVENT_UNDEFINED; g->init_event_action = -1; g->anim_event_action = -1; g->draw_masked = FALSE; @@ -1311,6 +1317,7 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, g->fade_delay = -1; g->post_delay = -1; g->auto_delay = -1; + g->auto_delay_unit = AUTO_DELAY_UNIT_DEFAULT; g->align = ALIGN_CENTER; // default for title screens g->valign = VALIGN_MIDDLE; // default for title screens g->sort_priority = 0; // default for title screens @@ -1371,20 +1378,20 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, { if (g->width <= 0) { - Error(ERR_INFO_LINE, "-"); - Error(ERR_WARN, "invalid value %d for '%s.width' (fallback done to %d)", - g->width, getTokenFromImageID(graphic), TILEX); - Error(ERR_INFO_LINE, "-"); + Warn("---"); + Warn("invalid value %d for '%s.width' (fallback done to %d)", + g->width, getTokenFromImageID(graphic), TILEX); + Warn("---"); g->width = TILEX; // will be checked to be inside bitmap later } if (g->height <= 0) { - Error(ERR_INFO_LINE, "-"); - Error(ERR_WARN, "invalid value %d for '%s.height' (fallback done to %d)", - g->height, getTokenFromImageID(graphic), TILEY); - Error(ERR_INFO_LINE, "-"); + Warn("---"); + Warn("invalid value %d for '%s.height' (fallback done to %d)", + g->height, getTokenFromImageID(graphic), TILEY); + Warn("---"); g->height = TILEY; // will be checked to be inside bitmap later } @@ -1472,7 +1479,7 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, else g->anim_frames = 1; - if (g->anim_frames == 0) // frames must be at least 1 + if (g->anim_frames < 1) // frames must be at least 1 g->anim_frames = 1; g->anim_frames_per_line = @@ -1480,7 +1487,7 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, parameter[GFX_ARG_FRAMES_PER_LINE] : anim_frames_per_line); g->anim_delay = parameter[GFX_ARG_DELAY]; - if (g->anim_delay == 0) // delay must be at least 1 + if (g->anim_delay < 1) // delay must be at least 1 g->anim_delay = 1; g->anim_mode = parameter[GFX_ARG_ANIM_MODE]; @@ -1531,6 +1538,12 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, g->init_event_action = parameter[GFX_ARG_INIT_EVENT_ACTION]; if (parameter[GFX_ARG_ANIM_EVENT_ACTION] != ARG_UNDEFINED_VALUE) g->anim_event_action = parameter[GFX_ARG_ANIM_EVENT_ACTION]; + if (parameter[GFX_ARG_INIT_DELAY_ACTION] != ARG_UNDEFINED_VALUE) + g->init_delay_action = parameter[GFX_ARG_INIT_DELAY_ACTION]; + if (parameter[GFX_ARG_ANIM_DELAY_ACTION] != ARG_UNDEFINED_VALUE) + g->anim_delay_action = parameter[GFX_ARG_ANIM_DELAY_ACTION]; + if (parameter[GFX_ARG_POST_DELAY_ACTION] != ARG_UNDEFINED_VALUE) + g->post_delay_action = parameter[GFX_ARG_POST_DELAY_ACTION]; // used for toon animations and global animations g->step_offset = parameter[GFX_ARG_STEP_OFFSET]; @@ -1542,6 +1555,9 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, g->x = parameter[GFX_ARG_X]; // (may be uninitialized, g->y = parameter[GFX_ARG_Y]; // unlike src_x and src_y) + if (g->step_delay < 1) // delay must be at least 1 + g->step_delay = 1; + // this is only used for drawing font characters g->draw_xoffset = parameter[GFX_ARG_DRAW_XOFFSET]; g->draw_yoffset = parameter[GFX_ARG_DRAW_YOFFSET]; @@ -1572,6 +1588,8 @@ static void set_graphic_parameters_ext(int graphic, int *parameter, g->post_delay = parameter[GFX_ARG_POST_DELAY]; if (parameter[GFX_ARG_AUTO_DELAY] != ARG_UNDEFINED_VALUE) g->auto_delay = parameter[GFX_ARG_AUTO_DELAY]; + if (parameter[GFX_ARG_AUTO_DELAY_UNIT] != ARG_UNDEFINED_VALUE) + g->auto_delay_unit = parameter[GFX_ARG_AUTO_DELAY_UNIT]; if (parameter[GFX_ARG_ALIGN] != ARG_UNDEFINED_VALUE) g->align = parameter[GFX_ARG_ALIGN]; if (parameter[GFX_ARG_VALIGN] != ARG_UNDEFINED_VALUE) @@ -1631,18 +1649,18 @@ static void set_cloned_graphic_parameters(int graphic) if (num_references_followed >= max_num_images) { - Error(ERR_INFO_LINE, "-"); - Error(ERR_INFO, "warning: error found in config file:"); - Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename()); - Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(graphic)); - Error(ERR_INFO, "error: loop discovered when resolving cloned graphics"); - Error(ERR_INFO, "custom graphic rejected for this element/action"); + Warn("---"); + Warn("error found in config file:"); + Warn("- config file: '%s'", getImageConfigFilename()); + Warn("- config token: '%s'", getTokenFromImageID(graphic)); + Warn("error: loop discovered when resolving cloned graphics"); + Warn("custom graphic rejected for this element/action"); if (graphic == fallback_graphic) - Error(ERR_EXIT, "no fallback graphic available"); + Fail("no fallback graphic available"); - Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic"); - Error(ERR_INFO_LINE, "-"); + Warn("fallback done to 'char_exclam' for this graphic"); + Warn("---"); graphic_info[graphic] = graphic_info[fallback_graphic]; } @@ -1679,6 +1697,7 @@ static void InitGraphicInfo(void) IMG_BACKGROUND_TITLE_INITIAL, IMG_BACKGROUND_TITLE, IMG_BACKGROUND_MAIN, + IMG_BACKGROUND_NAMES, IMG_BACKGROUND_LEVELS, IMG_BACKGROUND_LEVELNR, IMG_BACKGROUND_SCORES, @@ -1723,6 +1742,8 @@ static void InitGraphicInfo(void) -1 }; + FreeGlobalAnimEventInfo(); + checked_free(graphic_info); graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); @@ -1779,22 +1800,21 @@ static void InitGraphicInfo(void) src_x + width > src_bitmap_width || src_y + height > src_bitmap_height) { - Error(ERR_INFO_LINE, "-"); - Error(ERR_INFO, "warning: error found in config file:"); - Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename()); - Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(i)); - Error(ERR_INFO, "- image file: '%s'", src_bitmap->source_filename); - Error(ERR_INFO, "- frame size: %d, %d", width, height); - Error(ERR_INFO, - "error: first animation frame out of bounds (%d, %d) [%d, %d]", - src_x, src_y, src_bitmap_width, src_bitmap_height); - Error(ERR_INFO, "custom graphic rejected for this element/action"); + Warn("---"); + Warn("error found in config file:"); + Warn("- config file: '%s'", getImageConfigFilename()); + Warn("- config token: '%s'", getTokenFromImageID(i)); + Warn("- image file: '%s'", src_bitmap->source_filename); + Warn("- frame size: %d, %d", width, height); + Warn("error: first animation frame out of bounds (%d, %d) [%d, %d]", + src_x, src_y, src_bitmap_width, src_bitmap_height); + Warn("custom graphic rejected for this element/action"); if (i == fallback_graphic) - Error(ERR_EXIT, "no fallback graphic available"); + Fail("no fallback graphic available"); - Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic"); - Error(ERR_INFO_LINE, "-"); + Warn("fallback done to 'char_exclam' for this graphic"); + Warn("---"); graphic_info[i] = graphic_info[fallback_graphic]; @@ -1811,22 +1831,21 @@ static void InitGraphicInfo(void) src_x + width > src_bitmap_width || src_y + height > src_bitmap_height) { - Error(ERR_INFO_LINE, "-"); - Error(ERR_INFO, "warning: error found in config file:"); - Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename()); - Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(i)); - Error(ERR_INFO, "- image file: '%s'", src_bitmap->source_filename); - Error(ERR_INFO, "- frame size: %d, %d", width, height); - Error(ERR_INFO, - "error: last animation frame (%d) out of bounds (%d, %d) [%d, %d]", - last_frame, src_x, src_y, src_bitmap_width, src_bitmap_height); - Error(ERR_INFO, "custom graphic rejected for this element/action"); + Warn("---"); + Warn("error found in config file:"); + Warn("- config file: '%s'", getImageConfigFilename()); + Warn("- config token: '%s'", getTokenFromImageID(i)); + Warn("- image file: '%s'", src_bitmap->source_filename); + Warn("- frame size: %d, %d", width, height); + Warn("error: last animation frame (%d) out of bounds (%d, %d) [%d, %d]", + last_frame, src_x, src_y, src_bitmap_width, src_bitmap_height); + Warn("custom graphic rejected for this element/action"); if (i == fallback_graphic) - Error(ERR_EXIT, "no fallback graphic available"); + Fail("no fallback graphic available"); - Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic"); - Error(ERR_INFO_LINE, "-"); + Warn("fallback done to 'char_exclam' for this graphic"); + Warn("---"); graphic_info[i] = graphic_info[fallback_graphic]; } @@ -1863,7 +1882,10 @@ 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); +#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; @@ -2341,6 +2363,8 @@ static int get_special_property_bit(int element, int property_bit_nr) { EL_SP_ELECTRON, 15 }, { EL_BALLOON, 16 }, { EL_SPRING, 17 }, + { EL_SPRING_LEFT, 17 }, + { EL_SPRING_RIGHT, 17 }, { EL_EMC_ANDROID, 18 }, { -1, -1 }, @@ -2419,7 +2443,7 @@ static void ResolveGroupElementExt(int group_element, int recursion_depth) if (recursion_depth > NUM_GROUP_ELEMENTS) // recursion too deep { - Error(ERR_WARN, "recursion too deep when resolving group element %d", + Warn("recursion too deep when resolving group element %d", group_element - EL_GROUP_START + 1); // replace element which caused too deep recursion by question mark @@ -2846,6 +2870,7 @@ void InitElementPropertiesStatic(void) EL_BOMB, EL_NUT, EL_AMOEBA_DROP, + EL_AMOEBA_DROPPING, EL_QUICKSAND_FULL, EL_QUICKSAND_FAST_FULL, EL_MAGIC_WALL_FULL, @@ -4639,7 +4664,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))); @@ -4760,7 +4785,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; @@ -4772,7 +4797,7 @@ 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; } @@ -4876,8 +4901,12 @@ 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; @@ -4886,6 +4915,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) @@ -4987,38 +5018,71 @@ 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); - LoadTapeFromFilename(filename); - DumpTape(&tape); + 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.dumptape_leveldir = leveldir; + global.dumptape_level_nr = atoi(level_nr); + + program.headless = TRUE; } - else if (strPrefix(command, "autotest ") || - strPrefix(command, "autoplay ") || + else if (strPrefix(command, "autoplay ") || strPrefix(command, "autoffwd ") || - strPrefix(command, "autowarp ")) + strPrefix(command, "autowarp ") || + strPrefix(command, "autotest ") || + strPrefix(command, "autosave ") || + strPrefix(command, "autoupload ") || + strPrefix(command, "autofix ")) { - char *str_ptr = getStringCopy(&command[9]); // read command parameters + char *arg_ptr = strchr(command, ' '); + char *str_ptr = getStringCopy(arg_ptr); // read command parameters global.autoplay_mode = - (strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST : - strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY : + (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); while (*str_ptr != '\0') // continue parsing string @@ -5053,9 +5117,68 @@ static void Execute_Command(char *command) str_ptr++; } - if (global.autoplay_mode == AUTOPLAY_MODE_TEST) + if (global.autoplay_mode & AUTOPLAY_WARP_NO_DISPLAY) program.headless = TRUE; } + else if (strPrefix(command, "patch tapes ")) + { + char *str_ptr = getStringCopy(&command[12]); // read command parameters + + // skip leading whitespace + while (*str_ptr == ' ' || *str_ptr == '\t') + str_ptr++; + + if (*str_ptr == '\0') + Fail("cannot find MODE in command '%s'", command); + + global.patchtapes_mode = str_ptr; // store patch mode + + // advance to next whitespace (or end of string) + while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0') + str_ptr++; + + while (*str_ptr != '\0') // continue parsing string + { + // cut leading whitespace from string, replace it by string terminator + while (*str_ptr == ' ' || *str_ptr == '\t') + *str_ptr++ = '\0'; + + if (*str_ptr == '\0') // end of string reached + break; + + if (global.patchtapes_leveldir == NULL) // read level set string + { + global.patchtapes_leveldir = str_ptr; + global.patchtapes_all = TRUE; // default: patch all tapes + + for (i = 0; i < MAX_TAPES_PER_SET; i++) + global.patchtapes_level[i] = FALSE; + } + else // read level number string + { + int level_nr = atoi(str_ptr); // get level_nr value + + if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET) + global.patchtapes_level[level_nr] = TRUE; + + global.patchtapes_all = FALSE; + } + + // advance string pointer to the next whitespace (or end of string) + while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0') + str_ptr++; + } + + if (global.patchtapes_leveldir == NULL) + { + if (strEqual(global.patchtapes_mode, "help")) + global.patchtapes_leveldir = UNDEFINED_LEVELSET; + else + Fail("cannot find LEVELDIR in command '%s'", command); + } + + program.headless = TRUE; + } else if (strPrefix(command, "convert ")) { char *str_copy = getStringCopy(strchr(command, ' ') + 1); @@ -5072,13 +5195,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 ")) { @@ -5088,7 +5219,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 @@ -5097,8 +5228,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 @@ -5113,7 +5246,9 @@ static void InitGameInfo(void) { game.restart_level = FALSE; game.restart_game_message = NULL; + game.request_active = FALSE; + game.request_active_or_moving = FALSE; } static void InitPlayerInfo(void) @@ -5379,7 +5514,7 @@ 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(); @@ -5394,7 +5529,7 @@ 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]; @@ -5465,7 +5600,7 @@ static void InitGfx(void) } if (filename_anim_initial == NULL) // should not happen - Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_GLOBAL_BUSY); + Fail("cannot get filename for '%s'", CONFIG_TOKEN_GLOBAL_BUSY); anim_initial.bitmaps = checked_calloc(sizeof(Bitmap *) * NUM_IMG_BITMAP_POINTERS); @@ -5537,36 +5672,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(); @@ -5725,22 +5860,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)) @@ -5749,14 +5889,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; @@ -5781,7 +5923,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) @@ -5800,16 +5943,17 @@ 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 initialized[3] = { FALSE, FALSE, FALSE }; @@ -5844,16 +5988,15 @@ static char *getNewArtworkIdentifier(int type) 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 && + if (last_leveldir_identifier[type] != leveldir_identifier && (last_has_level_artwork_set[type] || has_level_artwork_set)) artwork_new_identifier = artwork_current_identifier; - leveldir_current_identifier[type] = leveldir_identifier; + last_leveldir_identifier[type] = leveldir_identifier; last_has_level_artwork_set[type] = has_level_artwork_set; // ---------- reload if "override artwork" setting has changed -------------- @@ -5863,11 +6006,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]) @@ -5891,7 +6036,8 @@ void ReloadCustomArtwork(int force_reload) InitOverrideArtwork(); - force_reload_gfx |= AdjustGraphicsForEMC(); + AdjustGraphicsForEMC(); + AdjustSoundsForEMC(); gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS); snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS); @@ -5918,11 +6064,12 @@ void ReloadCustomArtwork(int force_reload) 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(); @@ -6048,25 +6195,29 @@ 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); InitNetworkSettings(); + InitRuntimeInfo(); + if (network.serveronly) { #if defined(PLATFORM_UNIX) NetworkServer(network.server_port, TRUE); #else - Error(ERR_WARN, "networking only supported in Unix version"); + Warn("networking only supported in Unix version"); #endif exit(0); // never reached, server loops forever @@ -6083,9 +6234,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]"); @@ -6095,6 +6243,8 @@ void OpenAll(void) InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); InitVideoOverlay(); + InitEventFilter(FilterMouseMotionEvents); + print_timestamp_time("[init video stuff]"); InitElementPropertiesStatic(); @@ -6135,7 +6285,12 @@ void OpenAll(void) if (global.autoplay_leveldir) { - AutoPlayTape(); + AutoPlayTapes(); + return; + } + else if (global.patchtapes_leveldir) + { + PatchTapes(); return; } else if (global.convert_leveldir) @@ -6143,11 +6298,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(); @@ -6161,19 +6331,22 @@ void OpenAll(void) print_timestamp_done("OpenAll"); + if (setup.ask_for_remaining_tapes) + setup.ask_for_uploading_tapes = TRUE; + DrawMainMenu(); #if 0 - Error(ERR_DEBUG, "::: SDL_GetBasePath() == '%s'", + Debug("internal:path", "SDL_GetBasePath() == '%s'", SDL_GetBasePath()); - Error(ERR_DEBUG, "::: SDL_GetPrefPath() == '%s'", + Debug("internal:path", "SDL_GetPrefPath() == '%s'", SDL_GetPrefPath("artsoft", "rocksndiamonds")); #if defined(PLATFORM_ANDROID) - Error(ERR_DEBUG, "::: SDL_AndroidGetInternalStoragePath() == '%s'", + Debug("internal:path", "SDL_AndroidGetInternalStoragePath() == '%s'", SDL_AndroidGetInternalStoragePath()); - Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStoragePath() == '%s'", + Debug("internal:path", "SDL_AndroidGetExternalStoragePath() == '%s'", SDL_AndroidGetExternalStoragePath()); - Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStorageState() == '%s'", + Debug("internal:path", "SDL_AndroidGetExternalStorageState() == '%s'", (SDL_AndroidGetExternalStorageState() & SDL_ANDROID_EXTERNAL_STORAGE_WRITE ? "writable" : SDL_AndroidGetExternalStorageState() & @@ -6182,8 +6355,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(); @@ -6194,16 +6403,13 @@ void CloseAllAndExit(int exit_value) FreeAllImages(); -#if defined(TARGET_SDL) -#if defined(TARGET_SDL2) // !!! TODO !!! // set a flag to tell the network server thread to quit and wait for it // using SDL_WaitThread() -#else - if (network_server) // terminate network server - SDL_KillThread(server_thread); -#endif -#endif + // + // Code used with SDL 1.2: + // if (network.server_thread) // terminate network server + // SDL_KillThread(network.server_thread); CloseVideoDisplay(); ClosePlatformDependentStuff();