rnd-20060805-5-src
[rocksndiamonds.git] / src / files.c
index 5f5b1fbb0517d71c2c03b5a089a4c79c36d3cde2..4a89c9b2d9870e686caa4f76a39663657870be60 100644 (file)
@@ -227,8 +227,8 @@ static struct LevelFileConfigInfo chunk_config_INFO[] =
   {
     -1,                                        -1,
     -1,                                        -1,
-    NULL,                              -1,
-  },
+    NULL,                              -1
+  }
 };
 
 static struct LevelFileConfigInfo chunk_config_ELEM[] =
@@ -722,8 +722,8 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
   {
     -1,                                        -1,
     -1,                                        -1,
-    NULL,                              -1,
-  },
+    NULL,                              -1
+  }
 };
 
 static struct LevelFileConfigInfo chunk_config_NOTE[] =
@@ -750,8 +750,8 @@ static struct LevelFileConfigInfo chunk_config_NOTE[] =
   {
     -1,                                        -1,
     -1,                                        -1,
-    NULL,                              -1,
-  },
+    NULL,                              -1
+  }
 };
 
 static struct LevelFileConfigInfo chunk_config_CUSX_base[] =
@@ -956,7 +956,7 @@ static struct LevelFileConfigInfo chunk_config_CUSX_base[] =
     -1,                                        -1,
     NULL,                              -1,
     NULL
-  },
+  }
 };
 
 static struct LevelFileConfigInfo chunk_config_CUSX_change[] =
@@ -1094,8 +1094,8 @@ static struct LevelFileConfigInfo chunk_config_CUSX_change[] =
   {
     -1,                                        -1,
     -1,                                        -1,
-    NULL,                              -1,
-  },
+    NULL,                              -1
+  }
 };
 
 static struct LevelFileConfigInfo chunk_config_GRPX[] =
@@ -1135,8 +1135,63 @@ 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
@@ -1683,6 +1738,11 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
     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;
@@ -1705,11 +1765,6 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
     }
 #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);
 
@@ -3010,6 +3065,28 @@ static int LoadLevel_INFO(FILE *file, int chunk_size, struct LevelInfo *level)
   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;
@@ -3358,6 +3435,7 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
       { "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 },
@@ -4665,7 +4743,7 @@ void LoadLevelFromFilename(struct LevelInfo *level, char *filename)
 
 static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
 {
-  int i;
+  int i, j;
 
   if (leveldir_current == NULL)                /* only when dumping level */
     return;
@@ -4762,8 +4840,6 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
   /* trigger settings did not exist before 3.1.0; set to default "any" */
   if (level->game_version < VERSION_IDENT(3,1,0,0))
   {
-    int i, j;
-
     /* correct "can move into acid" settings (all zero in old levels) */
 
     level->can_move_into_acid_bits = 0; /* nothing can move into acid */
@@ -4793,6 +4869,30 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
       }
     }
   }
+
+#if 1
+  /* try to detect and fix "Snake Bite" levels, which are broken with 3.2.0 */
+  {
+    int element = EL_CUSTOM_START + 255;
+    struct ElementInfo *ei = &element_info[element];
+    struct ElementChangeInfo *change = &ei->change_page[0];
+
+    /* This is needed to fix a problem that was caused by a bugfix in function
+       game.c/CreateFieldExt() introduced with 3.2.0 that corrects the behaviour
+       when a custom element changes to EL_SOKOBAN_FIELD_PLAYER (before, it did
+       not replace walkable elements, but instead just placed the player on it,
+       without placing the Sokoban field under the player). Unfortunately, this
+       breaks "Snake Bite" style levels when the snake is halfway through a door
+       that just closes (the snake head is still alive and can be moved in this
+       case). This can be fixed by replacing the EL_SOKOBAN_FIELD_PLAYER by the
+       player (without Sokoban element) which then gets killed as designed). */
+
+    if ((strncmp(leveldir_current->identifier, "snake_bite", 10) == 0 ||
+        strncmp(ei->description, "pause b4 death", 14) == 0) &&
+       change->target_element == EL_SOKOBAN_FIELD_PLAYER)
+      change->target_element = EL_PLAYER_1;
+  }
+#endif
 }
 
 static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
@@ -6775,19 +6875,20 @@ void SaveScore(int nr)
 #define SETUP_TOKEN_SKIP_LEVELS                        14
 #define SETUP_TOKEN_TIME_LIMIT                 15
 #define SETUP_TOKEN_FULLSCREEN                 16
-#define SETUP_TOKEN_ASK_ON_ESCAPE              17
-#define SETUP_TOKEN_ASK_ON_ESCAPE_EDITOR       18
-#define SETUP_TOKEN_QUICK_SWITCH               19
-#define SETUP_TOKEN_INPUT_ON_FOCUS             20
-#define SETUP_TOKEN_PREFER_AGA_GRAPHICS                21
-#define SETUP_TOKEN_GRAPHICS_SET               22
-#define SETUP_TOKEN_SOUNDS_SET                 23
-#define SETUP_TOKEN_MUSIC_SET                  24
-#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS    25
-#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS      26
-#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC       27
-
-#define NUM_GLOBAL_SETUP_TOKENS                        28
+#define SETUP_TOKEN_FULLSCREEN_MODE            17
+#define SETUP_TOKEN_ASK_ON_ESCAPE              18
+#define SETUP_TOKEN_ASK_ON_ESCAPE_EDITOR       19
+#define SETUP_TOKEN_QUICK_SWITCH               20
+#define SETUP_TOKEN_INPUT_ON_FOCUS             21
+#define SETUP_TOKEN_PREFER_AGA_GRAPHICS                22
+#define SETUP_TOKEN_GRAPHICS_SET               23
+#define SETUP_TOKEN_SOUNDS_SET                 24
+#define SETUP_TOKEN_MUSIC_SET                  25
+#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS    26
+#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS      27
+#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC       28
+
+#define NUM_GLOBAL_SETUP_TOKENS                        29
 
 /* editor setup */
 #define SETUP_TOKEN_EDITOR_EL_BOULDERDASH      0
@@ -6803,9 +6904,11 @@ void SaveScore(int nr)
 #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
@@ -6819,8 +6922,8 @@ void SaveScore(int nr)
 #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
@@ -6896,6 +6999,7 @@ static struct TokenInfo global_setup_tokens[] =
   { TYPE_SWITCH, &si.skip_levels,      "skip_levels"                   },
   { TYPE_SWITCH, &si.time_limit,       "time_limit"                    },
   { TYPE_SWITCH, &si.fullscreen,       "fullscreen"                    },
+  { TYPE_STRING, &si.fullscreen_mode,  "fullscreen_mode"               },
   { TYPE_SWITCH, &si.ask_on_escape,    "ask_on_escape"                 },
   { TYPE_SWITCH, &si.ask_on_escape_editor, "ask_on_escape_editor"      },
   { TYPE_SWITCH, &si.quick_switch,     "quick_player_switch"           },
@@ -6909,8 +7013,19 @@ static struct TokenInfo global_setup_tokens[] =
   { TYPE_SWITCH, &si.override_level_music,    "override_level_music"   },
 };
 
+static boolean not_used = FALSE;
 static struct TokenInfo editor_setup_tokens[] =
 {
+#if 1
+  { TYPE_SWITCH, &not_used,            "editor.el_boulderdash"         },
+  { TYPE_SWITCH, &not_used,            "editor.el_emerald_mine"        },
+  { TYPE_SWITCH, &not_used,            "editor.el_emerald_mine_club"   },
+  { TYPE_SWITCH, &not_used,            "editor.el_more"                },
+  { TYPE_SWITCH, &not_used,            "editor.el_sokoban"             },
+  { TYPE_SWITCH, &not_used,            "editor.el_supaplex"            },
+  { TYPE_SWITCH, &not_used,            "editor.el_diamond_caves"       },
+  { TYPE_SWITCH, &not_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"},
@@ -6919,11 +7034,18 @@ static struct TokenInfo editor_setup_tokens[] =
   { 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, &not_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"   },
 };
 
@@ -6940,6 +7062,7 @@ static struct TokenInfo editor_cascade_setup_tokens[] =
   { 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"     },
 };
@@ -7026,6 +7149,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->skip_levels = TRUE;
   si->time_limit = TRUE;
   si->fullscreen = FALSE;
+  si->fullscreen_mode = getStringCopy(DEFAULT_FULLSCREEN_MODE);
   si->ask_on_escape = TRUE;
   si->ask_on_escape_editor = TRUE;
   si->quick_switch = FALSE;
@@ -7106,6 +7230,7 @@ static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si)
   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;
 }
@@ -7332,7 +7457,7 @@ void SaveSetup_EditorCascade()
 
   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);