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 static const short map_emc[256] =
45 Xstone, Xstone, Xdiamond, Xdiamond,
46 Xalien, Xalien, Xblank, Xblank,
47 Xtank_1_n, Xtank_1_e, Xtank_1_s, Xtank_1_w,
48 Xtank_2_n, Xtank_2_e, Xtank_2_s, Xtank_2_w,
50 Xbomb, Xbomb, Xemerald, Xemerald,
51 Xbug_1_n, Xbug_1_e, Xbug_1_s, Xbug_1_w,
52 Xbug_2_n, Xbug_2_e, Xbug_2_s, Xbug_2_w,
53 Xdrip, Xdrip, Xdrip, Xdrip,
55 Xstone, Xbomb, Xdiamond, Xemerald,
56 Xwonderwall, Xnut, Xnut, Xnut,
57 Xwheel, Xeater_n, Xeater_s, Xeater_w,
58 Xeater_e, Xsand_stone, Xblank, Xblank,
60 Xblank, Xsand, Xsand, Xsand,
61 Xsand_stone, Xsand_stone, Xsand_stone, Xsand,
62 Xstone, Xslide_ew, Xslide_ns, Xdynamite_1,
63 Xdynamite_2, Xdynamite_3, Xdynamite_4, Xacid_s,
65 Xexit_1, Xexit_2, Xexit_3, Xballoon,
66 Xplant, Xspring, Xspring_fall, Xspring_w,
67 Xspring_e, Xball_1, Xball_2, Xandroid,
68 Xblank, Xandroid, Xandroid, Xandroid,
70 Xandroid, Xandroid, Xandroid, Xandroid,
71 Xandroid, Xblank, Xblank, Xblank,
72 Xblank, Xblank, Xblank, Xblank,
73 Xblank, Xblank, Xblank, Xblank,
75 Xblank, Xblank, Xblank, Xpush_spring_w,
76 Xpush_spring_e, Xacid_1, Xacid_2, Xacid_3,
77 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
78 Xacid_8, Xblank, Xblank, Xblank,
80 Xblank, Xblank, Xpush_nut_w, Xpush_nut_e,
81 Xsteel_1, Xblank, Xblank, Xpush_bomb_w,
82 Xpush_bomb_e, Xpush_stone_w, Xpush_stone_e, Xblank,
83 Xblank, Xblank, Xblank, Xblank,
85 Xblank, Xroundwall_1, Xgrass, Xsteel_1,
86 Xwall_1, Xkey_1, Xkey_2, Xkey_3,
87 Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3,
88 Xdoor_4, Xfake_amoeba, Xfake_door_1, Xfake_door_2,
90 Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel,
91 Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
92 Xacid_se, Xfake_blank, Xamoeba_1, Xamoeba_2,
93 Xamoeba_3, Xamoeba_4, Xexit, Xalpha_arrow_w,
95 Xfake_grass, Xlenses, Xmagnify, Xfake_blank,
96 Xfake_grass, Xswitch, Xswitch, Xblank,
97 Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5,
98 Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
100 Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2,
101 Xroundwall_2, Xdecor_2, Xdecor_4, Xdecor_3,
102 Xwind_any, Xwind_e, Xwind_s, Xwind_w,
103 Xwind_n, Xdirt, Xplant, Xkey_5,
105 Xkey_6, Xkey_7, Xkey_8, Xdoor_5,
106 Xdoor_6, Xdoor_7, Xdoor_8, Xbumper,
107 Xalpha_a, Xalpha_b, Xalpha_c, Xalpha_d,
108 Xalpha_e, Xalpha_f, Xalpha_g, Xalpha_h,
110 Xalpha_i, Xalpha_j, Xalpha_k, Xalpha_l,
111 Xalpha_m, Xalpha_n, Xalpha_o, Xalpha_p,
112 Xalpha_q, Xalpha_r, Xalpha_s, Xalpha_t,
113 Xalpha_u, Xalpha_v, Xalpha_w, Xalpha_x,
115 Xalpha_y, Xalpha_z, Xalpha_0, Xalpha_1,
116 Xalpha_2, Xalpha_3, Xalpha_4, Xalpha_5,
117 Xalpha_6, Xalpha_7, Xalpha_8, Xalpha_9,
118 Xalpha_perio, Xalpha_excla, Xalpha_colon, Xalpha_quest,
120 Xalpha_arrow_e, Xdecor_1, Xfake_door_5, Xfake_door_6,
121 Xfake_door_7, Xfake_door_8, Xblank, Xblank,
122 Xblank, Xblank, Xblank, Xblank,
123 Xblank, Xblank, Xalpha_copyr, Xfake_acid_1
126 static int get_em_element(unsigned short em_element_raw, int file_version)
128 int em_element = map_emc[em_element_raw];
130 if (file_version < FILE_VERSION_EM_V5)
132 /* versions below V5 had no grass, but only sand/dirt */
133 if (em_element == Xgrass)
140 void convert_em_level(unsigned char *src, int file_version)
142 static int eater_offset[8] =
144 0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
148 lev.time_seconds = src[0x83E] << 8 | src[0x83F];
149 if (lev.time_seconds > 9999)
150 lev.time_seconds = 9999;
152 lev.required_initial = src[0x82F];
154 for (i = 0; i < 2; i++)
156 temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
157 ply[i].x_initial = (temp & 63);
158 ply[i].y_initial = (temp >> 6 & 31);
161 temp = (src[0x834] << 8 | src[0x835]) * 28;
164 lev.amoeba_time = temp;
166 lev.android_move_time = src[0x874] << 8 | src[0x875];
167 lev.android_clone_time = src[0x876] << 8 | src[0x877];
169 lev.ball_random = src[0x872] & 1 ? 1 : 0;
170 lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
171 lev.ball_time = src[0x870] << 8 | src[0x871];
173 lev.emerald_score = src[0x824];
174 lev.diamond_score = src[0x825];
175 lev.alien_score = src[0x826];
176 lev.tank_score = src[0x827];
177 lev.bug_score = src[0x828];
178 lev.eater_score = src[0x829];
179 lev.nut_score = src[0x82A];
180 lev.dynamite_score = src[0x82B];
181 lev.key_score = src[0x82C];
182 lev.exit_score = src[0x82D] * 8 / 5;
183 lev.lenses_score = src[0x867];
184 lev.magnify_score = src[0x868];
185 lev.slurp_score = src[0x869];
187 lev.lenses_time = src[0x86A] << 8 | src[0x86B];
188 lev.magnify_time = src[0x86C] << 8 | src[0x86D];
189 lev.wheel_time = src[0x838] << 8 | src[0x839];
191 lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
193 lev.wind_direction_initial = (temp & 8 ? 0 :
198 lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
200 for (i = 0; i < 8; i++)
201 for (x = 0; x < 9; x++)
202 lev.eater_array[i][x] =
203 get_em_element(src[eater_offset[i] + x], file_version);
205 temp = get_em_element(src[0x86F], file_version);
206 for (y = 0; y < 8; y++)
210 for (x = 0; x < 8; x++)
211 lev.ball_array[y][x] = temp;
215 lev.ball_array[y][1] = (src[0x873] & 1) ? temp : Xblank; /* north */
216 lev.ball_array[y][6] = (src[0x873] & 2) ? temp : Xblank; /* south */
217 lev.ball_array[y][3] = (src[0x873] & 4) ? temp : Xblank; /* west */
218 lev.ball_array[y][4] = (src[0x873] & 8) ? temp : Xblank; /* east */
219 lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* southeast */
220 lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
221 lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
222 lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
226 temp = src[0x878] << 8 | src[0x879];
228 lev.android_emerald = (temp & 1) != 0;
229 lev.android_diamond = (temp & 2) != 0;
230 lev.android_stone = (temp & 4) != 0;
231 lev.android_bomb = (temp & 8) != 0;
232 lev.android_nut = (temp & 16) != 0;
233 lev.android_tank = (temp & 32) != 0;
234 lev.android_eater = (temp & 64) != 0;
235 lev.android_bug = (temp & 128) != 0;
236 lev.android_alien = (temp & 256) != 0;
237 lev.android_spring = (temp & 512) != 0;
238 lev.android_balloon = (temp & 1024) != 0;
239 lev.android_amoeba = (temp & 2048) != 0;
240 lev.android_dynamite = (temp & 4096) != 0;
242 for (temp = 1; temp < 2047; temp++)
246 case 0x24: /* wonderwall */
247 lev.wonderwall_state_initial = 1;
248 lev.wonderwall_time_initial = 9999;
251 case 0x28: /* wheel */
252 lev.wheel_x_initial = temp & 63;
253 lev.wheel_y_initial = temp >> 6;
254 lev.wheel_cnt_initial = lev.wheel_time;
257 case 0xA3: /* fake blank */
258 lev.lenses_cnt_initial = 9999;
261 case 0xA4: /* fake grass */
262 lev.magnify_cnt_initial = 9999;
267 /* first fill the complete playfield with the default border element */
268 for (y = 0; y < CAVE_HEIGHT; y++)
269 for (x = 0; x < CAVE_WIDTH; x++)
270 native_em_level.cave[x][y] = Zborder;
272 /* then copy the real level contents from level file into the playfield */
274 for (y = 0; y < lev.height; y++)
275 for (x = 0; x < lev.width; x++)
276 native_em_level.cave[x][y] =
277 get_em_element(src[temp++], file_version);
279 /* at last, set the two players at their positions in the playfield */
280 /* (native EM[C] levels always have exactly two players in a level) */
281 for (i = 0; i < 2; i++)
282 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
284 native_em_level.file_version = file_version;
288 /* convert all emerald mine caves to emc version 6 cave format.
290 * caves are filtered to get rid of invalid or unsupported tiles.
292 * although the result is a somewhat clean cave, it is meant only
293 * to give a common structure for the binary cave format. it is not
294 * for archiving purposes (it is better to keep the raw cave as-is)
295 * and it is not meant for serializing (the intermediate structure
296 * is better defined).
298 * acid top is added to acid bottom in both the cave and the eaters.
299 * fake acid (only in v4) does not exist because it adds nothing to
300 * the game, and is different even in different versions of the emc
303 * v4/v5 time is converted to 10x old time (as it should be).
304 * the reason the kingsoft player used 5x time was copy protection.
306 * note: emc v6 converter has an error in converting v4 eaters to the
307 * wrong bug(24 instead of 20) and tank(12 instead of 8).
310 static const unsigned char map_v6[256] =
314 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
315 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
316 0,16,2,18, 36,37,37,37, 40,41,42,43, 44,45,128,128,
317 128,148,148, 148,45,45,45, 148,0,57,58, 59,60,61,62,63,
319 64,65,66,67, 68,69,69,71, 72,73,74,75, 118,75,75,75,
320 75,75,75,75, 75,153,153,153, 153,153,153,153, 153,153,153,153,
321 153,153,153,99, 100,68,68,68, 68,68,68,68, 68,118,118,118,
322 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
324 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
325 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
326 160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
327 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
329 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
330 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
331 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
332 240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
335 static const unsigned char map_v5[256] =
339 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
340 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
341 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
342 128,148,148,148, 45,45,45,148, 0,57,58,59, 60,61,62,63,
344 64,65,66,67, 68,153,153,153, 153,153,153,153, 153,153,153,153,
345 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
346 153,153,153,153, 153,68,68,68, 68,68,68,68, 68,118,118,118,
347 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
349 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
350 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
351 160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
352 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
354 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
355 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
356 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
357 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
360 static const unsigned char map_v4[256] =
364 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
365 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
366 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
367 128,148,148,148, 45,45,45,148, 0,153,153,59, 60,61,62,63,
369 64,65,66,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
370 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
371 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
372 153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
374 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
375 144,145,146,147, 148,149,150,151, 152,68,154,155, 156,157,158,160,
376 160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
377 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
379 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
380 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
381 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
382 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
385 static const unsigned char map_v4_eater[32] =
387 /* filter for v4 eater */
389 128,18,2,0, 4,8,16,20, 28,37,41,45, 130,129,131,132,
390 133,134,135,136, 146,147,175,65, 66,64,2,18, 128,128,128,128
393 static boolean filename_has_v1_format(char *filename)
395 char *basename = getBaseNamePtr(filename);
397 return (strlen(basename) == 3 &&
398 basename[0] == 'a' &&
399 basename[1] >= 'a' && basename[1] <= 'k' &&
400 basename[2] >= '0' && basename[2] <= '9');
403 int cleanup_em_level(unsigned char *src, int length, char *filename)
405 int file_version = FILE_VERSION_EM_UNKNOWN;
408 if (length >= 2172 &&
409 src[2106] == 255 && /* version id: */
410 src[2107] == 54 && /* '6' */
411 src[2108] == 48 && /* '0' */
412 src[2109] == 48) /* '0' */
414 /* ---------- this cave has V6 file format ---------- */
415 file_version = FILE_VERSION_EM_V6;
417 /* remap elements to internal EMC level format */
418 for (i = 0; i < 2048; i++)
419 src[i] = map_v6[src[i]];
420 for (i = 2048; i < 2084; i++)
421 src[i] = map_v6[src[i]];
422 for (i = 2112; i < 2148; i++)
423 src[i] = map_v6[src[i]];
425 else if (length >= 2110 &&
426 src[2106] == 255 && /* version id: */
427 src[2107] == 53 && /* '5' */
428 src[2108] == 48 && /* '0' */
429 src[2109] == 48) /* '0' */
431 /* ---------- this cave has V5 file format ---------- */
432 file_version = FILE_VERSION_EM_V5;
434 /* remap elements to internal EMC level format */
435 for (i = 0; i < 2048; i++)
436 src[i] = map_v5[src[i]];
437 for (i = 2048; i < 2084; i++)
438 src[i] = map_v5[src[i]];
439 for (i = 2112; i < 2148; i++)
440 src[i] = src[i - 64];
442 else if (length >= 2106 &&
443 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
444 src[1983] == 116 || /* unencrypted (usual case) */
445 src[1983] == 131)) /* unencrypted (rare case) */
447 /* ---------- this cave has V1, V2 or V3 file format ---------- */
449 boolean fix_copyright = FALSE;
452 byte at position 1983 (0x07bf) is used as "magic byte":
453 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
454 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
455 - 131 (0x83) => unencrypted level (happens only in very rare cases)
458 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
460 /* this is original (encrypted) Emerald Mine I, II or III level file */
462 int first_byte = src[0];
463 unsigned char code0 = 0x65;
464 unsigned char code1 = 0x11;
466 /* decode encrypted level data */
467 for (i = 0; i < 2106; i++)
472 code0 = (code0 + 7) & 0xff;
475 src[1] = 131; /* needed for all Emerald Mine levels */
477 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
478 if (first_byte == 0xf5)
480 src[0] = 131; /* only needed for Emerald Mine II levels */
482 fix_copyright = TRUE;
485 /* ---------- this cave has V3 file format ---------- */
486 file_version = FILE_VERSION_EM_V3;
488 else if (filename_has_v1_format(filename))
490 /* ---------- this cave has V1 file format ---------- */
491 file_version = FILE_VERSION_EM_V1;
495 /* ---------- this cave has V2 file format ---------- */
496 file_version = FILE_VERSION_EM_V2;
499 /* remap elements to internal EMC level format */
500 for (i = 0; i < 2048; i++)
501 src[i] = map_v4[src[i]];
502 for (i = 2048; i < 2084; i++)
503 src[i] = map_v4_eater[src[i] >= 28 ? 0 : src[i]];
504 for (i = 2112; i < 2148; i++)
505 src[i] = src[i - 64];
507 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
509 for (i = 0; i < 2048; i++)
511 src[i] = 254; /* replace 'Xdecor_1' with 'Xalpha_copyr' */
516 /* ---------- this cave has unknown file format ---------- */
518 /* if file has length of old-style level file, print (wrong) magic byte */
520 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
523 return FILE_VERSION_EM_UNKNOWN;
526 if (file_version < FILE_VERSION_EM_V6)
529 src[2106] = 255; /* version id: */
530 src[2107] = 54; /* '6' */
531 src[2108] = 48; /* '0' */
532 src[2109] = 48; /* '0' */
536 /* stored level time of levels for the V2 player was changed to 50% of the
537 time for the V1 player (original V3 levels already considered this) */
538 if (file_version != FILE_VERSION_EM_V1 &&
539 file_version != FILE_VERSION_EM_V3)
544 for (i = 2148; i < 2172; i++)
551 /* ---------- at this stage, the cave data always has V6 format ---------- */
554 for (i = 0; i < 2048; i++)
557 for (i++; i < 2048; i++)
562 for (i = 64; i < 2048; i++)
563 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
564 src[i - 64] = 101; /* ... with 'Xacid_1' */
566 /* fix acid with no base beneath it (see below for details (*)) */
567 for (i = 64; i < 2048 - 1; i++)
569 if (file_version <= FILE_VERSION_EM_V2 &&
570 src[i - 64] == 101 && src[i] != 63) /* acid without base */
572 if (src[i - 1] == 101 || /* remove acid over acid row */
574 src[i - 64] = 6; /* replace element above with 'Xblank' */
576 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
580 /* fix acid in eater 1 */
581 for (i = 2051; i < 2057; i++)
585 /* fix acid in eater 2 */
586 for (i = 2060; i < 2066; i++)
590 /* fix acid in eater 3 */
591 for (i = 2069; i < 2075; i++)
595 /* fix acid in eater 4 */
596 for (i = 2078; i < 2084; i++)
600 /* fix acid in eater 5 */
601 for (i = 2115; i < 2121; i++)
605 /* fix acid in eater 6 */
606 for (i = 2124; i < 2130; i++)
610 /* fix acid in eater 7 */
611 for (i = 2133; i < 2139; i++)
615 /* fix acid in eater 8 */
616 for (i = 2142; i < 2148; i++)
625 src[src[2096] << 8 | src[2097]] = 128;
629 src[src[2098] << 8 | src[2099]] = 128;
632 if ((src[2100] << 8 | src[2101]) > 9999)
638 /* time wonderwall */
639 if ((src[2102] << 8 | src[2103]) > 9999)
646 if ((src[2110] << 8 | src[2111]) > 9999)
659 if ((src[2154] << 8 | src[2155]) > 9999)
666 if ((src[2156] << 8 | src[2157]) > 9999)
674 src[2159] = map_v6[src[2159]];
677 if ((src[2160] << 8 | src[2161]) > 9999)
688 /* android move pause */
689 if ((src[2164] << 8 | src[2165]) > 9999)
695 /* android clone pause */
696 if ((src[2166] << 8 | src[2167]) > 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 ----------------------------------------------------------------------