1 /* 2000-08-20T09:41:18Z
3 * identify all emerald mine caves and turn them into v6 format.
4 * fixes illegal tiles, acid, wheel, limits times, cleans flags.
6 * these tables weed out bad tiles for older caves (eg. wheel on -> wheel off)
7 * and clean up v6 caves (acid, number limits) which should(!) be
8 * inconsequential, but no doubt it will break some caves.
14 #define ALLOW_ROLLING_SPRING
16 static unsigned char remap_v6[256] =
18 /* filter crap for v6 */
20 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
21 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
22 0,16,2,18, 36,37,37,37, 40,41,42,43, 44,45,128,128,
23 128,148,148, 148,45,45,45, 148,0,57,58, 59,60,61,62,63,
25 #ifdef ALLOW_ROLLING_SPRING
26 64,65,66,67, 68,69,69,71, 72,73,74,75, 118,75,75,75,
28 64,65,66,67, 68,69,69,69, 69,73,74,75, 118,75,75,75,
30 75,75,75,75, 75,153,153,153, 153,153,153,153, 153,153,153,153,
31 153,153,153,99, 100,68,68,68, 68,68,68,68, 68,118,118,118,
32 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
34 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
35 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
36 160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
37 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
39 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
40 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
41 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
42 240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
45 static unsigned char remap_v5[256] =
47 /* filter crap for v5 */
49 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
50 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
51 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
52 128,148,148,148, 45,45,45,148, 0,57,58,59, 60,61,62,63,
54 64,65,66,67, 68,153,153,153, 153,153,153,153, 153,153,153,153,
55 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
56 153,153,153,153, 153,68,68,68,68, 68,68,68,68,118, 118,118,
57 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
59 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
60 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
61 160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
62 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
64 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
65 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
66 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
67 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
70 static unsigned char remap_v4[256] =
72 /* filter crap for v4 */
74 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
75 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
76 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
77 128,148,148,148, 45,45,45,148, 0,153,153,59, 60,61,62,63,
79 64,65,66,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
80 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
81 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
82 153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
84 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
85 144,145,146,147, 148,149,150,151, 152,68,154,155, 156,157,158,160,
86 160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
87 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
89 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
90 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
91 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
92 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
95 static unsigned char remap_v4eater[28] =
97 /* filter crap for v4 */
99 128,18,2,0,4,8,16,20,28,37,
100 41,45,130,129,131,132,133,134,135,136,
101 146,147,175,65,66,64,2,18
104 static boolean filename_has_v1_format(char *filename)
106 char *basename = getBaseNamePtr(filename);
108 return (strlen(basename) == 3 &&
109 basename[0] == 'a' &&
110 basename[1] >= 'a' && basename[1] <= 'k' &&
111 basename[2] >= '0' && basename[2] <= '9');
114 int cleanup_em_level(unsigned char *src, int length, char *filename)
116 int file_version = FILE_VERSION_EM_UNKNOWN;
119 if (length >= 2172 &&
120 src[2106] == 255 && /* version id: */
121 src[2107] == 54 && /* '6' */
122 src[2108] == 48 && /* '0' */
123 src[2109] == 48) /* '0' */
125 /* ---------- this cave has V6 file format ---------- */
126 file_version = FILE_VERSION_EM_V6;
128 /* remap elements to internal EMC level format */
129 for (i = 0; i < 2048; i++)
130 src[i] = remap_v6[src[i]];
131 for (i = 2048; i < 2084; i++)
132 src[i] = remap_v6[src[i]];
133 for (i = 2112; i < 2148; i++)
134 src[i] = remap_v6[src[i]];
136 else if (length >= 2110 &&
137 src[2106] == 255 && /* version id: */
138 src[2107] == 53 && /* '5' */
139 src[2108] == 48 && /* '0' */
140 src[2109] == 48) /* '0' */
142 /* ---------- this cave has V5 file format ---------- */
143 file_version = FILE_VERSION_EM_V5;
145 /* remap elements to internal EMC level format */
146 for (i = 0; i < 2048; i++)
147 src[i] = remap_v5[src[i]];
148 for (i = 2048; i < 2084; i++)
149 src[i] = remap_v5[src[i]];
150 for (i = 2112; i < 2148; i++)
151 src[i] = src[i - 64];
153 else if (length >= 2106 &&
154 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
155 src[1983] == 116 || /* unencrypted (usual case) */
156 src[1983] == 131)) /* unencrypted (rare case) */
158 /* ---------- this cave has V1, V2 or V3 file format ---------- */
160 boolean fix_copyright = FALSE;
163 byte at position 1983 (0x07bf) is used as "magic byte":
164 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
165 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
166 - 131 (0x83) => unencrypted level (happens only in very rare cases)
169 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
171 /* this is original (encrypted) Emerald Mine I, II or III level file */
173 int first_byte = src[0];
174 unsigned char code0 = 0x65;
175 unsigned char code1 = 0x11;
177 /* decode encrypted level data */
178 for (i = 0; i < 2106; i++)
183 code0 = (code0 + 7) & 0xff;
186 src[1] = 131; /* needed for all Emerald Mine levels */
188 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
189 if (first_byte == 0xf5)
191 src[0] = 131; /* only needed for Emerald Mine II levels */
193 fix_copyright = TRUE;
196 /* ---------- this cave has V3 file format ---------- */
197 file_version = FILE_VERSION_EM_V3;
199 else if (filename_has_v1_format(filename))
201 /* ---------- this cave has V1 file format ---------- */
202 file_version = FILE_VERSION_EM_V1;
206 /* ---------- this cave has V2 file format ---------- */
207 file_version = FILE_VERSION_EM_V2;
210 /* remap elements to internal EMC level format */
211 for (i = 0; i < 2048; i++)
212 src[i] = remap_v4[src[i]];
213 for (i = 2048; i < 2084; i++)
214 src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
215 for (i = 2112; i < 2148; i++)
216 src[i] = src[i - 64];
218 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
220 for (i = 0; i < 2048; i++)
222 src[i] = 254; /* replace 'Xdecor_1' with 'Xalpha_copyr' */
227 /* ---------- this cave has unknown file format ---------- */
229 /* if file has length of old-style level file, print (wrong) magic byte */
231 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
234 return FILE_VERSION_EM_UNKNOWN;
237 if (file_version < FILE_VERSION_EM_V6)
240 src[2106] = 255; /* version id: */
241 src[2107] = 54; /* '6' */
242 src[2108] = 48; /* '0' */
243 src[2109] = 48; /* '0' */
247 /* stored level time of levels for the V2 player was changed to 50% of the
248 time for the V1 player (original V3 levels already considered this) */
249 if (file_version != FILE_VERSION_EM_V1 &&
250 file_version != FILE_VERSION_EM_V3)
255 for (i = 2148; i < 2172; i++)
262 /* ---------- at this stage, the cave data always has V6 format ---------- */
265 for (i = 0; i < 2048; i++)
268 for (i++; i < 2048; i++)
275 for (i = 64; i < 2048; i++)
276 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
277 src[i - 64] = 101; /* ... with 'Xacid_1' */
283 for (i = 64; i < 2048; i++)
284 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
285 src[i - 64] = 101; /* ... with 'Xacid_1' */
287 /* fix acid with no base beneath it (see below for details (*)) */
288 for (i = 64; i < 2048 - 1; i++)
290 if (file_version <= FILE_VERSION_EM_V2 &&
291 src[i - 64] == 101 && src[i] != 63) /* acid without base */
293 if (src[i - 1] == 101 || /* remove acid over acid row */
295 src[i - 64] = 6; /* replace element above with 'Xblank' */
297 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
304 for (i = 64; i < 2048; i++)
306 if (src[i] == 63) /* 'Xacid_s' (acid pool, bottom middle) */
308 if (file_version <= FILE_VERSION_EM_V2 &&
309 i < 2048 - 64 && src[i + 64] == 63)
311 int obj_left = remap_emerald[src[i - 1]];
312 int obj_right = remap_emerald[src[i + 1]];
314 if (obj_left == Xblank || obj_right == Xblank ||
315 obj_left == Xplant || obj_right == Xplant)
316 src[i - 64] = 6; /* replace element above with 'Xblank' */
318 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
322 src[i - 64] = 101; /* replace element above with 'Xacid_1' */
329 /* fix acid in eater 1 */
330 for (i = 2051; i < 2057; i++)
334 /* fix acid in eater 2 */
335 for (i = 2060; i < 2066; i++)
339 /* fix acid in eater 3 */
340 for (i = 2069; i < 2075; i++)
344 /* fix acid in eater 4 */
345 for (i = 2078; i < 2084; i++)
349 /* fix acid in eater 5 */
350 for (i = 2115; i < 2121; i++)
354 /* fix acid in eater 6 */
355 for (i = 2124; i < 2130; i++)
359 /* fix acid in eater 7 */
360 for (i = 2133; i < 2139; i++)
364 /* fix acid in eater 8 */
365 for (i = 2142; i < 2148; i++)
374 src[src[2096] << 8 | src[2097]] = 128;
378 src[src[2098] << 8 | src[2099]] = 128;
381 if ((src[2100] << 8 | src[2101]) > 9999)
387 /* time wonderwall */
388 if ((src[2102] << 8 | src[2103]) > 9999)
395 if ((src[2110] << 8 | src[2111]) > 9999)
408 if ((src[2154] << 8 | src[2155]) > 9999)
415 if ((src[2156] << 8 | src[2157]) > 9999)
423 src[2159] = remap_v6[src[2159]];
426 if ((src[2160] << 8 | src[2161]) > 9999)
437 /* android move pause */
438 if ((src[2164] << 8 | src[2165]) > 9999)
444 /* android clone pause */
445 if ((src[2166] << 8 | src[2167]) > 9999)
454 /* size of v6 cave */
459 Error(ERR_DEBUG, "EM level file version: %d", file_version);
465 /* 2000-07-30T00:26:00Z
467 * Read emerald mine caves version 6
469 * v4 and v5 emerald mine caves are converted to v6 (which completely supports
472 * converting to the internal format loses /significant/ information which can
473 * break lots of caves.
475 * major incompatibilities:
476 * - borderless caves behave completely differently, the player no longer
477 * "warps" to the other side.
478 * - a compile time option for spring can make it behave differently when it
480 * - a compile time option for rolling objects (stone, nut, spring, bomb) only
482 * - acid is always deadly even with no base beneath it (this breaks cave 0 in
484 * (*) fixed (see above):
485 * - downunder mine 16, level 0, works again
486 * - downunder mine 11, level 71, corrected (only cosmetically)
488 * so far all below have not broken any caves:
490 * - active wheel inside an eater will not function, eater explosions will not
492 * - initial collect objects (emerald, diamond, dynamite) don't exist.
493 * - initial rolling objects will be moved manually and made into sitting
495 * - drips always appear from dots.
496 * - more than one thing can fall into acid at the same time.
497 * - acid explodes when the player walks into it, rather than splashing.
498 * - simultaneous explosions may be in a slightly different order.
499 * - quicksand states have been reduced.
500 * - acid base is effectively an indestructable wall now which can affect eater
502 * - android can clone forever with a clone pause of 0 (emeralds, diamonds,
503 * nuts, stones, bombs, springs).
505 * 2001-03-12T02:46:55Z
506 * - rolling stuff is now allowed in the cave, i didn't like making this
508 * - if BAD_ROLL is not defined, initial rolling objects are moved by hand.
509 * - initial collect objects break some cave in elvis mine 5.
510 * - different timing for wonderwall break some cave in exception mine 2.
511 * - i think i'm pretty locked into always using the bad roll. *sigh*
512 * - rolling spring is now turned into regular spring. it appears the emc
513 * editor only uses the force code for initially moving spring. i will
514 * follow this in my editor.
517 * - introduced ALLOW_ROLLING_SPRING; if defined, do NOT turn rolling spring
518 * into regular spring, because this breaks at least E.M.C. Mine 3, level 79
519 * (see comment directly above)
522 static unsigned short remap_emerald[256] =
524 Xstone, Xstone, Xdiamond, Xdiamond,
525 Xalien, Xalien, Xblank, Xblank,
526 Xtank_n, Xtank_e, Xtank_s, Xtank_w,
527 Xtank_gon, Xtank_goe, Xtank_gos, Xtank_gow,
529 Xbomb, Xbomb, Xemerald, Xemerald,
530 Xbug_n, Xbug_e, Xbug_s, Xbug_w,
531 Xbug_gon, Xbug_goe, Xbug_gos, Xbug_gow,
532 Xdrip_eat, Xdrip_eat, Xdrip_eat, Xdrip_eat,
534 Xstone, Xbomb, Xdiamond, Xemerald,
535 Xwonderwall, Xnut, Xnut, Xnut,
536 Xwheel, Xeater_n, Xeater_s, Xeater_w,
537 Xeater_e, Xsand_stone, Xblank, Xblank,
539 Xblank, Xsand, Xsand, Xsand,
540 Xsand_stone, Xsand_stone, Xsand_stone, Xsand,
541 Xstone, Xgrow_ew, Xgrow_ns, Xdynamite_1,
542 Xdynamite_2, Xdynamite_3, Xdynamite_4, Xacid_s,
544 #ifdef ALLOW_ROLLING_SPRING
545 Xexit_1, Xexit_2, Xexit_3, Xballoon,
546 Xplant, Xspring, Xspring_fall, Xspring_w,
547 Xspring_e, Xball_1, Xball_2, Xandroid,
548 Xblank, Xandroid, Xandroid, Xandroid,
550 Xexit_1, Xexit_2, Xexit_3, Xballoon,
551 Xplant, Xspring, Xspring, Xspring,
552 Xspring, Xball_1, Xball_2, Xandroid,
553 Xblank, Xandroid, Xandroid, Xandroid,
556 Xandroid, Xandroid, Xandroid, Xandroid,
557 Xandroid, Xblank, Xblank, Xblank,
558 Xblank, Xblank, Xblank, Xblank,
559 Xblank, Xblank, Xblank, Xblank,
563 Xblank, Xblank, Xblank, Xspring_force_w,
564 Xspring_force_e, Xacid_1, Xacid_2, Xacid_3,
565 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
566 Xacid_8, Xblank, Xblank, Xblank,
568 Xblank, Xblank, Xnut_force_w, Xnut_force_e,
569 Xsteel_1, Xblank, Xblank, Xbomb_force_w,
570 Xbomb_force_e, Xstone_force_w, Xstone_force_e, Xblank,
571 Xblank, Xblank, Xblank, Xblank,
575 Xblank, Xblank, Xblank, Xspring,
576 Xspring, Xacid_1, Xacid_2, Xacid_3,
577 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
578 Xacid_8, Xblank, Xblank, Xblank,
580 Xblank, Xblank, Xnut, Xnut,
581 Xsteel_1, Xblank, Xblank, Xbomb,
582 Xbomb, Xstone, Xstone, Xblank,
583 Xblank, Xblank, Xblank, Xblank,
587 Xblank, Xround_wall_1, Xgrass, Xsteel_1,
588 Xwall_1, Xkey_1, Xkey_2, Xkey_3,
589 Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3,
590 Xdoor_4, Xdripper, Xfake_door_1, Xfake_door_2,
592 Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel,
593 Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
594 Xacid_se, Xfake_blank, Xamoeba_1, Xamoeba_2,
595 Xamoeba_3, Xamoeba_4, Xexit, Xalpha_arrow_w,
597 Xfake_grass, Xlenses, Xmagnify, Xfake_blank,
598 Xfake_grass, Xswitch, Xswitch, Xblank,
599 Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5,
600 Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
602 Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2,
603 Xround_wall_2, Xdecor_2, Xdecor_4, Xdecor_3,
604 Xwind_nesw, Xwind_e, Xwind_s, Xwind_w,
605 Xwind_n, Xdirt, Xplant, Xkey_5,
607 Xkey_6, Xkey_7, Xkey_8, Xdoor_5,
608 Xdoor_6, Xdoor_7, Xdoor_8, Xbumper,
609 Xalpha_a, Xalpha_b, Xalpha_c, Xalpha_d,
610 Xalpha_e, Xalpha_f, Xalpha_g, Xalpha_h,
612 Xalpha_i, Xalpha_j, Xalpha_k, Xalpha_l,
613 Xalpha_m, Xalpha_n, Xalpha_o, Xalpha_p,
614 Xalpha_q, Xalpha_r, Xalpha_s, Xalpha_t,
615 Xalpha_u, Xalpha_v, Xalpha_w, Xalpha_x,
617 Xalpha_y, Xalpha_z, Xalpha_0, Xalpha_1,
618 Xalpha_2, Xalpha_3, Xalpha_4, Xalpha_5,
619 Xalpha_6, Xalpha_7, Xalpha_8, Xalpha_9,
620 Xalpha_perio, Xalpha_excla, Xalpha_colon, Xalpha_quest,
622 Xalpha_arrow_e, Xdecor_1, Xfake_door_5, Xfake_door_6,
623 Xfake_door_7, Xfake_door_8, Xblank, Xblank,
624 Xblank, Xblank, Xblank, Xblank,
626 Xblank, Xblank, Xblank, Xblank,
628 /* special elements added to solve compatibility problems */
629 Xblank, Xblank, Xalpha_copyr, Xfake_acid_1
633 static int get_em_element(unsigned short em_element_raw, int file_version)
635 int em_element = remap_emerald[em_element_raw];
637 if (file_version < FILE_VERSION_EM_V5)
639 /* versions below V5 had no grass, but only sand/dirt */
640 if (em_element == Xgrass)
647 void convert_em_level(unsigned char *src, int file_version)
649 static int eater_offset[8] =
651 0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
656 lev.time_seconds = src[0x83E] << 8 | src[0x83F];
657 if (lev.time_seconds > 9999)
658 lev.time_seconds = 9999;
660 temp = ((src[0x83E] << 8 | src[0x83F]) * 25 + 3) / 4;
661 if (temp == 0 || temp > 9999)
663 lev.time_initial = temp;
666 lev.required_initial = src[0x82F];
668 for (i = 0; i < 2; i++)
670 temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
671 ply[i].x_initial = (temp & 63) + 1;
672 ply[i].y_initial = (temp >> 6 & 31) + 1;
675 temp = (src[0x834] << 8 | src[0x835]) * 28;
678 lev.amoeba_time = temp;
680 lev.android_move_time = src[0x874] << 8 | src[0x875];
681 lev.android_clone_time = src[0x876] << 8 | src[0x877];
683 lev.ball_random = src[0x872] & 1 ? 1 : 0;
684 lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
685 lev.ball_time = src[0x870] << 8 | src[0x871];
687 lev.emerald_score = src[0x824];
688 lev.diamond_score = src[0x825];
689 lev.alien_score = src[0x826];
690 lev.tank_score = src[0x827];
691 lev.bug_score = src[0x828];
692 lev.eater_score = src[0x829];
693 lev.nut_score = src[0x82A];
694 lev.dynamite_score = src[0x82B];
695 lev.key_score = src[0x82C];
696 lev.exit_score = src[0x82D] * 8 / 5;
697 lev.lenses_score = src[0x867];
698 lev.magnify_score = src[0x868];
699 lev.slurp_score = src[0x869];
701 lev.lenses_time = src[0x86A] << 8 | src[0x86B];
702 lev.magnify_time = src[0x86C] << 8 | src[0x86D];
703 lev.wheel_time = src[0x838] << 8 | src[0x839];
705 lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
707 lev.wind_direction_initial = (temp & 8 ? 0 :
712 lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
714 for (i = 0; i < 8; i++)
715 for (x = 0; x < 9; x++)
716 lev.eater_array[i][x] =
717 get_em_element(src[eater_offset[i] + x], file_version);
719 temp = get_em_element(src[0x86F], file_version);
720 for (y = 0; y < 8; y++)
724 for (x = 0; x < 8; x++)
725 lev.ball_array[y][x] = temp;
729 lev.ball_array[y][1] = (src[0x873] & 1) ? temp : Xblank; /* north */
730 lev.ball_array[y][6] = (src[0x873] & 2) ? temp : Xblank; /* south */
731 lev.ball_array[y][3] = (src[0x873] & 4) ? temp : Xblank; /* west */
732 lev.ball_array[y][4] = (src[0x873] & 8) ? temp : Xblank; /* east */
733 lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* southeast */
734 lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
735 lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
736 lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
740 temp = src[0x878] << 8 | src[0x879];
744 lev.android_array[Xemerald] = Xemerald;
745 lev.android_array[Xemerald_pause] = Xemerald;
746 lev.android_array[Xemerald_fall] = Xemerald;
747 lev.android_array[Yemerald_sB] = Xemerald;
748 lev.android_array[Yemerald_eB] = Xemerald;
749 lev.android_array[Yemerald_wB] = Xemerald;
754 lev.android_array[Xdiamond] = Xdiamond;
755 lev.android_array[Xdiamond_pause] = Xdiamond;
756 lev.android_array[Xdiamond_fall] = Xdiamond;
757 lev.android_array[Ydiamond_sB] = Xdiamond;
758 lev.android_array[Ydiamond_eB] = Xdiamond;
759 lev.android_array[Ydiamond_wB] = Xdiamond;
764 lev.android_array[Xstone] = Xstone;
765 lev.android_array[Xstone_pause] = Xstone;
766 lev.android_array[Xstone_fall] = Xstone;
767 lev.android_array[Ystone_sB] = Xstone;
768 lev.android_array[Ystone_eB] = Xstone;
769 lev.android_array[Ystone_wB] = Xstone;
774 lev.android_array[Xbomb] = Xbomb;
775 lev.android_array[Xbomb_pause] = Xbomb;
776 lev.android_array[Xbomb_fall] = Xbomb;
777 lev.android_array[Ybomb_sB] = Xbomb;
778 lev.android_array[Ybomb_eB] = Xbomb;
779 lev.android_array[Ybomb_wB] = Xbomb;
784 lev.android_array[Xnut] = Xnut;
785 lev.android_array[Xnut_pause] = Xnut;
786 lev.android_array[Xnut_fall] = Xnut;
787 lev.android_array[Ynut_sB] = Xnut;
788 lev.android_array[Ynut_eB] = Xnut;
789 lev.android_array[Ynut_wB] = Xnut;
794 lev.android_array[Xtank_n] = Xtank_n;
795 lev.android_array[Xtank_gon] = Xtank_n;
796 lev.android_array[Ytank_nB] = Xtank_n;
797 lev.android_array[Ytank_n_e] = Xtank_n;
798 lev.android_array[Ytank_n_w] = Xtank_n;
800 lev.android_array[Xtank_e] = Xtank_e;
801 lev.android_array[Xtank_goe] = Xtank_e;
802 lev.android_array[Ytank_eB] = Xtank_e;
803 lev.android_array[Ytank_e_s] = Xtank_e;
804 lev.android_array[Ytank_e_n] = Xtank_e;
806 lev.android_array[Xtank_s] = Xtank_s;
807 lev.android_array[Xtank_gos] = Xtank_s;
808 lev.android_array[Ytank_sB] = Xtank_s;
809 lev.android_array[Ytank_s_w] = Xtank_s;
810 lev.android_array[Ytank_s_e] = Xtank_s;
812 lev.android_array[Xtank_w] = Xtank_w;
813 lev.android_array[Xtank_gow] = Xtank_w;
814 lev.android_array[Ytank_wB] = Xtank_w;
815 lev.android_array[Ytank_w_n] = Xtank_w;
816 lev.android_array[Ytank_w_s] = Xtank_w;
821 lev.android_array[Xeater_n] = Xeater_n;
822 lev.android_array[Yeater_nB] = Xeater_n;
824 lev.android_array[Xeater_e] = Xeater_e;
825 lev.android_array[Yeater_eB] = Xeater_e;
827 lev.android_array[Xeater_s] = Xeater_s;
828 lev.android_array[Yeater_sB] = Xeater_s;
830 lev.android_array[Xeater_w] = Xeater_w;
831 lev.android_array[Yeater_wB] = Xeater_w;
836 lev.android_array[Xbug_n] = Xbug_gon;
837 lev.android_array[Xbug_gon] = Xbug_gon;
838 lev.android_array[Ybug_nB] = Xbug_gon;
839 lev.android_array[Ybug_n_e] = Xbug_gon;
840 lev.android_array[Ybug_n_w] = Xbug_gon;
842 lev.android_array[Xbug_e] = Xbug_goe;
843 lev.android_array[Xbug_goe] = Xbug_goe;
844 lev.android_array[Ybug_eB] = Xbug_goe;
845 lev.android_array[Ybug_e_s] = Xbug_goe;
846 lev.android_array[Ybug_e_n] = Xbug_goe;
848 lev.android_array[Xbug_s] = Xbug_gos;
849 lev.android_array[Xbug_gos] = Xbug_gos;
850 lev.android_array[Ybug_sB] = Xbug_gos;
851 lev.android_array[Ybug_s_w] = Xbug_gos;
852 lev.android_array[Ybug_s_e] = Xbug_gos;
854 lev.android_array[Xbug_w] = Xbug_gow;
855 lev.android_array[Xbug_gow] = Xbug_gow;
856 lev.android_array[Ybug_wB] = Xbug_gow;
857 lev.android_array[Ybug_w_n] = Xbug_gow;
858 lev.android_array[Ybug_w_s] = Xbug_gow;
863 lev.android_array[Xalien] = Xalien;
864 lev.android_array[Xalien_pause] = Xalien;
865 lev.android_array[Yalien_nB] = Xalien;
866 lev.android_array[Yalien_eB] = Xalien;
867 lev.android_array[Yalien_sB] = Xalien;
868 lev.android_array[Yalien_wB] = Xalien;
873 lev.android_array[Xspring] = Xspring;
874 lev.android_array[Xspring_pause] = Xspring;
875 lev.android_array[Xspring_e] = Xspring;
876 lev.android_array[Yspring_eB] = Xspring;
877 lev.android_array[Yspring_kill_eB] = Xspring;
878 lev.android_array[Xspring_w] = Xspring;
879 lev.android_array[Yspring_wB] = Xspring;
880 lev.android_array[Yspring_kill_wB] = Xspring;
881 lev.android_array[Xspring_fall] = Xspring;
882 lev.android_array[Yspring_sB] = Xspring;
887 lev.android_array[Yballoon_nB] = Xballoon;
888 lev.android_array[Yballoon_eB] = Xballoon;
889 lev.android_array[Yballoon_sB] = Xballoon;
890 lev.android_array[Yballoon_wB] = Xballoon;
891 lev.android_array[Xballoon] = Xballoon;
896 lev.android_array[Xdripper] = Xdrip_eat;
897 lev.android_array[XdripperB] = Xdrip_eat;
898 lev.android_array[Xamoeba_1] = Xdrip_eat;
899 lev.android_array[Xamoeba_2] = Xdrip_eat;
900 lev.android_array[Xamoeba_3] = Xdrip_eat;
901 lev.android_array[Xamoeba_4] = Xdrip_eat;
902 lev.android_array[Xamoeba_5] = Xdrip_eat;
903 lev.android_array[Xamoeba_6] = Xdrip_eat;
904 lev.android_array[Xamoeba_7] = Xdrip_eat;
905 lev.android_array[Xamoeba_8] = Xdrip_eat;
910 lev.android_array[Xdynamite] = Xdynamite;
913 for (temp = 1; temp < 2047; temp++)
917 case 0x24: /* wonderwall */
918 lev.wonderwall_state_initial = 1;
919 lev.wonderwall_time_initial = 9999;
922 case 0x28: /* wheel */
923 lev.wheel_x_initial = temp & 63;
924 lev.wheel_y_initial = temp >> 6;
925 lev.wheel_cnt_initial = lev.wheel_time;
929 case 0x63: /* spring roll left */
930 src[temp - 1] = 0x45;
934 case 0x64: /* spring roll right */
935 src[temp + 1] = 0x45;
939 case 0x72: /* nut roll left */
940 src[temp - 1] = 0x25;
944 case 0x73: /* nut roll right */
945 src[temp + 1] = 0x25;
949 case 0x77: /* bomb roll left */
950 src[temp - 1] = 0x10;
954 case 0x78: /* bomb roll right */
955 src[temp + 1] = 0x10;
959 case 0x79: /* stone roll left */
960 src[temp - 1] = 0x00;
964 case 0x7A: /* stone roll right */
965 src[temp + 1] = 0x00;
970 case 0xA3: /* fake blank */
971 lev.lenses_cnt_initial = 9999;
974 case 0xA4: /* fake grass */
975 lev.magnify_cnt_initial = 9999;
980 /* first fill the complete playfield with the default border element */
981 for (y = 0; y < HEIGHT; y++)
982 for (x = 0; x < WIDTH; x++)
983 native_em_level.cave[x][y] = ZBORDER;
985 /* then copy the real level contents from level file into the playfield */
987 for (y = 0; y < lev.height; y++)
988 for (x = 0; x < lev.width; x++)
989 native_em_level.cave[x + 1][y + 1] =
990 get_em_element(src[temp++], file_version);
992 /* at last, set the two players at their positions in the playfield */
993 /* (native EM[C] levels always have exactly two players in a level) */
994 for (i = 0; i < 2; i++)
995 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
997 native_em_level.file_version = file_version;
1000 void prepare_em_level(void)
1006 /* reset all runtime variables to their initial values */
1008 for (y = 0; y < HEIGHT; y++)
1009 for (x = 0; x < WIDTH; x++)
1010 Cave[y][x] = native_em_level.cave[x][y];
1012 for (y = 0; y < HEIGHT; y++)
1013 for (x = 0; x < WIDTH; x++)
1014 Next[y][x] = Cave[y][x];
1016 for (y = 0; y < HEIGHT; y++)
1017 for (x = 0; x < WIDTH; x++)
1018 Draw[y][x] = Cave[y][x];
1020 lev.time_initial = lev.time_seconds;
1021 lev.time = lev.time_initial;
1023 lev.required = lev.required_initial;
1026 lev.android_move_cnt = lev.android_move_time;
1027 lev.android_clone_cnt = lev.android_clone_time;
1030 lev.ball_state = lev.ball_state_initial;
1031 lev.ball_cnt = lev.ball_time;
1036 lev.lenses_cnt = lev.lenses_cnt_initial;
1037 lev.magnify_cnt = lev.magnify_cnt_initial;
1039 lev.wheel_cnt = lev.wheel_cnt_initial;
1040 lev.wheel_x = lev.wheel_x_initial;
1041 lev.wheel_y = lev.wheel_y_initial;
1043 lev.wind_direction = lev.wind_direction_initial;
1044 lev.wind_cnt = lev.wind_cnt_initial;
1046 lev.wonderwall_state = lev.wonderwall_state_initial;
1047 lev.wonderwall_time = lev.wonderwall_time_initial;
1049 lev.killed_out_of_time = FALSE;
1051 /* determine number of players in this level */
1052 lev.home_initial = 0;
1054 for (i = 0; i < MAX_PLAYERS; i++)
1057 ply[i].alive_initial = FALSE;
1059 if (ply[i].x_initial > 0 && ply[i].y_initial > 0)
1067 team_mode = getTeamMode_EM();
1070 lev.home_initial = 1;
1072 lev.home = lev.home_initial;
1073 players_left = lev.home_initial;
1075 for (i = 0; i < MAX_PLAYERS; i++)
1081 ply[i].alive_initial = TRUE;
1086 int x = ply[i].x_initial;
1087 int y = ply[i].y_initial;
1089 native_em_level.cave[x][y] = Xblank;
1091 Cave[y][x] = Next[y][x] = Draw[y][x] = Xblank;
1096 for (i = 0; i < MAX_PLAYERS; i++)
1099 ply[i].alive = ply[i].alive_initial;
1100 ply[i].dynamite = 0;
1101 ply[i].dynamite_cnt = 0;
1104 ply[i].oldx = ply[i].x = ply[i].x_initial;
1105 ply[i].oldy = ply[i].y = ply[i].y_initial;
1106 ply[i].last_move_dir = MV_NONE;
1107 ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
1108 ply[i].joy_snap = ply[i].joy_drop = 0;
1109 ply[i].joy_stick = ply[i].joy_spin = 0;
1112 // the following engine variables are initialized to version-specific values
1113 // in function InitGameEngine() (src/game.c):
1115 // - game_em.use_single_button (default: TRUE)
1116 // - game_em.use_snap_key_bug (default: FALSE)
1118 game_em.level_solved = FALSE;
1119 game_em.game_over = FALSE;
1121 game_em.any_player_moving = FALSE;
1122 game_em.any_player_snapping = FALSE;
1124 game_em.last_moving_player = 0; /* default: first player */
1126 for (i = 0; i < MAX_PLAYERS; i++)
1127 game_em.last_player_direction[i] = MV_NONE;
1129 lev.exit_x = lev.exit_y = -1; /* kludge for playing player exit sound */