rnd-20030413-1-src
[rocksndiamonds.git] / src / libgame / misc.c
index f35620c237768cadcb77ac225d9bf8ba7c168bc0..efb56bba2cfc6d9030c5de4e1be6dc74f151f9e4 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;
@@ -261,74 +261,70 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
 /* random generator functions                                                */
 /* ------------------------------------------------------------------------- */
 
+#if 0
 unsigned int SimpleRND(unsigned int max)
 {
-#if defined(TARGET_SDL)
-  static unsigned long root = 654321;
-  unsigned long current_ms;
+  return (random_linux_libc(RND_FREE) % max);
+}
 
-  current_ms = SDL_GetTicks();
-  root = root * 4253261 + current_ms;
-  return (root % max);
-#else
-  static unsigned long root = 654321;
-  struct timeval current_time;
+unsigned int InitSimpleRND(long seed)
+{
+  if (seed == NEW_RANDOMIZE)
+  {
+    struct timeval current_time;
 
-  gettimeofday(&current_time, NULL);
-  root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
-  return (root % max);
-#endif
-}
+    gettimeofday(&current_time, NULL);
+    seed = (long)current_time.tv_usec;
+  }
 
-#ifdef DEBUG
-static unsigned int last_RND_value = 0;
+  srandom_linux_libc(RND_FREE, (unsigned int) seed);
 
-unsigned int last_RND()
-{
-  return last_RND_value;
+  return (unsigned int) seed;
 }
-#endif
 
 unsigned int RND(unsigned int max)
 {
-#ifdef DEBUG
-  return (last_RND_value = random_linux_libc() % max);
-#else
-  return (random_linux_libc() % max);
-#endif
+  return (random_linux_libc(RND_GAME) % max);
 }
 
 unsigned int InitRND(long seed)
 {
-#if defined(TARGET_SDL)
-  unsigned long current_ms;
-
   if (seed == NEW_RANDOMIZE)
   {
-    current_ms = SDL_GetTicks();
-    srandom_linux_libc((unsigned int) current_ms);
-    return (unsigned int) current_ms;
-  }
-  else
-  {
-    srandom_linux_libc((unsigned int) seed);
-    return (unsigned int) seed;
+    struct timeval current_time;
+
+    gettimeofday(&current_time, NULL);
+    seed = (long)current_time.tv_usec;
   }
-#else
-  struct timeval current_time;
 
+  srandom_linux_libc(RND_GAME, (unsigned int) seed);
+
+  return (unsigned int) seed;
+}
+#endif
+
+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);
-    srandom_linux_libc((unsigned int) current_time.tv_usec);
-    return (unsigned int) current_time.tv_usec;
-  }
-  else
-  {
-    srandom_linux_libc((unsigned int) seed);
-    return (unsigned int) seed;
-  }
+    seed = (long)current_time.tv_usec;
 #endif
+  }
+
+  srandom_linux_libc(nr, (unsigned int) seed);
+
+  return (unsigned int) seed;
+}
+
+unsigned int get_random_number(int nr, unsigned int max)
+{
+  return (random_linux_libc(nr) % max);
 }
 
 
@@ -336,13 +332,53 @@ unsigned int InitRND(long seed)
 /* 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;
@@ -352,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 (home_dir == NULL)
+#if defined(PLATFORM_WIN32)
+  if (dir == NULL)
   {
-    if ((home_dir = getenv("HOME")) == NULL)
+    dir = checked_malloc(MAX_PATH + 1);
+
+    if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir)))
+      strcpy(dir, ".");
+  }
+#elif defined(PLATFORM_UNIX)
+  if (dir == 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;
 }
 
 
@@ -429,6 +468,7 @@ char *getPath2(char *path1, char *path2)
                                       strlen(path2) + 1);
 
   sprintf(complete_path, "%s/%s", path1, path2);
+
   return complete_path;
 }
 
@@ -439,6 +479,7 @@ char *getPath3(char *path1, char *path2, char *path3)
                                       strlen(path3) + 1);
 
   sprintf(complete_path, "%s/%s/%s", path1, path2, path3);
+
   return complete_path;
 }
 
@@ -447,6 +488,7 @@ char *getStringCat2(char *s1, char *s2)
   char *complete_string = checked_malloc(strlen(s1) + strlen(s2) + 1);
 
   sprintf(complete_string, "%s%s", s1, s2);
+
   return complete_string;
 }
 
@@ -458,8 +500,8 @@ char *getStringCopy(char *s)
     return NULL;
 
   s_copy = checked_malloc(strlen(s) + 1);
-
   strcpy(s_copy, s);
+
   return s_copy;
 }
 
@@ -531,12 +573,18 @@ 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;
   options.verbose = FALSE;
   options.debug = FALSE;
 
+#if !defined(PLATFORM_UNIX)
+  if (*options_left == NULL)   /* no options given -- enable verbose mode */
+    options.verbose = TRUE;
+#endif
+
   while (*options_left)
   {
     char option_str[MAX_OPTION_LEN];
@@ -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 &&
@@ -1507,12 +1564,79 @@ boolean FileIsArtworkType(char *basename, int type)
 /* functions for loading artwork configuration information                   */
 /* ------------------------------------------------------------------------- */
 
-int get_parameter_value(int type, char *value)
+/* This function checks if a string <s> of the format "string1, string2, ..."
+   exactly contains a string <s_contained>. */
+
+static boolean string_has_parameter(char *s, char *s_contained)
+{
+  char *substring;
+
+  if (s == NULL || s_contained == NULL)
+    return FALSE;
+
+  if (strlen(s_contained) > strlen(s))
+    return FALSE;
+
+  if (strncmp(s, s_contained, strlen(s_contained)) == 0)
+  {
+    char next_char = s[strlen(s_contained)];
+
+    /* check if next character is delimiter or whitespace */
+    return (next_char == ',' || next_char == '\0' ||
+           next_char == ' ' || next_char == '\t' ? TRUE : FALSE);
+  }
+
+  /* check if string contains another parameter string after a comma */
+  substring = strchr(s, ',');
+  if (substring == NULL)       /* string does not contain a comma */
+    return FALSE;
+
+  /* advance string pointer to next character after the comma */
+  substring++;
+
+  /* skip potential whitespaces after the comma */
+  while (*substring == ' ' || *substring == '\t')
+    substring++;
+
+  return string_has_parameter(substring, s_contained);
+}
+
+int get_parameter_value(char *token, char *value_raw, int type)
 {
-  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) :
-         ARG_UNDEFINED_VALUE);
+  char *value = getStringToLower(value_raw);
+  int result = 0;      /* probably a save default value */
+
+  if (strcmp(token, ".direction") == 0)
+  {
+    result = (strcmp(value, "left")  == 0 ? MV_LEFT :
+             strcmp(value, "right") == 0 ? MV_RIGHT :
+             strcmp(value, "up")    == 0 ? MV_UP :
+             strcmp(value, "down")  == 0 ? MV_DOWN : MV_NO_MOVING);
+  }
+  else if (strcmp(token, ".anim_mode") == 0)
+  {
+    result = (string_has_parameter(value, "loop")      ? ANIM_LOOP :
+             string_has_parameter(value, "linear")    ? ANIM_LINEAR :
+             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"))
+      result |= ANIM_REVERSE;
+  }
+  else         /* generic parameter of type integer or boolean */
+  {
+    result = (strcmp(value, ARG_UNDEFINED) == 0 ? ARG_UNDEFINED_VALUE :
+             type == TYPE_INTEGER ? get_integer_from_string(value) :
+             type == TYPE_BOOLEAN ? get_boolean_from_string(value) :
+             ARG_UNDEFINED_VALUE);
+  }
+
+  free(value);
+
+  return result;
 }
 
 static void FreeCustomArtworkList(struct ArtworkListInfo *,
@@ -1520,6 +1644,7 @@ static void FreeCustomArtworkList(struct ArtworkListInfo *,
 
 struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
                                           struct ConfigInfo *suffix_list,
+                                          char **ignore_tokens,
                                           int num_file_list_entries)
 {
   struct FileInfo *file_list;
@@ -1580,9 +1705,9 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
     }
 
     /* the following tokens are no file definitions, but other config tokens */
-    if (strcmp(config_list[i].token, "global.num_toons") == 0 ||
-       strcmp(config_list[i].token, "menu.main.hide_static_text") == 0)
-      is_file_entry = FALSE;
+    for (j=0; ignore_tokens[j] != NULL; j++)
+      if (strcmp(config_list[i].token, ignore_tokens[j]) == 0)
+       is_file_entry = FALSE;
 
     if (is_file_entry)
     {