added support for using LLDB instead of GDB when debugging on Mac
[rocksndiamonds.git] / src / tape.c
index 70791579eac89cadd48d15bdb70d83a4d3176a3f..c1e4bcea9f05cb67f8035a0af5cd0336c014cd6b 100644 (file)
@@ -459,6 +459,8 @@ void TapeDeactivateDisplayOff(boolean redraw_display)
   if (redraw_display)
   {
     RedrawPlayfield();
+
+    UpdateGameDoorValues();
     DrawGameDoorValues();
   }
 }
@@ -539,7 +541,11 @@ void TapeErase(void)
   tape.length_seconds = 0;
 
   if (leveldir_current)
-    setString(&tape.level_identifier, leveldir_current->identifier);
+  {
+    strncpy(tape.level_identifier, leveldir_current->identifier,
+           MAX_FILENAME_LEN);
+    tape.level_identifier[MAX_FILENAME_LEN] = '\0';
+  }
 
   tape.level_nr = level_nr;
   tape.pos[tape.counter].delay = 0;
@@ -1158,12 +1164,7 @@ static boolean checkTapesFromSameLevel(struct TapeInfo *t1, struct TapeInfo *t2)
 
 static void CopyTape(struct TapeInfo *tape_from, struct TapeInfo *tape_to)
 {
-  if (tape_to->level_identifier != NULL)
-    checked_free(tape_to->level_identifier);
-
   *tape_to = *tape_from;
-
-  tape_to->level_identifier = getStringCopy(tape_from->level_identifier);
 }
 
 static void SwapTapes(struct TapeInfo *t1, struct TapeInfo *t2)
@@ -1237,6 +1238,7 @@ void AutoPlayTapes(void)
   {
     "original tape",
     "em_random_bug",
+    "screen_34x34",
 
     NULL
   };
@@ -1244,6 +1246,7 @@ void AutoPlayTapes(void)
   {
     VERSION_IDENT(0,0,0,0),
     VERSION_IDENT(3,3,1,0),
+    VERSION_IDENT(0,0,0,0),
 
     -1
   };
@@ -1251,6 +1254,7 @@ void AutoPlayTapes(void)
   {
     VERSION_IDENT(9,9,9,9),
     VERSION_IDENT(4,0,1,1),
+    VERSION_IDENT(4,2,2,0),
 
     -1
   };
@@ -1258,6 +1262,7 @@ void AutoPlayTapes(void)
   {
     TAPE_PROPERTY_NONE,
     TAPE_PROPERTY_EM_RANDOM_BUG,
+    TAPE_PROPERTY_NONE,
 
     -1
   };
@@ -1408,6 +1413,8 @@ void AutoPlayTapes(void)
 
     if (global.autoplay_mode == AUTOPLAY_MODE_FIX)
     {
+      boolean skip_patch = FALSE;
+
       if (tape.engine_version < patch_version_first[patch_nr] ||
          tape.engine_version > patch_version_last[patch_nr])
       {
@@ -1420,6 +1427,22 @@ void AutoPlayTapes(void)
              (tape.engine_version / 100    ) % 100,
              (tape.engine_version          ) % 100);
 
+       skip_patch = TRUE;
+      }
+
+      if (strEqual(patch_name[patch_nr], "screen_34x34") &&
+         tape.num_participating_players == 1)
+      {
+       Print("Tape %03d %s[%02d:%02d]: (%s) - skipped.\n",
+             level_nr,  tape_patch_info,
+             tape.length_seconds / 60, tape.length_seconds % 60,
+             "not suitable for single player tapes");
+
+       skip_patch = TRUE;
+      }
+
+      if (skip_patch)
+      {
        if (patch_name[patch_nr + 1] != NULL)
        {
          // continue with next patch
@@ -1434,7 +1457,15 @@ void AutoPlayTapes(void)
        continue;
       }
 
-      tape.property_bits |= patch_property_bit[patch_nr];
+      if (strEqual(patch_name[patch_nr], "screen_34x34"))
+      {
+       tape.scr_fieldx = SCR_FIELDX_DEFAULT * 2;
+       tape.scr_fieldy = SCR_FIELDY_DEFAULT * 2;
+      }
+      else
+      {
+       tape.property_bits |= patch_property_bit[patch_nr];
+      }
     }
 
     InitCounter();
@@ -1493,14 +1524,14 @@ static boolean PatchTape(struct TapeInfo *tape, char *mode)
     return FALSE;
   }
 
-  byte property_bits = tape->property_bits;
+  boolean unpatch_tape = FALSE;
+  boolean use_property_bit = FALSE;
   byte property_bitmask = 0;
-  boolean set_property_bit = TRUE;
 
   if (strSuffix(mode, ":0") ||
       strSuffix(mode, ":off") ||
       strSuffix(mode, ":clear"))
-    set_property_bit = FALSE;
+    unpatch_tape = TRUE;
 
   if (strEqual(mode, "em_random_bug") || strPrefix(mode, "em_random_bug:"))
   {
@@ -1514,6 +1545,41 @@ static boolean PatchTape(struct TapeInfo *tape, char *mode)
     }
 
     property_bitmask = TAPE_PROPERTY_EM_RANDOM_BUG;
+
+    use_property_bit = TRUE;
+  }
+  else if (strEqual(mode, "screen_34x34") || strPrefix(mode, "screen_34x34:"))
+  {
+    // this bug only affects team mode tapes
+    if (tape->num_participating_players == 1)
+    {
+      Print("Only team mode tapes can be patched against screen size bug!\n");
+
+      return FALSE;
+    }
+
+    // this bug (that always existed before) was fixed in version 4.2.2.1
+    if (tape->engine_version >= VERSION_IDENT(4,2,2,1))
+    {
+      Print("This tape version cannot be patched against screen size bug!\n");
+
+      return FALSE;
+    }
+
+    int factor = (unpatch_tape ? 1 : 2);
+    int scr_fieldx_new = SCR_FIELDX_DEFAULT * factor;
+    int scr_fieldy_new = SCR_FIELDY_DEFAULT * factor;
+
+    if (scr_fieldx_new == tape->scr_fieldx &&
+       scr_fieldy_new == tape->scr_fieldy)
+    {
+      Print("Tape already patched for '%s'!\n", mode);
+
+      return FALSE;
+    }
+
+    tape->scr_fieldx = scr_fieldx_new;
+    tape->scr_fieldy = scr_fieldy_new;
   }
   else
   {
@@ -1522,22 +1588,29 @@ static boolean PatchTape(struct TapeInfo *tape, char *mode)
     return FALSE;
   }
 
-  if (set_property_bit)
-    property_bits |= property_bitmask;
-  else
-    property_bits &= ~property_bitmask;
-
-  if (property_bits == tape->property_bits)
+  // patching tapes using property bits may be used for several patch modes
+  if (use_property_bit)
   {
-    Print("Tape already patched for '%s'!\n", mode);
+    byte property_bits = tape->property_bits;
+    boolean set_property_bit = (unpatch_tape ? FALSE : TRUE);
 
-    return FALSE;
+    if (set_property_bit)
+      property_bits |= property_bitmask;
+    else
+      property_bits &= ~property_bitmask;
+
+    if (property_bits == tape->property_bits)
+    {
+      Print("Tape already patched for '%s'!\n", mode);
+
+      return FALSE;
+    }
+
+    tape->property_bits = property_bits;
   }
 
   Print("Patching for '%s' ... ", mode);
 
-  tape->property_bits = property_bits;
-
   return TRUE;
 }
 
@@ -1554,6 +1627,7 @@ void PatchTapes(void)
     PrintLine("=", 79);
     Print("Supported patch modes:\n");
     Print("- \"em_random_bug\"   - use 64-bit random value bug for EM engine\n");
+    Print("- \"screen_34x34\"    - force visible playfield size of 34 x 34\n");
     PrintLine("-", 79);
     Print("Supported modifiers:\n");
     Print("- add \":0\", \":off\" or \":clear\" to patch mode to un-patch tape file\n");