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])
44 #define PUT_BE16(x, y) {(&x)[0] = (y) >> 8; (&x)[1] = (y) & 0xff;}
46 static const short map_emc[256] =
48 Xstone, Xstone, Xdiamond, Xdiamond,
49 Xalien, Xalien, Xblank, Xblank,
50 Xtank_1_n, Xtank_1_e, Xtank_1_s, Xtank_1_w,
51 Xtank_2_n, Xtank_2_e, Xtank_2_s, Xtank_2_w,
53 Xbomb, Xbomb, Xemerald, Xemerald,
54 Xbug_1_n, Xbug_1_e, Xbug_1_s, Xbug_1_w,
55 Xbug_2_n, Xbug_2_e, Xbug_2_s, Xbug_2_w,
56 Xdrip, Xdrip, Xdrip, Xdrip,
58 Xstone, Xbomb, Xdiamond, Xemerald,
59 Xwonderwall, Xnut, Xnut, Xnut,
60 Xwheel, Xeater_n, Xeater_s, Xeater_w,
61 Xeater_e, Xsand_stone, Xblank, Xblank,
63 Xblank, Xsand, Xsand, Xsand,
64 Xsand_stone, Xsand_stone, Xsand_stone, Xsand,
65 Xstone, Xslide_ew, Xslide_ns, Xdynamite_1,
66 Xdynamite_2, Xdynamite_3, Xdynamite_4, Xacid_s,
68 Xexit_1, Xexit_2, Xexit_3, Xballoon,
69 Xplant, Xspring, Xspring_fall, Xspring_w,
70 Xspring_e, Xball_1, Xball_2, Xandroid,
71 Xblank, Xandroid, Xandroid, Xandroid,
73 Xandroid, Xandroid, Xandroid, Xandroid,
74 Xandroid, Xblank, Xblank, Xblank,
75 Xblank, Xblank, Xblank, Xblank,
76 Xblank, Xblank, Xblank, Xblank,
78 Xblank, Xblank, Xblank, Xpush_spring_w,
79 Xpush_spring_e, Xacid_1, Xacid_2, Xacid_3,
80 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
81 Xacid_8, Xblank, Xblank, Xblank,
83 Xblank, Xblank, Xpush_nut_w, Xpush_nut_e,
84 Xsteel_1, Xblank, Xblank, Xpush_bomb_w,
85 Xpush_bomb_e, Xpush_stone_w, Xpush_stone_e, Xblank,
86 Xblank, Xblank, Xblank, Xblank,
88 Xblank, Xroundwall_1, Xgrass, Xsteel_1,
89 Xwall_1, Xkey_1, Xkey_2, Xkey_3,
90 Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3,
91 Xdoor_4, Xfake_amoeba, Xfake_door_1, Xfake_door_2,
93 Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel,
94 Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
95 Xacid_se, Xfake_blank, Xamoeba_1, Xamoeba_2,
96 Xamoeba_3, Xamoeba_4, Xexit, Xalpha_arrow_w,
98 Xfake_grass, Xlenses, Xmagnify, Xfake_blank,
99 Xfake_grass, Xswitch, Xswitch, Xblank,
100 Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5,
101 Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
103 Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2,
104 Xroundwall_2, Xdecor_2, Xdecor_4, Xdecor_3,
105 Xwind_any, Xwind_e, Xwind_s, Xwind_w,
106 Xwind_n, Xdirt, Xplant, Xkey_5,
108 Xkey_6, Xkey_7, Xkey_8, Xdoor_5,
109 Xdoor_6, Xdoor_7, Xdoor_8, Xbumper,
110 Xalpha_a, Xalpha_b, Xalpha_c, Xalpha_d,
111 Xalpha_e, Xalpha_f, Xalpha_g, Xalpha_h,
113 Xalpha_i, Xalpha_j, Xalpha_k, Xalpha_l,
114 Xalpha_m, Xalpha_n, Xalpha_o, Xalpha_p,
115 Xalpha_q, Xalpha_r, Xalpha_s, Xalpha_t,
116 Xalpha_u, Xalpha_v, Xalpha_w, Xalpha_x,
118 Xalpha_y, Xalpha_z, Xalpha_0, Xalpha_1,
119 Xalpha_2, Xalpha_3, Xalpha_4, Xalpha_5,
120 Xalpha_6, Xalpha_7, Xalpha_8, Xalpha_9,
121 Xalpha_perio, Xalpha_excla, Xalpha_colon, Xalpha_quest,
123 Xalpha_arrow_e, Xdecor_1, Xfake_door_5, Xfake_door_6,
124 Xfake_door_7, Xfake_door_8, Xblank, Xblank,
125 Xblank, Xblank, Xblank, Xblank,
126 Xblank, Xblank, Xalpha_copyr, Xfake_acid_1
129 static int get_em_element(unsigned short em_element_raw, int file_version)
131 int em_element = map_emc[em_element_raw];
133 if (file_version < FILE_VERSION_EM_V5)
135 /* versions below V5 had no grass, but only sand/dirt */
136 if (em_element == Xgrass)
143 void convert_em_level(unsigned char *src, int file_version)
145 static int eater_offset[8] =
147 2048, 2057, 2066, 2075,
148 2112, 2121, 2130, 2139
152 /* common to all emc caves */
154 lev.time_seconds = GET_BE16(src[2110]);
155 if (lev.time_seconds > 9999)
156 lev.time_seconds = 9999;
158 lev.required_initial = src[2095];
162 lev.emerald_score = src[2084];
163 lev.diamond_score = src[2085];
164 lev.alien_score = src[2086];
165 lev.tank_score = src[2087];
166 lev.bug_score = src[2088];
167 lev.eater_score = src[2089];
168 lev.nut_score = src[2090];
169 lev.dynamite_score = src[2091];
170 lev.key_score = src[2092];
171 lev.exit_score = src[2093] * 8 / 5;
173 lev.lenses_score = src[2151];
174 lev.magnify_score = src[2152];
175 lev.slurp_score = src[2153];
179 lev.android_move_time = GET_BE16(src[2164]);
180 lev.android_clone_time = GET_BE16(src[2166]);
181 lev.ball_time = GET_BE16(src[2160]);
183 lev.lenses_time = GET_BE16(src[2154]);
184 lev.magnify_time = GET_BE16(src[2156]);
185 lev.wheel_time = GET_BE16(src[2104]);
187 temp = GET_BE16(src[2100]) * 28;
190 lev.amoeba_time = temp;
192 lev.wonderwall_time_initial = GET_BE16(src[2102]);
194 lev.wind_cnt_initial = src[2149] & 15 ? lev.wind_time : 0;
196 lev.wind_direction_initial = (temp & 8 ? 0 :
202 lev.ball_random = src[2162] & 1 ? 1 : 0;
203 lev.ball_state_initial = src[2162] & 128 ? 1 : 0;
205 for (temp = 1; temp < 2047; temp++)
209 case 36: /* wonderwall */
210 lev.wonderwall_state_initial = 1;
211 lev.wonderwall_time_initial = 9999;
215 lev.wheel_x_initial = temp & 63;
216 lev.wheel_y_initial = temp >> 6;
217 lev.wheel_cnt_initial = lev.wheel_time;
220 case 163: /* fake blank */
221 lev.lenses_cnt_initial = 9999;
224 case 164: /* fake grass */
225 lev.magnify_cnt_initial = 9999;
232 temp = GET_BE16(src[2168]);
234 lev.android_emerald = (temp & 1) != 0;
235 lev.android_diamond = (temp & 2) != 0;
236 lev.android_stone = (temp & 4) != 0;
237 lev.android_bomb = (temp & 8) != 0;
238 lev.android_nut = (temp & 16) != 0;
239 lev.android_tank = (temp & 32) != 0;
240 lev.android_eater = (temp & 64) != 0;
241 lev.android_bug = (temp & 128) != 0;
242 lev.android_alien = (temp & 256) != 0;
243 lev.android_spring = (temp & 512) != 0;
244 lev.android_balloon = (temp & 1024) != 0;
245 lev.android_amoeba = (temp & 2048) != 0;
246 lev.android_dynamite = (temp & 4096) != 0;
250 for (i = 0; i < 8; i++)
251 for (x = 0; x < 9; x++)
252 lev.eater_array[i][x] =
253 get_em_element(src[eater_offset[i] + x], file_version);
257 temp = get_em_element(src[2159], file_version);
259 for (y = 0; y < 8; y++)
263 for (x = 0; x < 8; x++)
264 lev.ball_array[y][x] = temp;
268 lev.ball_array[y][1] = (src[2163] & 1) ? temp : Xblank; /* north */
269 lev.ball_array[y][6] = (src[2163] & 2) ? temp : Xblank; /* south */
270 lev.ball_array[y][3] = (src[2163] & 4) ? temp : Xblank; /* west */
271 lev.ball_array[y][4] = (src[2163] & 8) ? temp : Xblank; /* east */
272 lev.ball_array[y][7] = (src[2163] & 16) ? temp : Xblank; /* southeast */
273 lev.ball_array[y][5] = (src[2163] & 32) ? temp : Xblank; /* southwest */
274 lev.ball_array[y][2] = (src[2163] & 64) ? temp : Xblank; /* northeast */
275 lev.ball_array[y][0] = (src[2163] & 128)? temp : Xblank; /* northwest */
281 for (i = 0; i < 2; i++)
283 temp = GET_BE16(src[2096 + i * 2]);
285 ply[i].x_initial = (temp & 63);
286 ply[i].y_initial = (temp >> 6 & 31);
291 /* first fill the complete playfield with the default border element */
292 for (y = 0; y < CAVE_HEIGHT; y++)
293 for (x = 0; x < CAVE_WIDTH; x++)
294 native_em_level.cave[x][y] = Zborder;
296 /* then copy the real level contents from level file into the playfield */
298 for (y = 0; y < lev.height; y++)
299 for (x = 0; x < lev.width; x++)
300 native_em_level.cave[x][y] =
301 get_em_element(src[temp++], file_version);
303 /* at last, set the two players at their positions in the playfield */
304 /* (native EM[C] levels always have exactly two players in a level) */
305 for (i = 0; i < 2; i++)
306 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
308 native_em_level.file_version = file_version;
312 /* convert all emerald mine caves to emc version 6 cave format.
314 * caves are filtered to get rid of invalid or unsupported tiles.
316 * although the result is a somewhat clean cave, it is meant only
317 * to give a common structure for the binary cave format. it is not
318 * for archiving purposes (it is better to keep the raw cave as-is)
319 * and it is not meant for serializing (the intermediate structure
320 * is better defined).
322 * acid top is added to acid bottom in both the cave and the eaters.
323 * fake acid (only in v4) does not exist because it adds nothing to
324 * the game, and is different even in different versions of the emc
327 * v4/v5 time is converted to 10x old time (as it should be).
328 * the reason the kingsoft player used 5x time was copy protection.
330 * note: emc v6 converter has an error in converting v4 eaters to the
331 * wrong bug(24 instead of 20) and tank(12 instead of 8).
334 static const unsigned char map_v6[256] =
338 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
339 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
340 0,16,2,18, 36,37,37,37, 40,41,42,43, 44,45,128,128,
341 128,148,148, 148,45,45,45, 148,0,57,58, 59,60,61,62,63,
343 64,65,66,67, 68,69,69,71, 72,73,74,75, 118,75,75,75,
344 75,75,75,75, 75,153,153,153, 153,153,153,153, 153,153,153,153,
345 153,153,153,99, 100,68,68,68, 68,68,68,68, 68,118,118,118,
346 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
348 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
349 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
350 160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
351 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
353 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
354 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
355 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
356 240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
359 static const unsigned char map_v5[256] =
363 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
364 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
365 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
366 128,148,148,148, 45,45,45,148, 0,57,58,59, 60,61,62,63,
368 64,65,66,67, 68,153,153,153, 153,153,153,153, 153,153,153,153,
369 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
370 153,153,153,153, 153,68,68,68, 68,68,68,68, 68,118,118,118,
371 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
373 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
374 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
375 160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
376 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
378 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
379 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
380 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
381 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
384 static const unsigned char map_v4[256] =
388 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
389 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
390 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
391 128,148,148,148, 45,45,45,148, 0,153,153,59, 60,61,62,63,
393 64,65,66,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
394 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
395 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
396 153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
398 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
399 144,145,146,147, 148,149,150,151, 152,68,154,155, 156,157,158,160,
400 160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
401 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
403 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
404 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
405 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
406 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
409 static const unsigned char map_v4_eater[32] =
411 /* filter for v4 eater */
413 128,18,2,0, 4,8,16,20, 28,37,41,45, 130,129,131,132,
414 133,134,135,136, 146,147,175,65, 66,64,2,18, 128,128,128,128
417 static boolean filename_has_v1_format(char *filename)
419 char *basename = getBaseNamePtr(filename);
421 return (strlen(basename) == 3 &&
422 basename[0] == 'a' &&
423 basename[1] >= 'a' && basename[1] <= 'k' &&
424 basename[2] >= '0' && basename[2] <= '9');
427 int cleanup_em_level(unsigned char *src, int length, char *filename)
429 int file_version = FILE_VERSION_EM_UNKNOWN;
432 if (length >= 2172 &&
433 src[2106] == 255 && /* version id: */
434 src[2107] == 54 && /* '6' */
435 src[2108] == 48 && /* '0' */
436 src[2109] == 48) /* '0' */
438 /* ---------- this cave has V6 file format ---------- */
439 file_version = FILE_VERSION_EM_V6;
441 /* remap elements to internal EMC level format */
442 for (i = 0; i < 2048; i++)
443 src[i] = map_v6[src[i]];
444 for (i = 2048; i < 2084; i++)
445 src[i] = map_v6[src[i]];
446 for (i = 2112; i < 2148; i++)
447 src[i] = map_v6[src[i]];
449 else if (length >= 2110 &&
450 src[2106] == 255 && /* version id: */
451 src[2107] == 53 && /* '5' */
452 src[2108] == 48 && /* '0' */
453 src[2109] == 48) /* '0' */
455 /* ---------- this cave has V5 file format ---------- */
456 file_version = FILE_VERSION_EM_V5;
458 /* remap elements to internal EMC level format */
459 for (i = 0; i < 2048; i++)
460 src[i] = map_v5[src[i]];
461 for (i = 2048; i < 2084; i++)
462 src[i] = map_v5[src[i]];
463 for (i = 2112; i < 2148; i++)
464 src[i] = src[i - 64];
466 else if (length >= 2106 &&
467 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
468 src[1983] == 116 || /* unencrypted (usual case) */
469 src[1983] == 131)) /* unencrypted (rare case) */
471 /* ---------- this cave has V1, V2 or V3 file format ---------- */
473 boolean fix_copyright = FALSE;
476 byte at position 1983 (0x07bf) is used as "magic byte":
477 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
478 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
479 - 131 (0x83) => unencrypted level (happens only in very rare cases)
482 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
484 /* this is original (encrypted) Emerald Mine I, II or III level file */
486 int first_byte = src[0];
487 unsigned char code0 = 0x65;
488 unsigned char code1 = 0x11;
490 /* decode encrypted level data */
491 for (i = 0; i < 2106; i++)
496 code0 = (code0 + 7) & 0xff;
499 src[1] = 131; /* needed for all Emerald Mine levels */
501 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
502 if (first_byte == 0xf5)
504 src[0] = 131; /* only needed for Emerald Mine II levels */
506 fix_copyright = TRUE;
509 /* ---------- this cave has V3 file format ---------- */
510 file_version = FILE_VERSION_EM_V3;
512 else if (filename_has_v1_format(filename))
514 /* ---------- this cave has V1 file format ---------- */
515 file_version = FILE_VERSION_EM_V1;
519 /* ---------- this cave has V2 file format ---------- */
520 file_version = FILE_VERSION_EM_V2;
523 /* remap elements to internal EMC level format */
524 for (i = 0; i < 2048; i++)
525 src[i] = map_v4[src[i]];
526 for (i = 2048; i < 2084; i++)
527 src[i] = map_v4_eater[src[i] >= 28 ? 0 : src[i]];
528 for (i = 2112; i < 2148; i++)
529 src[i] = src[i - 64];
531 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
533 for (i = 0; i < 2048; i++)
535 src[i] = 254; /* replace 'Xdecor_1' with 'Xalpha_copyr' */
540 /* ---------- this cave has unknown file format ---------- */
542 /* if file has length of old-style level file, print (wrong) magic byte */
544 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
547 return FILE_VERSION_EM_UNKNOWN;
550 if (file_version < FILE_VERSION_EM_V6)
553 src[2106] = 255; /* version id: */
554 src[2107] = 54; /* '6' */
555 src[2108] = 48; /* '0' */
556 src[2109] = 48; /* '0' */
560 /* stored level time of levels for the V2 player was changed to 50% of the
561 time for the V1 player (original V3 levels already considered this) */
562 if (file_version != FILE_VERSION_EM_V1 &&
563 file_version != FILE_VERSION_EM_V3)
568 for (i = 2148; i < 2172; i++)
575 /* ---------- at this stage, the cave data always has V6 format ---------- */
578 for (i = 0; i < 2048; i++)
581 for (i++; i < 2048; i++)
586 for (i = 64; i < 2048; i++)
587 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
588 src[i - 64] = 101; /* ... with 'Xacid_1' */
590 /* fix acid with no base beneath it (see below for details (*)) */
591 for (i = 64; i < 2048 - 1; i++)
593 if (file_version <= FILE_VERSION_EM_V2 &&
594 src[i - 64] == 101 && src[i] != 63) /* acid without base */
596 if (src[i - 1] == 101 || /* remove acid over acid row */
598 src[i - 64] = 6; /* replace element above with 'Xblank' */
600 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
604 /* fix acid in eater 1 */
605 for (i = 2051; i < 2057; i++)
609 /* fix acid in eater 2 */
610 for (i = 2060; i < 2066; i++)
614 /* fix acid in eater 3 */
615 for (i = 2069; i < 2075; i++)
619 /* fix acid in eater 4 */
620 for (i = 2078; i < 2084; i++)
624 /* fix acid in eater 5 */
625 for (i = 2115; i < 2121; i++)
629 /* fix acid in eater 6 */
630 for (i = 2124; i < 2130; i++)
634 /* fix acid in eater 7 */
635 for (i = 2133; i < 2139; i++)
639 /* fix acid in eater 8 */
640 for (i = 2142; i < 2148; i++)
649 src[GET_BE16(src[2096])] = 128;
653 src[GET_BE16(src[2098])] = 128;
656 if (GET_BE16(src[2100]) > 9999)
657 PUT_BE16(src[2100], 9999);
659 /* time wonderwall */
660 if (GET_BE16(src[2102]) > 9999)
661 PUT_BE16(src[2102], 9999);
664 if (GET_BE16(src[2110]) > 9999)
665 PUT_BE16(src[2110], 9999);
674 if (GET_BE16(src[2154]) > 9999)
675 PUT_BE16(src[2154], 9999);
678 if (GET_BE16(src[2156]) > 9999)
679 PUT_BE16(src[2156], 9999);
683 src[2159] = map_v6[src[2159]];
686 if (GET_BE16(src[2160]) > 9999)
687 PUT_BE16(src[2160], 9999);
694 /* android move pause */
695 if (GET_BE16(src[2164]) > 9999)
696 PUT_BE16(src[2164], 9999);
698 /* android clone pause */
699 if (GET_BE16(src[2166]) > 9999)
700 PUT_BE16(src[2166], 9999);
705 /* size of v6 cave */
709 Error(ERR_DEBUG, "EM level file version: %d", file_version);
718 structure of emerald mine level disk files
719 ----------------------------------------------------------------------
721 if(len >= 2172 && (buf[2106] == 255 && buf[2107] == 54 && buf[2108] == 48 && buf[2109] == 48)) // v6
722 if(len >= 2110 && (buf[2106] == 255 && buf[2107] == 53 && buf[2108] == 48 && buf[2109] == 48)) // v5
723 if(len >= 2106 && (buf[1983] == 116 || buf[2047] == 116)) // v4
724 if(len >= 2106 && (buf[1983] == 27 || buf[2047] == 219)) // v3
726 buf[0]=241;buf[1]=248;for(i=0,j=101;i<2106;i++,j+=7)buf[i]=(buf[i]^j)-17; // decrypt
728 number of movements (calls to logic) = time * 50 / 8
730 {} reserved (but some broken levels use them)
732 ----------------------------------------------------------------------
752 2095: emeralds needed
756 2102: wonderwall time
758 2106: ID (0xff363030)
764 2148: flags bit#7=NOI #6=RIS
765 2149: wind direction bit#0=right #1=down #2=left #3=up
766 2150: cave number bit#7=teamwork
775 2162: ball info bit#15=switch state #8=random
776 ; bit#0=N #1=S #2=W #3=E #4=SE #5=SW #6=NE #7=NW
777 2164: android move speed
778 2166: android clone speed
780 ; bit#0=emerald #1=diamond #2=stone #3=bomb #4=nut #5=tank #6=eater
781 ; #7=bug #8=alien #9=spring #10=balloon #11=ameuba #12=dynamite
786 1: stone {stone_fall}
788 3: diamond {diamond_fall}
790 5: alien {alien_pause}
804 19: emerald {emerald_fall}
815 30: blank {drip_stretchB}
816 31: drip {drip_stretch}
817 32: stone {stone_pause}
818 33: bomb {bomb_pause}
819 34: diamond {diamond_pause}
820 35: emerald {emerald_pause}
821 36: wonderwall {wonderwallB}
831 46: blank {sand_stonein_2}
832 47: blank {sand_stonein_3}
833 48: blank {sand_stonein_4}
834 49: sand {sand_stonesand_2}
835 50: sand {sand_stonesand_3}
836 51: sand {sand_stonesand_4}
837 52: sand_stone {sand_sandstone_2}
838 53: sand_stone {sand_sandstone_3}
839 54: sand_stone {sand_sandstone_4}
840 55: sand {sand_stonesand_4}
841 56: stone {sand_stoneout_2}
855 70: spring {spring_fall}
856 71: spring {spring_w}
857 72: spring {spring_e}
862 77: android {android_n_1}
863 78: android {android_n_2}
864 79: android {android_s_1}
865 80: android {android_s_2}
866 81: android {android_e_1}
867 82: android {android_e_2}
868 83: android {android_w_1}
869 84: android {android_w_2}
884 99: spring {push_spring_w}
885 100: spring {push_spring_e}
894 109: pause {grass_wB}
895 110: pause {grass_eB}
896 111: pause {grass_nB}
897 112: pause {grass_sB}
898 113: pause {dynamite_blank}
899 114: nut {push_nut_w}
900 115: nut {push_nut_e}
901 116: steel_2 {end of level}
903 118: pause {emerald_blank}
904 119: bomb {push_bomb_w}
905 120: bomb {push_bomb_e}
906 121: stone {push_stone_w}
907 122: stone {push_stone_e}
908 123: pause {diamond_blank}
949 163: fake_blank {fake_blankB}
950 164: fake_grass {fake_grassB}
952 166: switch {switchB}
1043 ----------------------------------------------------------------------
1059 2091: dynamite value
1063 2095: emeralds needed
1067 2102: wonderwall time
1069 2106: ID (0xff353030)
1073 1: stone {stone_fall}
1075 3: diamond {diamond_fall}
1077 5: alien {alien_pause}
1089 17: bomb {bomb_fall}
1091 19: emerald {emerald_fall}
1101 29: drip {drip_fall}
1102 30: blank {drip_stretchB}
1103 31: drip {drip_stretch}
1104 32: stone {stone_pause}
1105 33: bomb {bomb_pause}
1106 34: diamond {diamond_pause}
1107 35: emerald {emerald_pause}
1108 36: wonderwall {wonderwallB}
1118 46: blank {sand_stonein_2}
1119 47: blank {sand_stonein_3}
1120 48: blank {sand_stonein_4}
1121 49: sand {sand_stonesand_2}
1122 50: sand {sand_stonesand_3}
1123 51: sand {sand_stonesand_4}
1124 52: sand_stone {sand_sandstone_2}
1125 53: sand_stone {sand_sandstone_3}
1126 54: sand_stone {sand_sandstone_4}
1127 55: sand {sand_stonesand_4}
1128 56: stone {sand_stoneout_2}
1181 109: pause {grass_wB}
1182 110: pause {grass_eB}
1183 111: pause {grass_nB}
1184 112: pause {grass_sB}
1185 113: pause {dynamite_blank}
1186 114: nut {push_nut_w}
1187 115: nut {push_nut_e}
1188 116: steel_2 {end of level}
1189 117: dynamite_4 {boom_2}
1190 118: pause {emerald_blank}
1191 119: bomb {push_bomb_w}
1192 120: bomb {push_bomb_e}
1193 121: stone {push_stone_w}
1194 122: stone {push_stone_e}
1195 123: pause {diamond_blank}
1196 124: pause {dirt_wB}
1197 125: pause {dirt_eB}
1198 126: pause {dirt_nB}
1199 127: pause {dirt_sB}
1330 ----------------------------------------------------------------------
1346 2091: dynamite value
1350 2095: emeralds needed
1354 2102: wonderwall time
1384 26: diamond {diamond_shine}
1385 27: emerald {emerald_shine}
1388 1: stone {stone_fall}
1390 3: diamond {diamond_fall}
1392 5: alien {alien_pause}
1404 17: bomb {bomb_fall}
1406 19: emerald {emerald_fall}
1416 29: drip {drip_fall}
1417 30: blank {drip_stretchB}
1418 31: drip {drip_stretch}
1419 32: stone {stone_pause}
1420 33: bomb {bomb_pause}
1421 34: diamond {diamond_pause}
1422 35: emerald {emerald_pause}
1423 36: wonderwall {wonderwallB}
1433 46: blank {sand_stonein_2}
1434 47: blank {sand_stonein_3}
1435 48: blank {sand_stonein_4}
1436 49: sand {sand_stonesand_2}
1437 50: sand {sand_stonesand_3}
1438 51: sand {sand_stonesand_4}
1439 52: sand_stone {sand_sandstone_2}
1440 53: sand_stone {sand_sandstone_3}
1441 54: sand_stone {sand_sandstone_4}
1442 55: sand {sand_stonesand_4}
1443 56: stone {sand_stoneout_2}
1500 113: pause {dynamite_blank}
1501 114: nut {push_nut_w}
1502 115: nut {push_nut_e}
1503 116: steel_1 {end of level}
1504 117: dynamite_4 {boom_2}
1505 118: pause {emerald_blank}
1506 119: bomb {push_bomb_w}
1507 120: bomb {push_bomb_e}
1508 121: stone {push_stone_w}
1509 122: stone {push_stone_e}
1510 123: pause {diamond_blank}
1511 124: pause {dirt_wB}
1512 125: pause {dirt_eB}
1513 126: pause {dirt_nB}
1514 127: pause {dirt_sB}
1547 159: fake_grass {dirt}
1548 160: fake_grass {dirt}
1549 161: fake_grass {dirt}
1550 162: fake_grass {dirt}
1551 163: fake_grass {dirt}
1552 164: fake_grass {dirt}
1553 165: fake_grass {dirt}
1554 166: fake_grass {dirt}
1555 167: fake_grass {dirt}
1556 168: fake_grass {dirt}
1557 169: fake_grass {dirt}
1558 170: fake_grass {dirt}
1559 171: fake_grass {dirt}
1560 172: fake_grass {dirt}
1561 173: fake_grass {dirt}
1562 174: fake_grass {dirt}
1628 240: alpha_arrow_e {}
1629 241: decor_1 {alpha_copyr}
1645 ----------------------------------------------------------------------