rnd-20060407-1-src
[rocksndiamonds.git] / src / game_em / convert.c
1 /* 2000-08-20T09:41:18Z
2  *
3  * identify all emerald mine caves and turn them into v6 format.
4  * fixes illegal tiles, acid, wheel, limits times, cleans flags.
5  *
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.
9  */
10
11 #include "main_em.h"
12
13
14 #define ALLOW_ROLLING_SPRING
15
16 static unsigned char remap_v6[256] =
17 {
18   /* filter crap for v6 */
19
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,
24
25 #ifdef ALLOW_ROLLING_SPRING
26   64,65,66,67,     68,69,69,71,     72,73,74,75,     118,75,75,75,
27 #else
28   64,65,66,67,     68,69,69,69,     69,73,74,75,     118,75,75,75,
29 #endif
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,
33
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,
38
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
43 };
44
45 static unsigned char remap_v5[256] =
46 {
47   /* filter crap for v5 */
48
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,
53
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,
58
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,
63
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
68 };
69
70 static unsigned char remap_v4[256] =
71 {
72   /* filter crap for v4 */
73
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,
78
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,
83
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,
88
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
93 };
94
95 static unsigned char remap_v4eater[28] =
96 {
97   /* filter crap for v4 */
98
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
102 };
103
104 int cleanup_em_level(unsigned char *src, int length)
105 {
106   int file_version = 0;
107   int i;
108
109   if (length >= 2172 &&
110       src[2106] == 255 &&
111       src[2107] == 54 &&
112       src[2108] == 48 &&
113       src[2109] == 48)
114   {
115     /* ---------- this cave has V6 file format ---------- */
116     file_version = FILE_VERSION_EM_V6;
117
118     for (i = 0; i < 2048; i++)
119       src[i] = remap_v6[src[i]];
120     for (i = 2048; i < 2084; i++)
121       src[i] = remap_v6[src[i]];
122     for (i = 2112; i < 2148; i++)
123       src[i] = remap_v6[src[i]];
124   }
125   else if (length >= 2110 &&
126            src[2106] == 255 &&
127            src[2107] == 53 &&
128            src[2108] == 48 &&
129            src[2109] == 48)
130   {
131     /* ---------- this cave has V5 file format ---------- */
132     file_version = FILE_VERSION_EM_V5;
133
134     for (i = 0; i < 2048; i++)
135       src[i] = remap_v5[src[i]];
136     for (i = 2048; i < 2084; i++)
137       src[i] = remap_v5[src[i]];
138     for (i = 2112; i < 2148; i++)
139       src[i] = src[i - 64];
140   }
141 #if 0
142   else if (length >= 2106)      /* !!! TEST ONLY: SHOW BROKEN LEVELS !!! */
143 #else
144   else if (length >= 2106 &&
145            src[1983] == 116)
146 #endif
147   {
148     /* ---------- this cave has V4 file format ---------- */
149     file_version = FILE_VERSION_EM_V4;
150
151     for (i = 0; i < 2048; i++)
152       src[i] = remap_v4[src[i]];
153     for (i = 2048; i < 2084; i++)
154       src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
155     for (i = 2112; i < 2148; i++) src[i] = src[i - 64];
156   }
157   else if (length >= 2106 &&
158            src[0] == 241 &&     /* <-- Emerald Mine I levels */
159            src[1983] == 27)
160   {
161     unsigned char j = 94;
162
163     /* ---------- this cave has V3 file format ---------- */
164     file_version = FILE_VERSION_EM_V3;
165
166     for (i = 0; i < 2106; i++)
167       src[i] = (src[i] ^ (j += 7)) - 0x11;
168     src[1] = 131;
169     for (i = 0; i < 2048; i++)
170       src[i] = remap_v4[src[i]];
171     for (i = 2048; i < 2084; i++)
172       src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
173     for (i = 2112; i < 2148; i++)
174       src[i] = src[i - 64];
175   }
176 #if 1
177   else if (length >= 2106 &&
178            src[0] == 245 &&     /* <-- Emerald Mine II levels */
179            src[1983] == 27)
180   {
181     unsigned char j = 94;
182
183     /* ---------- this cave has V3 file format ---------- */
184     file_version = FILE_VERSION_EM_V3;
185
186     for (i = 0; i < 2106; i++)
187       src[i] = (src[i] ^ (j += 7)) - 0x11;
188     src[0] = 131;               /* needed for Emerald Mine II levels */
189     src[1] = 131;
190     for (i = 0; i < 2048; i++)
191       src[i] = remap_v4[src[i]];
192     for (i = 2048; i < 2084; i++)
193       src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
194     for (i = 2112; i < 2148; i++)
195       src[i] = src[i - 64];
196
197     /* fix copyright sign in Emerald Mine II levels */
198     for (i = 0; i < 2048; i++)
199       if (src[i] == 241)
200         src[i] = 254;           /* replace 'Xdecor_1' with 'Xalpha_copyr' */
201   }
202 #endif
203   else
204   {
205     /* ---------- this cave has unknown file format ---------- */
206
207 #if 0
208     printf("::: %d, %d\n", src[0], src[1983]);
209 #endif
210
211     return 0;
212   }
213
214   if (file_version < FILE_VERSION_EM_V6)
215   {
216     /* id */
217     src[2106] = 255;
218     src[2107] = 54;
219     src[2108] = 48;
220     src[2109] = 48;
221
222     /* time */
223     i = src[2094] * 10;
224     src[2110] = i >> 8;
225     src[2111] = i;
226
227     for (i = 2148; i < 2172; i++)
228       src[i] = 0;
229
230     /* ball data */
231     src[2159] = 128;
232   }
233
234   /* ---------- at this stage, the cave data always has V6 format ---------- */
235
236   /* fix wheel */
237   for (i = 0; i < 2048; i++)
238     if (src[i] == 40)
239       break;
240   for (i++; i < 2048; i++)
241     if (src[i] == 40)
242       src[i] = 147;
243
244 #if 0
245   /* fix acid */
246   for (i = 64; i < 2048; i++)
247     if (src[i] == 63)           /* replace element above 'Xacid_s' ... */
248       src[i - 64] = 101;        /* ... with 'Xacid_1' */
249
250 #else
251
252   /* fix acid */
253   for (i = 64; i < 2048; i++)
254   {
255     if (src[i] == 63)           /* 'Xacid_s' (acid pool, bottom middle) */
256     {
257       if (file_version == FILE_VERSION_EM_V4 &&
258           i < 2048 - 64 && src[i + 64] == 63)
259         src[i - 64] = 255;      /* replace element above with 'Xfake_acid_1' */
260       else
261         src[i - 64] = 101;      /* replace element above with 'Xacid_1' */
262     }
263   }
264 #endif
265
266   /* fix acid in eater 1 */
267   for (i = 2051; i < 2057; i++)
268     if (src[i] == 63)
269       src[i - 3] = 101;
270
271   /* fix acid in eater 2 */
272   for (i = 2060; i < 2066; i++)
273     if (src[i] == 63)
274       src[i - 3] = 101;
275
276   /* fix acid in eater 3 */
277   for (i = 2069; i < 2075; i++)
278     if (src[i] == 63)
279       src[i - 3] = 101;
280
281   /* fix acid in eater 4 */
282   for (i = 2078; i < 2084; i++)
283     if (src[i] == 63)
284       src[i - 3] = 101;
285
286   /* fix acid in eater 5 */
287   for (i = 2115; i < 2121; i++)
288     if (src[i] == 63)
289       src[i - 3] = 101;
290
291   /* fix acid in eater 6 */
292   for (i = 2124; i < 2130; i++)
293     if (src[i] == 63)
294       src[i - 3] = 101;
295
296   /* fix acid in eater 7 */
297   for (i = 2133; i < 2139; i++)
298     if (src[i] == 63)
299       src[i - 3] = 101;
300
301   /* fix acid in eater 8 */
302   for (i = 2142; i < 2148; i++)
303     if (src[i] == 63)
304       src[i - 3] = 101;
305
306   /* old style time */
307   src[2094] = 0;
308
309   /* player 1 pos */
310   src[2096] &= 7;
311   src[src[2096] << 8 | src[2097]] = 128;
312
313   /* player 2 pos */
314   src[2098] &= 7;
315   src[src[2098] << 8 | src[2099]] = 128;
316
317   /* amoeba speed */
318   if ((src[2100] << 8 | src[2101]) > 9999)
319   {
320     src[2100] = 39;
321     src[2101] = 15;
322   }
323
324   /* time wonderwall */
325   if ((src[2102] << 8 | src[2103]) > 9999)
326   {
327     src[2102] = 39;
328     src[2103] = 15;
329   }
330
331   /* time */
332   if ((src[2110] << 8 | src[2111]) > 9999)
333   {
334     src[2110] = 39;
335     src[2111] = 15;
336   }
337
338   /* wind direction */
339   i = src[2149];
340   i &= 15;
341   i &= -i;
342   src[2149] = i;
343
344   /* time lenses */
345   if ((src[2154] << 8 | src[2155]) > 9999)
346   {
347     src[2154] = 39;
348     src[2155] = 15;
349   }
350
351   /* time magnify */
352   if ((src[2156] << 8 | src[2157]) > 9999)
353   {
354     src[2156] = 39;
355     src[2157] = 15;
356   }
357
358   /* ball object */
359   src[2158] = 0;
360   src[2159] = remap_v6[src[2159]];
361
362   /* ball pause */
363   if ((src[2160] << 8 | src[2161]) > 9999)
364   {
365     src[2160] = 39;
366     src[2161] = 15;
367   }
368
369   /* ball data */
370   src[2162] &= 129;
371   if (src[2162] & 1)
372     src[2163] = 0;
373
374   /* android move pause */
375   if ((src[2164] << 8 | src[2165]) > 9999)
376   {
377     src[2164] = 39;
378     src[2165] = 15;
379   }
380
381   /* android clone pause */
382   if ((src[2166] << 8 | src[2167]) > 9999)
383   {
384     src[2166] = 39;
385     src[2167] = 15;
386   }
387
388   /* android data */
389   src[2168] &= 31;
390
391   /* size of v6 cave */
392   length = 2172;
393
394 #if 1
395   if (options.debug)
396     printf("::: EM level file version: %d\n", file_version);
397 #endif
398
399   return file_version;
400 }
401
402 /* 2000-07-30T00:26:00Z
403  *
404  * Read emerald mine caves version 6
405  *
406  * v4 and v5 emerald mine caves are converted to v6 (which completely supports
407  * older versions)
408  * 
409  * converting to the internal format loses /significant/ information which can
410  * break lots of caves.
411  * 
412  * major incompatibilities:
413  * - borderless caves behave completely differently, the player no longer
414  *   "warps" to the other side.
415  * - a compile time option for spring can make it behave differently when it
416  *   rolls.
417  * - a compile time option for rolling objects (stone, nut, spring, bomb) only
418  *   in eater.
419  * - acid is always deadly even with no base beneath it (this breaks cave 0 in
420  *   downunder mine 16)
421  *
422  * so far all below have not broken any caves:
423  *
424  * - active wheel inside an eater will not function, eater explosions will not
425  *   change settings.
426  * - initial collect objects (emerald, diamond, dynamite) don't exist.
427  * - initial rolling objects will be moved manually and made into sitting
428  *   objects.
429  * - drips always appear from dots.
430  * - more than one thing can fall into acid at the same time.
431  * - acid explodes when the player walks into it, rather than splashing.
432  * - simultaneous explosions may be in a slightly different order.
433  * - quicksand states have been reduced.
434  * - acid base is effectively an indestructable wall now which can affect eater
435  *   explosions.
436  * - android can clone forever with a clone pause of 0 (emeralds, diamonds,
437  *   nuts, stones, bombs, springs).
438  *
439  * 2001-03-12T02:46:55Z
440  * - rolling stuff is now allowed in the cave, i didn't like making this
441  *   decision.
442  * - if BAD_ROLL is not defined, initial rolling objects are moved by hand.
443  * - initial collect objects break some cave in elvis mine 5.
444  * - different timing for wonderwall break some cave in exception mine 2.
445  * - i think i'm pretty locked into always using the bad roll. *sigh*
446  * - rolling spring is now turned into regular spring. it appears the emc
447  *   editor only uses the force code for initially moving spring. i will
448  *   follow this in my editor.
449  *
450  * 2006-04-02
451  * - introduced ALLOW_ROLLING_SPRING; if defined, do NOT turn rolling spring
452  *   into regular spring, because this breaks at least E.M.C. Mine 3, level 79
453  *   (see comment directly above)
454  */
455
456 static unsigned short remap_emerald[256] =
457 {
458   Xstone,               Xstone,         Xdiamond,       Xdiamond,
459   Xalien,               Xalien,         Xblank,         Xblank,
460   Xtank_n,              Xtank_e,        Xtank_s,        Xtank_w,
461   Xtank_gon,            Xtank_goe,      Xtank_gos,      Xtank_gow,
462
463   Xbomb,                Xbomb,          Xemerald,       Xemerald,
464   Xbug_n,               Xbug_e,         Xbug_s,         Xbug_w,
465   Xbug_gon,             Xbug_goe,       Xbug_gos,       Xbug_gow,
466   Xdrip_eat,            Xdrip_eat,      Xdrip_eat,      Xdrip_eat,
467
468   Xstone,               Xbomb,          Xdiamond,       Xemerald,
469   Xwonderwall,          Xnut,           Xnut,           Xnut,
470   Xwheel,               Xeater_n,       Xeater_s,       Xeater_w,
471   Xeater_e,             Xsand_stone,    Xblank,         Xblank,
472
473   Xblank,               Xsand,          Xsand,          Xsand,
474   Xsand_stone,          Xsand_stone,    Xsand_stone,    Xsand,
475   Xstone,               Xgrow_ew,       Xgrow_ns,       Xdynamite_1,
476   Xdynamite_2,          Xdynamite_3,    Xdynamite_4,    Xacid_s,
477
478 #ifdef ALLOW_ROLLING_SPRING
479   Xexit_1,              Xexit_2,        Xexit_3,        Xballoon,
480   Xplant,               Xspring,        Xspring_fall,   Xspring_w,
481   Xspring_e,            Xball_1,        Xball_2,        Xandroid,
482   Xblank,               Xandroid,       Xandroid,       Xandroid,
483 #else
484   Xexit_1,              Xexit_2,        Xexit_3,        Xballoon,
485   Xplant,               Xspring,        Xspring,        Xspring,
486   Xspring,              Xball_1,        Xball_2,        Xandroid,
487   Xblank,               Xandroid,       Xandroid,       Xandroid,
488 #endif
489
490   Xandroid,             Xandroid,       Xandroid,       Xandroid,
491   Xandroid,             Xblank,         Xblank,         Xblank,
492   Xblank,               Xblank,         Xblank,         Xblank,
493   Xblank,               Xblank,         Xblank,         Xblank,
494
495 #ifdef BAD_ROLL
496
497   Xblank,               Xblank,         Xblank,         Xspring_force_w,
498   Xspring_force_e,      Xacid_1,        Xacid_2,        Xacid_3,
499   Xacid_4,              Xacid_5,        Xacid_6,        Xacid_7,
500   Xacid_8,              Xblank,         Xblank,         Xblank,
501
502   Xblank,               Xblank,         Xnut_force_w,   Xnut_force_e,
503   Xsteel_1,             Xblank,         Xblank,         Xbomb_force_w,
504   Xbomb_force_e,        Xstone_force_w, Xstone_force_e, Xblank,
505   Xblank,               Xblank,         Xblank,         Xblank,
506
507 #else
508
509   Xblank,               Xblank,         Xblank,         Xspring,
510   Xspring,              Xacid_1,        Xacid_2,        Xacid_3,
511   Xacid_4,              Xacid_5,        Xacid_6,        Xacid_7,
512   Xacid_8,              Xblank,         Xblank,         Xblank,
513
514   Xblank,               Xblank,         Xnut,           Xnut,
515   Xsteel_1,             Xblank,         Xblank,         Xbomb,
516   Xbomb,                Xstone,         Xstone,         Xblank,
517   Xblank,               Xblank,         Xblank,         Xblank,
518
519 #endif
520
521   Xblank,               Xround_wall_1,  Xgrass,         Xsteel_1,
522   Xwall_1,              Xkey_1,         Xkey_2,         Xkey_3,
523   Xkey_4,               Xdoor_1,        Xdoor_2,        Xdoor_3,
524   Xdoor_4,              Xdripper,       Xfake_door_1,   Xfake_door_2,
525
526   Xfake_door_3,         Xfake_door_4,   Xwonderwall,    Xwheel,
527   Xsand,                Xacid_nw,       Xacid_ne,       Xacid_sw,
528   Xacid_se,             Xfake_blank,    Xamoeba_1,      Xamoeba_2,
529   Xamoeba_3,            Xamoeba_4,      Xexit,          Xalpha_arrow_w,
530
531   Xfake_grass,          Xlenses,        Xmagnify,       Xfake_blank,
532   Xfake_grass,          Xswitch,        Xswitch,        Xblank,
533   Xdecor_8,             Xdecor_9,       Xdecor_10,      Xdecor_5,
534   Xalpha_comma,         Xalpha_quote,   Xalpha_minus,   Xdynamite,
535
536   Xsteel_3,             Xdecor_6,       Xdecor_7,       Xsteel_2,
537   Xround_wall_2,        Xdecor_2,       Xdecor_4,       Xdecor_3,
538   Xwind_nesw,           Xwind_e,        Xwind_s,        Xwind_w,
539   Xwind_n,              Xdirt,          Xplant,         Xkey_5,
540
541   Xkey_6,               Xkey_7,         Xkey_8,         Xdoor_5,
542   Xdoor_6,              Xdoor_7,        Xdoor_8,        Xbumper,
543   Xalpha_a,             Xalpha_b,       Xalpha_c,       Xalpha_d,
544   Xalpha_e,             Xalpha_f,       Xalpha_g,       Xalpha_h,
545
546   Xalpha_i,             Xalpha_j,       Xalpha_k,       Xalpha_l,
547   Xalpha_m,             Xalpha_n,       Xalpha_o,       Xalpha_p,
548   Xalpha_q,             Xalpha_r,       Xalpha_s,       Xalpha_t,
549   Xalpha_u,             Xalpha_v,       Xalpha_w,       Xalpha_x,
550
551   Xalpha_y,             Xalpha_z,       Xalpha_0,       Xalpha_1,
552   Xalpha_2,             Xalpha_3,       Xalpha_4,       Xalpha_5,
553   Xalpha_6,             Xalpha_7,       Xalpha_8,       Xalpha_9,
554   Xalpha_perio,         Xalpha_excla,   Xalpha_colon,   Xalpha_quest,
555
556   Xalpha_arrow_e,       Xdecor_1,       Xfake_door_5,   Xfake_door_6,
557   Xfake_door_7,         Xfake_door_8,   Xblank,         Xblank,
558   Xblank,               Xblank,         Xblank,         Xblank,
559 #if 0
560   Xblank,               Xblank,         Xblank,         Xblank,
561 #else
562   /* special elements added to solve compatibility problems */
563   Xblank,               Xblank,         Xalpha_copyr,   Xfake_acid_1
564 #endif
565 };
566
567 static int get_em_element(unsigned short em_element_raw, int file_version)
568 {
569   int em_element = remap_emerald[em_element_raw];
570
571   if (file_version <= FILE_VERSION_EM_V4)
572   {
573     /* versions up to V4 had no grass, but only sand/dirt */
574     if (em_element == Xgrass)
575       em_element = Xdirt;
576   }
577
578   return em_element;
579 }
580
581 void convert_em_level(unsigned char *src, int file_version)
582 {
583   static int eater_offset[8] =
584   {
585     0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
586   };
587   int i, x, y, temp;
588
589 #if 1
590   lev.time_seconds = src[0x83E] << 8 | src[0x83F];
591   if (lev.time_seconds > 9999)
592     lev.time_seconds = 9999;
593 #else
594   temp = ((src[0x83E] << 8 | src[0x83F]) * 25 + 3) / 4;
595   if (temp == 0 || temp > 9999)
596     temp = 9999;
597   lev.time_initial = temp;
598 #endif
599
600   lev.required_initial = src[0x82F];
601
602   for (i = 0; i < 2; i++)
603   {
604     temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
605     ply[i].x_initial = (temp & 63) + 1;
606     ply[i].y_initial = (temp >> 6 & 31) + 1;
607   }
608
609   temp = (src[0x834] << 8 | src[0x835]) * 28;
610   if (temp > 9999)
611     temp = 9999;
612   lev.amoeba_time = temp;
613
614   lev.android_move_time = src[0x874] << 8 | src[0x875];
615   lev.android_clone_time = src[0x876] << 8 | src[0x877];
616
617   lev.ball_random = src[0x872] & 1 ? 1 : 0;
618   lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
619   lev.ball_time = src[0x870] << 8 | src[0x871];
620
621   lev.emerald_score = src[0x824];
622   lev.diamond_score = src[0x825];
623   lev.alien_score = src[0x826];
624   lev.tank_score = src[0x827];
625   lev.bug_score = src[0x828];
626   lev.eater_score = src[0x829];
627   lev.nut_score = src[0x82A];
628   lev.dynamite_score = src[0x82B];
629   lev.key_score = src[0x82C];
630   lev.exit_score = src[0x82D] * 8 / 5;
631   lev.lenses_score = src[0x867];
632   lev.magnify_score = src[0x868];
633   lev.slurp_score = src[0x869];
634
635   lev.lenses_time = src[0x86A] << 8 | src[0x86B];
636   lev.magnify_time = src[0x86C] << 8 | src[0x86D];
637   lev.wheel_time = src[0x838] << 8 | src[0x839];
638
639   lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
640   temp = src[0x865];
641   lev.wind_direction_initial = (temp & 8 ? 0 :
642                                 temp & 1 ? 1 :
643                                 temp & 2 ? 2 :
644                                 temp & 4 ? 3 : 0);
645
646   lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
647
648   for (i = 0; i < 8; i++)
649     for (x = 0; x < 9; x++)
650       lev.eater_array[i][x] =
651         get_em_element(src[eater_offset[i] + x], file_version);
652
653   temp = get_em_element(src[0x86F], file_version);
654   for (y = 0; y < 8; y++)
655   {
656     if (src[0x872] & 1)
657     {
658       for (x = 0; x < 8; x++)
659         lev.ball_array[y][x] = temp;
660     }
661     else
662     {
663       lev.ball_array[y][1] = (src[0x873] & 1)  ? temp : Xblank; /* north */
664       lev.ball_array[y][6] = (src[0x873] & 2)  ? temp : Xblank; /* south */
665       lev.ball_array[y][3] = (src[0x873] & 4)  ? temp : Xblank; /* west */
666       lev.ball_array[y][4] = (src[0x873] & 8)  ? temp : Xblank; /* east */
667       lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* southeast */
668       lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
669       lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
670       lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
671     }
672   }
673
674   temp = src[0x878] << 8 | src[0x879];
675
676   if (temp & 1)
677   {
678     lev.android_array[Xemerald]         = Xemerald;
679     lev.android_array[Xemerald_pause]   = Xemerald;
680     lev.android_array[Xemerald_fall]    = Xemerald;
681     lev.android_array[Yemerald_sB]      = Xemerald;
682     lev.android_array[Yemerald_eB]      = Xemerald;
683     lev.android_array[Yemerald_wB]      = Xemerald;
684   }
685
686   if (temp & 2)
687   {
688     lev.android_array[Xdiamond]         = Xdiamond;
689     lev.android_array[Xdiamond_pause]   = Xdiamond;
690     lev.android_array[Xdiamond_fall]    = Xdiamond;
691     lev.android_array[Ydiamond_sB]      = Xdiamond;
692     lev.android_array[Ydiamond_eB]      = Xdiamond;
693     lev.android_array[Ydiamond_wB]      = Xdiamond;
694   }
695
696   if (temp & 4)
697   {
698     lev.android_array[Xstone]           = Xstone;
699     lev.android_array[Xstone_pause]     = Xstone;
700     lev.android_array[Xstone_fall]      = Xstone;
701     lev.android_array[Ystone_sB]        = Xstone;
702     lev.android_array[Ystone_eB]        = Xstone;
703     lev.android_array[Ystone_wB]        = Xstone;
704   }
705
706   if (temp & 8)
707   {
708     lev.android_array[Xbomb]            = Xbomb;
709     lev.android_array[Xbomb_pause]      = Xbomb;
710     lev.android_array[Xbomb_fall]       = Xbomb;
711     lev.android_array[Ybomb_sB]         = Xbomb;
712     lev.android_array[Ybomb_eB]         = Xbomb;
713     lev.android_array[Ybomb_wB]         = Xbomb;
714   }
715
716   if (temp & 16)
717   {
718     lev.android_array[Xnut]             = Xnut;
719     lev.android_array[Xnut_pause]       = Xnut;
720     lev.android_array[Xnut_fall]        = Xnut;
721     lev.android_array[Ynut_sB]          = Xnut;
722     lev.android_array[Ynut_eB]          = Xnut;
723     lev.android_array[Ynut_wB]          = Xnut;
724   }
725
726   if (temp & 32)
727   {
728     lev.android_array[Xtank_n]          = Xtank_n;
729     lev.android_array[Xtank_gon]        = Xtank_n;
730     lev.android_array[Ytank_nB]         = Xtank_n;
731     lev.android_array[Ytank_n_e]        = Xtank_n;
732     lev.android_array[Ytank_n_w]        = Xtank_n;
733
734     lev.android_array[Xtank_e]          = Xtank_e;
735     lev.android_array[Xtank_goe]        = Xtank_e;
736     lev.android_array[Ytank_eB]         = Xtank_e;
737     lev.android_array[Ytank_e_s]        = Xtank_e;
738     lev.android_array[Ytank_e_n]        = Xtank_e;
739
740     lev.android_array[Xtank_s]          = Xtank_s;
741     lev.android_array[Xtank_gos]        = Xtank_s;
742     lev.android_array[Ytank_sB]         = Xtank_s;
743     lev.android_array[Ytank_s_w]        = Xtank_s;
744     lev.android_array[Ytank_s_e]        = Xtank_s;
745
746     lev.android_array[Xtank_w]          = Xtank_w;
747     lev.android_array[Xtank_gow]        = Xtank_w;
748     lev.android_array[Ytank_wB]         = Xtank_w;
749     lev.android_array[Ytank_w_n]        = Xtank_w;
750     lev.android_array[Ytank_w_s]        = Xtank_w;
751   }
752
753   if (temp & 64)
754   {
755     lev.android_array[Xeater_n]         = Xeater_n;
756     lev.android_array[Yeater_nB]        = Xeater_n;
757
758     lev.android_array[Xeater_e]         = Xeater_e;
759     lev.android_array[Yeater_eB]        = Xeater_e;
760
761     lev.android_array[Xeater_s]         = Xeater_s;
762     lev.android_array[Yeater_sB]        = Xeater_s;
763
764     lev.android_array[Xeater_w]         = Xeater_w;
765     lev.android_array[Yeater_wB]        = Xeater_w;
766   }
767
768   if (temp & 128)
769   {
770     lev.android_array[Xbug_n]           = Xbug_gon;
771     lev.android_array[Xbug_gon]         = Xbug_gon;
772     lev.android_array[Ybug_nB]          = Xbug_gon;
773     lev.android_array[Ybug_n_e]         = Xbug_gon;
774     lev.android_array[Ybug_n_w]         = Xbug_gon;
775
776     lev.android_array[Xbug_e]           = Xbug_goe;
777     lev.android_array[Xbug_goe]         = Xbug_goe;
778     lev.android_array[Ybug_eB]          = Xbug_goe;
779     lev.android_array[Ybug_e_s]         = Xbug_goe;
780     lev.android_array[Ybug_e_n]         = Xbug_goe;
781
782     lev.android_array[Xbug_s]           = Xbug_gos;
783     lev.android_array[Xbug_gos]         = Xbug_gos;
784     lev.android_array[Ybug_sB]          = Xbug_gos;
785     lev.android_array[Ybug_s_w]         = Xbug_gos;
786     lev.android_array[Ybug_s_e]         = Xbug_gos;
787
788     lev.android_array[Xbug_w]           = Xbug_gow;
789     lev.android_array[Xbug_gow]         = Xbug_gow;
790     lev.android_array[Ybug_wB]          = Xbug_gow;
791     lev.android_array[Ybug_w_n]         = Xbug_gow;
792     lev.android_array[Ybug_w_s]         = Xbug_gow;
793   }
794
795   if (temp & 256)
796   {
797     lev.android_array[Xalien]           = Xalien;
798     lev.android_array[Xalien_pause]     = Xalien;
799     lev.android_array[Yalien_nB]        = Xalien;
800     lev.android_array[Yalien_eB]        = Xalien;
801     lev.android_array[Yalien_sB]        = Xalien;
802     lev.android_array[Yalien_wB]        = Xalien;
803   }
804
805   if (temp & 512)
806   {
807     lev.android_array[Xspring]          = Xspring;
808     lev.android_array[Xspring_pause]    = Xspring;
809     lev.android_array[Xspring_e]        = Xspring;
810     lev.android_array[Yspring_eB]       = Xspring;
811     lev.android_array[Yspring_kill_eB]  = Xspring;
812     lev.android_array[Xspring_w]        = Xspring;
813     lev.android_array[Yspring_wB]       = Xspring;
814     lev.android_array[Yspring_kill_wB]  = Xspring;
815     lev.android_array[Xspring_fall]     = Xspring;
816     lev.android_array[Yspring_sB]       = Xspring;
817   }
818
819   if (temp & 1024)
820   {
821     lev.android_array[Yballoon_nB]      = Xballoon;
822     lev.android_array[Yballoon_eB]      = Xballoon;
823     lev.android_array[Yballoon_sB]      = Xballoon;
824     lev.android_array[Yballoon_wB]      = Xballoon;
825     lev.android_array[Xballoon]         = Xballoon;
826   }
827
828   if (temp & 2048)
829   {
830     lev.android_array[Xdripper]         = Xdrip_eat;
831     lev.android_array[XdripperB]        = Xdrip_eat;
832     lev.android_array[Xamoeba_1]        = Xdrip_eat;
833     lev.android_array[Xamoeba_2]        = Xdrip_eat;
834     lev.android_array[Xamoeba_3]        = Xdrip_eat;
835     lev.android_array[Xamoeba_4]        = Xdrip_eat;
836     lev.android_array[Xamoeba_5]        = Xdrip_eat;
837     lev.android_array[Xamoeba_6]        = Xdrip_eat;
838     lev.android_array[Xamoeba_7]        = Xdrip_eat;
839     lev.android_array[Xamoeba_8]        = Xdrip_eat;
840   }
841
842   if (temp & 4096)
843   {
844     lev.android_array[Xdynamite]        = Xdynamite;
845   }
846
847   for (temp = 1; temp < 2047; temp++)
848   {
849     switch (src[temp])
850     {
851       case 0x24:                                /* wonderwall */
852         lev.wonderwall_state_initial = 1;
853         lev.wonderwall_time_initial = 9999;
854         break;
855
856       case 0x28:                                /* wheel */
857         lev.wheel_x_initial = temp & 63;
858         lev.wheel_y_initial = temp >> 6;
859         lev.wheel_cnt_initial = lev.wheel_time;
860         break;
861
862 #ifndef BAD_ROLL
863       case 0x63:                                /* spring roll left */
864         src[temp - 1] = 0x45;
865         src[temp] = 0x80;
866         break;
867
868       case 0x64:                                /* spring roll right */
869         src[temp + 1] = 0x45;
870         src[temp] = 0x80;
871         break;
872
873       case 0x72:                                /* nut roll left */
874         src[temp - 1] = 0x25;
875         src[temp] = 0x80;
876         break;
877
878       case 0x73:                                /* nut roll right */
879         src[temp + 1] = 0x25;
880         src[temp] = 0x80;
881         break;
882
883       case 0x77:                                /* bomb roll left */
884         src[temp - 1] = 0x10;
885         src[temp] = 0x80;
886         break;
887
888       case 0x78:                                /* bomb roll right */
889         src[temp + 1] = 0x10;
890         src[temp] = 0x80;
891         break;
892
893       case 0x79:                                /* stone roll left */
894         src[temp - 1] = 0x00;
895         src[temp] = 0x80;
896         break;
897
898       case 0x7A:                                /* stone roll right */
899         src[temp + 1] = 0x00;
900         src[temp] = 0x80;
901         break;
902 #endif
903
904       case 0xA3:                                /* fake blank */
905         lev.lenses_cnt_initial = 9999;
906         break;
907
908       case 0xA4:                                /* fake grass */
909         lev.magnify_cnt_initial = 9999;
910         break;
911     }
912   }
913
914   /* first fill the complete playfield with the default border element */
915   for (y = 0; y < HEIGHT; y++)
916     for (x = 0; x < WIDTH; x++)
917       native_em_level.cave[x][y] = ZBORDER;
918
919   /* then copy the real level contents from level file into the playfield */
920   temp = 0;
921   for (y = 0; y < lev.height; y++)
922     for (x = 0; x < lev.width; x++)
923       native_em_level.cave[x + 1][y + 1] =
924         get_em_element(src[temp++], file_version);
925
926   /* at last, set the two players at their positions in the playfield */
927   /* (native EM[C] levels always have exactly two players in a level) */
928 #if 1
929   for (i = 0; i < 2; i++)
930     native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
931 #else
932   for (i = 0; i < 2; i++)
933     if (ply[i].alive_initial)
934       native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
935 #endif
936
937   native_em_level.file_version = file_version;
938 }
939
940 void prepare_em_level(void)
941 {
942   int i, x, y;
943   int players_left;
944   int num_tape_players;
945
946   /* reset all runtime variables to their initial values */
947
948   for (y = 0; y < HEIGHT; y++)
949     for (x = 0; x < WIDTH; x++)
950       Cave[y][x] = native_em_level.cave[x][y];
951
952   for (y = 0; y < HEIGHT; y++)
953     for (x = 0; x < WIDTH; x++)
954       Next[y][x] = Cave[y][x];
955
956   for (y = 0; y < HEIGHT; y++)
957     for (x = 0; x < WIDTH; x++)
958       Draw[y][x] = Cave[y][x];
959
960 #if 1
961   lev.time_initial = lev.time_seconds;
962 #else
963   lev.time_initial = (lev.time_seconds * 50 + 7) / 8;
964 #endif
965   lev.time = lev.time_initial;
966
967   lev.required = lev.required_initial;
968   lev.score = 0;
969
970   lev.android_move_cnt  = lev.android_move_time;
971   lev.android_clone_cnt = lev.android_clone_time;
972
973   lev.ball_pos = 0;
974   lev.ball_state = lev.ball_state_initial;
975   lev.ball_cnt = lev.ball_time;
976
977   lev.eater_pos = 0;
978   lev.shine_cnt = 0;
979
980   lev.lenses_cnt = lev.lenses_cnt_initial;
981   lev.magnify_cnt = lev.magnify_cnt_initial;
982
983   lev.wheel_cnt = lev.wheel_cnt_initial;
984   lev.wheel_x   = lev.wheel_x_initial;
985   lev.wheel_y   = lev.wheel_y_initial;
986
987   lev.wind_direction = lev.wind_direction_initial;
988   lev.wind_cnt       = lev.wind_cnt_initial;
989
990   lev.wonderwall_state = lev.wonderwall_state_initial;
991   lev.wonderwall_time  = lev.wonderwall_time_initial;
992
993   lev.killed_out_of_time = FALSE;
994
995   /* determine number of players in this level */
996   lev.home_initial = 0;
997
998   for (i = 0; i < MAX_PLAYERS; i++)
999   {
1000     ply[i].exists = 0;
1001     ply[i].alive_initial = FALSE;
1002
1003     if (ply[i].x_initial > 0 && ply[i].y_initial > 0)
1004     {
1005       ply[i].exists = 1;
1006
1007       lev.home_initial++;
1008     }
1009   }
1010
1011   num_tape_players = getNumActivePlayers_EM();
1012
1013   if (num_tape_players != -1)
1014     lev.home_initial = MIN(lev.home_initial, num_tape_players);
1015   else if (!setup.team_mode)
1016     lev.home_initial = MIN(lev.home_initial, 1);
1017
1018   lev.home = lev.home_initial;
1019   players_left = lev.home_initial;
1020
1021   for (i = 0; i < MAX_PLAYERS; i++)
1022   {
1023     if (ply[i].exists)
1024     {
1025       if (players_left)
1026       {
1027         ply[i].alive_initial = TRUE;
1028         players_left--;
1029       }
1030       else
1031       {
1032         int x = ply[i].x_initial;
1033         int y = ply[i].y_initial;
1034
1035         native_em_level.cave[x][y] = Xblank;
1036
1037         Cave[y][x] = Next[y][x] = Draw[y][x] = Xblank;
1038       }
1039     }
1040   }
1041
1042   for (i = 0; i < MAX_PLAYERS; i++)
1043   {
1044     ply[i].num = i;
1045     ply[i].alive = ply[i].alive_initial;
1046     ply[i].dynamite = 0;
1047     ply[i].dynamite_cnt = 0;
1048     ply[i].keys = 0;
1049     ply[i].anim = 0;
1050     ply[i].oldx = ply[i].x = ply[i].x_initial;
1051     ply[i].oldy = ply[i].y = ply[i].y_initial;
1052     ply[i].last_move_dir = MV_NONE;
1053     ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
1054     ply[i].joy_snap  = ply[i].joy_drop = 0;
1055     ply[i].joy_stick = ply[i].joy_spin = 0;
1056
1057 #if 0
1058     printf("player %d: x/y == %d/%d, alive == %d\n",
1059            i, ply[i].x_initial, ply[i].y_initial, ply[i].alive);
1060 #endif
1061   }
1062
1063   game_em.any_player_moving = FALSE;
1064   game_em.last_moving_player = 0;       /* default: first player */
1065
1066   for (i = 0; i < MAX_PLAYERS; i++)
1067     game_em.last_player_direction[i] = MV_NONE;
1068 }