X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=8fe110f24254cece6bd2d43f606229d665c35da3;hb=4096fcbae692bfbf2f6506786659872a60b31693;hp=6038711a994f5568680b1a1af62dbc0b5690f718;hpb=fbe0eaa3234fb6a69a65136f764922e24943501d;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 6038711a..8fe110f2 100644 --- a/src/files.c +++ b/src/files.c @@ -27,12 +27,16 @@ #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 14 /* unused level header bytes */ +#define LEVEL_HEADER_UNUSED 13 /* 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_CPART_CUS3_SIZE 134 /* size of CUS3 chunk part */ +#define LEVEL_CPART_CUS3_UNUSED 15 /* unused CUS3 bytes / part */ #define TAPE_HEADER_SIZE 20 /* size of tape file header */ #define TAPE_HEADER_UNUSED 3 /* unused tape header bytes */ +#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + x * LEVEL_CPART_CUS3_SIZE) + /* file identifier strings */ #define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x" #define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x" @@ -45,7 +49,7 @@ static void setLevelInfoToDefaults() { - int i, x, y; + int i, j, x, y; level.file_version = FILE_VERSION_ACTUAL; level.game_version = GAME_VERSION_ACTUAL; @@ -73,6 +77,8 @@ static void setLevelInfoToDefaults() level.gravity = FALSE; level.em_slippery_gems = FALSE; + level.use_custom_template = FALSE; + for(i=0; iscore[i] = fgetc(file); - level->num_yam_contents = STD_ELEMENT_CONTENTS; + level->num_yamyam_contents = STD_ELEMENT_CONTENTS; for(i=0; iyam_content[i][x][y] = checkLevelElement(fgetc(file)); + level->yamyam_content[i][x][y] = checkLevelElement(fgetc(file)); level->amoeba_speed = fgetc(file); level->time_magic_wall = fgetc(file); @@ -194,6 +267,8 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) level->encoding_16bit_field = (fgetc(file) == 1 ? TRUE : FALSE); level->em_slippery_gems = (fgetc(file) == 1 ? TRUE : FALSE); + level->use_custom_template = (fgetc(file) == 1 ? TRUE : FALSE); + ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED); return chunk_size; @@ -259,19 +334,19 @@ static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level) } fgetc(file); - level->num_yam_contents = fgetc(file); + level->num_yamyam_contents = fgetc(file); fgetc(file); fgetc(file); /* correct invalid number of content fields -- should never happen */ - if (level->num_yam_contents < 1 || - level->num_yam_contents > MAX_ELEMENT_CONTENTS) - level->num_yam_contents = STD_ELEMENT_CONTENTS; + if (level->num_yamyam_contents < 1 || + level->num_yamyam_contents > MAX_ELEMENT_CONTENTS) + level->num_yamyam_contents = STD_ELEMENT_CONTENTS; for(i=0; iyam_content[i][x][y] = + level->yamyam_content[i][x][y] = checkLevelElement(level->encoding_16bit_field ? getFile16BitBE(file) : fgetc(file)); return chunk_size; @@ -301,12 +376,12 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level) if (element == EL_YAMYAM) { - level->num_yam_contents = num_contents; + level->num_yamyam_contents = num_contents; for(i=0; iyam_content[i][x][y] = content_array[i][x][y]; + level->yamyam_content[i][x][y] = content_array[i][x][y]; } else if (element == EL_BD_AMOEBA) { @@ -361,11 +436,10 @@ static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level) for (i=0; i < num_changed_custom_elements; i++) { int element = getFile16BitBE(file); - int custom_element_successor = getFile16BitBE(file); - int i = element - EL_CUSTOM_START; + int custom_target_element = getFile16BitBE(file); if (IS_CUSTOM_ELEMENT(element)) - level->custom_element_successor[i] = custom_element_successor; + element_info[element].change.target_element = custom_target_element; else Error(ERR_WARN, "invalid custom element number %d", element); } @@ -373,6 +447,93 @@ static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level) return chunk_size; } +static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level) +{ + int num_changed_custom_elements = getFile16BitBE(file); + int chunk_size_expected = LEVEL_CHUNK_CUS3_SIZE(num_changed_custom_elements); + int i, j, x, y; + + if (chunk_size_expected != chunk_size) + { + ReadUnusedBytesFromFile(file, chunk_size - 2); + return chunk_size_expected; + } + + for (i=0; i < num_changed_custom_elements; i++) + { + int element = getFile16BitBE(file); + + if (!IS_CUSTOM_ELEMENT(element)) + { + Error(ERR_WARN, "invalid custom element number %d", element); + + element = EL_DEFAULT; /* dummy element used for artwork config */ + } + + for(j=0; jencoding_16bit_yamyam ? EL_EMPTY : - level->yam_content[i][x][y]), + level->yamyam_content[i][x][y]), file); fputc(level->amoeba_speed, file); fputc(level->time_magic_wall, file); @@ -623,6 +785,8 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) fputc((level->encoding_16bit_field ? 1 : 0), file); fputc((level->em_slippery_gems ? 1 : 0), file); + fputc((level->use_custom_template ? 1 : 0), file); + WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED); } @@ -652,7 +816,7 @@ static void SaveLevel_CONT(FILE *file, struct LevelInfo *level) int i, x, y; fputc(EL_YAMYAM, file); - fputc(level->num_yam_contents, file); + fputc(level->num_yamyam_contents, file); fputc(0, file); fputc(0, file); @@ -660,9 +824,9 @@ static void SaveLevel_CONT(FILE *file, struct LevelInfo *level) for(y=0; y<3; y++) for(x=0; x<3; x++) if (level->encoding_16bit_field) - putFile16BitBE(file, level->yam_content[i][x][y]); + putFile16BitBE(file, level->yamyam_content[i][x][y]); else - fputc(level->yam_content[i][x][y], file); + fputc(level->yamyam_content[i][x][y], file); } #endif @@ -674,14 +838,14 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) if (element == EL_YAMYAM) { - num_contents = level->num_yam_contents; + num_contents = level->num_yamyam_contents; content_xsize = 3; content_ysize = 3; for(i=0; iyam_content[i][x][y]; + content_array[i][x][y] = level->yamyam_content[i][x][y]; } else if (element == EL_BD_AMOEBA) { @@ -717,6 +881,7 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) putFile16BitBE(file, content_array[i][x][y]); } +#if 0 static void SaveLevel_CUS1(FILE *file, struct LevelInfo *level, int num_changed_custom_elements) { @@ -743,7 +908,9 @@ static void SaveLevel_CUS1(FILE *file, struct LevelInfo *level, if (check != num_changed_custom_elements) /* should not happen */ Error(ERR_WARN, "inconsistent number of custom element properties"); } +#endif +#if 0 static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level, int num_changed_custom_elements) { @@ -755,12 +922,12 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level, { int element = EL_CUSTOM_START + i; - if (level->custom_element_successor[i] != EL_EMPTY_SPACE) + if (element_info[element].change.target_element != EL_EMPTY_SPACE) { if (check < num_changed_custom_elements) { putFile16BitBE(file, element); - putFile16BitBE(file, level->custom_element_successor[i]); + putFile16BitBE(file, element_info[element].change.target_element); } check++; @@ -768,15 +935,96 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level, } if (check != num_changed_custom_elements) /* should not happen */ - Error(ERR_WARN, "inconsistent number of custom element successors"); + Error(ERR_WARN, "inconsistent number of custom target elements"); +} +#endif + +static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level, + int num_changed_custom_elements) +{ + int i, j, x, y, check = 0; + + putFile16BitBE(file, num_changed_custom_elements); + + for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + + if (Properties[element][EP_BITFIELD_BASE] != EP_BITMASK_DEFAULT) + { + if (check < num_changed_custom_elements) + { + putFile16BitBE(file, element); + + for(j=0; j 255) + if (level.yamyam_content[i][x][y] > 255) level.encoding_16bit_yamyam = TRUE; /* check amoeba content for 16-bit elements */ @@ -813,15 +1061,11 @@ void SaveLevel(int level_nr) body_chunk_size = level.fieldx * level.fieldy * (level.encoding_16bit_field ? 2 : 1); - /* check for non-standard custom elements and calculate "CUS1" chunk size */ + /* check for non-standard custom elements and calculate "CUS3" chunk size */ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) if (Properties[EL_CUSTOM_START +i][EP_BITFIELD_BASE] != EP_BITMASK_DEFAULT) - num_changed_custom_elements1++; - - /* check for non-standard custom elements and calculate "CUS2" chunk size */ - for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) - if (level.custom_element_successor[i] != EL_EMPTY_SPACE) - num_changed_custom_elements2++; + num_changed_custom_elements++; + level_chunk_CUS3_size = LEVEL_CHUNK_CUS3_SIZE(num_changed_custom_elements); putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); putFileChunkBE(file, "CAVE", CHUNK_SIZE_NONE); @@ -839,7 +1083,7 @@ void SaveLevel(int level_nr) SaveLevel_BODY(file, &level); if (level.encoding_16bit_yamyam || - level.num_yam_contents != STD_ELEMENT_CONTENTS) + level.num_yamyam_contents != STD_ELEMENT_CONTENTS) { putFileChunkBE(file, "CNT2", LEVEL_CHUNK_CNT2_SIZE); SaveLevel_CNT2(file, &level, EL_YAMYAM); @@ -851,16 +1095,10 @@ void SaveLevel(int level_nr) SaveLevel_CNT2(file, &level, EL_BD_AMOEBA); } - if (num_changed_custom_elements1 > 0) + if (num_changed_custom_elements > 0) { - putFileChunkBE(file, "CUS1", 2 + num_changed_custom_elements1 * 6); - SaveLevel_CUS1(file, &level, num_changed_custom_elements1); - } - - if (num_changed_custom_elements2 > 0) - { - putFileChunkBE(file, "CUS2", 2 + num_changed_custom_elements2 * 4); - SaveLevel_CUS2(file, &level, num_changed_custom_elements2); + putFileChunkBE(file, "CUS3", level_chunk_CUS3_size); + SaveLevel_CUS3(file, &level, num_changed_custom_elements); } fclose(file); @@ -871,7 +1109,7 @@ void SaveLevel(int level_nr) void DumpLevel(struct LevelInfo *level) { printf_line("-", 79); - printf("Level xxx (file version %06d, game version %06d)\n", + printf("Level xxx (file version %08d, game version %08d)\n", level->file_version, level->game_version); printf_line("-", 79); @@ -1191,6 +1429,10 @@ void LoadTapeFromFilename(char *filename) fclose(file); tape.length_seconds = GetTapeLength(); + +#if 0 + printf("tape version: %d\n", tape.game_version); +#endif } void LoadTape(int level_nr) @@ -1328,7 +1570,7 @@ void DumpTape(struct TapeInfo *tape) } printf_line("-", 79); - printf("Tape of Level %03d (file version %06d, game version %06d)\n", + printf("Tape of Level %03d (file version %08d, game version %08d)\n", tape->level_nr, tape->file_version, tape->game_version); printf("Level series identifier: '%s'\n", tape->level_identifier); printf_line("-", 79); @@ -1700,32 +1942,32 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->options.verbose = FALSE; } -static void decodeSetupFileList(struct SetupFileList *setup_file_list) +static void decodeSetupFileHash(SetupFileHash *setup_file_hash) { int i, pnr; - if (!setup_file_list) + if (!setup_file_hash) return; /* global setup */ si = setup; for (i=0; i