X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=c684ab843bd5e854d309063eb5bd7c3b1d4ae616;hb=da8f8eaa9d466f33d94ff884230a613b3f239700;hp=7280860bbe8fd48029be0765ed5dbe0375f9170d;hpb=7ffc21d9a4a3772e2855611cd03c8942b8f0e395;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 7280860b..c684ab84 100644 --- a/src/files.c +++ b/src/files.c @@ -29,7 +29,7 @@ #define CHUNK_SIZE_NONE -1 /* do not write chunk size */ #define FILE_VERS_CHUNK_SIZE 8 /* size of file version chunk */ #define LEVEL_HEADER_SIZE 80 /* size of level file header */ -#define LEVEL_HEADER_UNUSED 1 /* unused level header bytes */ +#define LEVEL_HEADER_UNUSED 0 /* unused level header bytes */ #define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */ #define LEVEL_CHUNK_CNT2_UNUSED 11 /* unused CNT2 chunk bytes */ #define LEVEL_CHUNK_CNT3_HEADER 16 /* size of level CNT3 header */ @@ -49,22 +49,6 @@ #define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x" #define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2" -/* values for level file type identifier */ -#define LEVEL_FILE_TYPE_UNKNOWN 0 -#define LEVEL_FILE_TYPE_RND 1 -#define LEVEL_FILE_TYPE_BD 2 -#define LEVEL_FILE_TYPE_EM 3 -#define LEVEL_FILE_TYPE_SP 4 -#define LEVEL_FILE_TYPE_DX 5 -#define LEVEL_FILE_TYPE_SB 6 -#define LEVEL_FILE_TYPE_DC 7 - -#define LEVEL_FILE_TYPE_RND_PACKED (10 + LEVEL_FILE_TYPE_RND) -#define LEVEL_FILE_TYPE_EM_PACKED (10 + LEVEL_FILE_TYPE_EM) - -#define IS_SINGLE_LEVEL_FILE(x) (x < 10) -#define IS_PACKED_LEVEL_FILE(x) (x > 10) - /* ========================================================================= */ /* level file functions */ @@ -130,6 +114,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) int i, j, x, y; + level->game_engine_type = GAME_ENGINE_TYPE_RND; + level->file_version = FILE_VERSION_ACTUAL; level->game_version = GAME_VERSION_ACTUAL; @@ -313,6 +299,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) level->no_valid_file = FALSE; + level->changed = FALSE; + if (leveldir_current == NULL) /* only when dumping level */ return; @@ -549,6 +537,20 @@ static void determineLevelFileInfo_Filetype(struct LevelFileInfo *lfi) lfi->type = getFileTypeFromBasename(lfi->basename); } +#if 1 +static void setLevelFileInfo(struct LevelFileInfo *level_file_info, int nr) +{ + /* always start with reliable default values */ + setFileInfoToDefaults(level_file_info); + + level_file_info->nr = nr; /* set requested level number */ + + determineLevelFileInfo_Filename(level_file_info); + determineLevelFileInfo_Filetype(level_file_info); +} + +#else + static struct LevelFileInfo *getLevelFileInfo(int nr) { static struct LevelFileInfo level_file_info; @@ -563,7 +565,7 @@ static struct LevelFileInfo *getLevelFileInfo(int nr) return &level_file_info; } - +#endif /* ------------------------------------------------------------------------- */ /* functions for loading R'n'D level */ @@ -712,6 +714,8 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) level->can_pass_to_walkable = (getFile8Bit(file) == 1 ? TRUE : FALSE); level->grow_into_diggable = (getFile8Bit(file) == 1 ? TRUE : FALSE); + level->game_engine_type = getFile8Bit(file); + ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED); return chunk_size; @@ -1339,6 +1343,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, /* functions for loading EM level */ /* ------------------------------------------------------------------------- */ +#if 0 + static int map_em_element_yam(int element) { switch (element) @@ -1651,16 +1657,13 @@ static int map_em_element_field(int element) #define EM_LEVEL_XSIZE 64 #define EM_LEVEL_YSIZE 32 -static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) +static void OLD_LoadLevelFromFileInfo_EM(struct LevelInfo *level, + struct LevelFileInfo *level_file_info) { char *filename = level_file_info->filename; FILE *file; unsigned char leveldata[EM_LEVEL_SIZE]; unsigned char *header = &leveldata[EM_LEVEL_XSIZE * EM_LEVEL_YSIZE]; - unsigned char code0 = 0x65; - unsigned char code1 = 0x11; - boolean level_is_crypted = FALSE; int nr = level_file_info->nr; int i, x, y; @@ -1673,7 +1676,7 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, return; } - for(i = 0; i < EM_LEVEL_SIZE; i++) + for (i = 0; i < EM_LEVEL_SIZE; i++) leveldata[i] = fgetc(file); fclose(file); @@ -1684,20 +1687,20 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, if ((leveldata[0] == 0xf1 || leveldata[0] == 0xf5) && leveldata[2] == 0xe7 && leveldata[3] == 0xee) { - level_is_crypted = TRUE; + unsigned char code0 = 0x65; + unsigned char code1 = 0x11; if (leveldata[0] == 0xf5) /* error in crypted Emerald Mine 2 levels */ leveldata[0] = 0xf1; - } - if (level_is_crypted) /* decode crypted level data */ - { - for(i = 0; i < EM_LEVEL_SIZE; i++) + /* decode crypted level data */ + + for (i = 0; i < EM_LEVEL_SIZE; i++) { leveldata[i] ^= code0; leveldata[i] -= code1; - code0 = (code0 + 7) & 0xff; + code0 = (code0 + 7) & 0xff; } } @@ -1730,9 +1733,9 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, level->num_yamyam_contents = 4; - for(i = 0; i < level->num_yamyam_contents; i++) - for(y = 0; y < 3; y++) - for(x = 0; x < 3; x++) + for (i = 0; i < level->num_yamyam_contents; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) level->yamyam_content[i][x][y] = map_em_element_yam(header[i * 9 + y * 3 + x]); @@ -1760,6 +1763,18 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, level->field[x][y] = EL_PLAYER_2; } +#else + +static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, + struct LevelFileInfo *level_file_info) +{ + if (!LoadNativeLevel_EM(level_file_info->filename)) + level->no_valid_file = TRUE; +} + +#endif + + /* ------------------------------------------------------------------------- */ /* functions for loading SP level */ /* ------------------------------------------------------------------------- */ @@ -1911,13 +1926,13 @@ static void LoadLevelFromFileStream_SP(FILE *file, struct LevelInfo *level, level->time_wheel = 0; level->amoeba_content = EL_EMPTY; - for(i = 0; i < LEVEL_SCORE_ELEMENTS; i++) + for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++) level->score[i] = 0; /* !!! CORRECT THIS !!! */ /* there are no yamyams in supaplex levels */ - for(i = 0; i < level->num_yamyam_contents; i++) - for(y = 0; y < 3; y++) - for(x = 0; x < 3; x++) + for (i = 0; i < level->num_yamyam_contents; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) level->yamyam_content[i][x][y] = EL_EMPTY; } @@ -2118,6 +2133,7 @@ void LoadLevelFromFileInfo(struct LevelInfo *level, case LEVEL_FILE_TYPE_EM: LoadLevelFromFileInfo_EM(level, level_file_info); + level->game_engine_type = GAME_ENGINE_TYPE_EM; break; case LEVEL_FILE_TYPE_SP: @@ -2128,6 +2144,9 @@ void LoadLevelFromFileInfo(struct LevelInfo *level, LoadLevelFromFileInfo_RND(level, level_file_info); break; } + + if (level->game_engine_type == GAME_ENGINE_TYPE_UNKNOWN) + level->game_engine_type = GAME_ENGINE_TYPE_RND; } void LoadLevelFromFilename(struct LevelInfo *level, char *filename) @@ -2374,6 +2393,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } /* initialize "can_explode" field for old levels which did not store this */ + /* !!! CHECK THIS -- "<= 3,1,0,0" IS PROBABLY WRONG !!! */ if (level->game_version <= VERSION_IDENT(3,1,0,0)) { for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) @@ -2389,6 +2409,22 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } } + /* correct previously hard-coded move delay values for maze runner style */ + if (level->game_version < VERSION_IDENT(3,1,1,0)) + { + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + + if (element_info[element].move_pattern & MV_MAZE_RUNNER_STYLE) + { + /* previously hard-coded and therefore ignored */ + element_info[element].move_delay_fixed = 9; + element_info[element].move_delay_random = 0; + } + } + } + #if 0 /* set default push delay values (corrected since version 3.0.7-1) */ if (level->game_version < VERSION_IDENT(3,0,7,1)) @@ -2481,6 +2517,16 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename) void LoadLevelTemplate(int nr) { +#if 1 + char *filename; + + setLevelFileInfo(&level_template.file_info, nr); + filename = level_template.file_info.filename; + + LoadLevelFromFileInfo(&level_template, &level_template.file_info); + +#else + #if 1 struct LevelFileInfo *level_file_info = getLevelFileInfo(nr); char *filename = level_file_info->filename; @@ -2491,6 +2537,7 @@ void LoadLevelTemplate(int nr) LoadLevelFromFilename_RND(&level_template, filename); #endif +#endif #if 1 LoadLevel_InitVersion(&level_template, filename); @@ -2505,6 +2552,16 @@ void LoadLevelTemplate(int nr) void LoadLevel(int nr) { +#if 1 + char *filename; + + setLevelFileInfo(&level.file_info, nr); + filename = level.file_info.filename; + + LoadLevelFromFileInfo(&level, &level.file_info); + +#else + #if 1 struct LevelFileInfo *level_file_info = getLevelFileInfo(nr); char *filename = level_file_info->filename; @@ -2514,6 +2571,7 @@ void LoadLevel(int nr) char *filename = getLevelFilename(nr); LoadLevelFromFilename_RND(&level, filename); +#endif #endif if (level.use_custom_template) @@ -2579,6 +2637,8 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) putFile8Bit(file, (level->can_pass_to_walkable ? 1 : 0)); putFile8Bit(file, (level->grow_into_diggable ? 1 : 0)); + putFile8Bit(file, level->game_engine_type); + WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED); } @@ -3606,6 +3666,8 @@ void DumpTape(struct TapeInfo *tape) printf_line("-", 79); printf("Tape of Level %03d (file version %08d, game version %08d)\n", tape->level_nr, tape->file_version, tape->game_version); + printf(" (effective engine version %08d)\n", + tape->engine_version); printf("Level series identifier: '%s'\n", tape->level_identifier); printf_line("-", 79);