rnd-20031118-1-src
[rocksndiamonds.git] / src / files.c
index 36751f4630437fb12df9e828268a5e960e02760a..f8b4983994e6549448e8ad9a577da8dddb5170ca 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <ctype.h>
 #include <sys/stat.h>
+#include <math.h>
 
 #include "libgame/libgame.h"
 
@@ -947,7 +948,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     printf("\n::: This level is private or contributed: '%s'\n", filename);
 #endif
 
-#if 1
+#if 0
     printf("\n::: Use the stored game engine version for this level\n");
 #endif
 
@@ -972,7 +973,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     }
 
     /* Default behaviour for EM style gems was "slippery" only in 2.0.1 */
-    if (level->game_version == VERSION_IDENT(2,0,1))
+    if (level->game_version == VERSION_IDENT(2,0,1,0))
       level->em_slippery_gems = TRUE;
   }
   else
@@ -982,7 +983,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
           leveldir_current->sort_priority, filename);
 #endif
 
-#if 1
+#if 0
     printf("\n::: Use latest game engine version for this level.\n");
 #endif
 
@@ -1023,7 +1024,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
 
   /* map custom element change events that have changed in newer versions
      (these following values were accidentally changed in version 3.0.1) */
-  if (level->game_version <= VERSION_IDENT(3,0,0))
+  if (level->game_version <= VERSION_IDENT(3,0,0,0))
   {
     for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
@@ -1067,7 +1068,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
   }
 
   /* initialize "can_change" field for old levels with only one change page */
-  if (level->game_version <= VERSION_IDENT(3,0,2))
+  if (level->game_version <= VERSION_IDENT(3,0,2,0))
   {
     for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
@@ -1078,8 +1079,9 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
-  /* set default push delay values (corrected since version 3.0.7) */
-  if (level->game_version < VERSION_IDENT(3,0,7))
+#if 0
+  /* set default push delay values (corrected since version 3.0.7-1) */
+  if (level->game_version < VERSION_IDENT(3,0,7,1))
   {
     game.default_push_delay_fixed = 2;
     game.default_push_delay_random = 8;
@@ -1100,6 +1102,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     if (element_info[element].push_delay_random == -1)
       element_info[element].push_delay_random = game.default_push_delay_random;
   }
+#endif
 
   /* initialize element properties for level editor etc. */
   InitElementPropertiesEngine(level->game_version);
@@ -1116,7 +1119,7 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename)
     {
       int element = level->field[x][y];
 
-      if (level->game_version <= VERSION_IDENT(2,2,0))
+      if (level->game_version <= VERSION_IDENT(2,2,0,0))
       {
        /* map game font elements */
        element = (element == EL_CHAR('[')  ? EL_CHAR_AUMLAUT :
@@ -1125,7 +1128,7 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename)
                   element == EL_CHAR('^')  ? EL_CHAR_COPYRIGHT : element);
       }
 
-      if (level->game_version < VERSION_IDENT(3,0,0))
+      if (level->game_version < VERSION_IDENT(3,0,0,0))
       {
        /* map Supaplex gravity tube elements */
        element = (element == EL_SP_GRAVITY_PORT_LEFT  ? EL_SP_PORT_LEFT  :
@@ -1995,8 +1998,8 @@ void LoadTapeFromFilename(char *filename)
   tape.length_seconds = GetTapeLength();
 
 #if 0
-  printf("tape game version: %d\n", tape.game_version);
-  printf("tape engine version: %d\n", tape.engine_version);
+  printf("::: tape game version: %d\n", tape.game_version);
+  printf("::: tape engine version: %d\n", tape.engine_version);
 #endif
 }
 
@@ -2297,8 +2300,9 @@ void SaveScore(int level_nr)
 #define SETUP_TOKEN_EDITOR_EL_CUSTOM           8
 #define SETUP_TOKEN_EDITOR_EL_CUSTOM_MORE      9
 #define SETUP_TOKEN_EDITOR_EL_HEADLINES                10
+#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED     11
 
-#define NUM_EDITOR_SETUP_TOKENS                        11
+#define NUM_EDITOR_SETUP_TOKENS                        12
 
 /* shortcut setup */
 #define SETUP_TOKEN_SHORTCUT_SAVE_GAME         0
@@ -2385,6 +2389,7 @@ static struct TokenInfo editor_setup_tokens[] =
   { TYPE_SWITCH, &sei.el_custom,       "editor.el_custom"              },
   { TYPE_SWITCH, &sei.el_custom_more,  "editor.el_custom_more"         },
   { TYPE_SWITCH, &sei.el_headlines,    "editor.el_headlines"           },
+  { TYPE_SWITCH, &sei.el_user_defined, "editor.el_user_defined"        },
 };
 
 static struct TokenInfo shortcut_setup_tokens[] =
@@ -2483,6 +2488,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->editor.el_custom_more = FALSE;
 
   si->editor.el_headlines = TRUE;
+  si->editor.el_user_defined = FALSE;
 
   si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME;
   si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME;
@@ -2754,3 +2760,87 @@ void LoadSpecialMenuDesignSettings()
 
   freeSetupFileHash(setup_file_hash);
 }
+
+static char *itoa(unsigned int i)
+{
+  static char *a = NULL;
+
+  if (a != NULL)
+    free(a);
+
+  if (i > 2147483647)  /* yes, this is a kludge */
+    i = 2147483647;
+
+  a = checked_malloc(10 + 1);
+
+  sprintf(a, "%d", i);
+
+  return a;
+}
+
+void LoadUserDefinedEditorElementList(int **elements, int *num_elements)
+{
+  char *filename = getEditorSetupFilename();
+  SetupFileList *setup_file_list, *list;
+  SetupFileHash *element_hash;
+  int num_unknown_tokens = 0;
+  int i;
+
+  if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+    return;
+
+  element_hash = newSetupFileHash();
+
+  for (i=0; i < NUM_FILE_ELEMENTS; i++)
+    setHashEntry(element_hash, element_info[i].token_name, itoa(i));
+
+  /* determined size may be larger than needed (due to unknown elements) */
+  *num_elements = 0;
+  for (list = setup_file_list; list != NULL; list = list->next)
+    (*num_elements)++;
+
+  /* add space for up to 3 more elements for padding that may be needed */
+  *num_elements += 3;
+
+  *elements = checked_malloc(*num_elements * sizeof(int));
+
+  *num_elements = 0;
+  for (list = setup_file_list; list != NULL; list = list->next)
+  {
+    char *value = getHashEntry(element_hash, list->token);
+
+    if (value)
+    {
+      (*elements)[(*num_elements)++] = atoi(value);
+    }
+    else
+    {
+      if (num_unknown_tokens == 0)
+      {
+       Error(ERR_RETURN_LINE, "-");
+       Error(ERR_RETURN, "warning: unknown token(s) found in config file:");
+       Error(ERR_RETURN, "- config file: '%s'", filename);
+
+       num_unknown_tokens++;
+      }
+
+      Error(ERR_RETURN, "- token: '%s'", list->token);
+    }
+  }
+
+  if (num_unknown_tokens > 0)
+    Error(ERR_RETURN_LINE, "-");
+
+  while (*num_elements % 4)    /* pad with empty elements, if needed */
+    (*elements)[(*num_elements)++] = EL_EMPTY;
+
+  freeSetupFileList(setup_file_list);
+  freeSetupFileHash(element_hash);
+
+#if 0
+  /* TEST-ONLY */
+  for (i=0; i < *num_elements; i++)
+    printf("editor: element '%s' [%d]\n",
+          element_info[(*elements)[i]].token_name, (*elements)[i]);
+#endif
+}