X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=436decce8759e073aefceeb3d69aaa1fad2d8bfc;hb=91afd13180ad610e2a6cbef32b85677cf8148864;hp=bcb579aee47d7676458a263a7035a6f970777afc;hpb=3140ab2a0de5599122e88579f48603146595e1c7;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index bcb579ae..436decce 100644 --- a/src/files.c +++ b/src/files.c @@ -90,10 +90,13 @@ static void setLevelInfoToDefaults() level.yam_content[i][x][y] = (i < STD_ELEMENT_CONTENTS ? EL_ROCK : EL_EMPTY); - Feld[0][0] = Ur[0][0] = EL_PLAYER1; + Feld[0][0] = Ur[0][0] = EL_PLAYER_1; Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_EXIT_CLOSED; + for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) + Properties1[EL_CUSTOM_START + i] = EP_BITMASK_DEFAULT; + BorderElement = EL_STEELWALL; level.no_level_file = FALSE; @@ -140,9 +143,9 @@ static int checkLevelElement(int element) element = EL_CHAR_QUESTION; } else if (element == EL_PLAYER_OBSOLETE) - element = EL_PLAYER1; + element = EL_PLAYER_1; else if (element == EL_KEY_OBSOLETE) - element = EL_KEY1; + element = EL_KEY_1; return element; } @@ -203,6 +206,33 @@ static int LoadLevel_AUTH(FILE *file, int chunk_size, struct LevelInfo *level) return chunk_size; } +static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level) +{ + int x, y; + int chunk_size_expected = level->fieldx * level->fieldy; + + /* Note: "chunk_size" was wrong before version 2.0 when elements are + stored with 16-bit encoding (and should be twice as big then). + Even worse, playfield data was stored 16-bit when only yamyam content + contained 16-bit elements and vice versa. */ + + if (level->encoding_16bit_field && level->file_version >= FILE_VERSION_2_0) + chunk_size_expected *= 2; + + if (chunk_size_expected != chunk_size) + { + ReadUnusedBytesFromFile(file, chunk_size); + return chunk_size_expected; + } + + for(y=0; yfieldy; y++) + for(x=0; xfieldx; x++) + Feld[x][y] = Ur[x][y] = + checkLevelElement(level->encoding_16bit_field ? + getFile16BitBE(file) : fgetc(file)); + return chunk_size; +} + static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level) { int i, x, y; @@ -243,33 +273,6 @@ static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level) return chunk_size; } -static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level) -{ - int x, y; - int chunk_size_expected = level->fieldx * level->fieldy; - - /* Note: "chunk_size" was wrong before version 2.0 when elements are - stored with 16-bit encoding (and should be twice as big then). - Even worse, playfield data was stored 16-bit when only yamyam content - contained 16-bit elements and vice versa. */ - - if (level->encoding_16bit_field && level->file_version >= FILE_VERSION_2_0) - chunk_size_expected *= 2; - - if (chunk_size_expected != chunk_size) - { - ReadUnusedBytesFromFile(file, chunk_size); - return chunk_size_expected; - } - - for(y=0; yfieldy; y++) - for(x=0; xfieldx; x++) - Feld[x][y] = Ur[x][y] = - checkLevelElement(level->encoding_16bit_field ? - getFile16BitBE(file) : fgetc(file)); - return chunk_size; -} - static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level) { int i, x, y; @@ -313,6 +316,32 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level) return chunk_size; } +static int LoadLevel_CUS1(FILE *file, int chunk_size, struct LevelInfo *level) +{ + int num_changed_custom_elements = getFile16BitBE(file); + int chunk_size_expected = 2 + num_changed_custom_elements * 6; + int i; + + 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); + int properties = getFile32BitBE(file); + + if (IS_CUSTOM_ELEMENT(element)) + Properties1[element] = properties; + else + Error(ERR_WARN, "invalid custom element number %d", element); + } + + return chunk_size; +} + void LoadLevelFromFilename(char *filename) { char cookie[MAX_LINE_LEN]; @@ -388,9 +417,10 @@ void LoadLevelFromFilename(char *filename) { "VERS", FILE_VERS_CHUNK_SIZE, LoadLevel_VERS }, { "HEAD", LEVEL_HEADER_SIZE, LoadLevel_HEAD }, { "AUTH", MAX_LEVEL_AUTHOR_LEN, LoadLevel_AUTH }, - { "CONT", -1, LoadLevel_CONT }, { "BODY", -1, LoadLevel_BODY }, + { "CONT", -1, LoadLevel_CONT }, { "CNT2", LEVEL_CHUNK_CNT2_SIZE, LoadLevel_CNT2 }, + { "CUS1", -1, LoadLevel_CUS1 }, { NULL, 0, NULL } }; @@ -545,6 +575,18 @@ static void SaveLevel_AUTH(FILE *file, struct LevelInfo *level) fputc(level->author[i], file); } +static void SaveLevel_BODY(FILE *file, struct LevelInfo *level) +{ + int x, y; + + for(y=0; yfieldy; y++) + for(x=0; xfieldx; x++) + if (level->encoding_16bit_field) + putFile16BitBE(file, Ur[x][y]); + else + fputc(Ur[x][y], file); +} + #if 0 static void SaveLevel_CONT(FILE *file, struct LevelInfo *level) { @@ -565,18 +607,6 @@ static void SaveLevel_CONT(FILE *file, struct LevelInfo *level) } #endif -static void SaveLevel_BODY(FILE *file, struct LevelInfo *level) -{ - int x, y; - - for(y=0; yfieldy; y++) - for(x=0; xfieldx; x++) - if (level->encoding_16bit_field) - putFile16BitBE(file, Ur[x][y]); - else - fputc(Ur[x][y], file); -} - static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) { int i, x, y; @@ -628,11 +658,38 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) putFile16BitBE(file, content_array[i][x][y]); } +static void SaveLevel_CUS1(FILE *file, int num_changed_custom_elements) +{ + int i, check = 0; + + putFile16BitBE(file, num_changed_custom_elements); + + for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + + if (Properties1[element] != EP_BITMASK_DEFAULT) + { + if (check < num_changed_custom_elements) + { + putFile16BitBE(file, element); + putFile32BitBE(file, Properties1[element]); + } + + check++; + } + } + + if (check != num_changed_custom_elements) /* should not happen */ + Error(ERR_WARN, "inconsistent number of custom element properties"); +} + void SaveLevel(int level_nr) { - int i, x, y; char *filename = getLevelFilename(level_nr); int body_chunk_size; + int num_changed_custom_elements = 0; + int i, x, y; FILE *file; if (!(file = fopen(filename, MODE_WRITE))) @@ -664,9 +721,15 @@ void SaveLevel(int level_nr) if (level.amoeba_content > 255) level.encoding_16bit_amoeba = TRUE; + /* calculate size of "BODY" chunk */ body_chunk_size = level.fieldx * level.fieldy * (level.encoding_16bit_field ? 2 : 1); + /* check for non-standard custom elements and calculate "CUS1" chunk size */ + for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) + if (Properties1[EL_CUSTOM_START + i] != EP_BITMASK_DEFAULT) + num_changed_custom_elements++; + putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); putFileChunkBE(file, "CAVE", CHUNK_SIZE_NONE); @@ -695,6 +758,12 @@ void SaveLevel(int level_nr) SaveLevel_CNT2(file, &level, EL_BD_AMOEBA); } + if (num_changed_custom_elements > 0) + { + putFileChunkBE(file, "CUS1", 2 + num_changed_custom_elements * 6); + SaveLevel_CUS1(file, num_changed_custom_elements); + } + fclose(file); SetFilePermissions(filename, PERMS_PRIVATE); @@ -803,6 +872,26 @@ static int LoadTape_HEAD(FILE *file, int chunk_size, struct TapeInfo *tape) return chunk_size; } +static int LoadTape_INFO(FILE *file, int chunk_size, struct TapeInfo *tape) +{ + int level_identifier_size; + int i; + + level_identifier_size = getFile16BitBE(file); + + tape->level_identifier = + checked_realloc(tape->level_identifier, level_identifier_size); + + for(i=0; i < level_identifier_size; i++) + tape->level_identifier[i] = fgetc(file); + + tape->level_nr = getFile16BitBE(file); + + chunk_size = 2 + level_identifier_size + 2; + + return chunk_size; +} + static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape) { int i, j; @@ -956,6 +1045,7 @@ void LoadTapeFromFilename(char *filename) { { "VERS", FILE_VERS_CHUNK_SIZE, LoadTape_VERS }, { "HEAD", TAPE_HEADER_SIZE, LoadTape_HEAD }, + { "INFO", -1, LoadTape_INFO }, { "BODY", -1, LoadTape_BODY }, { NULL, 0, NULL } }; @@ -1039,6 +1129,19 @@ static void SaveTape_HEAD(FILE *file, struct TapeInfo *tape) putFileVersion(file, tape->engine_version); } +static void SaveTape_INFO(FILE *file, struct TapeInfo *tape) +{ + int level_identifier_size = strlen(tape->level_identifier) + 1; + int i; + + putFile16BitBE(file, level_identifier_size); + + for(i=0; i < level_identifier_size; i++) + fputc(tape->level_identifier[i], file); + + putFile16BitBE(file, tape->level_nr); +} + static void SaveTape_BODY(FILE *file, struct TapeInfo *tape) { int i, j; @@ -1055,12 +1158,13 @@ static void SaveTape_BODY(FILE *file, struct TapeInfo *tape) void SaveTape(int level_nr) { - int i; char *filename = getTapeFilename(level_nr); FILE *file; boolean new_tape = TRUE; int num_participating_players = 0; + int info_chunk_size; int body_chunk_size; + int i; InitTapeDirectory(leveldir_current->filename); @@ -1086,6 +1190,7 @@ void SaveTape(int level_nr) if (tape.player_participates[i]) num_participating_players++; + info_chunk_size = 2 + (strlen(tape.level_identifier) + 1) + 2; body_chunk_size = (num_participating_players + 1) * tape.length; putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); @@ -1097,6 +1202,9 @@ void SaveTape(int level_nr) putFileChunkBE(file, "HEAD", TAPE_HEADER_SIZE); SaveTape_HEAD(file, &tape); + putFileChunkBE(file, "INFO", info_chunk_size); + SaveTape_INFO(file, &tape); + putFileChunkBE(file, "BODY", body_chunk_size); SaveTape_BODY(file, &tape); @@ -1123,6 +1231,7 @@ void DumpTape(struct TapeInfo *tape) printf_line("-", 79); printf("Tape of Level %03d (file version %06d, game version %06d)\n", tape->level_nr, tape->file_version, tape->game_version); + printf("Level series identifier: '%s'\n", tape->level_identifier); printf_line("-", 79); for(i=0; ilength; i++) @@ -1310,14 +1419,27 @@ void SaveScore(int level_nr) #define NUM_PLAYER_SETUP_TOKENS 16 +/* system setup */ +#define SETUP_TOKEN_SYSTEM_SDL_AUDIODRIVER 0 +#define SETUP_TOKEN_SYSTEM_AUDIO_FRAGMENT_SIZE 1 + +#define NUM_SYSTEM_SETUP_TOKENS 2 + +/* options setup */ +#define SETUP_TOKEN_OPTIONS_VERBOSE 0 + +#define NUM_OPTIONS_SETUP_TOKENS 1 + + static struct SetupInfo si; static struct SetupEditorInfo sei; static struct SetupShortcutInfo ssi; static struct SetupInputInfo sii; +static struct SetupSystemInfo syi; +static struct OptionInfo soi; static struct TokenInfo global_setup_tokens[] = { - /* global setup */ { TYPE_STRING, &si.player_name, "player_name" }, { TYPE_SWITCH, &si.sound, "sound" }, { TYPE_SWITCH, &si.sound_loops, "repeating_sound_loops" }, @@ -1344,7 +1466,6 @@ static struct TokenInfo global_setup_tokens[] = static struct TokenInfo editor_setup_tokens[] = { - /* shortcut setup */ { TYPE_SWITCH, &sei.el_boulderdash, "editor.el_boulderdash" }, { TYPE_SWITCH, &sei.el_emerald_mine, "editor.el_emerald_mine" }, { TYPE_SWITCH, &sei.el_more, "editor.el_more" }, @@ -1358,7 +1479,6 @@ static struct TokenInfo editor_setup_tokens[] = static struct TokenInfo shortcut_setup_tokens[] = { - /* shortcut setup */ { TYPE_KEY_X11, &ssi.save_game, "shortcut.save_game" }, { TYPE_KEY_X11, &ssi.load_game, "shortcut.load_game" }, { TYPE_KEY_X11, &ssi.toggle_pause, "shortcut.toggle_pause" } @@ -1366,7 +1486,6 @@ static struct TokenInfo shortcut_setup_tokens[] = static struct TokenInfo player_setup_tokens[] = { - /* player setup */ { TYPE_BOOLEAN, &sii.use_joystick, ".use_joystick" }, { TYPE_STRING, &sii.joy.device_name, ".joy.device_name" }, { TYPE_INTEGER, &sii.joy.xleft, ".joy.xleft" }, @@ -1385,6 +1504,17 @@ static struct TokenInfo player_setup_tokens[] = { TYPE_KEY_X11, &sii.key.bomb, ".key.place_bomb" } }; +static struct TokenInfo system_setup_tokens[] = +{ + { TYPE_STRING, &syi.sdl_audiodriver, "system.sdl_audiodriver" }, + { TYPE_INTEGER, &syi.audio_fragment_size,"system.audio_fragment_size" } +}; + +static struct TokenInfo options_setup_tokens[] = +{ + { TYPE_BOOLEAN, &soi.verbose, "options.verbose" } +}; + static void setSetupInfoToDefaults(struct SetupInfo *si) { int i; @@ -1424,7 +1554,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->editor.el_diamond_caves = TRUE; si->editor.el_dx_boulderdash = TRUE; si->editor.el_chars = TRUE; - si->editor.el_custom = FALSE; + si->editor.el_custom = TRUE; si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME; si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME; @@ -1449,6 +1579,11 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KSYM_UNDEFINED); si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KSYM_UNDEFINED); } + + si->system.sdl_audiodriver = getStringCopy(ARG_DEFAULT); + si->system.audio_fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE; + + si->options.verbose = FALSE; } static void decodeSetupFileList(struct SetupFileList *setup_file_list) @@ -1497,6 +1632,20 @@ static void decodeSetupFileList(struct SetupFileList *setup_file_list) } setup.input[pnr] = sii; } + + /* system setup */ + syi = setup.system; + for (i=0; i