+#if 0
+#define CONF_VALUE_ELEMENTS CONF_VALUE_BYTES(1)
+#define CONF_VALUE_CONTENTS CONF_VALUE_BYTES(2)
+#endif
+
+#if 0
+#define CONF_VALUE_INTEGER(x) ((x) >= CONF_VALUE_INTEGER_1 && \
+ (x) <= CONF_VALUE_INTEGER_8)
+
+#define CONF_VALUE_BOOLEAN(x) ((x) >= CONF_VALUE_BOOLEAN_1 && \
+ (x) <= CONF_VALUE_BOOLEAN_8)
+#endif
+
+#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)
+
+#if 0
+#define CONF_CONTENT_NUM_ELEMENTS (3 * 3)
+#define CONF_CONTENT_NUM_BYTES (CONF_CONTENT_NUM_ELEMENTS * 2)
+#define CONF_ELEMENT_NUM_BYTES (2)
+
+#define CONF_ENTITY_NUM_BYTES(t) ((t) == CONF_VALUE_ELEMENTS ? \
+ CONF_ELEMENT_NUM_BYTES : \
+ (t) == CONF_VALUE_CONTENTS ? \
+ CONF_CONTENT_NUM_BYTES : 1)
+#endif
+
+#define CONF_CONTENT_NUM_ELEMENTS (3 * 3)
+#define CONF_CONTENT_NUM_BYTES (CONF_CONTENT_NUM_ELEMENTS * 2)
+#define CONF_ELEMENT_NUM_BYTES (2)
+
+#define CONF_ENTITY_NUM_BYTES(t) ((t) == TYPE_ELEMENT || \
+ (t) == TYPE_ELEMENT_LIST ? \
+ CONF_ELEMENT_NUM_BYTES : \
+ (t) == TYPE_CONTENT || \
+ (t) == TYPE_CONTENT_LIST ? \
+ CONF_CONTENT_NUM_BYTES : 1)
+
+#define CONF_ELEMENT_BYTE_POS(i) ((i) * CONF_ELEMENT_NUM_BYTES)
+#define CONF_ELEMENTS_ELEMENT(b,i) ((b[CONF_ELEMENT_BYTE_POS(i)] << 8) | \
+ (b[CONF_ELEMENT_BYTE_POS(i) + 1]))
+
+#define CONF_CONTENT_ELEMENT_POS(c,x,y) ((c) * CONF_CONTENT_NUM_ELEMENTS + \
+ (y) * 3 + (x))
+#define CONF_CONTENT_BYTE_POS(c,x,y) (CONF_CONTENT_ELEMENT_POS(c,x,y) * \
+ CONF_ELEMENT_NUM_BYTES)
+#define CONF_CONTENTS_ELEMENT(b,c,x,y) ((b[CONF_CONTENT_BYTE_POS(c,x,y)]<< 8)|\
+ (b[CONF_CONTENT_BYTE_POS(c,x,y) + 1]))
+
+#if 0
+static void LoadLevel_InitPlayfield(struct LevelInfo *, char *);
+#endif
+
+/* temporary variables used to store pointers to structure members */
+static struct LevelInfo li;
+static struct ElementInfo xx_ei;
+static struct ElementChangeInfo xx_change;
+static struct ElementGroupInfo xx_group;
+static unsigned int xx_event_bits_0_31, xx_event_bits_32_63;
+static char xx_default_description[MAX_ELEMENT_NAME_LEN + 1];
+static int xx_default_description_length;
+static int xx_num_contents;
+static int xx_current_change_page;
+
+struct ElementFileConfig
+{
+ int element; /* element for which data is to be stored */
+ int data_type; /* internal type of data */
+ int conf_type; /* special type identifier stored in file */
+
+ /* (mandatory) */
+ void *value; /* variable that holds the data to be stored */
+ int default_value; /* initial default value for this variable */
+
+ /* (optional) */
+ void *num_entities; /* number of entities for multi-byte data */
+ int default_num_entities; /* default number of entities for this data */
+ int max_num_entities; /* maximal number of entities for this data */
+ char *default_string; /* optional default string for string data */
+};
+
+static struct ElementFileConfig element_conf[] =
+{
+ /* ---------- 1-byte values ---------------------------------------------- */
+
+ {
+ EL_EMC_ANDROID,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.android_move_time, 10
+ },
+ {
+ EL_EMC_ANDROID,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_2,
+ &li.android_clone_time, 10
+ },
+ {
+ EL_EMC_LENSES,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.lenses_score, 10
+ },
+ {
+ EL_EMC_LENSES,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_2,
+ &li.lenses_time, 10
+ },
+ {
+ EL_EMC_MAGNIFIER,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.magnify_score, 10
+ },
+ {
+ EL_EMC_MAGNIFIER,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_2,
+ &li.magnify_time, 10
+ },
+ {
+ EL_ROBOT,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.slurp_score, 10
+ },
+ {
+ EL_GAME_OF_LIFE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.game_of_life[0], 2
+ },
+ {
+ EL_GAME_OF_LIFE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_2,
+ &li.game_of_life[1], 3
+ },
+ {
+ EL_GAME_OF_LIFE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_3,
+ &li.game_of_life[2], 3
+ },
+ {
+ EL_GAME_OF_LIFE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_4,
+ &li.game_of_life[3], 3
+ },
+ {
+ EL_BIOMAZE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.biomaze[0], 2
+ },
+ {
+ EL_BIOMAZE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_2,
+ &li.biomaze[1], 3
+ },
+ {
+ EL_BIOMAZE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_3,
+ &li.biomaze[2], 3
+ },
+ {
+ EL_BIOMAZE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_4,
+ &li.biomaze[3], 3
+ },
+ {
+ EL_BALLOON,
+ TYPE_BITFIELD, CONF_VALUE_INTEGER_1,
+ &li.wind_direction_initial, MV_NONE
+ },
+ {
+ EL_TIMEGATE_SWITCH,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.time_timegate, 10
+ },
+ {
+ EL_LIGHT_SWITCH_ACTIVE,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.time_light, 10
+ },
+ {
+ EL_SHIELD_NORMAL,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.shield_normal_time, 10
+ },
+ {
+ EL_SHIELD_DEADLY,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.shield_deadly_time, 10
+ },
+ {
+ EL_EXTRA_TIME,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.extra_time, 10
+ },
+ {
+ EL_EXTRA_TIME,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_2,
+ &li.extra_time_score, 10
+ },
+ {
+ EL_TIME_ORB_FULL,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.time_orb_time, 10
+ },
+ {
+ EL_TIME_ORB_FULL,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_1,
+ &li.use_time_orb_bug, FALSE
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_1,
+ &li.block_snap_field, TRUE
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_2,
+ &li.use_start_element[0], FALSE
+ },
+ {
+ EL_PLAYER_2,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_2,
+ &li.use_start_element[1], FALSE
+ },
+ {
+ EL_PLAYER_3,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_2,
+ &li.use_start_element[2], FALSE
+ },
+ {
+ EL_PLAYER_4,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_2,
+ &li.use_start_element[3], FALSE
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_3,
+ &li.use_artwork_element[0], FALSE
+ },
+ {
+ EL_PLAYER_2,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_3,
+ &li.use_artwork_element[1], FALSE
+ },
+ {
+ EL_PLAYER_3,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_3,
+ &li.use_artwork_element[2], FALSE
+ },
+ {
+ EL_PLAYER_4,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_3,
+ &li.use_artwork_element[3], FALSE
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_4,
+ &li.use_explosion_element[0], FALSE
+ },
+ {
+ EL_PLAYER_2,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_4,
+ &li.use_explosion_element[1], FALSE
+ },
+ {
+ EL_PLAYER_3,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_4,
+ &li.use_explosion_element[2], FALSE
+ },
+ {
+ EL_PLAYER_4,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_4,
+ &li.use_explosion_element[3], FALSE
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_5,
+ &li.continuous_snapping, TRUE
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.initial_player_stepsize, STEPSIZE_NORMAL
+ },
+ {
+ EL_EMC_MAGIC_BALL,
+ TYPE_INTEGER, CONF_VALUE_INTEGER_1,
+ &li.ball_time, 10
+ },
+ {
+ EL_EMC_MAGIC_BALL,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_1,
+ &li.ball_random, FALSE
+ },
+ {
+ EL_EMC_MAGIC_BALL,
+ TYPE_BOOLEAN, CONF_VALUE_BOOLEAN_2,
+ &li.ball_state_initial, FALSE
+ },
+
+ /* ---------- 2-byte values ---------------------------------------------- */
+
+ {
+ EL_PLAYER_1,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_1,
+ &li.start_element[0], EL_PLAYER_1
+ },
+ {
+ EL_PLAYER_2,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_1,
+ &li.start_element[1], EL_PLAYER_2
+ },
+ {
+ EL_PLAYER_3,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_1,
+ &li.start_element[2], EL_PLAYER_3
+ },
+ {
+ EL_PLAYER_4,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_1,
+ &li.start_element[3], EL_PLAYER_4
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_2,
+ &li.artwork_element[0], EL_PLAYER_1
+ },
+ {
+ EL_PLAYER_2,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_2,
+ &li.artwork_element[1], EL_PLAYER_2
+ },
+ {
+ EL_PLAYER_3,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_2,
+ &li.artwork_element[2], EL_PLAYER_3
+ },
+ {
+ EL_PLAYER_4,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_2,
+ &li.artwork_element[3], EL_PLAYER_4
+ },
+ {
+ EL_PLAYER_1,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_3,
+ &li.explosion_element[0], EL_PLAYER_1
+ },
+ {
+ EL_PLAYER_2,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_3,
+ &li.explosion_element[1], EL_PLAYER_2
+ },
+ {
+ EL_PLAYER_3,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_3,
+ &li.explosion_element[2], EL_PLAYER_3
+ },
+ {
+ EL_PLAYER_4,
+ TYPE_ELEMENT, CONF_VALUE_ELEMENT_3,
+ &li.explosion_element[3], EL_PLAYER_4
+ },
+
+ /* ---------- multi-byte values ------------------------------------------ */
+
+ {
+ EL_EMC_ANDROID,
+ TYPE_ELEMENT_LIST, CONF_VALUE_BYTES(1),
+ &li.android_clone_element[0], EL_EMPTY,
+ &li.num_android_clone_elements, 1, MAX_ANDROID_ELEMENTS
+ },
+ {
+ EL_EMC_MAGIC_BALL,
+ TYPE_CONTENT_LIST, CONF_VALUE_BYTES(2),
+ &li.ball_content, EL_EMPTY,
+ &li.num_ball_contents, 4, MAX_ELEMENT_CONTENTS
+ },
+
+ {
+ -1,
+ -1, -1,
+ NULL, -1,
+ },
+};
+
+static struct ElementFileConfig custom_element_conf[] =
+{
+ {
+ -1,
+ TYPE_STRING, CONF_VALUE_BYTES(1),
+ &xx_ei.description[0], -1,
+ &xx_default_description_length, -1, MAX_ELEMENT_NAME_LEN,
+ &xx_default_description[0]
+ },
+
+ {
+ -1,
+ TYPE_BITFIELD, CONF_VALUE_32_BIT(1),
+ &xx_ei.properties[EP_BITFIELD_BASE],
+#if 0
+ EP_BITMASK_DEFAULT
+#else
+ (1 << EP_CAN_MOVE_INTO_ACID)
+#endif
+ },
+#if 0
+ /* (reserved) */
+ {
+ -1,
+ TYPE_BITFIELD, CONF_VALUE_32_BIT(2),
+ &xx_ei.properties[EP_BITFIELD_BASE + 1], EP_BITMASK_DEFAULT
+ },
+#endif
+
+ {
+ -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(1),
+ &xx_ei.use_gfx_element, FALSE
+ },
+ {
+ -1,
+ TYPE_ELEMENT, CONF_VALUE_16_BIT(1),
+ &xx_ei.gfx_element, EL_EMPTY_SPACE
+ },
+
+ {
+ -1,
+ TYPE_BITFIELD, CONF_VALUE_8_BIT(2),
+ &xx_ei.access_direction, MV_ALL_DIRECTIONS
+ },
+
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(2),
+ &xx_ei.collect_score_initial, 10
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(3),
+ &xx_ei.collect_count_initial, 1
+ },
+
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(4),
+ &xx_ei.ce_value_fixed_initial, 0
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(5),
+ &xx_ei.ce_value_random_initial, 0
+ },
+ {
+ -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(3),
+ &xx_ei.use_last_ce_value, FALSE
+ },
+
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(6),
+ &xx_ei.push_delay_fixed, 8,
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(7),
+ &xx_ei.push_delay_random, 8,
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(8),
+ &xx_ei.drop_delay_fixed, 0
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(9),
+ &xx_ei.drop_delay_random, 0
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(10),
+ &xx_ei.move_delay_fixed, 0
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(11),
+ &xx_ei.move_delay_random, 0
+ },
+
+ {
+ -1,
+ TYPE_BITFIELD, CONF_VALUE_32_BIT(3),
+ &xx_ei.move_pattern, MV_ALL_DIRECTIONS
+ },
+ {
+ -1,
+ TYPE_BITFIELD, CONF_VALUE_8_BIT(4),
+ &xx_ei.move_direction_initial, MV_START_AUTOMATIC
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_8_BIT(5),
+ &xx_ei.move_stepsize, TILEX / 8
+ },
+
+ {
+ -1,
+ TYPE_ELEMENT, CONF_VALUE_16_BIT(12),
+ &xx_ei.move_enter_element, EL_EMPTY_SPACE
+ },
+ {
+ -1,
+ TYPE_ELEMENT, CONF_VALUE_16_BIT(13),
+ &xx_ei.move_leave_element, EL_EMPTY_SPACE
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_8_BIT(6),
+ &xx_ei.move_leave_type, LEAVE_TYPE_UNLIMITED
+ },
+
+ {
+ -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(7),
+ &xx_ei.slippery_type, SLIPPERY_ANY_RANDOM
+ },
+
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_8_BIT(8),
+ &xx_ei.explosion_type, EXPLODES_3X3
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(14),
+ &xx_ei.explosion_delay, 16
+ },
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_16_BIT(15),
+ &xx_ei.ignition_delay, 8
+ },
+
+ {
+ -1,
+ TYPE_CONTENT_LIST, CONF_VALUE_BYTES(2),
+ &xx_ei.content, EL_EMPTY_SPACE,
+ &xx_num_contents, 1, 1
+ },
+
+ /* ---------- "num_change_pages" must be the last entry ------------------- */
+
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_8_BIT(9),
+ &xx_ei.num_change_pages, -1 /* always save this value */
+ },
+
+ {
+ -1,
+ -1, -1,
+ NULL, -1,
+ },
+};
+
+static struct ElementFileConfig custom_element_change_conf[] =
+{
+ /* ---------- "current_change_page" must be the first entry --------------- */
+
+ {
+ -1,
+ TYPE_INTEGER, CONF_VALUE_8_BIT(1),
+ &xx_current_change_page, -1
+ },
+
+ {
+ -1,
+ TYPE_BOOLEAN, CONF_VALUE_8_BIT(2),
+ &xx_change.can_change, FALSE
+ },
+
+ {
+ -1,
+ TYPE_BITFIELD, CONF_VALUE_32_BIT(1),
+ &xx_event_bits_0_31, 0
+ },
+ {
+ -1,
+ TYPE_BITFIELD, CONF_VALUE_32_BIT(2),
+ &xx_event_bits_32_63, 0
+ },