3 * handle binary emc cave file format
9 /* convert emc caves to intermediate cave format.
11 * the intermediate format supports most emc caves, but some internal
12 * objects are not supported.
15 * - active objects - use global flags instead of individual on/off
16 * - falling or paused objects - become still objects
17 * - sand states - become either sand with/without stone
18 * - collected objects - become a common pause object
19 * - drip states - become a normal drip
22 * - exploding objects (not in emc player either)
24 * pushed objects are supported in the cave, eaters and magic ball.
25 * they behave almost the same as in the emc player, pushing over
26 * steel wall, androids, players etc. a compile time option chooses
27 * if pushed objects go into the acid.
29 * acid is handled completely different in my player. acid top is a
30 * separate object, which can be put anywhere and the beasts will
31 * be gobbled, even if they go in from below. in the emc player, an
32 * acid top without a bottom becomes plant.
34 * borderless caves are supported, almost the same as in the emc
35 * player. going off the left edge of the screen resulted in the
36 * beast/player moving up 1 square (and the player disappeared).
37 * going off the right edge of the screen, the beast/player would
38 * go down 1 square. in my player, everything stays on the same y
39 * coord, which is sensible, but breaks caves which expect the old
43 #define GET_BE16(x) ((&x)[0] << 8 | (&x)[1])
45 static const short map_emc[256] =
47 Cstone, Cstone, Cdiamond, Cdiamond,
48 Calien, Calien, Cblank, Cblank,
49 Ctank_1_n, Ctank_1_e, Ctank_1_s, Ctank_1_w,
50 Ctank_2_n, Ctank_2_e, Ctank_2_s, Ctank_2_w,
52 Cbomb, Cbomb, Cemerald, Cemerald,
53 Cbug_1_n, Cbug_1_e, Cbug_1_s, Cbug_1_w,
54 Cbug_2_n, Cbug_2_e, Cbug_2_s, Cbug_2_w,
55 Cdrip, Cdrip, Cdrip, Cdrip,
57 Cstone, Cbomb, Cdiamond, Cemerald,
58 Cwonderwall, Cnut, Cnut, Cnut,
59 Cwheel, Ceater_n, Ceater_s, Ceater_w,
60 Ceater_e, Csand_stone, Cblank, Cblank,
62 Cblank, Csand, Csand, Csand,
63 Csand_stone, Csand_stone, Csand_stone, Csand,
64 Cstone, Cslide_ew, Cslide_ns, Cdynamite_1,
65 Cdynamite_2, Cdynamite_3, Cdynamite_4, Cacid_s,
67 Cexit_1, Cexit_2, Cexit_3, Cballoon,
68 Cplant, Cspring, Cspring, Cpush_spring_w,
69 Cpush_spring_e, Cball_1, Cball_2, Candroid,
70 Cblank, Candroid, Candroid, Candroid,
72 Candroid, Candroid, Candroid, Candroid,
73 Candroid, Cblank, Cblank, Cblank,
74 Cblank, Cblank, Cblank, Cblank,
75 Cblank, Cblank, Cblank, Cblank,
77 Cblank, Cblank, Cblank, Cpush_spring_w,
78 Cpush_spring_e, Cacid_1, Cacid_2, Cacid_3,
79 Cacid_4, Cacid_5, Cacid_6, Cacid_7,
80 Cacid_8, Cblank, Cblank, Cblank,
82 Cblank, Cblank, Cpush_nut_w, Cpush_nut_e,
83 Csteel_1, Cblank, Cblank, Cpush_bomb_w,
84 Cpush_bomb_e, Cpush_stone_w, Cpush_stone_e, Cblank,
85 Cblank, Cblank, Cblank, Cblank,
87 Cblank, Croundwall_1, Cgrass, Csteel_1,
88 Cwall_1, Ckey_1, Ckey_2, Ckey_3,
89 Ckey_4, Cdoor_1, Cdoor_2, Cdoor_3,
90 Cdoor_4, Cfake_amoeba, Cfake_door_1, Cfake_door_2,
92 Cfake_door_3, Cfake_door_4, Cwonderwall, Cwheel,
93 Csand, Cacid_nw, Cacid_ne, Cacid_sw,
94 Cacid_se, Cfake_blank, Camoeba_1, Camoeba_2,
95 Camoeba_3, Camoeba_4, Cexit, Calpha_arrow_w,
97 Cfake_grass, Clenses, Cmagnify, Cfake_blank,
98 Cfake_grass, Cswitch, Cswitch, Cblank,
99 Cdecor_8, Cdecor_9, Cdecor_10, Cdecor_5,
100 Calpha_comma, Calpha_apost, Calpha_minus, Cdynamite,
102 Csteel_3, Cdecor_6, Cdecor_7, Csteel_2,
103 Croundwall_2, Cdecor_2, Cdecor_4, Cdecor_3,
104 Cwind_any, Cwind_e, Cwind_s, Cwind_w,
105 Cwind_n, Cdirt, Cplant, Ckey_5,
107 Ckey_6, Ckey_7, Ckey_8, Cdoor_5,
108 Cdoor_6, Cdoor_7, Cdoor_8, Cbumper,
109 Calpha_a, Calpha_b, Calpha_c, Calpha_d,
110 Calpha_e, Calpha_f, Calpha_g, Calpha_h,
112 Calpha_i, Calpha_j, Calpha_k, Calpha_l,
113 Calpha_m, Calpha_n, Calpha_o, Calpha_p,
114 Calpha_q, Calpha_r, Calpha_s, Calpha_t,
115 Calpha_u, Calpha_v, Calpha_w, Calpha_x,
117 Calpha_y, Calpha_z, Calpha_0, Calpha_1,
118 Calpha_2, Calpha_3, Calpha_4, Calpha_5,
119 Calpha_6, Calpha_7, Calpha_8, Calpha_9,
120 Calpha_perio, Calpha_excla, Calpha_colon, Calpha_quest,
122 Calpha_arrow_e, Cdecor_1, Cfake_door_5, Cfake_door_6,
123 Cfake_door_7, Cfake_door_8, Cblank, Cblank,
124 Cblank, Cblank, Cblank, Cblank,
125 Cblank, Cblank, Calpha_copyr, Cfake_acid_1
128 static void init_android_clone_table(short android_clone_bits)
130 boolean android_emerald = (android_clone_bits & 1) != 0;
131 boolean android_diamond = (android_clone_bits & 2) != 0;
132 boolean android_stone = (android_clone_bits & 4) != 0;
133 boolean android_bomb = (android_clone_bits & 8) != 0;
134 boolean android_nut = (android_clone_bits & 16) != 0;
135 boolean android_tank = (android_clone_bits & 32) != 0;
136 boolean android_eater = (android_clone_bits & 64) != 0;
137 boolean android_bug = (android_clone_bits & 128) != 0;
138 boolean android_alien = (android_clone_bits & 256) != 0;
139 boolean android_spring = (android_clone_bits & 512) != 0;
140 boolean android_balloon = (android_clone_bits & 1024) != 0;
141 boolean android_amoeba = (android_clone_bits & 2048) != 0;
142 boolean android_dynamite = (android_clone_bits & 4096) != 0;
145 for (i = 0; i < TILE_MAX; i++)
146 cav.android_array[i] = Cblank;
150 cav.android_array[Xeater_n] = Ceater_n;
151 cav.android_array[Yeater_nB] = Ceater_n;
153 cav.android_array[Xeater_e] = Ceater_e;
154 cav.android_array[Yeater_eB] = Ceater_e;
156 cav.android_array[Xeater_s] = Ceater_s;
157 cav.android_array[Yeater_sB] = Ceater_s;
159 cav.android_array[Xeater_w] = Ceater_w;
160 cav.android_array[Yeater_wB] = Ceater_w;
165 cav.android_array[Xalien] = Calien;
166 cav.android_array[Xalien_pause] = Calien;
167 cav.android_array[Yalien_nB] = Calien;
168 cav.android_array[Yalien_eB] = Calien;
169 cav.android_array[Yalien_sB] = Calien;
170 cav.android_array[Yalien_wB] = Calien;
175 cav.android_array[Xbug_1_n] = Cbug_2_n;
176 cav.android_array[Xbug_2_n] = Cbug_2_n;
177 cav.android_array[Ybug_nB] = Cbug_2_n;
178 cav.android_array[Ybug_n_e] = Cbug_2_n;
179 cav.android_array[Ybug_n_w] = Cbug_2_n;
181 cav.android_array[Xbug_1_e] = Cbug_2_e;
182 cav.android_array[Xbug_2_e] = Cbug_2_e;
183 cav.android_array[Ybug_eB] = Cbug_2_e;
184 cav.android_array[Ybug_e_s] = Cbug_2_e;
185 cav.android_array[Ybug_e_n] = Cbug_2_e;
187 cav.android_array[Xbug_1_s] = Cbug_2_s;
188 cav.android_array[Xbug_2_s] = Cbug_2_s;
189 cav.android_array[Ybug_sB] = Cbug_2_s;
190 cav.android_array[Ybug_s_w] = Cbug_2_s;
191 cav.android_array[Ybug_s_e] = Cbug_2_s;
193 cav.android_array[Xbug_1_w] = Cbug_2_w;
194 cav.android_array[Xbug_2_w] = Cbug_2_w;
195 cav.android_array[Ybug_wB] = Cbug_2_w;
196 cav.android_array[Ybug_w_n] = Cbug_2_w;
197 cav.android_array[Ybug_w_s] = Cbug_2_w;
202 cav.android_array[Xtank_1_n] = Ctank_1_n;
203 cav.android_array[Xtank_2_n] = Ctank_1_n;
204 cav.android_array[Ytank_nB] = Ctank_1_n;
205 cav.android_array[Ytank_n_e] = Ctank_1_n;
206 cav.android_array[Ytank_n_w] = Ctank_1_n;
208 cav.android_array[Xtank_1_e] = Ctank_1_e;
209 cav.android_array[Xtank_2_e] = Ctank_1_e;
210 cav.android_array[Ytank_eB] = Ctank_1_e;
211 cav.android_array[Ytank_e_s] = Ctank_1_e;
212 cav.android_array[Ytank_e_n] = Ctank_1_e;
214 cav.android_array[Xtank_1_s] = Ctank_1_s;
215 cav.android_array[Xtank_2_s] = Ctank_1_s;
216 cav.android_array[Ytank_sB] = Ctank_1_s;
217 cav.android_array[Ytank_s_w] = Ctank_1_s;
218 cav.android_array[Ytank_s_e] = Ctank_1_s;
220 cav.android_array[Xtank_1_w] = Ctank_1_w;
221 cav.android_array[Xtank_2_w] = Ctank_1_w;
222 cav.android_array[Ytank_wB] = Ctank_1_w;
223 cav.android_array[Ytank_w_n] = Ctank_1_w;
224 cav.android_array[Ytank_w_s] = Ctank_1_w;
229 cav.android_array[Xemerald] = Cemerald;
230 cav.android_array[Xemerald_pause] = Cemerald;
231 cav.android_array[Xemerald_fall] = Cemerald;
232 cav.android_array[Yemerald_sB] = Cemerald;
233 cav.android_array[Yemerald_eB] = Cemerald;
234 cav.android_array[Yemerald_wB] = Cemerald;
239 cav.android_array[Xdiamond] = Cdiamond;
240 cav.android_array[Xdiamond_pause] = Cdiamond;
241 cav.android_array[Xdiamond_fall] = Cdiamond;
242 cav.android_array[Ydiamond_sB] = Cdiamond;
243 cav.android_array[Ydiamond_eB] = Cdiamond;
244 cav.android_array[Ydiamond_wB] = Cdiamond;
249 cav.android_array[Xstone] = Cstone;
250 cav.android_array[Xstone_pause] = Cstone;
251 cav.android_array[Xstone_fall] = Cstone;
252 cav.android_array[Ystone_sB] = Cstone;
253 cav.android_array[Ystone_eB] = Cstone;
254 cav.android_array[Ystone_wB] = Cstone;
259 cav.android_array[Xbomb] = Cbomb;
260 cav.android_array[Xbomb_pause] = Cbomb;
261 cav.android_array[Xbomb_fall] = Cbomb;
262 cav.android_array[Ybomb_sB] = Cbomb;
263 cav.android_array[Ybomb_eB] = Cbomb;
264 cav.android_array[Ybomb_wB] = Cbomb;
269 cav.android_array[Xnut] = Cnut;
270 cav.android_array[Xnut_pause] = Cnut;
271 cav.android_array[Xnut_fall] = Cnut;
272 cav.android_array[Ynut_sB] = Cnut;
273 cav.android_array[Ynut_eB] = Cnut;
274 cav.android_array[Ynut_wB] = Cnut;
279 cav.android_array[Xspring] = Cspring;
280 cav.android_array[Xspring_pause] = Cspring;
281 cav.android_array[Xspring_fall] = Cspring;
282 cav.android_array[Xspring_e] = Cspring;
283 cav.android_array[Xspring_w] = Cspring;
284 cav.android_array[Yspring_sB] = Cspring;
285 cav.android_array[Yspring_eB] = Cspring;
286 cav.android_array[Yspring_wB] = Cspring;
287 cav.android_array[Yspring_alien_eB] = Cspring;
288 cav.android_array[Yspring_alien_wB] = Cspring;
291 if (android_dynamite)
293 cav.android_array[Xdynamite] = Cdynamite;
298 cav.android_array[Xballoon] = Cballoon;
299 cav.android_array[Yballoon_nB] = Cballoon;
300 cav.android_array[Yballoon_eB] = Cballoon;
301 cav.android_array[Yballoon_sB] = Cballoon;
302 cav.android_array[Yballoon_wB] = Cballoon;
307 cav.android_array[Xfake_amoeba] = Cdrip;
308 cav.android_array[Yfake_amoeba] = Cdrip;
309 cav.android_array[Xamoeba_1] = Cdrip;
310 cav.android_array[Xamoeba_2] = Cdrip;
311 cav.android_array[Xamoeba_3] = Cdrip;
312 cav.android_array[Xamoeba_4] = Cdrip;
313 cav.android_array[Xamoeba_5] = Cdrip;
314 cav.android_array[Xamoeba_6] = Cdrip;
315 cav.android_array[Xamoeba_7] = Cdrip;
316 cav.android_array[Xamoeba_8] = Cdrip;
320 void convert_em_level(unsigned char *src, int file_version)
322 static int eater_offset[8] =
324 2048, 2057, 2066, 2075,
325 2112, 2121, 2130, 2139
329 /* common to all emc caves */
331 cav.time_seconds = MIN(GET_BE16(src[2110]), 9999);
332 cav.gems_needed = src[2095];
336 cav.emerald_score = src[2084];
337 cav.diamond_score = src[2085];
338 cav.alien_score = src[2086];
339 cav.tank_score = src[2087];
340 cav.bug_score = src[2088];
341 cav.eater_score = src[2089];
342 cav.nut_score = src[2090];
343 cav.dynamite_score = src[2091];
344 cav.key_score = src[2092];
345 cav.exit_score = src[2093] * 8 / 5;
347 cav.lenses_score = src[2151];
348 cav.magnify_score = src[2152];
349 cav.slurp_score = src[2153];
353 cav.android_move_time = MIN(GET_BE16(src[2164]), 9999);
354 cav.android_clone_time = MIN(GET_BE16(src[2166]), 9999);
355 cav.ball_time = MIN(GET_BE16(src[2160]), 9999);
357 cav.lenses_time = MIN(GET_BE16(src[2154]), 9999);
358 cav.magnify_time = MIN(GET_BE16(src[2156]), 9999);
359 cav.wheel_time = MIN(GET_BE16(src[2104]), 9999);
361 cav.amoeba_time = MIN(GET_BE16(src[2100]) * 28, 9999);
362 cav.wonderwall_time = MIN(GET_BE16(src[2102]), 9999);
364 cav.wind_cnt = src[2149] & 15 ? cav.wind_time : 0;
366 cav.wind_direction = (temp & 8 ? 0 :
373 cav.ball_random = src[2162] & 1 ? 1 : 0;
374 cav.ball_state = src[2162] & 128 ? 1 : 0;
376 for (temp = 1; temp < 2047; temp++)
380 case 36: /* wonderwall */
381 cav.wonderwall_state = 1;
382 cav.wonderwall_time = 9999;
386 cav.wheel_x = temp & 63;
387 cav.wheel_y = temp >> 6;
388 cav.wheel_cnt = cav.wheel_time;
391 case 163: /* fake blank */
392 cav.lenses_cnt = 9999;
395 case 164: /* fake grass */
396 cav.magnify_cnt = 9999;
403 init_android_clone_table(GET_BE16(src[2168]));
407 for (i = 0; i < 8; i++)
408 for (x = 0; x < 9; x++)
409 cav.eater_array[i][x] = map_emc[src[eater_offset[i] + x]];
413 temp = map_emc[src[2159]];
415 for (y = 0; y < 8; y++)
419 for (x = 0; x < 8; x++)
420 cav.ball_array[y][x] = temp;
424 cav.ball_array[y][1] = (src[2163] & 1) ? temp : Cblank; /* north */
425 cav.ball_array[y][6] = (src[2163] & 2) ? temp : Cblank; /* south */
426 cav.ball_array[y][3] = (src[2163] & 4) ? temp : Cblank; /* west */
427 cav.ball_array[y][4] = (src[2163] & 8) ? temp : Cblank; /* east */
428 cav.ball_array[y][7] = (src[2163] & 16) ? temp : Cblank; /* southeast */
429 cav.ball_array[y][5] = (src[2163] & 32) ? temp : Cblank; /* southwest */
430 cav.ball_array[y][2] = (src[2163] & 64) ? temp : Cblank; /* northeast */
431 cav.ball_array[y][0] = (src[2163] & 128)? temp : Cblank; /* northwest */
437 for (i = 0; i < 2; i++)
439 temp = GET_BE16(src[2096 + i * 2]);
441 cav.player_x[i] = (temp & 63);
442 cav.player_y[i] = (temp >> 6 & 31);
447 /* first fill the complete playfield with the empty space element */
448 for (y = 0; y < CAVE_HEIGHT; y++)
449 for (x = 0; x < CAVE_WIDTH; x++)
450 cav.cave[x][y] = Cblank;
452 /* then copy the real level contents from level file into the playfield */
454 for (y = 0; y < cav.height; y++)
455 for (x = 0; x < cav.width; x++)
456 cav.cave[x][y] = map_emc[src[temp++]];
458 native_em_level.file_version = file_version;
462 /* convert all emerald mine caves to emc version 6 cave format.
464 * caves are filtered to get rid of invalid or unsupported tiles.
466 * although the result is a somewhat clean cave, it is meant only
467 * to give a common structure for the binary cave format. it is not
468 * for archiving purposes (it is better to keep the raw cave as-is)
469 * and it is not meant for serializing (the intermediate structure
470 * is better defined).
472 * acid top is added to acid bottom in both the cave and the eaters.
473 * fake acid (only in v4) does not exist because it adds nothing to
474 * the game, and is different even in different versions of the emc
477 * v4/v5 time is converted to 10x old time (as it should be).
478 * the reason the kingsoft player used 5x time was copy protection.
480 * note: emc v6 converter has an error in converting v4 eaters to the
481 * wrong bug(24 instead of 20) and tank(12 instead of 8).
484 /* changes for game engine integration in Rocks'n'Diamonds:
486 * cave versions below V5 had no grass, but only sand/dirt
487 * - object code 130 (V6 grass) is changed to 189 (V6 dirt)
488 * - object codes are changed in both cave and eater arrays
489 * - only graphical change, as both objects behave the same
492 static const unsigned char map_v6[256] =
496 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
497 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
498 0,16,2,18, 36,37,37,37, 40,41,42,43, 44,45,128,128,
499 128,148,148, 148,45,45,45, 148,0,57,58, 59,60,61,62,63,
501 64,65,66,67, 68,69,69,71, 72,73,74,75, 118,75,75,75,
502 75,75,75,75, 75,153,153,153, 153,153,153,153, 153,153,153,153,
503 153,153,153,99, 100,68,68,68, 68,68,68,68, 68,118,118,118,
504 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
506 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
507 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
508 160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
509 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
511 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
512 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
513 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
514 240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
517 static const unsigned char map_v5[256] =
521 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
522 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
523 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
524 128,148,148,148, 45,45,45,148, 0,57,58,59, 60,61,62,63,
526 64,65,66,67, 68,153,153,153, 153,153,153,153, 153,153,153,153,
527 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
528 153,153,153,153, 153,68,68,68, 68,68,68,68, 68,118,118,118,
529 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
531 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
532 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
533 160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
534 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
536 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
537 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
538 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
539 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
542 static const unsigned char map_v4[256] =
546 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
547 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
548 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
549 128,148,148,148, 45,45,45,148, 0,153,153,59, 60,61,62,63,
551 64,65,66,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
552 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
553 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
554 153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
556 128,129,189,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
557 144,145,146,147, 148,149,150,151, 152,68,154,155, 156,157,158,160,
558 160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
559 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
561 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
562 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
563 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
564 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
567 static const unsigned char map_v4_eater[32] =
569 /* filter for v4 eater */
571 128,18,2,0, 4,8,16,20, 28,37,41,45, 189,129,131,132,
572 133,134,135,136, 146,147,175,65, 66,64,2,18, 128,128,128,128
575 static boolean filename_has_v1_format(char *filename)
577 char *basename = getBaseNamePtr(filename);
579 return (strlen(basename) == 3 &&
580 basename[0] == 'a' &&
581 basename[1] >= 'a' && basename[1] <= 'k' &&
582 basename[2] >= '0' && basename[2] <= '9');
585 int cleanup_em_level(unsigned char *src, int length, char *filename)
587 int file_version = FILE_VERSION_EM_UNKNOWN;
590 if (length >= 2172 &&
591 src[2106] == 255 && /* version id: */
592 src[2107] == 54 && /* '6' */
593 src[2108] == 48 && /* '0' */
594 src[2109] == 48) /* '0' */
596 /* ---------- this cave has V6 file format ---------- */
597 file_version = FILE_VERSION_EM_V6;
599 /* remap elements to internal EMC level format */
600 for (i = 0; i < 2048; i++)
601 src[i] = map_v6[src[i]];
602 for (i = 2048; i < 2084; i++)
603 src[i] = map_v6[src[i]];
604 for (i = 2112; i < 2148; i++)
605 src[i] = map_v6[src[i]];
607 else if (length >= 2110 &&
608 src[2106] == 255 && /* version id: */
609 src[2107] == 53 && /* '5' */
610 src[2108] == 48 && /* '0' */
611 src[2109] == 48) /* '0' */
613 /* ---------- this cave has V5 file format ---------- */
614 file_version = FILE_VERSION_EM_V5;
616 /* remap elements to internal EMC level format */
617 for (i = 0; i < 2048; i++)
618 src[i] = map_v5[src[i]];
619 for (i = 2048; i < 2084; i++)
620 src[i] = map_v5[src[i]];
621 for (i = 2112; i < 2148; i++)
622 src[i] = src[i - 64];
624 else if (length >= 2106 &&
625 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
626 src[1983] == 116 || /* unencrypted (usual case) */
627 src[1983] == 131)) /* unencrypted (rare case) */
629 /* ---------- this cave has V1, V2 or V3 file format ---------- */
631 boolean fix_copyright = FALSE;
634 byte at position 1983 (0x07bf) is used as "magic byte":
635 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
636 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
637 - 131 (0x83) => unencrypted level (happens only in very rare cases)
640 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
642 /* this is original (encrypted) Emerald Mine I, II or III level file */
644 int first_byte = src[0];
645 unsigned char code0 = 0x65;
646 unsigned char code1 = 0x11;
648 /* decode encrypted level data */
649 for (i = 0; i < 2106; i++)
654 code0 = (code0 + 7) & 0xff;
657 src[1] = 131; /* needed for all Emerald Mine levels */
659 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
660 if (first_byte == 0xf5)
662 src[0] = 131; /* only needed for Emerald Mine II levels */
664 fix_copyright = TRUE;
667 /* ---------- this cave has V3 file format ---------- */
668 file_version = FILE_VERSION_EM_V3;
670 else if (filename_has_v1_format(filename))
672 /* ---------- this cave has V1 file format ---------- */
673 file_version = FILE_VERSION_EM_V1;
677 /* ---------- this cave has V2 file format ---------- */
678 file_version = FILE_VERSION_EM_V2;
681 /* remap elements to internal EMC level format */
682 for (i = 0; i < 2048; i++)
683 src[i] = map_v4[src[i]];
684 for (i = 2048; i < 2084; i++)
685 src[i] = map_v4_eater[src[i] >= 28 ? 0 : src[i]];
686 for (i = 2112; i < 2148; i++)
687 src[i] = src[i - 64];
689 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
691 for (i = 0; i < 2048; i++)
693 src[i] = 254; /* replace 'Cdecor_1' with 'Calpha_copyr' */
698 /* ---------- this cave has unknown file format ---------- */
700 /* if file has length of old-style level file, print (wrong) magic byte */
702 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
705 return FILE_VERSION_EM_UNKNOWN;
708 if (file_version < FILE_VERSION_EM_V6)
711 src[2106] = 255; /* version id: */
712 src[2107] = 54; /* '6' */
713 src[2108] = 48; /* '0' */
714 src[2109] = 48; /* '0' */
718 /* stored level time of levels for the V2 player was changed to 50% of the
719 time for the V1 player (original V3 levels already considered this) */
720 if (file_version != FILE_VERSION_EM_V1 &&
721 file_version != FILE_VERSION_EM_V3)
726 for (i = 2148; i < 2172; i++)
733 /* ---------- at this stage, the cave data always has V6 format ---------- */
736 for (i = 0; i < 2048; i++)
739 for (i++; i < 2048; i++)
744 for (i = 64; i < 2048; i++)
745 if (src[i] == 63) /* replace element above 'Cacid_s' ... */
746 src[i - 64] = 101; /* ... with 'Cacid_1' */
748 /* fix acid with no base beneath it (see below for details (*)) */
749 for (i = 64; i < 2048 - 1; i++)
751 if (file_version <= FILE_VERSION_EM_V2 &&
752 src[i - 64] == 101 && src[i] != 63) /* acid without base */
754 if (src[i - 1] == 101 || /* remove acid over acid row */
756 src[i - 64] = 6; /* replace element above with 'Cblank' */
758 src[i - 64] = 255; /* replace element above with 'Cfake_acid_1' */
762 /* fix acid in eater 1 */
763 for (i = 2051; i < 2057; i++)
767 /* fix acid in eater 2 */
768 for (i = 2060; i < 2066; i++)
772 /* fix acid in eater 3 */
773 for (i = 2069; i < 2075; i++)
777 /* fix acid in eater 4 */
778 for (i = 2078; i < 2084; i++)
782 /* fix acid in eater 5 */
783 for (i = 2115; i < 2121; i++)
787 /* fix acid in eater 6 */
788 for (i = 2124; i < 2130; i++)
792 /* fix acid in eater 7 */
793 for (i = 2133; i < 2139; i++)
797 /* fix acid in eater 8 */
798 for (i = 2142; i < 2148; i++)
807 src[GET_BE16(src[2096])] = 128;
811 src[GET_BE16(src[2098])] = 128;
821 src[2159] = map_v6[src[2159]];
831 /* size of v6 cave */
835 Error(ERR_DEBUG, "EM level file version: %d", file_version);
844 structure of emerald mine level disk files
845 ----------------------------------------------------------------------
847 if(len >= 2172 && (buf[2106] == 255 && buf[2107] == 54 && buf[2108] == 48 && buf[2109] == 48)) // v6
848 if(len >= 2110 && (buf[2106] == 255 && buf[2107] == 53 && buf[2108] == 48 && buf[2109] == 48)) // v5
849 if(len >= 2106 && (buf[1983] == 116 || buf[2047] == 116)) // v4
850 if(len >= 2106 && (buf[1983] == 27 || buf[2047] == 219)) // v3
852 buf[0]=241;buf[1]=248;for(i=0,j=101;i<2106;i++,j+=7)buf[i]=(buf[i]^j)-17; // decrypt
854 number of movements (calls to logic) = time * 50 / 8
856 {} reserved (but some broken levels use them)
858 ----------------------------------------------------------------------
878 2095: emeralds needed
882 2102: wonderwall time
884 2106: ID (0xff363030)
890 2148: flags bit#7=NOI #6=RIS
891 2149: wind direction bit#0=right #1=down #2=left #3=up
892 2150: cave number bit#7=teamwork
901 2162: ball info bit#15=switch state #8=random
902 ; bit#0=N #1=S #2=W #3=E #4=SE #5=SW #6=NE #7=NW
903 2164: android move speed
904 2166: android clone speed
906 ; bit#0=emerald #1=diamond #2=stone #3=bomb #4=nut #5=tank #6=eater
907 ; #7=bug #8=alien #9=spring #10=balloon #11=ameuba #12=dynamite
912 1: stone {stone_fall}
914 3: diamond {diamond_fall}
916 5: alien {alien_pause}
930 19: emerald {emerald_fall}
941 30: blank {drip_stretchB}
942 31: drip {drip_stretch}
943 32: stone {stone_pause}
944 33: bomb {bomb_pause}
945 34: diamond {diamond_pause}
946 35: emerald {emerald_pause}
947 36: wonderwall {wonderwallB}
957 46: blank {sand_stonein_2}
958 47: blank {sand_stonein_3}
959 48: blank {sand_stonein_4}
960 49: sand {sand_stonesand_2}
961 50: sand {sand_stonesand_3}
962 51: sand {sand_stonesand_4}
963 52: sand_stone {sand_sandstone_2}
964 53: sand_stone {sand_sandstone_3}
965 54: sand_stone {sand_sandstone_4}
966 55: sand {sand_stonesand_4}
967 56: stone {sand_stoneout_2}
981 70: spring {spring_fall}
982 71: spring {spring_w}
983 72: spring {spring_e}
988 77: android {android_n_1}
989 78: android {android_n_2}
990 79: android {android_s_1}
991 80: android {android_s_2}
992 81: android {android_e_1}
993 82: android {android_e_2}
994 83: android {android_w_1}
995 84: android {android_w_2}
1010 99: spring {push_spring_w}
1011 100: spring {push_spring_e}
1020 109: pause {grass_wB}
1021 110: pause {grass_eB}
1022 111: pause {grass_nB}
1023 112: pause {grass_sB}
1024 113: pause {dynamite_blank}
1025 114: nut {push_nut_w}
1026 115: nut {push_nut_e}
1027 116: steel_2 {end of level}
1029 118: pause {emerald_blank}
1030 119: bomb {push_bomb_w}
1031 120: bomb {push_bomb_e}
1032 121: stone {push_stone_w}
1033 122: stone {push_stone_e}
1034 123: pause {diamond_blank}
1035 124: pause {dirt_wB}
1036 125: pause {dirt_eB}
1037 126: pause {dirt_nB}
1038 127: pause {dirt_sB}
1075 163: fake_blank {fake_blankB}
1076 164: fake_grass {fake_grassB}
1078 166: switch {switchB}
1169 ----------------------------------------------------------------------
1185 2091: dynamite value
1189 2095: emeralds needed
1193 2102: wonderwall time
1195 2106: ID (0xff353030)
1199 1: stone {stone_fall}
1201 3: diamond {diamond_fall}
1203 5: alien {alien_pause}
1215 17: bomb {bomb_fall}
1217 19: emerald {emerald_fall}
1227 29: drip {drip_fall}
1228 30: blank {drip_stretchB}
1229 31: drip {drip_stretch}
1230 32: stone {stone_pause}
1231 33: bomb {bomb_pause}
1232 34: diamond {diamond_pause}
1233 35: emerald {emerald_pause}
1234 36: wonderwall {wonderwallB}
1244 46: blank {sand_stonein_2}
1245 47: blank {sand_stonein_3}
1246 48: blank {sand_stonein_4}
1247 49: sand {sand_stonesand_2}
1248 50: sand {sand_stonesand_3}
1249 51: sand {sand_stonesand_4}
1250 52: sand_stone {sand_sandstone_2}
1251 53: sand_stone {sand_sandstone_3}
1252 54: sand_stone {sand_sandstone_4}
1253 55: sand {sand_stonesand_4}
1254 56: stone {sand_stoneout_2}
1307 109: pause {grass_wB}
1308 110: pause {grass_eB}
1309 111: pause {grass_nB}
1310 112: pause {grass_sB}
1311 113: pause {dynamite_blank}
1312 114: nut {push_nut_w}
1313 115: nut {push_nut_e}
1314 116: steel_2 {end of level}
1315 117: dynamite_4 {boom_2}
1316 118: pause {emerald_blank}
1317 119: bomb {push_bomb_w}
1318 120: bomb {push_bomb_e}
1319 121: stone {push_stone_w}
1320 122: stone {push_stone_e}
1321 123: pause {diamond_blank}
1322 124: pause {dirt_wB}
1323 125: pause {dirt_eB}
1324 126: pause {dirt_nB}
1325 127: pause {dirt_sB}
1456 ----------------------------------------------------------------------
1472 2091: dynamite value
1476 2095: emeralds needed
1480 2102: wonderwall time
1510 26: diamond {diamond_shine}
1511 27: emerald {emerald_shine}
1514 1: stone {stone_fall}
1516 3: diamond {diamond_fall}
1518 5: alien {alien_pause}
1530 17: bomb {bomb_fall}
1532 19: emerald {emerald_fall}
1542 29: drip {drip_fall}
1543 30: blank {drip_stretchB}
1544 31: drip {drip_stretch}
1545 32: stone {stone_pause}
1546 33: bomb {bomb_pause}
1547 34: diamond {diamond_pause}
1548 35: emerald {emerald_pause}
1549 36: wonderwall {wonderwallB}
1559 46: blank {sand_stonein_2}
1560 47: blank {sand_stonein_3}
1561 48: blank {sand_stonein_4}
1562 49: sand {sand_stonesand_2}
1563 50: sand {sand_stonesand_3}
1564 51: sand {sand_stonesand_4}
1565 52: sand_stone {sand_sandstone_2}
1566 53: sand_stone {sand_sandstone_3}
1567 54: sand_stone {sand_sandstone_4}
1568 55: sand {sand_stonesand_4}
1569 56: stone {sand_stoneout_2}
1626 113: pause {dynamite_blank}
1627 114: nut {push_nut_w}
1628 115: nut {push_nut_e}
1629 116: steel_1 {end of level}
1630 117: dynamite_4 {boom_2}
1631 118: pause {emerald_blank}
1632 119: bomb {push_bomb_w}
1633 120: bomb {push_bomb_e}
1634 121: stone {push_stone_w}
1635 122: stone {push_stone_e}
1636 123: pause {diamond_blank}
1637 124: pause {dirt_wB}
1638 125: pause {dirt_eB}
1639 126: pause {dirt_nB}
1640 127: pause {dirt_sB}
1673 159: fake_grass {dirt}
1674 160: fake_grass {dirt}
1675 161: fake_grass {dirt}
1676 162: fake_grass {dirt}
1677 163: fake_grass {dirt}
1678 164: fake_grass {dirt}
1679 165: fake_grass {dirt}
1680 166: fake_grass {dirt}
1681 167: fake_grass {dirt}
1682 168: fake_grass {dirt}
1683 169: fake_grass {dirt}
1684 170: fake_grass {dirt}
1685 171: fake_grass {dirt}
1686 172: fake_grass {dirt}
1687 173: fake_grass {dirt}
1688 174: fake_grass {dirt}
1754 240: alpha_arrow_e {}
1755 241: decor_1 {alpha_copyr}
1771 ----------------------------------------------------------------------