rnd-20030503-1-src
[rocksndiamonds.git] / src / libgame / misc.c
index d94b37d55c174a63a3684ca2266ac19ed349dc12..60aff1cca96ed5772fbe1475ddb86091a56c853e 100644 (file)
@@ -215,8 +215,8 @@ boolean FrameReached(unsigned long *frame_counter_var,
 {
   unsigned long actual_frame_counter = FrameCounter;
 
-  if (actual_frame_counter < *frame_counter_var + frame_delay &&
-      actual_frame_counter >= *frame_counter_var)
+  if (actual_frame_counter >= *frame_counter_var &&
+      actual_frame_counter < *frame_counter_var + frame_delay)
     return FALSE;
 
   *frame_counter_var = actual_frame_counter;
@@ -229,8 +229,8 @@ boolean DelayReached(unsigned long *counter_var,
 {
   unsigned long actual_counter = Counter();
 
-  if (actual_counter < *counter_var + delay &&
-      actual_counter >= *counter_var)
+  if (actual_counter >= *counter_var &&
+      actual_counter < *counter_var + delay)
     return FALSE;
 
   *counter_var = actual_counter;
@@ -246,8 +246,8 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
   {
     actual_counter = Counter();
 
-    if (actual_counter < *counter_var + delay &&
-       actual_counter >= *counter_var)
+    if (actual_counter >= *counter_var &&
+       actual_counter < *counter_var + delay)
       sleep_milliseconds((*counter_var + delay - actual_counter) / 2);
     else
       break;
@@ -307,10 +307,14 @@ unsigned int init_random_number(int nr, long seed)
 {
   if (seed == NEW_RANDOMIZE)
   {
+#if defined(TARGET_SDL)
+    seed = (long)SDL_GetTicks();
+#else
     struct timeval current_time;
 
     gettimeofday(&current_time, NULL);
     seed = (long)current_time.tv_usec;
+#endif
   }
 
   srandom_linux_libc(nr, (unsigned int) seed);
@@ -320,7 +324,7 @@ unsigned int init_random_number(int nr, long seed)
 
 unsigned int get_random_number(int nr, unsigned int max)
 {
-  return (random_linux_libc(nr) % max);
+  return (max > 0 ? random_linux_libc(nr) % max : 0);
 }
 
 
@@ -328,13 +332,53 @@ unsigned int get_random_number(int nr, unsigned int max)
 /* system info functions                                                     */
 /* ------------------------------------------------------------------------- */
 
+static char *get_corrected_real_name(char *real_name)
+{
+  char *real_name_new = checked_malloc(MAX_USERNAME_LEN + 1);
+  char *from_ptr = real_name;
+  char *to_ptr   = real_name_new;
+
+  if (strchr(real_name, 'ß') == NULL)  /* name does not contain 'ß' */
+  {
+    strncpy(real_name_new, real_name, MAX_USERNAME_LEN);
+    real_name_new[MAX_USERNAME_LEN] = '\0';
+
+    return real_name_new;
+  }
+
+  /* the user's real name may contain a 'ß' character (german sharp s),
+     which has no equivalent in upper case letters (which our fonts use) */
+  while (*from_ptr && (long)(to_ptr - real_name_new) < MAX_USERNAME_LEN - 1)
+  {
+    if (*from_ptr != 'ß')
+      *to_ptr++ = *from_ptr++;
+    else
+    {
+      from_ptr++;
+      *to_ptr++ = 's';
+      *to_ptr++ = 's';
+    }
+  }
+
+  *to_ptr = '\0';
+
+  return real_name_new;
+}
+
 char *getLoginName()
 {
-#if defined(PLATFORM_WIN32)
-  return ANONYMOUS_NAME;
-#else
   static char *login_name = NULL;
 
+#if defined(PLATFORM_WIN32)
+  if (login_name == NULL)
+  {
+    unsigned long buffer_size = MAX_USERNAME_LEN + 1;
+    login_name = checked_malloc(buffer_size);
+
+    if (GetUserName(login_name, &buffer_size) == 0)
+      strcpy(login_name, ANONYMOUS_NAME);
+  }
+#else
   if (login_name == NULL)
   {
     struct passwd *pwd;
@@ -344,70 +388,73 @@ char *getLoginName()
     else
       login_name = getStringCopy(pwd->pw_name);
   }
+#endif
 
   return login_name;
-#endif
 }
 
 char *getRealName()
 {
-#if defined(PLATFORM_UNIX)
-  struct passwd *pwd;
+  static char *real_name = NULL;
 
-  if ((pwd = getpwuid(getuid())) == NULL || strlen(pwd->pw_gecos) == 0)
-    return ANONYMOUS_NAME;
-  else
+#if defined(PLATFORM_WIN32)
+  if (real_name == NULL)
   {
-    static char real_name[1024];
-    char *from_ptr = pwd->pw_gecos, *to_ptr = real_name;
+    static char buffer[MAX_USERNAME_LEN + 1];
+    unsigned long buffer_size = MAX_USERNAME_LEN + 1;
 
-    if (strchr(pwd->pw_gecos, 'ß') == NULL)
-      return pwd->pw_gecos;
-
-    /* the user's real name contains a 'ß' character (german sharp s),
-       which has no equivalent in upper case letters (which our fonts use) */
-    while (*from_ptr != '\0' && (long)(to_ptr - real_name) < 1024 - 2)
-    {
-      if (*from_ptr != 'ß')
-       *to_ptr++ = *from_ptr++;
-      else
-      {
-       from_ptr++;
-       *to_ptr++ = 's';
-       *to_ptr++ = 's';
-      }
-    }
-    *to_ptr = '\0';
+    if (GetUserName(buffer, &buffer_size) != 0)
+      real_name = get_corrected_real_name(buffer);
+    else
+      real_name = ANONYMOUS_NAME;
+  }
+#elif defined(PLATFORM_UNIX)
+  if (real_name == NULL)
+  {
+    struct passwd *pwd;
 
-    return real_name;
+    if ((pwd = getpwuid(getuid())) != NULL && strlen(pwd->pw_gecos) != 0)
+      real_name = get_corrected_real_name(pwd->pw_gecos);
+    else
+      real_name = ANONYMOUS_NAME;
   }
-#else /* !PLATFORM_UNIX */
-  return ANONYMOUS_NAME;
+#else
+  real_name = ANONYMOUS_NAME;
 #endif
+
+  return real_name;
 }
 
 char *getHomeDir()
 {
-#if defined(PLATFORM_UNIX)
-  static char *home_dir = NULL;
+  static char *dir = NULL;
+
+#if defined(PLATFORM_WIN32)
+  if (dir == NULL)
+  {
+    dir = checked_malloc(MAX_PATH + 1);
 
-  if (home_dir == NULL)
+    if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir)))
+      strcpy(dir, ".");
+  }
+#elif defined(PLATFORM_UNIX)
+  if (dir == NULL)
   {
-    if ((home_dir = getenv("HOME")) == NULL)
+    if ((dir = getenv("HOME")) == NULL)
     {
       struct passwd *pwd;
 
-      if ((pwd = getpwuid(getuid())) == NULL)
-       home_dir = ".";
+      if ((pwd = getpwuid(getuid())) != NULL)
+       dir = getStringCopy(pwd->pw_dir);
       else
-       home_dir = getStringCopy(pwd->pw_dir);
+       dir = ".";
     }
   }
-
-  return home_dir;
 #else
-  return ".";
+  dir = ".";
 #endif
+
+  return dir;
 }
 
 
@@ -526,6 +573,7 @@ void GetOptions(char *argv[])
   options.graphics_directory = RO_BASE_PATH "/" GRAPHICS_DIRECTORY;
   options.sounds_directory = RO_BASE_PATH "/" SOUNDS_DIRECTORY;
   options.music_directory = RO_BASE_PATH "/" MUSIC_DIRECTORY;
+  options.docs_directory = RO_BASE_PATH "/" DOCS_DIRECTORY;
   options.execute_command = NULL;
   options.serveronly = FALSE;
   options.network = FALSE;
@@ -1453,9 +1501,18 @@ void dumpList(ListNode *node_first)
 
 
 /* ------------------------------------------------------------------------- */
-/* functions for checking filenames                                          */
+/* functions for checking files and filenames                                */
 /* ------------------------------------------------------------------------- */
 
+boolean fileExists(char *filename)
+{
+#if 0
+  printf("checking file '%s'\n", filename);
+#endif
+
+  return (access(filename, F_OK) == 0);
+}
+
 boolean FileIsGraphic(char *filename)
 {
   if (strlen(filename) > 4 &&
@@ -1563,6 +1620,7 @@ int get_parameter_value(char *token, char *value_raw, int type)
              string_has_parameter(value, "pingpong")  ? ANIM_PINGPONG :
              string_has_parameter(value, "pingpong2") ? ANIM_PINGPONG2 :
              string_has_parameter(value, "random")    ? ANIM_RANDOM :
+             string_has_parameter(value, "none")      ? ANIM_NONE :
              ANIM_LOOP);
 
     if (string_has_parameter(value, "reverse"))
@@ -1719,12 +1777,12 @@ static boolean token_suffix_match(char *token, char *suffix, int start_pos)
 
 #define KNOWN_TOKEN_VALUE      "[KNOWN_TOKEN]"
 
-static void read_token_parameters(struct SetupFileList *setup_file_list,
+static void read_token_parameters(SetupFileHash *setup_file_hash,
                                  struct ConfigInfo *suffix_list,
                                  struct FileInfo *file_list_entry)
 {
   /* check for config token that is the base token without any suffixes */
-  char *filename = getTokenValue(setup_file_list, file_list_entry->token);
+  char *filename = getHashEntry(setup_file_hash, file_list_entry->token);
   char *known_token_value = KNOWN_TOKEN_VALUE;
   int i;
 
@@ -1739,7 +1797,7 @@ static void read_token_parameters(struct SetupFileList *setup_file_list,
     file_list_entry->redefined = TRUE;
 
     /* mark config file token as well known from default config */
-    setTokenValue(setup_file_list, file_list_entry->token, known_token_value);
+    setHashEntry(setup_file_hash, file_list_entry->token, known_token_value);
   }
   else
     setString(&file_list_entry->filename, file_list_entry->default_filename);
@@ -1748,14 +1806,14 @@ static void read_token_parameters(struct SetupFileList *setup_file_list,
   for (i=0; suffix_list[i].token != NULL; i++)
   {
     char *token = getStringCat2(file_list_entry->token, suffix_list[i].token);
-    char *value = getTokenValue(setup_file_list, token);
+    char *value = getHashEntry(setup_file_hash, token);
 
     if (value != NULL)
     {
       setString(&file_list_entry->parameter[i], value);
 
       /* mark config file token as well known from default config */
-      setTokenValue(setup_file_list, token, known_token_value);
+      setHashEntry(setup_file_hash, token, known_token_value);
     }
 
     free(token);
@@ -1764,7 +1822,7 @@ static void read_token_parameters(struct SetupFileList *setup_file_list,
 
 static void add_dynamic_file_list_entry(struct FileInfo **list,
                                        int *num_list_entries,
-                                       struct SetupFileList *extra_file_list,
+                                       SetupFileHash *extra_file_hash,
                                        struct ConfigInfo *suffix_list,
                                        int num_suffix_list_entries,
                                        char *token)
@@ -1785,7 +1843,7 @@ static void add_dynamic_file_list_entry(struct FileInfo **list,
   new_list_entry->filename = NULL;
   new_list_entry->parameter = checked_calloc(parameter_array_size);
 
-  read_token_parameters(extra_file_list, suffix_list, new_list_entry);
+  read_token_parameters(extra_file_hash, suffix_list, new_list_entry);
 }
 
 static void add_property_mapping(struct PropertyMapping **list,
@@ -1826,9 +1884,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
   int num_ext3_suffixes = artwork_info->num_ext3_suffixes;
   int num_ignore_tokens = artwork_info->num_ignore_tokens;
   char *filename = getCustomArtworkConfigFilename(artwork_info->type);
-  struct SetupFileList *setup_file_list;
-  struct SetupFileList *extra_file_list = NULL;
-  struct SetupFileList *list;
+  SetupFileHash *setup_file_hash, *extra_file_hash;
   char *known_token_value = KNOWN_TOKEN_VALUE;
   int i, j, k, l;
 
@@ -1876,35 +1932,33 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
   if (filename == NULL)
     return;
 
-  if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+  if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
     return;
 
   /* read parameters for all known config file tokens */
   for (i=0; i<num_file_list_entries; i++)
-    read_token_parameters(setup_file_list, suffix_list, &file_list[i]);
+    read_token_parameters(setup_file_hash, suffix_list, &file_list[i]);
 
   /* set all tokens that can be ignored here to "known" keyword */
   for (i=0; i < num_ignore_tokens; i++)
-    setTokenValue(setup_file_list, ignore_tokens[i], known_token_value);
+    setHashEntry(setup_file_hash, ignore_tokens[i], known_token_value);
 
   /* copy all unknown config file tokens to extra config list */
-  for (list = setup_file_list; list != NULL; list = list->next)
+  extra_file_hash = newSetupFileHash();
+  BEGIN_HASH_ITERATION(setup_file_hash, itr)
   {
-    if (strcmp(list->value, known_token_value) != 0)
-    {
-      if (extra_file_list == NULL)
-       extra_file_list = newSetupFileList(list->token, list->value);
-      else
-       setTokenValue(extra_file_list, list->token, list->value);
-    }
+    if (strcmp(HASH_ITERATION_VALUE(itr), known_token_value) != 0)
+      setHashEntry(extra_file_hash,
+                  HASH_ITERATION_TOKEN(itr), HASH_ITERATION_VALUE(itr));
   }
+  END_HASH_ITERATION(setup_file_hash, itr)
 
-  /* at this point, we do not need the config file list anymore -- free it */
-  freeSetupFileList(setup_file_list);
+  /* at this point, we do not need the config file hash anymore -- free it */
+  freeSetupFileHash(setup_file_hash);
 
   /* now try to determine valid, dynamically defined config tokens */
 
-  for (list = extra_file_list; list != NULL; list = list->next)
+  BEGIN_HASH_ITERATION(extra_file_hash, itr)
   {
     struct FileInfo **dynamic_file_list =
       &artwork_info->dynamic_file_list;
@@ -1917,7 +1971,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
     int current_summarized_file_list_entry =
       artwork_info->num_file_list_entries +
       artwork_info->num_dynamic_file_list_entries;
-    char *token = list->token;
+    char *token = HASH_ITERATION_TOKEN(itr);
     int len_token = strlen(token);
     int start_pos;
     boolean base_prefix_found = FALSE;
@@ -1974,7 +2028,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
 
        add_dynamic_file_list_entry(dynamic_file_list,
                                    num_dynamic_file_list_entries,
-                                   extra_file_list,
+                                   extra_file_hash,
                                    suffix_list,
                                    num_suffix_list_entries,
                                    token);
@@ -2011,7 +2065,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
 
          add_dynamic_file_list_entry(dynamic_file_list,
                                      num_dynamic_file_list_entries,
-                                     extra_file_list,
+                                     extra_file_hash,
                                      suffix_list,
                                      num_suffix_list_entries,
                                      token);
@@ -2053,7 +2107,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
 
          add_dynamic_file_list_entry(dynamic_file_list,
                                      num_dynamic_file_list_entries,
-                                     extra_file_list,
+                                     extra_file_hash,
                                      suffix_list,
                                      num_suffix_list_entries,
                                      token);
@@ -2095,7 +2149,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
 
          add_dynamic_file_list_entry(dynamic_file_list,
                                      num_dynamic_file_list_entries,
-                                     extra_file_list,
+                                     extra_file_hash,
                                      suffix_list,
                                      num_suffix_list_entries,
                                      token);
@@ -2108,6 +2162,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
       }
     }
   }
+  END_HASH_ITERATION(extra_file_hash, itr)
 
   if (artwork_info->num_dynamic_file_list_entries > 0)
   {
@@ -2116,18 +2171,23 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
                     artwork_info->sizeof_artwork_list_entry);
   }
 
-  if (extra_file_list != NULL && options.verbose && IS_PARENT_PROCESS())
+  if (extra_file_hash != NULL && options.verbose && IS_PARENT_PROCESS())
   {
+    SetupFileList *setup_file_list, *list;
     boolean dynamic_tokens_found = FALSE;
     boolean unknown_tokens_found = FALSE;
 
-    for (list = extra_file_list; list != NULL; list = list->next)
+    if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+      Error(ERR_EXIT, "loadSetupFileHash works, but loadSetupFileList fails");
+
+    BEGIN_HASH_ITERATION(extra_file_hash, itr)
     {
-      if (strcmp(list->value, known_token_value) == 0)
+      if (strcmp(HASH_ITERATION_VALUE(itr), known_token_value) == 0)
        dynamic_tokens_found = TRUE;
       else
        unknown_tokens_found = TRUE;
     }
+    END_HASH_ITERATION(extra_file_hash, itr)
 
 #if DEBUG
     if (dynamic_tokens_found)
@@ -2135,9 +2195,13 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
       Error(ERR_RETURN_LINE, "-");
       Error(ERR_RETURN, "dynamic token(s) found:");
 
-      for (list = extra_file_list; list != NULL; list = list->next)
-       if (strcmp(list->value, known_token_value) == 0)
+      for (list = setup_file_list; list != NULL; list = list->next)
+      {
+       char *value = getHashEntry(extra_file_hash, list->token);
+
+       if (value != NULL && strcmp(value, known_token_value) == 0)
          Error(ERR_RETURN, "- dynamic token: '%s'", list->token);
+      }
 
       Error(ERR_RETURN_LINE, "-");
     }
@@ -2149,15 +2213,21 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
       Error(ERR_RETURN, "warning: unknown token(s) found in config file:");
       Error(ERR_RETURN, "- config file: '%s'", filename);
 
-      for (list = extra_file_list; list != NULL; list = list->next)
-       if (strcmp(list->value, known_token_value) != 0)
-         Error(ERR_RETURN, "- unknown token: '%s'", list->token);
+      for (list = setup_file_list; list != NULL; list = list->next)
+      {
+       char *value = getHashEntry(extra_file_hash, list->token);
+
+       if (value != NULL && strcmp(value, known_token_value) != 0)
+         Error(ERR_RETURN, "- dynamic token: '%s'", list->token);
+      }
 
       Error(ERR_RETURN_LINE, "-");
     }
+
+    freeSetupFileList(setup_file_list);
   }
 
-  freeSetupFileList(extra_file_list);
+  freeSetupFileHash(extra_file_hash);
 
 #if 0
   for (i=0; i<num_file_list_entries; i++)