- /* order of checking and copying events to be mapped is important */
- /* (do not change the start and end value -- they are constant) */
- for (j = CE_BY_OTHER_ACTION; j >= CE_VALUE_GETS_ZERO; j--)
- {
- if (HAS_CHANGE_EVENT(element, j - 2))
- {
- SET_CHANGE_EVENT(element, j - 2, FALSE);
- SET_CHANGE_EVENT(element, j, TRUE);
- }
- }
-
- /* order of checking and copying events to be mapped is important */
- /* (do not change the start and end value -- they are constant) */
- for (j = CE_PLAYER_COLLECTS_X; j >= CE_HITTING_SOMETHING; j--)
- {
- if (HAS_CHANGE_EVENT(element, j - 1))
- {
- SET_CHANGE_EVENT(element, j - 1, FALSE);
- SET_CHANGE_EVENT(element, j, TRUE);
- }
- }
- }
- }
-
- /* initialize "can_change" field for old levels with only one change page */
- if (level->game_version <= VERSION_IDENT(3,0,2,0))
- {
- for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- int element = EL_CUSTOM_START + i;
-
- if (CAN_CHANGE(element))
- element_info[element].change->can_change = TRUE;
- }
- }
-
- /* correct custom element values (for old levels without these options) */
- if (level->game_version < VERSION_IDENT(3,1,1,0))
- {
- for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- int element = EL_CUSTOM_START + i;
- struct ElementInfo *ei = &element_info[element];
-
- if (ei->access_direction == MV_NO_DIRECTION)
- ei->access_direction = MV_ALL_DIRECTIONS;
- }
- }
-
- /* correct custom element values (fix invalid values for all versions) */
- if (1)
- {
- for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- int element = EL_CUSTOM_START + i;
- struct ElementInfo *ei = &element_info[element];
-
- for (j = 0; j < ei->num_change_pages; j++)
- {
- struct ElementChangeInfo *change = &ei->change_page[j];
-
- if (change->trigger_player == CH_PLAYER_NONE)
- change->trigger_player = CH_PLAYER_ANY;
-
- if (change->trigger_side == CH_SIDE_NONE)
- change->trigger_side = CH_SIDE_ANY;
- }
- }
- }
-
- /* 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++)
- {
- int element = EL_CUSTOM_START + i;
-
- if (EXPLODES_1X1_OLD(element))
- element_info[element].explosion_type = EXPLODES_1X1;
-
- SET_PROPERTY(element, EP_CAN_EXPLODE, (EXPLODES_BY_FIRE(element) ||
- EXPLODES_SMASHED(element) ||
- EXPLODES_IMPACT(element)));
- }
- }
-
- /* 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;
- }
- }
- }
-
- /* 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].e[x][y] =
- getMappedElementByVersion(level->yamyam_content[i].e[x][y],
- level->game_version);
-
- /* initialize element properties for level editor etc. */
- InitElementPropertiesEngine(level->game_version);
- InitElementPropertiesAfterLoading(level->game_version);
- InitElementPropertiesGfxElement();
-}
-
-static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename)
-{
- int x, y;
-
- /* map elements that have changed in newer versions */
- for (y = 0; y < level->fieldy; y++)
- for (x = 0; x < level->fieldx; x++)
- level->field[x][y] = getMappedElementByVersion(level->field[x][y],
- level->game_version);
-
- /* copy elements to runtime playfield array */
- for (x = 0; x < MAX_LEV_FIELDX; x++)
- for (y = 0; y < MAX_LEV_FIELDY; y++)
- Feld[x][y] = level->field[x][y];
-
- /* initialize level size variables for faster access */
- lev_fieldx = level->fieldx;
- lev_fieldy = level->fieldy;
-
- /* determine border element for this level */
- if (level->file_info.type == LEVEL_FILE_TYPE_DC)
- BorderElement = EL_EMPTY; /* (in editor, SetBorderElement() is used) */
- else
- SetBorderElement();
-}
-
-static void LoadLevel_InitNativeEngines(struct LevelInfo *level,char *filename)
-{
- struct LevelFileInfo *level_file_info = &level->file_info;
-
- if (level_file_info->type == LEVEL_FILE_TYPE_RND)
- CopyNativeLevel_RND_to_Native(level);
-}
-
-void LoadLevelTemplate(int nr)
-{
- char *filename;
-
- setLevelFileInfo(&level_template.file_info, nr);
- filename = level_template.file_info.filename;
-
- LoadLevelFromFileInfo(&level_template, &level_template.file_info, FALSE);
-
- LoadLevel_InitVersion(&level_template, filename);
- LoadLevel_InitElements(&level_template, filename);
-
- ActivateLevelTemplate();
-}
-
-void LoadLevel(int nr)
-{
- char *filename;
-
- setLevelFileInfo(&level.file_info, nr);
- filename = level.file_info.filename;
-
- LoadLevelFromFileInfo(&level, &level.file_info, FALSE);
-
- if (level.use_custom_template)
- LoadLevelTemplate(-1);
-
- LoadLevel_InitVersion(&level, filename);
- LoadLevel_InitElements(&level, filename);
- LoadLevel_InitPlayfield(&level, filename);
-
- LoadLevel_InitNativeEngines(&level, filename);
-}
-
-void LoadLevelInfoOnly(int nr)
-{
-#if 0
- char *filename;
-#endif
-
- setLevelFileInfo(&level.file_info, nr);
-#if 0
- filename = level.file_info.filename;
-#endif
-
- LoadLevelFromFileInfo(&level, &level.file_info, TRUE);
-}
-
-static int SaveLevel_VERS(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
-
- chunk_size += putFileVersion(file, level->file_version);
- chunk_size += putFileVersion(file, level->game_version);
-
- return chunk_size;
-}
-
-static int SaveLevel_DATE(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
-
- chunk_size += putFile16BitBE(file, level->creation_date.year);
- chunk_size += putFile8Bit(file, level->creation_date.month);
- chunk_size += putFile8Bit(file, level->creation_date.day);
-
- return chunk_size;
-}
-
-#if 0
-static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level)
-{
- int i, x, y;
-
- putFile8Bit(file, level->fieldx);
- putFile8Bit(file, level->fieldy);
-
- putFile16BitBE(file, level->time);
- putFile16BitBE(file, level->gems_needed);
-
- for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
- putFile8Bit(file, level->name[i]);
-
- for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
- putFile8Bit(file, level->score[i]);
-
- for (i = 0; i < STD_ELEMENT_CONTENTS; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- putFile8Bit(file, (level->encoding_16bit_yamyam ? EL_EMPTY :
- level->yamyam_content[i].e[x][y]));
- putFile8Bit(file, level->amoeba_speed);
- putFile8Bit(file, level->time_magic_wall);
- putFile8Bit(file, level->time_wheel);
- putFile8Bit(file, (level->encoding_16bit_amoeba ? EL_EMPTY :
- level->amoeba_content));
- putFile8Bit(file, (level->initial_player_stepsize == STEPSIZE_FAST ? 1 : 0));
- putFile8Bit(file, (level->initial_gravity ? 1 : 0));
- putFile8Bit(file, (level->encoding_16bit_field ? 1 : 0));
- putFile8Bit(file, (level->em_slippery_gems ? 1 : 0));
-
- putFile8Bit(file, (level->use_custom_template ? 1 : 0));
-
- putFile8Bit(file, (level->block_last_field ? 1 : 0));
- putFile8Bit(file, (level->sp_block_last_field ? 1 : 0));
- putFile32BitBE(file, level->can_move_into_acid_bits);
- putFile8Bit(file, level->dont_collide_with_bits);
-
- putFile8Bit(file, (level->use_spring_bug ? 1 : 0));
- putFile8Bit(file, (level->use_step_counter ? 1 : 0));
-
- putFile8Bit(file, (level->instant_relocation ? 1 : 0));
- 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_CHUNK_HEAD_UNUSED);
-}
-#endif
-
-static int SaveLevel_NAME(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
- int i;
-
- for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
- chunk_size += putFile8Bit(file, level->name[i]);
-
- return chunk_size;
-}
-
-static int SaveLevel_AUTH(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
- int i;
-
- for (i = 0; i < MAX_LEVEL_AUTHOR_LEN; i++)
- chunk_size += putFile8Bit(file, level->author[i]);
-
- return chunk_size;
-}
-
-#if 0
-static int SaveLevel_BODY(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
- int x, y;
-
- for (y = 0; y < level->fieldy; y++)
- for (x = 0; x < level->fieldx; x++)
- if (level->encoding_16bit_field)
- chunk_size += putFile16BitBE(file, level->field[x][y]);
- else
- chunk_size += putFile8Bit(file, level->field[x][y]);
-
- return chunk_size;
-}
-#endif
-
-static int SaveLevel_BODY(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
- int x, y;
-
- for (y = 0; y < level->fieldy; y++)
- for (x = 0; x < level->fieldx; x++)
- chunk_size += putFile16BitBE(file, level->field[x][y]);
-
- return chunk_size;
-}
-
-#if 0
-static void SaveLevel_CONT(FILE *file, struct LevelInfo *level)
-{
- int i, x, y;
-
- putFile8Bit(file, EL_YAMYAM);
- putFile8Bit(file, level->num_yamyam_contents);
- putFile8Bit(file, 0);
- putFile8Bit(file, 0);
-
- for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- if (level->encoding_16bit_field)
- putFile16BitBE(file, level->yamyam_content[i].e[x][y]);
- else
- putFile8Bit(file, level->yamyam_content[i].e[x][y]);
-}
-#endif
-
-#if 0
-static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
-{
- int i, x, y;
- int num_contents, content_xsize, content_ysize;
- int content_array[MAX_ELEMENT_CONTENTS][3][3];
-
- if (element == EL_YAMYAM)
- {
- num_contents = level->num_yamyam_contents;
- content_xsize = 3;
- content_ysize = 3;
-
- for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- content_array[i][x][y] = level->yamyam_content[i].e[x][y];
- }
- else if (element == EL_BD_AMOEBA)
- {
- num_contents = 1;
- content_xsize = 1;
- content_ysize = 1;
-
- for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- content_array[i][x][y] = EL_EMPTY;
- content_array[0][0][0] = level->amoeba_content;
- }
- else
- {
- /* chunk header already written -- write empty chunk data */
- WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT2_SIZE);
-
- Error(ERR_WARN, "cannot save content for element '%d'", element);
- return;
- }
-
- putFile16BitBE(file, element);
- putFile8Bit(file, num_contents);
- putFile8Bit(file, content_xsize);
- putFile8Bit(file, content_ysize);
-
- WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT2_UNUSED);
-
- for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- putFile16BitBE(file, content_array[i][x][y]);
-}
-#endif
-
-#if 0
-static int SaveLevel_CNT3(FILE *file, struct LevelInfo *level, int element)
-{
- int envelope_nr = element - EL_ENVELOPE_1;
- int envelope_len = strlen(level->envelope_text[envelope_nr]) + 1;
- int chunk_size = 0;
- int i;
-
- chunk_size += putFile16BitBE(file, element);
- chunk_size += putFile16BitBE(file, envelope_len);
- chunk_size += putFile8Bit(file, level->envelope_xsize[envelope_nr]);
- chunk_size += putFile8Bit(file, level->envelope_ysize[envelope_nr]);
-
- WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT3_UNUSED);
- chunk_size += LEVEL_CHUNK_CNT3_UNUSED;
-
- for (i = 0; i < envelope_len; i++)
- chunk_size += putFile8Bit(file, level->envelope_text[envelope_nr][i]);
-
- return chunk_size;
-}
-#endif
-
-#if 0
-static void SaveLevel_CUS1(FILE *file, struct LevelInfo *level,
- 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;
-
- struct ElementInfo *ei = &element_info[element];
-
- if (ei->properties[EP_BITFIELD_BASE_NR] != EP_BITMASK_DEFAULT)
- {
- if (check < num_changed_custom_elements)
- {
- putFile16BitBE(file, element);
- putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
- }
-
- check++;
- }
- }
-
- 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)
-{
- 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 (element_info[element].change->target_element != EL_EMPTY_SPACE)
- {
- if (check < num_changed_custom_elements)
- {
- putFile16BitBE(file, element);
- putFile16BitBE(file, element_info[element].change->target_element);
- }
-
- check++;
- }
- }
-
- if (check != num_changed_custom_elements) /* should not happen */
- Error(ERR_WARN, "inconsistent number of custom target elements");
-}
-#endif
-
-#if 0
-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;
- struct ElementInfo *ei = &element_info[element];
-
- if (ei->modified_settings)
- {
- if (check < num_changed_custom_elements)
- {
- putFile16BitBE(file, element);
-
- for (j = 0; j < MAX_ELEMENT_NAME_LEN; j++)
- putFile8Bit(file, ei->description[j]);
-
- putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
-
- /* some free bytes for future properties and padding */
- WriteUnusedBytesToFile(file, 7);
-
- putFile8Bit(file, ei->use_gfx_element);
- putFile16BitBE(file, ei->gfx_element_initial);
-
- putFile8Bit(file, ei->collect_score_initial);
- putFile8Bit(file, ei->collect_count_initial);
-
- putFile16BitBE(file, ei->push_delay_fixed);
- putFile16BitBE(file, ei->push_delay_random);
- putFile16BitBE(file, ei->move_delay_fixed);
- putFile16BitBE(file, ei->move_delay_random);
-
- putFile16BitBE(file, ei->move_pattern);
- putFile8Bit(file, ei->move_direction_initial);
- putFile8Bit(file, ei->move_stepsize);
-
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- putFile16BitBE(file, ei->content.e[x][y]);
-
- putFile32BitBE(file, ei->change->events);
-
- putFile16BitBE(file, ei->change->target_element);
-
- putFile16BitBE(file, ei->change->delay_fixed);
- putFile16BitBE(file, ei->change->delay_random);
- putFile16BitBE(file, ei->change->delay_frames);
-
- putFile16BitBE(file, ei->change->initial_trigger_element);
-
- putFile8Bit(file, ei->change->explode);
- putFile8Bit(file, ei->change->use_target_content);
- putFile8Bit(file, ei->change->only_if_complete);
- putFile8Bit(file, ei->change->use_random_replace);
-
- putFile8Bit(file, ei->change->random_percentage);
- putFile8Bit(file, ei->change->replace_when);
-
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- putFile16BitBE(file, ei->change->content.e[x][y]);
-
- putFile8Bit(file, ei->slippery_type);
-
- /* some free bytes for future properties and padding */
- WriteUnusedBytesToFile(file, LEVEL_CPART_CUS3_UNUSED);
- }
-
- check++;
- }
- }
-
- if (check != num_changed_custom_elements) /* should not happen */
- Error(ERR_WARN, "inconsistent number of custom element properties");
-}
-#endif
-
-#if 0
-static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
-{
- struct ElementInfo *ei = &element_info[element];
- int i, j, x, y;
-
- /* ---------- custom element base property values (96 bytes) ------------- */
-
- putFile16BitBE(file, element);
-
- for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++)
- putFile8Bit(file, ei->description[i]);
-
- putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
-
- WriteUnusedBytesToFile(file, 4); /* reserved for more base properties */
-
- putFile8Bit(file, ei->num_change_pages);
-
- putFile16BitBE(file, ei->ce_value_fixed_initial);
- putFile16BitBE(file, ei->ce_value_random_initial);
- putFile8Bit(file, ei->use_last_ce_value);
-
- putFile8Bit(file, ei->use_gfx_element);
- putFile16BitBE(file, ei->gfx_element_initial);
-
- putFile8Bit(file, ei->collect_score_initial);
- putFile8Bit(file, ei->collect_count_initial);
-
- putFile8Bit(file, ei->drop_delay_fixed);
- putFile8Bit(file, ei->push_delay_fixed);
- putFile8Bit(file, ei->drop_delay_random);
- putFile8Bit(file, ei->push_delay_random);
- putFile16BitBE(file, ei->move_delay_fixed);
- putFile16BitBE(file, ei->move_delay_random);
-
- /* bits 0 - 15 of "move_pattern" ... */
- putFile16BitBE(file, ei->move_pattern & 0xffff);
- putFile8Bit(file, ei->move_direction_initial);
- putFile8Bit(file, ei->move_stepsize);
-
- putFile8Bit(file, ei->slippery_type);
-
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- putFile16BitBE(file, ei->content.e[x][y]);
-
- putFile16BitBE(file, ei->move_enter_element);
- putFile16BitBE(file, ei->move_leave_element);
- putFile8Bit(file, ei->move_leave_type);
-
- /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */
- putFile16BitBE(file, (ei->move_pattern >> 16) & 0xffff);
-
- putFile8Bit(file, ei->access_direction);
-
- putFile8Bit(file, ei->explosion_delay);
- putFile8Bit(file, ei->ignition_delay);
- putFile8Bit(file, ei->explosion_type);
-
- /* some free bytes for future custom property values and padding */
- WriteUnusedBytesToFile(file, 1);
-
- /* ---------- change page property values (48 bytes) --------------------- */
-
- for (i = 0; i < ei->num_change_pages; i++)
- {
- struct ElementChangeInfo *change = &ei->change_page[i];
- unsigned int event_bits;
-
- /* 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);
-
- putFile16BitBE(file, change->delay_fixed);
- putFile16BitBE(file, change->delay_random);
- putFile16BitBE(file, change->delay_frames);
-
- putFile16BitBE(file, change->initial_trigger_element);
-
- putFile8Bit(file, change->explode);
- putFile8Bit(file, change->use_target_content);
- putFile8Bit(file, change->only_if_complete);
- putFile8Bit(file, change->use_random_replace);
-
- putFile8Bit(file, change->random_percentage);
- putFile8Bit(file, change->replace_when);
-
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- putFile16BitBE(file, change->target_content.e[x][y]);
-
- putFile8Bit(file, change->can_change);
-
- putFile8Bit(file, change->trigger_side);
-
- putFile8Bit(file, change->trigger_player);
- putFile8Bit(file, (change->trigger_page == CH_PAGE_ANY ? CH_PAGE_ANY_FILE :
- log_2(change->trigger_page)));
-
- putFile8Bit(file, change->has_action);
- putFile8Bit(file, change->action_type);
- putFile8Bit(file, change->action_mode);
- putFile16BitBE(file, change->action_arg);
-
- /* ... 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);
- }
-}
-#endif
-
-#if 0
-static void SaveLevel_GRP1(FILE *file, struct LevelInfo *level, int element)
-{
- struct ElementInfo *ei = &element_info[element];
- struct ElementGroupInfo *group = ei->group;
- int i;
-
- putFile16BitBE(file, element);
-
- for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++)
- putFile8Bit(file, ei->description[i]);
-
- putFile8Bit(file, group->num_elements);
-
- putFile8Bit(file, ei->use_gfx_element);
- putFile16BitBE(file, ei->gfx_element_initial);
-
- putFile8Bit(file, group->choice_mode);
-
- /* some free bytes for future values and padding */
- WriteUnusedBytesToFile(file, 3);
-
- for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
- putFile16BitBE(file, group->element[i]);
-}
-#endif
-
-static int SaveLevel_MicroChunk(FILE *file, struct LevelFileConfigInfo *entry,
- boolean write_element)
-{
- int save_type = entry->save_type;
- int data_type = entry->data_type;
- int conf_type = entry->conf_type;
- int byte_mask = conf_type & CONF_MASK_BYTES;
- int element = entry->element;
- int default_value = entry->default_value;
- int num_bytes = 0;
- boolean modified = FALSE;
-
- if (byte_mask != CONF_MASK_MULTI_BYTES)
- {
- void *value_ptr = entry->value;
- int value = (data_type == TYPE_BOOLEAN ? *(boolean *)value_ptr :
- *(int *)value_ptr);
-
- /* check if any settings have been modified before saving them */
- if (value != default_value)
- modified = TRUE;
-
- /* do not save if explicitly told or if unmodified default settings */
- if ((save_type == SAVE_CONF_NEVER) ||
- (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
- return 0;
-
- if (write_element)
- num_bytes += putFile16BitBE(file, element);
-
- num_bytes += putFile8Bit(file, conf_type);
- num_bytes += (byte_mask == CONF_MASK_1_BYTE ? putFile8Bit (file, value) :
- byte_mask == CONF_MASK_2_BYTE ? putFile16BitBE(file, value) :
- byte_mask == CONF_MASK_4_BYTE ? putFile32BitBE(file, value) :
- 0);
- }
- else if (data_type == TYPE_STRING)
- {
- char *default_string = entry->default_string;
- char *string = (char *)(entry->value);
- int string_length = strlen(string);
- int i;
-
- /* check if any settings have been modified before saving them */
- if (!strEqual(string, default_string))
- modified = TRUE;
-
- /* do not save if explicitly told or if unmodified default settings */
- if ((save_type == SAVE_CONF_NEVER) ||
- (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
- return 0;
-
- if (write_element)
- num_bytes += putFile16BitBE(file, element);
-
- num_bytes += putFile8Bit(file, conf_type);
- num_bytes += putFile16BitBE(file, string_length);
-
- for (i = 0; i < string_length; i++)
- num_bytes += putFile8Bit(file, string[i]);
- }
- else if (data_type == TYPE_ELEMENT_LIST)
- {
- int *element_array = (int *)(entry->value);
- int num_elements = *(int *)(entry->num_entities);
- int i;
-
- /* check if any settings have been modified before saving them */
- for (i = 0; i < num_elements; i++)
- if (element_array[i] != default_value)
- modified = TRUE;
-
- /* do not save if explicitly told or if unmodified default settings */
- if ((save_type == SAVE_CONF_NEVER) ||
- (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
- return 0;
-
- if (write_element)
- num_bytes += putFile16BitBE(file, element);
-
- num_bytes += putFile8Bit(file, conf_type);
- num_bytes += putFile16BitBE(file, num_elements * CONF_ELEMENT_NUM_BYTES);
-
- for (i = 0; i < num_elements; i++)
- num_bytes += putFile16BitBE(file, element_array[i]);
- }
- else if (data_type == TYPE_CONTENT_LIST)
- {
- struct Content *content = (struct Content *)(entry->value);
- int num_contents = *(int *)(entry->num_entities);
- int i, x, y;
-
- /* check if any settings have been modified before saving them */
- for (i = 0; i < num_contents; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- if (content[i].e[x][y] != default_value)
- modified = TRUE;
-
- /* do not save if explicitly told or if unmodified default settings */
- if ((save_type == SAVE_CONF_NEVER) ||
- (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
- return 0;
-
- if (write_element)
- num_bytes += putFile16BitBE(file, element);
-
- num_bytes += putFile8Bit(file, conf_type);
- num_bytes += putFile16BitBE(file, num_contents * CONF_CONTENT_NUM_BYTES);
-
- for (i = 0; i < num_contents; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- num_bytes += putFile16BitBE(file, content[i].e[x][y]);
- }
-
- return num_bytes;
-}
-
-static int SaveLevel_INFO(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
- int i;
-
- li = *level; /* copy level data into temporary buffer */
-
- for (i = 0; chunk_config_INFO[i].data_type != -1; i++)
- chunk_size += SaveLevel_MicroChunk(file, &chunk_config_INFO[i], FALSE);
-
- return chunk_size;
-}
-
-static int SaveLevel_ELEM(FILE *file, struct LevelInfo *level)
-{
- int chunk_size = 0;
- int i;
-
- li = *level; /* copy level data into temporary buffer */
-
- for (i = 0; chunk_config_ELEM[i].data_type != -1; i++)
- chunk_size += SaveLevel_MicroChunk(file, &chunk_config_ELEM[i], TRUE);
-
- return chunk_size;
-}
-
-static int SaveLevel_NOTE(FILE *file, struct LevelInfo *level, int element)
-{
- int envelope_nr = element - EL_ENVELOPE_1;
- int chunk_size = 0;
- int i;
-
- chunk_size += putFile16BitBE(file, element);
-
- /* copy envelope data into temporary buffer */
- xx_envelope = level->envelope[envelope_nr];
-
- for (i = 0; chunk_config_NOTE[i].data_type != -1; i++)
- chunk_size += SaveLevel_MicroChunk(file, &chunk_config_NOTE[i], FALSE);
-
- return chunk_size;
-}
-
-static int SaveLevel_CUSX(FILE *file, struct LevelInfo *level, int element)
-{
- struct ElementInfo *ei = &element_info[element];
- int chunk_size = 0;
- int i, j;
-
- chunk_size += putFile16BitBE(file, element);
-
- xx_ei = *ei; /* copy element data into temporary buffer */
-
- /* set default description string for this specific element */
- strcpy(xx_default_description, getDefaultElementDescription(ei));
-
-#if 0
- /* set (fixed) number of content areas (may be wrong by broken level file) */
- /* (this is now directly corrected for broken level files after loading) */
- xx_num_contents = 1;
-#endif
-
- for (i = 0; chunk_config_CUSX_base[i].data_type != -1; i++)
- chunk_size += SaveLevel_MicroChunk(file, &chunk_config_CUSX_base[i], FALSE);
-
- for (i = 0; i < ei->num_change_pages; i++)
- {
- struct ElementChangeInfo *change = &ei->change_page[i];
-
- xx_current_change_page = i;
-
- xx_change = *change; /* copy change data into temporary buffer */
-
- resetEventBits();
- setEventBitsFromEventFlags(change);
-
- for (j = 0; chunk_config_CUSX_change[j].data_type != -1; j++)
- chunk_size += SaveLevel_MicroChunk(file, &chunk_config_CUSX_change[j],
- FALSE);
- }
-
- return chunk_size;
-}
-
-static int SaveLevel_GRPX(FILE *file, struct LevelInfo *level, int element)
-{
- struct ElementInfo *ei = &element_info[element];
- struct ElementGroupInfo *group = ei->group;
- int chunk_size = 0;
- int i;
-
- chunk_size += putFile16BitBE(file, element);
-
- xx_ei = *ei; /* copy element data into temporary buffer */
- xx_group = *group; /* copy group data into temporary buffer */
-
- /* set default description string for this specific element */
- strcpy(xx_default_description, getDefaultElementDescription(ei));
-
- for (i = 0; chunk_config_GRPX[i].data_type != -1; i++)
- chunk_size += SaveLevel_MicroChunk(file, &chunk_config_GRPX[i], FALSE);
-
- return chunk_size;
-}
-
-static void SaveLevelFromFilename(struct LevelInfo *level, char *filename)
-{
- int chunk_size;
- int i;
- FILE *file;
-
- if (!(file = fopen(filename, MODE_WRITE)))
- {
- Error(ERR_WARN, "cannot save level file '%s'", filename);
- return;
- }
-
- level->file_version = FILE_VERSION_ACTUAL;
- level->game_version = GAME_VERSION_ACTUAL;
-
- level->creation_date = getCurrentDate();
-
- putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
- putFileChunkBE(file, "CAVE", CHUNK_SIZE_NONE);
-
- chunk_size = SaveLevel_VERS(NULL, level);
- putFileChunkBE(file, "VERS", chunk_size);
- SaveLevel_VERS(file, level);
-
- chunk_size = SaveLevel_DATE(NULL, level);
- putFileChunkBE(file, "DATE", chunk_size);
- SaveLevel_DATE(file, level);
-
- chunk_size = SaveLevel_NAME(NULL, level);
- putFileChunkBE(file, "NAME", chunk_size);
- SaveLevel_NAME(file, level);
-
- chunk_size = SaveLevel_AUTH(NULL, level);
- putFileChunkBE(file, "AUTH", chunk_size);
- SaveLevel_AUTH(file, level);
-
- chunk_size = SaveLevel_INFO(NULL, level);
- putFileChunkBE(file, "INFO", chunk_size);
- SaveLevel_INFO(file, level);