rnd-20030118-6-src
[rocksndiamonds.git] / src / libgame / misc.c
index 7caaa3af88251b1601ff0abe0864058c6fe31c7c..abea627781cfebb3d2a20b09351055ccc69177e4 100644 (file)
 #include "text.h"
 
 
+/* ------------------------------------------------------------------------- */
+/* some generic helper functions                                             */
+/* ------------------------------------------------------------------------- */
+
+void fprintf_line(FILE *stream, char *line_string, int line_length)
+{
+  int i;
+
+  for (i=0; i<line_length; i++)
+    fprintf(stream, "%s", line_string);
+
+  fprintf(stream, "\n");
+}
+
+void printf_line(char *line_string, int line_length)
+{
+  fprintf_line(stdout, line_string, line_length);
+}
+
+/* int2str() returns a number converted to a string;
+   the used memory is static, but will be overwritten by later calls,
+   so if you want to save the result, copy it to a private string buffer;
+   there can be 10 local calls of int2str() without buffering the result --
+   the 11th call will then destroy the result from the first call and so on.
+*/
+
+char *int2str(int number, int size)
+{
+  static char shift_array[10][40];
+  static int shift_counter = 0;
+  char *s = shift_array[shift_counter];
+
+  shift_counter = (shift_counter + 1) % 10;
+
+  if (size > 20)
+    size = 20;
+
+  if (size)
+  {
+    sprintf(s, "                    %09d", number);
+    return &s[strlen(s) - size];
+  }
+  else
+  {
+    sprintf(s, "%d", number);
+    return s;
+  }
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* counter functions                                                         */
+/* ------------------------------------------------------------------------- */
+
 #if defined(PLATFORM_MSDOS)
 volatile unsigned long counter = 0;
 
@@ -202,35 +256,10 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
   *counter_var = actual_counter;
 }
 
-/* int2str() returns a number converted to a string;
-   the used memory is static, but will be overwritten by later calls,
-   so if you want to save the result, copy it to a private string buffer;
-   there can be 10 local calls of int2str() without buffering the result --
-   the 11th call will then destroy the result from the first call and so on.
-*/
-
-char *int2str(int number, int size)
-{
-  static char shift_array[10][40];
-  static int shift_counter = 0;
-  char *s = shift_array[shift_counter];
-
-  shift_counter = (shift_counter + 1) % 10;
-
-  if (size > 20)
-    size = 20;
 
-  if (size)
-  {
-    sprintf(s, "                    %09d", number);
-    return &s[strlen(s) - size];
-  }
-  else
-  {
-    sprintf(s, "%d", number);
-    return s;
-  }
-}
+/* ------------------------------------------------------------------------- */
+/* random generator functions                                                */
+/* ------------------------------------------------------------------------- */
 
 unsigned int SimpleRND(unsigned int max)
 {
@@ -302,6 +331,11 @@ unsigned int InitRND(long seed)
 #endif
 }
 
+
+/* ------------------------------------------------------------------------- */
+/* system info functions                                                     */
+/* ------------------------------------------------------------------------- */
+
 char *getLoginName()
 {
 #if defined(PLATFORM_WIN32)
@@ -384,6 +418,11 @@ char *getHomeDir()
 #endif
 }
 
+
+/* ------------------------------------------------------------------------- */
+/* various string functions                                                  */
+/* ------------------------------------------------------------------------- */
+
 char *getPath2(char *path1, char *path2)
 {
   char *complete_path = checked_malloc(strlen(path1) + 1 +
@@ -436,6 +475,11 @@ char *getStringToLower(char *s)
   return s_copy;
 }
 
+
+/* ------------------------------------------------------------------------- */
+/* command line option handling functions                                    */
+/* ------------------------------------------------------------------------- */
+
 static void printUsage()
 {
   printf("\n"
@@ -458,6 +502,7 @@ static void printUsage()
         "  \"print graphicsinfo.conf\"        print default graphics config\n"
         "  \"print soundsinfo.conf\"          print default sounds config\n"
         "  \"print musicinfo.conf\"           print default music config\n"
+        "  \"dump level FILE\"                dump level data from FILE\n"
         "  \"dump tape FILE\"                 dump tape data from FILE\n"
         "  \"autoplay LEVELDIR\"              play level tapes for LEVELDIR\n"
         "\n",
@@ -630,6 +675,11 @@ void GetOptions(char *argv[])
   }
 }
 
+
+/* ------------------------------------------------------------------------- */
+/* error handling functions                                                  */
+/* ------------------------------------------------------------------------- */
+
 /* used by SetError() and GetError() to store internal error messages */
 static char internal_error[1024];      /* this is bad */
 
@@ -649,6 +699,7 @@ char *GetError()
 
 void Error(int mode, char *format, ...)
 {
+  static boolean last_line_was_separator = FALSE;
   char *process_name = "";
   FILE *error = stderr;
   char *newline = "\n";
@@ -657,6 +708,18 @@ void Error(int mode, char *format, ...)
   if (mode & ERR_WARN && !options.verbose)
     return;
 
+  if (mode == ERR_RETURN_LINE)
+  {
+    if (!last_line_was_separator)
+      fprintf_line(error, format, 79);
+
+    last_line_was_separator = TRUE;
+
+    return;
+  }
+
+  last_line_was_separator = FALSE;
+
 #if defined(PLATFORM_MSDOS)
   newline = "\r\n";
 
@@ -710,6 +773,11 @@ void Error(int mode, char *format, ...)
   }
 }
 
+
+/* ------------------------------------------------------------------------- */
+/* memory allocation functions                                               */
+/* ------------------------------------------------------------------------- */
+
 void *checked_malloc(unsigned long size)
 {
   void *ptr;
@@ -744,6 +812,11 @@ void *checked_realloc(void *ptr, unsigned long size)
   return ptr;
 }
 
+
+/* ------------------------------------------------------------------------- */
+/* various helper functions                                                  */
+/* ------------------------------------------------------------------------- */
+
 inline void swap_numbers(int *i1, int *i2)
 {
   int help = *i1;
@@ -1291,9 +1364,9 @@ boolean get_boolean_from_string(char *s)
 }
 
 
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 /* functions for generic lists                                               */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 
 ListNode *newListNode()
 {
@@ -1371,9 +1444,9 @@ void dumpList(ListNode *node_first)
 }
 
 
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 /* functions for checking filenames                                          */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 
 boolean FileIsGraphic(char *filename)
 {
@@ -1422,13 +1495,14 @@ boolean FileIsArtworkType(char *basename, int type)
   return FALSE;
 }
 
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 /* functions for loading artwork configuration information                   */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 
 static int get_parameter_value(int type, char *value)
 {
-  return (type == TYPE_INTEGER ? get_integer_from_string(value) :
+  return (strcmp(value, ARG_UNDEFINED) == 0 ? ARG_UNDEFINED_VALUE :
+         type == TYPE_INTEGER ? get_integer_from_string(value) :
          type == TYPE_BOOLEAN ? get_boolean_from_string(value) :
          -1);
 }
@@ -1532,7 +1606,7 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
   return file_list;
 }
 
-static void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
+void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
 {
   struct FileInfo *file_list = artwork_info->file_list;
   struct ConfigInfo *suffix_list = artwork_info->suffix_list;
@@ -1540,6 +1614,7 @@ static void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
   int num_suffix_list_entries = artwork_info->num_suffix_list_entries;
   char *filename = getCustomArtworkConfigFilename(artwork_info->type);
   struct SetupFileList *setup_file_list;
+  char *known_token_value = "[KNOWN_TOKEN]";
   int i, j;
 
 #if 0
@@ -1560,42 +1635,91 @@ static void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
   if (filename == NULL)
     return;
 
-  if ((setup_file_list = loadSetupFileList(filename)))
+  if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+    return;
+
+  for (i=0; i<num_file_list_entries; i++)
   {
-    for (i=0; i<num_file_list_entries; i++)
+    /* check for config token that is the base token without any suffixes */
+    char *filename = getTokenValue(setup_file_list, file_list[i].token);
+
+    if (filename != NULL)
     {
-      char *filename = getTokenValue(setup_file_list, file_list[i].token);
+      for (j=0; j<num_suffix_list_entries; j++)
+       file_list[i].parameter[j] =
+         get_parameter_value(suffix_list[j].type, suffix_list[j].value);
 
-      if (filename == NULL)
-       filename = file_list[i].default_filename;
       file_list[i].filename = getStringCopy(filename);
 
-      for (j=0; j<num_suffix_list_entries; j++)
-      {
-       char *token = getStringCat2(file_list[i].token, suffix_list[j].token);
-       char *value = getTokenValue(setup_file_list, token);
+      /* mark token as well known from default config */
+      setTokenValue(setup_file_list, file_list[i].token, known_token_value);
+    }
+    else
+      file_list[i].filename = getStringCopy(file_list[i].default_filename);
+
+    /* check for config tokens that can be build by base token and suffixes */
+    for (j=0; j<num_suffix_list_entries; j++)
+    {
+      char *token = getStringCat2(file_list[i].token, suffix_list[j].token);
+      char *value = getTokenValue(setup_file_list, token);
 
-       if (value != NULL)
-         file_list[i].parameter[j] =
-           get_parameter_value(suffix_list[j].type, value);
+      if (value != NULL)
+      {
+       file_list[i].parameter[j] =
+         get_parameter_value(suffix_list[j].type, value);
 
-       free(token);
+       /* mark token as well known from default config */
+       setTokenValue(setup_file_list, token, known_token_value);
       }
+
+      free(token);
     }
+  }
 
-    freeSetupFileList(setup_file_list);
+  /* set some additional tokens to "known" */
+  setTokenValue(setup_file_list, "name", known_token_value);
+  setTokenValue(setup_file_list, "sort_priority", known_token_value);
 
-#if 0
-    for (i=0; i<num_file_list_entries; i++)
+  if (options.verbose && !IS_CHILD_PROCESS(audio.mixer_pid))
+  {
+    boolean unknown_tokens_found = FALSE;
+
+    /* check each token in config file if it is defined in default config */
+    while (setup_file_list != NULL)
     {
-      printf("'%s' ", file_list[i].token);
-      if (file_list[i].filename)
-       printf("-> '%s'\n", file_list[i].filename);
-      else
-       printf("-> UNDEFINED [-> '%s']\n", file_list[i].default_filename);
+      if (strcmp(setup_file_list->value, known_token_value) != 0)
+      {
+       if (!unknown_tokens_found)
+       {
+         Error(ERR_RETURN_LINE, "-");
+         Error(ERR_RETURN, "warning: unknown token(s) found in config file:");
+         Error(ERR_RETURN, "- config file: '%s'", filename);
+
+         unknown_tokens_found = TRUE;
+       }
+
+       Error(ERR_RETURN, "- unknown token: '%s'", setup_file_list->token);
+      }
+
+      setup_file_list = setup_file_list->next;
     }
-#endif
+
+    if (unknown_tokens_found)
+      Error(ERR_RETURN_LINE, "-");
+  }
+
+  freeSetupFileList(setup_file_list);
+
+#if 0
+  for (i=0; i<num_file_list_entries; i++)
+  {
+    printf("'%s' ", file_list[i].token);
+    if (file_list[i].filename)
+      printf("-> '%s'\n", file_list[i].filename);
+    else
+      printf("-> UNDEFINED [-> '%s']\n", file_list[i].default_filename);
   }
+#endif
 }
 
 static void deleteArtworkListEntry(struct ArtworkListInfo *artwork_info,
@@ -1778,7 +1902,9 @@ void ReloadCustomArtworkList(struct ArtworkListInfo *artwork_info)
   struct FileInfo *file_list = artwork_info->file_list;
   int i;
 
+#if 0
   LoadArtworkConfig(artwork_info);
+#endif
 
 #if 0
   if (draw_init[artwork_info->type].do_it)
@@ -1843,10 +1969,10 @@ void FreeCustomArtworkList(struct ArtworkListInfo *artwork_info)
 }
 
 
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 /* functions only needed for non-Unix (non-command-line) systems             */
 /* (MS-DOS only; SDL/Windows creates files "stdout.txt" and "stderr.txt")    */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 
 #if defined(PLATFORM_MSDOS)
 
@@ -1877,24 +2003,9 @@ void dumpErrorFile()
 #endif
 
 
-/* ========================================================================= */
-/* some generic helper functions                                             */
-/* ========================================================================= */
-
-void printf_line(char line_char, int line_length)
-{
-  int i;
-
-  for (i=0; i<line_length; i++)
-    printf("%c", line_char);
-
-  printf("\n");
-}
-
-
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 /* the following is only for debugging purpose and normally not used         */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
 
 #define DEBUG_NUM_TIMESTAMPS   3