X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame_em%2Freademc.c;h=dfa293a6ebe1eeee4d905142e7af8a0618bb9db0;hp=23c3f743c31d86f505319d4281c8ffdf88599fdf;hb=7f87d0a871432b2ed2fc1a7f3c30fc2c4ecf2dcf;hpb=ccae7930955b9fdb46e1d2da1373cc00ff76cff1 diff --git a/src/game_em/reademc.c b/src/game_em/reademc.c index 23c3f743..dfa293a6 100644 --- a/src/game_em/reademc.c +++ b/src/game_em/reademc.c @@ -40,246 +40,406 @@ * 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, - return em_element; + [Croundwall_1] = Croundwall_2, + [Croundwall_2] = Croundwall_1 +}; + +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++) + /* swap tiles for pre-EMC caves (older than V5/V6), if needed */ + + 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]]; + + /* common to all emc caves */ + + cav.width = 64; + cav.height = 32; + + cav.time_seconds = MIN(GET_BE16(src[2110]), 9999); + cav.gems_needed = src[2095]; + + cav.teamwork = (src[2150] & 128) != 0; + + /* scores */ + + 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]; + + cav.lenses_score = src[2151]; + cav.magnify_score = src[2152]; + cav.slurp_score = src[2153]; + + /* times */ + + 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); + + 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); + + cav.amoeba_time = MIN(GET_BE16(src[2100]) * 28, 9999); + cav.wonderwall_time = MIN(GET_BE16(src[2102]), 9999); + + cav.wind_time = 9999; + temp = src[2149]; + cav.wind_direction = (temp & 8 ? 0 : + temp & 1 ? 1 : + temp & 2 ? 2 : + temp & 4 ? 3 : 4); + + /* global flags */ + + cav.ball_random = (src[2162] & 1) != 0; + cav.ball_active = (src[2162] & 128) != 0; + + cav.wonderwall_active = FALSE; + cav.wheel_active = FALSE; + cav.lenses_active = FALSE; + cav.magnify_active = FALSE; + + for (temp = 1; temp < 2047; temp++) { - temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2]; - ply[i].x_initial = (temp & 63); - ply[i].y_initial = (temp >> 6 & 31); + switch (src[temp]) + { + case 36: /* wonderwall */ + cav.wonderwall_active = TRUE; + cav.wonderwall_time = 9999; + break; + + case 40: /* wheel */ + cav.wheel_active = TRUE; + cav.wheel_x = temp % 64; + cav.wheel_y = temp / 64; + break; + + case 163: /* fake blank */ + cav.lenses_active = TRUE; + break; + + case 164: /* fake grass */ + cav.magnify_active = TRUE; + break; + } } - 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]; + /* 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++) - lev.eater_array[i][x] = - get_em_element(src[eater_offset[i] + x], file_version); + 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]]; - temp = get_em_element(src[0x86F], file_version); for (y = 0; y < 8; y++) { - if (src[0x872] & 1) + if (src[2162] & 1) { for (x = 0; x < 8; x++) - lev.ball_array[y][x] = temp; + cav.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.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 */ } } - temp = src[0x878] << 8 | src[0x879]; - - lev.android_emerald = (temp & 1) != 0; - lev.android_diamond = (temp & 2) != 0; - lev.android_stone = (temp & 4) != 0; - lev.android_bomb = (temp & 8) != 0; - lev.android_nut = (temp & 16) != 0; - lev.android_tank = (temp & 32) != 0; - lev.android_eater = (temp & 64) != 0; - lev.android_bug = (temp & 128) != 0; - lev.android_alien = (temp & 256) != 0; - lev.android_spring = (temp & 512) != 0; - lev.android_balloon = (temp & 1024) != 0; - lev.android_amoeba = (temp & 2048) != 0; - lev.android_dynamite = (temp & 4096) != 0; + /* players */ - for (temp = 1; temp < 2047; temp++) + for (i = 0; i < 2; i++) { - switch (src[temp]) - { - case 0x24: /* wonderwall */ - lev.wonderwall_state_initial = 1; - lev.wonderwall_time_initial = 9999; - break; - - case 0x28: /* wheel */ - lev.wheel_x_initial = temp & 63; - lev.wheel_y_initial = temp >> 6; - lev.wheel_cnt_initial = lev.wheel_time; - break; - - case 0xA3: /* fake blank */ - lev.lenses_cnt_initial = 9999; - break; + temp = GET_BE16(src[2096 + i * 2]); - case 0xA4: /* fake grass */ - lev.magnify_cnt_initial = 9999; - break; - } + cav.player_x[i] = (temp & 63); + cav.player_y[i] = (temp >> 6 & 31); } - /* first fill the complete playfield with the default border element */ + /* 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; } @@ -307,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) @@ -403,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: */ @@ -415,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 && @@ -432,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 && @@ -497,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 @@ -517,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; } @@ -560,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 && @@ -571,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]; @@ -655,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; }