X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=7b851893f1ab6eea1d5cd808fade44b29f72da5b;hb=bddf6c22480ed7f7fca83b7d6c4f9dc10d19f57a;hp=34d9f6d0b92f2e00810e63c5b799c9a5f566ebbc;hpb=9f0fd9ccc8b367c5cca4de7b4504fdd7231c866c;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 34d9f6d0..7b851893 100644 --- a/src/files.c +++ b/src/files.c @@ -2101,6 +2101,13 @@ static int getFileTypeFromBasename(char *basename) strchr(basename, '%') == NULL) return LEVEL_FILE_TYPE_SB; + // check for typical filename of a Boulder Dash (GDash) level package file + if (strSuffixLower(basename, ".bd") || + strSuffixLower(basename, ".bdr") || + strSuffixLower(basename, ".brc") || + strSuffixLower(basename, ".gds")) + return LEVEL_FILE_TYPE_BD; + // ---------- try to determine file type from filesize ---------- checked_free(filename); @@ -3657,17 +3664,126 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, static void CopyNativeLevel_RND_to_BD(struct LevelInfo *level) { struct LevelInfo_BD *level_bd = level->native_bd_level; + GdCave *cave = NULL; // will be changed below + int cave_w = MIN(level->fieldx, MAX_PLAYFIELD_WIDTH); + int cave_h = MIN(level->fieldy, MAX_PLAYFIELD_HEIGHT); + int i, x, y; + + setLevelInfoToDefaults_BD_Ext(cave_w, cave_h); + + // cave and map newly allocated when set to defaults above + cave = level_bd->cave; + + for (i = 0; i < 5; i++) + { + cave->level_time[i] = level->time; + cave->level_diamonds[i] = level->gems_needed; + cave->level_magic_wall_time[i] = level->time_magic_wall; + cave->level_timevalue[i] = level->score[SC_TIME_BONUS]; + } + + cave->diamond_value = level->score[SC_DIAMOND]; + cave->extra_diamond_value = level->score[SC_DIAMOND]; + + cave->level_speed[0] = 160; // set cave speed - level_bd->width = MIN(level->fieldx, MAX_PLAYFIELD_WIDTH); - level_bd->height = MIN(level->fieldy, MAX_PLAYFIELD_HEIGHT); + strncpy(cave->name, level->name, sizeof(GdString)); + cave->name[sizeof(GdString) - 1] = '\0'; + + for (x = 0; x < cave->w; x++) + for (y = 0; y < cave->h; y++) + cave->map[y][x] = map_element_RND_to_BD(level->field[x][y]); } static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level) { struct LevelInfo_BD *level_bd = level->native_bd_level; + GdCave *cave = level_bd->cave; + int bd_level_nr = level_bd->level_nr; + int x, y; + + level->fieldx = MIN(cave->w, MAX_LEV_FIELDX); + level->fieldy = MIN(cave->h, MAX_LEV_FIELDY); - level->fieldx = MIN(level_bd->width, MAX_LEV_FIELDX); - level->fieldy = MIN(level_bd->height, MAX_LEV_FIELDY); + level->time = cave->level_time[bd_level_nr]; + level->gems_needed = cave->level_diamonds[bd_level_nr]; + level->time_magic_wall = cave->level_magic_wall_time[bd_level_nr]; + + level->score[SC_TIME_BONUS] = cave->level_timevalue[bd_level_nr]; + level->score[SC_DIAMOND] = cave->diamond_value; + + strncpy(level->name, cave->name, MAX_LEVEL_NAME_LEN); + level->name[MAX_LEVEL_NAME_LEN] = '\0'; + + for (x = 0; x < level->fieldx; x++) + for (y = 0; y < level->fieldy; y++) + level->field[x][y] = map_element_BD_to_RND(cave->map[y][x]); +} + +static void setTapeInfoToDefaults(void); + +static void CopyNativeTape_BD_to_RND(struct LevelInfo *level) +{ + struct LevelInfo_BD *level_bd = level->native_bd_level; + GdCave *cave = level_bd->cave; + GdReplay *replay = level_bd->replay; + int i; + + if (replay == NULL) + return; + + // always start with reliable default values + setTapeInfoToDefaults(); + + tape.level_nr = level_nr; // (currently not used) + tape.random_seed = replay->seed; + + TapeSetDateFromIsoDateString(replay->date); + + tape.counter = 0; + tape.pos[tape.counter].delay = 0; + + tape.bd_replay = TRUE; + + // all time calculations only used to display approximate tape time + int cave_speed = cave->speed; + int milliseconds_game = 0; + int milliseconds_elapsed = 20; + + for (i = 0; i < replay->movements->len; i++) + { + int replay_action = replay->movements->data[i]; + int tape_action = map_action_BD_to_RND(replay_action); + byte action[MAX_TAPE_ACTIONS] = { tape_action }; + boolean success = 0; + + while (1) + { + success = TapeAddAction(action); + + milliseconds_game += milliseconds_elapsed; + + if (milliseconds_game >= cave_speed) + { + milliseconds_game -= cave_speed; + + break; + } + } + + tape.counter++; + tape.pos[tape.counter].delay = 0; + tape.pos[tape.counter].action[0] = 0; + + if (!success) + { + Warn("BD replay truncated: size exceeds maximum tape size %d", MAX_TAPE_LEN); + + break; + } + } + + TapeHaltRecording(); } @@ -4129,8 +4245,6 @@ static void CopyNativeTape_RND_to_SP(struct LevelInfo *level) demo->is_available = TRUE; } -static void setTapeInfoToDefaults(void); - static void CopyNativeTape_SP_to_RND(struct LevelInfo *level) { struct LevelInfo_SP *level_sp = level->native_sp_level; @@ -6312,6 +6426,20 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level, // functions for handling native levels // ------------------------------------------------------------------------- +static void LoadLevelFromFileInfo_BD(struct LevelInfo *level, + struct LevelFileInfo *level_file_info, + boolean level_info_only) +{ + int pos = 0; + + // determine position of requested level inside level package + if (level_file_info->packed) + pos = level_file_info->nr - leveldir_current->first_level; + + if (!LoadNativeLevel_BD(level_file_info->filename, pos, level_info_only)) + level->no_valid_file = TRUE; +} + static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, struct LevelFileInfo *level_file_info, boolean level_info_only) @@ -6398,6 +6526,11 @@ static void LoadLevelFromFileInfo(struct LevelInfo *level, LoadLevelFromFileInfo_RND(level, level_file_info, level_info_only); break; + case LEVEL_FILE_TYPE_BD: + LoadLevelFromFileInfo_BD(level, level_file_info, level_info_only); + level->game_engine_type = GAME_ENGINE_TYPE_BD; + break; + case LEVEL_FILE_TYPE_EM: LoadLevelFromFileInfo_EM(level, level_file_info, level_info_only); level->game_engine_type = GAME_ENGINE_TYPE_EM; @@ -6430,6 +6563,9 @@ static void LoadLevelFromFileInfo(struct LevelInfo *level, if (level->no_valid_file) setLevelInfoToDefaults(level, level_info_only, FALSE); + if (check_special_flags("use_native_bd_game_engine")) + level->game_engine_type = GAME_ENGINE_TYPE_BD; + if (level->game_engine_type == GAME_ENGINE_TYPE_UNKNOWN) level->game_engine_type = GAME_ENGINE_TYPE_RND; @@ -8450,10 +8586,15 @@ void LoadSolutionTape(int nr) LoadTapeFromFilename(filename); - if (TAPE_IS_EMPTY(tape) && - level.game_engine_type == GAME_ENGINE_TYPE_SP && - level.native_sp_level->demo.is_available) - CopyNativeTape_SP_to_RND(&level); + if (TAPE_IS_EMPTY(tape)) + { + if (level.game_engine_type == GAME_ENGINE_TYPE_BD && + level.native_bd_level->replay != NULL) + CopyNativeTape_BD_to_RND(&level); + else if (level.game_engine_type == GAME_ENGINE_TYPE_SP && + level.native_sp_level->demo.is_available) + CopyNativeTape_SP_to_RND(&level); + } } void LoadScoreTape(char *score_tape_basename, int nr) @@ -9664,6 +9805,22 @@ static struct TokenInfo global_setup_tokens[] = TYPE_INTEGER, &setup.game_frame_delay, "game_frame_delay" }, + { + TYPE_SWITCH, + &setup.bd_skip_uncovering, "bd_skip_uncovering" + }, + { + TYPE_SWITCH, + &setup.bd_skip_hatching, "bd_skip_hatching" + }, + { + TYPE_SWITCH, + &setup.bd_scroll_delay, "bd_scroll_delay" + }, + { + TYPE_SWITCH3, + &setup.bd_smooth_movements, "bd_smooth_movements" + }, { TYPE_SWITCH, &setup.sp_show_border_elements, "sp_show_border_elements" @@ -9868,6 +10025,10 @@ static struct TokenInfo editor_cascade_setup_tokens[] = TYPE_SWITCH, &setup.editor_cascade.el_bd, "editor.cascade.el_bd" }, + { + TYPE_SWITCH, + &setup.editor_cascade.el_bd_native, "editor.cascade.el_bd_native" + }, { TYPE_SWITCH, &setup.editor_cascade.el_em, "editor.cascade.el_em" @@ -10476,6 +10637,10 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->prefer_extra_panel_items = TRUE; si->game_speed_extended = FALSE; si->game_frame_delay = GAME_FRAME_DELAY; + si->bd_skip_uncovering = FALSE; + si->bd_skip_hatching = FALSE; + si->bd_scroll_delay = TRUE; + si->bd_smooth_movements = AUTO; si->sp_show_border_elements = FALSE; si->small_game_graphics = FALSE; si->show_load_save_buttons = FALSE; @@ -10557,6 +10722,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->touch.overlay_buttons = FALSE; si->editor.el_boulderdash = TRUE; + si->editor.el_boulderdash_native = TRUE; si->editor.el_emerald_mine = TRUE; si->editor.el_emerald_mine_club = TRUE; si->editor.el_more = TRUE; @@ -10730,6 +10896,7 @@ static void setSetupInfoToDefaults_ServerSetup(struct SetupInfo *si) static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si) { si->editor_cascade.el_bd = TRUE; + si->editor_cascade.el_bd_native = TRUE; si->editor_cascade.el_em = TRUE; si->editor_cascade.el_emc = TRUE; si->editor_cascade.el_rnd = TRUE;