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 void convert_em_level(unsigned char *src, int file_version)
131 static int eater_offset[8] =
133 2048, 2057, 2066, 2075,
134 2112, 2121, 2130, 2139
138 /* common to all emc caves */
140 lev.time_seconds = GET_BE16(src[2110]);
141 if (lev.time_seconds > 9999)
142 lev.time_seconds = 9999;
144 lev.required_initial = src[2095];
148 lev.emerald_score = src[2084];
149 lev.diamond_score = src[2085];
150 lev.alien_score = src[2086];
151 lev.tank_score = src[2087];
152 lev.bug_score = src[2088];
153 lev.eater_score = src[2089];
154 lev.nut_score = src[2090];
155 lev.dynamite_score = src[2091];
156 lev.key_score = src[2092];
157 lev.exit_score = src[2093] * 8 / 5;
159 lev.lenses_score = src[2151];
160 lev.magnify_score = src[2152];
161 lev.slurp_score = src[2153];
165 lev.android_move_time = GET_BE16(src[2164]);
166 lev.android_clone_time = GET_BE16(src[2166]);
167 lev.ball_time = GET_BE16(src[2160]);
169 lev.lenses_time = GET_BE16(src[2154]);
170 lev.magnify_time = GET_BE16(src[2156]);
171 lev.wheel_time = GET_BE16(src[2104]);
173 temp = GET_BE16(src[2100]) * 28;
176 lev.amoeba_time = temp;
178 lev.wonderwall_time_initial = GET_BE16(src[2102]);
180 lev.wind_cnt_initial = src[2149] & 15 ? lev.wind_time : 0;
182 lev.wind_direction_initial = (temp & 8 ? 0 :
188 lev.ball_random = src[2162] & 1 ? 1 : 0;
189 lev.ball_state_initial = src[2162] & 128 ? 1 : 0;
191 for (temp = 1; temp < 2047; temp++)
195 case 36: /* wonderwall */
196 lev.wonderwall_state_initial = 1;
197 lev.wonderwall_time_initial = 9999;
201 lev.wheel_x_initial = temp & 63;
202 lev.wheel_y_initial = temp >> 6;
203 lev.wheel_cnt_initial = lev.wheel_time;
206 case 163: /* fake blank */
207 lev.lenses_cnt_initial = 9999;
210 case 164: /* fake grass */
211 lev.magnify_cnt_initial = 9999;
218 temp = GET_BE16(src[2168]);
220 lev.android_emerald = (temp & 1) != 0;
221 lev.android_diamond = (temp & 2) != 0;
222 lev.android_stone = (temp & 4) != 0;
223 lev.android_bomb = (temp & 8) != 0;
224 lev.android_nut = (temp & 16) != 0;
225 lev.android_tank = (temp & 32) != 0;
226 lev.android_eater = (temp & 64) != 0;
227 lev.android_bug = (temp & 128) != 0;
228 lev.android_alien = (temp & 256) != 0;
229 lev.android_spring = (temp & 512) != 0;
230 lev.android_balloon = (temp & 1024) != 0;
231 lev.android_amoeba = (temp & 2048) != 0;
232 lev.android_dynamite = (temp & 4096) != 0;
236 for (i = 0; i < 8; i++)
237 for (x = 0; x < 9; x++)
238 lev.eater_array[i][x] = map_emc[src[eater_offset[i] + x]];
242 temp = map_emc[src[2159]];
244 for (y = 0; y < 8; y++)
248 for (x = 0; x < 8; x++)
249 lev.ball_array[y][x] = temp;
253 lev.ball_array[y][1] = (src[2163] & 1) ? temp : Xblank; /* north */
254 lev.ball_array[y][6] = (src[2163] & 2) ? temp : Xblank; /* south */
255 lev.ball_array[y][3] = (src[2163] & 4) ? temp : Xblank; /* west */
256 lev.ball_array[y][4] = (src[2163] & 8) ? temp : Xblank; /* east */
257 lev.ball_array[y][7] = (src[2163] & 16) ? temp : Xblank; /* southeast */
258 lev.ball_array[y][5] = (src[2163] & 32) ? temp : Xblank; /* southwest */
259 lev.ball_array[y][2] = (src[2163] & 64) ? temp : Xblank; /* northeast */
260 lev.ball_array[y][0] = (src[2163] & 128)? temp : Xblank; /* northwest */
266 for (i = 0; i < 2; i++)
268 temp = GET_BE16(src[2096 + i * 2]);
270 ply[i].x_initial = (temp & 63);
271 ply[i].y_initial = (temp >> 6 & 31);
276 /* first fill the complete playfield with the default border element */
277 for (y = 0; y < CAVE_HEIGHT; y++)
278 for (x = 0; x < CAVE_WIDTH; x++)
279 native_em_level.cave[x][y] = Zborder;
281 /* then copy the real level contents from level file into the playfield */
283 for (y = 0; y < lev.height; y++)
284 for (x = 0; x < lev.width; x++)
285 native_em_level.cave[x][y] = map_emc[src[temp++]];
287 /* at last, set the two players at their positions in the playfield */
288 /* (native EM[C] levels always have exactly two players in a level) */
289 for (i = 0; i < 2; i++)
290 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
292 native_em_level.file_version = file_version;
296 /* convert all emerald mine caves to emc version 6 cave format.
298 * caves are filtered to get rid of invalid or unsupported tiles.
300 * although the result is a somewhat clean cave, it is meant only
301 * to give a common structure for the binary cave format. it is not
302 * for archiving purposes (it is better to keep the raw cave as-is)
303 * and it is not meant for serializing (the intermediate structure
304 * is better defined).
306 * acid top is added to acid bottom in both the cave and the eaters.
307 * fake acid (only in v4) does not exist because it adds nothing to
308 * the game, and is different even in different versions of the emc
311 * v4/v5 time is converted to 10x old time (as it should be).
312 * the reason the kingsoft player used 5x time was copy protection.
314 * note: emc v6 converter has an error in converting v4 eaters to the
315 * wrong bug(24 instead of 20) and tank(12 instead of 8).
318 /* changes for game engine integration in Rocks'n'Diamonds:
320 * cave versions below V5 had no grass, but only sand/dirt
321 * - object code 130 (V6 grass) is changed to 189 (V6 dirt)
322 * - object codes are changed in both cave and eater arrays
323 * - only graphical change, as both objects behave the same
326 static const unsigned char map_v6[256] =
330 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
331 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
332 0,16,2,18, 36,37,37,37, 40,41,42,43, 44,45,128,128,
333 128,148,148, 148,45,45,45, 148,0,57,58, 59,60,61,62,63,
335 64,65,66,67, 68,69,69,71, 72,73,74,75, 118,75,75,75,
336 75,75,75,75, 75,153,153,153, 153,153,153,153, 153,153,153,153,
337 153,153,153,99, 100,68,68,68, 68,68,68,68, 68,118,118,118,
338 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
340 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
341 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
342 160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
343 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
345 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
346 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
347 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
348 240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
351 static const unsigned char map_v5[256] =
355 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
356 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
357 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
358 128,148,148,148, 45,45,45,148, 0,57,58,59, 60,61,62,63,
360 64,65,66,67, 68,153,153,153, 153,153,153,153, 153,153,153,153,
361 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
362 153,153,153,153, 153,68,68,68, 68,68,68,68, 68,118,118,118,
363 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
365 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
366 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
367 160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
368 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
370 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
371 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
372 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
373 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
376 static const unsigned char map_v4[256] =
380 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
381 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
382 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
383 128,148,148,148, 45,45,45,148, 0,153,153,59, 60,61,62,63,
385 64,65,66,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
386 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
387 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
388 153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
390 128,129,189,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
391 144,145,146,147, 148,149,150,151, 152,68,154,155, 156,157,158,160,
392 160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
393 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
395 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
396 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
397 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
398 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
401 static const unsigned char map_v4_eater[32] =
403 /* filter for v4 eater */
405 128,18,2,0, 4,8,16,20, 28,37,41,45, 189,129,131,132,
406 133,134,135,136, 146,147,175,65, 66,64,2,18, 128,128,128,128
409 static boolean filename_has_v1_format(char *filename)
411 char *basename = getBaseNamePtr(filename);
413 return (strlen(basename) == 3 &&
414 basename[0] == 'a' &&
415 basename[1] >= 'a' && basename[1] <= 'k' &&
416 basename[2] >= '0' && basename[2] <= '9');
419 int cleanup_em_level(unsigned char *src, int length, char *filename)
421 int file_version = FILE_VERSION_EM_UNKNOWN;
424 if (length >= 2172 &&
425 src[2106] == 255 && /* version id: */
426 src[2107] == 54 && /* '6' */
427 src[2108] == 48 && /* '0' */
428 src[2109] == 48) /* '0' */
430 /* ---------- this cave has V6 file format ---------- */
431 file_version = FILE_VERSION_EM_V6;
433 /* remap elements to internal EMC level format */
434 for (i = 0; i < 2048; i++)
435 src[i] = map_v6[src[i]];
436 for (i = 2048; i < 2084; i++)
437 src[i] = map_v6[src[i]];
438 for (i = 2112; i < 2148; i++)
439 src[i] = map_v6[src[i]];
441 else if (length >= 2110 &&
442 src[2106] == 255 && /* version id: */
443 src[2107] == 53 && /* '5' */
444 src[2108] == 48 && /* '0' */
445 src[2109] == 48) /* '0' */
447 /* ---------- this cave has V5 file format ---------- */
448 file_version = FILE_VERSION_EM_V5;
450 /* remap elements to internal EMC level format */
451 for (i = 0; i < 2048; i++)
452 src[i] = map_v5[src[i]];
453 for (i = 2048; i < 2084; i++)
454 src[i] = map_v5[src[i]];
455 for (i = 2112; i < 2148; i++)
456 src[i] = src[i - 64];
458 else if (length >= 2106 &&
459 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
460 src[1983] == 116 || /* unencrypted (usual case) */
461 src[1983] == 131)) /* unencrypted (rare case) */
463 /* ---------- this cave has V1, V2 or V3 file format ---------- */
465 boolean fix_copyright = FALSE;
468 byte at position 1983 (0x07bf) is used as "magic byte":
469 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
470 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
471 - 131 (0x83) => unencrypted level (happens only in very rare cases)
474 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
476 /* this is original (encrypted) Emerald Mine I, II or III level file */
478 int first_byte = src[0];
479 unsigned char code0 = 0x65;
480 unsigned char code1 = 0x11;
482 /* decode encrypted level data */
483 for (i = 0; i < 2106; i++)
488 code0 = (code0 + 7) & 0xff;
491 src[1] = 131; /* needed for all Emerald Mine levels */
493 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
494 if (first_byte == 0xf5)
496 src[0] = 131; /* only needed for Emerald Mine II levels */
498 fix_copyright = TRUE;
501 /* ---------- this cave has V3 file format ---------- */
502 file_version = FILE_VERSION_EM_V3;
504 else if (filename_has_v1_format(filename))
506 /* ---------- this cave has V1 file format ---------- */
507 file_version = FILE_VERSION_EM_V1;
511 /* ---------- this cave has V2 file format ---------- */
512 file_version = FILE_VERSION_EM_V2;
515 /* remap elements to internal EMC level format */
516 for (i = 0; i < 2048; i++)
517 src[i] = map_v4[src[i]];
518 for (i = 2048; i < 2084; i++)
519 src[i] = map_v4_eater[src[i] >= 28 ? 0 : src[i]];
520 for (i = 2112; i < 2148; i++)
521 src[i] = src[i - 64];
523 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
525 for (i = 0; i < 2048; i++)
527 src[i] = 254; /* replace 'Xdecor_1' with 'Xalpha_copyr' */
532 /* ---------- this cave has unknown file format ---------- */
534 /* if file has length of old-style level file, print (wrong) magic byte */
536 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
539 return FILE_VERSION_EM_UNKNOWN;
542 if (file_version < FILE_VERSION_EM_V6)
545 src[2106] = 255; /* version id: */
546 src[2107] = 54; /* '6' */
547 src[2108] = 48; /* '0' */
548 src[2109] = 48; /* '0' */
552 /* stored level time of levels for the V2 player was changed to 50% of the
553 time for the V1 player (original V3 levels already considered this) */
554 if (file_version != FILE_VERSION_EM_V1 &&
555 file_version != FILE_VERSION_EM_V3)
560 for (i = 2148; i < 2172; i++)
567 /* ---------- at this stage, the cave data always has V6 format ---------- */
570 for (i = 0; i < 2048; i++)
573 for (i++; i < 2048; i++)
578 for (i = 64; i < 2048; i++)
579 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
580 src[i - 64] = 101; /* ... with 'Xacid_1' */
582 /* fix acid with no base beneath it (see below for details (*)) */
583 for (i = 64; i < 2048 - 1; i++)
585 if (file_version <= FILE_VERSION_EM_V2 &&
586 src[i - 64] == 101 && src[i] != 63) /* acid without base */
588 if (src[i - 1] == 101 || /* remove acid over acid row */
590 src[i - 64] = 6; /* replace element above with 'Xblank' */
592 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
596 /* fix acid in eater 1 */
597 for (i = 2051; i < 2057; i++)
601 /* fix acid in eater 2 */
602 for (i = 2060; i < 2066; i++)
606 /* fix acid in eater 3 */
607 for (i = 2069; i < 2075; i++)
611 /* fix acid in eater 4 */
612 for (i = 2078; i < 2084; i++)
616 /* fix acid in eater 5 */
617 for (i = 2115; i < 2121; i++)
621 /* fix acid in eater 6 */
622 for (i = 2124; i < 2130; i++)
626 /* fix acid in eater 7 */
627 for (i = 2133; i < 2139; i++)
631 /* fix acid in eater 8 */
632 for (i = 2142; i < 2148; i++)
641 src[GET_BE16(src[2096])] = 128;
645 src[GET_BE16(src[2098])] = 128;
648 if (GET_BE16(src[2100]) > 9999)
649 PUT_BE16(src[2100], 9999);
651 /* time wonderwall */
652 if (GET_BE16(src[2102]) > 9999)
653 PUT_BE16(src[2102], 9999);
656 if (GET_BE16(src[2110]) > 9999)
657 PUT_BE16(src[2110], 9999);
666 if (GET_BE16(src[2154]) > 9999)
667 PUT_BE16(src[2154], 9999);
670 if (GET_BE16(src[2156]) > 9999)
671 PUT_BE16(src[2156], 9999);
675 src[2159] = map_v6[src[2159]];
678 if (GET_BE16(src[2160]) > 9999)
679 PUT_BE16(src[2160], 9999);
686 /* android move pause */
687 if (GET_BE16(src[2164]) > 9999)
688 PUT_BE16(src[2164], 9999);
690 /* android clone pause */
691 if (GET_BE16(src[2166]) > 9999)
692 PUT_BE16(src[2166], 9999);
697 /* size of v6 cave */
701 Error(ERR_DEBUG, "EM level file version: %d", file_version);
710 structure of emerald mine level disk files
711 ----------------------------------------------------------------------
713 if(len >= 2172 && (buf[2106] == 255 && buf[2107] == 54 && buf[2108] == 48 && buf[2109] == 48)) // v6
714 if(len >= 2110 && (buf[2106] == 255 && buf[2107] == 53 && buf[2108] == 48 && buf[2109] == 48)) // v5
715 if(len >= 2106 && (buf[1983] == 116 || buf[2047] == 116)) // v4
716 if(len >= 2106 && (buf[1983] == 27 || buf[2047] == 219)) // v3
718 buf[0]=241;buf[1]=248;for(i=0,j=101;i<2106;i++,j+=7)buf[i]=(buf[i]^j)-17; // decrypt
720 number of movements (calls to logic) = time * 50 / 8
722 {} reserved (but some broken levels use them)
724 ----------------------------------------------------------------------
744 2095: emeralds needed
748 2102: wonderwall time
750 2106: ID (0xff363030)
756 2148: flags bit#7=NOI #6=RIS
757 2149: wind direction bit#0=right #1=down #2=left #3=up
758 2150: cave number bit#7=teamwork
767 2162: ball info bit#15=switch state #8=random
768 ; bit#0=N #1=S #2=W #3=E #4=SE #5=SW #6=NE #7=NW
769 2164: android move speed
770 2166: android clone speed
772 ; bit#0=emerald #1=diamond #2=stone #3=bomb #4=nut #5=tank #6=eater
773 ; #7=bug #8=alien #9=spring #10=balloon #11=ameuba #12=dynamite
778 1: stone {stone_fall}
780 3: diamond {diamond_fall}
782 5: alien {alien_pause}
796 19: emerald {emerald_fall}
807 30: blank {drip_stretchB}
808 31: drip {drip_stretch}
809 32: stone {stone_pause}
810 33: bomb {bomb_pause}
811 34: diamond {diamond_pause}
812 35: emerald {emerald_pause}
813 36: wonderwall {wonderwallB}
823 46: blank {sand_stonein_2}
824 47: blank {sand_stonein_3}
825 48: blank {sand_stonein_4}
826 49: sand {sand_stonesand_2}
827 50: sand {sand_stonesand_3}
828 51: sand {sand_stonesand_4}
829 52: sand_stone {sand_sandstone_2}
830 53: sand_stone {sand_sandstone_3}
831 54: sand_stone {sand_sandstone_4}
832 55: sand {sand_stonesand_4}
833 56: stone {sand_stoneout_2}
847 70: spring {spring_fall}
848 71: spring {spring_w}
849 72: spring {spring_e}
854 77: android {android_n_1}
855 78: android {android_n_2}
856 79: android {android_s_1}
857 80: android {android_s_2}
858 81: android {android_e_1}
859 82: android {android_e_2}
860 83: android {android_w_1}
861 84: android {android_w_2}
876 99: spring {push_spring_w}
877 100: spring {push_spring_e}
886 109: pause {grass_wB}
887 110: pause {grass_eB}
888 111: pause {grass_nB}
889 112: pause {grass_sB}
890 113: pause {dynamite_blank}
891 114: nut {push_nut_w}
892 115: nut {push_nut_e}
893 116: steel_2 {end of level}
895 118: pause {emerald_blank}
896 119: bomb {push_bomb_w}
897 120: bomb {push_bomb_e}
898 121: stone {push_stone_w}
899 122: stone {push_stone_e}
900 123: pause {diamond_blank}
941 163: fake_blank {fake_blankB}
942 164: fake_grass {fake_grassB}
944 166: switch {switchB}
1035 ----------------------------------------------------------------------
1051 2091: dynamite value
1055 2095: emeralds needed
1059 2102: wonderwall time
1061 2106: ID (0xff353030)
1065 1: stone {stone_fall}
1067 3: diamond {diamond_fall}
1069 5: alien {alien_pause}
1081 17: bomb {bomb_fall}
1083 19: emerald {emerald_fall}
1093 29: drip {drip_fall}
1094 30: blank {drip_stretchB}
1095 31: drip {drip_stretch}
1096 32: stone {stone_pause}
1097 33: bomb {bomb_pause}
1098 34: diamond {diamond_pause}
1099 35: emerald {emerald_pause}
1100 36: wonderwall {wonderwallB}
1110 46: blank {sand_stonein_2}
1111 47: blank {sand_stonein_3}
1112 48: blank {sand_stonein_4}
1113 49: sand {sand_stonesand_2}
1114 50: sand {sand_stonesand_3}
1115 51: sand {sand_stonesand_4}
1116 52: sand_stone {sand_sandstone_2}
1117 53: sand_stone {sand_sandstone_3}
1118 54: sand_stone {sand_sandstone_4}
1119 55: sand {sand_stonesand_4}
1120 56: stone {sand_stoneout_2}
1173 109: pause {grass_wB}
1174 110: pause {grass_eB}
1175 111: pause {grass_nB}
1176 112: pause {grass_sB}
1177 113: pause {dynamite_blank}
1178 114: nut {push_nut_w}
1179 115: nut {push_nut_e}
1180 116: steel_2 {end of level}
1181 117: dynamite_4 {boom_2}
1182 118: pause {emerald_blank}
1183 119: bomb {push_bomb_w}
1184 120: bomb {push_bomb_e}
1185 121: stone {push_stone_w}
1186 122: stone {push_stone_e}
1187 123: pause {diamond_blank}
1188 124: pause {dirt_wB}
1189 125: pause {dirt_eB}
1190 126: pause {dirt_nB}
1191 127: pause {dirt_sB}
1322 ----------------------------------------------------------------------
1338 2091: dynamite value
1342 2095: emeralds needed
1346 2102: wonderwall time
1376 26: diamond {diamond_shine}
1377 27: emerald {emerald_shine}
1380 1: stone {stone_fall}
1382 3: diamond {diamond_fall}
1384 5: alien {alien_pause}
1396 17: bomb {bomb_fall}
1398 19: emerald {emerald_fall}
1408 29: drip {drip_fall}
1409 30: blank {drip_stretchB}
1410 31: drip {drip_stretch}
1411 32: stone {stone_pause}
1412 33: bomb {bomb_pause}
1413 34: diamond {diamond_pause}
1414 35: emerald {emerald_pause}
1415 36: wonderwall {wonderwallB}
1425 46: blank {sand_stonein_2}
1426 47: blank {sand_stonein_3}
1427 48: blank {sand_stonein_4}
1428 49: sand {sand_stonesand_2}
1429 50: sand {sand_stonesand_3}
1430 51: sand {sand_stonesand_4}
1431 52: sand_stone {sand_sandstone_2}
1432 53: sand_stone {sand_sandstone_3}
1433 54: sand_stone {sand_sandstone_4}
1434 55: sand {sand_stonesand_4}
1435 56: stone {sand_stoneout_2}
1492 113: pause {dynamite_blank}
1493 114: nut {push_nut_w}
1494 115: nut {push_nut_e}
1495 116: steel_1 {end of level}
1496 117: dynamite_4 {boom_2}
1497 118: pause {emerald_blank}
1498 119: bomb {push_bomb_w}
1499 120: bomb {push_bomb_e}
1500 121: stone {push_stone_w}
1501 122: stone {push_stone_e}
1502 123: pause {diamond_blank}
1503 124: pause {dirt_wB}
1504 125: pause {dirt_eB}
1505 126: pause {dirt_nB}
1506 127: pause {dirt_sB}
1539 159: fake_grass {dirt}
1540 160: fake_grass {dirt}
1541 161: fake_grass {dirt}
1542 162: fake_grass {dirt}
1543 163: fake_grass {dirt}
1544 164: fake_grass {dirt}
1545 165: fake_grass {dirt}
1546 166: fake_grass {dirt}
1547 167: fake_grass {dirt}
1548 168: fake_grass {dirt}
1549 169: fake_grass {dirt}
1550 170: fake_grass {dirt}
1551 171: fake_grass {dirt}
1552 172: fake_grass {dirt}
1553 173: fake_grass {dirt}
1554 174: fake_grass {dirt}
1620 240: alpha_arrow_e {}
1621 241: decor_1 {alpha_copyr}
1637 ----------------------------------------------------------------------