X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=4647c4ef3ca5ccfbfcac6d3014c1b651a77d324f;hb=3bf51f147946d7080ed973f7d1fca2971e5009d2;hp=33896235093ac3f83497ccd91c4685b0f8ac04a5;hpb=78d098e62a32cf968776c927d0f62e5b06e242fa;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 33896235..4647c4ef 100644 --- a/src/files.c +++ b/src/files.c @@ -40,52 +40,52 @@ #define TAPE_HEADER_SIZE 20 /* size of tape file header */ #define TAPE_HEADER_UNUSED 3 /* unused tape header bytes */ -#define LEVEL_CHUNK_CNT3_SIZE(x) (LEVEL_CHUNK_CNT3_HEADER + (x)) -#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE) -#define LEVEL_CHUNK_CUS4_SIZE(x) (96 + (x) * 48) +#define LEVEL_CHUNK_CNT3_SIZE(x) (LEVEL_CHUNK_CNT3_HEADER + (x)) +#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE) +#define LEVEL_CHUNK_CUS4_SIZE(x) (96 + (x) * 48) /* file identifier strings */ -#define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x" -#define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x" -#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2" +#define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x" +#define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x" +#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2" /* values for "CONF" chunk */ -#define CONF_MASK_1_BYTE 0x00 -#define CONF_MASK_2_BYTE 0x40 -#define CONF_MASK_4_BYTE 0x80 -#define CONF_MASK_MULTI_BYTES 0xc0 +#define CONF_MASK_1_BYTE 0x00 +#define CONF_MASK_2_BYTE 0x40 +#define CONF_MASK_4_BYTE 0x80 +#define CONF_MASK_MULTI_BYTES 0xc0 -#define CONF_MASK_BYTES 0xc0 -#define CONF_MASK_TOKEN 0x3f +#define CONF_MASK_BYTES 0xc0 +#define CONF_MASK_TOKEN 0x3f -#define CONF_LAST_ENTRY (CONF_MASK_1_BYTE | 0) +#define CONF_LAST_ENTRY (CONF_MASK_1_BYTE | 0) -#define CONF_VALUE_INTEGER_1 (CONF_MASK_1_BYTE | 1) -#define CONF_VALUE_INTEGER_2 (CONF_MASK_1_BYTE | 2) -#define CONF_VALUE_INTEGER_3 (CONF_MASK_1_BYTE | 3) -#define CONF_VALUE_INTEGER_4 (CONF_MASK_1_BYTE | 4) -#define CONF_VALUE_BOOLEAN_1 (CONF_MASK_1_BYTE | 5) -#define CONF_VALUE_BOOLEAN_2 (CONF_MASK_1_BYTE | 6) -#define CONF_VALUE_BOOLEAN_3 (CONF_MASK_1_BYTE | 7) -#define CONF_VALUE_BOOLEAN_4 (CONF_MASK_1_BYTE | 8) +#define CONF_VALUE_INTEGER_1 (CONF_MASK_1_BYTE | 1) +#define CONF_VALUE_INTEGER_2 (CONF_MASK_1_BYTE | 2) +#define CONF_VALUE_INTEGER_3 (CONF_MASK_1_BYTE | 3) +#define CONF_VALUE_INTEGER_4 (CONF_MASK_1_BYTE | 4) +#define CONF_VALUE_BOOLEAN_1 (CONF_MASK_1_BYTE | 5) +#define CONF_VALUE_BOOLEAN_2 (CONF_MASK_1_BYTE | 6) +#define CONF_VALUE_BOOLEAN_3 (CONF_MASK_1_BYTE | 7) +#define CONF_VALUE_BOOLEAN_4 (CONF_MASK_1_BYTE | 8) -#define CONF_VALUE_ELEMENT_1 (CONF_MASK_2_BYTE | 1) -#define CONF_VALUE_ELEMENT_2 (CONF_MASK_2_BYTE | 2) -#define CONF_VALUE_ELEMENT_3 (CONF_MASK_2_BYTE | 3) -#define CONF_VALUE_ELEMENT_4 (CONF_MASK_2_BYTE | 4) +#define CONF_VALUE_ELEMENT_1 (CONF_MASK_2_BYTE | 1) +#define CONF_VALUE_ELEMENT_2 (CONF_MASK_2_BYTE | 2) +#define CONF_VALUE_ELEMENT_3 (CONF_MASK_2_BYTE | 3) +#define CONF_VALUE_ELEMENT_4 (CONF_MASK_2_BYTE | 4) -#define CONF_VALUE_CONTENT_1 (CONF_MASK_MULTI_BYTES | 1) -#define CONF_VALUE_CONTENT_8 (CONF_MASK_MULTI_BYTES | 2) +#define CONF_VALUE_CONTENT_1 (CONF_MASK_MULTI_BYTES | 1) +#define CONF_VALUE_CONTENT_8 (CONF_MASK_MULTI_BYTES | 2) -#define CONF_VALUE_INTEGER(x) ((x) >= CONF_VALUE_INTEGER_1 && \ - (x) <= CONF_VALUE_INTEGER_4) +#define CONF_VALUE_INTEGER(x) ((x) >= CONF_VALUE_INTEGER_1 && \ + (x) <= CONF_VALUE_INTEGER_4) -#define CONF_VALUE_BOOLEAN(x) ((x) >= CONF_VALUE_BOOLEAN_1 && \ - (x) <= CONF_VALUE_BOOLEAN_4) +#define CONF_VALUE_BOOLEAN(x) ((x) >= CONF_VALUE_BOOLEAN_1 && \ + (x) <= CONF_VALUE_BOOLEAN_4) -#define CONF_VALUE_NUM_BYTES(x) ((x) == CONF_MASK_1_BYTE ? 1 : \ - (x) == CONF_MASK_2_BYTE ? 2 : \ - (x) == CONF_MASK_4_BYTE ? 4 : 0) +#define CONF_VALUE_NUM_BYTES(x) ((x) == CONF_MASK_1_BYTE ? 1 : \ + (x) == CONF_MASK_2_BYTE ? 2 : \ + (x) == CONF_MASK_4_BYTE ? 4 : 0) #define CONF_CONTENT_NUM_ELEMENTS (3 * 3) #define CONF_CONTENT_NUM_BYTES (CONF_CONTENT_NUM_ELEMENTS * 2) @@ -115,10 +115,6 @@ static struct EL_EMC_ANDROID, CONF_VALUE_INTEGER_2, &li.android_clone_time, 10 }, - { - EL_EMC_MAGIC_BALL, CONF_VALUE_INTEGER_1, - &li.ball_time, 10 - }, { EL_EMC_LENSES, CONF_VALUE_INTEGER_1, &li.lenses_score, 10 @@ -195,6 +191,10 @@ static struct EL_EXTRA_TIME, CONF_VALUE_INTEGER_1, &li.extra_time, 10 }, + { + EL_EXTRA_TIME, CONF_VALUE_INTEGER_2, + &li.extra_time_score, 10 + }, { EL_TIME_ORB_FULL, CONF_VALUE_INTEGER_1, &li.time_orb_time, 10 @@ -207,6 +207,56 @@ static struct EL_PLAYER_1, CONF_VALUE_BOOLEAN_1, &li.block_snap_field, TRUE }, + { + EL_PLAYER_1, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[0], FALSE + }, + { + EL_PLAYER_2, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[1], FALSE + }, + { + EL_PLAYER_3, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[2], FALSE + }, + { + EL_PLAYER_4, CONF_VALUE_BOOLEAN_2, + &li.use_start_element[3], FALSE + }, + { + EL_EMC_MAGIC_BALL, CONF_VALUE_INTEGER_1, + &li.ball_time, 10 + }, + { + EL_EMC_MAGIC_BALL, CONF_VALUE_INTEGER_2, + &li.num_ball_contents, 8 + }, + { + EL_EMC_MAGIC_BALL, CONF_VALUE_BOOLEAN_1, + &li.ball_random, FALSE + }, + { + EL_EMC_MAGIC_BALL, CONF_VALUE_BOOLEAN_2, + &li.ball_state_initial, FALSE + }, + + /* ---------- 2-byte values ---------------------------------------------- */ + { + EL_PLAYER_1, CONF_VALUE_ELEMENT_1, + &li.start_element[0], EL_PLAYER_1 + }, + { + EL_PLAYER_2, CONF_VALUE_ELEMENT_1, + &li.start_element[1], EL_PLAYER_2 + }, + { + EL_PLAYER_3, CONF_VALUE_ELEMENT_1, + &li.start_element[2], EL_PLAYER_3 + }, + { + EL_PLAYER_4, CONF_VALUE_ELEMENT_1, + &li.start_element[3], EL_PLAYER_4 + }, /* ---------- multi-byte values ------------------------------------------ */ { @@ -308,7 +358,7 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change) change->delay_fixed = 0; change->delay_random = 0; - change->delay_frames = 1; + change->delay_frames = FRAMES_PER_SECOND; change->trigger_element = EL_EMPTY_SPACE; @@ -341,6 +391,10 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) static boolean clipboard_elements_initialized = FALSE; int i, j, x, y; +#if 1 + InitElementPropertiesStatic(); +#endif + setLevelInfoToDefaultsFromConfigList(level); setLevelInfoToDefaults_EM(); @@ -417,10 +471,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) level->magnify_time = 10; level->slurp_score = 10; level->wind_direction_initial = MV_NONE; -#endif level->ball_random = FALSE; level->ball_state_initial = FALSE; -#if 0 for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (x = 0; x < 3; x++) for (y = 0; y < 3; y++) @@ -447,7 +499,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) } for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++) - level->score[i] = 10; + level->score[i] = (i == SC_TIME_BONUS ? 1 : 10); level->num_yamyam_contents = STD_ELEMENT_CONTENTS; for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) @@ -539,9 +591,13 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) ei->current_change_page = 0; +#if 0 + /* !!! now done in InitElementPropertiesStatic() (see above) !!! */ + /* !!! (else properties set there will be overwritten here) !!! */ /* start with no properties at all */ for (j = 0; j < NUM_EP_BITFIELDS; j++) Properties[element][j] = EP_BITMASK_DEFAULT; +#endif /* now set default properties */ SET_PROPERTY(element, EP_CAN_MOVE_INTO_ACID, TRUE); @@ -1418,8 +1474,9 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) /* always start with reliable default values */ setElementChangeInfoToDefaults(change); + /* bits 0 - 31 of "has_event[]" ... */ event_bits = getFile32BitBE(file); - for (j = 0; j < NUM_CHANGE_EVENTS; j++) + for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++) if (event_bits & (1 << j)) change->has_event[j] = TRUE; @@ -1458,8 +1515,11 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) change->action_mode = getFile8Bit(file); change->action_arg = getFile16BitBE(file); - /* some free bytes for future change property values and padding */ - ReadUnusedBytesFromFile(file, 1); + /* ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible) */ + event_bits = getFile8Bit(file); + for (j = 32; j < NUM_CHANGE_EVENTS; j++) + if (event_bits & (1 << (j - 32))) + change->has_event[j] = TRUE; } /* mark this custom element as modified */ @@ -2217,6 +2277,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) lev->ball_random = level->ball_random; lev->ball_state_initial = level->ball_state_initial; lev->ball_time = level->ball_time; + lev->num_ball_arrays = level->num_ball_contents; lev->lenses_score = level->lenses_score; lev->magnify_score = level->magnify_score; @@ -2224,7 +2285,11 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) lev->lenses_time = level->lenses_time; lev->magnify_time = level->magnify_time; - lev->wind_direction_initial = level->wind_direction_initial; + + lev->wind_direction_initial = + map_direction_RND_to_EM(level->wind_direction_initial); + lev->wind_cnt_initial = (level->wind_direction_initial != MV_NONE ? + lev->wind_time : 0); for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (j = 0; j < 8; j++) @@ -2260,6 +2325,16 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) /* initialize player positions and delete players from the playfield */ for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++) { +#if 1 + /* !!! CURRENTLY ONLY SUPPORT FOR ONE PLAYER !!! */ + if (ELEM_IS_PLAYER(level->field[x][y])) + { + ply1->x_initial = x + 1; + ply1->y_initial = y + 1; + level_em->cave[x + 1][y + 1] = map_element_RND_to_EM(EL_EMPTY); + } +#else + /* !!! ADD SUPPORT FOR MORE THAN ONE PLAYER !!! */ if (level->field[x][y] == EL_PLAYER_1) { ply1->x_initial = x + 1; @@ -2272,6 +2347,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) ply2->y_initial = y + 1; level_em->cave[x + 1][y + 1] = map_element_RND_to_EM(EL_EMPTY); } +#endif } } @@ -2330,6 +2406,7 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) level->ball_random = lev->ball_random; level->ball_state_initial = lev->ball_state_initial; level->ball_time = lev->ball_time; + level->num_ball_contents = lev->num_ball_arrays; level->lenses_score = lev->lenses_score; level->magnify_score = lev->magnify_score; @@ -2337,7 +2414,9 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) level->lenses_time = lev->lenses_time; level->magnify_time = lev->magnify_time; - level->wind_direction_initial = lev->wind_direction_initial; + + level->wind_direction_initial = + map_direction_EM_to_RND(lev->wind_direction_initial); for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (j = 0; j < 8; j++) @@ -2840,14 +2919,21 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename) if (level->game_version < VERSION_IDENT(2,2,0,0)) level->use_spring_bug = TRUE; - /* time orb caused limited time in endless time levels before 3.1.2 */ - if (level->game_version < VERSION_IDENT(3,1,2,0)) + if (level->game_version < VERSION_IDENT(3,2,0,5)) + { + /* time orb caused limited time in endless time levels before 3.2.0-5 */ level->use_time_orb_bug = TRUE; - /* default behaviour for snapping was "no snap delay" before 3.1.2 */ - if (level->game_version < VERSION_IDENT(3,1,2,0)) + /* default behaviour for snapping was "no snap delay" before 3.2.0-5 */ level->block_snap_field = FALSE; + /* extra time score was same value as time left score before 3.2.0-5 */ + level->extra_time_score = level->score[SC_TIME_BONUS]; + + /* time bonus score was given for 10 s instead of 1 s before 3.2.0-5 */ + level->score[SC_TIME_BONUS] /= 10; + } + /* only few elements were able to actively move into acid before 3.1.0 */ /* trigger settings did not exist before 3.1.0; set to default "any" */ if (level->game_version < VERSION_IDENT(3,1,0,0)) @@ -3451,12 +3537,13 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) for (i = 0; i < ei->num_change_pages; i++) { struct ElementChangeInfo *change = &ei->change_page[i]; - unsigned long event_bits = 0; + unsigned long event_bits; - for (j = 0; j < NUM_CHANGE_EVENTS; j++) + /* bits 0 - 31 of "has_event[]" ... */ + event_bits = 0; + for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++) if (change->has_event[j]) event_bits |= (1 << j); - putFile32BitBE(file, event_bits); putFile16BitBE(file, change->target_element); @@ -3492,8 +3579,12 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) putFile8Bit(file, change->action_mode); putFile16BitBE(file, change->action_arg); - /* some free bytes for future change property values and padding */ - WriteUnusedBytesToFile(file, 1); + /* ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible) */ + event_bits = 0; + for (j = 32; j < NUM_CHANGE_EVENTS; j++) + if (change->has_event[j]) + event_bits |= (1 << (j - 32)); + putFile8Bit(file, event_bits); } } @@ -4407,12 +4498,30 @@ void SaveScore(int nr) #define SETUP_TOKEN_EDITOR_EL_DX_BOULDERDASH 7 #define SETUP_TOKEN_EDITOR_EL_CHARS 8 #define SETUP_TOKEN_EDITOR_EL_CUSTOM 9 -#define SETUP_TOKEN_EDITOR_EL_CUSTOM_MORE 10 -#define SETUP_TOKEN_EDITOR_EL_HEADLINES 11 -#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED 12 +#define SETUP_TOKEN_EDITOR_EL_HEADLINES 10 +#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED 11 +#define SETUP_TOKEN_EDITOR_EL_DYNAMIC 12 #define NUM_EDITOR_SETUP_TOKENS 13 +/* editor cascade setup */ +#define SETUP_TOKEN_EDITOR_CASCADE_BD 0 +#define SETUP_TOKEN_EDITOR_CASCADE_EM 1 +#define SETUP_TOKEN_EDITOR_CASCADE_EMC 2 +#define SETUP_TOKEN_EDITOR_CASCADE_RND 3 +#define SETUP_TOKEN_EDITOR_CASCADE_SB 4 +#define SETUP_TOKEN_EDITOR_CASCADE_SP 5 +#define SETUP_TOKEN_EDITOR_CASCADE_DC 6 +#define SETUP_TOKEN_EDITOR_CASCADE_DX 7 +#define SETUP_TOKEN_EDITOR_CASCADE_TEXT 8 +#define SETUP_TOKEN_EDITOR_CASCADE_CE 9 +#define SETUP_TOKEN_EDITOR_CASCADE_GE 10 +#define SETUP_TOKEN_EDITOR_CASCADE_USER 11 +#define SETUP_TOKEN_EDITOR_CASCADE_GENERIC 12 +#define SETUP_TOKEN_EDITOR_CASCADE_DYNAMIC 13 + +#define NUM_EDITOR_CASCADE_SETUP_TOKENS 14 + /* shortcut setup */ #define SETUP_TOKEN_SHORTCUT_SAVE_GAME 0 #define SETUP_TOKEN_SHORTCUT_LOAD_GAME 1 @@ -4454,6 +4563,7 @@ void SaveScore(int nr) static struct SetupInfo si; static struct SetupEditorInfo sei; +static struct SetupEditorCascadeInfo seci; static struct SetupShortcutInfo ssi; static struct SetupInputInfo sii; static struct SetupSystemInfo syi; @@ -4498,9 +4608,27 @@ static struct TokenInfo editor_setup_tokens[] = { TYPE_SWITCH, &sei.el_dx_boulderdash,"editor.el_dx_boulderdash" }, { TYPE_SWITCH, &sei.el_chars, "editor.el_chars" }, { TYPE_SWITCH, &sei.el_custom, "editor.el_custom" }, - { TYPE_SWITCH, &sei.el_custom_more, "editor.el_custom_more" }, { TYPE_SWITCH, &sei.el_headlines, "editor.el_headlines" }, { TYPE_SWITCH, &sei.el_user_defined, "editor.el_user_defined" }, + { TYPE_SWITCH, &sei.el_dynamic, "editor.el_dynamic" }, +}; + +static struct TokenInfo editor_cascade_setup_tokens[] = +{ + { TYPE_SWITCH, &seci.el_bd, "editor.cascade.el_bd" }, + { TYPE_SWITCH, &seci.el_em, "editor.cascade.el_em" }, + { TYPE_SWITCH, &seci.el_emc, "editor.cascade.el_emc" }, + { TYPE_SWITCH, &seci.el_rnd, "editor.cascade.el_rnd" }, + { TYPE_SWITCH, &seci.el_sb, "editor.cascade.el_sb" }, + { TYPE_SWITCH, &seci.el_sp, "editor.cascade.el_sp" }, + { TYPE_SWITCH, &seci.el_dc, "editor.cascade.el_dc" }, + { TYPE_SWITCH, &seci.el_dx, "editor.cascade.el_dx" }, + { TYPE_SWITCH, &seci.el_chars, "editor.cascade.el_chars" }, + { TYPE_SWITCH, &seci.el_ce, "editor.cascade.el_ce" }, + { TYPE_SWITCH, &seci.el_ge, "editor.cascade.el_ge" }, + { TYPE_SWITCH, &seci.el_user, "editor.cascade.el_user" }, + { TYPE_SWITCH, &seci.el_generic, "editor.cascade.el_generic" }, + { TYPE_SWITCH, &seci.el_dynamic, "editor.cascade.el_dynamic" }, }; static struct TokenInfo shortcut_setup_tokens[] = @@ -4598,10 +4726,10 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->editor.el_dx_boulderdash = TRUE; si->editor.el_chars = TRUE; si->editor.el_custom = TRUE; - si->editor.el_custom_more = FALSE; si->editor.el_headlines = TRUE; si->editor.el_user_defined = FALSE; + si->editor.el_dynamic = TRUE; si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME; si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME; @@ -4633,6 +4761,25 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->options.verbose = FALSE; } +static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si) +{ + si->editor_cascade.el_bd = TRUE; + si->editor_cascade.el_em = TRUE; + si->editor_cascade.el_emc = TRUE; + si->editor_cascade.el_rnd = TRUE; + si->editor_cascade.el_sb = TRUE; + si->editor_cascade.el_sp = TRUE; + si->editor_cascade.el_dc = TRUE; + si->editor_cascade.el_dx = TRUE; + + si->editor_cascade.el_chars = FALSE; + si->editor_cascade.el_ce = FALSE; + si->editor_cascade.el_ge = FALSE; + si->editor_cascade.el_user = FALSE; + si->editor_cascade.el_generic = FALSE; + si->editor_cascade.el_dynamic = FALSE; +} + static void decodeSetupFileHash(SetupFileHash *setup_file_hash) { int i, pnr; @@ -4695,6 +4842,22 @@ static void decodeSetupFileHash(SetupFileHash *setup_file_hash) setup.options = soi; } +static void decodeSetupFileHash_EditorCascade(SetupFileHash *setup_file_hash) +{ + int i; + + if (!setup_file_hash) + return; + + /* editor cascade setup */ + seci = setup.editor_cascade; + for (i = 0; i < NUM_EDITOR_CASCADE_SETUP_TOKENS; i++) + setSetupInfo(editor_cascade_setup_tokens, i, + getHashEntry(setup_file_hash, + editor_cascade_setup_tokens[i].text)); + setup.editor_cascade = seci; +} + void LoadSetup() { char *filename = getSetupFilename(); @@ -4725,6 +4888,27 @@ void LoadSetup() Error(ERR_WARN, "using default setup values"); } +void LoadSetup_EditorCascade() +{ + char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME); + SetupFileHash *setup_file_hash = NULL; + + /* always start with reliable default values */ + setSetupInfoToDefaults_EditorCascade(&setup); + + setup_file_hash = loadSetupFileHash(filename); + + if (setup_file_hash) + { + checkSetupFileHashIdentifier(setup_file_hash, getCookie("SETUP")); + decodeSetupFileHash_EditorCascade(setup_file_hash); + + freeSetupFileHash(setup_file_hash); + } + + free(filename); +} + void SaveSetup() { char *filename = getSetupFilename(); @@ -4797,6 +4981,37 @@ void SaveSetup() SetFilePermissions(filename, PERMS_PRIVATE); } +void SaveSetup_EditorCascade() +{ + char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME); + FILE *file; + int i; + + InitUserDataDirectory(); + + if (!(file = fopen(filename, MODE_WRITE))) + { + Error(ERR_WARN, "cannot write editor cascade state file '%s'", filename); + free(filename); + return; + } + + fprintf(file, "%s\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER, + getCookie("SETUP"))); + fprintf(file, "\n"); + + seci = setup.editor_cascade; + fprintf(file, "\n"); + for (i = 0; i < NUM_EDITOR_SETUP_TOKENS; i++) + fprintf(file, "%s\n", getSetupLine(editor_cascade_setup_tokens, "", i)); + + fclose(file); + + SetFilePermissions(filename, PERMS_PRIVATE); + + free(filename); +} + void LoadCustomElementDescriptions() { char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS); @@ -4898,6 +5113,10 @@ void LoadUserDefinedEditorElementList(int **elements, int *num_elements) /* add space for up to 3 more elements for padding that may be needed */ *num_elements += 3; + /* free memory for old list of elements, if needed */ + checked_free(*elements); + + /* allocate memory for new list of elements */ *elements = checked_malloc(*num_elements * sizeof(int)); *num_elements = 0;