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 */
458 printf("::: EM level file version: %d\n", file_version);
463 /* 2000-07-30T00:26:00Z
465 * Read emerald mine caves version 6
467 * v4 and v5 emerald mine caves are converted to v6 (which completely supports
470 * converting to the internal format loses /significant/ information which can
471 * break lots of caves.
473 * major incompatibilities:
474 * - borderless caves behave completely differently, the player no longer
475 * "warps" to the other side.
476 * - a compile time option for spring can make it behave differently when it
478 * - a compile time option for rolling objects (stone, nut, spring, bomb) only
480 * - acid is always deadly even with no base beneath it (this breaks cave 0 in
482 * (*) fixed (see above):
483 * - downunder mine 16, level 0, works again
484 * - downunder mine 11, level 71, corrected (only cosmetically)
486 * so far all below have not broken any caves:
488 * - active wheel inside an eater will not function, eater explosions will not
490 * - initial collect objects (emerald, diamond, dynamite) don't exist.
491 * - initial rolling objects will be moved manually and made into sitting
493 * - drips always appear from dots.
494 * - more than one thing can fall into acid at the same time.
495 * - acid explodes when the player walks into it, rather than splashing.
496 * - simultaneous explosions may be in a slightly different order.
497 * - quicksand states have been reduced.
498 * - acid base is effectively an indestructable wall now which can affect eater
500 * - android can clone forever with a clone pause of 0 (emeralds, diamonds,
501 * nuts, stones, bombs, springs).
503 * 2001-03-12T02:46:55Z
504 * - rolling stuff is now allowed in the cave, i didn't like making this
506 * - if BAD_ROLL is not defined, initial rolling objects are moved by hand.
507 * - initial collect objects break some cave in elvis mine 5.
508 * - different timing for wonderwall break some cave in exception mine 2.
509 * - i think i'm pretty locked into always using the bad roll. *sigh*
510 * - rolling spring is now turned into regular spring. it appears the emc
511 * editor only uses the force code for initially moving spring. i will
512 * follow this in my editor.
515 * - introduced ALLOW_ROLLING_SPRING; if defined, do NOT turn rolling spring
516 * into regular spring, because this breaks at least E.M.C. Mine 3, level 79
517 * (see comment directly above)
520 static unsigned short remap_emerald[256] =
522 Xstone, Xstone, Xdiamond, Xdiamond,
523 Xalien, Xalien, Xblank, Xblank,
524 Xtank_n, Xtank_e, Xtank_s, Xtank_w,
525 Xtank_gon, Xtank_goe, Xtank_gos, Xtank_gow,
527 Xbomb, Xbomb, Xemerald, Xemerald,
528 Xbug_n, Xbug_e, Xbug_s, Xbug_w,
529 Xbug_gon, Xbug_goe, Xbug_gos, Xbug_gow,
530 Xdrip_eat, Xdrip_eat, Xdrip_eat, Xdrip_eat,
532 Xstone, Xbomb, Xdiamond, Xemerald,
533 Xwonderwall, Xnut, Xnut, Xnut,
534 Xwheel, Xeater_n, Xeater_s, Xeater_w,
535 Xeater_e, Xsand_stone, Xblank, Xblank,
537 Xblank, Xsand, Xsand, Xsand,
538 Xsand_stone, Xsand_stone, Xsand_stone, Xsand,
539 Xstone, Xgrow_ew, Xgrow_ns, Xdynamite_1,
540 Xdynamite_2, Xdynamite_3, Xdynamite_4, Xacid_s,
542 #ifdef ALLOW_ROLLING_SPRING
543 Xexit_1, Xexit_2, Xexit_3, Xballoon,
544 Xplant, Xspring, Xspring_fall, Xspring_w,
545 Xspring_e, Xball_1, Xball_2, Xandroid,
546 Xblank, Xandroid, Xandroid, Xandroid,
548 Xexit_1, Xexit_2, Xexit_3, Xballoon,
549 Xplant, Xspring, Xspring, Xspring,
550 Xspring, Xball_1, Xball_2, Xandroid,
551 Xblank, Xandroid, Xandroid, Xandroid,
554 Xandroid, Xandroid, Xandroid, Xandroid,
555 Xandroid, Xblank, Xblank, Xblank,
556 Xblank, Xblank, Xblank, Xblank,
557 Xblank, Xblank, Xblank, Xblank,
561 Xblank, Xblank, Xblank, Xspring_force_w,
562 Xspring_force_e, Xacid_1, Xacid_2, Xacid_3,
563 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
564 Xacid_8, Xblank, Xblank, Xblank,
566 Xblank, Xblank, Xnut_force_w, Xnut_force_e,
567 Xsteel_1, Xblank, Xblank, Xbomb_force_w,
568 Xbomb_force_e, Xstone_force_w, Xstone_force_e, Xblank,
569 Xblank, Xblank, Xblank, Xblank,
573 Xblank, Xblank, Xblank, Xspring,
574 Xspring, Xacid_1, Xacid_2, Xacid_3,
575 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
576 Xacid_8, Xblank, Xblank, Xblank,
578 Xblank, Xblank, Xnut, Xnut,
579 Xsteel_1, Xblank, Xblank, Xbomb,
580 Xbomb, Xstone, Xstone, Xblank,
581 Xblank, Xblank, Xblank, Xblank,
585 Xblank, Xround_wall_1, Xgrass, Xsteel_1,
586 Xwall_1, Xkey_1, Xkey_2, Xkey_3,
587 Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3,
588 Xdoor_4, Xdripper, Xfake_door_1, Xfake_door_2,
590 Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel,
591 Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
592 Xacid_se, Xfake_blank, Xamoeba_1, Xamoeba_2,
593 Xamoeba_3, Xamoeba_4, Xexit, Xalpha_arrow_w,
595 Xfake_grass, Xlenses, Xmagnify, Xfake_blank,
596 Xfake_grass, Xswitch, Xswitch, Xblank,
597 Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5,
598 Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
600 Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2,
601 Xround_wall_2, Xdecor_2, Xdecor_4, Xdecor_3,
602 Xwind_nesw, Xwind_e, Xwind_s, Xwind_w,
603 Xwind_n, Xdirt, Xplant, Xkey_5,
605 Xkey_6, Xkey_7, Xkey_8, Xdoor_5,
606 Xdoor_6, Xdoor_7, Xdoor_8, Xbumper,
607 Xalpha_a, Xalpha_b, Xalpha_c, Xalpha_d,
608 Xalpha_e, Xalpha_f, Xalpha_g, Xalpha_h,
610 Xalpha_i, Xalpha_j, Xalpha_k, Xalpha_l,
611 Xalpha_m, Xalpha_n, Xalpha_o, Xalpha_p,
612 Xalpha_q, Xalpha_r, Xalpha_s, Xalpha_t,
613 Xalpha_u, Xalpha_v, Xalpha_w, Xalpha_x,
615 Xalpha_y, Xalpha_z, Xalpha_0, Xalpha_1,
616 Xalpha_2, Xalpha_3, Xalpha_4, Xalpha_5,
617 Xalpha_6, Xalpha_7, Xalpha_8, Xalpha_9,
618 Xalpha_perio, Xalpha_excla, Xalpha_colon, Xalpha_quest,
620 Xalpha_arrow_e, Xdecor_1, Xfake_door_5, Xfake_door_6,
621 Xfake_door_7, Xfake_door_8, Xblank, Xblank,
622 Xblank, Xblank, Xblank, Xblank,
624 Xblank, Xblank, Xblank, Xblank,
626 /* special elements added to solve compatibility problems */
627 Xblank, Xblank, Xalpha_copyr, Xfake_acid_1
631 static int get_em_element(unsigned short em_element_raw, int file_version)
633 int em_element = remap_emerald[em_element_raw];
635 if (file_version < FILE_VERSION_EM_V5)
637 /* versions below V5 had no grass, but only sand/dirt */
638 if (em_element == Xgrass)
645 void convert_em_level(unsigned char *src, int file_version)
647 static int eater_offset[8] =
649 0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
654 lev.time_seconds = src[0x83E] << 8 | src[0x83F];
655 if (lev.time_seconds > 9999)
656 lev.time_seconds = 9999;
658 temp = ((src[0x83E] << 8 | src[0x83F]) * 25 + 3) / 4;
659 if (temp == 0 || temp > 9999)
661 lev.time_initial = temp;
664 lev.required_initial = src[0x82F];
666 for (i = 0; i < 2; i++)
668 temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
669 ply[i].x_initial = (temp & 63) + 1;
670 ply[i].y_initial = (temp >> 6 & 31) + 1;
673 temp = (src[0x834] << 8 | src[0x835]) * 28;
676 lev.amoeba_time = temp;
678 lev.android_move_time = src[0x874] << 8 | src[0x875];
679 lev.android_clone_time = src[0x876] << 8 | src[0x877];
681 lev.ball_random = src[0x872] & 1 ? 1 : 0;
682 lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
683 lev.ball_time = src[0x870] << 8 | src[0x871];
685 lev.emerald_score = src[0x824];
686 lev.diamond_score = src[0x825];
687 lev.alien_score = src[0x826];
688 lev.tank_score = src[0x827];
689 lev.bug_score = src[0x828];
690 lev.eater_score = src[0x829];
691 lev.nut_score = src[0x82A];
692 lev.dynamite_score = src[0x82B];
693 lev.key_score = src[0x82C];
694 lev.exit_score = src[0x82D] * 8 / 5;
695 lev.lenses_score = src[0x867];
696 lev.magnify_score = src[0x868];
697 lev.slurp_score = src[0x869];
699 lev.lenses_time = src[0x86A] << 8 | src[0x86B];
700 lev.magnify_time = src[0x86C] << 8 | src[0x86D];
701 lev.wheel_time = src[0x838] << 8 | src[0x839];
703 lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
705 lev.wind_direction_initial = (temp & 8 ? 0 :
710 lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
712 for (i = 0; i < 8; i++)
713 for (x = 0; x < 9; x++)
714 lev.eater_array[i][x] =
715 get_em_element(src[eater_offset[i] + x], file_version);
717 temp = get_em_element(src[0x86F], file_version);
718 for (y = 0; y < 8; y++)
722 for (x = 0; x < 8; x++)
723 lev.ball_array[y][x] = temp;
727 lev.ball_array[y][1] = (src[0x873] & 1) ? temp : Xblank; /* north */
728 lev.ball_array[y][6] = (src[0x873] & 2) ? temp : Xblank; /* south */
729 lev.ball_array[y][3] = (src[0x873] & 4) ? temp : Xblank; /* west */
730 lev.ball_array[y][4] = (src[0x873] & 8) ? temp : Xblank; /* east */
731 lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* southeast */
732 lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
733 lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
734 lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
738 temp = src[0x878] << 8 | src[0x879];
742 lev.android_array[Xemerald] = Xemerald;
743 lev.android_array[Xemerald_pause] = Xemerald;
744 lev.android_array[Xemerald_fall] = Xemerald;
745 lev.android_array[Yemerald_sB] = Xemerald;
746 lev.android_array[Yemerald_eB] = Xemerald;
747 lev.android_array[Yemerald_wB] = Xemerald;
752 lev.android_array[Xdiamond] = Xdiamond;
753 lev.android_array[Xdiamond_pause] = Xdiamond;
754 lev.android_array[Xdiamond_fall] = Xdiamond;
755 lev.android_array[Ydiamond_sB] = Xdiamond;
756 lev.android_array[Ydiamond_eB] = Xdiamond;
757 lev.android_array[Ydiamond_wB] = Xdiamond;
762 lev.android_array[Xstone] = Xstone;
763 lev.android_array[Xstone_pause] = Xstone;
764 lev.android_array[Xstone_fall] = Xstone;
765 lev.android_array[Ystone_sB] = Xstone;
766 lev.android_array[Ystone_eB] = Xstone;
767 lev.android_array[Ystone_wB] = Xstone;
772 lev.android_array[Xbomb] = Xbomb;
773 lev.android_array[Xbomb_pause] = Xbomb;
774 lev.android_array[Xbomb_fall] = Xbomb;
775 lev.android_array[Ybomb_sB] = Xbomb;
776 lev.android_array[Ybomb_eB] = Xbomb;
777 lev.android_array[Ybomb_wB] = Xbomb;
782 lev.android_array[Xnut] = Xnut;
783 lev.android_array[Xnut_pause] = Xnut;
784 lev.android_array[Xnut_fall] = Xnut;
785 lev.android_array[Ynut_sB] = Xnut;
786 lev.android_array[Ynut_eB] = Xnut;
787 lev.android_array[Ynut_wB] = Xnut;
792 lev.android_array[Xtank_n] = Xtank_n;
793 lev.android_array[Xtank_gon] = Xtank_n;
794 lev.android_array[Ytank_nB] = Xtank_n;
795 lev.android_array[Ytank_n_e] = Xtank_n;
796 lev.android_array[Ytank_n_w] = Xtank_n;
798 lev.android_array[Xtank_e] = Xtank_e;
799 lev.android_array[Xtank_goe] = Xtank_e;
800 lev.android_array[Ytank_eB] = Xtank_e;
801 lev.android_array[Ytank_e_s] = Xtank_e;
802 lev.android_array[Ytank_e_n] = Xtank_e;
804 lev.android_array[Xtank_s] = Xtank_s;
805 lev.android_array[Xtank_gos] = Xtank_s;
806 lev.android_array[Ytank_sB] = Xtank_s;
807 lev.android_array[Ytank_s_w] = Xtank_s;
808 lev.android_array[Ytank_s_e] = Xtank_s;
810 lev.android_array[Xtank_w] = Xtank_w;
811 lev.android_array[Xtank_gow] = Xtank_w;
812 lev.android_array[Ytank_wB] = Xtank_w;
813 lev.android_array[Ytank_w_n] = Xtank_w;
814 lev.android_array[Ytank_w_s] = Xtank_w;
819 lev.android_array[Xeater_n] = Xeater_n;
820 lev.android_array[Yeater_nB] = Xeater_n;
822 lev.android_array[Xeater_e] = Xeater_e;
823 lev.android_array[Yeater_eB] = Xeater_e;
825 lev.android_array[Xeater_s] = Xeater_s;
826 lev.android_array[Yeater_sB] = Xeater_s;
828 lev.android_array[Xeater_w] = Xeater_w;
829 lev.android_array[Yeater_wB] = Xeater_w;
834 lev.android_array[Xbug_n] = Xbug_gon;
835 lev.android_array[Xbug_gon] = Xbug_gon;
836 lev.android_array[Ybug_nB] = Xbug_gon;
837 lev.android_array[Ybug_n_e] = Xbug_gon;
838 lev.android_array[Ybug_n_w] = Xbug_gon;
840 lev.android_array[Xbug_e] = Xbug_goe;
841 lev.android_array[Xbug_goe] = Xbug_goe;
842 lev.android_array[Ybug_eB] = Xbug_goe;
843 lev.android_array[Ybug_e_s] = Xbug_goe;
844 lev.android_array[Ybug_e_n] = Xbug_goe;
846 lev.android_array[Xbug_s] = Xbug_gos;
847 lev.android_array[Xbug_gos] = Xbug_gos;
848 lev.android_array[Ybug_sB] = Xbug_gos;
849 lev.android_array[Ybug_s_w] = Xbug_gos;
850 lev.android_array[Ybug_s_e] = Xbug_gos;
852 lev.android_array[Xbug_w] = Xbug_gow;
853 lev.android_array[Xbug_gow] = Xbug_gow;
854 lev.android_array[Ybug_wB] = Xbug_gow;
855 lev.android_array[Ybug_w_n] = Xbug_gow;
856 lev.android_array[Ybug_w_s] = Xbug_gow;
861 lev.android_array[Xalien] = Xalien;
862 lev.android_array[Xalien_pause] = Xalien;
863 lev.android_array[Yalien_nB] = Xalien;
864 lev.android_array[Yalien_eB] = Xalien;
865 lev.android_array[Yalien_sB] = Xalien;
866 lev.android_array[Yalien_wB] = Xalien;
871 lev.android_array[Xspring] = Xspring;
872 lev.android_array[Xspring_pause] = Xspring;
873 lev.android_array[Xspring_e] = Xspring;
874 lev.android_array[Yspring_eB] = Xspring;
875 lev.android_array[Yspring_kill_eB] = Xspring;
876 lev.android_array[Xspring_w] = Xspring;
877 lev.android_array[Yspring_wB] = Xspring;
878 lev.android_array[Yspring_kill_wB] = Xspring;
879 lev.android_array[Xspring_fall] = Xspring;
880 lev.android_array[Yspring_sB] = Xspring;
885 lev.android_array[Yballoon_nB] = Xballoon;
886 lev.android_array[Yballoon_eB] = Xballoon;
887 lev.android_array[Yballoon_sB] = Xballoon;
888 lev.android_array[Yballoon_wB] = Xballoon;
889 lev.android_array[Xballoon] = Xballoon;
894 lev.android_array[Xdripper] = Xdrip_eat;
895 lev.android_array[XdripperB] = Xdrip_eat;
896 lev.android_array[Xamoeba_1] = Xdrip_eat;
897 lev.android_array[Xamoeba_2] = Xdrip_eat;
898 lev.android_array[Xamoeba_3] = Xdrip_eat;
899 lev.android_array[Xamoeba_4] = Xdrip_eat;
900 lev.android_array[Xamoeba_5] = Xdrip_eat;
901 lev.android_array[Xamoeba_6] = Xdrip_eat;
902 lev.android_array[Xamoeba_7] = Xdrip_eat;
903 lev.android_array[Xamoeba_8] = Xdrip_eat;
908 lev.android_array[Xdynamite] = Xdynamite;
911 for (temp = 1; temp < 2047; temp++)
915 case 0x24: /* wonderwall */
916 lev.wonderwall_state_initial = 1;
917 lev.wonderwall_time_initial = 9999;
920 case 0x28: /* wheel */
921 lev.wheel_x_initial = temp & 63;
922 lev.wheel_y_initial = temp >> 6;
923 lev.wheel_cnt_initial = lev.wheel_time;
927 case 0x63: /* spring roll left */
928 src[temp - 1] = 0x45;
932 case 0x64: /* spring roll right */
933 src[temp + 1] = 0x45;
937 case 0x72: /* nut roll left */
938 src[temp - 1] = 0x25;
942 case 0x73: /* nut roll right */
943 src[temp + 1] = 0x25;
947 case 0x77: /* bomb roll left */
948 src[temp - 1] = 0x10;
952 case 0x78: /* bomb roll right */
953 src[temp + 1] = 0x10;
957 case 0x79: /* stone roll left */
958 src[temp - 1] = 0x00;
962 case 0x7A: /* stone roll right */
963 src[temp + 1] = 0x00;
968 case 0xA3: /* fake blank */
969 lev.lenses_cnt_initial = 9999;
972 case 0xA4: /* fake grass */
973 lev.magnify_cnt_initial = 9999;
978 /* first fill the complete playfield with the default border element */
979 for (y = 0; y < HEIGHT; y++)
980 for (x = 0; x < WIDTH; x++)
981 native_em_level.cave[x][y] = ZBORDER;
983 /* then copy the real level contents from level file into the playfield */
985 for (y = 0; y < lev.height; y++)
986 for (x = 0; x < lev.width; x++)
987 native_em_level.cave[x + 1][y + 1] =
988 get_em_element(src[temp++], file_version);
990 /* at last, set the two players at their positions in the playfield */
991 /* (native EM[C] levels always have exactly two players in a level) */
992 for (i = 0; i < 2; i++)
993 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
995 native_em_level.file_version = file_version;
998 void prepare_em_level(void)
1004 /* reset all runtime variables to their initial values */
1006 for (y = 0; y < HEIGHT; y++)
1007 for (x = 0; x < WIDTH; x++)
1008 Cave[y][x] = native_em_level.cave[x][y];
1010 for (y = 0; y < HEIGHT; y++)
1011 for (x = 0; x < WIDTH; x++)
1012 Next[y][x] = Cave[y][x];
1014 for (y = 0; y < HEIGHT; y++)
1015 for (x = 0; x < WIDTH; x++)
1016 Draw[y][x] = Cave[y][x];
1018 lev.time_initial = lev.time_seconds;
1019 lev.time = lev.time_initial;
1021 lev.required = lev.required_initial;
1024 lev.android_move_cnt = lev.android_move_time;
1025 lev.android_clone_cnt = lev.android_clone_time;
1028 lev.ball_state = lev.ball_state_initial;
1029 lev.ball_cnt = lev.ball_time;
1034 lev.lenses_cnt = lev.lenses_cnt_initial;
1035 lev.magnify_cnt = lev.magnify_cnt_initial;
1037 lev.wheel_cnt = lev.wheel_cnt_initial;
1038 lev.wheel_x = lev.wheel_x_initial;
1039 lev.wheel_y = lev.wheel_y_initial;
1041 lev.wind_direction = lev.wind_direction_initial;
1042 lev.wind_cnt = lev.wind_cnt_initial;
1044 lev.wonderwall_state = lev.wonderwall_state_initial;
1045 lev.wonderwall_time = lev.wonderwall_time_initial;
1047 lev.killed_out_of_time = FALSE;
1049 /* determine number of players in this level */
1050 lev.home_initial = 0;
1052 for (i = 0; i < MAX_PLAYERS; i++)
1055 ply[i].alive_initial = FALSE;
1057 if (ply[i].x_initial > 0 && ply[i].y_initial > 0)
1065 team_mode = getTeamMode_EM();
1068 lev.home_initial = 1;
1070 lev.home = lev.home_initial;
1071 players_left = lev.home_initial;
1073 for (i = 0; i < MAX_PLAYERS; i++)
1079 ply[i].alive_initial = TRUE;
1084 int x = ply[i].x_initial;
1085 int y = ply[i].y_initial;
1087 native_em_level.cave[x][y] = Xblank;
1089 Cave[y][x] = Next[y][x] = Draw[y][x] = Xblank;
1094 for (i = 0; i < MAX_PLAYERS; i++)
1097 ply[i].alive = ply[i].alive_initial;
1098 ply[i].dynamite = 0;
1099 ply[i].dynamite_cnt = 0;
1102 ply[i].oldx = ply[i].x = ply[i].x_initial;
1103 ply[i].oldy = ply[i].y = ply[i].y_initial;
1104 ply[i].last_move_dir = MV_NONE;
1105 ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
1106 ply[i].joy_snap = ply[i].joy_drop = 0;
1107 ply[i].joy_stick = ply[i].joy_spin = 0;
1110 game_em.any_player_moving = FALSE;
1111 game_em.any_player_snapping = FALSE;
1112 game_em.last_moving_player = 0; /* default: first player */
1114 for (i = 0; i < MAX_PLAYERS; i++)
1115 game_em.last_player_direction[i] = MV_NONE;
1117 lev.exit_x = lev.exit_y = -1; /* kludge for playing player exit sound */