/* temporary variables used to store pointers to structure members */
static struct LevelInfo li;
-static struct ElementInfo xx_ei;
+static struct ElementInfo xx_ei, yy_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 int xx_num_description_bytes;
+static unsigned int xx_event_bits[NUM_CE_BITFIELDS];
+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;
int default_value; /* initial default value for this variable */
/* (optional) */
+ void *value_copy; /* variable that holds the data to be copied */
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[] =
{
EL_EMC_ANDROID,
TYPE_ELEMENT_LIST, CONF_VALUE_BYTES(1),
- &li.android_clone_element[0], EL_EMPTY,
+ &li.android_clone_element[0], EL_EMPTY, NULL,
&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.ball_content, EL_EMPTY, NULL,
&li.num_ball_contents, 4, MAX_ELEMENT_CONTENTS
},
{
-1,
TYPE_STRING, CONF_VALUE_BYTES(1),
- &xx_ei.description[0], 0,
- &xx_num_description_bytes, MAX_ELEMENT_NAME_LEN, MAX_ELEMENT_NAME_LEN,
+ &xx_ei.description[0], -1,
+ &yy_ei.description[0],
+ &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
+ &xx_ei.properties[EP_BITFIELD_BASE_NR], EP_BITMASK_BASE_DEFAULT,
+ &yy_ei.properties[EP_BITFIELD_BASE_NR]
},
#if 0
/* (reserved) */
{
-1,
TYPE_BITFIELD, CONF_VALUE_32_BIT(2),
- &xx_ei.properties[EP_BITFIELD_BASE + 1], EP_BITMASK_DEFAULT
+ &xx_ei.properties[EP_BITFIELD_BASE_NR + 1], EP_BITMASK_DEFAULT,
+ &yy_ei.properties[EP_BITFIELD_BASE_NR + 1]
},
#endif
{
-1,
TYPE_BOOLEAN, CONF_VALUE_8_BIT(1),
- &xx_ei.use_gfx_element, FALSE
+ &xx_ei.use_gfx_element, FALSE,
+ &yy_ei.use_gfx_element
},
{
-1,
TYPE_ELEMENT, CONF_VALUE_16_BIT(1),
- &xx_ei.gfx_element, EL_EMPTY_SPACE
+ &xx_ei.gfx_element, EL_EMPTY_SPACE,
+ &yy_ei.gfx_element
},
{
-1,
TYPE_BITFIELD, CONF_VALUE_8_BIT(2),
- &xx_ei.access_direction, MV_ALL_DIRECTIONS
+ &xx_ei.access_direction, MV_ALL_DIRECTIONS,
+ &yy_ei.access_direction
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(2),
- &xx_ei.collect_score_initial, 10
+ &xx_ei.collect_score_initial, 10,
+ &yy_ei.collect_score_initial
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(3),
- &xx_ei.collect_count_initial, 1
+ &xx_ei.collect_count_initial, 1,
+ &yy_ei.collect_count_initial
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(4),
- &xx_ei.ce_value_fixed_initial, 0
+ &xx_ei.ce_value_fixed_initial, 0,
+ &yy_ei.ce_value_fixed_initial
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(5),
- &xx_ei.ce_value_random_initial, 0
+ &xx_ei.ce_value_random_initial, 0,
+ &yy_ei.ce_value_random_initial
},
{
-1,
TYPE_BOOLEAN, CONF_VALUE_8_BIT(3),
- &xx_ei.use_last_ce_value, FALSE
+ &xx_ei.use_last_ce_value, FALSE,
+ &yy_ei.use_last_ce_value
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(6),
&xx_ei.push_delay_fixed, 8,
+ &yy_ei.push_delay_fixed
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(7),
&xx_ei.push_delay_random, 8,
+ &yy_ei.push_delay_random
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(8),
- &xx_ei.drop_delay_fixed, 0
+ &xx_ei.drop_delay_fixed, 0,
+ &yy_ei.drop_delay_fixed
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(9),
- &xx_ei.drop_delay_random, 0
+ &xx_ei.drop_delay_random, 0,
+ &yy_ei.drop_delay_random
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(10),
- &xx_ei.move_delay_fixed, 0
+ &xx_ei.move_delay_fixed, 0,
+ &yy_ei.move_delay_fixed
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(11),
- &xx_ei.move_delay_random, 0
+ &xx_ei.move_delay_random, 0,
+ &yy_ei.move_delay_random
},
{
-1,
TYPE_BITFIELD, CONF_VALUE_32_BIT(3),
- &xx_ei.move_pattern, MV_ALL_DIRECTIONS
+ &xx_ei.move_pattern, MV_ALL_DIRECTIONS,
+ &yy_ei.move_pattern
},
{
-1,
TYPE_BITFIELD, CONF_VALUE_8_BIT(4),
- &xx_ei.move_direction_initial, MV_START_AUTOMATIC
+ &xx_ei.move_direction_initial, MV_START_AUTOMATIC,
+ &yy_ei.move_direction_initial
},
{
-1,
TYPE_INTEGER, CONF_VALUE_8_BIT(5),
- &xx_ei.move_stepsize, TILEX / 8
+ &xx_ei.move_stepsize, TILEX / 8,
+ &yy_ei.move_stepsize
},
{
-1,
TYPE_ELEMENT, CONF_VALUE_16_BIT(12),
- &xx_ei.move_enter_element, EL_EMPTY_SPACE
+ &xx_ei.move_enter_element, EL_EMPTY_SPACE,
+ &yy_ei.move_enter_element
},
{
-1,
TYPE_ELEMENT, CONF_VALUE_16_BIT(13),
- &xx_ei.move_leave_element, EL_EMPTY_SPACE
+ &xx_ei.move_leave_element, EL_EMPTY_SPACE,
+ &yy_ei.move_leave_element
},
{
-1,
TYPE_INTEGER, CONF_VALUE_8_BIT(6),
- &xx_ei.move_leave_type, LEAVE_TYPE_UNLIMITED
+ &xx_ei.move_leave_type, LEAVE_TYPE_UNLIMITED,
+ &yy_ei.move_leave_type
},
{
-1,
- TYPE_BOOLEAN, CONF_VALUE_8_BIT(7),
- &xx_ei.slippery_type, SLIPPERY_ANY_RANDOM
+ TYPE_INTEGER, CONF_VALUE_8_BIT(7),
+ &xx_ei.slippery_type, SLIPPERY_ANY_RANDOM,
+ &yy_ei.slippery_type
},
{
-1,
TYPE_INTEGER, CONF_VALUE_8_BIT(8),
- &xx_ei.explosion_type, EXPLODES_3X3
+ &xx_ei.explosion_type, EXPLODES_3X3,
+ &yy_ei.explosion_type
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(14),
- &xx_ei.explosion_delay, 16
+ &xx_ei.explosion_delay, 16,
+ &yy_ei.explosion_delay
},
{
-1,
TYPE_INTEGER, CONF_VALUE_16_BIT(15),
- &xx_ei.ignition_delay, 8
+ &xx_ei.ignition_delay, 8,
+ &yy_ei.ignition_delay
},
{
-1,
TYPE_CONTENT_LIST, CONF_VALUE_BYTES(2),
&xx_ei.content, EL_EMPTY_SPACE,
+ &yy_ei.content,
&xx_num_contents, 1, 1
},
{
-1,
TYPE_INTEGER, CONF_VALUE_8_BIT(9),
- &xx_ei.num_change_pages, -1 /* always save this value */
+ &xx_ei.num_change_pages, -1, /* value must always be saved */
+ &yy_ei.num_change_pages
},
{
-1,
-1, -1,
NULL, -1,
+ NULL
},
};
{
-1,
TYPE_INTEGER, CONF_VALUE_8_BIT(1),
- &xx_current_change_page, -1
+ &xx_current_change_page, -1 /* value must always be saved */
},
+ /* ---------- (the remaining entries can be in any order) ----------------- */
+
{
-1,
TYPE_BOOLEAN, CONF_VALUE_8_BIT(2),
{
-1,
TYPE_BITFIELD, CONF_VALUE_32_BIT(1),
- &xx_event_bits_0_31, 0
+ &xx_event_bits[0], 0
},
{
-1,
TYPE_BITFIELD, CONF_VALUE_32_BIT(2),
- &xx_event_bits_32_63, 0
+ &xx_event_bits[1], 0
},
{
{
-1,
TYPE_CONTENT_LIST, CONF_VALUE_BYTES(1),
- &xx_change.target_content, EL_EMPTY_SPACE,
+ &xx_change.target_content, EL_EMPTY_SPACE, NULL,
&xx_num_contents, 1, 1
},
{
-1,
TYPE_STRING, CONF_VALUE_BYTES(1),
- &xx_ei.description[0], 0,
- &xx_num_description_bytes, MAX_ELEMENT_NAME_LEN, MAX_ELEMENT_NAME_LEN,
+ &xx_ei.description[0], -1, NULL,
+ &xx_default_description_length, -1, MAX_ELEMENT_NAME_LEN,
+ &xx_default_description[0]
},
{
{
-1,
TYPE_ELEMENT_LIST, CONF_VALUE_BYTES(2),
- &xx_group.element[0], EL_EMPTY_SPACE,
+ &xx_group.element[0], EL_EMPTY_SPACE, NULL,
&xx_group.num_elements, 1, MAX_ELEMENTS_IN_GROUP
},
/* level file functions */
/* ========================================================================= */
-static void setLevelInfoToDefaultsFromConfigList(struct LevelInfo *level)
+static void resetEventFlags(struct ElementChangeInfo *change)
{
int i;
- li = *level; /* copy level data into temporary buffer */
+ for (i = 0; i < NUM_CHANGE_EVENTS; i++)
+ change->has_event[i] = FALSE;
+}
- for (i = 0; element_conf[i].data_type != -1; i++)
+static void resetEventBits()
+{
+ int i;
+
+ for (i = 0; i < NUM_CE_BITFIELDS; i++)
+ xx_event_bits[i] = 0;
+}
+
+static void setEventFlagsFromEventBits(struct ElementChangeInfo *change)
+{
+ int i;
+
+ /* important: only change event flag if corresponding event bit is set */
+ for (i = 0; i < NUM_CHANGE_EVENTS; i++)
+ if (xx_event_bits[CH_EVENT_BITFIELD_NR(i)] & CH_EVENT_BIT(i))
+ change->has_event[i] = TRUE;
+}
+
+static void setEventBitsFromEventFlags(struct ElementChangeInfo *change)
+{
+ int i;
+
+ /* important: only change event bit if corresponding event flag is set */
+ for (i = 0; i < NUM_CHANGE_EVENTS; i++)
+ if (change->has_event[i])
+ xx_event_bits[CH_EVENT_BITFIELD_NR(i)] |= CH_EVENT_BIT(i);
+}
+
+static char *getDefaultElementDescription(struct ElementInfo *ei)
+{
+ static char description[MAX_ELEMENT_NAME_LEN + 1];
+ char *default_description = (ei->custom_description != NULL ?
+ ei->custom_description :
+ ei->editor_description);
+ int i;
+
+ /* always start with reliable default values */
+ for (i = 0; i < MAX_ELEMENT_NAME_LEN + 1; i++)
+ description[i] = '\0';
+
+ /* truncate element description to MAX_ELEMENT_NAME_LEN bytes */
+ strncpy(description, default_description, MAX_ELEMENT_NAME_LEN);
+
+ return &description[0];
+}
+
+static void setElementDescriptionToDefault(struct ElementInfo *ei)
+{
+ char *default_description = getDefaultElementDescription(ei);
+ int i;
+
+ for (i = 0; i < MAX_ELEMENT_NAME_LEN + 1; i++)
+ ei->description[i] = default_description[i];
+}
+
+static void setConfigToDefaultsFromConfigList(struct ElementFileConfig *config)
+{
+ int i;
+
+ for (i = 0; config[i].data_type != -1; i++)
{
- int default_value = element_conf[i].default_value;
- int data_type = element_conf[i].data_type;
- int conf_type = element_conf[i].conf_type;
+ int default_value = config[i].default_value;
+ int data_type = config[i].data_type;
+ int conf_type = config[i].conf_type;
int byte_mask = conf_type & CONF_MASK_BYTES;
if (byte_mask == CONF_MASK_MULTI_BYTES)
{
- int default_num_entities = element_conf[i].default_num_entities;
- int max_num_entities = element_conf[i].max_num_entities;
+ int default_num_entities = config[i].default_num_entities;
+ int max_num_entities = config[i].max_num_entities;
- *(int *)(element_conf[i].num_entities) = default_num_entities;
+ *(int *)(config[i].num_entities) = default_num_entities;
- if (data_type == TYPE_ELEMENT_LIST)
+ if (data_type == TYPE_STRING)
{
- int *element_array = (int *)(element_conf[i].value);
+ char *default_string = config[i].default_string;
+ char *string = (char *)(config[i].value);
+
+ strncpy(string, default_string, max_num_entities);
+ }
+ else if (data_type == TYPE_ELEMENT_LIST)
+ {
+ int *element_array = (int *)(config[i].value);
int j;
for (j = 0; j < max_num_entities; j++)
}
else if (data_type == TYPE_CONTENT_LIST)
{
- struct Content *content = (struct Content *)(element_conf[i].value);
+ struct Content *content = (struct Content *)(config[i].value);
int c, x, y;
for (c = 0; c < max_num_entities; c++)
else /* constant size configuration data (1, 2 or 4 bytes) */
{
if (data_type == TYPE_BOOLEAN)
- *(boolean *)(element_conf[i].value) = default_value;
+ *(boolean *)(config[i].value) = default_value;
else
- *(int *) (element_conf[i].value) = default_value;
+ *(int *) (config[i].value) = default_value;
}
}
+}
- *level = li; /* copy temporary buffer back to level data */
+static void copyConfigFromConfigList(struct ElementFileConfig *config)
+{
+ int i;
+
+ for (i = 0; config[i].data_type != -1; i++)
+ {
+ int data_type = config[i].data_type;
+ int conf_type = config[i].conf_type;
+ int byte_mask = conf_type & CONF_MASK_BYTES;
+
+ if (byte_mask == CONF_MASK_MULTI_BYTES)
+ {
+ int max_num_entities = config[i].max_num_entities;
+
+ if (data_type == TYPE_STRING)
+ {
+ char *string = (char *)(config[i].value);
+ char *string_copy = (char *)(config[i].value_copy);
+
+ strncpy(string_copy, string, max_num_entities);
+ }
+ else if (data_type == TYPE_ELEMENT_LIST)
+ {
+ int *element_array = (int *)(config[i].value);
+ int *element_array_copy = (int *)(config[i].value_copy);
+ int j;
+
+ for (j = 0; j < max_num_entities; j++)
+ element_array_copy[j] = element_array[j];
+ }
+ else if (data_type == TYPE_CONTENT_LIST)
+ {
+ struct Content *content = (struct Content *)(config[i].value);
+ struct Content *content_copy = (struct Content *)(config[i].value_copy);
+ int c, x, y;
+
+ for (c = 0; c < max_num_entities; c++)
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ content_copy[c].e[x][y] = content[c].e[x][y];
+ }
+ }
+ else /* constant size configuration data (1, 2 or 4 bytes) */
+ {
+ if (data_type == TYPE_BOOLEAN)
+ *(boolean *)(config[i].value_copy) = *(boolean *)(config[i].value);
+ else
+ *(int *) (config[i].value_copy) = *(int *) (config[i].value);
+ }
+ }
}
+#if 1
+void copyElementInfo(struct ElementInfo *ei_from, struct ElementInfo *ei_to)
+{
+#if 1
+ int i;
+#else
+ int i, x, y;
+#endif
+
+#if 1
+ xx_ei = *ei_from; /* copy element data into temporary buffer */
+ yy_ei = *ei_to; /* copy element data into temporary buffer */
+
+ copyConfigFromConfigList(custom_element_conf);
+
+ *ei_from = xx_ei;
+ *ei_to = yy_ei;
+#endif
+
+#if 0
+ /* ---------- copy element description ---------- */
+ for (i = 0; i < MAX_ELEMENT_NAME_LEN + 1; i++)
+ ei_to->description[i] = ei_from->description[i];
+
+ /* ---------- copy element base properties ---------- */
+ ei_to->properties[EP_BITFIELD_BASE_NR] =
+ ei_from->properties[EP_BITFIELD_BASE_NR];
+
+ /* ---------- copy custom property values ---------- */
+
+ ei_to->use_gfx_element = ei_from->use_gfx_element;
+ ei_to->gfx_element = ei_from->gfx_element;
+
+ ei_to->access_direction = ei_from->access_direction;
+
+ ei_to->collect_score_initial = ei_from->collect_score_initial;
+ ei_to->collect_count_initial = ei_from->collect_count_initial;
+
+ ei_to->ce_value_fixed_initial = ei_from->ce_value_fixed_initial;
+ ei_to->ce_value_random_initial = ei_from->ce_value_random_initial;
+ ei_to->use_last_ce_value = ei_from->use_last_ce_value;
+
+ ei_to->push_delay_fixed = ei_from->push_delay_fixed;
+ ei_to->push_delay_random = ei_from->push_delay_random;
+ ei_to->drop_delay_fixed = ei_from->drop_delay_fixed;
+ ei_to->drop_delay_random = ei_from->drop_delay_random;
+ ei_to->move_delay_fixed = ei_from->move_delay_fixed;
+ ei_to->move_delay_random = ei_from->move_delay_random;
+
+ ei_to->move_pattern = ei_from->move_pattern;
+ ei_to->move_direction_initial = ei_from->move_direction_initial;
+ ei_to->move_stepsize = ei_from->move_stepsize;
+
+ ei_to->move_enter_element = ei_from->move_enter_element;
+ ei_to->move_leave_element = ei_from->move_leave_element;
+ ei_to->move_leave_type = ei_from->move_leave_type;
+
+ ei_to->slippery_type = ei_from->slippery_type;
+
+ ei_to->explosion_type = ei_from->explosion_type;
+ ei_to->explosion_delay = ei_from->explosion_delay;
+ ei_to->ignition_delay = ei_from->ignition_delay;
+
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ ei_to->content.e[x][y] = ei_from->content.e[x][y];
+#endif
+
+ /* ---------- reinitialize and copy change pages ---------- */
+
+ ei_to->num_change_pages = ei_from->num_change_pages;
+ ei_to->current_change_page = ei_from->current_change_page;
+
+ setElementChangePages(ei_to, ei_to->num_change_pages);
+
+ for (i = 0; i < ei_to->num_change_pages; i++)
+ ei_to->change_page[i] = ei_from->change_page[i];
+
+ /* ---------- copy group element info ---------- */
+ if (ei_from->group != NULL && ei_to->group != NULL) /* group or internal */
+ *ei_to->group = *ei_from->group;
+
+ /* mark this custom element as modified */
+ ei_to->modified_settings = TRUE;
+}
+#endif
+
void setElementChangePages(struct ElementInfo *ei, int change_pages)
{
int change_page_size = sizeof(struct ElementChangeInfo);
void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
{
+#if 0
int i, x, y;
+#endif
+
+#if 1
+ xx_change = *change; /* copy change data into temporary buffer */
+ xx_num_contents = 1;
+
+ setConfigToDefaultsFromConfigList(custom_element_change_conf);
+ *change = xx_change;
+
+ resetEventFlags(change);
+#endif
+
+#if 0
change->can_change = FALSE;
for (i = 0; i < NUM_CHANGE_EVENTS; i++)
for (x = 0; x < 3; x++)
for (y = 0; y < 3; y++)
change->target_content.e[x][y] = EL_EMPTY_SPACE;
+#endif
change->direct_action = 0;
change->other_action = 0;
static void setLevelInfoToDefaults(struct LevelInfo *level)
{
static boolean clipboard_elements_initialized = FALSE;
+#if 0
int i, j, x, y;
+#else
+ int i, x, y;
+#endif
#if 1
InitElementPropertiesStatic();
#endif
- setLevelInfoToDefaultsFromConfigList(level);
+#if 1
+ li = *level; /* copy level data into temporary buffer */
+
+ setConfigToDefaultsFromConfigList(element_conf);
+
+ *level = li; /* copy temporary buffer back to level data */
+#endif
+
setLevelInfoToDefaults_EM();
level->native_em_level = &native_em_level;
level->amoeba_content = EL_DIAMOND;
+#if 0
level->game_of_life[0] = 2;
level->game_of_life[1] = 3;
level->game_of_life[2] = 3;
level->biomaze[1] = 3;
level->biomaze[2] = 3;
level->biomaze[3] = 3;
+#endif
#if 0
level->double_speed = FALSE;
level->wind_direction_initial = MV_NONE;
level->ball_random = FALSE;
level->ball_state_initial = FALSE;
+
for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
for (x = 0; x < 3; x++)
for (y = 0; y < 3; y++)
level->ball_content[i].e[x][y] = EL_EMPTY;
-#endif
-#if 0
+
for (i = 0; i < 16; i++)
level->android_array[i] = FALSE;
#endif
int element = i;
struct ElementInfo *ei = &element_info[element];
+#if 1
+ if (IS_CUSTOM_ELEMENT(element) ||
+ IS_GROUP_ELEMENT(element) ||
+ IS_INTERNAL_ELEMENT(element))
+ {
+ xx_ei = *ei; /* copy element data into temporary buffer */
+
+ setConfigToDefaultsFromConfigList(custom_element_conf);
+
+ *ei = xx_ei;
+ }
+#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;
IS_GROUP_ELEMENT(element) ||
IS_INTERNAL_ELEMENT(element))
{
+#if 1
+ setElementDescriptionToDefault(ei);
+#else
for (j = 0; j < MAX_ELEMENT_NAME_LEN + 1; j++)
ei->description[j] = '\0';
strncpy(ei->description, ei->custom_description,MAX_ELEMENT_NAME_LEN);
else
strcpy(ei->description, ei->editor_description);
+#endif
+#if 0
ei->use_gfx_element = FALSE;
ei->gfx_element = EL_EMPTY_SPACE;
+#endif
ei->modified_settings = FALSE;
}
if (IS_CUSTOM_ELEMENT(element) ||
IS_INTERNAL_ELEMENT(element))
{
+#if 0
ei->access_direction = MV_ALL_DIRECTIONS;
ei->collect_score_initial = 10; /* special default */
for (x = 0; x < 3; x++)
for (y = 0; y < 3; y++)
ei->content.e[x][y] = EL_EMPTY_SPACE;
+#endif
ei->access_type = 0;
ei->access_layer = 0;
#endif
#endif
+#if 0
/* now set default properties */
SET_PROPERTY(element, EP_CAN_MOVE_INTO_ACID, TRUE);
+#endif
}
if (IS_GROUP_ELEMENT(element) ||
group = ei->group;
+#if 1
+ xx_group = *group; /* copy group data into temporary buffer */
+
+ setConfigToDefaultsFromConfigList(group_element_conf);
+
+ *group = xx_group;
+#endif
+
+#if 0
for (j = 0; j < MAX_ELEMENTS_IN_GROUP; j++)
group->element[j] = EL_EMPTY_SPACE;
group->num_elements = 1;
group->choice_mode = ANIM_RANDOM;
+#endif
}
}
#if 1
if (IS_CUSTOM_ELEMENT(element))
- element_info[element].properties[EP_BITFIELD_BASE] = properties;
+ element_info[element].properties[EP_BITFIELD_BASE_NR] = properties;
else
Error(ERR_WARN, "invalid custom element number %d", element);
#else
if (IS_CUSTOM_ELEMENT(element))
- Properties[element][EP_BITFIELD_BASE] = properties;
+ Properties[element][EP_BITFIELD_BASE_NR] = properties;
else
Error(ERR_WARN, "invalid custom element number %d", element);
#endif
ei->description[MAX_ELEMENT_NAME_LEN] = 0;
#if 1
- ei->properties[EP_BITFIELD_BASE] = getFile32BitBE(file);
+ ei->properties[EP_BITFIELD_BASE_NR] = getFile32BitBE(file);
#else
- Properties[element][EP_BITFIELD_BASE] = getFile32BitBE(file);
+ Properties[element][EP_BITFIELD_BASE_NR] = getFile32BitBE(file);
#endif
/* some free bytes for future properties and padding */
ei->description[MAX_ELEMENT_NAME_LEN] = 0;
#if 1
- ei->properties[EP_BITFIELD_BASE] = getFile32BitBE(file);
+ ei->properties[EP_BITFIELD_BASE_NR] = getFile32BitBE(file);
#else
- Properties[element][EP_BITFIELD_BASE] = getFile32BitBE(file);
+ Properties[element][EP_BITFIELD_BASE_NR] = getFile32BitBE(file);
#endif
ReadUnusedBytesFromFile(file, 4); /* reserved for more base properties */
int num_bytes = getFile16BitBE(file);
byte *buffer = checked_malloc(num_bytes);
-#if 1
+#if 0
printf("::: - found multi bytes\n");
#endif
element_found = TRUE;
- if (data_type == TYPE_ELEMENT_LIST)
+ if (data_type == TYPE_STRING)
+ {
+ char *string = (char *)(config[i].value);
+ int j;
+
+ for (j = 0; j < max_num_entities; j++)
+ string[j] = (j < num_entities ? buffer[j] : '\0');
+ }
+ else if (data_type == TYPE_ELEMENT_LIST)
{
int *element_array = (int *)(config[i].value);
int j;
byte_mask == CONF_MASK_2_BYTE ? getFile16BitBE(file) :
byte_mask == CONF_MASK_4_BYTE ? getFile32BitBE(file) : 0);
-#if 1
+#if 0
printf("::: - found single bytes\n");
#endif
int element = getFile16BitBE(file);
int real_chunk_size = 2;
struct ElementInfo *ei = &element_info[element];
+ int i;
-#if 1
+#if 0
printf("::: CUSX: loading element '%s' ...\n", EL_NAME(element));
#endif
{
real_chunk_size += LoadLevel_MicroChunk(file, custom_element_conf, -1);
-#if 1
+#if 0
printf("::: - real_chunk_size now %d\n", real_chunk_size);
#endif
EL_NAME(element));
ei->num_change_pages = 1;
+
setElementChangePages(ei, 1);
+ setElementChangeInfoToDefaults(ei->change);
return real_chunk_size;
}
+ /* initialize number of change pages stored for this custom element */
setElementChangePages(ei, ei->num_change_pages);
+ for (i = 0; i < ei->num_change_pages; i++)
+ setElementChangeInfoToDefaults(&ei->change_page[i]);
+ /* start with reading properties for the first change page */
xx_current_change_page = 0;
- xx_event_bits_0_31 = 0;
- xx_event_bits_32_63 = 0;
-
while (!feof(file))
{
struct ElementChangeInfo *change = &ei->change_page[xx_current_change_page];
- int i;
xx_change = *change; /* copy change data into temporary buffer */
+ resetEventBits(); /* reset bits; change page might have changed */
+
real_chunk_size += LoadLevel_MicroChunk(file,custom_element_change_conf,-1);
*change = xx_change;
- for (i = 0; i < NUM_CHANGE_EVENTS; i++)
- if ((i < 32 && xx_event_bits_0_31 & (1 << i)) ||
- (i >= 32 && xx_event_bits_32_63 & (1 << (i - 32))))
- change->has_event[i] = TRUE;
-
- xx_event_bits_0_31 = 0;
- xx_event_bits_32_63 = 0;
+ setEventFlagsFromEventBits(change);
if (real_chunk_size >= chunk_size)
break;
#if 1
struct ElementInfo *ei = &element_info[element];
- if (ei->properties[EP_BITFIELD_BASE] != EP_BITMASK_DEFAULT)
+ 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]);
+ putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
}
check++;
}
#else
- if (Properties[element][EP_BITFIELD_BASE] != EP_BITMASK_DEFAULT)
+ if (Properties[element][EP_BITFIELD_BASE_NR] != EP_BITMASK_DEFAULT)
{
if (check < num_changed_custom_elements)
{
putFile16BitBE(file, element);
- putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
+ putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE_NR]);
}
check++;
putFile8Bit(file, ei->description[j]);
#if 1
- putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE]);
+ putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
#else
- putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
+ putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE_NR]);
#endif
/* some free bytes for future properties and padding */
}
#endif
+#if 0
static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
{
struct ElementInfo *ei = &element_info[element];
putFile8Bit(file, ei->description[i]);
#if 1
- putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE]);
+ putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
#else
- putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
+ putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE_NR]);
#endif
WriteUnusedBytesToFile(file, 4); /* reserved for more base properties */
putFile8Bit(file, event_bits);
}
}
+#endif
+#if 0
static void SaveLevel_GRP1(FILE *file, struct LevelInfo *level, int element)
{
struct ElementInfo *ei = &element_info[element];
for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
putFile16BitBE(file, group->element[i]);
}
+#endif
+
+static int SaveLevel_MicroChunk(FILE *file, struct ElementFileConfig *entry)
+{
+ 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;
+
+ if (!modified) /* do not save unmodified default settings */
+ return 0;
+
+ if (element != -1)
+ 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);
+
+ return num_bytes;
+ }
+ 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;
+
+ if (!modified) /* do not save unmodified default settings */
+ return 0;
+
+ if (element != -1)
+ 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]);
+
+ return num_bytes;
+ }
+ 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;
+
+ if (!modified) /* do not save unmodified default settings */
+ return 0;
+
+ if (element != -1)
+ 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]);
+
+ return num_bytes;
+ }
+ 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;
+
+ if (!modified) /* do not save unmodified default settings */
+ return 0;
+
+ if (element != -1)
+ 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;
+ }
+
+ return 0;
+}
+
+#if 0
static int SaveLevel_MicroChunk_SingleValue(FILE *file,
struct ElementFileConfig *entry)
return num_bytes;
}
+#endif
+
static int SaveLevel_CONF(FILE *file, struct LevelInfo *level)
{
int chunk_size = 0;
for (i = 0; element_conf[i].data_type != -1; i++)
{
+#if 1
+ chunk_size += SaveLevel_MicroChunk(file, &element_conf[i]);
+#else
struct ElementFileConfig *config = &element_conf[i];
int data_type = config->data_type;
int conf_type = config->conf_type;
chunk_size += SaveLevel_MicroChunk_ElementList(file, config);
else if (data_type == TYPE_CONTENT_LIST)
chunk_size += SaveLevel_MicroChunk_ContentList(file, config);
+#endif
}
return chunk_size;
{
struct ElementInfo *ei = &element_info[element];
int chunk_size = 0;
- int i;
+ int i, j;
chunk_size += putFile16BitBE(file, element);
xx_ei = *ei; /* copy element data into temporary buffer */
- xx_num_description_bytes = MAX_ELEMENT_NAME_LEN;
+ /* set default description string for this specific element */
+ strcpy(xx_default_description, getDefaultElementDescription(ei));
+
+ /* set (fixed) number of content areas (may have been overwritten earlier) */
xx_num_contents = 1;
#if 0
#endif
for (i = 0; custom_element_conf[i].data_type != -1; i++)
- {
- struct ElementFileConfig *config = &custom_element_conf[i];
- int data_type = config->data_type;
- int conf_type = config->conf_type;
- int byte_mask = conf_type & CONF_MASK_BYTES;
-
- if (byte_mask != CONF_MASK_MULTI_BYTES)
- chunk_size += SaveLevel_MicroChunk_SingleValue(file, config);
- else if (data_type == TYPE_ELEMENT_LIST)
- chunk_size += SaveLevel_MicroChunk_ElementList(file, config);
- else if (data_type == TYPE_CONTENT_LIST)
- chunk_size += SaveLevel_MicroChunk_ContentList(file, config);
- }
+ chunk_size += SaveLevel_MicroChunk(file, &custom_element_conf[i]);
#if 0
printf("::: - change pages\n");
i, xx_change.action_arg);
#endif
- xx_event_bits_0_31 = 0;
- xx_event_bits_32_63 = 0;
+ resetEventBits();
+ setEventBitsFromEventFlags(change);
- for (i = 0; i < NUM_CHANGE_EVENTS; i++)
- {
- if (change->has_event[i])
- {
- if (i < 32)
- xx_event_bits_0_31 |= (1 << i);
- else
- xx_event_bits_32_63 |= (1 << (i - 32));
- }
- }
+ for (j = 0; custom_element_change_conf[j].data_type != -1; j++)
+ chunk_size += SaveLevel_MicroChunk(file, &custom_element_change_conf[j]);
- for (i = 0; custom_element_change_conf[i].data_type != -1; i++)
- {
- struct ElementFileConfig *config = &custom_element_change_conf[i];
- int data_type = config->data_type;
- int conf_type = config->conf_type;
- int byte_mask = conf_type & CONF_MASK_BYTES;
-
- if (byte_mask != CONF_MASK_MULTI_BYTES)
- chunk_size += SaveLevel_MicroChunk_SingleValue(file, config);
- else if (data_type == TYPE_ELEMENT_LIST)
- chunk_size += SaveLevel_MicroChunk_ElementList(file, config);
- else if (data_type == TYPE_CONTENT_LIST)
- chunk_size += SaveLevel_MicroChunk_ContentList(file, config);
- }
+#if 0
+ if (element == EL_CUSTOM_START)
+ printf("::: - saving change page %d / %d (%d bytes)\n",
+ i, ei->num_change_pages, chunk_size);
+#endif
}
return chunk_size;
xx_ei = *ei; /* copy element data into temporary buffer */
xx_group = *group; /* copy group data into temporary buffer */
- xx_num_description_bytes = MAX_ELEMENT_NAME_LEN;
- xx_num_contents = 1;
+ /* set default description string for this specific element */
+ strcpy(xx_default_description, getDefaultElementDescription(ei));
for (i = 0; group_element_conf[i].data_type != -1; i++)
- {
- struct ElementFileConfig *config = &group_element_conf[i];
- int data_type = config->data_type;
- int conf_type = config->conf_type;
- int byte_mask = conf_type & CONF_MASK_BYTES;
-
- if (byte_mask != CONF_MASK_MULTI_BYTES)
- chunk_size += SaveLevel_MicroChunk_SingleValue(file, config);
- else if (data_type == TYPE_ELEMENT_LIST)
- chunk_size += SaveLevel_MicroChunk_ElementList(file, config);
- else if (data_type == TYPE_CONTENT_LIST)
- chunk_size += SaveLevel_MicroChunk_ContentList(file, config);
- }
+ chunk_size += SaveLevel_MicroChunk(file, &group_element_conf[i]);
return chunk_size;
}
/* if not using template level, check for non-default custom/group elements */
if (!level->use_custom_template)
{
-#if 1
+#if 0
for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
{
int element = EL_CUSTOM_START + i;
SaveLevel_CUS4(file, level, element);
}
}
-#endif
-#if 1
for (i = 0; i < NUM_GROUP_ELEMENTS; i++)
{
int element = EL_GROUP_START + i;
putFileChunkBE(file, "CUSX", cusx_chunk_size);
SaveLevel_CUSX(file, level, element);
}
-
-#if 0
- if (i == 1)
- break;
-#endif
}
-#endif
-#if 1
for (i = 0; i < NUM_GROUP_ELEMENTS; i++)
{
int element = EL_GROUP_START + i;
putFileChunkBE(file, "GRPX", grpx_chunk_size);
SaveLevel_GRPX(file, level, element);
}
-
-#if 0
- if (i == 1)
- break;
-#endif
}
#endif
}