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];
154 #if 1 /* ================================================================== */
156 else if (length >= 2106 &&
157 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
158 src[1983] == 116 || /* unencrypted (usual case) */
159 src[1983] == 131)) /* unencrypted (rare case) */
161 /* ---------- this cave has V1, V2 or V3 file format ---------- */
163 boolean fix_copyright = FALSE;
166 byte at position 1983 (0x07bf) is used as "magic byte":
167 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
168 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
169 - 131 (0x83) => unencrypted level (happens only in very rare cases)
172 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
174 /* this is original (encrypted) Emerald Mine I, II or III level file */
176 int first_byte = src[0];
177 unsigned char code0 = 0x65;
178 unsigned char code1 = 0x11;
180 /* decode encrypted level data */
181 for (i = 0; i < 2106; i++)
186 code0 = (code0 + 7) & 0xff;
189 src[1] = 131; /* needed for all Emerald Mine levels */
191 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
192 if (first_byte == 0xf5)
194 src[0] = 131; /* only needed for Emerald Mine II levels */
196 fix_copyright = TRUE;
199 /* ---------- this cave has V3 file format ---------- */
200 file_version = FILE_VERSION_EM_V3;
202 else if (filename_has_v1_format(filename))
204 /* ---------- this cave has V1 file format ---------- */
205 file_version = FILE_VERSION_EM_V1;
209 /* ---------- this cave has V2 file format ---------- */
210 file_version = FILE_VERSION_EM_V2;
213 /* remap elements to internal EMC level format */
214 for (i = 0; i < 2048; i++)
215 src[i] = remap_v4[src[i]];
216 for (i = 2048; i < 2084; i++)
217 src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
218 for (i = 2112; i < 2148; i++)
219 src[i] = src[i - 64];
221 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
223 for (i = 0; i < 2048; i++)
225 src[i] = 254; /* replace 'Xdecor_1' with 'Xalpha_copyr' */
230 /* ---------- this cave has unknown file format ---------- */
232 /* if file has length of old-style level file, print (wrong) magic byte */
234 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
237 return FILE_VERSION_EM_UNKNOWN;
240 #else /* ================================================================== */
243 else if (length >= 2106) /* !!! TEST ONLY: SHOW BROKEN LEVELS !!! */
245 else if (length >= 2106 &&
249 /* ---------- this cave has V4 file format ---------- */
250 file_version = FILE_VERSION_EM_V4;
252 /* remap elements to internal EMC level format */
253 for (i = 0; i < 2048; i++)
254 src[i] = remap_v4[src[i]];
255 for (i = 2048; i < 2084; i++)
256 src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
257 for (i = 2112; i < 2148; i++)
258 src[i] = src[i - 64];
260 else if (length >= 2106 &&
261 src[0] == 241 && /* <-- Emerald Mine I and III levels */
264 unsigned char j = 94;
266 /* ---------- this cave has V3 file format ---------- */
267 file_version = FILE_VERSION_EM_V3;
269 /* decrypt encrypted level file */
270 for (i = 0; i < 2106; i++)
271 src[i] = (src[i] ^ (j += 7)) - 0x11;
275 /* remap elements to internal EMC level format */
276 for (i = 0; i < 2048; i++)
277 src[i] = remap_v4[src[i]];
278 for (i = 2048; i < 2084; i++)
279 src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
280 for (i = 2112; i < 2148; i++)
281 src[i] = src[i - 64];
284 else if (length >= 2106 &&
285 src[0] == 245 && /* <-- Emerald Mine II levels */
288 unsigned char j = 94;
290 /* ---------- this cave has V3 file format ---------- */
291 file_version = FILE_VERSION_EM_V3;
293 /* decrypt encrypted level file */
294 for (i = 0; i < 2106; i++)
295 src[i] = (src[i] ^ (j += 7)) - 0x11;
297 src[0] = 131; /* needed for Emerald Mine II levels */
300 /* remap elements to internal EMC level format */
301 for (i = 0; i < 2048; i++)
302 src[i] = remap_v4[src[i]];
303 for (i = 2048; i < 2084; i++)
304 src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
305 for (i = 2112; i < 2148; i++)
306 src[i] = src[i - 64];
308 /* fix copyright sign in Emerald Mine II levels */
309 for (i = 0; i < 2048; i++)
311 src[i] = 254; /* replace 'Xdecor_1' with 'Xalpha_copyr' */
316 /* ---------- this cave has unknown file format ---------- */
319 printf("::: %d, %d\n", src[0], src[1983]);
325 #endif /* ================================================================== */
327 if (file_version < FILE_VERSION_EM_V6)
330 src[2106] = 255; /* version id: */
331 src[2107] = 54; /* '6' */
332 src[2108] = 48; /* '0' */
333 src[2109] = 48; /* '0' */
337 /* stored level time of levels for the V2 player was changed to 50% of the
338 time for the V1 player (original V3 levels already considered this) */
339 if (file_version != FILE_VERSION_EM_V1 &&
340 file_version != FILE_VERSION_EM_V3)
345 for (i = 2148; i < 2172; i++)
352 printf("::: STORED TIME (< V6): %d s\n", src[2094] * 10);
358 printf("::: STORED TIME (>= V6): %d s\n", src[2110] * 256 + src[2111]);
362 /* ---------- at this stage, the cave data always has V6 format ---------- */
365 for (i = 0; i < 2048; i++)
368 for (i++; i < 2048; i++)
375 for (i = 64; i < 2048; i++)
376 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
377 src[i - 64] = 101; /* ... with 'Xacid_1' */
383 for (i = 64; i < 2048; i++)
384 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
385 src[i - 64] = 101; /* ... with 'Xacid_1' */
387 /* fix acid with no base beneath it (see below for details (*)) */
388 for (i = 64; i < 2048 - 1; i++)
390 if (file_version <= FILE_VERSION_EM_V2 &&
391 src[i - 64] == 101 && src[i] != 63) /* acid without base */
393 if (src[i - 1] == 101 || /* remove acid over acid row */
395 src[i - 64] = 6; /* replace element above with 'Xblank' */
397 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
404 for (i = 64; i < 2048; i++)
406 if (src[i] == 63) /* 'Xacid_s' (acid pool, bottom middle) */
408 if (file_version <= FILE_VERSION_EM_V2 &&
409 i < 2048 - 64 && src[i + 64] == 63)
411 int obj_left = remap_emerald[src[i - 1]];
412 int obj_right = remap_emerald[src[i + 1]];
414 if (obj_left == Xblank || obj_right == Xblank ||
415 obj_left == Xplant || obj_right == Xplant)
416 src[i - 64] = 6; /* replace element above with 'Xblank' */
418 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
422 src[i - 64] = 101; /* replace element above with 'Xacid_1' */
429 /* fix acid in eater 1 */
430 for (i = 2051; i < 2057; i++)
434 /* fix acid in eater 2 */
435 for (i = 2060; i < 2066; i++)
439 /* fix acid in eater 3 */
440 for (i = 2069; i < 2075; i++)
444 /* fix acid in eater 4 */
445 for (i = 2078; i < 2084; i++)
449 /* fix acid in eater 5 */
450 for (i = 2115; i < 2121; i++)
454 /* fix acid in eater 6 */
455 for (i = 2124; i < 2130; i++)
459 /* fix acid in eater 7 */
460 for (i = 2133; i < 2139; i++)
464 /* fix acid in eater 8 */
465 for (i = 2142; i < 2148; i++)
474 src[src[2096] << 8 | src[2097]] = 128;
478 src[src[2098] << 8 | src[2099]] = 128;
481 if ((src[2100] << 8 | src[2101]) > 9999)
487 /* time wonderwall */
488 if ((src[2102] << 8 | src[2103]) > 9999)
495 if ((src[2110] << 8 | src[2111]) > 9999)
508 if ((src[2154] << 8 | src[2155]) > 9999)
515 if ((src[2156] << 8 | src[2157]) > 9999)
523 src[2159] = remap_v6[src[2159]];
526 if ((src[2160] << 8 | src[2161]) > 9999)
537 /* android move pause */
538 if ((src[2164] << 8 | src[2165]) > 9999)
544 /* android clone pause */
545 if ((src[2166] << 8 | src[2167]) > 9999)
554 /* size of v6 cave */
561 printf("::: EM level file version: %d\n", file_version);
567 /* 2000-07-30T00:26:00Z
569 * Read emerald mine caves version 6
571 * v4 and v5 emerald mine caves are converted to v6 (which completely supports
574 * converting to the internal format loses /significant/ information which can
575 * break lots of caves.
577 * major incompatibilities:
578 * - borderless caves behave completely differently, the player no longer
579 * "warps" to the other side.
580 * - a compile time option for spring can make it behave differently when it
582 * - a compile time option for rolling objects (stone, nut, spring, bomb) only
584 * - acid is always deadly even with no base beneath it (this breaks cave 0 in
586 * (*) fixed (see above):
587 * - downunder mine 16, level 0, works again
588 * - downunder mine 11, level 71, corrected (only cosmetically)
590 * so far all below have not broken any caves:
592 * - active wheel inside an eater will not function, eater explosions will not
594 * - initial collect objects (emerald, diamond, dynamite) don't exist.
595 * - initial rolling objects will be moved manually and made into sitting
597 * - drips always appear from dots.
598 * - more than one thing can fall into acid at the same time.
599 * - acid explodes when the player walks into it, rather than splashing.
600 * - simultaneous explosions may be in a slightly different order.
601 * - quicksand states have been reduced.
602 * - acid base is effectively an indestructable wall now which can affect eater
604 * - android can clone forever with a clone pause of 0 (emeralds, diamonds,
605 * nuts, stones, bombs, springs).
607 * 2001-03-12T02:46:55Z
608 * - rolling stuff is now allowed in the cave, i didn't like making this
610 * - if BAD_ROLL is not defined, initial rolling objects are moved by hand.
611 * - initial collect objects break some cave in elvis mine 5.
612 * - different timing for wonderwall break some cave in exception mine 2.
613 * - i think i'm pretty locked into always using the bad roll. *sigh*
614 * - rolling spring is now turned into regular spring. it appears the emc
615 * editor only uses the force code for initially moving spring. i will
616 * follow this in my editor.
619 * - introduced ALLOW_ROLLING_SPRING; if defined, do NOT turn rolling spring
620 * into regular spring, because this breaks at least E.M.C. Mine 3, level 79
621 * (see comment directly above)
624 static unsigned short remap_emerald[256] =
626 Xstone, Xstone, Xdiamond, Xdiamond,
627 Xalien, Xalien, Xblank, Xblank,
628 Xtank_n, Xtank_e, Xtank_s, Xtank_w,
629 Xtank_gon, Xtank_goe, Xtank_gos, Xtank_gow,
631 Xbomb, Xbomb, Xemerald, Xemerald,
632 Xbug_n, Xbug_e, Xbug_s, Xbug_w,
633 Xbug_gon, Xbug_goe, Xbug_gos, Xbug_gow,
634 Xdrip_eat, Xdrip_eat, Xdrip_eat, Xdrip_eat,
636 Xstone, Xbomb, Xdiamond, Xemerald,
637 Xwonderwall, Xnut, Xnut, Xnut,
638 Xwheel, Xeater_n, Xeater_s, Xeater_w,
639 Xeater_e, Xsand_stone, Xblank, Xblank,
641 Xblank, Xsand, Xsand, Xsand,
642 Xsand_stone, Xsand_stone, Xsand_stone, Xsand,
643 Xstone, Xgrow_ew, Xgrow_ns, Xdynamite_1,
644 Xdynamite_2, Xdynamite_3, Xdynamite_4, Xacid_s,
646 #ifdef ALLOW_ROLLING_SPRING
647 Xexit_1, Xexit_2, Xexit_3, Xballoon,
648 Xplant, Xspring, Xspring_fall, Xspring_w,
649 Xspring_e, Xball_1, Xball_2, Xandroid,
650 Xblank, Xandroid, Xandroid, Xandroid,
652 Xexit_1, Xexit_2, Xexit_3, Xballoon,
653 Xplant, Xspring, Xspring, Xspring,
654 Xspring, Xball_1, Xball_2, Xandroid,
655 Xblank, Xandroid, Xandroid, Xandroid,
658 Xandroid, Xandroid, Xandroid, Xandroid,
659 Xandroid, Xblank, Xblank, Xblank,
660 Xblank, Xblank, Xblank, Xblank,
661 Xblank, Xblank, Xblank, Xblank,
665 Xblank, Xblank, Xblank, Xspring_force_w,
666 Xspring_force_e, Xacid_1, Xacid_2, Xacid_3,
667 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
668 Xacid_8, Xblank, Xblank, Xblank,
670 Xblank, Xblank, Xnut_force_w, Xnut_force_e,
671 Xsteel_1, Xblank, Xblank, Xbomb_force_w,
672 Xbomb_force_e, Xstone_force_w, Xstone_force_e, Xblank,
673 Xblank, Xblank, Xblank, Xblank,
677 Xblank, Xblank, Xblank, Xspring,
678 Xspring, Xacid_1, Xacid_2, Xacid_3,
679 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
680 Xacid_8, Xblank, Xblank, Xblank,
682 Xblank, Xblank, Xnut, Xnut,
683 Xsteel_1, Xblank, Xblank, Xbomb,
684 Xbomb, Xstone, Xstone, Xblank,
685 Xblank, Xblank, Xblank, Xblank,
689 Xblank, Xround_wall_1, Xgrass, Xsteel_1,
690 Xwall_1, Xkey_1, Xkey_2, Xkey_3,
691 Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3,
692 Xdoor_4, Xdripper, Xfake_door_1, Xfake_door_2,
694 Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel,
695 Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
696 Xacid_se, Xfake_blank, Xamoeba_1, Xamoeba_2,
697 Xamoeba_3, Xamoeba_4, Xexit, Xalpha_arrow_w,
699 Xfake_grass, Xlenses, Xmagnify, Xfake_blank,
700 Xfake_grass, Xswitch, Xswitch, Xblank,
701 Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5,
702 Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
704 Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2,
705 Xround_wall_2, Xdecor_2, Xdecor_4, Xdecor_3,
706 Xwind_nesw, Xwind_e, Xwind_s, Xwind_w,
707 Xwind_n, Xdirt, Xplant, Xkey_5,
709 Xkey_6, Xkey_7, Xkey_8, Xdoor_5,
710 Xdoor_6, Xdoor_7, Xdoor_8, Xbumper,
711 Xalpha_a, Xalpha_b, Xalpha_c, Xalpha_d,
712 Xalpha_e, Xalpha_f, Xalpha_g, Xalpha_h,
714 Xalpha_i, Xalpha_j, Xalpha_k, Xalpha_l,
715 Xalpha_m, Xalpha_n, Xalpha_o, Xalpha_p,
716 Xalpha_q, Xalpha_r, Xalpha_s, Xalpha_t,
717 Xalpha_u, Xalpha_v, Xalpha_w, Xalpha_x,
719 Xalpha_y, Xalpha_z, Xalpha_0, Xalpha_1,
720 Xalpha_2, Xalpha_3, Xalpha_4, Xalpha_5,
721 Xalpha_6, Xalpha_7, Xalpha_8, Xalpha_9,
722 Xalpha_perio, Xalpha_excla, Xalpha_colon, Xalpha_quest,
724 Xalpha_arrow_e, Xdecor_1, Xfake_door_5, Xfake_door_6,
725 Xfake_door_7, Xfake_door_8, Xblank, Xblank,
726 Xblank, Xblank, Xblank, Xblank,
728 Xblank, Xblank, Xblank, Xblank,
730 /* special elements added to solve compatibility problems */
731 Xblank, Xblank, Xalpha_copyr, Xfake_acid_1
735 static int get_em_element(unsigned short em_element_raw, int file_version)
737 int em_element = remap_emerald[em_element_raw];
739 if (file_version < FILE_VERSION_EM_V5)
741 /* versions below V5 had no grass, but only sand/dirt */
742 if (em_element == Xgrass)
749 void convert_em_level(unsigned char *src, int file_version)
751 static int eater_offset[8] =
753 0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
758 lev.time_seconds = src[0x83E] << 8 | src[0x83F];
759 if (lev.time_seconds > 9999)
760 lev.time_seconds = 9999;
762 temp = ((src[0x83E] << 8 | src[0x83F]) * 25 + 3) / 4;
763 if (temp == 0 || temp > 9999)
765 lev.time_initial = temp;
768 lev.required_initial = src[0x82F];
770 for (i = 0; i < 2; i++)
772 temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
773 ply[i].x_initial = (temp & 63) + 1;
774 ply[i].y_initial = (temp >> 6 & 31) + 1;
777 temp = (src[0x834] << 8 | src[0x835]) * 28;
780 lev.amoeba_time = temp;
782 lev.android_move_time = src[0x874] << 8 | src[0x875];
783 lev.android_clone_time = src[0x876] << 8 | src[0x877];
785 lev.ball_random = src[0x872] & 1 ? 1 : 0;
786 lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
787 lev.ball_time = src[0x870] << 8 | src[0x871];
789 lev.emerald_score = src[0x824];
790 lev.diamond_score = src[0x825];
791 lev.alien_score = src[0x826];
792 lev.tank_score = src[0x827];
793 lev.bug_score = src[0x828];
794 lev.eater_score = src[0x829];
795 lev.nut_score = src[0x82A];
796 lev.dynamite_score = src[0x82B];
797 lev.key_score = src[0x82C];
798 lev.exit_score = src[0x82D] * 8 / 5;
799 lev.lenses_score = src[0x867];
800 lev.magnify_score = src[0x868];
801 lev.slurp_score = src[0x869];
803 lev.lenses_time = src[0x86A] << 8 | src[0x86B];
804 lev.magnify_time = src[0x86C] << 8 | src[0x86D];
805 lev.wheel_time = src[0x838] << 8 | src[0x839];
807 lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
809 lev.wind_direction_initial = (temp & 8 ? 0 :
814 lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
816 for (i = 0; i < 8; i++)
817 for (x = 0; x < 9; x++)
818 lev.eater_array[i][x] =
819 get_em_element(src[eater_offset[i] + x], file_version);
821 temp = get_em_element(src[0x86F], file_version);
822 for (y = 0; y < 8; y++)
826 for (x = 0; x < 8; x++)
827 lev.ball_array[y][x] = temp;
831 lev.ball_array[y][1] = (src[0x873] & 1) ? temp : Xblank; /* north */
832 lev.ball_array[y][6] = (src[0x873] & 2) ? temp : Xblank; /* south */
833 lev.ball_array[y][3] = (src[0x873] & 4) ? temp : Xblank; /* west */
834 lev.ball_array[y][4] = (src[0x873] & 8) ? temp : Xblank; /* east */
835 lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* southeast */
836 lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
837 lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
838 lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
842 temp = src[0x878] << 8 | src[0x879];
846 lev.android_array[Xemerald] = Xemerald;
847 lev.android_array[Xemerald_pause] = Xemerald;
848 lev.android_array[Xemerald_fall] = Xemerald;
849 lev.android_array[Yemerald_sB] = Xemerald;
850 lev.android_array[Yemerald_eB] = Xemerald;
851 lev.android_array[Yemerald_wB] = Xemerald;
856 lev.android_array[Xdiamond] = Xdiamond;
857 lev.android_array[Xdiamond_pause] = Xdiamond;
858 lev.android_array[Xdiamond_fall] = Xdiamond;
859 lev.android_array[Ydiamond_sB] = Xdiamond;
860 lev.android_array[Ydiamond_eB] = Xdiamond;
861 lev.android_array[Ydiamond_wB] = Xdiamond;
866 lev.android_array[Xstone] = Xstone;
867 lev.android_array[Xstone_pause] = Xstone;
868 lev.android_array[Xstone_fall] = Xstone;
869 lev.android_array[Ystone_sB] = Xstone;
870 lev.android_array[Ystone_eB] = Xstone;
871 lev.android_array[Ystone_wB] = Xstone;
876 lev.android_array[Xbomb] = Xbomb;
877 lev.android_array[Xbomb_pause] = Xbomb;
878 lev.android_array[Xbomb_fall] = Xbomb;
879 lev.android_array[Ybomb_sB] = Xbomb;
880 lev.android_array[Ybomb_eB] = Xbomb;
881 lev.android_array[Ybomb_wB] = Xbomb;
886 lev.android_array[Xnut] = Xnut;
887 lev.android_array[Xnut_pause] = Xnut;
888 lev.android_array[Xnut_fall] = Xnut;
889 lev.android_array[Ynut_sB] = Xnut;
890 lev.android_array[Ynut_eB] = Xnut;
891 lev.android_array[Ynut_wB] = Xnut;
896 lev.android_array[Xtank_n] = Xtank_n;
897 lev.android_array[Xtank_gon] = Xtank_n;
898 lev.android_array[Ytank_nB] = Xtank_n;
899 lev.android_array[Ytank_n_e] = Xtank_n;
900 lev.android_array[Ytank_n_w] = Xtank_n;
902 lev.android_array[Xtank_e] = Xtank_e;
903 lev.android_array[Xtank_goe] = Xtank_e;
904 lev.android_array[Ytank_eB] = Xtank_e;
905 lev.android_array[Ytank_e_s] = Xtank_e;
906 lev.android_array[Ytank_e_n] = Xtank_e;
908 lev.android_array[Xtank_s] = Xtank_s;
909 lev.android_array[Xtank_gos] = Xtank_s;
910 lev.android_array[Ytank_sB] = Xtank_s;
911 lev.android_array[Ytank_s_w] = Xtank_s;
912 lev.android_array[Ytank_s_e] = Xtank_s;
914 lev.android_array[Xtank_w] = Xtank_w;
915 lev.android_array[Xtank_gow] = Xtank_w;
916 lev.android_array[Ytank_wB] = Xtank_w;
917 lev.android_array[Ytank_w_n] = Xtank_w;
918 lev.android_array[Ytank_w_s] = Xtank_w;
923 lev.android_array[Xeater_n] = Xeater_n;
924 lev.android_array[Yeater_nB] = Xeater_n;
926 lev.android_array[Xeater_e] = Xeater_e;
927 lev.android_array[Yeater_eB] = Xeater_e;
929 lev.android_array[Xeater_s] = Xeater_s;
930 lev.android_array[Yeater_sB] = Xeater_s;
932 lev.android_array[Xeater_w] = Xeater_w;
933 lev.android_array[Yeater_wB] = Xeater_w;
938 lev.android_array[Xbug_n] = Xbug_gon;
939 lev.android_array[Xbug_gon] = Xbug_gon;
940 lev.android_array[Ybug_nB] = Xbug_gon;
941 lev.android_array[Ybug_n_e] = Xbug_gon;
942 lev.android_array[Ybug_n_w] = Xbug_gon;
944 lev.android_array[Xbug_e] = Xbug_goe;
945 lev.android_array[Xbug_goe] = Xbug_goe;
946 lev.android_array[Ybug_eB] = Xbug_goe;
947 lev.android_array[Ybug_e_s] = Xbug_goe;
948 lev.android_array[Ybug_e_n] = Xbug_goe;
950 lev.android_array[Xbug_s] = Xbug_gos;
951 lev.android_array[Xbug_gos] = Xbug_gos;
952 lev.android_array[Ybug_sB] = Xbug_gos;
953 lev.android_array[Ybug_s_w] = Xbug_gos;
954 lev.android_array[Ybug_s_e] = Xbug_gos;
956 lev.android_array[Xbug_w] = Xbug_gow;
957 lev.android_array[Xbug_gow] = Xbug_gow;
958 lev.android_array[Ybug_wB] = Xbug_gow;
959 lev.android_array[Ybug_w_n] = Xbug_gow;
960 lev.android_array[Ybug_w_s] = Xbug_gow;
965 lev.android_array[Xalien] = Xalien;
966 lev.android_array[Xalien_pause] = Xalien;
967 lev.android_array[Yalien_nB] = Xalien;
968 lev.android_array[Yalien_eB] = Xalien;
969 lev.android_array[Yalien_sB] = Xalien;
970 lev.android_array[Yalien_wB] = Xalien;
975 lev.android_array[Xspring] = Xspring;
976 lev.android_array[Xspring_pause] = Xspring;
977 lev.android_array[Xspring_e] = Xspring;
978 lev.android_array[Yspring_eB] = Xspring;
979 lev.android_array[Yspring_kill_eB] = Xspring;
980 lev.android_array[Xspring_w] = Xspring;
981 lev.android_array[Yspring_wB] = Xspring;
982 lev.android_array[Yspring_kill_wB] = Xspring;
983 lev.android_array[Xspring_fall] = Xspring;
984 lev.android_array[Yspring_sB] = Xspring;
989 lev.android_array[Yballoon_nB] = Xballoon;
990 lev.android_array[Yballoon_eB] = Xballoon;
991 lev.android_array[Yballoon_sB] = Xballoon;
992 lev.android_array[Yballoon_wB] = Xballoon;
993 lev.android_array[Xballoon] = Xballoon;
998 lev.android_array[Xdripper] = Xdrip_eat;
999 lev.android_array[XdripperB] = Xdrip_eat;
1000 lev.android_array[Xamoeba_1] = Xdrip_eat;
1001 lev.android_array[Xamoeba_2] = Xdrip_eat;
1002 lev.android_array[Xamoeba_3] = Xdrip_eat;
1003 lev.android_array[Xamoeba_4] = Xdrip_eat;
1004 lev.android_array[Xamoeba_5] = Xdrip_eat;
1005 lev.android_array[Xamoeba_6] = Xdrip_eat;
1006 lev.android_array[Xamoeba_7] = Xdrip_eat;
1007 lev.android_array[Xamoeba_8] = Xdrip_eat;
1012 lev.android_array[Xdynamite] = Xdynamite;
1015 for (temp = 1; temp < 2047; temp++)
1019 case 0x24: /* wonderwall */
1020 lev.wonderwall_state_initial = 1;
1021 lev.wonderwall_time_initial = 9999;
1024 case 0x28: /* wheel */
1025 lev.wheel_x_initial = temp & 63;
1026 lev.wheel_y_initial = temp >> 6;
1027 lev.wheel_cnt_initial = lev.wheel_time;
1031 case 0x63: /* spring roll left */
1032 src[temp - 1] = 0x45;
1036 case 0x64: /* spring roll right */
1037 src[temp + 1] = 0x45;
1041 case 0x72: /* nut roll left */
1042 src[temp - 1] = 0x25;
1046 case 0x73: /* nut roll right */
1047 src[temp + 1] = 0x25;
1051 case 0x77: /* bomb roll left */
1052 src[temp - 1] = 0x10;
1056 case 0x78: /* bomb roll right */
1057 src[temp + 1] = 0x10;
1061 case 0x79: /* stone roll left */
1062 src[temp - 1] = 0x00;
1066 case 0x7A: /* stone roll right */
1067 src[temp + 1] = 0x00;
1072 case 0xA3: /* fake blank */
1073 lev.lenses_cnt_initial = 9999;
1076 case 0xA4: /* fake grass */
1077 lev.magnify_cnt_initial = 9999;
1082 /* first fill the complete playfield with the default border element */
1083 for (y = 0; y < HEIGHT; y++)
1084 for (x = 0; x < WIDTH; x++)
1085 native_em_level.cave[x][y] = ZBORDER;
1087 /* then copy the real level contents from level file into the playfield */
1089 for (y = 0; y < lev.height; y++)
1090 for (x = 0; x < lev.width; x++)
1091 native_em_level.cave[x + 1][y + 1] =
1092 get_em_element(src[temp++], file_version);
1094 /* at last, set the two players at their positions in the playfield */
1095 /* (native EM[C] levels always have exactly two players in a level) */
1097 for (i = 0; i < 2; i++)
1098 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
1100 for (i = 0; i < 2; i++)
1101 if (ply[i].alive_initial)
1102 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
1105 native_em_level.file_version = file_version;
1108 void prepare_em_level(void)
1115 int num_tape_players;
1118 /* reset all runtime variables to their initial values */
1120 for (y = 0; y < HEIGHT; y++)
1121 for (x = 0; x < WIDTH; x++)
1122 Cave[y][x] = native_em_level.cave[x][y];
1124 for (y = 0; y < HEIGHT; y++)
1125 for (x = 0; x < WIDTH; x++)
1126 Next[y][x] = Cave[y][x];
1128 for (y = 0; y < HEIGHT; y++)
1129 for (x = 0; x < WIDTH; x++)
1130 Draw[y][x] = Cave[y][x];
1133 lev.time_initial = lev.time_seconds;
1135 lev.time_initial = (lev.time_seconds * 50 + 7) / 8;
1137 lev.time = lev.time_initial;
1139 lev.required = lev.required_initial;
1142 lev.android_move_cnt = lev.android_move_time;
1143 lev.android_clone_cnt = lev.android_clone_time;
1146 lev.ball_state = lev.ball_state_initial;
1147 lev.ball_cnt = lev.ball_time;
1152 lev.lenses_cnt = lev.lenses_cnt_initial;
1153 lev.magnify_cnt = lev.magnify_cnt_initial;
1155 lev.wheel_cnt = lev.wheel_cnt_initial;
1156 lev.wheel_x = lev.wheel_x_initial;
1157 lev.wheel_y = lev.wheel_y_initial;
1159 lev.wind_direction = lev.wind_direction_initial;
1160 lev.wind_cnt = lev.wind_cnt_initial;
1162 lev.wonderwall_state = lev.wonderwall_state_initial;
1163 lev.wonderwall_time = lev.wonderwall_time_initial;
1165 lev.killed_out_of_time = FALSE;
1167 /* determine number of players in this level */
1168 lev.home_initial = 0;
1170 for (i = 0; i < MAX_PLAYERS; i++)
1173 ply[i].alive_initial = FALSE;
1175 if (ply[i].x_initial > 0 && ply[i].y_initial > 0)
1184 team_mode = getTeamMode_EM();
1187 lev.home_initial = 1;
1189 num_tape_players = getNumActivePlayers_EM();
1192 printf("::: getNumActivePlayers_EM: %d\n", num_tape_players);
1196 lev.home_initial = MIN(lev.home_initial, num_tape_players);
1198 if (num_tape_players != -1)
1199 lev.home_initial = MIN(lev.home_initial, num_tape_players);
1200 else if (!setup.team_mode)
1201 lev.home_initial = MIN(lev.home_initial, 1);
1205 lev.home = lev.home_initial;
1206 players_left = lev.home_initial;
1208 for (i = 0; i < MAX_PLAYERS; i++)
1214 ply[i].alive_initial = TRUE;
1219 int x = ply[i].x_initial;
1220 int y = ply[i].y_initial;
1222 native_em_level.cave[x][y] = Xblank;
1224 Cave[y][x] = Next[y][x] = Draw[y][x] = Xblank;
1229 for (i = 0; i < MAX_PLAYERS; i++)
1232 ply[i].alive = ply[i].alive_initial;
1233 ply[i].dynamite = 0;
1234 ply[i].dynamite_cnt = 0;
1237 ply[i].oldx = ply[i].x = ply[i].x_initial;
1238 ply[i].oldy = ply[i].y = ply[i].y_initial;
1239 ply[i].last_move_dir = MV_NONE;
1240 ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
1241 ply[i].joy_snap = ply[i].joy_drop = 0;
1242 ply[i].joy_stick = ply[i].joy_spin = 0;
1245 printf("player %d: x/y == %d/%d, alive == %d\n",
1246 i, ply[i].x_initial, ply[i].y_initial, ply[i].alive);
1250 game_em.any_player_moving = FALSE;
1251 game_em.last_moving_player = 0; /* default: first player */
1253 for (i = 0; i < MAX_PLAYERS; i++)
1254 game_em.last_player_direction[i] = MV_NONE;
1256 lev.exit_x = lev.exit_y = -1; /* kludge for playing player exit sound */