rnd-19981120-1
[rocksndiamonds.git] / src / misc.c
index 7d0a7fde159d3fff69de8e447ac15f32c124f4a4..2c01f36401e0e7eed881a71f23b5e1f4ab2baa3e 100644 (file)
@@ -18,6 +18,7 @@
 #include <sys/param.h>
 #include <sys/types.h>
 #include <stdarg.h>
+#include <ctype.h>
 
 #include "misc.h"
 #include "init.h"
@@ -158,9 +159,22 @@ unsigned int SimpleRND(unsigned int max)
   return (root % max);
 }
 
+#ifdef DEBUG
+static unsigned int last_RND_value = 0;
+
+unsigned int last_RND()
+{
+  return last_RND_value;
+}
+#endif
+
 unsigned int RND(unsigned int max)
 {
+#ifdef DEBUG
+  return (last_RND_value = random_linux_libc() % max);
+#else
   return (random_linux_libc() % max);
+#endif
 }
 
 unsigned int InitRND(long seed)
@@ -210,6 +224,33 @@ char *getHomeDir()
   return home_dir;
 }
 
+char *getPath2(char *path1, char *path2)
+{
+  char *complete_path = checked_malloc(strlen(path1) + strlen(path2) + 2);
+
+  sprintf(complete_path, "%s/%s", path1, path2);
+  return complete_path;
+}
+
+char *getStringCopy(char *s)
+{
+  char *s_copy = checked_malloc(strlen(s) + 1);
+
+  strcpy(s_copy, s);
+  return s_copy;
+}
+
+char *getStringToLower(char *s)
+{
+  char *s_copy = checked_malloc(strlen(s) + 1);
+  char *s_ptr = s_copy;
+
+  while (*s)
+    *s_ptr++ = tolower(*s++);
+
+  return s_copy;
+}
+
 void MarkTileDirty(int x, int y)
 {
   int xx = redraw_x1 + x;
@@ -230,6 +271,8 @@ void GetOptions(char *argv[])
   options.display_name = NULL;
   options.server_host = NULL;
   options.server_port = 0;
+  options.base_directory = BASE_PATH;
+  options.level_directory = BASE_PATH "/" LEVELS_DIRECTORY;
   options.serveronly = FALSE;
   options.network = FALSE;
   options.verbose = FALSE;
@@ -273,6 +316,7 @@ void GetOptions(char *argv[])
       printf("Usage: %s [options] [server.name [port]]\n"
             "Options:\n"
             "  -d, --display machine:0       X server display\n"
+            "  -b, --basepath directory      alternative base directory\n"
             "  -l, --levels directory        alternative level directory\n"
             "  -s, --serveronly              only start network server\n"
             "  -n, --network                 network multiplayer game\n"
@@ -291,16 +335,33 @@ void GetOptions(char *argv[])
 
       printf("--display == '%s'\n", options.display_name);
     }
+    else if (strncmp(option, "-basepath", option_len) == 0)
+    {
+      if (option_arg == NULL)
+       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
+
+      options.base_directory = option_arg;
+      if (option_arg == next_option)
+       options_left++;
+
+      printf("--basepath == '%s'\n", options.base_directory);
+
+      /* adjust path for level directory accordingly */
+      options.level_directory = checked_malloc(strlen(options.base_directory) +
+                                              strlen(LEVELS_DIRECTORY) + 2);
+      sprintf(options.level_directory, "%s/%s",
+             options.base_directory, LEVELS_DIRECTORY);
+    }
     else if (strncmp(option, "-levels", option_len) == 0)
     {
       if (option_arg == NULL)
        Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
 
-      level_directory = option_arg;
+      options.level_directory = option_arg;
       if (option_arg == next_option)
        options_left++;
 
-      printf("--levels == '%s'\n", level_directory);
+      printf("--levels == '%s'\n", options.level_directory);
     }
     else if (strncmp(option, "-network", option_len) == 0)
     {
@@ -343,7 +404,7 @@ void GetOptions(char *argv[])
   }
 }
 
-void Error(int mode, char *format_str, ...)
+void Error(int mode, char *format, ...)
 {
   FILE *output_stream = stderr;
   char *process_name = "";
@@ -351,53 +412,17 @@ void Error(int mode, char *format_str, ...)
   if (mode & ERR_SOUNDSERVER)
     process_name = " sound server";
 
-  if (format_str)
+  if (format)
   {
     va_list ap;
-    char *format_ptr;
-    char *s_value;
-    int i_value;
-    double d_value;
 
     fprintf(output_stream, "%s%s: ", program_name, process_name);
 
     if (mode & ERR_WARN)
       fprintf(output_stream, "warning: ");
 
-    va_start(ap, format_str);  /* ap points to first unnamed argument */
-  
-    for(format_ptr=format_str; *format_ptr; format_ptr++)
-    {
-      if (*format_ptr != '%')
-      {
-       fprintf(output_stream, "%c", *format_ptr);
-       continue;
-      }
-  
-      switch(*++format_ptr)
-      {
-       case 'd':
-         i_value = va_arg(ap, int);
-         fprintf(output_stream, "%d", i_value);
-         break;
-  
-       case 'f':
-         d_value = va_arg(ap, double);
-         fprintf(output_stream, "%f", d_value);
-         break;
-  
-       case 's':
-         s_value = va_arg(ap, char *);
-         fprintf(output_stream, "%s", s_value);
-         break;
-  
-       default:
-         fprintf(stderr, "\n%s: Error(): invalid format string: %s\n",
-                 program_name, format_str);
-         CloseAllAndExit(10);
-      }
-    }
-
+    va_start(ap, format);
+    vfprintf(output_stream, format, ap);
     va_end(ap);
   
     fprintf(output_stream, "\n");
@@ -426,6 +451,18 @@ void *checked_malloc(unsigned long size)
   return ptr;
 }
 
+void *checked_calloc(unsigned long size)
+{
+  void *ptr;
+
+  ptr = calloc(1, size);
+
+  if (ptr == NULL)
+    Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size);
+
+  return ptr;
+}
+
 #define TRANSLATE_KEYSYM_TO_KEYNAME    0
 #define TRANSLATE_KEYSYM_TO_X11KEYNAME 1
 #define TRANSLATE_X11KEYNAME_TO_KEYSYM 2
@@ -754,3 +791,22 @@ int getJoySymbolFromJoyName(char *name)
   translate_joyname(&joysymbol, &name, TRANSLATE_JOYNAME_TO_JOYSYMBOL);
   return joysymbol;
 }
+
+/* the following is only for debugging purpose and normally not used */
+#define DEBUG_NUM_TIMESTAMPS   3
+
+void debug_print_timestamp(int counter_nr, char *message)
+{
+  static long counter[DEBUG_NUM_TIMESTAMPS][2];
+
+  if (counter_nr >= DEBUG_NUM_TIMESTAMPS)
+    Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c");
+
+  counter[counter_nr][0] = Counter();
+
+  if (message)
+    printf("%s %.2f seconds\n", message,
+          (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000);
+
+  counter[counter_nr][1] = Counter();
+}