X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=708ab4a67d66058c99945acf9cc43733631e2b0e;hb=1e5cae5e3ab889c3bcba80a065c6d7ba1e6d28a2;hp=a6caa27281be0506801eff4642de87776d311f92;hpb=86e1890b2d87dd7710b320e2b306c7291d41e2a5;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index a6caa272..708ab4a6 100644 --- a/src/init.c +++ b/src/init.c @@ -37,182 +37,45 @@ #define CONFIG_TOKEN_FONT_INITIAL "font.initial" -struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS]; +static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS]; - -static void InitTileClipmasks() +static int copy_properties[][5] = { -#if 0 -#if defined(TARGET_X11) - XGCValues clip_gc_values; - unsigned long clip_gc_valuemask; - -#if defined(TARGET_X11_NATIVE) - -#if 0 - GC copy_clipmask_gc; - - static struct { - int start; - int count; - } - tile_needs_clipping[] = - { - { GFX_SPIELER1_UP, 4 }, - { GFX_SPIELER1_DOWN, 4 }, - { GFX_SPIELER1_LEFT, 4 }, - { GFX_SPIELER1_RIGHT, 4 }, - { GFX_SPIELER1_PUSH_LEFT, 4 }, - { GFX_SPIELER1_PUSH_RIGHT, 4 }, - { GFX_SPIELER2_UP, 4 }, - { GFX_SPIELER2_DOWN, 4 }, - { GFX_SPIELER2_LEFT, 4 }, - { GFX_SPIELER2_RIGHT, 4 }, - { GFX_SPIELER2_PUSH_LEFT, 4 }, - { GFX_SPIELER2_PUSH_RIGHT, 4 }, - { GFX_SPIELER3_UP, 4 }, - { GFX_SPIELER3_DOWN, 4 }, - { GFX_SPIELER3_LEFT, 4 }, - { GFX_SPIELER3_RIGHT, 4 }, - { GFX_SPIELER3_PUSH_LEFT, 4 }, - { GFX_SPIELER3_PUSH_RIGHT, 4 }, - { GFX_SPIELER4_UP, 4 }, - { GFX_SPIELER4_DOWN, 4 }, - { GFX_SPIELER4_LEFT, 4 }, - { GFX_SPIELER4_RIGHT, 4 }, - { GFX_SPIELER4_PUSH_LEFT, 4 }, - { GFX_SPIELER4_PUSH_RIGHT, 4 }, - { GFX_SP_MURPHY, 1 }, - { GFX_MURPHY_GO_LEFT, 3 }, - { GFX_MURPHY_GO_RIGHT, 3 }, - { GFX_MURPHY_SNAP_UP, 1 }, - { GFX_MURPHY_SNAP_DOWN, 1 }, - { GFX_MURPHY_SNAP_RIGHT, 1 }, - { GFX_MURPHY_SNAP_LEFT, 1 }, - { GFX_MURPHY_PUSH_RIGHT, 1 }, - { GFX_MURPHY_PUSH_LEFT, 1 }, - { GFX_GEBLUBBER, 4 }, - { GFX_DYNAMIT, 7 }, - { GFX_DYNABOMB, 4 }, - { GFX_EXPLOSION, 8 }, - { GFX_SOKOBAN_OBJEKT, 1 }, - { GFX_FUNKELN_BLAU, 3 }, - { GFX_FUNKELN_WEISS, 3 }, - { GFX2_SHIELD_PASSIVE, 3 }, - { GFX2_SHIELD_ACTIVE, 3 }, - { -1, 0 } - }; -#endif - -#endif /* TARGET_X11_NATIVE */ -#endif /* TARGET_X11 */ - - int i; - - /* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */ - for (i = 0; i < NUM_TILES; i++) - tile_clipmask[i] = None; - -#if defined(TARGET_X11) - /* This stuff is needed because X11 (XSetClipOrigin(), to be precise) is - often very slow when preparing a masked XCopyArea() for big Pixmaps. - To prevent this, create small (tile-sized) mask Pixmaps which will then - be set much faster with XSetClipOrigin() and speed things up a lot. */ - - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - tile_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask, &clip_gc_values); - -#if 0 - for (i = 0; i < NUM_BITMAPS; i++) + EL_BUG, + EL_BUG_LEFT, EL_BUG_RIGHT, + EL_BUG_UP, EL_BUG_DOWN + }, { - if (pix[i]->clip_mask) - { - clip_gc_values.graphics_exposures = False; - clip_gc_values.clip_mask = pix[i]->clip_mask; - clip_gc_valuemask = GCGraphicsExposures | GCClipMask; - pix[i]->stored_clip_gc = XCreateGC(display, window->drawable, - clip_gc_valuemask, &clip_gc_values); - } - } -#endif - -#if defined(TARGET_X11_NATIVE) - -#if 0 - /* create graphic context structures needed for clipping */ - clip_gc_values.graphics_exposures = False; - clip_gc_valuemask = GCGraphicsExposures; - copy_clipmask_gc = XCreateGC(display, pix[PIX_BACK]->clip_mask, - clip_gc_valuemask, &clip_gc_values); - - /* create only those clipping Pixmaps we really need */ - for (i = 0; tile_needs_clipping[i].start >= 0; i++) + EL_SPACESHIP, + EL_SPACESHIP_LEFT, EL_SPACESHIP_RIGHT, + EL_SPACESHIP_UP, EL_SPACESHIP_DOWN + }, { - int j; - - for (j = 0; j < tile_needs_clipping[i].count; j++) - { - int tile = tile_needs_clipping[i].start + j; - int graphic = tile; - int src_x, src_y; - Bitmap *src_bitmap; - Pixmap src_pixmap; - - getGraphicSource(graphic, &src_bitmap, &src_x, &src_y); - src_pixmap = src_bitmap->clip_mask; - - tile_clipmask[tile] = XCreatePixmap(display, window->drawable, - TILEX, TILEY, 1); - - XCopyArea(display, src_pixmap, tile_clipmask[tile], copy_clipmask_gc, - src_x, src_y, TILEX, TILEY, 0, 0); - } - } - - XFreeGC(display, copy_clipmask_gc); -#endif - -#endif /* TARGET_X11_NATIVE */ -#endif /* TARGET_X11 */ -#endif -} - -void FreeTileClipmasks() -{ -#if 0 -#if defined(TARGET_X11) - int i; - - for (i = 0; i < NUM_TILES; i++) + EL_BD_BUTTERFLY, + EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_RIGHT, + EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_DOWN + }, { - if (tile_clipmask[i] != None) - { - XFreePixmap(display, tile_clipmask[i]); - tile_clipmask[i] = None; - } - } - - if (tile_clip_gc) - XFreeGC(display, tile_clip_gc); - tile_clip_gc = None; - -#if 0 - for (i = 0; i < NUM_BITMAPS; i++) + EL_BD_FIREFLY, + EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_RIGHT, + EL_BD_FIREFLY_UP, EL_BD_FIREFLY_DOWN + }, { - if (pix[i] != NULL && pix[i]->stored_clip_gc) - { - XFreeGC(display, pix[i]->stored_clip_gc); - pix[i]->stored_clip_gc = None; - } + EL_PACMAN, + EL_PACMAN_LEFT, EL_PACMAN_RIGHT, + EL_PACMAN_UP, EL_PACMAN_DOWN + }, + { + EL_MOLE, + EL_MOLE_LEFT, EL_MOLE_RIGHT, + EL_MOLE_UP, EL_MOLE_DOWN + }, + { + -1, + -1, -1, -1, -1 } -#endif - -#endif /* TARGET_X11 */ -#endif -} +}; void FreeGadgets() { @@ -246,6 +109,14 @@ inline void InitElementSmallImagesScaledUp(int graphic) void InitElementSmallImages() { + static int special_graphics[] = + { + IMG_EDITOR_ELEMENT_BORDER, + IMG_EDITOR_ELEMENT_BORDER_INPUT, + IMG_EDITOR_CASCADE_LIST, + IMG_EDITOR_CASCADE_LIST_ACTIVE, + -1 + }; struct PropertyMapping *property_mapping = getImageListPropertyMapping(); int num_property_mappings = getImageListPropertyMappingSize(); int i; @@ -259,22 +130,12 @@ void InitElementSmallImages() InitElementSmallImagesScaledUp(element_to_special_graphic[i].graphic); /* initialize images from dynamic configuration (may be elements or other) */ -#if 1 for (i = 0; i < num_property_mappings; i++) InitElementSmallImagesScaledUp(property_mapping[i].artwork_index); -#else - /* !!! THIS DOES NOT WORK -- "artwork_index" is graphic, not element !!! */ - /* !!! ALSO, non-element graphics might need scaling-up !!! */ - for (i = 0; i < num_property_mappings; i++) - if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS) - InitElementSmallImagesScaledUp(property_mapping[i].artwork_index); -#endif -#if 1 - /* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */ - for (i = IMG_EMC_OBJECT; i <= IMG_EMC_SPRITE; i++) - InitElementSmallImagesScaledUp(i); -#endif + /* initialize special images from above list (non-element images) */ + for (i = 0; special_graphics[i] > -1; i++) + InitElementSmallImagesScaledUp(special_graphics[i]); } #if 1 @@ -321,13 +182,8 @@ void InitFontGraphicInfo() /* ---------- initialize font graphic definitions ---------- */ /* always start with reliable default values (normal font graphics) */ -#if 1 for (i = 0; i < NUM_FONTS; i++) font_info[i].graphic = IMG_FONT_INITIAL_1; -#else - for (i = 0; i < NUM_FONTS; i++) - font_info[i].graphic = FONT_INITIAL_1; -#endif /* initialize normal font/graphic mapping from static configuration */ for (i = 0; font_to_graphic[i].font_nr > -1; i++) @@ -355,12 +211,25 @@ void InitFontGraphicInfo() /* initialize special font/graphic mapping from static configuration */ for (i = 0; font_to_graphic[i].font_nr > -1; i++) { - int font_nr = font_to_graphic[i].font_nr; - int special = font_to_graphic[i].special; - int graphic = font_to_graphic[i].graphic; + int font_nr = font_to_graphic[i].font_nr; + int special = font_to_graphic[i].special; + int graphic = font_to_graphic[i].graphic; + int base_graphic = font2baseimg(font_nr); if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) { + boolean base_redefined = + getImageListEntryFromImageID(base_graphic)->redefined; + boolean special_redefined = + getImageListEntryFromImageID(graphic)->redefined; + + /* if the base font ("font.title_1", for example) has been redefined, + but not the special font ("font.title_1.LEVELS", for example), do not + use an existing (in this case considered obsolete) special font + anymore, but use the automatically determined default font */ + if (base_redefined && !special_redefined) + continue; + font_info[font_nr].special_graphic[special] = graphic; font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps; num_font_bitmaps++; @@ -595,6 +464,16 @@ void InitElementGraphicInfo() #endif #if 1 + /* set hardcoded definitions for some internal elements without graphic */ + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + { + if (IS_EDITOR_CASCADE_INACTIVE(i)) + element_info[i].graphic[ACTION_DEFAULT] = IMG_EDITOR_CASCADE_LIST; + else if (IS_EDITOR_CASCADE_ACTIVE(i)) + element_info[i].graphic[ACTION_DEFAULT] = IMG_EDITOR_CASCADE_LIST_ACTIVE; + } +#endif + /* now set all undefined/invalid graphics to -1 to set to default after it */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -622,9 +501,7 @@ void InitElementGraphicInfo() } } } -#endif -#if 1 /* 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++) @@ -639,7 +516,9 @@ void InitElementGraphicInfo() if (act == ACTION_FALLING) /* special case */ graphic = element_info[i].graphic[act]; - if (graphic != -1 && graphic_info[graphic].double_movement) + if (graphic != -1 && + graphic_info[graphic].double_movement && + graphic_info[graphic].swap_double_tiles != 0) { struct GraphicInfo *g = &graphic_info[graphic]; int src_x_front = g->src_x; @@ -650,20 +529,17 @@ void InitElementGraphicInfo() g->offset_y != 0); boolean front_is_left_or_upper = (src_x_front < src_x_back || src_y_front < src_y_back); + boolean swap_movement_tiles_always = (g->swap_double_tiles == 1); + boolean swap_movement_tiles_autodetected = + (!frames_are_ordered_diagonally && + ((move_dir == MV_BIT_LEFT && !front_is_left_or_upper) || + (move_dir == MV_BIT_UP && !front_is_left_or_upper) || + (move_dir == MV_BIT_RIGHT && front_is_left_or_upper) || + (move_dir == MV_BIT_DOWN && front_is_left_or_upper))); Bitmap *dummy; -#if 0 - printf("::: CHECKING ELEMENT %d ('%s'), ACTION '%s', DIRECTION %d\n", - i, element_info[i].token_name, - element_action_info[act].suffix, move_dir); -#endif - /* swap frontside and backside graphic tile coordinates, if needed */ - if (!frames_are_ordered_diagonally && - ((move_dir == MV_BIT_LEFT && !front_is_left_or_upper) || - (move_dir == MV_BIT_RIGHT && front_is_left_or_upper) || - (move_dir == MV_BIT_UP && !front_is_left_or_upper) || - (move_dir == MV_BIT_DOWN && front_is_left_or_upper))) + if (swap_movement_tiles_always || swap_movement_tiles_autodetected) { /* get current (wrong) backside tile coordinates */ getGraphicSourceExt(graphic, 0, &dummy, &src_x_back, &src_y_back, @@ -677,15 +553,13 @@ void InitElementGraphicInfo() g->offset2_x *= -1; g->offset2_y *= -1; -#if 0 - printf(" CORRECTED\n"); -#endif + /* do not swap front and backside tiles again after correction */ + g->swap_double_tiles = 0; } } } } } -#endif /* now set all '-1' values to element specific default values */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) @@ -697,8 +571,14 @@ void InitElementGraphicInfo() if (default_graphic == -1) default_graphic = IMG_UNKNOWN; +#if 1 + if (default_crumbled == -1) + default_crumbled = default_graphic; +#else + /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */ if (default_crumbled == -1) default_crumbled = IMG_EMPTY; +#endif for (dir = 0; dir < NUM_DIRECTIONS; dir++) { @@ -709,8 +589,14 @@ void InitElementGraphicInfo() if (default_direction_graphic[dir] == -1) default_direction_graphic[dir] = default_graphic; +#if 1 + if (default_direction_crumbled[dir] == -1) + default_direction_crumbled[dir] = default_direction_graphic[dir]; +#else + /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */ if (default_direction_crumbled[dir] == -1) default_direction_crumbled[dir] = default_crumbled; +#endif } for (act = 0; act < NUM_ACTIONS; act++) @@ -758,32 +644,50 @@ void InitElementGraphicInfo() if (default_action_graphic == -1) default_action_graphic = default_graphic; +#if 1 + if (default_action_crumbled == -1) + default_action_crumbled = default_action_graphic; +#else + /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */ if (default_action_crumbled == -1) default_action_crumbled = default_crumbled; +#endif for (dir = 0; dir < NUM_DIRECTIONS; dir++) { + /* use action graphic as the default direction graphic, if undefined */ int default_action_direction_graphic = element_info[i].graphic[act]; int default_action_direction_crumbled = element_info[i].crumbled[act]; /* no graphic for current action -- use default direction graphic */ - /* !!! maybe it's better to use default _action_ graphic here !!! */ if (default_action_direction_graphic == -1) default_action_direction_graphic = (act_remove ? default_remove_graphic : act_turning ? element_info[i].direction_graphic[ACTION_TURNING][dir] : + default_action_graphic != default_graphic ? + default_action_graphic : default_direction_graphic[dir]); + + if (element_info[i].direction_graphic[act][dir] == -1) + element_info[i].direction_graphic[act][dir] = + default_action_direction_graphic; + +#if 1 + if (default_action_direction_crumbled == -1) + default_action_direction_crumbled = + element_info[i].direction_graphic[act][dir]; +#else if (default_action_direction_crumbled == -1) default_action_direction_crumbled = (act_remove ? default_remove_graphic : act_turning ? element_info[i].direction_crumbled[ACTION_TURNING][dir] : + default_action_crumbled != default_crumbled ? + default_action_crumbled : default_direction_crumbled[dir]); +#endif - if (element_info[i].direction_graphic[act][dir] == -1) - element_info[i].direction_graphic[act][dir] = - default_action_direction_graphic; if (element_info[i].direction_crumbled[act][dir] == -1) element_info[i].direction_crumbled[act][dir] = default_action_direction_crumbled; @@ -795,15 +699,19 @@ void InitElementGraphicInfo() (act_remove ? default_remove_graphic : act_turning ? element_info[i].graphic[ACTION_TURNING] : default_action_graphic); +#if 1 + if (element_info[i].crumbled[act] == -1) + element_info[i].crumbled[act] = element_info[i].graphic[act]; +#else if (element_info[i].crumbled[act] == -1) element_info[i].crumbled[act] = (act_remove ? default_remove_graphic : act_turning ? element_info[i].crumbled[ACTION_TURNING] : default_action_crumbled); +#endif } } -#if 1 /* set animation mode to "none" for each graphic with only 1 frame */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { @@ -829,7 +737,6 @@ void InitElementGraphicInfo() } } } -#endif #if 0 #if DEBUG @@ -893,24 +800,46 @@ void InitElementSpecialGraphicInfo() element_info[element].special_graphic[special] = graphic; } -#if 1 /* now set all undefined/invalid graphics to default */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) for (j = 0; j < NUM_SPECIAL_GFX_ARGS; j++) if (graphic_info[element_info[i].special_graphic[j]].bitmap == NULL) element_info[i].special_graphic[j] = element_info[i].graphic[ACTION_DEFAULT]; -#endif } -static int get_element_from_token(char *token) +static int get_graphic_parameter_value(char *value_raw, char *suffix, int type) { int i; + int x = 0; + + if (type != TYPE_TOKEN) + return get_parameter_value(value_raw, suffix, type); + if (strcmp(value_raw, ARG_UNDEFINED) == 0) + return ARG_UNDEFINED_VALUE; + + /* !!! OPTIMIZE THIS BY USING HASH !!! */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) - if (strcmp(element_info[i].token_name, token) == 0) + if (strcmp(element_info[i].token_name, value_raw) == 0) return i; + /* !!! OPTIMIZE THIS BY USING HASH !!! */ + for (i = 0; image_config[i].token != NULL; i++) + { + int len_config_value = strlen(image_config[i].value); + + if (strcmp(&image_config[i].value[len_config_value - 4], ".pcx") != 0 && + strcmp(&image_config[i].value[len_config_value - 4], ".wav") != 0 && + strcmp(image_config[i].value, UNDEFINED_FILENAME) != 0) + continue; + + if (strcmp(image_config[i].token, value_raw) == 0) + return x; + + x++; + } + return -1; } @@ -930,30 +859,31 @@ static int get_scaled_graphic_height(int graphic) return original_height * scale_up_factor; } -static void set_graphic_parameters(int graphic, int graphic_copy_from) +static void set_graphic_parameters(int graphic) { - struct FileInfo *image = getImageListEntryFromImageID(graphic_copy_from); + struct FileInfo *image = getImageListEntryFromImageID(graphic); char **parameter_raw = image->parameter; - Bitmap *src_bitmap = getBitmapFromImageID(graphic_copy_from); + Bitmap *src_bitmap = getBitmapFromImageID(graphic); int parameter[NUM_GFX_ARGS]; int anim_frames_per_row = 1, anim_frames_per_col = 1; int anim_frames_per_line = 1; int i; + /* if fallback to default artwork is done, also use the default parameters */ + if (image->fallback_to_default) + parameter_raw = image->default_parameter; + /* get integer values from string parameters */ for (i = 0; i < NUM_GFX_ARGS; i++) - { - parameter[i] = - get_parameter_value(image_config_suffix[i].token, parameter_raw[i], - image_config_suffix[i].type); - - if (image_config_suffix[i].type == TYPE_TOKEN) - parameter[i] = get_element_from_token(parameter_raw[i]); - } + parameter[i] = get_graphic_parameter_value(parameter_raw[i], + image_config_suffix[i].token, + image_config_suffix[i].type); graphic_info[graphic].bitmap = src_bitmap; /* start with reliable default values */ + graphic_info[graphic].src_image_width = 0; + graphic_info[graphic].src_image_height = 0; graphic_info[graphic].src_x = 0; graphic_info[graphic].src_y = 0; graphic_info[graphic].width = TILEX; @@ -962,10 +892,12 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from) graphic_info[graphic].offset_y = 0; /* ... will be corrected later */ graphic_info[graphic].offset2_x = 0; /* one or both of these values ... */ graphic_info[graphic].offset2_y = 0; /* ... will be corrected later */ + graphic_info[graphic].swap_double_tiles = -1; /* auto-detect tile swapping */ graphic_info[graphic].crumbled_like = -1; /* do not use clone element */ graphic_info[graphic].diggable_like = -1; /* do not use clone element */ graphic_info[graphic].border_size = TILEX / 8; /* "CRUMBLED" border size */ graphic_info[graphic].scale_up_factor = 1; /* default: no scaling up */ + graphic_info[graphic].clone_from = -1; /* do not use clone graphic */ graphic_info[graphic].anim_delay_fixed = 0; graphic_info[graphic].anim_delay_random = 0; graphic_info[graphic].post_delay_fixed = 0; @@ -998,11 +930,14 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from) if (src_bitmap) { /* get final bitmap size (with scaling, but without small images) */ - int src_bitmap_width = get_scaled_graphic_width(graphic); - int src_bitmap_height = get_scaled_graphic_height(graphic); + int src_image_width = get_scaled_graphic_width(graphic); + int src_image_height = get_scaled_graphic_height(graphic); + + anim_frames_per_row = src_image_width / graphic_info[graphic].width; + anim_frames_per_col = src_image_height / graphic_info[graphic].height; - anim_frames_per_row = src_bitmap_width / graphic_info[graphic].width; - anim_frames_per_col = src_bitmap_height / graphic_info[graphic].height; + graphic_info[graphic].src_image_width = src_image_width; + graphic_info[graphic].src_image_height = src_image_height; } /* correct x or y offset dependent of vertical or horizontal frame order */ @@ -1049,6 +984,10 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from) if (parameter[GFX_ARG_2ND_YOFFSET] != ARG_UNDEFINED_VALUE) graphic_info[graphic].offset2_y = parameter[GFX_ARG_2ND_YOFFSET]; + /* optionally, the second movement tile can be specified as start tile */ + if (parameter[GFX_ARG_2ND_SWAP_TILES] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].swap_double_tiles= parameter[GFX_ARG_2ND_SWAP_TILES]; + /* automatically determine correct number of frames, if not defined */ if (parameter[GFX_ARG_FRAMES] != ARG_UNDEFINED_VALUE) graphic_info[graphic].anim_frames = parameter[GFX_ARG_FRAMES]; @@ -1121,6 +1060,49 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from) /* this is only used for drawing envelope graphics */ graphic_info[graphic].draw_masked = parameter[GFX_ARG_DRAW_MASKED]; + + /* optional graphic for cloning all graphics settings */ + if (parameter[GFX_ARG_CLONE_FROM] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].clone_from = parameter[GFX_ARG_CLONE_FROM]; +} + +static void set_cloned_graphic_parameters(int graphic) +{ + int fallback_graphic = IMG_CHAR_EXCLAM; + int max_num_images = getImageListSize(); + int clone_graphic = graphic_info[graphic].clone_from; + int num_references_followed = 1; + + while (graphic_info[clone_graphic].clone_from != -1 && + num_references_followed < max_num_images) + { + clone_graphic = graphic_info[clone_graphic].clone_from; + + num_references_followed++; + } + + if (num_references_followed >= max_num_images) + { + Error(ERR_RETURN_LINE, "-"); + Error(ERR_RETURN, "warning: error found in config file:"); + Error(ERR_RETURN, "- config file: '%s'", getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", getTokenFromImageID(graphic)); + Error(ERR_RETURN, "error: loop discovered when resolving cloned graphics"); + Error(ERR_RETURN, "custom graphic rejected for this element/action"); + + if (graphic == fallback_graphic) + Error(ERR_EXIT, "fatal error: no fallback graphic available"); + + Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); + Error(ERR_RETURN_LINE, "-"); + + graphic_info[graphic] = graphic_info[fallback_graphic]; + } + else + { + graphic_info[graphic] = graphic_info[clone_graphic]; + graphic_info[graphic].clone_from = clone_graphic; + } } static void InitGraphicInfo() @@ -1141,10 +1123,6 @@ static void InitGraphicInfo() graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo)); -#if 0 - printf("::: graphic_info: %d entries\n", num_images); -#endif - #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) if (clipmasks_initialized) { @@ -1161,6 +1139,15 @@ static void InitGraphicInfo() } #endif + /* first set all graphic paramaters ... */ + for (i = 0; i < num_images; i++) + set_graphic_parameters(i); + + /* ... then copy these parameters for cloned graphics */ + for (i = 0; i < num_images; i++) + if (graphic_info[i].clone_from != -1) + set_cloned_graphic_parameters(i); + for (i = 0; i < num_images; i++) { Bitmap *src_bitmap; @@ -1168,76 +1155,60 @@ static void InitGraphicInfo() int first_frame, last_frame; int src_bitmap_width, src_bitmap_height; -#if 0 - printf("::: image: '%s' [%d]\n", image->token, i); -#endif - -#if 0 - printf("::: image # %d: '%s' ['%s']\n", - i, image->token, - getTokenFromImageID(i)); -#endif - - set_graphic_parameters(i, i); - /* now check if no animation frames are outside of the loaded image */ if (graphic_info[i].bitmap == NULL) continue; /* skip check for optional images that are undefined */ /* get final bitmap size (with scaling, but without small images) */ - src_bitmap_width = get_scaled_graphic_width(i); - src_bitmap_height = get_scaled_graphic_height(i); + src_bitmap_width = graphic_info[i].src_image_width; + src_bitmap_height = graphic_info[i].src_image_height; + + /* check if first animation frame is inside specified bitmap */ first_frame = 0; getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y); + if (src_x < 0 || src_y < 0 || src_x + TILEX > src_bitmap_width || src_y + TILEY > src_bitmap_height) { Error(ERR_RETURN_LINE, "-"); Error(ERR_RETURN, "warning: error found in config file:"); - Error(ERR_RETURN, "- config file: '%s'", - getImageConfigFilename()); - Error(ERR_RETURN, "- config token: '%s'", - getTokenFromImageID(i)); - Error(ERR_RETURN, "- image file: '%s'", - src_bitmap->source_filename); + Error(ERR_RETURN, "- config file: '%s'", getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", getTokenFromImageID(i)); + Error(ERR_RETURN, "- image file: '%s'", src_bitmap->source_filename); Error(ERR_RETURN, - "error: first animation frame out of bounds (%d, %d)", - src_x, src_y); + "error: first animation frame out of bounds (%d, %d) [%d, %d]", + src_x, src_y, src_bitmap_width, src_bitmap_height); Error(ERR_RETURN, "custom graphic rejected for this element/action"); -#if 0 - Error(ERR_RETURN, "scale_up_factor == %d", scale_up_factor); -#endif - if (i == fallback_graphic) Error(ERR_EXIT, "fatal error: no fallback graphic available"); Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); Error(ERR_RETURN_LINE, "-"); - set_graphic_parameters(i, fallback_graphic); + graphic_info[i] = graphic_info[fallback_graphic]; } + /* check if last animation frame is inside specified bitmap */ + last_frame = graphic_info[i].anim_frames - 1; getGraphicSource(i, last_frame, &src_bitmap, &src_x, &src_y); + if (src_x < 0 || src_y < 0 || src_x + TILEX > src_bitmap_width || src_y + TILEY > src_bitmap_height) { Error(ERR_RETURN_LINE, "-"); Error(ERR_RETURN, "warning: error found in config file:"); - Error(ERR_RETURN, "- config file: '%s'", - getImageConfigFilename()); - Error(ERR_RETURN, "- config token: '%s'", - getTokenFromImageID(i)); - Error(ERR_RETURN, "- image file: '%s'", - src_bitmap->source_filename); + Error(ERR_RETURN, "- config file: '%s'", getImageConfigFilename()); + Error(ERR_RETURN, "- config token: '%s'", getTokenFromImageID(i)); + Error(ERR_RETURN, "- image file: '%s'", src_bitmap->source_filename); Error(ERR_RETURN, - "error: last animation frame (%d) out of bounds (%d, %d)", - last_frame, src_x, src_y); + "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_RETURN, "custom graphic rejected for this element/action"); if (i == fallback_graphic) @@ -1246,7 +1217,7 @@ static void InitGraphicInfo() Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic"); Error(ERR_RETURN_LINE, "-"); - set_graphic_parameters(i, fallback_graphic); + graphic_info[i] = graphic_info[fallback_graphic]; } #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) @@ -1386,6 +1357,14 @@ static void InitElementSoundInfo() element_info[i].sound[act] = default_action_sound; } } + + /* copy sound settings to some elements that are only stored in level file + in native R'n'D levels, but are used by game engine in native EM levels */ + for (i = 0; copy_properties[i][0] != -1; i++) + for (j = 1; j <= 4; j++) + for (act = 0; act < NUM_ACTIONS; act++) + element_info[copy_properties[i][j]].sound[act] = + element_info[copy_properties[i][0]].sound[act]; } static void InitGameModeSoundInfo() @@ -1414,7 +1393,6 @@ static void InitGameModeSoundInfo() menu.sound[i] = menu.sound[GAME_MODE_DEFAULT]; #if 0 - /* TEST ONLY */ for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++) if (menu.sound[i] != -1) printf("::: menu.sound[%d] == %d\n", i, menu.sound[i]); @@ -1429,7 +1407,8 @@ static void set_sound_parameters(int sound, char **parameter_raw) /* get integer values from string parameters */ for (i = 0; i < NUM_SND_ARGS; i++) parameter[i] = - get_parameter_value(sound_config_suffix[i].token, parameter_raw[i], + get_parameter_value(parameter_raw[i], + sound_config_suffix[i].token, sound_config_suffix[i].type); /* explicit loop mode setting in configuration overrides default value */ @@ -1445,10 +1424,6 @@ static void set_sound_parameters(int sound, char **parameter_raw) static void InitSoundInfo() { -#if 0 - struct PropertyMapping *property_mapping = getSoundListPropertyMapping(); - int num_property_mappings = getSoundListPropertyMappingSize(); -#endif int *sound_effect_properties; int num_sounds = getSoundListSize(); int i, j; @@ -1492,11 +1467,6 @@ static void InitSoundInfo() } } -#if 0 - if (strcmp(sound->token, "custom_42") == 0) - printf("::: '%s' -> %d\n", sound->token, sound_info[i].loop); -#endif - /* associate elements and some selected sound actions */ for (j = 0; j < MAX_NUM_ELEMENTS; j++) @@ -1521,61 +1491,6 @@ static void InitSoundInfo() } free(sound_effect_properties); - -#if 0 - /* !!! now handled in InitElementSoundInfo() !!! */ - /* initialize element/sound mapping from dynamic configuration */ - for (i = 0; i < num_property_mappings; i++) - { - int element = property_mapping[i].base_index; - int action = property_mapping[i].ext1_index; - int sound = property_mapping[i].artwork_index; - - if (action < 0) - action = ACTION_DEFAULT; - - printf("::: %d: %d, %d, %d ['%s']\n", - i, element, action, sound, element_info[element].token_name); - - element_info[element].sound[action] = sound; - } -#endif - -#if 0 - /* TEST ONLY */ - { - int element = EL_CUSTOM_11; - int j = 0; - - while (element_action_info[j].suffix) - { - printf("element %d, sound action '%s' == %d\n", - element, element_action_info[j].suffix, - element_info[element].sound[j]); - j++; - } - } - - PlaySoundLevelElementAction(0,0, EL_CUSTOM_11, ACTION_PUSHING); -#endif - -#if 0 - /* TEST ONLY */ - { - int element = EL_SAND; - int sound_action = ACTION_DIGGING; - int j = 0; - - while (element_action_info[j].suffix) - { - if (element_action_info[j].value == sound_action) - printf("element %d, sound action '%s' == %d\n", - element, element_action_info[j].suffix, - element_info[element].sound[sound_action]); - j++; - } - } -#endif } static void InitGameModeMusicInfo() @@ -1653,7 +1568,6 @@ static void InitGameModeMusicInfo() menu.music[i] = menu.music[GAME_MODE_DEFAULT]; #if 0 - /* TEST ONLY */ for (i = 0; i < MAX_LEVELS; i++) if (levelset.music[i] != -1) printf("::: levelset.music[%d] == %d\n", i, levelset.music[i]); @@ -1671,7 +1585,8 @@ static void set_music_parameters(int music, char **parameter_raw) /* get integer values from string parameters */ for (i = 0; i < NUM_MUS_ARGS; i++) parameter[i] = - get_parameter_value(music_config_suffix[i].token, parameter_raw[i], + get_parameter_value(parameter_raw[i], + music_config_suffix[i].token, music_config_suffix[i].type); /* explicit loop mode setting in configuration overrides default value */ @@ -1766,7 +1681,7 @@ static int get_special_property_bit(int element, int property_bit_nr) { EL_SP_MURPHY, 0 }, { EL_SOKOBAN_FIELD_PLAYER, 0 }, - /* all element that can move may be able to also move into acid */ + /* all elements that can move may be able to also move into acid */ { EL_BUG, 1 }, { EL_BUG_LEFT, 1 }, { EL_BUG_RIGHT, 1 }, @@ -1808,6 +1723,7 @@ static int get_special_property_bit(int element, int property_bit_nr) { EL_SP_ELECTRON, 15 }, { EL_BALLOON, 16 }, { EL_SPRING, 17 }, + { EL_EMC_ANDROID, 18 }, { -1, -1 }, }; @@ -1849,7 +1765,6 @@ static int get_special_property_bit(int element, int property_bit_nr) return -1; } -#if 1 void setBitfieldProperty(int *bitfield, int property_bit_nr, int element, boolean property_value) { @@ -1874,32 +1789,6 @@ boolean getBitfieldProperty(int *bitfield, int property_bit_nr, int element) return FALSE; } -#else - -void setMoveIntoAcidProperty(struct LevelInfo *level, int element, boolean set) -{ - int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); - - if (bit_nr > -1) - { - level->can_move_into_acid_bits &= ~(1 << bit_nr); - - if (set) - level->can_move_into_acid_bits |= (1 << bit_nr); - } -} - -boolean getMoveIntoAcidProperty(struct LevelInfo *level, int element) -{ - int bit_nr = get_special_property_bit(element, EP_CAN_MOVE_INTO_ACID); - - if (bit_nr > -1) - return ((level->can_move_into_acid_bits & (1 << bit_nr)) != 0); - - return FALSE; -} -#endif - void InitElementPropertiesStatic() { static int ep_diggable[] = @@ -1921,6 +1810,7 @@ void InitElementPropertiesStatic() EL_SP_BUGGY_BASE_ACTIVE, EL_EMC_PLANT, #endif + -1 }; @@ -1940,10 +1830,10 @@ void InitElementPropertiesStatic() EL_EM_KEY_2, EL_EM_KEY_3, EL_EM_KEY_4, - EL_EM_KEY_5, - EL_EM_KEY_6, - EL_EM_KEY_7, - EL_EM_KEY_8, + EL_EMC_KEY_5, + EL_EMC_KEY_6, + EL_EMC_KEY_7, + EL_EMC_KEY_8, EL_DYNAMITE, EL_DYNABOMB_INCREASE_NUMBER, EL_DYNABOMB_INCREASE_SIZE, @@ -1963,6 +1853,7 @@ void InitElementPropertiesStatic() EL_SPEED_PILL, EL_EMC_LENSES, EL_EMC_MAGNIFIER, + -1 }; @@ -1993,6 +1884,7 @@ void InitElementPropertiesStatic() EL_SP_BUGGY_BASE_ACTIVE, EL_EMC_PLANT, #endif + -1 }; @@ -2011,6 +1903,7 @@ void InitElementPropertiesStatic() EL_PACMAN, EL_SP_SNIKSNAK, EL_SP_ELECTRON, + -1 }; @@ -2020,6 +1913,7 @@ void InitElementPropertiesStatic() EL_SPACESHIP, EL_BD_BUTTERFLY, EL_BD_FIREFLY, + -1 }; @@ -2085,6 +1979,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -2093,6 +1991,22 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, + EL_EMC_GATE_5, + EL_EMC_GATE_6, + EL_EMC_GATE_7, + EL_EMC_GATE_8, + EL_EMC_GATE_5_GRAY, + EL_EMC_GATE_6_GRAY, + EL_EMC_GATE_7_GRAY, + EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_SWITCHGATE_OPENING, EL_SWITCHGATE_CLOSED, @@ -2120,6 +2034,7 @@ void InitElementPropertiesStatic() EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + -1 }; @@ -2161,6 +2076,9 @@ void InitElementPropertiesStatic() EL_EMC_WALL_SLIPPERY_2, EL_EMC_WALL_SLIPPERY_3, EL_EMC_WALL_SLIPPERY_4, + EL_EMC_MAGIC_BALL, + EL_EMC_MAGIC_BALL_ACTIVE, + -1 }; @@ -2190,6 +2108,7 @@ void InitElementPropertiesStatic() EL_BALLOON, EL_SPRING, EL_EMC_ANDROID, + -1 }; @@ -2218,6 +2137,7 @@ void InitElementPropertiesStatic() EL_CRYSTAL, EL_SPRING, EL_DX_SUPABOMB, + -1 }; @@ -2243,6 +2163,7 @@ void InitElementPropertiesStatic() EL_CRYSTAL, EL_SPRING, EL_DX_SUPABOMB, + -1 }; @@ -2251,6 +2172,7 @@ void InitElementPropertiesStatic() EL_ROCK, EL_BD_ROCK, EL_SP_ZONK, + -1 }; @@ -2259,6 +2181,7 @@ void InitElementPropertiesStatic() EL_ROCK, EL_BD_ROCK, EL_SP_ZONK, + -1 }; @@ -2295,6 +2218,7 @@ void InitElementPropertiesStatic() #if 0 EL_BLACK_ORB, #endif + -1 }; @@ -2310,6 +2234,7 @@ void InitElementPropertiesStatic() EL_PIG, EL_DRAGON, EL_MOLE, + -1 }; @@ -2318,6 +2243,7 @@ void InitElementPropertiesStatic() EL_BOMB, EL_SP_DISK_ORANGE, EL_DX_SUPABOMB, + -1 }; @@ -2337,9 +2263,14 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_PENGUIN, EL_PIG, EL_DRAGON, + -1 }; @@ -2356,6 +2287,7 @@ void InitElementPropertiesStatic() EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + -1 }; @@ -2370,20 +2302,29 @@ void InitElementPropertiesStatic() EL_EM_GATE_2, EL_EM_GATE_3, EL_EM_GATE_4, - EL_EM_GATE_5, - EL_EM_GATE_6, - EL_EM_GATE_7, - EL_EM_GATE_8, EL_EM_GATE_1_GRAY, EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, - EL_EM_GATE_5_GRAY, - EL_EM_GATE_6_GRAY, - EL_EM_GATE_7_GRAY, - EL_EM_GATE_8_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, + EL_EMC_GATE_5, + EL_EMC_GATE_6, + EL_EMC_GATE_7, + EL_EMC_GATE_8, + EL_EMC_GATE_5_GRAY, + EL_EMC_GATE_6_GRAY, + EL_EMC_GATE_7_GRAY, + EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_TIMEGATE_OPEN, + -1 }; @@ -2408,6 +2349,7 @@ void InitElementPropertiesStatic() EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, + -1 }; @@ -2443,6 +2385,7 @@ void InitElementPropertiesStatic() EL_SP_DISK_YELLOW, EL_BALLOON, EL_EMC_ANDROID, + -1 }; @@ -2471,18 +2414,26 @@ void InitElementPropertiesStatic() EL_EM_GATE_2, EL_EM_GATE_3, EL_EM_GATE_4, - EL_EM_GATE_5, - EL_EM_GATE_6, - EL_EM_GATE_7, - EL_EM_GATE_8, EL_EM_GATE_1_GRAY, EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, - EL_EM_GATE_5_GRAY, - EL_EM_GATE_6_GRAY, - EL_EM_GATE_7_GRAY, - EL_EM_GATE_8_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, + EL_EMC_GATE_5, + EL_EMC_GATE_6, + EL_EMC_GATE_7, + EL_EMC_GATE_8, + EL_EMC_GATE_5_GRAY, + EL_EMC_GATE_6_GRAY, + EL_EMC_GATE_7_GRAY, + EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_TIMEGATE_OPEN, @@ -2506,6 +2457,7 @@ void InitElementPropertiesStatic() EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, + -1 }; @@ -2547,6 +2499,7 @@ void InitElementPropertiesStatic() /* elements that can explode only by explosion */ EL_BLACK_ORB, + -1 }; @@ -2577,6 +2530,7 @@ void InitElementPropertiesStatic() EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, EL_EMC_GRASS, + -1 }; @@ -2589,6 +2543,7 @@ void InitElementPropertiesStatic() EL_SP_MURPHY, EL_SOKOBAN_FIELD_PLAYER, EL_TRIGGER_PLAYER, + -1 }; @@ -2602,6 +2557,7 @@ void InitElementPropertiesStatic() EL_EMERALD_RED, EL_EMERALD_PURPLE, EL_DIAMOND, + -1 }; @@ -2631,9 +2587,12 @@ void InitElementPropertiesStatic() EL_BALLOON_SWITCH_UP, EL_BALLOON_SWITCH_DOWN, EL_BALLOON_SWITCH_ANY, + EL_BALLOON_SWITCH_NONE, EL_LAMP, EL_TIME_ORB_FULL, EL_EMC_MAGIC_BALL_SWITCH, + EL_EMC_MAGIC_BALL_SWITCH_ACTIVE, + -1 }; @@ -2667,6 +2626,7 @@ void InitElementPropertiesStatic() EL_BD_AMOEBA, EL_CHAR_QUESTION, EL_UNKNOWN, + -1 }; @@ -2741,6 +2701,7 @@ void InitElementPropertiesStatic() EL_SP_BUGGY_BASE_ACTIVE, EL_SP_EXIT_OPENING, EL_SP_EXIT_CLOSING, + -1 }; @@ -2757,6 +2718,7 @@ void InitElementPropertiesStatic() EL_PLAYER_3, EL_PLAYER_4, EL_INVISIBLE_STEELWALL, + -1 }; @@ -2768,6 +2730,7 @@ void InitElementPropertiesStatic() EL_EMERALD_RED, EL_EMERALD_PURPLE, EL_DIAMOND, + -1 }; @@ -2795,6 +2758,7 @@ void InitElementPropertiesStatic() EL_DIAMOND, EL_PEARL, EL_CRYSTAL, + -1 }; @@ -2808,6 +2772,7 @@ void InitElementPropertiesStatic() EL_DIAMOND, EL_PEARL, EL_CRYSTAL, + -1 }; @@ -2819,6 +2784,7 @@ void InitElementPropertiesStatic() EL_EMERALD_RED, EL_EMERALD_PURPLE, EL_DIAMOND, + -1 }; @@ -2833,6 +2799,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -2841,6 +2811,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_EXIT_CLOSED, EL_EXIT_OPENING, EL_EXIT_OPEN, @@ -2889,6 +2863,7 @@ void InitElementPropertiesStatic() EL_EMC_WALL_6, EL_EMC_WALL_7, EL_EMC_WALL_8, + -1 }; @@ -3017,6 +2992,10 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, @@ -3025,6 +3004,10 @@ void InitElementPropertiesStatic() EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, EL_SWITCHGATE_OPEN, EL_SWITCHGATE_OPENING, EL_SWITCHGATE_CLOSED, @@ -3044,6 +3027,7 @@ void InitElementPropertiesStatic() EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + -1 }; @@ -3060,6 +3044,7 @@ void InitElementPropertiesStatic() EL_PACMAN, EL_SP_SNIKSNAK, EL_SP_ELECTRON, + -1 }; @@ -3077,6 +3062,7 @@ void InitElementPropertiesStatic() EL_CONVEYOR_BELT_4_LEFT, EL_CONVEYOR_BELT_4_MIDDLE, EL_CONVEYOR_BELT_4_RIGHT, + -1 }; @@ -3094,6 +3080,7 @@ void InitElementPropertiesStatic() EL_CONVEYOR_BELT_4_LEFT_ACTIVE, EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE, EL_CONVEYOR_BELT_4_RIGHT_ACTIVE, + -1 }; @@ -3111,6 +3098,7 @@ void InitElementPropertiesStatic() EL_CONVEYOR_BELT_4_SWITCH_LEFT, EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, EL_CONVEYOR_BELT_4_SWITCH_RIGHT, + -1 }; @@ -3127,6 +3115,7 @@ void InitElementPropertiesStatic() EL_TUBE_VERTICAL_LEFT, EL_TUBE_VERTICAL_RIGHT, EL_TUBE_ANY, + -1 }; @@ -3140,22 +3129,35 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, EL_EM_GATE_4, - EL_EM_GATE_5, - EL_EM_GATE_6, - EL_EM_GATE_7, - EL_EM_GATE_8, EL_EM_GATE_1_GRAY, EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, - EL_EM_GATE_5_GRAY, - EL_EM_GATE_6_GRAY, - EL_EM_GATE_7_GRAY, - EL_EM_GATE_8_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, + EL_EMC_GATE_5, + EL_EMC_GATE_6, + EL_EMC_GATE_7, + EL_EMC_GATE_8, + EL_EMC_GATE_5_GRAY, + EL_EMC_GATE_6_GRAY, + EL_EMC_GATE_7_GRAY, + EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, + -1 }; @@ -3166,6 +3168,7 @@ void InitElementPropertiesStatic() EL_AMOEBA_DRY, EL_AMOEBA_FULL, EL_BD_AMOEBA, + -1 }; @@ -3175,16 +3178,25 @@ void InitElementPropertiesStatic() EL_AMOEBA_DRY, EL_AMOEBA_FULL, EL_BD_AMOEBA, + -1 }; - static int ep_has_content[] = + static int ep_has_editor_content[] = { + EL_PLAYER_1, + EL_PLAYER_2, + EL_PLAYER_3, + EL_PLAYER_4, + EL_SP_MURPHY, EL_YAMYAM, EL_AMOEBA_WET, EL_AMOEBA_DRY, EL_AMOEBA_FULL, EL_BD_AMOEBA, + EL_EMC_MAGIC_BALL, + EL_EMC_ANDROID, + -1 }; @@ -3203,6 +3215,7 @@ void InitElementPropertiesStatic() EL_AMOEBA_FULL, EL_GAME_OF_LIFE, EL_BIOMAZE, + -1 }; @@ -3214,6 +3227,7 @@ void InitElementPropertiesStatic() EL_DYNABOMB_PLAYER_3_ACTIVE, EL_DYNABOMB_PLAYER_4_ACTIVE, EL_SP_DISK_RED_ACTIVE, + -1 }; @@ -3237,10 +3251,10 @@ void InitElementPropertiesStatic() EL_EM_KEY_2, EL_EM_KEY_3, EL_EM_KEY_4, - EL_EM_KEY_5, - EL_EM_KEY_6, - EL_EM_KEY_7, - EL_EM_KEY_8, + EL_EMC_KEY_5, + EL_EMC_KEY_6, + EL_EMC_KEY_7, + EL_EMC_KEY_8, EL_GATE_1, EL_GATE_2, EL_GATE_3, @@ -3249,22 +3263,34 @@ void InitElementPropertiesStatic() EL_GATE_2_GRAY, EL_GATE_3_GRAY, EL_GATE_4_GRAY, + EL_GATE_1_GRAY_ACTIVE, + EL_GATE_2_GRAY_ACTIVE, + EL_GATE_3_GRAY_ACTIVE, + EL_GATE_4_GRAY_ACTIVE, EL_EM_GATE_1, EL_EM_GATE_2, EL_EM_GATE_3, EL_EM_GATE_4, - EL_EM_GATE_5, - EL_EM_GATE_6, - EL_EM_GATE_7, - EL_EM_GATE_8, EL_EM_GATE_1_GRAY, EL_EM_GATE_2_GRAY, EL_EM_GATE_3_GRAY, EL_EM_GATE_4_GRAY, - EL_EM_GATE_5_GRAY, - EL_EM_GATE_6_GRAY, - EL_EM_GATE_7_GRAY, - EL_EM_GATE_8_GRAY, + EL_EM_GATE_1_GRAY_ACTIVE, + EL_EM_GATE_2_GRAY_ACTIVE, + EL_EM_GATE_3_GRAY_ACTIVE, + EL_EM_GATE_4_GRAY_ACTIVE, + EL_EMC_GATE_5, + EL_EMC_GATE_6, + EL_EMC_GATE_7, + EL_EMC_GATE_8, + EL_EMC_GATE_5_GRAY, + EL_EMC_GATE_6_GRAY, + EL_EMC_GATE_7_GRAY, + EL_EMC_GATE_8_GRAY, + EL_EMC_GATE_5_GRAY_ACTIVE, + EL_EMC_GATE_6_GRAY_ACTIVE, + EL_EMC_GATE_7_GRAY_ACTIVE, + EL_EMC_GATE_8_GRAY_ACTIVE, EL_DYNAMITE, EL_INVISIBLE_STEELWALL, EL_INVISIBLE_WALL, @@ -3386,6 +3412,7 @@ void InitElementPropertiesStatic() EL_EMC_WALL_14, EL_EMC_WALL_15, EL_EMC_WALL_16, + -1 }; @@ -3400,6 +3427,47 @@ void InitElementPropertiesStatic() EL_LANDMINE, EL_TRAP, EL_TRAP_ACTIVE, + + -1 + }; + + static int ep_editor_cascade_active[] = + { + EL_INTERNAL_CASCADE_BD_ACTIVE, + EL_INTERNAL_CASCADE_EM_ACTIVE, + EL_INTERNAL_CASCADE_EMC_ACTIVE, + EL_INTERNAL_CASCADE_RND_ACTIVE, + EL_INTERNAL_CASCADE_SB_ACTIVE, + EL_INTERNAL_CASCADE_SP_ACTIVE, + EL_INTERNAL_CASCADE_DC_ACTIVE, + EL_INTERNAL_CASCADE_DX_ACTIVE, + EL_INTERNAL_CASCADE_CHARS_ACTIVE, + EL_INTERNAL_CASCADE_CE_ACTIVE, + EL_INTERNAL_CASCADE_GE_ACTIVE, + EL_INTERNAL_CASCADE_USER_ACTIVE, + EL_INTERNAL_CASCADE_GENERIC_ACTIVE, + EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE, + + -1 + }; + + static int ep_editor_cascade_inactive[] = + { + EL_INTERNAL_CASCADE_BD, + EL_INTERNAL_CASCADE_EM, + EL_INTERNAL_CASCADE_EMC, + EL_INTERNAL_CASCADE_RND, + EL_INTERNAL_CASCADE_SB, + EL_INTERNAL_CASCADE_SP, + EL_INTERNAL_CASCADE_DC, + EL_INTERNAL_CASCADE_DX, + EL_INTERNAL_CASCADE_CHARS, + EL_INTERNAL_CASCADE_CE, + EL_INTERNAL_CASCADE_GE, + EL_INTERNAL_CASCADE_USER, + EL_INTERNAL_CASCADE_GENERIC, + EL_INTERNAL_CASCADE_DYNAMIC, + -1 }; @@ -3409,106 +3477,71 @@ void InitElementPropertiesStatic() int property; } element_properties[] = { - { ep_diggable, EP_DIGGABLE }, - { ep_collectible_only, EP_COLLECTIBLE_ONLY }, - { ep_dont_run_into, EP_DONT_RUN_INTO }, - { ep_dont_collide_with, EP_DONT_COLLIDE_WITH }, - { ep_dont_touch, EP_DONT_TOUCH }, - { ep_indestructible, EP_INDESTRUCTIBLE }, - { ep_slippery, EP_SLIPPERY }, - { ep_can_change, EP_CAN_CHANGE }, - { ep_can_move, EP_CAN_MOVE }, - { ep_can_fall, EP_CAN_FALL }, - { ep_can_smash_player, EP_CAN_SMASH_PLAYER }, - { ep_can_smash_enemies, EP_CAN_SMASH_ENEMIES }, - { ep_can_smash_everything, EP_CAN_SMASH_EVERYTHING }, - { ep_explodes_by_fire, EP_EXPLODES_BY_FIRE }, - { ep_explodes_smashed, EP_EXPLODES_SMASHED }, - { ep_explodes_impact, EP_EXPLODES_IMPACT }, - { ep_walkable_over, EP_WALKABLE_OVER }, - { ep_walkable_inside, EP_WALKABLE_INSIDE }, - { ep_walkable_under, EP_WALKABLE_UNDER }, - { ep_passable_over, EP_PASSABLE_OVER }, - { ep_passable_inside, EP_PASSABLE_INSIDE }, - { ep_passable_under, EP_PASSABLE_UNDER }, - { ep_droppable, EP_DROPPABLE }, - { ep_explodes_1x1_old, EP_EXPLODES_1X1_OLD }, - { ep_pushable, EP_PUSHABLE }, - { ep_explodes_cross_old, EP_EXPLODES_CROSS_OLD }, - { ep_protected, EP_PROTECTED }, - { ep_throwable, EP_THROWABLE }, - { ep_can_explode, EP_CAN_EXPLODE }, - { ep_gravity_reachable, EP_GRAVITY_REACHABLE }, - - { ep_player, EP_PLAYER }, - { ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL }, - { ep_switchable, EP_SWITCHABLE }, - { ep_bd_element, EP_BD_ELEMENT }, - { ep_sp_element, EP_SP_ELEMENT }, - { ep_sb_element, EP_SB_ELEMENT }, - { ep_gem, EP_GEM }, - { ep_food_dark_yamyam, EP_FOOD_DARK_YAMYAM }, - { ep_food_penguin, EP_FOOD_PENGUIN }, - { ep_food_pig, EP_FOOD_PIG }, - { ep_historic_wall, EP_HISTORIC_WALL }, - { ep_historic_solid, EP_HISTORIC_SOLID }, - { ep_classic_enemy, EP_CLASSIC_ENEMY }, - { ep_belt, EP_BELT }, - { ep_belt_active, EP_BELT_ACTIVE }, - { ep_belt_switch, EP_BELT_SWITCH }, - { ep_tube, EP_TUBE }, - { ep_keygate, EP_KEYGATE }, - { ep_amoeboid, EP_AMOEBOID }, - { ep_amoebalive, EP_AMOEBALIVE }, - { ep_has_content, EP_HAS_CONTENT }, - { ep_can_turn_each_move, EP_CAN_TURN_EACH_MOVE }, - { ep_can_grow, EP_CAN_GROW }, - { ep_active_bomb, EP_ACTIVE_BOMB }, - { ep_inactive, EP_INACTIVE }, - - { ep_em_slippery_wall, EP_EM_SLIPPERY_WALL }, - - { ep_gfx_crumbled, EP_GFX_CRUMBLED }, - - { NULL, -1 } - }; - - static int copy_properties[][5] = - { - { - EL_BUG, - EL_BUG_LEFT, EL_BUG_RIGHT, - EL_BUG_UP, EL_BUG_DOWN - }, - { - EL_SPACESHIP, - EL_SPACESHIP_LEFT, EL_SPACESHIP_RIGHT, - EL_SPACESHIP_UP, EL_SPACESHIP_DOWN - }, - { - EL_BD_BUTTERFLY, - EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_RIGHT, - EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_DOWN - }, - { - EL_BD_FIREFLY, - EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_RIGHT, - EL_BD_FIREFLY_UP, EL_BD_FIREFLY_DOWN - }, - { - EL_PACMAN, - EL_PACMAN_LEFT, EL_PACMAN_RIGHT, - EL_PACMAN_UP, EL_PACMAN_DOWN - }, - { - EL_MOLE, - EL_MOLE_LEFT, EL_MOLE_RIGHT, - EL_MOLE_UP, EL_MOLE_DOWN - }, - { - -1, - -1, -1, -1, -1 - } + { ep_diggable, EP_DIGGABLE }, + { ep_collectible_only, EP_COLLECTIBLE_ONLY }, + { ep_dont_run_into, EP_DONT_RUN_INTO }, + { ep_dont_collide_with, EP_DONT_COLLIDE_WITH }, + { ep_dont_touch, EP_DONT_TOUCH }, + { ep_indestructible, EP_INDESTRUCTIBLE }, + { ep_slippery, EP_SLIPPERY }, + { ep_can_change, EP_CAN_CHANGE }, + { ep_can_move, EP_CAN_MOVE }, + { ep_can_fall, EP_CAN_FALL }, + { ep_can_smash_player, EP_CAN_SMASH_PLAYER }, + { ep_can_smash_enemies, EP_CAN_SMASH_ENEMIES }, + { ep_can_smash_everything, EP_CAN_SMASH_EVERYTHING }, + { ep_explodes_by_fire, EP_EXPLODES_BY_FIRE }, + { ep_explodes_smashed, EP_EXPLODES_SMASHED }, + { ep_explodes_impact, EP_EXPLODES_IMPACT }, + { ep_walkable_over, EP_WALKABLE_OVER }, + { ep_walkable_inside, EP_WALKABLE_INSIDE }, + { ep_walkable_under, EP_WALKABLE_UNDER }, + { ep_passable_over, EP_PASSABLE_OVER }, + { ep_passable_inside, EP_PASSABLE_INSIDE }, + { ep_passable_under, EP_PASSABLE_UNDER }, + { ep_droppable, EP_DROPPABLE }, + { ep_explodes_1x1_old, EP_EXPLODES_1X1_OLD }, + { ep_pushable, EP_PUSHABLE }, + { ep_explodes_cross_old, EP_EXPLODES_CROSS_OLD }, + { ep_protected, EP_PROTECTED }, + { ep_throwable, EP_THROWABLE }, + { ep_can_explode, EP_CAN_EXPLODE }, + { ep_gravity_reachable, EP_GRAVITY_REACHABLE }, + + { ep_player, EP_PLAYER }, + { ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL }, + { ep_switchable, EP_SWITCHABLE }, + { ep_bd_element, EP_BD_ELEMENT }, + { ep_sp_element, EP_SP_ELEMENT }, + { ep_sb_element, EP_SB_ELEMENT }, + { ep_gem, EP_GEM }, + { ep_food_dark_yamyam, EP_FOOD_DARK_YAMYAM }, + { ep_food_penguin, EP_FOOD_PENGUIN }, + { ep_food_pig, EP_FOOD_PIG }, + { ep_historic_wall, EP_HISTORIC_WALL }, + { ep_historic_solid, EP_HISTORIC_SOLID }, + { ep_classic_enemy, EP_CLASSIC_ENEMY }, + { ep_belt, EP_BELT }, + { ep_belt_active, EP_BELT_ACTIVE }, + { ep_belt_switch, EP_BELT_SWITCH }, + { ep_tube, EP_TUBE }, + { ep_keygate, EP_KEYGATE }, + { ep_amoeboid, EP_AMOEBOID }, + { ep_amoebalive, EP_AMOEBALIVE }, + { ep_has_editor_content, EP_HAS_EDITOR_CONTENT }, + { ep_can_turn_each_move, EP_CAN_TURN_EACH_MOVE }, + { ep_can_grow, EP_CAN_GROW }, + { ep_active_bomb, EP_ACTIVE_BOMB }, + { ep_inactive, EP_INACTIVE }, + + { ep_em_slippery_wall, EP_EM_SLIPPERY_WALL }, + + { ep_gfx_crumbled, EP_GFX_CRUMBLED }, + + { ep_editor_cascade_active, EP_EDITOR_CASCADE_ACTIVE }, + { ep_editor_cascade_inactive, EP_EDITOR_CASCADE_INACTIVE }, + + { NULL, -1 } }; int i, j, k; @@ -3534,38 +3567,6 @@ void InitElementPropertiesStatic() void InitElementPropertiesEngine(int engine_version) { -#if 0 - static int active_properties[] = - { - EP_AMOEBALIVE, - EP_AMOEBOID, - EP_PFORTE, - EP_DONT_COLLIDE_WITH, - EP_MAUER, - EP_CAN_FALL, - EP_CAN_SMASH, - EP_CAN_PASS_MAGIC_WALL, - EP_CAN_MOVE, - EP_DONT_TOUCH, - EP_DONT_RUN_INTO, - EP_GEM, - EP_EXPLODES_BY_FIRE, - EP_PUSHABLE, - EP_PLAYER, - EP_HAS_CONTENT, - EP_DIGGABLE, - EP_PASSABLE_INSIDE, - EP_OVER_PLAYER, - EP_ACTIVE_BOMB, - - EP_BELT, - EP_BELT_ACTIVE, - EP_BELT_SWITCH, - EP_WALKABLE_UNDER, - EP_EM_SLIPPERY_WALL, - }; -#endif - static int no_wall_properties[] = { EP_DIGGABLE, @@ -3597,10 +3598,6 @@ void InitElementPropertiesEngine(int engine_version) int i, j; -#if 0 - InitElementPropertiesStatic(); -#endif - /* important: after initialization in InitElementPropertiesStatic(), the elements are not again initialized to a default value; therefore all changes have to make sure that they leave the element with a defined @@ -3610,11 +3607,6 @@ void InitElementPropertiesEngine(int engine_version) /* set all special, combined or engine dependent element properties */ for (i = 0; i < MAX_NUM_ELEMENTS; i++) { -#if 0 - for (j = EP_ACCESSIBLE_OVER; j < NUM_ELEMENT_PROPERTIES; j++) - SET_PROPERTY(i, j, FALSE); -#endif - /* ---------- INACTIVE ------------------------------------------------- */ SET_PROPERTY(i, EP_INACTIVE, (i >= EL_CHAR_START && i <= EL_CHAR_END)); @@ -3669,12 +3661,6 @@ void InitElementPropertiesEngine(int engine_version) !IS_DIGGABLE(i) && !IS_COLLECTIBLE(i))); -#if 0 - /* ---------- PROTECTED ------------------------------------------------ */ - if (IS_ACCESSIBLE_INSIDE(i)) - SET_PROPERTY(i, EP_PROTECTED, TRUE); -#endif - /* ---------- DRAGONFIRE_PROOF ----------------------------------------- */ if (IS_HISTORIC_SOLID(i) || i == EL_EXPLOSION) @@ -3689,20 +3675,9 @@ void InitElementPropertiesEngine(int engine_version) else if (engine_version < VERSION_IDENT(2,2,0,0)) SET_PROPERTY(i, EP_EXPLOSION_PROOF, IS_INDESTRUCTIBLE(i)); else -#if 1 SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && (!IS_WALKABLE(i) || IS_PROTECTED(i)))); -#else -#if 1 - SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && - !IS_WALKABLE_OVER(i) && - !IS_WALKABLE_UNDER(i))); -#else - SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && - IS_PROTECTED(i))); -#endif -#endif if (IS_CUSTOM_ELEMENT(i)) { @@ -3726,25 +3701,6 @@ void InitElementPropertiesEngine(int engine_version) CAN_SMASH_ENEMIES(i) || CAN_SMASH_EVERYTHING(i))); -#if 0 - /* ---------- CAN_EXPLODE ---------------------------------------------- */ - SET_PROPERTY(i, EP_CAN_EXPLODE, (CAN_EXPLODE_BY_FIRE(i) || - CAN_EXPLODE_SMASHED(i) || - CAN_EXPLODE_IMPACT(i))); -#endif - -#if 0 - /* ---------- CAN_EXPLODE_3X3 ------------------------------------------ */ -#if 0 - SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (!CAN_EXPLODE_1X1(i) && - !CAN_EXPLODE_CROSS(i))); -#else - SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (CAN_EXPLODE(i) && - !CAN_EXPLODE_1X1(i) && - !CAN_EXPLODE_CROSS(i))); -#endif -#endif - /* ---------- CAN_EXPLODE_BY_FIRE -------------------------------------- */ SET_PROPERTY(i, EP_CAN_EXPLODE_BY_FIRE, (CAN_EXPLODE(i) && EXPLODES_BY_FIRE(i))); @@ -3793,29 +3749,31 @@ void InitElementPropertiesEngine(int engine_version) if (element_info[i].change_page[j].can_change) SET_PROPERTY(i, EP_CAN_CHANGE, TRUE); + /* ---------- HAS_ACTION ----------------------------------------------- */ + SET_PROPERTY(i, EP_HAS_ACTION, FALSE); /* default: has no action */ + for (j = 0; j < element_info[i].num_change_pages; j++) + if (element_info[i].change_page[j].has_action) + SET_PROPERTY(i, EP_HAS_ACTION, TRUE); + + /* ---------- CAN_CHANGE_OR_HAS_ACTION --------------------------------- */ + SET_PROPERTY(i, EP_CAN_CHANGE_OR_HAS_ACTION, (CAN_CHANGE(i) || + HAS_ACTION(i))); + /* ---------- GFX_CRUMBLED --------------------------------------------- */ +#if 1 + SET_PROPERTY(i, EP_GFX_CRUMBLED, + element_info[i].crumbled[ACTION_DEFAULT] != + element_info[i].graphic[ACTION_DEFAULT]); +#else + /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */ SET_PROPERTY(i, EP_GFX_CRUMBLED, element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY); - } - -#if 0 - /* determine inactive elements (used for engine main loop optimization) */ - for (i = 0; i < MAX_NUM_ELEMENTS; i++) - { - boolean active = FALSE; - - for (j = 0; i < NUM_ELEMENT_PROPERTIES; j++) - { - if (HAS_PROPERTY(i, j)) - active = TRUE; - } - -#if 0 - if (!active) - SET_PROPERTY(i, EP_INACTIVE, TRUE); #endif + + /* ---------- EDITOR_CASCADE ------------------------------------------- */ + SET_PROPERTY(i, EP_EDITOR_CASCADE, (IS_EDITOR_CASCADE_ACTIVE(i) || + IS_EDITOR_CASCADE_INACTIVE(i))); } -#endif /* dynamically adjust element properties according to game engine version */ { @@ -3841,7 +3799,6 @@ void InitElementPropertiesEngine(int engine_version) engine_version > VERSION_IDENT(2,0,1,0))); } -#if 1 /* set default push delay values (corrected since version 3.0.7-1) */ if (engine_version < VERSION_IDENT(3,0,7,1)) { @@ -3886,8 +3843,6 @@ void InitElementPropertiesEngine(int engine_version) SET_PROPERTY(EL_SP_SNIKSNAK, EP_DONT_COLLIDE_WITH, FALSE); SET_PROPERTY(EL_SP_ELECTRON, EP_DONT_COLLIDE_WITH, FALSE); } -#endif - #endif /* this is needed because some graphics depend on element properties */ @@ -3976,6 +3931,10 @@ void Execute_Command(char *command) printf("# (The entries below are default and therefore commented out.)\n"); printf("\n"); + /* this is needed to be able to check element list for cascade elements */ + InitElementPropertiesStatic(); + InitElementPropertiesEngine(GAME_VERSION_ACTUAL); + PrintEditorElementList(); exit(0); @@ -4013,7 +3972,7 @@ void Execute_Command(char *command) { char *filename = &command[11]; - if (access(filename, F_OK) != 0) + if (!fileExists(filename)) Error(ERR_EXIT, "cannot open file '%s'", filename); LoadLevelFromFilename(&level, filename); @@ -4025,7 +3984,7 @@ void Execute_Command(char *command) { char *filename = &command[10]; - if (access(filename, F_OK) != 0) + if (!fileExists(filename)) Error(ERR_EXIT, "cannot open file '%s'", filename); LoadTapeFromFilename(filename); @@ -4035,16 +3994,38 @@ void Execute_Command(char *command) } else if (strncmp(command, "autoplay ", 9) == 0) { - char *str_copy = getStringCopy(&command[9]); - char *str_ptr = strchr(str_copy, ' '); + char *str_ptr = getStringCopy(&command[9]); /* read command parameters */ - global.autoplay_leveldir = str_copy; - global.autoplay_level_nr = -1; - - if (str_ptr != NULL) + while (*str_ptr != '\0') /* continue parsing string */ { - *str_ptr++ = '\0'; /* terminate leveldir string */ - global.autoplay_level_nr = atoi(str_ptr); /* get level_nr value */ + /* 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.autoplay_leveldir == NULL) /* read level set string */ + { + global.autoplay_leveldir = str_ptr; + global.autoplay_all = TRUE; /* default: play all tapes */ + + for (i = 0; i < MAX_TAPES_PER_SET; i++) + global.autoplay_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.autoplay_level[level_nr] = TRUE; + + global.autoplay_all = FALSE; + } + + /* advance string pointer to the next whitespace (or end of string) */ + while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0') + str_ptr++; } } else if (strncmp(command, "convert ", 8) == 0) @@ -4055,7 +4036,7 @@ void Execute_Command(char *command) global.convert_leveldir = str_copy; global.convert_level_nr = -1; - if (str_ptr != NULL) + if (str_ptr != NULL) /* level number follows */ { *str_ptr++ = '\0'; /* terminate leveldir string */ global.convert_level_nr = atoi(str_ptr); /* get level_nr value */ @@ -4077,6 +4058,11 @@ static void InitSetup() options.verbose = TRUE; } +static void InitGameInfo() +{ + game.restart_level = FALSE; +} + static void InitPlayerInfo() { int i; @@ -4212,7 +4198,7 @@ static void InitArtworkConfig() for (i = 0; i < NUM_MUSIC_PREFIXES; i++) music_id_prefix[i] = music_prefix_info[i].prefix; - music_id_prefix[MAX_LEVELS] = NULL; + music_id_prefix[NUM_MUSIC_PREFIXES] = NULL; for (i = 0; i < NUM_ACTIONS; i++) action_id_suffix[i] = element_action_info[i].suffix; @@ -4313,8 +4299,6 @@ void InitGfx() DrawInitText(PROGRAM_COPYRIGHT_STRING, 50, FC_RED); DrawInitText("Loading graphics:", 120, FC_GREEN); - - InitTileClipmasks(); } void InitGfxBackground() @@ -4351,9 +4335,7 @@ void InitLevelArtworkInfo() static void InitImages() { -#if 1 setLevelArtworkDir(artwork.gfx_first); -#endif #if 0 printf("::: InitImages for '%s' ['%s', '%s'] ['%s', '%s']\n", @@ -4377,10 +4359,8 @@ static void InitSound(char *identifier) if (identifier == NULL) identifier = artwork.snd_current->identifier; -#if 1 /* set artwork path to send it to the sound server process */ setLevelArtworkDir(artwork.snd_first); -#endif InitReloadCustomSounds(identifier); ReinitializeSounds(); @@ -4391,10 +4371,8 @@ static void InitMusic(char *identifier) if (identifier == NULL) identifier = artwork.mus_current->identifier; -#if 1 /* set artwork path to send it to the sound server process */ setLevelArtworkDir(artwork.mus_first); -#endif InitReloadCustomMusic(identifier); ReinitializeMusic(); @@ -4507,7 +4485,7 @@ static char *getNewArtworkIdentifier(int type) artwork_current_identifier) != 0) artwork_new_identifier = artwork_current_identifier; - *(&(ARTWORK_CURRENT_IDENTIFIER(artwork, type))) = artwork_current_identifier; + *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type))= artwork_current_identifier; #if 0 if (type == ARTWORK_TYPE_GRAPHICS) @@ -4560,14 +4538,6 @@ void ReloadCustomArtwork(int force_reload) InitImages(); -#if 0 - printf("... '%s'\n", - leveldir_current->graphics_set); -#endif - - FreeTileClipmasks(); - InitTileClipmasks(); - redraw_screen = TRUE; } @@ -4612,7 +4582,7 @@ void KeyboardAutoRepeatOffUnlessAutoplay() void OpenAll() { - InitGlobal(); /* initialize some global variables */ + InitGlobal(); /* initialize some global variables */ if (options.execute_command) Execute_Command(options.execute_command); @@ -4624,11 +4594,13 @@ void OpenAll() #else Error(ERR_WARN, "networking only supported in Unix version"); #endif - exit(0); /* never reached */ + + exit(0); /* never reached, server loops forever */ } InitSetup(); + InitGameInfo(); InitPlayerInfo(); InitArtworkInfo(); /* needed before loading gfx, sound & music */ InitArtworkConfig(); /* needed before forking sound child process */ @@ -4695,7 +4667,6 @@ void CloseAllAndExit(int exit_value) #endif FreeAllImages(); - FreeTileClipmasks(); #if defined(TARGET_SDL) if (network_server) /* terminate network server */