rnd-20030304-1-src
[rocksndiamonds.git] / src / files.c
index f4c2065d6e0f86f4e464e9413871697ee79ab66b..a0e203572a7b13ad69de974a15fbe51f6e0c96f5 100644 (file)
@@ -94,8 +94,16 @@ static void setLevelInfoToDefaults()
   Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
     Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_EXIT_CLOSED;
 
+  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+    Properties1[EL_CUSTOM_START + i] = EP_BITMASK_DEFAULT;
+
   BorderElement = EL_STEELWALL;
 
+  level.no_level_file = FALSE;
+
+  if (leveldir_current == NULL)                /* only when dumping level */
+    return;
+
   /* try to determine better author name than 'anonymous' */
   if (strcmp(leveldir_current->author, ANONYMOUS_NAME) != 0)
   {
@@ -125,8 +133,6 @@ static void setLevelInfoToDefaults()
        break;
     }
   }
-
-  level.no_level_file = FALSE;
 }
 
 static int checkLevelElement(int element)
@@ -200,6 +206,33 @@ static int LoadLevel_AUTH(FILE *file, int chunk_size, struct LevelInfo *level)
   return chunk_size;
 }
 
+static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+  int x, y;
+  int chunk_size_expected = level->fieldx * level->fieldy;
+
+  /* Note: "chunk_size" was wrong before version 2.0 when elements are
+     stored with 16-bit encoding (and should be twice as big then).
+     Even worse, playfield data was stored 16-bit when only yamyam content
+     contained 16-bit elements and vice versa. */
+
+  if (level->encoding_16bit_field && level->file_version >= FILE_VERSION_2_0)
+    chunk_size_expected *= 2;
+
+  if (chunk_size_expected != chunk_size)
+  {
+    ReadUnusedBytesFromFile(file, chunk_size);
+    return chunk_size_expected;
+  }
+
+  for(y=0; y<level->fieldy; y++)
+    for(x=0; x<level->fieldx; x++)
+      Feld[x][y] = Ur[x][y] =
+       checkLevelElement(level->encoding_16bit_field ?
+                         getFile16BitBE(file) : fgetc(file));
+  return chunk_size;
+}
+
 static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level)
 {
   int i, x, y;
@@ -240,33 +273,6 @@ static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level)
   return chunk_size;
 }
 
-static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level)
-{
-  int x, y;
-  int chunk_size_expected = level->fieldx * level->fieldy;
-
-  /* Note: "chunk_size" was wrong before version 2.0 when elements are
-     stored with 16-bit encoding (and should be twice as big then).
-     Even worse, playfield data was stored 16-bit when only yamyam content
-     contained 16-bit elements and vice versa. */
-
-  if (level->encoding_16bit_field && level->file_version >= FILE_VERSION_2_0)
-    chunk_size_expected *= 2;
-
-  if (chunk_size_expected != chunk_size)
-  {
-    ReadUnusedBytesFromFile(file, chunk_size);
-    return chunk_size_expected;
-  }
-
-  for(y=0; y<level->fieldy; y++)
-    for(x=0; x<level->fieldx; x++)
-      Feld[x][y] = Ur[x][y] =
-       checkLevelElement(level->encoding_16bit_field ?
-                         getFile16BitBE(file) : fgetc(file));
-  return chunk_size;
-}
-
 static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level)
 {
   int i, x, y;
@@ -310,9 +316,34 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level)
   return chunk_size;
 }
 
-void LoadLevel(int level_nr)
+static int LoadLevel_CUS1(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+  int num_changed_custom_elements = getFile16BitBE(file);
+  int chunk_size_expected = 2 + num_changed_custom_elements * 6;
+  int i;
+
+  if (chunk_size_expected != chunk_size)
+  {
+    ReadUnusedBytesFromFile(file, chunk_size - 2);
+    return chunk_size_expected;
+  }
+
+  for (i=0; i < num_changed_custom_elements; i++)
+  {
+    int element = getFile16BitBE(file);
+    int properties = getFile32BitBE(file);
+
+    if (IS_CUSTOM_ELEMENT(element))
+      Properties1[element] = properties;
+    else
+      Error(ERR_WARN, "invalid custom element number %d", element);
+  }
+
+  return chunk_size;
+}
+
+void LoadLevelFromFilename(char *filename)
 {
-  char *filename = getLevelFilename(level_nr);
   char cookie[MAX_LINE_LEN];
   char chunk_name[CHUNK_ID_LEN + 1];
   int chunk_size;
@@ -386,9 +417,10 @@ void LoadLevel(int level_nr)
       { "VERS", FILE_VERS_CHUNK_SIZE,  LoadLevel_VERS },
       { "HEAD", LEVEL_HEADER_SIZE,     LoadLevel_HEAD },
       { "AUTH", MAX_LEVEL_AUTHOR_LEN,  LoadLevel_AUTH },
-      { "CONT", -1,                    LoadLevel_CONT },
       { "BODY", -1,                    LoadLevel_BODY },
+      { "CONT", -1,                    LoadLevel_CONT },
       { "CNT2", LEVEL_CHUNK_CNT2_SIZE, LoadLevel_CNT2 },
+      { "CUS1", -1,                    LoadLevel_CUS1 },
       {  NULL,  0,                     NULL }
     };
 
@@ -433,6 +465,9 @@ void LoadLevel(int level_nr)
 
   fclose(file);
 
+  if (leveldir_current == NULL)                /* only when dumping level */
+    return;
+
   if (IS_LEVELCLASS_CONTRIBUTION(leveldir_current) ||
       IS_LEVELCLASS_USER(leveldir_current))
   {
@@ -484,6 +519,13 @@ void LoadLevel(int level_nr)
   SetBorderElement();
 }
 
+void LoadLevel(int level_nr)
+{
+  char *filename = getLevelFilename(level_nr);
+
+  LoadLevelFromFilename(filename);
+}
+
 static void SaveLevel_VERS(FILE *file, struct LevelInfo *level)
 {
   putFileVersion(file, level->file_version);
@@ -533,6 +575,18 @@ static void SaveLevel_AUTH(FILE *file, struct LevelInfo *level)
     fputc(level->author[i], file);
 }
 
+static void SaveLevel_BODY(FILE *file, struct LevelInfo *level)
+{
+  int x, y;
+
+  for(y=0; y<level->fieldy; y++) 
+    for(x=0; x<level->fieldx; x++) 
+      if (level->encoding_16bit_field)
+       putFile16BitBE(file, Ur[x][y]);
+      else
+       fputc(Ur[x][y], file);
+}
+
 #if 0
 static void SaveLevel_CONT(FILE *file, struct LevelInfo *level)
 {
@@ -553,18 +607,6 @@ static void SaveLevel_CONT(FILE *file, struct LevelInfo *level)
 }
 #endif
 
-static void SaveLevel_BODY(FILE *file, struct LevelInfo *level)
-{
-  int x, y;
-
-  for(y=0; y<level->fieldy; y++) 
-    for(x=0; x<level->fieldx; x++) 
-      if (level->encoding_16bit_field)
-       putFile16BitBE(file, Ur[x][y]);
-      else
-       fputc(Ur[x][y], file);
-}
-
 static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
 {
   int i, x, y;
@@ -616,11 +658,38 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
        putFile16BitBE(file, content_array[i][x][y]);
 }
 
+static void SaveLevel_CUS1(FILE *file, int num_changed_custom_elements)
+{
+  int i, check = 0;
+
+  putFile16BitBE(file, num_changed_custom_elements);
+
+  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  {
+    int element = EL_CUSTOM_START + i;
+
+    if (Properties1[element] != EP_BITMASK_DEFAULT)
+    {
+      if (check < num_changed_custom_elements)
+      {
+       putFile16BitBE(file, element);
+       putFile32BitBE(file, Properties1[element]);
+      }
+
+      check++;
+    }
+  }
+
+  if (check != num_changed_custom_elements)    /* should not happen */
+    Error(ERR_WARN, "inconsistent number of custom element properties");
+}
+
 void SaveLevel(int level_nr)
 {
-  int i, x, y;
   char *filename = getLevelFilename(level_nr);
   int body_chunk_size;
+  int num_changed_custom_elements = 0;
+  int i, x, y;
   FILE *file;
 
   if (!(file = fopen(filename, MODE_WRITE)))
@@ -652,9 +721,15 @@ void SaveLevel(int level_nr)
   if (level.amoeba_content > 255)
     level.encoding_16bit_amoeba = TRUE;
 
+  /* calculate size of "BODY" chunk */
   body_chunk_size =
     level.fieldx * level.fieldy * (level.encoding_16bit_field ? 2 : 1);
 
+  /* check for non-standard custom elements and calculate "CUS1" chunk size */
+  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+    if (Properties1[EL_CUSTOM_START + i] != EP_BITMASK_DEFAULT)
+      num_changed_custom_elements++;
+
   putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
   putFileChunkBE(file, "CAVE", CHUNK_SIZE_NONE);
 
@@ -683,11 +758,46 @@ void SaveLevel(int level_nr)
     SaveLevel_CNT2(file, &level, EL_BD_AMOEBA);
   }
 
+  if (num_changed_custom_elements > 0)
+  {
+    putFileChunkBE(file, "CUS1", 2 + num_changed_custom_elements * 6);
+    SaveLevel_CUS1(file, num_changed_custom_elements);
+  }
+
   fclose(file);
 
   SetFilePermissions(filename, PERMS_PRIVATE);
 }
 
+void DumpLevel(struct LevelInfo *level)
+{
+  printf_line("-", 79);
+  printf("Level xxx (file version %06d, game version %06d)\n",
+        level->file_version, level->game_version);
+  printf_line("-", 79);
+
+  printf("Level Author: '%s'\n", level->author);
+  printf("Level Title:  '%s'\n", level->name);
+  printf("\n");
+  printf("Playfield Size: %d x %d\n", level->fieldx, level->fieldy);
+  printf("\n");
+  printf("Level Time:  %d seconds\n", level->time);
+  printf("Gems needed: %d\n", level->gems_needed);
+  printf("\n");
+  printf("Time for Magic Wall: %d seconds\n", level->time_magic_wall);
+  printf("Time for Wheel:      %d seconds\n", level->time_wheel);
+  printf("Time for Light:      %d seconds\n", level->time_light);
+  printf("Time for Timegate:   %d seconds\n", level->time_timegate);
+  printf("\n");
+  printf("Amoeba Speed: %d\n", level->amoeba_speed);
+  printf("\n");
+  printf("Gravity:                %s\n", (level->gravity ? "yes" : "no"));
+  printf("Double Speed Movement:  %s\n", (level->double_speed ? "yes" : "no"));
+  printf("EM style slippery gems: %s\n", (level->em_slippery_gems ? "yes" : "no"));
+
+  printf_line("-", 79);
+}
+
 
 /* ========================================================================= */
 /* tape file functions                                                       */
@@ -1079,10 +1189,10 @@ void DumpTape(struct TapeInfo *tape)
     return;
   }
 
-  printf_line('-', 79);
-  printf("Tape of Level %d (file version %06d, game version %06d)\n",
+  printf_line("-", 79);
+  printf("Tape of Level %03d (file version %06d, game version %06d)\n",
         tape->level_nr, tape->file_version, tape->game_version);
-  printf_line('-', 79);
+  printf_line("-", 79);
 
   for(i=0; i<tape->length; i++)
   {
@@ -1111,7 +1221,7 @@ void DumpTape(struct TapeInfo *tape)
     printf("(%03d)\n", tape->pos[i].delay);
   }
 
-  printf_line('-', 79);
+  printf_line("-", 79);
 }
 
 
@@ -1383,7 +1493,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->editor.el_diamond_caves = TRUE;
   si->editor.el_dx_boulderdash = TRUE;
   si->editor.el_chars = TRUE;
-  si->editor.el_custom = FALSE;
+  si->editor.el_custom = TRUE;
 
   si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME;
   si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME;
@@ -1552,3 +1662,59 @@ void SaveSetup()
 
   SetFilePermissions(filename, PERMS_PRIVATE);
 }
+
+void LoadCustomElementDescriptions()
+{
+  char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
+  struct SetupFileList *setup_file_list;
+  int i;
+
+  for (i=0; i<NUM_FILE_ELEMENTS; i++)
+  {
+    if (element_info[i].custom_description != NULL)
+    {
+      free(element_info[i].custom_description);
+      element_info[i].custom_description = NULL;
+    }
+  }
+
+  if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+    return;
+
+  for (i=0; i<NUM_FILE_ELEMENTS; i++)
+  {
+    char *token = getStringCat2(element_info[i].token_name, ".name");
+    char *value = getTokenValue(setup_file_list, token);
+
+    if (value != NULL)
+      element_info[i].custom_description = getStringCopy(value);
+
+    free(token);
+  }
+
+  freeSetupFileList(setup_file_list);
+}
+
+void LoadSpecialMenuDesignSettings()
+{
+  char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
+  struct SetupFileList *setup_file_list;
+  char *value;
+
+  /* !!! CHANGE THIS !!! (redundant initialization) !!! */
+  gfx.menu_main_hide_static_text = FALSE;
+  global.num_toons = 20;
+
+  if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+    return;
+
+  value = getTokenValue(setup_file_list, "menu.main.hide_static_text");
+  if (value != NULL)
+    gfx.menu_main_hide_static_text = get_boolean_from_string(value);
+
+  value = getTokenValue(setup_file_list, "global.num_toons");
+  if (value != NULL)
+    global.num_toons = get_integer_from_string(value);
+
+  freeSetupFileList(setup_file_list);
+}