added handling 64-bit random value bug with old tapes in EM engine
authorHolger Schemel <info@artsoft.org>
Thu, 10 Sep 2020 18:19:20 +0000 (20:19 +0200)
committerHolger Schemel <info@artsoft.org>
Thu, 10 Sep 2020 18:28:02 +0000 (20:28 +0200)
See commits 61c3da0 (incomplete fix) and c92edfe9 (final fix) for
details about this problem that was introduced (by a partial fix) in
version 3.3.1.0 and finally fixed in version 4.0.1.2, which resulted
in many tapes recorded between these versions with the EM game engine
to be broken.

To fix these broken tapes, it is required to set a new property bit in
all existing tape files that are affected by this bug.

The functionality to automatically patch these tapes will be added as
a new command line option.

src/game.c
src/game_em/convert.c
src/game_em/export.h
src/game_em/logic.c
src/tape.h

index 3544dcf7be975d6724bca3a9999dd46455f1751d..ea44ebd1b295e0fbd134a548d6f12fd0d56b0cc9 100644 (file)
@@ -2990,6 +2990,9 @@ static void InitGameEngine(void)
   game_em.use_snap_key_bug =
     (game.engine_version < VERSION_IDENT(4,0,1,0));
 
+  game_em.use_random_bug =
+    (tape.property_bits & TAPE_PROPERTY_EM_RANDOM_BUG);
+
   boolean use_old_em_engine = (game.engine_version < VERSION_IDENT(4,2,0,0));
 
   game_em.use_old_explosions           = use_old_em_engine;
index 993810648ea39c8e94941010a0d30cb6be9bb9cb..2ea8e96215aeb08299cd39203a0f34502605ae64 100644 (file)
@@ -461,6 +461,7 @@ void prepare_em_level(void)
   //
   // - game_em.use_single_button (default: TRUE)
   // - game_em.use_snap_key_bug (default: FALSE)
+  // - game_em.use_random_bug (default: FALSE)
   // - game_em.use_old_explosions (default: FALSE)
   // - game_em.use_old_android (default: FALSE)
   // - game_em.use_old_push_elements (default: FALSE)
index 51401e679cc582b19888ed70bdfc3a111419c10a..c5373fdb8a0af92ed48f1995b8d0d804fe40a384 100644 (file)
@@ -45,6 +45,7 @@ struct GameInfo_EM
   // flags to handle bugs in and changes between different engine versions
   boolean use_single_button;
   boolean use_snap_key_bug;
+  boolean use_random_bug;
   boolean use_old_explosions;
   boolean use_old_android;
   boolean use_old_push_elements;
index 68a977aad53bb02c072445e020b63ac5264a35f7..ba823a0ca86b20e6855ad35ba49d80862e5b36e6 100644 (file)
@@ -12,6 +12,8 @@
 #define ACID_ROLL      /* rolling objects go into acid rather than remove it */
 #define ACID_PLAYER    /* player gets killed by acid, but without explosion */
 
+#define RANDOM_BUG     /* handle problem with old tapes using 64-bit random */
+
 #define RANDOM(x)      ((seed = seed << 31 | seed >> 1) % x)
 
 static short **cave, **next, **boom;
@@ -7485,7 +7487,11 @@ static void logic_globals(void)
   int x;
   int y;
   int count;
-  unsigned int random;
+#ifdef RANDOM_BUG
+  uint64_t random;
+#else
+  uint32_t random;
+#endif
 
   cave = lev.cave;
   next = lev.next;
@@ -7531,6 +7537,11 @@ static void logic_globals(void)
       Lamoeba(x, y);
 
     random = random * 129 + 1;
+
+#ifdef RANDOM_BUG
+    if (!game_em.use_random_bug)
+      random = (uint32_t)random;
+#endif
   }
 
   game_em.random = random;
index c8c0675936fbdbdf81db5dc1169c8a4a218f1922..d5a19ac89c61c5eb890f21e0b1de6828bca28882 100644 (file)
@@ -37,6 +37,7 @@
 
 // values for tape properties stored in tape file
 #define TAPE_PROPERTY_NONE             0
+#define TAPE_PROPERTY_EM_RANDOM_BUG    (1 << 0)
 
 // some positions in the video tape control window
 #define VIDEO_DISPLAY1_XPOS    5