rnd-20061119-1-src
[rocksndiamonds.git] / src / files.c
index deff36d69d6824171a8b05abd1aa573c420f5100..4dc5608aed5d1cf2560bbd941ae2a6783313074b 100644 (file)
@@ -1249,7 +1249,11 @@ static void setEventFlagsFromEventBits(struct ElementChangeInfo *change)
 {
   int i;
 
-  /* important: only change event flag if corresponding event bit is set */
+  /* important: only change event flag if corresponding event bit is set
+     (this is because all xx_event_bits[] values are loaded separately,
+     and all xx_event_bits[] values are set back to zero before loading
+     another value xx_event_bits[x] (each value representing 32 flags)) */
+
   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;
@@ -1259,7 +1263,11 @@ static void setEventBitsFromEventFlags(struct ElementChangeInfo *change)
 {
   int i;
 
-  /* important: only change event bit if corresponding event flag is set */
+  /* in contrast to the above function setEventFlagsFromEventBits(), it
+     would also be possible to set all bits in xx_event_bits[] to 0 or 1
+     depending on the corresponding change->has_event[i] values here, as
+     all xx_event_bits[] values are reset in resetEventBits() before */
+
   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);
@@ -1446,7 +1454,11 @@ void setElementChangePages(struct ElementInfo *ei, int change_pages)
 void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
 {
   xx_change = *change;         /* copy change data into temporary buffer */
+
+#if 0
+  /* (not needed; set by setConfigToDefaultsFromConfigList()) */
   xx_num_contents = 1;
+#endif
 
   setConfigToDefaultsFromConfigList(chunk_config_CUSX_change);
 
@@ -2606,7 +2618,21 @@ static int LoadLevel_MicroChunk(FILE *file, struct LevelFileConfigInfo *conf,
          num_entities = max_num_entities;
        }
 
-       *(int *)(conf[i].num_entities) = num_entities;
+       if (num_entities == 0 && (data_type == TYPE_ELEMENT_LIST ||
+                                 data_type == TYPE_CONTENT_LIST))
+       {
+         /* for element and content lists, zero entities are not allowed */
+         Error(ERR_WARN, "found empty list of entities for element %d",
+               element);
+
+         /* do not set "num_entities" here to prevent reading behind buffer */
+
+         *(int *)(conf[i].num_entities) = 1;   /* at least one is required */
+       }
+       else
+       {
+         *(int *)(conf[i].num_entities) = num_entities;
+       }
 
        element_found = TRUE;
 
@@ -5120,8 +5146,11 @@ static int SaveLevel_CUSX(FILE *file, struct LevelInfo *level, int element)
   /* 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) */
+#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);
@@ -5276,6 +5305,25 @@ void SaveLevelTemplate()
   SaveLevelFromFilename(&level, filename);
 }
 
+boolean SaveLevelChecked(int nr)
+{
+  char *filename = getDefaultLevelFilename(nr);
+  boolean new_level = !fileExists(filename);
+  boolean level_saved = FALSE;
+
+  if (new_level || Request("Save this level and kill the old ?", REQ_ASK))
+  {
+    SaveLevel(nr);
+
+    if (new_level)
+      Request("Level saved !", REQ_CONFIRM);
+
+    level_saved = TRUE;
+  }
+
+  return level_saved;
+}
+
 void DumpLevel(struct LevelInfo *level)
 {
   if (level->no_valid_file)
@@ -5704,7 +5752,9 @@ void SaveTape(int nr)
 {
   char *filename = getTapeFilename(nr);
   FILE *file;
+#if 0
   boolean new_tape = TRUE;
+#endif
   int num_participating_players = 0;
   int info_chunk_size;
   int body_chunk_size;
@@ -5712,6 +5762,7 @@ void SaveTape(int nr)
 
   InitTapeDirectory(leveldir_current->subdir);
 
+#if 0
   /* if a tape still exists, ask to overwrite it */
   if (fileExists(filename))
   {
@@ -5719,6 +5770,7 @@ void SaveTape(int nr)
     if (!Request("Replace old tape ?", REQ_ASK))
       return;
   }
+#endif
 
   if (!(file = fopen(filename, MODE_WRITE)))
   {
@@ -5758,8 +5810,29 @@ void SaveTape(int nr)
 
   tape.changed = FALSE;
 
+#if 0
   if (new_tape)
     Request("Tape saved !", REQ_CONFIRM);
+#endif
+}
+
+boolean SaveTapeChecked(int nr)
+{
+  char *filename = getTapeFilename(nr);
+  boolean new_tape = !fileExists(filename);
+  boolean tape_saved = FALSE;
+
+  if (new_tape || Request("Replace old tape ?", REQ_ASK))
+  {
+    SaveTape(nr);
+
+    if (new_tape)
+      Request("Tape saved !", REQ_CONFIRM);
+
+    tape_saved = TRUE;
+  }
+
+  return tape_saved;
 }
 
 void DumpTape(struct TapeInfo *tape)
@@ -6575,6 +6648,18 @@ static void LoadSpecialMenuDesignSettingsFromFilename(char *filename)
       menu.list_size[i] = get_integer_from_string(list_size);
   }
 
+  /* special case: initialize with default values that may be overwritten */
+  for (i = 0; i < NUM_SPECIAL_GFX_INFO_ARGS; i++)
+  {
+    char *value_x = getHashEntry(setup_file_hash, "menu.draw_xoffset.INFO");
+    char *value_y = getHashEntry(setup_file_hash, "menu.draw_yoffset.INFO");
+
+    if (value_x != NULL)
+      menu.draw_xoffset_info[i] = get_integer_from_string(value_x);
+    if (value_y != NULL)
+      menu.draw_yoffset_info[i] = get_integer_from_string(value_y);
+  }
+
   /* read (and overwrite with) values that may be specified in config file */
   for (i = 0; image_config_vars[i].token != NULL; i++)
   {