X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Finit.c;h=7132ab78c99a89f07aad6e8ee759c55c1436194d;hb=76b3cb92402127cde194888bab57397eca735220;hp=40ecc4d759b37b0a7d8767933e494e83741a4390;hpb=6c244f56b4911dc83930193a43497388b91696af;p=rocksndiamonds.git diff --git a/src/init.c b/src/init.c index 40ecc4d7..7132ab78 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) @@ -363,7 +353,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)); @@ -421,30 +411,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 */ @@ -455,6 +474,13 @@ 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; @@ -465,54 +491,147 @@ 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; 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; @@ -572,19 +695,36 @@ void InitElementSpecialGraphicInfo() } } +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 parameter[NUM_GFX_ARGS]; - int num_xtiles = 1, num_ytiles = 1; + 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 */ @@ -594,6 +734,8 @@ 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 */ /* optional x and y tile position of animation frame sequence */ if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE) @@ -615,19 +757,25 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) if (src_bitmap) { - num_xtiles = src_bitmap->width / graphic_info[graphic].width; - num_ytiles = src_bitmap->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; } - /* correct x or y offset dependant of vertical or horizontal frame order */ + /* correct x or y offset dependent of vertical or horizontal frame order */ if (parameter[GFX_ARG_VERTICAL]) /* frames are ordered vertically */ + { 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 */ + { 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 */ if (parameter[GFX_ARG_XOFFSET] != ARG_UNDEFINED_VALUE) @@ -639,15 +787,15 @@ 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] : graphic_info[graphic].anim_frames); + 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 */ @@ -669,6 +817,14 @@ 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]; + /* 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]; @@ -722,6 +878,16 @@ static void InitGraphicInfo() int src_x, src_y; int first_frame, last_frame; +#if 0 + printf("::: image: '%s'\n", image->token); +#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 */ @@ -854,48 +1020,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++) @@ -957,12 +1142,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_BE_CRUMBLED ------------------------------------------ */ + SET_PROPERTY(i, EP_CAN_BE_CRUMBLED, + element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY); + +#if 0 + if (CAN_BE_CRUMBLED(i)) + printf("::: '%s' can be crumbled [%d]\n", + element_info[i].token_name, + element_info[i].crumbled[ACTION_DEFAULT]); +#endif + } + +#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(); @@ -2628,15 +3218,27 @@ 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; + + /* set artwork path to send it to the sound server process */ + setLevelArtworkDir(artwork.snd_first); + + InitReloadCustomSounds(identifier); ReinitializeSounds(); } -static void InitMusic() +static void InitMusic(char *identifier) { - InitReloadCustomMusic(artwork.mus_current->identifier); + if (identifier == NULL) + identifier = artwork.mus_current->identifier; + + /* set artwork path to send it to the sound server process */ + setLevelArtworkDir(artwork.mus_first); + + InitReloadCustomMusic(identifier); ReinitializeMusic(); } @@ -2663,83 +3265,100 @@ 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; + char *leveldir_artwork_set = LEVELDIR_ARTWORK_SET(leveldir_current, type); + boolean has_level_artwork_set = (leveldir_artwork_set != NULL); + char *artwork_current_identifier; + char *artwork_new_identifier = NULL; /* default: nothing has changed */ - if (leveldir_current_identifier == NULL) - leveldir_current_identifier = leveldir_current->identifier; + /* 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 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); -#endif -#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); -#endif + /* 2nd step: check if it is really needed to reload artwork set + ------------------------------------------------------------ */ - /* leveldir_current may be invalid (level group, parent link) */ - if (!validLevelSeries(leveldir_current)) - return; + /* ---------- 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; - /* 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; + leveldir_current_identifier[type] = leveldir_identifier; + last_has_level_artwork_set[type] = has_level_artwork_set; - 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; + /* ---------- reload if "override artwork" setting has changed ----------- */ + if (last_override_level_artwork[type] != setup_override_artwork) + artwork_new_identifier = artwork_current_identifier; - leveldir_current_identifier = leveldir_current->identifier; - } + last_override_level_artwork[type] = setup_override_artwork; + + /* ---------- reload if current artwork identifier has changed ----------- */ + if (strcmp(ARTWORK_CURRENT_IDENTIFIER(artwork, type), + artwork_current_identifier) != 0) + artwork_new_identifier = artwork_current_identifier; + + *(&(ARTWORK_CURRENT_IDENTIFIER(artwork, type))) = artwork_current_identifier; + + /* ---------- do not reload directly after starting ---------------------- */ + if (!initialized[type]) + artwork_new_identifier = NULL; + + initialized[type] = TRUE; + +#if 0 + 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; +} - /* 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; +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 (strcmp(artwork.gfx_current_identifier, gfx_new_identifier) != 0 || - last_override_level_graphics != setup.override_level_graphics) + if (gfx_new_identifier != NULL) { #if 0 - printf("RELOADING GRAPHICS '%s' -> '%s' ('%s')\n", + printf("RELOADING GRAPHICS '%s' -> '%s' ['%s']\n", artwork.gfx_current_identifier, - artwork.gfx_current->identifier, - gfx_new_identifier); + gfx_new_identifier, + artwork.gfx_current->identifier); #endif - setLevelArtworkDir(artwork.gfx_first); - ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE); InitImages(); @@ -2747,45 +3366,23 @@ void ReloadCustomArtwork() 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; } @@ -2800,6 +3397,12 @@ void ReloadCustomArtwork() } } +void KeyboardAutoRepeatOffUnlessAutoplay() +{ + if (global.autoplay_leveldir == NULL) + KeyboardAutoRepeatOff(); +} + /* ========================================================================= */ /* OpenAll() */ @@ -2842,7 +3445,7 @@ void OpenAll() InitEventFilter(FilterMouseMotionEvents); - InitElementProperties(); + InitElementPropertiesStatic(); InitGfx(); @@ -2850,8 +3453,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(); @@ -2861,7 +3464,7 @@ void OpenAll() return; } - game_status = MAINMENU; + game_status = GAME_MODE_MAIN; DrawMainMenu(); @@ -2879,7 +3482,7 @@ void CloseAllAndExit(int exit_value) FreeTileClipmasks(); CloseVideoDisplay(); - ClosePlatformDependantStuff(); + ClosePlatformDependentStuff(); exit(exit_value); }