X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=b3ef9a7e8fa58dd37a302b626de6da299ec29c7b;hb=8ba1db5ada8e24048c6cafdf4e784101b25f3c94;hp=c56fc69ee741c145fbaabe22b397042150011dc9;hpb=5bb4dba95d27f31aaa4a060c0efef70c671ebd7e;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index c56fc69e..b3ef9a7e 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); @@ -3713,6 +3720,72 @@ static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level) 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(); +} + // ---------------------------------------------------------------------------- // functions for loading EM level @@ -4172,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; @@ -6355,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) @@ -6441,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; @@ -8493,10 +8583,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)