#define LEVEL_CHUNK_AUTH_SIZE MAX_LEVEL_AUTHOR_LEN
#define LEVEL_CHUNK_VERS_SIZE 8 /* size of file version chunk */
+#define LEVEL_CHUNK_DATE_SIZE 4 /* size of file date chunk */
#define LEVEL_CHUNK_HEAD_SIZE 80 /* size of level file header */
#define LEVEL_CHUNK_HEAD_UNUSED 0 /* unused level header bytes */
#define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */
{
-1, -1,
-1, -1,
- NULL, -1,
- },
+ NULL, -1
+ }
};
static struct LevelFileConfigInfo chunk_config_ELEM[] =
{
-1, -1,
-1, -1,
- NULL, -1,
- },
+ NULL, -1
+ }
};
static struct LevelFileConfigInfo chunk_config_NOTE[] =
{
-1, -1,
-1, -1,
- NULL, -1,
- },
+ NULL, -1
+ }
};
static struct LevelFileConfigInfo chunk_config_CUSX_base[] =
-1, -1,
NULL, -1,
NULL
- },
+ }
};
static struct LevelFileConfigInfo chunk_config_CUSX_change[] =
{
-1, -1,
-1, -1,
- NULL, -1,
- },
+ NULL, -1
+ }
};
static struct LevelFileConfigInfo chunk_config_GRPX[] =
{
-1, -1,
-1, -1,
- NULL, -1,
+ NULL, -1
+ }
+};
+
+static struct LevelFileConfigInfo chunk_config_CONF[] = /* (OBSOLETE) */
+{
+ {
+ EL_PLAYER_1, -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(9),
+ &li.block_snap_field, TRUE
+ },
+ {
+ EL_PLAYER_1, -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(13),
+ &li.continuous_snapping, TRUE
+ },
+ {
+ EL_PLAYER_1, -1,
+ TYPE_INTEGER, CONF_VALUE_8_BIT(1),
+ &li.initial_player_stepsize[0], STEPSIZE_NORMAL
+ },
+ {
+ EL_PLAYER_1, -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(10),
+ &li.use_start_element[0], FALSE
+ },
+ {
+ EL_PLAYER_1, -1,
+ TYPE_ELEMENT, CONF_VALUE_16_BIT(1),
+ &li.start_element[0], EL_PLAYER_1
},
+ {
+ EL_PLAYER_1, -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(11),
+ &li.use_artwork_element[0], FALSE
+ },
+ {
+ EL_PLAYER_1, -1,
+ TYPE_ELEMENT, CONF_VALUE_16_BIT(2),
+ &li.artwork_element[0], EL_PLAYER_1
+ },
+ {
+ EL_PLAYER_1, -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(12),
+ &li.use_explosion_element[0], FALSE
+ },
+ {
+ EL_PLAYER_1, -1,
+ TYPE_ELEMENT, CONF_VALUE_16_BIT(3),
+ &li.explosion_element[0], EL_PLAYER_1
+ },
+
+ {
+ -1, -1,
+ -1, -1,
+ NULL, -1
+ }
};
static struct
/* level file functions */
/* ========================================================================= */
+static struct DateInfo getCurrentDate()
+{
+ time_t epoch_seconds = time(NULL);
+ struct tm *now = localtime(&epoch_seconds);
+ struct DateInfo date;
+
+ date.year = now->tm_year + 1900;
+ date.month = now->tm_mon + 1;
+ date.day = now->tm_mday;
+
+ return date;
+}
+
static void resetEventFlags(struct ElementChangeInfo *change)
{
int i;
level->file_version = FILE_VERSION_ACTUAL;
level->game_version = GAME_VERSION_ACTUAL;
+ level->creation_date = getCurrentDate();
+
#if 1
level->encoding_16bit_field = TRUE;
level->encoding_16bit_yamyam = TRUE;
int element = i;
struct ElementInfo *ei = &element_info[element];
+ /* never initialize clipboard elements after the very first time */
+ /* (to be able to use clipboard elements between several levels) */
+ if (IS_CLIPBOARD_ELEMENT(element) && clipboard_elements_initialized)
+ continue;
+
if (IS_ENVELOPE(element))
{
int envelope_nr = element - EL_ENVELOPE_1;
}
#endif
- /* never initialize clipboard elements after the very first time */
- /* (to be able to use clipboard elements between several levels) */
- if (IS_CLIPBOARD_ELEMENT(element) && clipboard_elements_initialized)
- continue;
-
setElementChangePages(ei, 1);
setElementChangeInfoToDefaults(ei->change);
return chunk_size;
}
+static int LoadLevel_DATE(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+ level->creation_date.year = getFile16BitBE(file);
+ level->creation_date.month = getFile8Bit(file);
+ level->creation_date.day = getFile8Bit(file);
+
+ return chunk_size;
+}
+
static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level)
{
int initial_player_stepsize;
#endif
#if 1
+ /* older game versions that wrote level files with CUS1 chunks used
+ different default push delay values (not yet stored in level file) */
+ element_info[element].push_delay_fixed = 2;
+ element_info[element].push_delay_random = 8;
+#else
/* needed for older levels (see src/init.c for details) */
element_info[element].push_delay_fixed = -1; /* initialize later */
element_info[element].push_delay_random = -1; /* initialize later */
return real_chunk_size;
}
+static int LoadLevel_CONF(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+ int real_chunk_size = 0;
+
+ li = *level; /* copy level data into temporary buffer */
+
+ while (!feof(file))
+ {
+ int element = getMappedElement(getFile16BitBE(file));
+
+ real_chunk_size += 2;
+ real_chunk_size += LoadLevel_MicroChunk(file, chunk_config_CONF,
+ element, element);
+ if (real_chunk_size >= chunk_size)
+ break;
+ }
+
+ *level = li; /* copy temporary buffer back to level data */
+
+ return real_chunk_size;
+}
+
static int LoadLevel_ELEM(FILE *file, int chunk_size, struct LevelInfo *level)
{
int real_chunk_size = 0;
chunk_info[] =
{
{ "VERS", LEVEL_CHUNK_VERS_SIZE, LoadLevel_VERS },
+ { "DATE", LEVEL_CHUNK_DATE_SIZE, LoadLevel_DATE },
{ "HEAD", LEVEL_CHUNK_HEAD_SIZE, LoadLevel_HEAD },
{ "NAME", LEVEL_CHUNK_NAME_SIZE, LoadLevel_NAME },
{ "AUTH", LEVEL_CHUNK_AUTH_SIZE, LoadLevel_AUTH },
{ "CUS3", -1, LoadLevel_CUS3 },
{ "CUS4", -1, LoadLevel_CUS4 },
{ "GRP1", -1, LoadLevel_GRP1 },
+ { "CONF", -1, LoadLevel_CONF },
{ "ELEM", -1, LoadLevel_ELEM },
{ "NOTE", -1, LoadLevel_NOTE },
{ "CUSX", -1, LoadLevel_CUSX },
/* initialize element properties for level editor etc. */
InitElementPropertiesEngine(level->game_version);
+ InitElementPropertiesAfterLoading(level->game_version);
}
static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename)
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)
{
level->file_version = FILE_VERSION_ACTUAL;
level->game_version = GAME_VERSION_ACTUAL;
+ level->creation_date = getCurrentDate();
+
#if 0
/* check level field for 16-bit elements */
level->encoding_16bit_field = FALSE;
putFileChunkBE(file, "VERS", chunk_size);
SaveLevel_VERS(file, level);
+ chunk_size = SaveLevel_DATE(NULL, level);
+ putFileChunkBE(file, "DATE", chunk_size);
+ SaveLevel_DATE(file, level);
+
#if 0
putFileChunkBE(file, "HEAD", LEVEL_CHUNK_HEAD_SIZE);
SaveLevel_HEAD(file, level);
#endif
chunk_size = SaveLevel_ELEM(NULL, level);
-
- /* check if non-default element settings need to be saved */
- if (chunk_size > LEVEL_CHUNK_ELEM_UNCHANGED)
+ if (chunk_size > LEVEL_CHUNK_ELEM_UNCHANGED) /* save if changed */
{
putFileChunkBE(file, "ELEM", chunk_size);
SaveLevel_ELEM(file, level);
}
#if 1
- for (i = 0; i < 4; i++)
+ for (i = 0; i < NUM_ENVELOPES; i++)
{
int element = EL_ENVELOPE_1 + i;
chunk_size = SaveLevel_NOTE(NULL, level, element);
-
- /* check if non-default element settings need to be saved */
- if (chunk_size > LEVEL_CHUNK_NOTE_UNCHANGED)
+ if (chunk_size > LEVEL_CHUNK_NOTE_UNCHANGED) /* save if changed */
{
putFileChunkBE(file, "NOTE", chunk_size);
SaveLevel_NOTE(file, level, element);
int element = EL_CUSTOM_START + i;
chunk_size = SaveLevel_CUSX(NULL, level, element);
-
- /* check if non-default element settings need to be saved */
- if (chunk_size > LEVEL_CHUNK_CUSX_UNCHANGED)
+ if (chunk_size > LEVEL_CHUNK_CUSX_UNCHANGED) /* save if changed */
{
putFileChunkBE(file, "CUSX", chunk_size);
SaveLevel_CUSX(file, level, element);
int element = EL_GROUP_START + i;
chunk_size = SaveLevel_GRPX(NULL, level, element);
-
- /* check if non-default element settings need to be saved */
- if (chunk_size > LEVEL_CHUNK_GRPX_UNCHANGED)
+ if (chunk_size > LEVEL_CHUNK_GRPX_UNCHANGED) /* save if changed */
{
putFileChunkBE(file, "GRPX", chunk_size);
SaveLevel_GRPX(file, level, element);
tape.length_seconds = GetTapeLength();
#if 0
+ printf("::: tape file version: %d\n", tape.file_version);
printf("::: tape game version: %d\n", tape.game_version);
printf("::: tape engine version: %d\n", tape.engine_version);
#endif
#define SETUP_TOKEN_EDITOR_EL_HEADLINES 10
#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED 11
#define SETUP_TOKEN_EDITOR_EL_DYNAMIC 12
-#define SETUP_TOKEN_EDITOR_SHOW_ELEMENT_TOKEN 13
+#define SETUP_TOKEN_EDITOR_EL_BY_GAME 13
+#define SETUP_TOKEN_EDITOR_EL_BY_TYPE 14
+#define SETUP_TOKEN_EDITOR_SHOW_ELEMENT_TOKEN 15
-#define NUM_EDITOR_SETUP_TOKENS 14
+#define NUM_EDITOR_SETUP_TOKENS 16
/* editor cascade setup */
#define SETUP_TOKEN_EDITOR_CASCADE_BD 0
#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_REF 11
+#define SETUP_TOKEN_EDITOR_CASCADE_USER 12
#define SETUP_TOKEN_EDITOR_CASCADE_DYNAMIC 13
#define NUM_EDITOR_CASCADE_SETUP_TOKENS 14
{ TYPE_SWITCH, &si.override_level_music, "override_level_music" },
};
+static boolean not_used = FALSE;
static struct TokenInfo editor_setup_tokens[] =
{
+#if 1
+ { TYPE_SWITCH, ¬_used, "editor.el_boulderdash" },
+ { TYPE_SWITCH, ¬_used, "editor.el_emerald_mine" },
+ { TYPE_SWITCH, ¬_used, "editor.el_emerald_mine_club" },
+ { TYPE_SWITCH, ¬_used, "editor.el_more" },
+ { TYPE_SWITCH, ¬_used, "editor.el_sokoban" },
+ { TYPE_SWITCH, ¬_used, "editor.el_supaplex" },
+ { TYPE_SWITCH, ¬_used, "editor.el_diamond_caves" },
+ { TYPE_SWITCH, ¬_used, "editor.el_dx_boulderdash" },
+#else
{ TYPE_SWITCH, &sei.el_boulderdash, "editor.el_boulderdash" },
{ TYPE_SWITCH, &sei.el_emerald_mine, "editor.el_emerald_mine" },
{ TYPE_SWITCH, &sei.el_emerald_mine_club,"editor.el_emerald_mine_club"},
{ TYPE_SWITCH, &sei.el_supaplex, "editor.el_supaplex" },
{ TYPE_SWITCH, &sei.el_diamond_caves, "editor.el_diamond_caves" },
{ TYPE_SWITCH, &sei.el_dx_boulderdash,"editor.el_dx_boulderdash" },
+#endif
{ TYPE_SWITCH, &sei.el_chars, "editor.el_chars" },
{ TYPE_SWITCH, &sei.el_custom, "editor.el_custom" },
+#if 1
+ { TYPE_SWITCH, ¬_used, "editor.el_headlines" },
+#else
{ TYPE_SWITCH, &sei.el_headlines, "editor.el_headlines" },
+#endif
{ TYPE_SWITCH, &sei.el_user_defined, "editor.el_user_defined" },
{ TYPE_SWITCH, &sei.el_dynamic, "editor.el_dynamic" },
+ { TYPE_SWITCH, &sei.el_by_game, "editor.el_by_game" },
+ { TYPE_SWITCH, &sei.el_by_type, "editor.el_by_type" },
{ TYPE_SWITCH, &sei.show_element_token,"editor.show_element_token" },
};
{ 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_ref, "editor.cascade.el_ref" },
{ TYPE_SWITCH, &seci.el_user, "editor.cascade.el_user" },
{ TYPE_SWITCH, &seci.el_dynamic, "editor.cascade.el_dynamic" },
};
si->editor_cascade.el_chars = FALSE;
si->editor_cascade.el_ce = FALSE;
si->editor_cascade.el_ge = FALSE;
+ si->editor_cascade.el_ref = FALSE;
si->editor_cascade.el_user = FALSE;
si->editor_cascade.el_dynamic = FALSE;
}
seci = setup.editor_cascade;
fprintf(file, "\n");
- for (i = 0; i < NUM_EDITOR_SETUP_TOKENS; i++)
+ for (i = 0; i < NUM_EDITOR_CASCADE_SETUP_TOKENS; i++)
fprintf(file, "%s\n", getSetupLine(editor_cascade_setup_tokens, "", i));
fclose(file);