X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=a4a926005cc45df991a2855d54b0146c47b3bdd5;hb=ad15815ec04f42779d0717a6d291f93b8e847d39;hp=80073129cc76208eb9d72c61abd0790f39b1e01d;hpb=ea933dd51bfca7ddcc6b75465476cce57afd1682;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index 80073129..a4a92600 100644 --- a/src/init.c +++ b/src/init.c @@ -260,21 +260,11 @@ static int getFontBitmapID(int font_nr) { int special = -1; - if (game_status == MAINMENU || game_status == TYPENAME) + if (game_status >= GAME_MODE_MAIN && game_status <= GAME_MODE_PSEUDO_PREVIEW) + special = game_status; + else if (game_status == GAME_MODE_PSEUDO_TYPENAME) special = GFX_SPECIAL_ARG_MAIN; - else if (game_status == CHOOSELEVEL) - special = GFX_SPECIAL_ARG_LEVELS; - else if (game_status == HALLOFFAME) - special = GFX_SPECIAL_ARG_SCORES; - else if (game_status == LEVELED) - special = GFX_SPECIAL_ARG_EDITOR; - else if (game_status == HELPSCREEN) - special = GFX_SPECIAL_ARG_INFO; - else if (game_status == SETUP) - special = GFX_SPECIAL_ARG_SETUP; - else if (game_status == PSEUDO_PREVIEW) - special = GFX_SPECIAL_ARG_PREVIEW; - else if (game_status == PLAYING || game_status == PSEUDO_DOOR) + else if (game_status == GAME_MODE_PLAYING) special = GFX_SPECIAL_ARG_DOOR; if (special != -1) @@ -301,8 +291,13 @@ 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++) @@ -363,7 +358,7 @@ void InitFontGraphicInfo() /* ---------- initialize font bitmap array ---------- */ if (font_bitmap_info != NULL) - free(font_bitmap_info); + FreeFontInfo(font_bitmap_info); font_bitmap_info = checked_calloc(num_font_bitmaps * sizeof(struct FontBitmapInfo)); @@ -383,6 +378,13 @@ void InitFontGraphicInfo() int font_bitmap_id = font_info[i].special_bitmap_id[j]; int graphic = font_info[i].special_graphic[j]; + /* set 'graphic_info' for font entries, if uninitialized (guessed) */ + if (graphic_info[graphic].anim_frames < MIN_NUM_CHARS_PER_FONT) + { + graphic_info[graphic].anim_frames = DEFAULT_NUM_CHARS_PER_FONT; + graphic_info[graphic].anim_frames_per_line= DEFAULT_NUM_CHARS_PER_LINE; + } + /* copy font relevant information from graphics information */ font_bitmap_info[font_bitmap_id].bitmap = graphic_info[graphic].bitmap; font_bitmap_info[font_bitmap_id].src_x = graphic_info[graphic].src_x; @@ -391,6 +393,11 @@ void InitFontGraphicInfo() font_bitmap_info[font_bitmap_id].height = graphic_info[graphic].height; font_bitmap_info[font_bitmap_id].draw_x = graphic_info[graphic].draw_x; font_bitmap_info[font_bitmap_id].draw_y = graphic_info[graphic].draw_y; + + font_bitmap_info[font_bitmap_id].num_chars = + graphic_info[graphic].anim_frames; + font_bitmap_info[font_bitmap_id].num_chars_per_line = + graphic_info[graphic].anim_frames_per_line; } } @@ -409,27 +416,59 @@ void InitElementGraphicInfo() for (act=0; act -1; i++) { - int element = element_to_graphic[i].element; - int action = element_to_graphic[i].action; - int direction = element_to_graphic[i].direction; - int graphic = element_to_graphic[i].graphic; + int element = element_to_graphic[i].element; + int action = element_to_graphic[i].action; + int direction = element_to_graphic[i].direction; + boolean crumbled = element_to_graphic[i].crumbled; + int graphic = element_to_graphic[i].graphic; + + if (graphic_info[graphic].bitmap == NULL) + continue; + + if ((action > -1 || direction > -1 || crumbled == TRUE) && + el2img(element) != -1) + { + boolean base_redefined = getImageListEntry(el2img(element))->redefined; + boolean act_dir_redefined = getImageListEntry(graphic)->redefined; + + /* if the base graphic ("emerald", for example) has been redefined, + but not the action graphic ("emerald.falling", for example), do not + use an existing (in this case considered obsolete) action graphic + anymore, but use the automatically determined default graphic */ + if (base_redefined && !act_dir_redefined) + continue; + } if (action < 0) action = ACTION_DEFAULT; - if (direction > -1) - element_info[element].direction_graphic[action][direction] = graphic; + if (crumbled) + { + if (direction > -1) + element_info[element].direction_crumbled[action][direction] = graphic; + else + element_info[element].crumbled[action] = graphic; + } else - element_info[element].graphic[action] = graphic; + { + if (direction > -1) + element_info[element].direction_graphic[action][direction] = graphic; + else + element_info[element].graphic[action] = graphic; + } } /* initialize normal element/graphic mapping from dynamic configuration */ @@ -440,6 +479,16 @@ void InitElementGraphicInfo() int direction = property_mapping[i].ext2_index; int special = property_mapping[i].ext3_index; int graphic = property_mapping[i].artwork_index; + boolean crumbled = FALSE; + + if (special == GFX_SPECIAL_ARG_CRUMBLED) + { + special = -1; + crumbled = TRUE; + } + + if (graphic_info[graphic].bitmap == NULL) + continue; if (element >= MAX_NUM_ELEMENTS || special != -1) continue; @@ -447,50 +496,207 @@ void InitElementGraphicInfo() if (action < 0) action = ACTION_DEFAULT; - if (direction > -1) - element_info[element].direction_graphic[action][direction] = graphic; + if (crumbled) + { + if (direction < 0) + for (dir=0; dir -1) + element_info[element].direction_crumbled[action][direction] = graphic; + else + element_info[element].crumbled[action] = graphic; + } else - element_info[element].graphic[action] = graphic; + { + if (direction < 0) + for (dir=0; dir -1) + element_info[element].direction_graphic[action][direction] = graphic; + else + element_info[element].graphic[action] = graphic; + } + } + + /* now copy all graphics that are defined to be cloned from other graphics */ + for (i=0; i 0 && graphic_info[graphic].bitmap == NULL) + element_info[i].graphic[act] = -1; + + graphic = element_info[i].crumbled[act]; + if (graphic > 0 && graphic_info[graphic].bitmap == NULL) + element_info[i].crumbled[act] = -1; + + for (dir=0; dir 0 && graphic_info[graphic].bitmap == NULL) + element_info[i].direction_graphic[act][dir] = -1; + + graphic = element_info[i].direction_crumbled[act][dir]; + if (graphic > 0 && graphic_info[graphic].bitmap == NULL) + element_info[i].direction_crumbled[act][dir] = -1; + } + } } +#endif /* now set all '-1' values to element specific default values */ for (i=0; iredefined; boolean special_redefined = getImageListEntry(graphic)->redefined; + /* if the base graphic ("emerald", for example) has been redefined, + but not the special graphic ("emerald.EDITOR", for example), do not + use an existing (in this case considered obsolete) special graphic + anymore, but use the automatically created (down-scaled) graphic */ if (base_redefined && !special_redefined) continue; @@ -546,22 +756,47 @@ void InitElementSpecialGraphicInfo() if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS) 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) +{ + int i; + + for (i=0; i < MAX_NUM_ELEMENTS; i++) + if (strcmp(element_info[i].token_name, token) == 0) + return i; + + return -1; } static void set_graphic_parameters(int graphic, char **parameter_raw) { Bitmap *src_bitmap = getBitmapFromImageID(graphic); - int num_xtiles = (src_bitmap ? src_bitmap->width : TILEX) / TILEX; - int num_ytiles = (src_bitmap ? src_bitmap->height * 2 / 3 : TILEY) / TILEY; int parameter[NUM_GFX_ARGS]; + int anim_frames_per_row = 1, anim_frames_per_col = 1; + int anim_frames_per_line = 1; int i; /* 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]); + } + graphic_info[graphic].bitmap = src_bitmap; /* start with reliable default values */ @@ -571,6 +806,9 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) graphic_info[graphic].height = TILEY; graphic_info[graphic].offset_x = 0; /* one or both of these values ... */ graphic_info[graphic].offset_y = 0; /* ... will be corrected later */ + graphic_info[graphic].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 */ /* optional x and y tile position of animation frame sequence */ if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE) @@ -590,20 +828,26 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE) graphic_info[graphic].height = parameter[GFX_ARG_HEIGHT]; - /* correct x or y offset dependant of vertical or horizontal frame order */ + if (src_bitmap) + { + anim_frames_per_row = src_bitmap->width / graphic_info[graphic].width; + anim_frames_per_col = src_bitmap->height / graphic_info[graphic].height; + } + + /* correct x or y offset dependent of vertical or horizontal frame order */ if (parameter[GFX_ARG_VERTICAL]) /* frames are ordered vertically */ { - if (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].offset_y = parameter[GFX_ARG_OFFSET]; - else - graphic_info[graphic].offset_y = graphic_info[graphic].height; + graphic_info[graphic].offset_y = + (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ? + parameter[GFX_ARG_OFFSET] : graphic_info[graphic].height); + anim_frames_per_line = anim_frames_per_col; } else /* frames are ordered horizontally */ { - if (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE) - graphic_info[graphic].offset_x = parameter[GFX_ARG_OFFSET]; - else - graphic_info[graphic].offset_x = graphic_info[graphic].width; + graphic_info[graphic].offset_x = + (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ? + parameter[GFX_ARG_OFFSET] : graphic_info[graphic].width); + anim_frames_per_line = anim_frames_per_row; } /* optionally, the x and y offset of frames can be specified directly */ @@ -616,20 +860,25 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) if (parameter[GFX_ARG_FRAMES] != ARG_UNDEFINED_VALUE) graphic_info[graphic].anim_frames = parameter[GFX_ARG_FRAMES]; else if (parameter[GFX_ARG_XPOS] == 0 && !parameter[GFX_ARG_VERTICAL]) - graphic_info[graphic].anim_frames = num_xtiles; + graphic_info[graphic].anim_frames = anim_frames_per_row; else if (parameter[GFX_ARG_YPOS] == 0 && parameter[GFX_ARG_VERTICAL]) - graphic_info[graphic].anim_frames = num_ytiles; + graphic_info[graphic].anim_frames = anim_frames_per_col; else graphic_info[graphic].anim_frames = 1; + graphic_info[graphic].anim_frames_per_line = + (parameter[GFX_ARG_FRAMES_PER_LINE] != ARG_UNDEFINED_VALUE ? + parameter[GFX_ARG_FRAMES_PER_LINE] : anim_frames_per_line); + graphic_info[graphic].anim_delay = parameter[GFX_ARG_DELAY]; if (graphic_info[graphic].anim_delay == 0) /* delay must be at least 1 */ graphic_info[graphic].anim_delay = 1; - if (parameter[GFX_ARG_ANIM_MODE] != ANIM_NONE) - graphic_info[graphic].anim_mode = parameter[GFX_ARG_ANIM_MODE]; - else if (graphic_info[graphic].anim_frames > 1) - graphic_info[graphic].anim_mode = ANIM_LOOP; + graphic_info[graphic].anim_mode = parameter[GFX_ARG_ANIM_MODE]; +#if 0 + if (graphic_info[graphic].anim_frames == 1) + graphic_info[graphic].anim_mode = ANIM_NONE; +#endif /* automatically determine correct start frame, if not defined */ if (parameter[GFX_ARG_START_FRAME] == ARG_UNDEFINED_VALUE) @@ -643,6 +892,18 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) /* animation synchronized with global frame counter, not move position */ graphic_info[graphic].anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC]; + /* optional element for cloning crumble graphics */ + if (parameter[GFX_ARG_CRUMBLED_LIKE] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].crumbled_like = parameter[GFX_ARG_CRUMBLED_LIKE]; + + /* optional element for cloning digging graphics */ + if (parameter[GFX_ARG_DIGGABLE_LIKE] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].diggable_like = parameter[GFX_ARG_DIGGABLE_LIKE]; + + /* optional border size for "crumbling" diggable graphics */ + if (parameter[GFX_ARG_BORDER_SIZE] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].border_size = parameter[GFX_ARG_BORDER_SIZE]; + /* this is only used for toon animations */ graphic_info[graphic].step_offset = parameter[GFX_ARG_STEP_OFFSET]; graphic_info[graphic].step_delay = parameter[GFX_ARG_STEP_DELAY]; @@ -650,6 +911,9 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) /* this is only used for drawing font characters */ graphic_info[graphic].draw_x = parameter[GFX_ARG_DRAW_XOFFSET]; graphic_info[graphic].draw_y = parameter[GFX_ARG_DRAW_YOFFSET]; + + /* this is only used for drawing envelope graphics */ + graphic_info[graphic].draw_masked = parameter[GFX_ARG_DRAW_MASKED]; } static void InitGraphicInfo() @@ -673,6 +937,10 @@ 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) { @@ -696,6 +964,16 @@ static void InitGraphicInfo() int src_x, src_y; int first_frame, last_frame; +#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, image->parameter); /* now check if no animation frames are outside of the loaded image */ @@ -828,48 +1106,61 @@ static void InitElementSoundInfo() element_info[j].sound[action] = sound; } - /* initialize element/sound mapping from dynamic configuration */ + /* initialize element class/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; + int element_class = property_mapping[i].base_index - MAX_NUM_ELEMENTS; + int action = property_mapping[i].ext1_index; + int sound = property_mapping[i].artwork_index; - if (element >= MAX_NUM_ELEMENTS) + if (element_class < 0 || element_class >= MAX_NUM_ELEMENTS) continue; if (action < 0) action = ACTION_DEFAULT; - element_info[element].sound[action] = sound; + for (j=0; j < MAX_NUM_ELEMENTS; j++) + if (strcmp(element_info[j].class_name, + element_info[element_class].class_name) == 0) + element_info[j].sound[action] = sound; } - /* initialize element class/sound mapping from dynamic configuration */ + /* initialize element/sound mapping from dynamic configuration */ for (i=0; i < num_property_mappings; i++) { - int element_class = property_mapping[i].base_index - MAX_NUM_ELEMENTS; - int action = property_mapping[i].ext1_index; - int sound = property_mapping[i].artwork_index; + int element = property_mapping[i].base_index; + int action = property_mapping[i].ext1_index; + int sound = property_mapping[i].artwork_index; - if (element_class < 0 || element_class >= MAX_NUM_ELEMENTS) + if (element >= MAX_NUM_ELEMENTS) continue; if (action < 0) action = ACTION_DEFAULT; - for (j=0; j < MAX_NUM_ELEMENTS; j++) - if (strcmp(element_info[j].class_name, - element_info[element_class].class_name) == 0) - element_info[j].sound[action] = sound; + element_info[element].sound[action] = sound; } /* now set all '-1' values to element specific default values */ for (i=0; itoken); +#endif + /* determine all loop sounds and identify certain sound classes */ for (j=0; element_action_info[j].suffix; j++) @@ -931,12 +1228,17 @@ static void InitSoundInfo() element_action_info[j].suffix) == 0) { sound_effect_properties[i] = element_action_info[j].value; + sound_info[i].loop = element_action_info[j].is_loop_sound; - if (element_action_info[j].is_loop_sound) - sound_info[i].loop = TRUE; + break; } } +#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= EL_CHAR_START && i <= EL_CHAR_END) + SET_PROPERTY(i, EP_INACTIVE, TRUE); + + /* ---------- WALKABLE, PASSABLE, ACCESSIBLE --------------------------- */ + SET_PROPERTY(i, EP_WALKABLE, (IS_WALKABLE_OVER(i) || + IS_WALKABLE_INSIDE(i) || + IS_WALKABLE_UNDER(i))); + + SET_PROPERTY(i, EP_PASSABLE, (IS_PASSABLE_OVER(i) || + IS_PASSABLE_INSIDE(i) || + IS_PASSABLE_UNDER(i))); + + SET_PROPERTY(i, EP_ACCESSIBLE_OVER, (IS_WALKABLE_OVER(i) || + IS_PASSABLE_OVER(i))); + + SET_PROPERTY(i, EP_ACCESSIBLE_INSIDE, (IS_WALKABLE_INSIDE(i) || + IS_PASSABLE_INSIDE(i))); + + SET_PROPERTY(i, EP_ACCESSIBLE_UNDER, (IS_WALKABLE_UNDER(i) || + IS_PASSABLE_UNDER(i))); + + SET_PROPERTY(i, EP_ACCESSIBLE, (IS_WALKABLE(i) || + IS_PASSABLE(i))); + + /* ---------- COLLECTIBLE ---------------------------------------------- */ + SET_PROPERTY(i, EP_COLLECTIBLE, (IS_COLLECTIBLE_ONLY(i) || + IS_DROPPABLE(i))); + + /* ---------- SNAPPABLE ------------------------------------------------ */ + SET_PROPERTY(i, EP_SNAPPABLE, (IS_DIGGABLE(i) || + IS_COLLECTIBLE(i) || + IS_SWITCHABLE(i) || + i == EL_BD_ROCK)); + + /* ---------- WALL ----------------------------------------------------- */ + SET_PROPERTY(i, EP_WALL, TRUE); /* default: element is wall */ + + for (j=0; no_wall_properties[j] != -1; j++) + if (HAS_PROPERTY(i, no_wall_properties[j]) || + i >= EL_FIRST_RUNTIME_UNREAL) + SET_PROPERTY(i, EP_WALL, FALSE); + + if (IS_HISTORIC_WALL(i)) + SET_PROPERTY(i, EP_WALL, TRUE); + + /* ---------- SOLID_FOR_PUSHING ---------------------------------------- */ + if (engine_version < VERSION_IDENT(2,2,0)) + SET_PROPERTY(i, EP_SOLID_FOR_PUSHING, IS_HISTORIC_SOLID(i)); + else + SET_PROPERTY(i, EP_SOLID_FOR_PUSHING, (!IS_WALKABLE(i) && + !IS_DIGGABLE(i) && + !IS_COLLECTIBLE(i))); + + /* ---------- DRAGONFIRE_PROOF ----------------------------------------- */ + + if (IS_HISTORIC_SOLID(i) || i == EL_EXPLOSION) + SET_PROPERTY(i, EP_DRAGONFIRE_PROOF, TRUE); + else + SET_PROPERTY(i, EP_DRAGONFIRE_PROOF, (IS_CUSTOM_ELEMENT(i) && + IS_INDESTRUCTIBLE(i))); + + /* ---------- EXPLOSION_PROOF ------------------------------------------ */ + if (i == EL_FLAMES) + SET_PROPERTY(i, EP_EXPLOSION_PROOF, TRUE); + else if (engine_version < VERSION_IDENT(2,2,0)) + SET_PROPERTY(i, EP_EXPLOSION_PROOF, IS_INDESTRUCTIBLE(i)); + else + SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) && + !IS_WALKABLE_OVER(i) && + !IS_WALKABLE_UNDER(i))); + + if (IS_CUSTOM_ELEMENT(i)) + { + /* ---------- DONT_COLLIDE_WITH / DONT_RUN_INTO ---------------------- */ + if (DONT_TOUCH(i)) + SET_PROPERTY(i, EP_DONT_COLLIDE_WITH, TRUE); + if (DONT_COLLIDE_WITH(i)) + SET_PROPERTY(i, EP_DONT_RUN_INTO, TRUE); + + /* ---------- CAN_SMASH_ENEMIES / CAN_SMASH_PLAYER ------------------- */ + if (CAN_SMASH_EVERYTHING(i)) + SET_PROPERTY(i, EP_CAN_SMASH_ENEMIES, TRUE); + if (CAN_SMASH_ENEMIES(i)) + SET_PROPERTY(i, EP_CAN_SMASH_PLAYER, TRUE); + } + + /* ---------- CAN_SMASH ------------------------------------------------ */ + SET_PROPERTY(i, EP_CAN_SMASH, (CAN_SMASH_PLAYER(i) || + CAN_SMASH_ENEMIES(i) || + CAN_SMASH_EVERYTHING(i))); + + /* ---------- CAN_EXPLODE ---------------------------------------------- */ + SET_PROPERTY(i, EP_CAN_EXPLODE, (CAN_EXPLODE_BY_FIRE(i) || + CAN_EXPLODE_SMASHED(i) || + CAN_EXPLODE_IMPACT(i))); + + /* ---------- CAN_EXPLODE_3X3 ------------------------------------------ */ + SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (CAN_EXPLODE(i) && + !CAN_EXPLODE_1X1(i))); + + /* ---------- CAN_CHANGE ----------------------------------------------- */ + SET_PROPERTY(i, EP_CAN_CHANGE, FALSE); /* default: cannot change */ + for (j=0; j < element_info[i].num_change_pages; j++) + if (element_info[i].change_page[j].can_change) + SET_PROPERTY(i, EP_CAN_CHANGE, TRUE); + + /* ---------- GFX_CRUMBLED --------------------------------------------- */ + 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 + } +#endif + + /* dynamically adjust element properties according to game engine version */ { - Properties1[i] = 0; - Properties2[i] = 0; + static int ep_em_slippery_wall[] = + { + EL_STEELWALL, + EL_WALL, + EL_EXPANDABLE_WALL, + EL_EXPANDABLE_WALL_HORIZONTAL, + EL_EXPANDABLE_WALL_VERTICAL, + EL_EXPANDABLE_WALL_ANY, + -1 + }; + + /* special EM style gems behaviour */ + for (i=0; ep_em_slippery_wall[i] != -1; i++) + SET_PROPERTY(ep_em_slippery_wall[i], EP_EM_SLIPPERY_WALL, + level.em_slippery_gems); + + /* "EL_EXPANDABLE_WALL_GROWING" wasn't slippery for EM gems in 2.0.1 */ + SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL, + (level.em_slippery_gems && + engine_version > VERSION_IDENT(2,0,1))); } - for (i=0; iidentifier, + artwork.gfx_current_identifier, + artwork.gfx_current->identifier, + leveldir_current->graphics_set, + leveldir_current->graphics_path); +#endif + ReloadCustomImages(); LoadCustomElementDescriptions(); @@ -2575,15 +3335,31 @@ static void InitImages() ReinitializeGraphics(); } -static void InitSound() +static void InitSound(char *identifier) { - InitReloadCustomSounds(artwork.snd_current->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(); } -static void InitMusic() +static void InitMusic(char *identifier) { - InitReloadCustomMusic(artwork.mus_current->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(); } @@ -2610,129 +3386,165 @@ void InitNetworkServer() #endif } -void ReloadCustomArtwork() +static char *getNewArtworkIdentifier(int type) { - static char *leveldir_current_identifier = NULL; - static boolean last_override_level_graphics = FALSE; - static boolean last_override_level_sounds = FALSE; - static boolean last_override_level_music = FALSE; - /* identifier for new artwork; default: artwork configured in setup */ - char *gfx_new_identifier = artwork.gfx_current->identifier; - char *snd_new_identifier = artwork.snd_current->identifier; - char *mus_new_identifier = artwork.mus_current->identifier; - boolean redraw_screen = FALSE; + static char *leveldir_current_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 }; + TreeInfo *artwork_first_node = ARTWORK_FIRST_NODE(artwork, type); + boolean setup_override_artwork = SETUP_OVERRIDE_ARTWORK(setup, type); + char *setup_artwork_set = SETUP_ARTWORK_SET(setup, type); + char *leveldir_identifier = leveldir_current->identifier; +#if 1 + /* !!! setLevelArtworkDir() should be moved to an earlier stage !!! */ + char *leveldir_artwork_set = setLevelArtworkDir(artwork_first_node); +#else + char *leveldir_artwork_set = LEVELDIR_ARTWORK_SET(leveldir_current, type); +#endif + boolean has_level_artwork_set = (leveldir_artwork_set != NULL); + char *artwork_current_identifier; + char *artwork_new_identifier = NULL; /* default: nothing has changed */ + + /* leveldir_current may be invalid (level group, parent link) */ + if (!validLevelSeries(leveldir_current)) + return NULL; + + /* 1st step: determine artwork set to be activated in descending order: + -------------------------------------------------------------------- + 1. setup artwork (when configured to override everything else) + 2. artwork set configured in "levelinfo.conf" of current level set + (artwork in level directory will have priority when loading later) + 3. artwork in level directory (stored in artwork sub-directory) + 4. setup artwork (currently configured in setup menu) */ + + if (setup_override_artwork) + artwork_current_identifier = setup_artwork_set; + else if (leveldir_artwork_set != NULL) + artwork_current_identifier = leveldir_artwork_set; + else if (getTreeInfoFromIdentifier(artwork_first_node, leveldir_identifier)) + artwork_current_identifier = leveldir_identifier; + else + artwork_current_identifier = setup_artwork_set; - if (leveldir_current_identifier == NULL) - leveldir_current_identifier = leveldir_current->identifier; + + /* 2nd step: check if it is really needed to reload artwork set + ------------------------------------------------------------ */ #if 0 - printf("CURRENT GFX: '%s' ['%s']\n", artwork.gfx_current->identifier, - leveldir_current->graphics_set); - printf("CURRENT LEV: '%s' / '%s'\n", leveldir_current_identifier, - leveldir_current->identifier); + if (type == ARTWORK_TYPE_GRAPHICS) + printf("::: 0: '%s' ['%s', '%s'] ['%s' ('%s')]\n", + artwork_new_identifier, + ARTWORK_CURRENT_IDENTIFIER(artwork, type), + artwork_current_identifier, + leveldir_current->graphics_set, + leveldir_current->identifier); #endif + /* ---------- reload if level set and also artwork set has changed ------- */ + if (leveldir_current_identifier[type] != leveldir_identifier && + (last_has_level_artwork_set[type] || has_level_artwork_set)) + artwork_new_identifier = artwork_current_identifier; + + leveldir_current_identifier[type] = leveldir_identifier; + last_has_level_artwork_set[type] = has_level_artwork_set; + #if 0 - printf("graphics --> '%s' ('%s')\n", - artwork.gfx_current_identifier, artwork.gfx_current->filename); - printf("sounds --> '%s' ('%s')\n", - artwork.snd_current_identifier, artwork.snd_current->filename); - printf("music --> '%s' ('%s')\n", - artwork.mus_current_identifier, artwork.mus_current->filename); + if (type == ARTWORK_TYPE_GRAPHICS) + printf("::: 1: '%s'\n", artwork_new_identifier); #endif - /* leveldir_current may be invalid (level group, parent link) */ - if (!validLevelSeries(leveldir_current)) - return; + /* ---------- reload if "override artwork" setting has changed ----------- */ + if (last_override_level_artwork[type] != setup_override_artwork) + artwork_new_identifier = artwork_current_identifier; - /* when a new level series was selected, check if there was a change - in custom artwork stored in level series directory */ - if (leveldir_current_identifier != leveldir_current->identifier) - { - char *identifier_old = leveldir_current_identifier; - char *identifier_new = leveldir_current->identifier; + last_override_level_artwork[type] = setup_override_artwork; - if (getTreeInfoFromIdentifier(artwork.gfx_first, identifier_old) != - getTreeInfoFromIdentifier(artwork.gfx_first, identifier_new)) - gfx_new_identifier = identifier_new; - if (getTreeInfoFromIdentifier(artwork.snd_first, identifier_old) != - getTreeInfoFromIdentifier(artwork.snd_first, identifier_new)) - snd_new_identifier = identifier_new; - if (getTreeInfoFromIdentifier(artwork.mus_first, identifier_new) != - getTreeInfoFromIdentifier(artwork.mus_first, identifier_new)) - mus_new_identifier = identifier_new; +#if 0 + if (type == ARTWORK_TYPE_GRAPHICS) + printf("::: 2: '%s'\n", artwork_new_identifier); +#endif - leveldir_current_identifier = leveldir_current->identifier; - } + /* ---------- reload if current artwork identifier has changed ----------- */ + if (strcmp(ARTWORK_CURRENT_IDENTIFIER(artwork, type), + artwork_current_identifier) != 0) + artwork_new_identifier = artwork_current_identifier; - /* custom level artwork configured in level series configuration file - always overrides custom level artwork stored in level series directory - and (level independant) custom artwork configured in setup menue */ - if (leveldir_current->graphics_set != NULL) - gfx_new_identifier = leveldir_current->graphics_set; - if (leveldir_current->sounds_set != NULL) - snd_new_identifier = leveldir_current->sounds_set; - if (leveldir_current->music_set != NULL) - mus_new_identifier = leveldir_current->music_set; + *(&(ARTWORK_CURRENT_IDENTIFIER(artwork, type))) = artwork_current_identifier; - if (strcmp(artwork.gfx_current_identifier, gfx_new_identifier) != 0 || - last_override_level_graphics != setup.override_level_graphics) +#if 0 + if (type == ARTWORK_TYPE_GRAPHICS) + printf("::: 3: '%s'\n", artwork_new_identifier); +#endif + + /* ---------- do not reload directly after starting ---------------------- */ + if (!initialized[type]) + artwork_new_identifier = NULL; + + initialized[type] = TRUE; + +#if 0 + if (type == ARTWORK_TYPE_GRAPHICS) + printf("::: 4: '%s'\n", artwork_new_identifier); +#endif + +#if 0 + if (type == ARTWORK_TYPE_GRAPHICS) + printf("CHECKING OLD/NEW GFX:\n- OLD: %s\n- NEW: %s ['%s', '%s'] ['%s']\n", + artwork.gfx_current_identifier, artwork_current_identifier, + artwork.gfx_current->identifier, leveldir_current->graphics_set, + artwork_new_identifier); +#endif + + return artwork_new_identifier; +} + +void ReloadCustomArtwork() +{ + char *gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS); + char *snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS); + char *mus_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_MUSIC); + boolean redraw_screen = FALSE; + + if (gfx_new_identifier != NULL) { #if 0 - printf("RELOADING GRAPHICS '%s' -> '%s' ('%s')\n", + printf("RELOADING GRAPHICS '%s' -> '%s' ['%s', '%s']\n", artwork.gfx_current_identifier, + gfx_new_identifier, artwork.gfx_current->identifier, - gfx_new_identifier); + leveldir_current->graphics_set); #endif - setLevelArtworkDir(artwork.gfx_first); - ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); InitImages(); +#if 0 + printf("... '%s'\n", + leveldir_current->graphics_set); +#endif + FreeTileClipmasks(); InitTileClipmasks(); - artwork.gfx_current_identifier = artwork.gfx_current->identifier; - last_override_level_graphics = setup.override_level_graphics; - redraw_screen = TRUE; } - if (strcmp(artwork.snd_current_identifier, snd_new_identifier) != 0 || - last_override_level_sounds != setup.override_level_sounds) + if (snd_new_identifier != NULL) { -#if 0 - printf("RELOADING SOUNDS '%s' -> '%s' ('%s')\n", - artwork.snd_current_identifier, - artwork.snd_current->identifier, - snd_new_identifier); -#endif - - /* set artwork path to send it to the sound server process */ - setLevelArtworkDir(artwork.snd_first); - - InitReloadCustomSounds(snd_new_identifier); - ReinitializeSounds(); + ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); - artwork.snd_current_identifier = artwork.snd_current->identifier; - last_override_level_sounds = setup.override_level_sounds; + InitSound(snd_new_identifier); redraw_screen = TRUE; } - if (strcmp(artwork.mus_current_identifier, mus_new_identifier) != 0 || - last_override_level_music != setup.override_level_music) + if (mus_new_identifier != NULL) { - /* set artwork path to send it to the sound server process */ - setLevelArtworkDir(artwork.mus_first); - - InitReloadCustomMusic(mus_new_identifier); - ReinitializeMusic(); + ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); - artwork.mus_current_identifier = artwork.mus_current->identifier; - last_override_level_music = setup.override_level_music; + InitMusic(mus_new_identifier); redraw_screen = TRUE; } @@ -2747,6 +3559,12 @@ void ReloadCustomArtwork() } } +void KeyboardAutoRepeatOffUnlessAutoplay() +{ + if (global.autoplay_leveldir == NULL) + KeyboardAutoRepeatOff(); +} + /* ========================================================================= */ /* OpenAll() */ @@ -2789,7 +3607,8 @@ void OpenAll() InitEventFilter(FilterMouseMotionEvents); - InitElementProperties(); + InitElementPropertiesStatic(); + InitElementPropertiesEngine(GAME_VERSION_ACTUAL); InitGfx(); @@ -2797,8 +3616,8 @@ void OpenAll() InitLevelArtworkInfo(); InitImages(); /* needs to know current level directory */ - InitSound(); /* needs to know current level directory */ - InitMusic(); /* needs to know current level directory */ + InitSound(NULL); /* needs to know current level directory */ + InitMusic(NULL); /* needs to know current level directory */ InitGfxBackground(); @@ -2808,7 +3627,7 @@ void OpenAll() return; } - game_status = MAINMENU; + game_status = GAME_MODE_MAIN; DrawMainMenu(); @@ -2826,7 +3645,7 @@ void CloseAllAndExit(int exit_value) FreeTileClipmasks(); CloseVideoDisplay(); - ClosePlatformDependantStuff(); + ClosePlatformDependentStuff(); exit(exit_value); }