added support for wrap-around levels in EM engine
[rocksndiamonds.git] / src / game_em / convert.c
index d009b7403927b71c14b99724aad89b1e25f8ef45..d25c4593eb4c1d1817f37382f5ac9c3b44d0f739 100644 (file)
@@ -643,8 +643,8 @@ void convert_em_level(unsigned char *src, int file_version)
   for (i = 0; i < 2; i++)
   {
     temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
-    ply[i].x_initial = (temp & 63) + 1;
-    ply[i].y_initial = (temp >> 6 & 31) + 1;
+    ply[i].x_initial = (temp & 63);
+    ply[i].y_initial = (temp >> 6 & 31);
   }
 
   temp = (src[0x834] << 8 | src[0x835]) * 28;
@@ -911,15 +911,15 @@ void convert_em_level(unsigned char *src, int file_version)
   }
 
   /* first fill the complete playfield with the default border element */
-  for (y = 0; y < HEIGHT; y++)
-    for (x = 0; x < WIDTH; x++)
+  for (y = 0; y < CAVE_HEIGHT; y++)
+    for (x = 0; x < CAVE_WIDTH; x++)
       native_em_level.cave[x][y] = Zborder;
 
   /* then copy the real level contents from level file into the playfield */
   temp = 0;
   for (y = 0; y < lev.height; y++)
     for (x = 0; x < lev.width; x++)
-      native_em_level.cave[x + 1][y + 1] =
+      native_em_level.cave[x][y] =
        get_em_element(src[temp++], file_version);
 
   /* at last, set the two players at their positions in the playfield */
@@ -938,17 +938,34 @@ void prepare_em_level(void)
 
   /* reset all runtime variables to their initial values */
 
-  for (y = 0; y < HEIGHT; y++)
-    for (x = 0; x < WIDTH; x++)
-      Cave[y][x] = native_em_level.cave[x][y];
+  game_init_cave_buffers();
 
-  for (y = 0; y < HEIGHT; y++)
-    for (x = 0; x < WIDTH; x++)
-      Next[y][x] = Cave[y][x];
+  lev.left = CAVE_BUFFER_XOFFSET;
+  lev.top  = CAVE_BUFFER_YOFFSET;
+  lev.right = lev.left + lev.width;
+  lev.bottom = lev.top + lev.height;
 
-  for (y = 0; y < HEIGHT; y++)
-    for (x = 0; x < WIDTH; x++)
-      Draw[y][x] = Cave[y][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++)
+    for (y = 0; y < lev.height; y++)
+      lev.cave[lev.left + x][lev.top + y] = native_em_level.cave[x][y];
+
+  for (x = lev.left; x < lev.right; x++)
+    for (y = lev.top; y < lev.bottom; y++)
+      lev.next[x][y] = lev.draw[x][y] = lev.cave[x][y];
 
   lev.time_initial = lev.time_seconds;
   lev.time = lev.time_initial;
@@ -989,7 +1006,7 @@ void prepare_em_level(void)
     ply[i].exists = 0;
     ply[i].alive_initial = FALSE;
 
-    if (ply[i].x_initial > 0 && ply[i].y_initial > 0)
+    if (ply[i].x_initial != -1 && ply[i].y_initial != -1)
     {
       ply[i].exists = 1;
 
@@ -1021,7 +1038,9 @@ void prepare_em_level(void)
 
        native_em_level.cave[x][y] = Xblank;
 
-       Cave[y][x] = Next[y][x] = Draw[y][x] = Xblank;
+       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;
       }
     }
   }
@@ -1034,8 +1053,8 @@ void prepare_em_level(void)
     ply[i].dynamite_cnt = 0;
     ply[i].keys = 0;
     ply[i].anim = 0;
-    ply[i].oldx = ply[i].x = ply[i].x_initial;
-    ply[i].oldy = ply[i].y = ply[i].y_initial;
+    ply[i].oldx = ply[i].x = ply[i].x_initial + lev.left;
+    ply[i].oldy = ply[i].y = ply[i].y_initial + lev.top;
     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;