rnd-20041017-2-src
[rocksndiamonds.git] / src / game_em / convert.c
index 245922f7f21af92e93f7eff6524a312fce4a83fd..6b8758546ad4f5116e888394985b75cbc6f8508b 100644 (file)
@@ -88,60 +88,64 @@ static unsigned char remap_v4eater[28] =
   146,147,175,65,66,64,2,18
 };
 
-boolean cleanup_em_level(unsigned char *src, int *length)
+int cleanup_em_level(unsigned char *src, int length)
 {
-  unsigned int i;
+  int file_version = 0;
+  int i;
 
-  if (*length >= 2172 &&
+  if (length >= 2172 &&
       src[2106] == 255 &&
       src[2107] == 54 &&
       src[2108] == 48 &&
       src[2109] == 48)
   {
+    /* ---------- this cave has V6 file format ---------- */
+    file_version = FILE_VERSION_EM_V6;
+
     for (i = 0; i < 2048; i++)
       src[i] = remap_v6[src[i]];
     for (i = 2048; i < 2084; i++)
       src[i] = remap_v6[src[i]];
     for (i = 2112; i < 2148; i++)
       src[i] = remap_v6[src[i]];
-
-    goto v6;
   }
-
-  if (*length >= 2110 &&
-      src[2106] == 255 &&
-      src[2107] == 53 &&
-      src[2108] == 48 &&
-      src[2109] == 48)
+  else if (length >= 2110 &&
+          src[2106] == 255 &&
+          src[2107] == 53 &&
+          src[2108] == 48 &&
+          src[2109] == 48)
   {
+    /* ---------- this cave has V5 file format ---------- */
+    file_version = FILE_VERSION_EM_V5;
+
     for (i = 0; i < 2048; i++)
       src[i] = remap_v5[src[i]];
     for (i = 2048; i < 2084; i++)
       src[i] = remap_v5[src[i]];
     for (i = 2112; i < 2148; i++)
       src[i] = src[i - 64];
-
-    goto v5;
   }
-
-  if (*length >= 2106 &&
-      src[1983] == 116)
+  else if (length >= 2106 &&
+          src[1983] == 116)
   {
+    /* ---------- this cave has V4 file format ---------- */
+    file_version = FILE_VERSION_EM_V4;
+
     for (i = 0; i < 2048; i++)
       src[i] = remap_v4[src[i]];
     for (i = 2048; i < 2084; i++)
       src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
     for (i = 2112; i < 2148; i++) src[i] = src[i - 64];
-
-    goto v4;
   }
-
-  if (*length >= 2106 &&
-      src[0] == 241 &&
-      src[1983] == 27)
+  else if (length >= 2106 &&
+          src[0] == 241 &&
+          src[1983] == 27)
   {
     unsigned char j = 94;
 
+    /* ---------- this cave has V3 file format ---------- */
+    file_version = FILE_VERSION_EM_V3;
+
     for (i = 0; i < 2106; i++)
       src[i] = (src[i] ^ (j += 7)) - 0x11;
     src[1] = 131;
@@ -151,34 +155,35 @@ boolean cleanup_em_level(unsigned char *src, int *length)
       src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
     for (i = 2112; i < 2148; i++)
       src[i] = src[i - 64];
-
-    goto v3;
   }
+  else
+  {
+    /* ---------- this cave has unknown file format ---------- */
 
-  return FALSE;                /* unrecognized cave */
-
- v3:
- v4:
- v5:
-
-  /* id */
-  src[2106] = 255;
-  src[2107] = 54;
-  src[2108] = 48;
-  src[2109] = 48;
-
-  /* time */
-  i = src[2094] * 10;
-  src[2110] = i >> 8;
-  src[2111] = i;
-
-  for (i = 2148; i < 2172; i++)
-    src[i] = 0;
+    return 0;
+  }
 
-  /* ball data */
-  src[2159] = 128;
+  if (file_version < FILE_VERSION_EM_V6)
+  {
+    /* id */
+    src[2106] = 255;
+    src[2107] = 54;
+    src[2108] = 48;
+    src[2109] = 48;
+
+    /* time */
+    i = src[2094] * 10;
+    src[2110] = i >> 8;
+    src[2111] = i;
+
+    for (i = 2148; i < 2172; i++)
+      src[i] = 0;
+
+    /* ball data */
+    src[2159] = 128;
+  }
 
- v6:
+  /* ---------- at this stage, the cave data always has V6 format ---------- */
 
   /* fix wheel */
   for (i = 0; i < 2048; i++)
@@ -244,7 +249,7 @@ boolean cleanup_em_level(unsigned char *src, int *length)
   src[2098] &= 7;
   src[src[2098] << 8 | src[2099]] = 128;
 
-  /* ameuba speed */
+  /* amoeba speed */
   if ((src[2100] << 8 | src[2101]) > 9999)
   {
     src[2100] = 39;
@@ -319,9 +324,9 @@ boolean cleanup_em_level(unsigned char *src, int *length)
   src[2168] &= 31;
 
   /* size of v6 cave */
-  *length = 2172;
+  length = 2172;
 
-  return TRUE;
+  return file_version;
 }
 
 /* 2000-07-30T00:26:00Z
@@ -406,7 +411,7 @@ static unsigned short remap_emerald[256] =
   Xblank, Xround_wall_1, Xgrass, Xsteel_1, Xwall_1, Xkey_1, Xkey_2, Xkey_3,
   Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3, Xdoor_4, Xdripper, Xfake_door_1, Xfake_door_2,
   Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel, Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
-  Xacid_se, Xfake_blank, Xameuba_1, Xameuba_2, Xameuba_3, Xameuba_4, Xexit, Xalpha_arrow_w,
+  Xacid_se, Xfake_blank, Xamoeba_1, Xamoeba_2, Xamoeba_3, Xamoeba_4, Xexit, Xalpha_arrow_w,
   Xfake_grass, Xlenses, Xmagnify, Xfake_blank, Xfake_grass, Xswitch, Xswitch, Xblank,
   Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5, Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
   Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2, Xround_wall_2, Xdecor_2, Xdecor_4, Xdecor_3,
@@ -421,14 +426,25 @@ static unsigned short remap_emerald[256] =
   Xblank, Xblank, Xblank, Xblank, Xblank, Xblank, Xblank, Xblank,
 };
 
-void convert_em_level(unsigned char *src)
+void convert_em_level(unsigned char *src, int file_version)
 {
-  unsigned int x, y, temp;
-
+  static int eater_offset[8] =
+  {
+    0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
+  };
+  unsigned int i, x, y, temp;
+
+#if 1
+  lev.time_seconds = src[0x83E] << 8 | src[0x83F];
+  if (lev.time_seconds > 9999)
+    lev.time_seconds = 9999;
+#else
   temp = ((src[0x83E] << 8 | src[0x83F]) * 25 + 3) / 4;
   if (temp == 0 || temp > 9999)
     temp = 9999;
   lev.time_initial = temp;
+#endif
+
   lev.required_initial = src[0x82F];
 
   temp = src[0x830] << 8 | src[0x831];
@@ -441,7 +457,7 @@ void convert_em_level(unsigned char *src)
   temp = (src[0x834] << 8 | src[0x835]) * 28;
   if (temp > 9999)
     temp = 9999;
-  lev.ameuba_time = temp;
+  lev.amoeba_time = temp;
 
   lev.android_move_time = src[0x874] << 8 | src[0x875];
   lev.android_clone_time = src[0x876] << 8 | src[0x877];
@@ -465,17 +481,9 @@ void convert_em_level(unsigned char *src)
   lev.slurp_score = src[0x869];
 
   lev.lenses_time = src[0x86A] << 8 | src[0x86B];
-  lev.lenses_cnt_initial = 0;
-
   lev.magnify_time = src[0x86C] << 8 | src[0x86D];
-  lev.magnify_cnt_initial = 0;
-
   lev.wheel_time = src[0x838] << 8 | src[0x839];
-  lev.wheel_cnt_initial = 0;
-  lev.wheel_x_initial = 1;
-  lev.wheel_y_initial = 1;
 
-  lev.wind_time = 9999;
   lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
   temp = src[0x865];
   lev.wind_direction_initial = (temp & 8 ? 0 :
@@ -483,25 +491,11 @@ void convert_em_level(unsigned char *src)
                                temp & 2 ? 2 :
                                temp & 4 ? 3 : 0);
 
-  lev.wonderwall_state_initial = 0;
   lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
 
-  for (x = 0; x < 9; x++)
-    lev.eater_array[0][x] = remap_emerald[src[0x800 + x]];
-  for (x = 0; x < 9; x++)
-    lev.eater_array[1][x] = remap_emerald[src[0x809 + x]];
-  for (x = 0; x < 9; x++)
-    lev.eater_array[2][x] = remap_emerald[src[0x812 + x]];
-  for (x = 0; x < 9; x++)
-    lev.eater_array[3][x] = remap_emerald[src[0x81B + x]];
-  for (x = 0; x < 9; x++)
-    lev.eater_array[4][x] = remap_emerald[src[0x840 + x]];
-  for (x = 0; x < 9; x++)
-    lev.eater_array[5][x] = remap_emerald[src[0x849 + x]];
-  for (x = 0; x < 9; x++)
-    lev.eater_array[6][x] = remap_emerald[src[0x852 + x]];
-  for (x = 0; x < 9; x++)
-    lev.eater_array[7][x] = remap_emerald[src[0x85B + x]];
+  for (i = 0; i < 8; i++)
+    for (x = 0; x < 9; x++)
+      lev.eater_array[i][x] = remap_emerald[src[eater_offset[i] + x]];
 
   temp = remap_emerald[src[0x86F]];
   for (y = 0; y < 8; y++)
@@ -513,20 +507,17 @@ void convert_em_level(unsigned char *src)
     }
     else
     {
-      lev.ball_array[y][1] = (src[0x873] & 1) ? temp : Xblank;  /* north */
-      lev.ball_array[y][6] = (src[0x873] & 2) ? temp : Xblank;  /* south */
-      lev.ball_array[y][3] = (src[0x873] & 4) ? temp : Xblank;  /* west */
-      lev.ball_array[y][4] = (src[0x873] & 8) ? temp : Xblank;  /* east */
+      lev.ball_array[y][1] = (src[0x873] & 1)  ? temp : Xblank; /* north */
+      lev.ball_array[y][6] = (src[0x873] & 2)  ? temp : Xblank; /* south */
+      lev.ball_array[y][3] = (src[0x873] & 4)  ? temp : Xblank; /* west */
+      lev.ball_array[y][4] = (src[0x873] & 8)  ? temp : Xblank; /* east */
       lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* southeast */
       lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
       lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
-      lev.ball_array[y][0] = (src[0x873] & 128) ? temp : Xblank;/* northwest */
+      lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
     }
   }
 
-  for (temp = 0; temp < TILE_MAX; temp++)
-    lev.android_array[temp] = Xblank;
-
   temp = src[0x878] << 8 | src[0x879];
 
   if (temp & 1)
@@ -675,14 +666,14 @@ void convert_em_level(unsigned char *src)
   {
     lev.android_array[Xdripper] =
       lev.android_array[XdripperB] =
-      lev.android_array[Xameuba_1] =
-      lev.android_array[Xameuba_2] =
-      lev.android_array[Xameuba_3] =
-      lev.android_array[Xameuba_4] =
-      lev.android_array[Xameuba_5] =
-      lev.android_array[Xameuba_6] =
-      lev.android_array[Xameuba_7] =
-      lev.android_array[Xameuba_8] = Xdrip_eat;
+      lev.android_array[Xamoeba_1] =
+      lev.android_array[Xamoeba_2] =
+      lev.android_array[Xamoeba_3] =
+      lev.android_array[Xamoeba_4] =
+      lev.android_array[Xamoeba_5] =
+      lev.android_array[Xamoeba_6] =
+      lev.android_array[Xamoeba_7] =
+      lev.android_array[Xamoeba_8] = Xdrip_eat;
   }
 
   if (temp & 4096)
@@ -757,11 +748,6 @@ void convert_em_level(unsigned char *src)
     }
   }
 
-  lev.home_initial = 1;                /* initial number of players in this level */
-
-  ply1.alive_initial = (lev.home_initial >= 1);
-  ply2.alive_initial = (lev.home_initial >= 2);
-
   /* first fill the complete playfield with the default border element */
   for (y = 0; y < HEIGHT; y++)
     for (x = 0; x < WIDTH; x++)
@@ -778,6 +764,8 @@ void convert_em_level(unsigned char *src)
     native_em_level.cave[ply1.x_initial][ply1.y_initial] = Zplayer;
   if (ply2.alive_initial)
     native_em_level.cave[ply2.x_initial][ply2.y_initial] = Zplayer;
+
+  native_em_level.file_version = file_version;
 }
 
 void prepare_em_level(void)
@@ -798,7 +786,9 @@ void prepare_em_level(void)
     for (x = 0; x < WIDTH; x++)
       Draw[y][x] = Cave[y][x];
 
+  lev.time_initial = (lev.time_seconds * 50 + 7) / 8;
   lev.time = lev.time_initial;
+
   lev.required = lev.required_initial;
   lev.score = 0;