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