improved startup speed by optimizing parsing of parameter values
[rocksndiamonds.git] / src / init.c
index 04d7f32a228cc26d53b5e85ce8143c3f6b83c194..be7447666d29dc90c4e29ca326d51a365bb2c84d 100644 (file)
@@ -4,7 +4,7 @@
 // (c) 1995-2014 by Artsoft Entertainment
 //                         Holger Schemel
 //                 info@artsoft.org
-//                 http://www.artsoft.org/
+//                 https://www.artsoft.org/
 // ----------------------------------------------------------------------------
 // init.c
 // ============================================================================
@@ -77,6 +77,11 @@ static int copy_properties[][5] =
     EL_MOLE_LEFT,              EL_MOLE_RIGHT,
     EL_MOLE_UP,                        EL_MOLE_DOWN
   },
+  {
+    EL_SPRING,
+    EL_SPRING_LEFT,            EL_SPRING_RIGHT,
+    EL_SPRING_LEFT,            EL_SPRING_RIGHT,        // (to match array size)
+  },
   {
     -1,
     -1, -1, -1, -1
@@ -2357,6 +2362,8 @@ static int get_special_property_bit(int element, int property_bit_nr)
     { EL_SP_ELECTRON,          15      },
     { EL_BALLOON,              16      },
     { EL_SPRING,               17      },
+    { EL_SPRING_LEFT,          17      },
+    { EL_SPRING_RIGHT,         17      },
     { EL_EMC_ANDROID,          18      },
 
     { -1,                      -1      },
@@ -4893,6 +4900,7 @@ static void InitGlobal(void)
   }
 
   global.autoplay_leveldir = NULL;
+  global.patchtapes_leveldir = NULL;
   global.convert_leveldir = NULL;
   global.create_images_dir = NULL;
 
@@ -5024,18 +5032,20 @@ static void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strPrefix(command, "autotest ") ||
-          strPrefix(command, "autoplay ") ||
+  else if (strPrefix(command, "autoplay ") ||
           strPrefix(command, "autoffwd ") ||
-          strPrefix(command, "autowarp "))
+          strPrefix(command, "autowarp ") ||
+          strPrefix(command, "autotest ") ||
+          strPrefix(command, "autofix "))
   {
-    char *str_ptr = getStringCopy(&command[9]);        // read command parameters
+    char *str_ptr = getStringCopy(&command[8]);        // read command parameters
 
     global.autoplay_mode =
-      (strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST :
-       strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY :
+      (strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY :
        strPrefix(command, "autoffwd") ? AUTOPLAY_MODE_FFWD :
        strPrefix(command, "autowarp") ? AUTOPLAY_MODE_WARP :
+       strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST :
+       strPrefix(command, "autofix")  ? AUTOPLAY_MODE_FIX :
        AUTOPLAY_MODE_NONE);
 
     while (*str_ptr != '\0')                   // continue parsing string
@@ -5070,9 +5080,68 @@ static void Execute_Command(char *command)
        str_ptr++;
     }
 
-    if (global.autoplay_mode == AUTOPLAY_MODE_TEST)
+    if (global.autoplay_mode & AUTOPLAY_MODE_WARP_NO_DISPLAY)
       program.headless = TRUE;
   }
+  else if (strPrefix(command, "patch tapes "))
+  {
+    char *str_ptr = getStringCopy(&command[12]); // read command parameters
+
+    // skip leading whitespace
+    while (*str_ptr == ' ' || *str_ptr == '\t')
+      str_ptr++;
+
+    if (*str_ptr == '\0')
+      Error(ERR_EXIT, "cannot find MODE in command '%s'", command);
+
+    global.patchtapes_mode = str_ptr;          // store patch mode
+
+    // advance to next whitespace (or end of string)
+    while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0')
+      str_ptr++;
+
+    while (*str_ptr != '\0')                   // continue parsing string
+    {
+      // cut leading whitespace from string, replace it by string terminator
+      while (*str_ptr == ' ' || *str_ptr == '\t')
+       *str_ptr++ = '\0';
+
+      if (*str_ptr == '\0')                    // end of string reached
+       break;
+
+      if (global.patchtapes_leveldir == NULL)  // read level set string
+      {
+       global.patchtapes_leveldir = str_ptr;
+       global.patchtapes_all = TRUE;           // default: patch all tapes
+
+       for (i = 0; i < MAX_TAPES_PER_SET; i++)
+         global.patchtapes_level[i] = FALSE;
+      }
+      else                                     // read level number string
+      {
+       int level_nr = atoi(str_ptr);           // get level_nr value
+
+       if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET)
+         global.patchtapes_level[level_nr] = TRUE;
+
+       global.patchtapes_all = FALSE;
+      }
+
+      // advance string pointer to the next whitespace (or end of string)
+      while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0')
+       str_ptr++;
+    }
+
+    if (global.patchtapes_leveldir == NULL)
+    {
+      if (strEqual(global.patchtapes_mode, "help"))
+       global.patchtapes_leveldir = UNDEFINED_LEVELSET;
+      else
+       Error(ERR_EXIT, "cannot find LEVELDIR in command '%s'", command);
+    }
+
+    program.headless = TRUE;
+  }
   else if (strPrefix(command, "convert "))
   {
     char *str_copy = getStringCopy(strchr(command, ' ') + 1);
@@ -6157,7 +6226,12 @@ void OpenAll(void)
 
   if (global.autoplay_leveldir)
   {
-    AutoPlayTape();
+    AutoPlayTapes();
+    return;
+  }
+  else if (global.patchtapes_leveldir)
+  {
+    PatchTapes();
     return;
   }
   else if (global.convert_leveldir)