fixed support for wrap-around levels in EM engine for old tapes
[rocksndiamonds.git] / src / game_em / convert.c
index 9ebf6f4c825afcc395df46714d44120b9d5e084b..bae0130c3920adcd4ed56a4e3e0ea4a0474855d5 100644 (file)
@@ -213,12 +213,14 @@ static const short map[CAVE_TILE_MAX] =
 
 int map_em_element_C_to_X(int element_em_cave)
 {
-  if (element_em_cave >= 0 && element_em_cave < CAVE_TILE_MAX)
-    return map[element_em_cave];
+  if (element_em_cave < 0 || element_em_cave >= CAVE_TILE_MAX)
+  {
+    Error(ERR_WARN, "invalid EM cave element %d", element_em_cave);
 
-  Error(ERR_WARN, "invalid EM cave element %d", element_em_cave);
+    return Xblank;
+  }
 
-  return Xblank;
+  return map[element_em_cave];
 }
 
 int map_em_element_X_to_C(int element_em_game)
@@ -240,19 +242,19 @@ int map_em_element_X_to_C(int element_em_game)
     map_reverse_initialized = TRUE;
   }
 
-  if (element_em_game >= 0 && element_em_game < GAME_TILE_MAX)
+  if (element_em_game < 0 || element_em_game >= GAME_TILE_MAX)
   {
-    int element_em_cave = map_reverse[element_em_game];
-
-    if (element_em_cave == Cblank && element_em_game != Xblank)
-      Error(ERR_WARN, "unknown EM game element %d", element_em_game);
+    Error(ERR_WARN, "invalid EM game element %d", element_em_game);
 
-    return element_em_cave;
+    return Cblank;
   }
 
-  Error(ERR_WARN, "invalid EM game element %d", element_em_game);
+  int element_em_cave = map_reverse[element_em_game];
 
-  return Cblank;
+  if (element_em_cave == Cblank && element_em_game != Xblank)
+    Error(ERR_WARN, "unknown EM game element %d", element_em_game);
+
+  return element_em_cave;
 }
 
 void prepare_em_level(void)
@@ -273,18 +275,21 @@ void prepare_em_level(void)
   lev.right = lev.left + lev.width;
   lev.bottom = lev.top + lev.height;
 
-  /* add linked cave buffer columns for wrap-around movement */
-  for (x = 0; x < lev.left; x++)
+  if (cav.infinite)
   {
-    lev.cavecol[x] = lev.cavecol[lev.width + x];
-    lev.nextcol[x] = lev.nextcol[lev.width + x];
-    lev.drawcol[x] = lev.drawcol[lev.width + x];
-    lev.boomcol[x] = lev.boomcol[lev.width + x];
-
-    lev.cavecol[lev.right + x] = lev.cavecol[lev.left + x];
-    lev.nextcol[lev.right + x] = lev.nextcol[lev.left + x];
-    lev.drawcol[lev.right + x] = lev.drawcol[lev.left + x];
-    lev.boomcol[lev.right + x] = lev.boomcol[lev.left + x];
+    /* add linked cave buffer columns for wrap-around movement */
+    for (x = 0; x < lev.left; x++)
+    {
+      lev.cavecol[x] = lev.cavecol[lev.width + x];
+      lev.nextcol[x] = lev.nextcol[lev.width + x];
+      lev.drawcol[x] = lev.drawcol[lev.width + x];
+      lev.boomcol[x] = lev.boomcol[lev.width + x];
+
+      lev.cavecol[lev.right + x] = lev.cavecol[lev.left + x];
+      lev.nextcol[lev.right + x] = lev.nextcol[lev.left + x];
+      lev.drawcol[lev.right + x] = lev.drawcol[lev.left + x];
+      lev.boomcol[lev.right + x] = lev.boomcol[lev.left + x];
+    }
   }
 
   for (x = 0; x < lev.width; x++)
@@ -299,6 +304,14 @@ void prepare_em_level(void)
   lev.gems_needed = cav.gems_needed;
   lev.score = 0;
 
+  lev.testmode = cav.testmode;
+
+  if (lev.testmode)
+  {
+    lev.time = 0;
+    lev.gems_needed = 0;
+  }
+
   lev.eater_score      = cav.eater_score;
   lev.alien_score      = cav.alien_score;
   lev.bug_score                = cav.bug_score;
@@ -323,7 +336,7 @@ void prepare_em_level(void)
 
   lev.ball_time   = cav.ball_time;
   lev.ball_cnt    = cav.ball_time;
-  lev.ball_state  = cav.ball_state;
+  lev.ball_active = cav.ball_active;
   lev.ball_random = cav.ball_random;
   lev.ball_pos    = 0;
 
@@ -331,22 +344,22 @@ void prepare_em_level(void)
   lev.shine_cnt = 0;
 
   lev.lenses_time = cav.lenses_time;
-  lev.lenses_cnt  = cav.lenses_cnt;
+  lev.lenses_cnt  = cav.lenses_active ? cav.lenses_time : 0;
 
   lev.magnify_time = cav.magnify_time;
-  lev.magnify_cnt  = cav.magnify_cnt;
+  lev.magnify_cnt  = cav.magnify_active ? cav.magnify_time : 0;
 
   lev.wheel_time = cav.wheel_time;
-  lev.wheel_cnt  = cav.wheel_cnt;
+  lev.wheel_cnt  = cav.wheel_active ? cav.wheel_time : 0;
   lev.wheel_x    = cav.wheel_x;
   lev.wheel_y    = cav.wheel_y;
 
   lev.wind_time      = cav.wind_time;
-  lev.wind_cnt       = cav.wind_cnt;
+  lev.wind_cnt       = cav.wind_time;
   lev.wind_direction = cav.wind_direction;
 
-  lev.wonderwall_time  = cav.wonderwall_time;
-  lev.wonderwall_state = cav.wonderwall_state;
+  lev.wonderwall_time   = cav.wonderwall_time;
+  lev.wonderwall_active = cav.wonderwall_active;
 
   lev.killed_out_of_time = FALSE;
 
@@ -363,18 +376,18 @@ void prepare_em_level(void)
   for (i = 0; i < GAME_TILE_MAX; i++)
     lev.android_array[i] = map[cav.android_array[i]];
 
-  /* determine number of players in this level */
   lev.home_initial = 0;
 
+  /* check for players in this level */
   for (i = 0; i < MAX_PLAYERS; i++)
   {
-    ply[i].exists = 0;
-    ply[i].alive_initial = FALSE;
+    ply[i].exists = FALSE;
+    ply[i].alive = FALSE;
 
     if (cav.player_x[i] != -1 &&
        cav.player_y[i] != -1)
     {
-      ply[i].exists = 1;
+      ply[i].exists = TRUE;
 
       lev.home_initial++;
     }
@@ -388,41 +401,56 @@ void prepare_em_level(void)
   lev.home = lev.home_initial;
   players_left = lev.home_initial;
 
+  /* assign active players */
   for (i = 0; i < MAX_PLAYERS; i++)
   {
-    if (ply[i].exists)
+    if (ply[i].exists && isActivePlayer_EM(i))
     {
       if (players_left)
       {
-       ply[i].alive_initial = TRUE;
+       ply[i].alive = TRUE;
        players_left--;
       }
-      else
-      {
-       int x = cav.player_x[i];
-       int y = cav.player_y[i];
+    }
+  }
 
-       lev.cave[lev.left + x][lev.top + y] = Xblank;
-       lev.next[lev.left + x][lev.top + y] = Xblank;
-       lev.draw[lev.left + x][lev.top + y] = Xblank;
-      }
+  /* remove inactive players */
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (ply[i].exists && !ply[i].alive)
+    {
+      int x = cav.player_x[i];
+      int y = cav.player_y[i];
+
+      lev.cave[lev.left + x][lev.top + y] = Xblank;
+      lev.next[lev.left + x][lev.top + y] = Xblank;
+      lev.draw[lev.left + x][lev.top + y] = Xblank;
     }
   }
 
   for (i = 0; i < MAX_PLAYERS; i++)
   {
     ply[i].num = i;
-    ply[i].alive = ply[i].alive_initial;
-    ply[i].dynamite = 0;
-    ply[i].dynamite_cnt = 0;
-    ply[i].keys = 0;
-    ply[i].anim = 0;
-    ply[i].oldx = ply[i].x = cav.player_x[i] + lev.left;
-    ply[i].oldy = ply[i].y = cav.player_y[i] + lev.top;
+    ply[i].anim = PLY_still;
+
+    ply[i].x = cav.player_x[i] + lev.left;
+    ply[i].y = cav.player_y[i] + lev.top;
+    ply[i].prev_x = ply[i].x;
+    ply[i].prev_y = ply[i].y;
+
+    ply[i].dynamite    = 0;
+    ply[i].dynamite_cnt        = 0;
+    ply[i].keys                = 0;
+
     ply[i].last_move_dir = MV_NONE;
-    ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
-    ply[i].joy_snap  = ply[i].joy_drop = 0;
-    ply[i].joy_stick = ply[i].joy_spin = 0;
+
+    ply[i].joy_n       = FALSE;
+    ply[i].joy_e       = FALSE;
+    ply[i].joy_s       = FALSE;
+    ply[i].joy_w       = FALSE;
+    ply[i].joy_snap    = FALSE;
+    ply[i].joy_drop    = FALSE;
+    ply[i].joy_stick   = FALSE;
   }
 
   // the following engine variables are initialized to version-specific values
@@ -431,6 +459,7 @@ void prepare_em_level(void)
   // - game_em.use_single_button (default: TRUE)
   // - game_em.use_snap_key_bug (default: FALSE)
   // - game_em.use_old_explosions (default: FALSE)
+  // - game_em.use_wrap_around (default: TRUE)
 
   game_em.level_solved = FALSE;
   game_em.game_over = FALSE;