added new screen definition for global animations in the hall of fame
[rocksndiamonds.git] / src / files.c
index bffb16052eab5ce67593c85d8296d430d0bd57ed..a2efae2a1874ceacf48a4210c472ebcbe193e867 100644 (file)
@@ -51,6 +51,7 @@
 
 // (element number only)
 #define LEVEL_CHUNK_GRPX_UNCHANGED     2
+#define LEVEL_CHUNK_EMPX_UNCHANGED     2
 #define LEVEL_CHUNK_NOTE_UNCHANGED     2
 
 // (nothing at all if unchanged)
@@ -1376,6 +1377,26 @@ static struct LevelFileConfigInfo chunk_config_GRPX[] =
   }
 };
 
+static struct LevelFileConfigInfo chunk_config_EMPX[] =
+{
+  {
+    -1,                                        -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &xx_ei.use_gfx_element,            FALSE
+  },
+  {
+    -1,                                        -1,
+    TYPE_ELEMENT,                      CONF_VALUE_16_BIT(1),
+    &xx_ei.gfx_element_initial,                EL_EMPTY_SPACE
+  },
+
+  {
+    -1,                                        -1,
+    -1,                                        -1,
+    NULL,                              -1
+  }
+};
+
 static struct LevelFileConfigInfo chunk_config_CONF[] =                // (OBSOLETE)
 {
   {
@@ -1893,6 +1914,16 @@ static void setLevelInfoToDefaults_Elements(struct LevelInfo *level)
 
       *group = xx_group;
     }
+
+    if (IS_EMPTY_ELEMENT(element) ||
+       IS_INTERNAL_ELEMENT(element))
+    {
+      xx_ei = *ei;             // copy element data into temporary buffer
+
+      setConfigToDefaultsFromConfigList(chunk_config_EMPX);
+
+      *ei = xx_ei;
+    }
   }
 
   clipboard_elements_initialized = TRUE;
@@ -3372,6 +3403,30 @@ static int LoadLevel_GRPX(File *file, int chunk_size, struct LevelInfo *level)
   return real_chunk_size;
 }
 
+static int LoadLevel_EMPX(File *file, int chunk_size, struct LevelInfo *level)
+{
+  int element = getMappedElement(getFile16BitBE(file));
+  int real_chunk_size = 2;
+  struct ElementInfo *ei = &element_info[element];
+
+  xx_ei = *ei;         // copy element data into temporary buffer
+
+  while (!checkEndOfFile(file))
+  {
+    real_chunk_size += LoadLevel_MicroChunk(file, chunk_config_EMPX,
+                                           -1, element);
+
+    if (real_chunk_size >= chunk_size)
+      break;
+  }
+
+  *ei = xx_ei;
+
+  level->file_has_custom_elements = TRUE;
+
+  return real_chunk_size;
+}
+
 static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
                                      struct LevelFileInfo *level_file_info,
                                      boolean level_info_only)
@@ -3494,6 +3549,7 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
       { "NOTE", -1,                    LoadLevel_NOTE },
       { "CUSX", -1,                    LoadLevel_CUSX },
       { "GRPX", -1,                    LoadLevel_GRPX },
+      { "EMPX", -1,                    LoadLevel_EMPX },
 
       {  NULL,  0,                     NULL }
     };
@@ -7538,6 +7594,22 @@ static int SaveLevel_GRPX(FILE *file, struct LevelInfo *level, int element)
   return chunk_size;
 }
 
+static int SaveLevel_EMPX(FILE *file, struct LevelInfo *level, int element)
+{
+  struct ElementInfo *ei = &element_info[element];
+  int chunk_size = 0;
+  int i;
+
+  chunk_size += putFile16BitBE(file, element);
+
+  xx_ei = *ei;         // copy element data into temporary buffer
+
+  for (i = 0; chunk_config_EMPX[i].data_type != -1; i++)
+    chunk_size += SaveLevel_MicroChunk(file, &chunk_config_EMPX[i], FALSE);
+
+  return chunk_size;
+}
+
 static void SaveLevelFromFilename(struct LevelInfo *level, char *filename,
                                  boolean save_as_template)
 {
@@ -7629,6 +7701,18 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename,
        SaveLevel_GRPX(file, level, element);
       }
     }
+
+    for (i = 0; i < NUM_EMPTY_ELEMENTS_ALL; i++)
+    {
+      int element = GET_EMPTY_ELEMENT(i);
+
+      chunk_size = SaveLevel_EMPX(NULL, level, element);
+      if (chunk_size > LEVEL_CHUNK_EMPX_UNCHANGED)     // save if changed
+      {
+       putFileChunkBE(file, "EMPX", chunk_size);
+       SaveLevel_EMPX(file, level, element);
+      }
+    }
   }
 
   fclose(file);
@@ -8566,6 +8650,13 @@ static void setScoreInfoToDefaultsExt(struct ScoreInfo *scores)
     strcpy(scores->entry[i].name, EMPTY_PLAYER_NAME);
     scores->entry[i].score = 0;
     scores->entry[i].time = 0;
+
+    scores->entry[i].id = -1;
+    strcpy(scores->entry[i].tape_date,    UNKNOWN_NAME);
+    strcpy(scores->entry[i].platform,     UNKNOWN_NAME);
+    strcpy(scores->entry[i].version,      UNKNOWN_NAME);
+    strcpy(scores->entry[i].country_name, UNKNOWN_NAME);
+    strcpy(scores->entry[i].country_code, "??");
   }
 
   scores->num_entries = 0;
@@ -8721,6 +8812,18 @@ static int LoadScore_SCOR(File *file, int chunk_size, struct ScoreInfo *scores)
   return chunk_size;
 }
 
+static int LoadScore_SC4R(File *file, int chunk_size, struct ScoreInfo *scores)
+{
+  int i;
+
+  for (i = 0; i < scores->num_entries; i++)
+    scores->entry[i].score = getFile32BitBE(file);
+
+  chunk_size = scores->num_entries * 4;
+
+  return chunk_size;
+}
+
 static int LoadScore_TIME(File *file, int chunk_size, struct ScoreInfo *scores)
 {
   int i;
@@ -8822,6 +8925,7 @@ void LoadScore(int nr)
       { "INFO", -1,                    LoadScore_INFO },
       { "NAME", -1,                    LoadScore_NAME },
       { "SCOR", -1,                    LoadScore_SCOR },
+      { "SC4R", -1,                    LoadScore_SC4R },
       { "TIME", -1,                    LoadScore_TIME },
       { "TAPE", -1,                    LoadScore_TAPE },
 
@@ -8941,6 +9045,14 @@ static void SaveScore_SCOR(FILE *file, struct ScoreInfo *scores)
     putFile16BitBE(file, scores->entry[i].score);
 }
 
+static void SaveScore_SC4R(FILE *file, struct ScoreInfo *scores)
+{
+  int i;
+
+  for (i = 0; i < scores->num_entries; i++)
+    putFile32BitBE(file, scores->entry[i].score);
+}
+
 static void SaveScore_TIME(FILE *file, struct ScoreInfo *scores)
 {
   int i;
@@ -8968,8 +9080,11 @@ static void SaveScoreToFilename(char *filename)
   int info_chunk_size;
   int name_chunk_size;
   int scor_chunk_size;
+  int sc4r_chunk_size;
   int time_chunk_size;
   int tape_chunk_size;
+  boolean has_large_score_values;
+  int i;
 
   if (!(file = fopen(filename, MODE_WRITE)))
   {
@@ -8981,9 +9096,15 @@ static void SaveScoreToFilename(char *filename)
   info_chunk_size = 2 + (strlen(scores.level_identifier) + 1) + 2 + 2;
   name_chunk_size = scores.num_entries * MAX_PLAYER_NAME_LEN;
   scor_chunk_size = scores.num_entries * 2;
+  sc4r_chunk_size = scores.num_entries * 4;
   time_chunk_size = scores.num_entries * 4;
   tape_chunk_size = scores.num_entries * MAX_SCORE_TAPE_BASENAME_LEN;
 
+  has_large_score_values = FALSE;
+  for (i = 0; i < scores.num_entries; i++)
+    if (scores.entry[i].score > 0xffff)
+      has_large_score_values = TRUE;
+
   putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
   putFileChunkBE(file, "SCOR", CHUNK_SIZE_NONE);
 
@@ -8996,8 +9117,16 @@ static void SaveScoreToFilename(char *filename)
   putFileChunkBE(file, "NAME", name_chunk_size);
   SaveScore_NAME(file, &scores);
 
-  putFileChunkBE(file, "SCOR", scor_chunk_size);
-  SaveScore_SCOR(file, &scores);
+  if (has_large_score_values)
+  {
+    putFileChunkBE(file, "SC4R", sc4r_chunk_size);
+    SaveScore_SC4R(file, &scores);
+  }
+  else
+  {
+    putFileChunkBE(file, "SCOR", scor_chunk_size);
+    SaveScore_SCOR(file, &scores);
+  }
 
   putFileChunkBE(file, "TIME", time_chunk_size);
   SaveScore_TIME(file, &scores);
@@ -9321,6 +9450,12 @@ static void LoadServerScoreFromCache(int nr)
     { &score_entry.time,               FALSE,  0                       },
     { score_entry.name,                        TRUE,   MAX_PLAYER_NAME_LEN     },
     { score_entry.tape_basename,       TRUE,   MAX_FILENAME_LEN        },
+    { score_entry.tape_date,           TRUE,   MAX_ISO_DATE_LEN        },
+    { &score_entry.id,                 FALSE,  0                       },
+    { score_entry.platform,            TRUE,   MAX_PLATFORM_TEXT_LEN   },
+    { score_entry.version,             TRUE,   MAX_VERSION_TEXT_LEN    },
+    { score_entry.country_code,                TRUE,   MAX_COUNTRY_CODE_LEN    },
+    { score_entry.country_name,                TRUE,   MAX_COUNTRY_NAME_LEN    },
 
     { NULL,                            FALSE,  0                       }
   };
@@ -9854,6 +9989,10 @@ static struct TokenInfo global_setup_tokens[] =
     TYPE_SWITCH,
     &setup.autorecord,                         "automatic_tape_recording"
   },
+  {
+    TYPE_SWITCH,
+    &setup.auto_pause_on_start,                        "auto_pause_on_start"
+  },
   {
     TYPE_SWITCH,
     &setup.show_titlescreen,                   "show_titlescreen"
@@ -10242,6 +10381,14 @@ static struct TokenInfo shortcut_setup_tokens[] =
     TYPE_KEY_X11,
     &setup.shortcut.load_game,                 "shortcut.load_game"
   },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.restart_game,              "shortcut.restart_game"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.pause_before_end,          "shortcut.pause_before_end"
+  },
   {
     TYPE_KEY_X11,
     &setup.shortcut.toggle_pause,              "shortcut.toggle_pause"
@@ -10664,6 +10811,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->engine_snapshot_memory = SNAPSHOT_MEMORY_DEFAULT;
   si->fade_screens = TRUE;
   si->autorecord = TRUE;
+  si->auto_pause_on_start = FALSE;
   si->show_titlescreen = TRUE;
   si->quick_doors = FALSE;
   si->team_mode = FALSE;
@@ -10800,6 +10948,8 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
 
   si->shortcut.save_game       = DEFAULT_KEY_SAVE_GAME;
   si->shortcut.load_game       = DEFAULT_KEY_LOAD_GAME;
+  si->shortcut.restart_game    = DEFAULT_KEY_RESTART_GAME;
+  si->shortcut.pause_before_end        = DEFAULT_KEY_PAUSE_BEFORE_END;
   si->shortcut.toggle_pause    = DEFAULT_KEY_TOGGLE_PAUSE;
 
   si->shortcut.focus_player[0] = DEFAULT_KEY_FOCUS_PLAYER_1;
@@ -12100,14 +12250,18 @@ static int get_token_parameter_value(char *token, char *value_raw)
   return get_parameter_value(value_raw, suffix, TYPE_INTEGER);
 }
 
-void InitMenuDesignSettings_Static(void)
+void InitMenuDesignSettings_FromHash(SetupFileHash *setup_file_hash,
+                                    boolean ignore_defaults)
 {
   int i;
 
-  // always start with reliable default values from static default config
   for (i = 0; image_config_vars[i].token != NULL; i++)
   {
-    char *value = getHashEntry(image_config_hash, image_config_vars[i].token);
+    char *value = getHashEntry(setup_file_hash, image_config_vars[i].token);
+
+    // (ignore definitions set to "[DEFAULT]" which are already initialized)
+    if (ignore_defaults && strEqual(value, ARG_DEFAULT))
+      continue;
 
     if (value != NULL)
       *image_config_vars[i].value =
@@ -12115,6 +12269,12 @@ void InitMenuDesignSettings_Static(void)
   }
 }
 
+void InitMenuDesignSettings_Static(void)
+{
+  // always start with reliable default values from static default config
+  InitMenuDesignSettings_FromHash(image_config_hash, FALSE);
+}
+
 static void InitMenuDesignSettings_SpecialPreProcessing(void)
 {
   int i;
@@ -12913,15 +13073,7 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
       *menu_config_players[i].value = TRUE;
 
   // read (and overwrite with) values that may be specified in config file
-  for (i = 0; image_config_vars[i].token != NULL; i++)
-  {
-    char *value = getHashEntry(setup_file_hash, image_config_vars[i].token);
-
-    // (ignore definitions set to "[DEFAULT]" which are already initialized)
-    if (value != NULL && !strEqual(value, ARG_DEFAULT))
-      *image_config_vars[i].value =
-       get_token_parameter_value(image_config_vars[i].token, value);
-  }
+  InitMenuDesignSettings_FromHash(setup_file_hash, TRUE);
 
   freeSetupFileHash(setup_file_hash);
 }