improved startup speed by optimizing parsing of parameter values
[rocksndiamonds.git] / src / files.c
index d34f3fe30b298172ced69349277af3bff81e7845..49813391c63e0e7a733a23447cb5e09862ee8eb2 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/
 // ----------------------------------------------------------------------------
 // files.c
 // ============================================================================
@@ -58,7 +58,7 @@
 
 #define TAPE_CHUNK_VERS_SIZE   8       // size of file version chunk
 #define TAPE_CHUNK_HEAD_SIZE   20      // size of tape file header
-#define TAPE_CHUNK_HEAD_UNUSED 2       // unused tape header bytes
+#define TAPE_CHUNK_HEAD_UNUSED 1       // unused tape header bytes
 
 #define LEVEL_CHUNK_CNT3_SIZE(x)        (LEVEL_CHUNK_CNT3_HEADER + (x))
 #define LEVEL_CHUNK_CUS3_SIZE(x)        (2 + (x) * LEVEL_CPART_CUS3_SIZE)
@@ -3541,6 +3541,8 @@ static void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
   cav->key_score       = level->score[SC_KEY];
   cav->exit_score      = level->score[SC_TIME_BONUS];
 
+  cav->num_eater_arrays        = level->num_yamyam_contents;
+
   for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
     for (y = 0; y < 3; y++)
       for (x = 0; x < 3; x++)
@@ -3649,9 +3651,9 @@ static void CopyNativeLevel_EM_to_RND(struct LevelInfo *level)
   level->score[SC_KEY]         = cav->key_score;
   level->score[SC_TIME_BONUS]  = cav->exit_score;
 
-  level->num_yamyam_contents = MAX_ELEMENT_CONTENTS;
+  level->num_yamyam_contents   = cav->num_eater_arrays;
 
-  for (i = 0; i < level->num_yamyam_contents; i++)
+  for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
     for (y = 0; y < 3; y++)
       for (x = 0; x < 3; x++)
        level->yamyam_content[i].e[x][y] =
@@ -6594,7 +6596,7 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level)
   // copy elements to runtime playfield array
   for (x = 0; x < MAX_LEV_FIELDX; x++)
     for (y = 0; y < MAX_LEV_FIELDY; y++)
-      Feld[x][y] = level->field[x][y];
+      Tile[x][y] = level->field[x][y];
 
   // initialize level size variables for faster access
   lev_fieldx = level->fieldx;
@@ -7608,6 +7610,8 @@ static void setTapeInfoToDefaults(void)
   // at least one (default: the first) player participates in every tape
   tape.num_participating_players = 1;
 
+  tape.property_bits = TAPE_PROPERTY_NONE;
+
   tape.level_nr = level_nr;
   tape.counter = 0;
   tape.changed = FALSE;
@@ -7692,6 +7696,8 @@ static int LoadTape_HEAD(File *file, int chunk_size, struct TapeInfo *tape)
 
     setTapeActionFlags(tape, getFile8Bit(file));
 
+    tape->property_bits = getFile8Bit(file);
+
     ReadUnusedBytesFromFile(file, TAPE_CHUNK_HEAD_UNUSED);
 
     engine_version = getFileVersion(file);
@@ -8093,6 +8099,8 @@ static void SaveTape_HEAD(FILE *file, struct TapeInfo *tape)
 
   putFile8Bit(file, getTapeActionValue(tape));
 
+  putFile8Bit(file, tape->property_bits);
+
   // unused bytes not at the end here for 4-byte alignment of engine_version
   WriteUnusedBytesToFile(file, TAPE_CHUNK_HEAD_UNUSED);
 
@@ -8136,16 +8144,12 @@ static void SaveTape_BODY(FILE *file, struct TapeInfo *tape)
   }
 }
 
-void SaveTape(int nr)
+void SaveTapeToFilename(char *filename)
 {
-  char *filename = getTapeFilename(nr);
   FILE *file;
   int tape_pos_size;
   int info_chunk_size;
   int body_chunk_size;
-  int i;
-
-  InitTapeDirectory(leveldir_current->subdir);
 
   if (!(file = fopen(filename, MODE_WRITE)))
   {
@@ -8153,16 +8157,6 @@ void SaveTape(int nr)
     return;
   }
 
-  tape.file_version = FILE_VERSION_ACTUAL;
-  tape.game_version = GAME_VERSION_ACTUAL;
-
-  tape.num_participating_players = 0;
-
-  // count number of participating players
-  for (i = 0; i < MAX_PLAYERS; i++)
-    if (tape.player_participates[i])
-      tape.num_participating_players++;
-
   tape_pos_size = getTapePosSize(&tape);
 
   info_chunk_size = 2 + (strlen(tape.level_identifier) + 1) + 2;
@@ -8186,6 +8180,26 @@ void SaveTape(int nr)
   fclose(file);
 
   SetFilePermissions(filename, PERMS_PRIVATE);
+}
+
+void SaveTape(int nr)
+{
+  char *filename = getTapeFilename(nr);
+  int i;
+
+  InitTapeDirectory(leveldir_current->subdir);
+
+  tape.file_version = FILE_VERSION_ACTUAL;
+  tape.game_version = GAME_VERSION_ACTUAL;
+
+  tape.num_participating_players = 0;
+
+  // count number of participating players
+  for (i = 0; i < MAX_PLAYERS; i++)
+    if (tape.player_participates[i])
+      tape.num_participating_players++;
+
+  SaveTapeToFilename(filename);
 
   tape.changed = FALSE;
 }
@@ -8505,6 +8519,10 @@ static struct TokenInfo global_setup_tokens[] =
     TYPE_SWITCH,
     &setup.prefer_aga_graphics,                        "prefer_aga_graphics"
   },
+  {
+    TYPE_SWITCH,
+    &setup.prefer_lowpass_sounds,              "prefer_lowpass_sounds"
+  },
   {
     TYPE_SWITCH,
     &setup.game_speed_extended,                        "game_speed_extended"
@@ -8882,6 +8900,10 @@ static struct TokenInfo player_setup_tokens[] =
 
 static struct TokenInfo system_setup_tokens[] =
 {
+  {
+    TYPE_STRING,
+    &setup.system.sdl_renderdriver,            "system.sdl_renderdriver"
+  },
   {
     TYPE_STRING,
     &setup.system.sdl_videodriver,             "system.sdl_videodriver"
@@ -9176,6 +9198,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->quick_switch = FALSE;
   si->input_on_focus = FALSE;
   si->prefer_aga_graphics = TRUE;
+  si->prefer_lowpass_sounds = FALSE;
   si->game_speed_extended = FALSE;
   si->game_frame_delay = GAME_FRAME_DELAY;
   si->sp_show_border_elements = FALSE;
@@ -9327,6 +9350,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
     si->input[i].key.drop  = (i == 0 ? DEFAULT_KEY_DROP  : KSYM_UNDEFINED);
   }
 
+  si->system.sdl_renderdriver = getStringCopy(ARG_DEFAULT);
   si->system.sdl_videodriver = getStringCopy(ARG_DEFAULT);
   si->system.sdl_audiodriver = getStringCopy(ARG_DEFAULT);
   si->system.audio_fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
@@ -10222,6 +10246,10 @@ static int get_anim_parameter_values(char *s)
 
 static int get_anim_action_parameter_value(char *token)
 {
+  // check most common default case first to massively speed things up
+  if (strEqual(token, ARG_UNDEFINED))
+    return ANIM_EVENT_ACTION_NONE;
+
   int result = getImageIDFromToken(token);
 
   if (result == -1)