X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=269a749b4c079accd068fb0186b31f5b51b9c103;hb=09c494592cdba76bdf8096fb20f9fcc6f3402981;hp=ae0dbf7dc053f11ad0c966185bc2b0115227c2d7;hpb=6b8725835d5397aadb73411c6f48b5f861256181;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index ae0dbf7d..269a749b 100644 --- a/src/files.c +++ b/src/files.c @@ -3657,17 +3657,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->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; + } + } - level->fieldx = MIN(level_bd->width, MAX_LEV_FIELDX); - level->fieldy = MIN(level_bd->height, MAX_LEV_FIELDY); + TapeHaltRecording(); } @@ -4129,8 +4238,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; @@ -8450,10 +8557,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)