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