fixed time score for native Emerald Mine and Diamond Caves levels
[rocksndiamonds.git] / src / game_em / reademc.c
index 3bb920ab2286dec72514f3f0356ad88d1fa2a1b3..dfa293a6ebe1eeee4d905142e7af8a0618bb9db0 100644 (file)
  * behaviour.
  */
 
-static const short map_emc[256] =
+/* changes for game engine integration in Rocks'n'Diamonds:
+ *
+ * added support for rolling spring (not mapped to pushed spring)
+ * - required for Elvis Mine 8, levels 3, 23, 48 and 73
+ */
+
+#define GET_BE16(x)            ((&x)[0] << 8 | (&x)[1])
+
+static const short map_emc_raw[256] =
 {
-  Xstone,              Xstone,         Xdiamond,       Xdiamond,
-  Xalien,              Xalien,         Xblank,         Xblank,
-  Xtank_1_n,           Xtank_1_e,      Xtank_1_s,      Xtank_1_w,
-  Xtank_2_n,           Xtank_2_e,      Xtank_2_s,      Xtank_2_w,
-
-  Xbomb,               Xbomb,          Xemerald,       Xemerald,
-  Xbug_1_n,            Xbug_1_e,       Xbug_1_s,       Xbug_1_w,
-  Xbug_2_n,            Xbug_2_e,       Xbug_2_s,       Xbug_2_w,
-  Xdrip,               Xdrip,          Xdrip,          Xdrip,
-
-  Xstone,              Xbomb,          Xdiamond,       Xemerald,
-  Xwonderwall,         Xnut,           Xnut,           Xnut,
-  Xwheel,              Xeater_n,       Xeater_s,       Xeater_w,
-  Xeater_e,            Xsand_stone,    Xblank,         Xblank,
-
-  Xblank,              Xsand,          Xsand,          Xsand,
-  Xsand_stone,         Xsand_stone,    Xsand_stone,    Xsand,
-  Xstone,              Xslide_ew,      Xslide_ns,      Xdynamite_1,
-  Xdynamite_2,         Xdynamite_3,    Xdynamite_4,    Xacid_s,
-
-  Xexit_1,             Xexit_2,        Xexit_3,        Xballoon,
-  Xplant,              Xspring,        Xspring_fall,   Xspring_w,
-  Xspring_e,           Xball_1,        Xball_2,        Xandroid,
-  Xblank,              Xandroid,       Xandroid,       Xandroid,
-
-  Xandroid,            Xandroid,       Xandroid,       Xandroid,
-  Xandroid,            Xblank,         Xblank,         Xblank,
-  Xblank,              Xblank,         Xblank,         Xblank,
-  Xblank,              Xblank,         Xblank,         Xblank,
-
-  Xblank,              Xblank,         Xblank,         Xpush_spring_w,
-  Xpush_spring_e,      Xacid_1,        Xacid_2,        Xacid_3,
-  Xacid_4,             Xacid_5,        Xacid_6,        Xacid_7,
-  Xacid_8,             Xblank,         Xblank,         Xblank,
-
-  Xblank,              Xblank,         Xpush_nut_w,    Xpush_nut_e,
-  Xsteel_1,            Xblank,         Xblank,         Xpush_bomb_w,
-  Xpush_bomb_e,                Xpush_stone_w,  Xpush_stone_e,  Xblank,
-  Xblank,              Xblank,         Xblank,         Xblank,
-
-  Xblank,              Xroundwall_1,   Xgrass,         Xsteel_1,
-  Xwall_1,             Xkey_1,         Xkey_2,         Xkey_3,
-  Xkey_4,              Xdoor_1,        Xdoor_2,        Xdoor_3,
-  Xdoor_4,             Xfake_amoeba,   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,    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,
-  Xroundwall_2,                Xdecor_2,       Xdecor_4,       Xdecor_3,
-  Xwind_any,           Xwind_e,        Xwind_s,        Xwind_w,
-  Xwind_n,             Xdirt,          Xplant,         Xkey_5,
-
-  Xkey_6,              Xkey_7,         Xkey_8,         Xdoor_5,
-  Xdoor_6,             Xdoor_7,        Xdoor_8,        Xbumper,
-  Xalpha_a,            Xalpha_b,       Xalpha_c,       Xalpha_d,
-  Xalpha_e,            Xalpha_f,       Xalpha_g,       Xalpha_h,
-
-  Xalpha_i,            Xalpha_j,       Xalpha_k,       Xalpha_l,
-  Xalpha_m,            Xalpha_n,       Xalpha_o,       Xalpha_p,
-  Xalpha_q,            Xalpha_r,       Xalpha_s,       Xalpha_t,
-  Xalpha_u,            Xalpha_v,       Xalpha_w,       Xalpha_x,
-
-  Xalpha_y,            Xalpha_z,       Xalpha_0,       Xalpha_1,
-  Xalpha_2,            Xalpha_3,       Xalpha_4,       Xalpha_5,
-  Xalpha_6,            Xalpha_7,       Xalpha_8,       Xalpha_9,
-  Xalpha_perio,                Xalpha_excla,   Xalpha_colon,   Xalpha_quest,
-
-  Xalpha_arrow_e,      Xdecor_1,       Xfake_door_5,   Xfake_door_6,
-  Xfake_door_7,                Xfake_door_8,   Xblank,         Xblank,
-  Xblank,              Xblank,         Xblank,         Xblank,
-  Xblank,              Xblank,         Xalpha_copyr,   Xfake_acid_1
+  Cstone,              Cstone,         Cdiamond,       Cdiamond,       //   0
+  Calien,              Calien,         Cpause,         Cpause,         //   4
+  Ctank_1_n,           Ctank_1_e,      Ctank_1_s,      Ctank_1_w,      //   8
+  Ctank_2_n,           Ctank_2_e,      Ctank_2_s,      Ctank_2_w,      //  12
+  Cbomb,               Cbomb,          Cemerald,       Cemerald,       //  16
+  Cbug_1_n,            Cbug_1_e,       Cbug_1_s,       Cbug_1_w,       //  20
+  Cbug_2_n,            Cbug_2_e,       Cbug_2_s,       Cbug_2_w,       //  24
+  Cdrip,               Cdrip,          Cblank,         Cdrip,          //  28
+  Cstone,              Cbomb,          Cdiamond,       Cemerald,       //  32
+  Cwonderwall,         Cnut,           Cnut,           Cnut,           //  36
+  Cwheel,              Ceater_n,       Ceater_s,       Ceater_w,       //  40
+  Ceater_e,            Csand_stone,    Cblank,         Cblank,         //  44
+  Cblank,              Csand,          Csand,          Csand,          //  48
+  Csand_stone,         Csand_stone,    Csand_stone,    Csand,          //  52
+  Cstone,              Cslide_ew,      Cslide_ns,      Cdynamite_1,    //  56
+  Cdynamite_2,         Cdynamite_3,    Cdynamite_4,    Cacid_s,        //  60
+
+  Cexit_1,             Cexit_2,        Cexit_3,        Cballoon,       //  64
+  Cplant,              Cspring,        Cspring,        Cspring_w,      //  68
+  Cspring_e,           Cball_1,        Cball_2,        Candroid,       //  72
+  Cpause,              Candroid,       Candroid,       Candroid,       //  76
+  Candroid,            Candroid,       Candroid,       Candroid,       //  80
+  Candroid,            Cblank,         Cblank,         Cblank,         //  84
+  Cblank,              Cblank,         Cblank,         Cblank,         //  88
+  Cblank,              Cblank,         Cblank,         Cblank,         //  92
+  Cblank,              Cblank,         Cblank,         Cpush_spring_w, //  96
+  Cpush_spring_e,      Cacid_1,        Cacid_2,        Cacid_3,        // 100
+  Cacid_4,             Cacid_5,        Cacid_6,        Cacid_7,        // 104
+  Cacid_8,             Cpause,         Cpause,         Cpause,         // 108
+  Cpause,              Cpause,         Cpush_nut_w,    Cpush_nut_e,    // 112
+  Csteel_1,            Cdynamite_4,    Cblank,         Cpush_bomb_w,   // 116
+  Cpush_bomb_e,                Cpush_stone_w,  Cpush_stone_e,  Cpause,         // 120
+  Cpause,              Cpause,         Cpause,         Cpause,         // 124
+
+  Cblank,              Croundwall_2,   Cgrass,         Csteel_2,       // 128
+  Cwall_2,             Ckey_1,         Ckey_2,         Ckey_3,         // 132
+  Ckey_4,              Cdoor_1,        Cdoor_2,        Cdoor_3,        // 136
+  Cdoor_4,             Cfake_amoeba,   Cfake_door_1,   Cfake_door_2,   // 140
+  Cfake_door_3,                Cfake_door_4,   Cwonderwall,    Cwheel,         // 144
+  Csand,               Cacid_nw,       Cacid_ne,       Cacid_sw,       // 148
+  Cacid_se,            Cfake_blank,    Camoeba_1,      Camoeba_2,      // 152
+  Camoeba_3,           Camoeba_4,      Cexit,          Calpha_arrow_w, // 156
+  Cfake_grass,         Clenses,        Cmagnify,       Cfake_blank,    // 160
+  Cfake_grass,         Cswitch,        Cswitch,        Cpause,         // 164
+  Cdecor_8,            Cdecor_9,       Cdecor_10,      Cdecor_5,       // 168
+  Calpha_comma,                Calpha_apost,   Calpha_minus,   Cdynamite,      // 172
+  Csteel_3,            Cdecor_6,       Cdecor_7,       Csteel_1,       // 176
+  Croundwall_1,                Cdecor_2,       Cdecor_4,       Cdecor_3,       // 180
+  Cwind_any,           Cwind_e,        Cwind_s,        Cwind_w,        // 184
+  Cwind_n,             Cdirt,          Cplant,         Ckey_5,         // 188
+
+  Ckey_6,              Ckey_7,         Ckey_8,         Cdoor_5,        // 192
+  Cdoor_6,             Cdoor_7,        Cdoor_8,        Cbumper,        // 196
+  Calpha_a,            Calpha_b,       Calpha_c,       Calpha_d,       // 200
+  Calpha_e,            Calpha_f,       Calpha_g,       Calpha_h,       // 204
+  Calpha_i,            Calpha_j,       Calpha_k,       Calpha_l,       // 208
+  Calpha_m,            Calpha_n,       Calpha_o,       Calpha_p,       // 212
+  Calpha_q,            Calpha_r,       Calpha_s,       Calpha_t,       // 216
+  Calpha_u,            Calpha_v,       Calpha_w,       Calpha_x,       // 220
+  Calpha_y,            Calpha_z,       Calpha_0,       Calpha_1,       // 224
+  Calpha_2,            Calpha_3,       Calpha_4,       Calpha_5,       // 228
+  Calpha_6,            Calpha_7,       Calpha_8,       Calpha_9,       // 232
+  Calpha_perio,                Calpha_excla,   Calpha_colon,   Calpha_quest,   // 236
+  Calpha_arrow_e,      Cdecor_1,       Cfake_door_5,   Cfake_door_6,   // 240
+  Cfake_door_7,                Cfake_door_8,   Cblank,         Cblank,         // 244
+  Camoeba_5,           Camoeba_6,      Camoeba_7,      Camoeba_8,      // 248
+  Cwall_1,             Cblank,         Calpha_copyr,   Cfake_acid_1    // 252
 };
 
-static int get_em_element(unsigned short em_element_raw, int file_version)
+static const short swap_emc[CAVE_TILE_MAX] =
 {
-  int em_element = map_emc[em_element_raw];
+  [Cdirt]              = Cgrass,
+  [Cgrass]             = Cdirt,
 
-  if (file_version < FILE_VERSION_EM_V5)
-  {
-    /* versions below V5 had no grass, but only sand/dirt */
-    if (em_element == Xgrass)
-      em_element = Xdirt;
-  }
+  [Csteel_1]           = Csteel_2,
+  [Csteel_2]           = Csteel_1,
+
+  [Cwall_1]            = Cwall_2,
+  [Cwall_2]            = Cwall_1,
+
+  [Croundwall_1]       = Croundwall_2,
+  [Croundwall_2]       = Croundwall_1
+};
 
-  return em_element;
+static struct
+{
+  int bit_nr;
+  int clone_from;
+  int clone_to;
 }
+android_clone_table[] =
+{
+  { 0, Xemerald,               Cemerald        },
+  { 0, Xemerald_pause,         Cemerald        },
+  { 0, Xemerald_fall,          Cemerald        },
+  { 0, Yemerald_sB,            Cemerald        },
+  { 0, Yemerald_eB,            Cemerald        },
+  { 0, Yemerald_wB,            Cemerald        },
+
+  { 1, Xdiamond,               Cdiamond        },
+  { 1, Xdiamond_pause,         Cdiamond        },
+  { 1, Xdiamond_fall,          Cdiamond        },
+  { 1, Ydiamond_sB,            Cdiamond        },
+  { 1, Ydiamond_eB,            Cdiamond        },
+  { 1, Ydiamond_wB,            Cdiamond        },
+
+  { 2, Xstone,                 Cstone          },
+  { 2, Xstone_pause,           Cstone          },
+  { 2, Xstone_fall,            Cstone          },
+  { 2, Ystone_sB,              Cstone          },
+  { 2, Ystone_eB,              Cstone          },
+  { 2, Ystone_wB,              Cstone          },
+
+  { 3, Xbomb,                  Cbomb           },
+  { 3, Xbomb_pause,            Cbomb           },
+  { 3, Xbomb_fall,             Cbomb           },
+  { 3, Ybomb_sB,               Cbomb           },
+  { 3, Ybomb_eB,               Cbomb           },
+  { 3, Ybomb_wB,               Cbomb           },
+
+  { 4, Xnut,                   Cnut            },
+  { 4, Xnut_pause,             Cnut            },
+  { 4, Xnut_fall,              Cnut            },
+  { 4, Ynut_sB,                Cnut            },
+  { 4, Ynut_eB,                Cnut            },
+  { 4, Ynut_wB,                Cnut            },
+
+  { 5, Xtank_1_n,              Ctank_1_n       },
+  { 5, Xtank_2_n,              Ctank_1_n       },
+  { 5, Ytank_nB,               Ctank_1_n       },
+  { 5, Ytank_n_e,              Ctank_1_n       },
+  { 5, Ytank_n_w,              Ctank_1_n       },
+  { 5, Xtank_1_e,              Ctank_1_e       },
+  { 5, Xtank_2_e,              Ctank_1_e       },
+  { 5, Ytank_eB,               Ctank_1_e       },
+  { 5, Ytank_e_s,              Ctank_1_e       },
+  { 5, Ytank_e_n,              Ctank_1_e       },
+  { 5, Xtank_1_s,              Ctank_1_s       },
+  { 5, Xtank_2_s,              Ctank_1_s       },
+  { 5, Ytank_sB,               Ctank_1_s       },
+  { 5, Ytank_s_w,              Ctank_1_s       },
+  { 5, Ytank_s_e,              Ctank_1_s       },
+  { 5, Xtank_1_w,              Ctank_1_w       },
+  { 5, Xtank_2_w,              Ctank_1_w       },
+  { 5, Ytank_wB,               Ctank_1_w       },
+  { 5, Ytank_w_n,              Ctank_1_w       },
+  { 5, Ytank_w_s,              Ctank_1_w       },
+
+  { 6, Xeater_n,               Ceater_n        },
+  { 6, Yeater_nB,              Ceater_n        },
+  { 6, Xeater_e,               Ceater_e        },
+  { 6, Yeater_eB,              Ceater_e        },
+  { 6, Xeater_s,               Ceater_s        },
+  { 6, Yeater_sB,              Ceater_s        },
+  { 6, Xeater_w,               Ceater_w        },
+  { 6, Yeater_wB,              Ceater_w        },
+
+  { 7, Xbug_1_n,               Cbug_2_n        },
+  { 7, Xbug_2_n,               Cbug_2_n        },
+  { 7, Ybug_nB,                Cbug_2_n        },
+  { 7, Ybug_n_e,               Cbug_2_n        },
+  { 7, Ybug_n_w,               Cbug_2_n        },
+  { 7, Xbug_1_e,               Cbug_2_e        },
+  { 7, Xbug_2_e,               Cbug_2_e        },
+  { 7, Ybug_eB,                Cbug_2_e        },
+  { 7, Ybug_e_s,               Cbug_2_e        },
+  { 7, Ybug_e_n,               Cbug_2_e        },
+  { 7, Xbug_1_s,               Cbug_2_s        },
+  { 7, Xbug_2_s,               Cbug_2_s        },
+  { 7, Ybug_sB,                Cbug_2_s        },
+  { 7, Ybug_s_w,               Cbug_2_s        },
+  { 7, Ybug_s_e,               Cbug_2_s        },
+  { 7, Xbug_1_w,               Cbug_2_w        },
+  { 7, Xbug_2_w,               Cbug_2_w        },
+  { 7, Ybug_wB,                Cbug_2_w        },
+  { 7, Ybug_w_n,               Cbug_2_w        },
+  { 7, Ybug_w_s,               Cbug_2_w        },
+
+  { 8, Xalien,                 Calien          },
+  { 8, Xalien_pause,           Calien          },
+  { 8, Yalien_nB,              Calien          },
+  { 8, Yalien_eB,              Calien          },
+  { 8, Yalien_sB,              Calien          },
+  { 8, Yalien_wB,              Calien          },
+
+  { 9, Xspring,                Cspring         },
+  { 9, Xspring_pause,          Cspring         },
+  { 9, Xspring_fall,           Cspring         },
+  { 9, Xspring_e,              Cspring         },
+  { 9, Xspring_w,              Cspring         },
+  { 9, Yspring_sB,             Cspring         },
+  { 9, Yspring_eB,             Cspring         },
+  { 9, Yspring_wB,             Cspring         },
+  { 9, Yspring_alien_eB,       Cspring         },
+  { 9, Yspring_alien_wB,       Cspring         },
+
+  { 10,        Xballoon,               Cballoon        },
+  { 10,        Yballoon_nB,            Cballoon        },
+  { 10,        Yballoon_eB,            Cballoon        },
+  { 10,        Yballoon_sB,            Cballoon        },
+  { 10,        Yballoon_wB,            Cballoon        },
+
+  { 11,        Xfake_amoeba,           Cdrip           },
+  { 11,        Yfake_amoeba,           Cdrip           },
+  { 11,        Xamoeba_1,              Cdrip           },
+  { 11,        Xamoeba_2,              Cdrip           },
+  { 11,        Xamoeba_3,              Cdrip           },
+  { 11,        Xamoeba_4,              Cdrip           },
+  { 11,        Xamoeba_5,              Cdrip           },
+  { 11,        Xamoeba_6,              Cdrip           },
+  { 11,        Xamoeba_7,              Cdrip           },
+  { 11,        Xamoeba_8,              Cdrip           },
+
+  { 12,        Xdynamite,              Cdynamite       },
+
+  { -1,                -1,             -1              },
+};
+
+static int eater_offset[8] =
+{
+  2048, 2057, 2066, 2075,
+  2112, 2121, 2130, 2139
+};
 
 void convert_em_level(unsigned char *src, int file_version)
 {
-  static int eater_offset[8] =
-  {
-    0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
-  };
   int i, x, y, temp;
+  short map_emc[256];
 
-  lev.time_seconds = src[0x83E] << 8 | src[0x83F];
-  if (lev.time_seconds > 9999)
-    lev.time_seconds = 9999;
+  /* initialize element mapping */
 
-  lev.required_initial = src[0x82F];
+  for (i = 0; i < 256; i++)
+    map_emc[i] = map_emc_raw[i];
 
-  for (i = 0; i < 2; i++)
-  {
-    temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
-    ply[i].x_initial = (temp & 63);
-    ply[i].y_initial = (temp >> 6 & 31);
-  }
+  /* swap tiles for pre-EMC caves (older than V5/V6), if needed */
 
-  temp = (src[0x834] << 8 | src[0x835]) * 28;
-  if (temp > 9999)
-    temp = 9999;
-  lev.amoeba_time = temp;
-
-  lev.android_move_time = src[0x874] << 8 | src[0x875];
-  lev.android_clone_time = src[0x876] << 8 | src[0x877];
-
-  lev.ball_random = src[0x872] & 1 ? 1 : 0;
-  lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
-  lev.ball_time = src[0x870] << 8 | src[0x871];
-
-  lev.emerald_score = src[0x824];
-  lev.diamond_score = src[0x825];
-  lev.alien_score = src[0x826];
-  lev.tank_score = src[0x827];
-  lev.bug_score = src[0x828];
-  lev.eater_score = src[0x829];
-  lev.nut_score = src[0x82A];
-  lev.dynamite_score = src[0x82B];
-  lev.key_score = src[0x82C];
-  lev.exit_score = src[0x82D] * 8 / 5;
-  lev.lenses_score = src[0x867];
-  lev.magnify_score = src[0x868];
-  lev.slurp_score = src[0x869];
-
-  lev.lenses_time = src[0x86A] << 8 | src[0x86B];
-  lev.magnify_time = src[0x86C] << 8 | src[0x86D];
-  lev.wheel_time = src[0x838] << 8 | src[0x839];
-
-  lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
-  temp = src[0x865];
-  lev.wind_direction_initial = (temp & 8 ? 0 :
-                               temp & 1 ? 1 :
-                               temp & 2 ? 2 :
-                               temp & 4 ? 3 : 0);
-
-  lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
+  if (swapTiles_EM(file_version < FILE_VERSION_EM_V5))
+    for (i = 0; i < 256; i++)
+      if (swap_emc[map_emc[i]] != 0)
+       map_emc[i] = swap_emc[map_emc[i]];
 
-  for (i = 0; i < 8; i++)
-    for (x = 0; x < 9; x++)
-      lev.eater_array[i][x] =
-       get_em_element(src[eater_offset[i] + x], file_version);
+  /* common to all emc caves */
 
-  temp = get_em_element(src[0x86F], file_version);
-  for (y = 0; y < 8; y++)
-  {
-    if (src[0x872] & 1)
-    {
-      for (x = 0; x < 8; x++)
-       lev.ball_array[y][x] = temp;
-    }
-    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][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 */
-    }
-  }
+  cav.width = 64;
+  cav.height = 32;
 
-  temp = src[0x878] << 8 | src[0x879];
+  cav.time_seconds = MIN(GET_BE16(src[2110]), 9999);
+  cav.gems_needed = src[2095];
 
-  if (temp & 1)
-  {
-    lev.android_array[Xemerald]                = Xemerald;
-    lev.android_array[Xemerald_pause]  = Xemerald;
-    lev.android_array[Xemerald_fall]   = Xemerald;
-    lev.android_array[Yemerald_sB]     = Xemerald;
-    lev.android_array[Yemerald_eB]     = Xemerald;
-    lev.android_array[Yemerald_wB]     = Xemerald;
-  }
-
-  if (temp & 2)
-  {
-    lev.android_array[Xdiamond]                = Xdiamond;
-    lev.android_array[Xdiamond_pause]  = Xdiamond;
-    lev.android_array[Xdiamond_fall]   = Xdiamond;
-    lev.android_array[Ydiamond_sB]     = Xdiamond;
-    lev.android_array[Ydiamond_eB]     = Xdiamond;
-    lev.android_array[Ydiamond_wB]     = Xdiamond;
-  }
+  cav.teamwork = (src[2150] & 128) != 0;
 
-  if (temp & 4)
-  {
-    lev.android_array[Xstone]          = Xstone;
-    lev.android_array[Xstone_pause]    = Xstone;
-    lev.android_array[Xstone_fall]     = Xstone;
-    lev.android_array[Ystone_sB]       = Xstone;
-    lev.android_array[Ystone_eB]       = Xstone;
-    lev.android_array[Ystone_wB]       = Xstone;
-  }
-
-  if (temp & 8)
-  {
-    lev.android_array[Xbomb]           = Xbomb;
-    lev.android_array[Xbomb_pause]     = Xbomb;
-    lev.android_array[Xbomb_fall]      = Xbomb;
-    lev.android_array[Ybomb_sB]                = Xbomb;
-    lev.android_array[Ybomb_eB]                = Xbomb;
-    lev.android_array[Ybomb_wB]                = Xbomb;
-  }
-
-  if (temp & 16)
-  {
-    lev.android_array[Xnut]            = Xnut;
-    lev.android_array[Xnut_pause]      = Xnut;
-    lev.android_array[Xnut_fall]       = Xnut;
-    lev.android_array[Ynut_sB]         = Xnut;
-    lev.android_array[Ynut_eB]         = Xnut;
-    lev.android_array[Ynut_wB]         = Xnut;
-  }
-
-  if (temp & 32)
-  {
-    lev.android_array[Xtank_1_n]       = Xtank_1_n;
-    lev.android_array[Xtank_2_n]       = Xtank_1_n;
-    lev.android_array[Ytank_nB]                = Xtank_1_n;
-    lev.android_array[Ytank_n_e]       = Xtank_1_n;
-    lev.android_array[Ytank_n_w]       = Xtank_1_n;
-
-    lev.android_array[Xtank_1_e]       = Xtank_1_e;
-    lev.android_array[Xtank_2_e]       = Xtank_1_e;
-    lev.android_array[Ytank_eB]                = Xtank_1_e;
-    lev.android_array[Ytank_e_s]       = Xtank_1_e;
-    lev.android_array[Ytank_e_n]       = Xtank_1_e;
-
-    lev.android_array[Xtank_1_s]       = Xtank_1_s;
-    lev.android_array[Xtank_2_s]       = Xtank_1_s;
-    lev.android_array[Ytank_sB]                = Xtank_1_s;
-    lev.android_array[Ytank_s_w]       = Xtank_1_s;
-    lev.android_array[Ytank_s_e]       = Xtank_1_s;
-
-    lev.android_array[Xtank_1_w]       = Xtank_1_w;
-    lev.android_array[Xtank_2_w]       = Xtank_1_w;
-    lev.android_array[Ytank_wB]                = Xtank_1_w;
-    lev.android_array[Ytank_w_n]       = Xtank_1_w;
-    lev.android_array[Ytank_w_s]       = Xtank_1_w;
-  }
+  /* scores */
 
-  if (temp & 64)
-  {
-    lev.android_array[Xeater_n]                = Xeater_n;
-    lev.android_array[Yeater_nB]       = Xeater_n;
+  cav.emerald_score    = src[2084];
+  cav.diamond_score    = src[2085];
+  cav.alien_score      = src[2086];
+  cav.tank_score       = src[2087];
+  cav.bug_score                = src[2088];
+  cav.eater_score      = src[2089];
+  cav.nut_score                = src[2090];
+  cav.dynamite_score   = src[2091];
+  cav.key_score                = src[2092];
+  cav.exit_score       = src[2093];
 
-    lev.android_array[Xeater_e]                = Xeater_e;
-    lev.android_array[Yeater_eB]       = Xeater_e;
+  cav.lenses_score     = src[2151];
+  cav.magnify_score    = src[2152];
+  cav.slurp_score      = src[2153];
 
-    lev.android_array[Xeater_s]                = Xeater_s;
-    lev.android_array[Yeater_sB]       = Xeater_s;
+  /* times */
 
-    lev.android_array[Xeater_w]                = Xeater_w;
-    lev.android_array[Yeater_wB]       = Xeater_w;
-  }
+  cav.android_move_time  = MIN(GET_BE16(src[2164]), 9999);
+  cav.android_clone_time = MIN(GET_BE16(src[2166]), 9999);
+  cav.ball_time                 = MIN(GET_BE16(src[2160]), 9999);
 
-  if (temp & 128)
-  {
-    lev.android_array[Xbug_1_n]                = Xbug_2_n;
-    lev.android_array[Xbug_2_n]                = Xbug_2_n;
-    lev.android_array[Ybug_nB]         = Xbug_2_n;
-    lev.android_array[Ybug_n_e]                = Xbug_2_n;
-    lev.android_array[Ybug_n_w]                = Xbug_2_n;
-
-    lev.android_array[Xbug_1_e]                = Xbug_2_e;
-    lev.android_array[Xbug_2_e]                = Xbug_2_e;
-    lev.android_array[Ybug_eB]         = Xbug_2_e;
-    lev.android_array[Ybug_e_s]                = Xbug_2_e;
-    lev.android_array[Ybug_e_n]                = Xbug_2_e;
-
-    lev.android_array[Xbug_1_s]                = Xbug_2_s;
-    lev.android_array[Xbug_2_s]                = Xbug_2_s;
-    lev.android_array[Ybug_sB]         = Xbug_2_s;
-    lev.android_array[Ybug_s_w]                = Xbug_2_s;
-    lev.android_array[Ybug_s_e]                = Xbug_2_s;
-
-    lev.android_array[Xbug_1_w]                = Xbug_2_w;
-    lev.android_array[Xbug_2_w]                = Xbug_2_w;
-    lev.android_array[Ybug_wB]         = Xbug_2_w;
-    lev.android_array[Ybug_w_n]                = Xbug_2_w;
-    lev.android_array[Ybug_w_s]                = Xbug_2_w;
-  }
+  cav.lenses_time      = MIN(GET_BE16(src[2154]), 9999);
+  cav.magnify_time     = MIN(GET_BE16(src[2156]), 9999);
+  cav.wheel_time       = MIN(GET_BE16(src[2104]), 9999);
 
-  if (temp & 256)
-  {
-    lev.android_array[Xalien]          = Xalien;
-    lev.android_array[Xalien_pause]    = Xalien;
-    lev.android_array[Yalien_nB]       = Xalien;
-    lev.android_array[Yalien_eB]       = Xalien;
-    lev.android_array[Yalien_sB]       = Xalien;
-    lev.android_array[Yalien_wB]       = Xalien;
-  }
+  cav.amoeba_time      = MIN(GET_BE16(src[2100]) * 28, 9999);
+  cav.wonderwall_time  = MIN(GET_BE16(src[2102]), 9999);
 
-  if (temp & 512)
-  {
-    lev.android_array[Xspring]         = Xspring;
-    lev.android_array[Xspring_pause]   = Xspring;
-    lev.android_array[Xspring_e]       = Xspring;
-    lev.android_array[Yspring_eB]      = Xspring;
-    lev.android_array[Yspring_alien_eB]        = Xspring;
-    lev.android_array[Xspring_w]       = Xspring;
-    lev.android_array[Yspring_wB]      = Xspring;
-    lev.android_array[Yspring_alien_wB]        = Xspring;
-    lev.android_array[Xspring_fall]    = Xspring;
-    lev.android_array[Yspring_sB]      = Xspring;
-  }
+  cav.wind_time                = 9999;
+  temp = src[2149];
+  cav.wind_direction = (temp & 8 ? 0 :
+                       temp & 1 ? 1 :
+                       temp & 2 ? 2 :
+                       temp & 4 ? 3 : 4);
 
-  if (temp & 1024)
-  {
-    lev.android_array[Yballoon_nB]     = Xballoon;
-    lev.android_array[Yballoon_eB]     = Xballoon;
-    lev.android_array[Yballoon_sB]     = Xballoon;
-    lev.android_array[Yballoon_wB]     = Xballoon;
-    lev.android_array[Xballoon]                = Xballoon;
-  }
+  /* global flags */
 
-  if (temp & 2048)
-  {
-    lev.android_array[Xfake_amoeba]    = Xdrip;
-    lev.android_array[Yfake_amoeba]    = Xdrip;
-    lev.android_array[Xamoeba_1]       = Xdrip;
-    lev.android_array[Xamoeba_2]       = Xdrip;
-    lev.android_array[Xamoeba_3]       = Xdrip;
-    lev.android_array[Xamoeba_4]       = Xdrip;
-    lev.android_array[Xamoeba_5]       = Xdrip;
-    lev.android_array[Xamoeba_6]       = Xdrip;
-    lev.android_array[Xamoeba_7]       = Xdrip;
-    lev.android_array[Xamoeba_8]       = Xdrip;
-  }
+  cav.ball_random = (src[2162] & 1)   != 0;
+  cav.ball_active = (src[2162] & 128) != 0;
 
-  if (temp & 4096)
-  {
-    lev.android_array[Xdynamite]       = Xdynamite;
-  }
+  cav.wonderwall_active        = FALSE;
+  cav.wheel_active     = FALSE;
+  cav.lenses_active    = FALSE;
+  cav.magnify_active   = FALSE;
 
   for (temp = 1; temp < 2047; temp++)
   {
     switch (src[temp])
     {
-      case 0x24:                               /* wonderwall */
-       lev.wonderwall_state_initial = 1;
-       lev.wonderwall_time_initial = 9999;
+      case 36:                                 /* wonderwall */
+       cav.wonderwall_active = TRUE;
+       cav.wonderwall_time = 9999;
        break;
 
-      case 0x28:                               /* wheel */
-       lev.wheel_x_initial = temp & 63;
-       lev.wheel_y_initial = temp >> 6;
-       lev.wheel_cnt_initial = lev.wheel_time;
+      case 40:                                 /* wheel */
+       cav.wheel_active = TRUE;
+       cav.wheel_x = temp % 64;
+       cav.wheel_y = temp / 64;
        break;
 
-      case 0xA3:                               /* fake blank */
-       lev.lenses_cnt_initial = 9999;
+      case 163:                                        /* fake blank */
+       cav.lenses_active = TRUE;
        break;
 
-      case 0xA4:                               /* fake grass */
-       lev.magnify_cnt_initial = 9999;
+      case 164:                                        /* fake grass */
+       cav.magnify_active = TRUE;
        break;
     }
   }
 
-  /* first fill the complete playfield with the default border element */
+  /* android */
+
+  temp = GET_BE16(src[2168]);
+
+  for (i = 0; i < GAME_TILE_MAX; i++)
+    cav.android_array[i] = Cblank;
+
+  for (i = 0; android_clone_table[i].bit_nr != -1; i++)
+    if (temp & (1 << android_clone_table[i].bit_nr))
+      cav.android_array[android_clone_table[i].clone_from] =
+       android_clone_table[i].clone_to;
+
+  /* eaters */
+
+  for (i = 0; i < 8; i++)
+    for (x = 0; x < 9; x++)
+      cav.eater_array[i][x] = map_emc[src[eater_offset[i] + x]];
+
+  if (file_version < FILE_VERSION_EM_V6)
+    cav.num_eater_arrays = 4;
+
+  /* ball */
+
+  temp = map_emc[src[2159]];
+
+  for (y = 0; y < 8; y++)
+  {
+    if (src[2162] & 1)
+    {
+      for (x = 0; x < 8; x++)
+       cav.ball_array[y][x] = temp;
+    }
+    else
+    {
+      cav.ball_array[y][1] = (src[2163] & 1)  ? temp : Cblank; /* north */
+      cav.ball_array[y][6] = (src[2163] & 2)  ? temp : Cblank; /* south */
+      cav.ball_array[y][3] = (src[2163] & 4)  ? temp : Cblank; /* west */
+      cav.ball_array[y][4] = (src[2163] & 8)  ? temp : Cblank; /* east */
+      cav.ball_array[y][7] = (src[2163] & 16) ? temp : Cblank; /* southeast */
+      cav.ball_array[y][5] = (src[2163] & 32) ? temp : Cblank; /* southwest */
+      cav.ball_array[y][2] = (src[2163] & 64) ? temp : Cblank; /* northeast */
+      cav.ball_array[y][0] = (src[2163] & 128)? temp : Cblank; /* northwest */
+    }
+  }
+
+  /* players */
+
+  for (i = 0; i < 2; i++)
+  {
+    temp = GET_BE16(src[2096 + i * 2]);
+
+    cav.player_x[i] = (temp & 63);
+    cav.player_y[i] = (temp >> 6 & 31);
+  }
+
+  /* cave */
+
+  /* first fill the complete playfield with the empty space element */
   for (y = 0; y < CAVE_HEIGHT; y++)
     for (x = 0; x < CAVE_WIDTH; x++)
-      native_em_level.cave[x][y] = Zborder;
+      cav.cave[x][y] = Cblank;
 
   /* 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][y] =
-       get_em_element(src[temp++], file_version);
-
-  /* at last, set the two players at their positions in the playfield */
-  /* (native EM[C] levels always have exactly two players in a level) */
-  for (i = 0; i < 2; i++)
-    native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
+  for (y = 0; y < cav.height; y++)
+    for (x = 0; x < cav.width; x++)
+      cav.cave[x][y] = map_emc[src[temp++]];
 
   native_em_level.file_version = file_version;
 }
@@ -464,87 +467,101 @@ void convert_em_level(unsigned char *src, int file_version)
  * wrong bug(24 instead of 20) and tank(12 instead of 8).
  */
 
+/* changes for game engine integration in Rocks'n'Diamonds:
+ *
+ * cave versions below V5 used different objects than later versions
+ * - steel/wall/roundwall of type 1 was used instead of type 2
+ * - dirt was used instead of grass
+ * - wall codes 129, 131 and 132 are changed to 180, 179 and 252
+ * - object code 130 (V6 grass) is changed to 189 (V6 dirt)
+ * - object codes are changed in both cave and eater arrays
+ * - only graphical change, as changed objects behave the same
+ *
+ * acid with no base beneath it is converted to fake acid
+ * - required for downunder mine 16, level 0 (and others)
+ */
+
 static const unsigned char map_v6[256] =
 {
   /* filter for v6 */
 
-  0,0,2,2,         4,4,118,118,     8,9,10,11,       12,13,14,15,
-  16,16,18,18,     20,21,22,23,     24,25,26,27,     28,28,118,28,
-  0,16,2,18,       36,37,37,37,     40,41,42,43,     44,45,128,128,
-  128,148,148,     148,45,45,45,    148,0,57,58,     59,60,61,62,63,
-
-  64,65,66,67,     68,69,69,71,     72,73,74,75,     118,75,75,75,
-  75,75,75,75,     75,153,153,153,  153,153,153,153, 153,153,153,153,
-  153,153,153,99,  100,68,68,68,    68,68,68,68,     68,118,118,118,
-  118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
-
-  128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
-  144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
-  160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
-  176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
-
-  192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
-  208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
-  224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
-  240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
+  0,0,2,2,         4,4,118,118,     8,9,10,11,       12,13,14,15,      //   0
+  16,16,18,18,     20,21,22,23,     24,25,26,27,     28,28,128,28,     //  16
+  0,16,2,18,       36,37,37,37,     40,41,42,43,     44,45,128,128,    //  32
+  128,148,148,148, 45,45,45,148,    0,57,58,59,      60,61,62,63,      //  48
+
+  64,65,66,67,     68,69,69,71,     72,73,74,75,     118,75,75,75,     //  64
+  75,75,75,75,     75,153,153,153,  153,153,153,153, 153,153,153,153,  //  80
+  153,153,153,99,  100,68,68,68,    68,68,68,68,     68,118,118,118,   //  96
+  118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,  // 112
+
+  128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,  // 128
+  144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,  // 144
+  160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,  // 160
+  176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,   // 176
+
+  192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,  // 192
+  208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,  // 208
+  224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,  // 224
+  240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153   // 240
 };
 
 static const unsigned char map_v5[256] =
 {
   /* filter for v5 */
 
-  0,0,2,2,         4,4,118,118,     8,9,10,11,       12,13,14,15,
-  16,16,18,18,     20,21,22,23,     24,25,26,27,     28,28,118,28,
-  0,16,2,18,       36,37,37,37,     147,41,42,43,    44,45,128,128,
-  128,148,148,148, 45,45,45,148,    0,57,58,59,      60,61,62,63,
-
-  64,65,66,67,     68,153,153,153,  153,153,153,153, 153,153,153,153,
-  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
-  153,153,153,153, 153,68,68,68,    68,68,68,68,     68,118,118,118,
-  118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
-
-  128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
-  144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
-  160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
-  176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
-
-  153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
-  208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
-  224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
-  240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
+  0,0,2,2,         4,4,118,118,     8,9,10,11,       12,13,14,15,      //   0
+  16,16,18,18,     20,21,22,23,     24,25,26,27,     28,28,128,28,     //  16
+  0,16,2,18,       36,37,37,37,     147,41,42,43,    44,45,128,128,    //  32
+  128,148,148,148, 45,45,45,148,    0,57,58,59,      60,61,62,63,      //  48
+
+  64,65,66,67,     68,153,153,153,  153,153,153,153, 153,153,153,153,  //  64
+  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,  //  80
+  153,153,153,153, 153,68,68,68,    68,68,68,68,     68,118,118,118,   //  96
+  118,118,114,115, 131,62,118,119,  120,121,122,118, 118,118,118,118,  // 112
+
+  128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,  // 128
+  144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,  // 144
+  160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,  // 160
+  176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,   // 176
+
+  153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,  // 192
+  208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,  // 208
+  224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,  // 224
+  240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153   // 240
 };
 
 static const unsigned char map_v4[256] =
 {
   /* filter for v4 */
 
-  0,0,2,2,         4,4,118,118,     8,9,10,11,       12,13,14,15,
-  16,16,18,18,     20,21,22,23,     24,25,26,27,     28,28,118,28,
-  0,16,2,18,       36,37,37,37,     147,41,42,43,    44,45,128,128,
-  128,148,148,148, 45,45,45,148,    0,153,153,59,    60,61,62,63,
-
-  64,65,66,153,    153,153,153,153, 153,153,153,153, 153,153,153,153,
-  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
-  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
-  153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
-
-  128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
-  144,145,146,147, 148,149,150,151, 152,68,154,155,  156,157,158,160,
-  160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
-  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
-
-  153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
-  208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
-  224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
-  240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
+  0,0,2,2,         4,4,118,118,     8,9,10,11,       12,13,14,15,      //   0
+  16,16,18,18,     20,21,22,23,     24,25,26,27,     28,28,128,28,     //  16
+  0,16,2,18,       36,37,37,37,     147,41,42,43,    44,45,128,128,    //  32
+  128,148,148,148, 45,45,45,148,    0,153,153,59,    60,61,62,63,      //  48
+
+  64,65,66,153,    153,153,153,153, 153,153,153,153, 153,153,153,153,  //  64
+  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,  //  80
+  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,  //  96
+  153,118,114,115, 179,62,118,119,  120,121,122,118, 118,118,118,118,  // 112
+
+  128,180,189,179, 252,133,134,135, 136,137,138,139, 140,141,142,143,  // 128
+  144,145,146,147, 148,149,150,151, 152,68,248,249,  250,251,158,160,  // 144
+  160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,  // 160
+  153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,   // 176
+
+  153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,  // 192
+  208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,  // 208
+  224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,  // 224
+  240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153   // 240
 };
 
-static const unsigned char map_v4_eater[32] =
+static const unsigned char map_v4_eater[28] =
 {
   /* filter for v4 eater */
 
-  128,18,2,0,      4,8,16,20,       28,37,41,45,     130,129,131,132,
-  133,134,135,136, 146,147,175,65,  66,64,2,18,      128,128,128,128
+  128,18,2,0,      4,8,16,20,       28,37,41,45,     189,180,179,252,  //   0
+  133,134,135,136, 146,147,175,65,  66,64,2,18                         //  16
 };
 
 static boolean filename_has_v1_format(char *filename)
@@ -560,7 +577,7 @@ static boolean filename_has_v1_format(char *filename)
 int cleanup_em_level(unsigned char *src, int length, char *filename)
 {
   int file_version = FILE_VERSION_EM_UNKNOWN;
-  int i;
+  int i, j;
 
   if (length >= 2172 &&
       src[2106] == 255 &&              /* version id: */
@@ -572,11 +589,11 @@ int cleanup_em_level(unsigned char *src, int length, char *filename)
     file_version = FILE_VERSION_EM_V6;
 
     /* remap elements to internal EMC level format */
-    for (i = 0; i < 2048; i++)
+    for (i = 0; i < 2048; i++)         /* cave */
       src[i] = map_v6[src[i]];
-    for (i = 2048; i < 2084; i++)
+    for (i = 2048; i < 2084; i++)      /* eaters */
       src[i] = map_v6[src[i]];
-    for (i = 2112; i < 2148; i++)
+    for (i = 2112; i < 2148; i++)      /* eaters */
       src[i] = map_v6[src[i]];
   }
   else if (length >= 2110 &&
@@ -589,11 +606,11 @@ int cleanup_em_level(unsigned char *src, int length, char *filename)
     file_version = FILE_VERSION_EM_V5;
 
     /* remap elements to internal EMC level format */
-    for (i = 0; i < 2048; i++)
+    for (i = 0; i < 2048; i++)         /* cave */
       src[i] = map_v5[src[i]];
-    for (i = 2048; i < 2084; i++)
+    for (i = 2048; i < 2084; i++)      /* eaters */
       src[i] = map_v5[src[i]];
-    for (i = 2112; i < 2148; i++)
+    for (i = 2112; i < 2148; i++)      /* eaters */
       src[i] = src[i - 64];
   }
   else if (length >= 2106 &&
@@ -654,18 +671,18 @@ int cleanup_em_level(unsigned char *src, int length, char *filename)
     }
 
     /* remap elements to internal EMC level format */
-    for (i = 0; i < 2048; i++)
+    for (i = 0; i < 2048; i++)         /* cave */
       src[i] = map_v4[src[i]];
-    for (i = 2048; i < 2084; i++)
-      src[i] = map_v4_eater[src[i] >= 28 ? 0 : src[i]];
-    for (i = 2112; i < 2148; i++)
+    for (i = 2048; i < 2084; i++)      /* eaters */
+      src[i] = map_v4_eater[src[i] < 28 ? src[i] : 0];
+    for (i = 2112; i < 2148; i++)      /* eaters */
       src[i] = src[i - 64];
 
     if (fix_copyright)         /* fix "(c)" sign in Emerald Mine II levels */
     {
       for (i = 0; i < 2048; i++)
        if (src[i] == 241)
-         src[i] = 254;         /* replace 'Xdecor_1' with 'Xalpha_copyr' */
+         src[i] = 254;         /* replace 'Cdecor_1' with 'Calpha_copyr' */
     }
   }
   else
@@ -674,8 +691,7 @@ int cleanup_em_level(unsigned char *src, int length, char *filename)
 
     /* if file has length of old-style level file, print (wrong) magic byte */
     if (length < 2110)
-      Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
-           src[1983], 1983);
+      Warn("unknown magic byte 0x%02x at position 0x%04x", src[1983], 1983);
 
     return FILE_VERSION_EM_UNKNOWN;
   }
@@ -717,10 +733,10 @@ int cleanup_em_level(unsigned char *src, int length, char *filename)
 
   /* fix acid */
   for (i = 64; i < 2048; i++)
-    if (src[i] == 63)          /* replace element above 'Xacid_s' ... */
-      src[i - 64] = 101;       /* ... with 'Xacid_1' */
+    if (src[i] == 63)          /* replace element above 'Cacid_s' ... */
+      src[i - 64] = 101;       /* ... with 'Cacid_1' */
 
-  /* fix acid with no base beneath it (see below for details (*)) */
+  /* fix acid with no base beneath it (see comment above for details) */
   for (i = 64; i < 2048 - 1; i++)
   {
     if (file_version <= FILE_VERSION_EM_V2 &&
@@ -728,83 +744,24 @@ int cleanup_em_level(unsigned char *src, int length, char *filename)
     {
       if (src[i - 1] == 101 ||                 /* remove acid over acid row */
          src[i + 1] == 101)
-       src[i - 64] = 6;        /* replace element above with 'Xblank' */
+       src[i - 64] = 6;        /* replace element above with 'Cblank' */
       else
-       src[i - 64] = 255;      /* replace element above with 'Xfake_acid_1' */
+       src[i - 64] = 255;      /* replace element above with 'Cfake_acid_1' */
     }
   }
 
-  /* fix acid in eater 1 */
-  for (i = 2051; i < 2057; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
-
-  /* fix acid in eater 2 */
-  for (i = 2060; i < 2066; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
-
-  /* fix acid in eater 3 */
-  for (i = 2069; i < 2075; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
-
-  /* fix acid in eater 4 */
-  for (i = 2078; i < 2084; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
-
-  /* fix acid in eater 5 */
-  for (i = 2115; i < 2121; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
-
-  /* fix acid in eater 6 */
-  for (i = 2124; i < 2130; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
-
-  /* fix acid in eater 7 */
-  for (i = 2133; i < 2139; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
-
-  /* fix acid in eater 8 */
-  for (i = 2142; i < 2148; i++)
-    if (src[i] == 63)
-      src[i - 3] = 101;
+  /* fix acid in eaters */
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 6; j++)
+      if (src[eater_offset[i] + j + 3] == 63)
+       src[eater_offset[i] + j] = 101;
 
   /* old style time */
   src[2094] = 0;
 
-  /* player 1 pos */
-  src[2096] &= 7;
-  src[src[2096] << 8 | src[2097]] = 128;
-
-  /* player 2 pos */
-  src[2098] &= 7;
-  src[src[2098] << 8 | src[2099]] = 128;
-
-  /* amoeba speed */
-  if ((src[2100] << 8 | src[2101]) > 9999)
-  {
-    src[2100] = 39;
-    src[2101] = 15;
-  }
-
-  /* time wonderwall */
-  if ((src[2102] << 8 | src[2103]) > 9999)
-  {
-    src[2102] = 39;
-    src[2103] = 15;
-  }
-
-  /* time */
-  if ((src[2110] << 8 | src[2111]) > 9999)
-  {
-    src[2110] = 39;
-    src[2111] = 15;
-  }
+  /* set cave tile at player position to blank */
+  for (i = 0; i < 2; i++)
+    src[GET_BE16(src[2096 + i * 2]) % 2048] = 128;
 
   /* wind direction */
   i = src[2149];
@@ -812,58 +769,22 @@ int cleanup_em_level(unsigned char *src, int length, char *filename)
   i &= -i;
   src[2149] = i;
 
-  /* time lenses */
-  if ((src[2154] << 8 | src[2155]) > 9999)
-  {
-    src[2154] = 39;
-    src[2155] = 15;
-  }
-
-  /* time magnify */
-  if ((src[2156] << 8 | src[2157]) > 9999)
-  {
-    src[2156] = 39;
-    src[2157] = 15;
-  }
-
   /* ball object */
   src[2158] = 0;
   src[2159] = map_v6[src[2159]];
 
-  /* ball pause */
-  if ((src[2160] << 8 | src[2161]) > 9999)
-  {
-    src[2160] = 39;
-    src[2161] = 15;
-  }
-
   /* ball data */
   src[2162] &= 129;
   if (src[2162] & 1)
     src[2163] = 0;
 
-  /* android move pause */
-  if ((src[2164] << 8 | src[2165]) > 9999)
-  {
-    src[2164] = 39;
-    src[2165] = 15;
-  }
-
-  /* android clone pause */
-  if ((src[2166] << 8 | src[2167]) > 9999)
-  {
-    src[2166] = 39;
-    src[2167] = 15;
-  }
-
   /* android data */
   src[2168] &= 31;
 
   /* size of v6 cave */
   length = 2172;
 
-  if (options.debug)
-    Error(ERR_DEBUG, "EM level file version: %d", file_version);
+  Debug("level:native:EM", "EM level file version: %d", file_version);
 
   return file_version;
 }