added waiting for press/release events when waiting for events to continue
[rocksndiamonds.git] / src / game_em / logic.c
index 3c68bfb9f73ea6250de9abf3ef47b29ec65ad8a1..8b759630e93bc8524f02d7c7663af538b7134030 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;
@@ -165,7 +167,7 @@ static void Lboom_eater(int x, int y)
   boom[x][y+1]   = lev.eater_array[lev.eater_pos][7];
   boom[x+1][y+1] = lev.eater_array[lev.eater_pos][8];
 
-  lev.eater_pos = (lev.eater_pos + 1) % 8;
+  lev.eater_pos = (lev.eater_pos + 1) % lev.num_eater_arrays;
 
 #if PLAY_ELEMENT_SOUND
   play_element_sound(x, y, SOUND_boom, Xeater_n);
@@ -245,6 +247,15 @@ static void Lboom_next_new(int x, int y, int element)
   next[x][y] = element;
 }
 
+static void Lpush_element_old(int x, int y, int element)
+{
+  if (!game_em.use_old_push_elements)
+    return;
+
+  cave[x][y] = element;
+  next[x][y] = element;
+}
+
 static boolean player_killed(struct PLAYER *ply)
 {
   int x = ply->x;
@@ -5709,6 +5720,9 @@ static void Lpush_emerald_e(int x, int y)
 
   switch (cave[x+1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -5720,6 +5734,7 @@ static void Lpush_emerald_e(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xemerald);
       return;
 
 #ifdef ACID_ROLL
@@ -5731,6 +5746,8 @@ static void Lpush_emerald_e(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x+2][y-1] == Xblank)
        cave[x+2][y-1] = Xsplash_e;
       if (cave[x][y-1] == Xblank)
@@ -5751,6 +5768,9 @@ static void Lpush_emerald_w(int x, int y)
 
   switch (cave[x-1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -5762,6 +5782,7 @@ static void Lpush_emerald_w(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xemerald);
       return;
 
 #ifdef ACID_ROLL
@@ -5773,6 +5794,8 @@ static void Lpush_emerald_w(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x][y-1] == Xblank)
        cave[x][y-1] = Xsplash_e;
       if (cave[x-2][y-1] == Xblank)
@@ -5793,6 +5816,9 @@ static void Lpush_diamond_e(int x, int y)
 
   switch (cave[x+1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -5804,6 +5830,7 @@ static void Lpush_diamond_e(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xdiamond);
       return;
 
 #ifdef ACID_ROLL
@@ -5815,6 +5842,8 @@ static void Lpush_diamond_e(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x+2][y-1] == Xblank)
        cave[x+2][y-1] = Xsplash_e;
       if (cave[x][y-1] == Xblank)
@@ -5835,6 +5864,9 @@ static void Lpush_diamond_w(int x, int y)
 
   switch (cave[x-1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -5846,6 +5878,7 @@ static void Lpush_diamond_w(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xdiamond);
       return;
 
 #ifdef ACID_ROLL
@@ -5857,6 +5890,8 @@ static void Lpush_diamond_w(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x][y-1] == Xblank)
        cave[x][y-1] = Xsplash_e;
       if (cave[x-2][y-1] == Xblank)
@@ -5877,6 +5912,9 @@ static void Lpush_stone_e(int x, int y)
 
   switch (cave[x+1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -5888,6 +5926,7 @@ static void Lpush_stone_e(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xstone);
       return;
 
 #ifdef ACID_ROLL
@@ -5899,6 +5938,8 @@ static void Lpush_stone_e(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x+2][y-1] == Xblank)
        cave[x+2][y-1] = Xsplash_e;
       if (cave[x][y-1] == Xblank)
@@ -5919,6 +5960,9 @@ static void Lpush_stone_w(int x, int y)
 
   switch (cave[x-1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -5930,6 +5974,7 @@ static void Lpush_stone_w(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xstone);
       return;
 
 #ifdef ACID_ROLL
@@ -5941,6 +5986,8 @@ static void Lpush_stone_w(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x][y-1] == Xblank)
        cave[x][y-1] = Xsplash_e;
       if (cave[x-2][y-1] == Xblank)
@@ -5961,6 +6008,9 @@ static void Lpush_bomb_e(int x, int y)
 
   switch (cave[x+1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -5972,6 +6022,7 @@ static void Lpush_bomb_e(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xbomb);
       return;
 
 #ifdef ACID_ROLL
@@ -5983,6 +6034,8 @@ static void Lpush_bomb_e(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x+2][y-1] == Xblank)
        cave[x+2][y-1] = Xsplash_e;
       if (cave[x][y-1] == Xblank)
@@ -6003,6 +6056,9 @@ static void Lpush_bomb_w(int x, int y)
 
   switch (cave[x-1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -6014,6 +6070,7 @@ static void Lpush_bomb_w(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xbomb);
       return;
 
 #ifdef ACID_ROLL
@@ -6025,6 +6082,8 @@ static void Lpush_bomb_w(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x][y-1] == Xblank)
        cave[x][y-1] = Xsplash_e;
       if (cave[x-2][y-1] == Xblank)
@@ -6045,6 +6104,9 @@ static void Lpush_nut_e(int x, int y)
 
   switch (cave[x+1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -6056,6 +6118,7 @@ static void Lpush_nut_e(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xnut);
       return;
 
 #ifdef ACID_ROLL
@@ -6067,6 +6130,8 @@ static void Lpush_nut_e(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x+2][y-1] == Xblank)
        cave[x+2][y-1] = Xsplash_e;
       if (cave[x][y-1] == Xblank)
@@ -6087,6 +6152,9 @@ static void Lpush_nut_w(int x, int y)
 
   switch (cave[x-1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -6098,6 +6166,7 @@ static void Lpush_nut_w(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xnut);
       return;
 
 #ifdef ACID_ROLL
@@ -6109,6 +6178,8 @@ static void Lpush_nut_w(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x][y-1] == Xblank)
        cave[x][y-1] = Xsplash_e;
       if (cave[x-2][y-1] == Xblank)
@@ -6129,6 +6200,9 @@ static void Lpush_spring_e(int x, int y)
 
   switch (cave[x+1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -6140,6 +6214,7 @@ static void Lpush_spring_e(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xspring);
       return;
 
 #ifdef ACID_ROLL
@@ -6151,6 +6226,8 @@ static void Lpush_spring_e(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x+2][y-1] == Xblank)
        cave[x+2][y-1] = Xsplash_e;
       if (cave[x][y-1] == Xblank)
@@ -6171,6 +6248,9 @@ static void Lpush_spring_w(int x, int y)
 
   switch (cave[x-1][y])
   {
+    case Zplayer:
+      if (!game_em.use_old_push_elements)
+       break;
     case Zborder:
     case Zbug:
     case Ztank:
@@ -6182,6 +6262,7 @@ static void Lpush_spring_w(int x, int y)
     case Xboom_tank:
     case Xboom_android:
     case Xboom_1:
+      Lpush_element_old(x, y, Xspring);
       return;
 
 #ifdef ACID_ROLL
@@ -6193,6 +6274,8 @@ static void Lpush_spring_w(int x, int y)
     case Xacid_6:
     case Xacid_7:
     case Xacid_8:
+      if (game_em.use_old_push_into_acid)
+       break;
       if (cave[x][y-1] == Xblank)
        cave[x][y-1] = Xsplash_e;
       if (cave[x-2][y-1] == Xblank)
@@ -7298,27 +7381,28 @@ static void handle_tile(int x, int y)
   }
 }
 
-static void logic_players(void)
+boolean logic_check_wrap(void)
 {
-  int start_check_nr;
   int i;
 
-  cave = lev.cave;
-  next = lev.next;
-  boom = lev.boom;
-
-  game_em.any_player_moving = FALSE;
-  game_em.any_player_snapping = FALSE;
-
-  /* must test for death and actually kill separately */
   for (i = 0; i < MAX_PLAYERS; i++)
   {
-    boolean ply_kill = player_killed(&ply[i]);
+    if (!ply[i].alive)
+      continue;
 
-    if (ply[i].alive && ply_kill)
-      kill_player(&ply[i]);
+    /* check for wrap-around movement */
+    if (ply[i].x < lev.left ||
+       ply[i].x > lev.right - 1)
+      return TRUE;
   }
 
+  return FALSE;
+}
+
+void logic_move(void)
+{
+  int i;
+
   for (i = 0; i < MAX_PLAYERS; i++)
   {
     if (!ply[i].alive)
@@ -7330,6 +7414,9 @@ static void logic_players(void)
     {
       ply[i].x = (ply[i].x < lev.left ? lev.right - 1 : lev.left);
 
+      if (!lev.infinite_true)
+       ply[i].y += (ply[i].x == lev.left ? 1 : -1);
+
       game.centered_player_nr_next = i;
       game.set_centered_player = TRUE;
       game.set_centered_player_wrap = TRUE;
@@ -7339,6 +7426,30 @@ static void logic_players(void)
     ply[i].prev_y = ply[i].y;
     ply[i].anim = PLY_still;
   }
+}
+
+static void logic_players(void)
+{
+  int start_check_nr;
+  int i;
+
+  cave = lev.cave;
+  next = lev.next;
+  boom = lev.boom;
+
+  game_em.any_player_moving = FALSE;
+  game_em.any_player_snapping = FALSE;
+
+  /* must test for death and actually kill separately */
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    boolean ply_kill = player_killed(&ply[i]);
+
+    if (ply[i].alive && ply_kill)
+      kill_player(&ply[i]);
+  }
+
+  logic_move();
 
   start_check_nr = ((game_em.random & 128 ? 0 : 1) * 2 +
                    (game_em.random & 256 ? 0 : 1));
@@ -7404,7 +7515,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;
@@ -7450,6 +7565,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;