X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=c5d8eb30691e232dcc0203f794525aead073b19f;hb=73dfe4a920cabf20138c0ba49964a3c8c3f752d0;hp=8e6ec1bb99c58cae3cca6f98f50d4bf1c7b1cefb;hpb=f7eeeedb1a0bb21cbd8366cf241faffc76aafc16;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 8e6ec1bb..c5d8eb30 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 7 /* unused level header bytes */ +#define LEVEL_HEADER_UNUSED 6 /* 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 */ @@ -164,6 +164,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) level->can_move_into_acid_bits = ~0; /* everything can move into acid */ + level->player_can_fall_into_acid = TRUE; + level->use_step_counter = FALSE; level->use_custom_template = FALSE; @@ -289,7 +291,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) BorderElement = EL_STEELWALL; - level->no_level_file = FALSE; + level->no_valid_file = FALSE; if (leveldir_current == NULL) /* only when dumping level */ return; @@ -549,7 +551,7 @@ static struct LevelFileInfo *getLevelFileInfo(int nr) int getMappedElement(int element) { - /* map some (historic, now obsolete) elements */ + /* remap some (historic, now obsolete) elements */ #if 1 switch (element) @@ -610,6 +612,32 @@ int getMappedElement(int element) return element; } +int getMappedElementByVersion(int element, int game_version) +{ + /* remap some elements due to certain game version */ + + if (game_version <= VERSION_IDENT(2,2,0,0)) + { + /* map game font elements */ + element = (element == EL_CHAR('[') ? EL_CHAR_AUMLAUT : + element == EL_CHAR('\\') ? EL_CHAR_OUMLAUT : + element == EL_CHAR(']') ? EL_CHAR_UUMLAUT : + element == EL_CHAR('^') ? EL_CHAR_COPYRIGHT : element); + } + + if (game_version < VERSION_IDENT(3,0,0,0)) + { + /* map Supaplex gravity tube elements */ + element = (element == EL_SP_GRAVITY_PORT_LEFT ? EL_SP_PORT_LEFT : + element == EL_SP_GRAVITY_PORT_RIGHT ? EL_SP_PORT_RIGHT : + element == EL_SP_GRAVITY_PORT_UP ? EL_SP_PORT_UP : + element == EL_SP_GRAVITY_PORT_DOWN ? EL_SP_PORT_DOWN : + element); + } + + return element; +} + static int LoadLevel_VERS(FILE *file, int chunk_size, struct LevelInfo *level) { level->file_version = getFileVersion(file); @@ -661,6 +689,8 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) level->use_step_counter = (getFile8Bit(file) == 1 ? TRUE : FALSE); + level->player_can_fall_into_acid = (getFile8Bit(file) == 1 ? TRUE : FALSE); + ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED); return chunk_size; @@ -1156,7 +1186,7 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, if (!(file = fopen(filename, MODE_READ))) { - level->no_level_file = TRUE; + level->no_valid_file = TRUE; if (level != &level_template) Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); @@ -1172,6 +1202,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, getFileChunkBE(file, chunk_name, NULL); if (strcmp(chunk_name, "CAVE") != 0) { + level->no_valid_file = TRUE; + Error(ERR_WARN, "unknown format of level file '%s'", filename); fclose(file); return; @@ -1186,6 +1218,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, if (!checkCookieString(cookie, LEVEL_COOKIE_TMPL)) { + level->no_valid_file = TRUE; + Error(ERR_WARN, "unknown format of level file '%s'", filename); fclose(file); return; @@ -1193,6 +1227,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, if ((level->file_version = getFileVersionFromCookieString(cookie)) == -1) { + level->no_valid_file = TRUE; + Error(ERR_WARN, "unsupported version of level file '%s'", filename); fclose(file); return; @@ -1606,7 +1642,7 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, if (!(file = fopen(filename, MODE_READ))) { - level->no_level_file = TRUE; + level->no_valid_file = TRUE; Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); @@ -1798,7 +1834,7 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, if (!(file = fopen(filename, MODE_READ))) { - level->no_level_file = TRUE; + level->no_valid_file = TRUE; Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename); @@ -1808,7 +1844,7 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, /* position file stream to the requested level inside the level package */ if (fseek(file, nr * SP_LEVEL_SIZE, SEEK_SET) != 0) { - level->no_level_file = TRUE; + level->no_valid_file = TRUE; Error(ERR_WARN, "cannot fseek level '%s' -- using empty level", filename); @@ -2130,7 +2166,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) { - int i, j; + int i, j, x, y; /* map custom element change events that have changed in newer versions (these following values were accidentally changed in version 3.0.1) */ @@ -2189,7 +2225,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } } - /* correct custom element fields (for old levels without these options) */ + /* correct custom element values (for old levels without these options) */ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) { int element = EL_CUSTOM_START + i; @@ -2232,6 +2268,16 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename) } #endif + /* map elements that have changed in newer versions */ + level->amoeba_content = getMappedElementByVersion(level->amoeba_content, + level->game_version); + for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) + for (x = 0; x < 3; x++) + for (y = 0; y < 3; y++) + level->yamyam_content[i][x][y] = + getMappedElementByVersion(level->yamyam_content[i][x][y], + level->game_version); + /* initialize element properties for level editor etc. */ InitElementPropertiesEngine(level->game_version); } @@ -2247,6 +2293,9 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename) { int element = level->field[x][y]; +#if 1 + element = getMappedElementByVersion(element, level->game_version); +#else if (level->game_version <= VERSION_IDENT(2,2,0,0)) { /* map game font elements */ @@ -2265,6 +2314,7 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename) element == EL_SP_GRAVITY_PORT_DOWN ? EL_SP_PORT_DOWN : element); } +#endif level->field[x][y] = element; } @@ -2375,6 +2425,8 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) putFile8Bit(file, (level->use_step_counter ? 1 : 0)); + putFile8Bit(file, (level->player_can_fall_into_acid ? 1 : 0)); + WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED); } @@ -2888,6 +2940,13 @@ void SaveLevelTemplate() void DumpLevel(struct LevelInfo *level) { + if (level->no_valid_file) + { + Error(ERR_WARN, "cannot dump -- no valid level file found"); + + return; + } + printf_line("-", 79); printf("Level xxx (file version %08d, game version %08d)\n", level->file_version, level->game_version); @@ -2946,6 +3005,8 @@ static void setTapeInfoToDefaults() tape.recording = FALSE; tape.playing = FALSE; tape.pausing = FALSE; + + tape.no_valid_file = FALSE; } static int LoadTape_VERS(FILE *file, int chunk_size, struct TapeInfo *tape) @@ -3110,7 +3171,13 @@ void LoadTapeFromFilename(char *filename) setTapeInfoToDefaults(); if (!(file = fopen(filename, MODE_READ))) + { + tape.no_valid_file = TRUE; + + Error(ERR_WARN, "cannot read tape '%s' -- using empty tape", filename); + return; + } getFileChunkBE(file, chunk_name, NULL); if (strcmp(chunk_name, "RND1") == 0) @@ -3120,6 +3187,8 @@ void LoadTapeFromFilename(char *filename) getFileChunkBE(file, chunk_name, NULL); if (strcmp(chunk_name, "TAPE") != 0) { + tape.no_valid_file = TRUE; + Error(ERR_WARN, "unknown format of tape file '%s'", filename); fclose(file); return; @@ -3134,6 +3203,8 @@ void LoadTapeFromFilename(char *filename) if (!checkCookieString(cookie, TAPE_COOKIE_TMPL)) { + tape.no_valid_file = TRUE; + Error(ERR_WARN, "unknown format of tape file '%s'", filename); fclose(file); return; @@ -3141,6 +3212,8 @@ void LoadTapeFromFilename(char *filename) if ((tape.file_version = getFileVersionFromCookieString(cookie)) == -1) { + tape.no_valid_file = TRUE; + Error(ERR_WARN, "unsupported version of tape file '%s'", filename); fclose(file); return; @@ -3357,11 +3430,21 @@ void DumpTape(struct TapeInfo *tape) { int i, j; +#if 1 + if (tape->no_valid_file) + { + Error(ERR_WARN, "cannot dump -- no valid tape file found"); + + return; + } +#else if (TAPE_IS_EMPTY(*tape)) { Error(ERR_WARN, "no tape available for level %d", tape->level_nr); + return; } +#endif printf_line("-", 79); printf("Tape of Level %03d (file version %08d, game version %08d)\n",