3 * handle binary emc cave file format
9 /* convert emc caves to intermediate cave format.
11 * the intermediate format supports most emc caves, but some internal
12 * objects are not supported.
15 * - active objects - use global flags instead of individual on/off
16 * - falling or paused objects - become still objects
17 * - sand states - become either sand with/without stone
18 * - collected objects - become a common pause object
19 * - drip states - become a normal drip
22 * - exploding objects (not in emc player either)
24 * pushed objects are supported in the cave, eaters and magic ball.
25 * they behave almost the same as in the emc player, pushing over
26 * steel wall, androids, players etc. a compile time option chooses
27 * if pushed objects go into the acid.
29 * acid is handled completely different in my player. acid top is a
30 * separate object, which can be put anywhere and the beasts will
31 * be gobbled, even if they go in from below. in the emc player, an
32 * acid top without a bottom becomes plant.
34 * borderless caves are supported, almost the same as in the emc
35 * player. going off the left edge of the screen resulted in the
36 * beast/player moving up 1 square (and the player disappeared).
37 * going off the right edge of the screen, the beast/player would
38 * go down 1 square. in my player, everything stays on the same y
39 * coord, which is sensible, but breaks caves which expect the old
43 #define GET_BE16(x) ((&x)[0] << 8 | (&x)[1])
44 #define PUT_BE16(x, y) {(&x)[0] = (y) >> 8; (&x)[1] = (y) & 0xff;}
46 static const short map_emc[256] =
48 Xstone, Xstone, Xdiamond, Xdiamond,
49 Xalien, Xalien, Xblank, Xblank,
50 Xtank_1_n, Xtank_1_e, Xtank_1_s, Xtank_1_w,
51 Xtank_2_n, Xtank_2_e, Xtank_2_s, Xtank_2_w,
53 Xbomb, Xbomb, Xemerald, Xemerald,
54 Xbug_1_n, Xbug_1_e, Xbug_1_s, Xbug_1_w,
55 Xbug_2_n, Xbug_2_e, Xbug_2_s, Xbug_2_w,
56 Xdrip, Xdrip, Xdrip, Xdrip,
58 Xstone, Xbomb, Xdiamond, Xemerald,
59 Xwonderwall, Xnut, Xnut, Xnut,
60 Xwheel, Xeater_n, Xeater_s, Xeater_w,
61 Xeater_e, Xsand_stone, Xblank, Xblank,
63 Xblank, Xsand, Xsand, Xsand,
64 Xsand_stone, Xsand_stone, Xsand_stone, Xsand,
65 Xstone, Xslide_ew, Xslide_ns, Xdynamite_1,
66 Xdynamite_2, Xdynamite_3, Xdynamite_4, Xacid_s,
68 Xexit_1, Xexit_2, Xexit_3, Xballoon,
69 Xplant, Xspring, Xspring_fall, Xspring_w,
70 Xspring_e, Xball_1, Xball_2, Xandroid,
71 Xblank, Xandroid, Xandroid, Xandroid,
73 Xandroid, Xandroid, Xandroid, Xandroid,
74 Xandroid, Xblank, Xblank, Xblank,
75 Xblank, Xblank, Xblank, Xblank,
76 Xblank, Xblank, Xblank, Xblank,
78 Xblank, Xblank, Xblank, Xpush_spring_w,
79 Xpush_spring_e, Xacid_1, Xacid_2, Xacid_3,
80 Xacid_4, Xacid_5, Xacid_6, Xacid_7,
81 Xacid_8, Xblank, Xblank, Xblank,
83 Xblank, Xblank, Xpush_nut_w, Xpush_nut_e,
84 Xsteel_1, Xblank, Xblank, Xpush_bomb_w,
85 Xpush_bomb_e, Xpush_stone_w, Xpush_stone_e, Xblank,
86 Xblank, Xblank, Xblank, Xblank,
88 Xblank, Xroundwall_1, Xgrass, Xsteel_1,
89 Xwall_1, Xkey_1, Xkey_2, Xkey_3,
90 Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3,
91 Xdoor_4, Xfake_amoeba, Xfake_door_1, Xfake_door_2,
93 Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel,
94 Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
95 Xacid_se, Xfake_blank, Xamoeba_1, Xamoeba_2,
96 Xamoeba_3, Xamoeba_4, Xexit, Xalpha_arrow_w,
98 Xfake_grass, Xlenses, Xmagnify, Xfake_blank,
99 Xfake_grass, Xswitch, Xswitch, Xblank,
100 Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5,
101 Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
103 Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2,
104 Xroundwall_2, Xdecor_2, Xdecor_4, Xdecor_3,
105 Xwind_any, Xwind_e, Xwind_s, Xwind_w,
106 Xwind_n, Xdirt, Xplant, Xkey_5,
108 Xkey_6, Xkey_7, Xkey_8, Xdoor_5,
109 Xdoor_6, Xdoor_7, Xdoor_8, Xbumper,
110 Xalpha_a, Xalpha_b, Xalpha_c, Xalpha_d,
111 Xalpha_e, Xalpha_f, Xalpha_g, Xalpha_h,
113 Xalpha_i, Xalpha_j, Xalpha_k, Xalpha_l,
114 Xalpha_m, Xalpha_n, Xalpha_o, Xalpha_p,
115 Xalpha_q, Xalpha_r, Xalpha_s, Xalpha_t,
116 Xalpha_u, Xalpha_v, Xalpha_w, Xalpha_x,
118 Xalpha_y, Xalpha_z, Xalpha_0, Xalpha_1,
119 Xalpha_2, Xalpha_3, Xalpha_4, Xalpha_5,
120 Xalpha_6, Xalpha_7, Xalpha_8, Xalpha_9,
121 Xalpha_perio, Xalpha_excla, Xalpha_colon, Xalpha_quest,
123 Xalpha_arrow_e, Xdecor_1, Xfake_door_5, Xfake_door_6,
124 Xfake_door_7, Xfake_door_8, Xblank, Xblank,
125 Xblank, Xblank, Xblank, Xblank,
126 Xblank, Xblank, Xalpha_copyr, Xfake_acid_1
129 static void init_android_clone_table(short android_clone_bits)
131 boolean android_emerald = (android_clone_bits & 1) != 0;
132 boolean android_diamond = (android_clone_bits & 2) != 0;
133 boolean android_stone = (android_clone_bits & 4) != 0;
134 boolean android_bomb = (android_clone_bits & 8) != 0;
135 boolean android_nut = (android_clone_bits & 16) != 0;
136 boolean android_tank = (android_clone_bits & 32) != 0;
137 boolean android_eater = (android_clone_bits & 64) != 0;
138 boolean android_bug = (android_clone_bits & 128) != 0;
139 boolean android_alien = (android_clone_bits & 256) != 0;
140 boolean android_spring = (android_clone_bits & 512) != 0;
141 boolean android_balloon = (android_clone_bits & 1024) != 0;
142 boolean android_amoeba = (android_clone_bits & 2048) != 0;
143 boolean android_dynamite = (android_clone_bits & 4096) != 0;
146 for (i = 0; i < TILE_MAX; i++)
147 lev.android_array[i] = Xblank;
151 lev.android_array[Xeater_n] = Xeater_n;
152 lev.android_array[Yeater_nB] = Xeater_n;
154 lev.android_array[Xeater_e] = Xeater_e;
155 lev.android_array[Yeater_eB] = Xeater_e;
157 lev.android_array[Xeater_s] = Xeater_s;
158 lev.android_array[Yeater_sB] = Xeater_s;
160 lev.android_array[Xeater_w] = Xeater_w;
161 lev.android_array[Yeater_wB] = Xeater_w;
166 lev.android_array[Xalien] = Xalien;
167 lev.android_array[Xalien_pause] = Xalien;
168 lev.android_array[Yalien_nB] = Xalien;
169 lev.android_array[Yalien_eB] = Xalien;
170 lev.android_array[Yalien_sB] = Xalien;
171 lev.android_array[Yalien_wB] = Xalien;
176 lev.android_array[Xbug_1_n] = Xbug_2_n;
177 lev.android_array[Xbug_2_n] = Xbug_2_n;
178 lev.android_array[Ybug_nB] = Xbug_2_n;
179 lev.android_array[Ybug_n_e] = Xbug_2_n;
180 lev.android_array[Ybug_n_w] = Xbug_2_n;
182 lev.android_array[Xbug_1_e] = Xbug_2_e;
183 lev.android_array[Xbug_2_e] = Xbug_2_e;
184 lev.android_array[Ybug_eB] = Xbug_2_e;
185 lev.android_array[Ybug_e_s] = Xbug_2_e;
186 lev.android_array[Ybug_e_n] = Xbug_2_e;
188 lev.android_array[Xbug_1_s] = Xbug_2_s;
189 lev.android_array[Xbug_2_s] = Xbug_2_s;
190 lev.android_array[Ybug_sB] = Xbug_2_s;
191 lev.android_array[Ybug_s_w] = Xbug_2_s;
192 lev.android_array[Ybug_s_e] = Xbug_2_s;
194 lev.android_array[Xbug_1_w] = Xbug_2_w;
195 lev.android_array[Xbug_2_w] = Xbug_2_w;
196 lev.android_array[Ybug_wB] = Xbug_2_w;
197 lev.android_array[Ybug_w_n] = Xbug_2_w;
198 lev.android_array[Ybug_w_s] = Xbug_2_w;
203 lev.android_array[Xtank_1_n] = Xtank_1_n;
204 lev.android_array[Xtank_2_n] = Xtank_1_n;
205 lev.android_array[Ytank_nB] = Xtank_1_n;
206 lev.android_array[Ytank_n_e] = Xtank_1_n;
207 lev.android_array[Ytank_n_w] = Xtank_1_n;
209 lev.android_array[Xtank_1_e] = Xtank_1_e;
210 lev.android_array[Xtank_2_e] = Xtank_1_e;
211 lev.android_array[Ytank_eB] = Xtank_1_e;
212 lev.android_array[Ytank_e_s] = Xtank_1_e;
213 lev.android_array[Ytank_e_n] = Xtank_1_e;
215 lev.android_array[Xtank_1_s] = Xtank_1_s;
216 lev.android_array[Xtank_2_s] = Xtank_1_s;
217 lev.android_array[Ytank_sB] = Xtank_1_s;
218 lev.android_array[Ytank_s_w] = Xtank_1_s;
219 lev.android_array[Ytank_s_e] = Xtank_1_s;
221 lev.android_array[Xtank_1_w] = Xtank_1_w;
222 lev.android_array[Xtank_2_w] = Xtank_1_w;
223 lev.android_array[Ytank_wB] = Xtank_1_w;
224 lev.android_array[Ytank_w_n] = Xtank_1_w;
225 lev.android_array[Ytank_w_s] = Xtank_1_w;
230 lev.android_array[Xemerald] = Xemerald;
231 lev.android_array[Xemerald_pause] = Xemerald;
232 lev.android_array[Xemerald_fall] = Xemerald;
233 lev.android_array[Yemerald_sB] = Xemerald;
234 lev.android_array[Yemerald_eB] = Xemerald;
235 lev.android_array[Yemerald_wB] = Xemerald;
240 lev.android_array[Xdiamond] = Xdiamond;
241 lev.android_array[Xdiamond_pause] = Xdiamond;
242 lev.android_array[Xdiamond_fall] = Xdiamond;
243 lev.android_array[Ydiamond_sB] = Xdiamond;
244 lev.android_array[Ydiamond_eB] = Xdiamond;
245 lev.android_array[Ydiamond_wB] = Xdiamond;
250 lev.android_array[Xstone] = Xstone;
251 lev.android_array[Xstone_pause] = Xstone;
252 lev.android_array[Xstone_fall] = Xstone;
253 lev.android_array[Ystone_sB] = Xstone;
254 lev.android_array[Ystone_eB] = Xstone;
255 lev.android_array[Ystone_wB] = Xstone;
260 lev.android_array[Xbomb] = Xbomb;
261 lev.android_array[Xbomb_pause] = Xbomb;
262 lev.android_array[Xbomb_fall] = Xbomb;
263 lev.android_array[Ybomb_sB] = Xbomb;
264 lev.android_array[Ybomb_eB] = Xbomb;
265 lev.android_array[Ybomb_wB] = Xbomb;
270 lev.android_array[Xnut] = Xnut;
271 lev.android_array[Xnut_pause] = Xnut;
272 lev.android_array[Xnut_fall] = Xnut;
273 lev.android_array[Ynut_sB] = Xnut;
274 lev.android_array[Ynut_eB] = Xnut;
275 lev.android_array[Ynut_wB] = Xnut;
280 lev.android_array[Xspring] = Xspring;
281 lev.android_array[Xspring_pause] = Xspring;
282 lev.android_array[Xspring_fall] = Xspring;
283 lev.android_array[Xspring_e] = Xspring;
284 lev.android_array[Xspring_w] = Xspring;
285 lev.android_array[Yspring_sB] = Xspring;
286 lev.android_array[Yspring_eB] = Xspring;
287 lev.android_array[Yspring_wB] = Xspring;
288 lev.android_array[Yspring_alien_eB] = Xspring;
289 lev.android_array[Yspring_alien_wB] = Xspring;
292 if (android_dynamite)
294 lev.android_array[Xdynamite] = Xdynamite;
299 lev.android_array[Xballoon] = Xballoon;
300 lev.android_array[Yballoon_nB] = Xballoon;
301 lev.android_array[Yballoon_eB] = Xballoon;
302 lev.android_array[Yballoon_sB] = Xballoon;
303 lev.android_array[Yballoon_wB] = Xballoon;
308 lev.android_array[Xfake_amoeba] = Xdrip;
309 lev.android_array[Yfake_amoeba] = Xdrip;
310 lev.android_array[Xamoeba_1] = Xdrip;
311 lev.android_array[Xamoeba_2] = Xdrip;
312 lev.android_array[Xamoeba_3] = Xdrip;
313 lev.android_array[Xamoeba_4] = Xdrip;
314 lev.android_array[Xamoeba_5] = Xdrip;
315 lev.android_array[Xamoeba_6] = Xdrip;
316 lev.android_array[Xamoeba_7] = Xdrip;
317 lev.android_array[Xamoeba_8] = Xdrip;
321 void convert_em_level(unsigned char *src, int file_version)
323 static int eater_offset[8] =
325 2048, 2057, 2066, 2075,
326 2112, 2121, 2130, 2139
330 /* common to all emc caves */
332 lev.time_seconds = GET_BE16(src[2110]);
333 if (lev.time_seconds > 9999)
334 lev.time_seconds = 9999;
336 lev.required_initial = src[2095];
340 lev.emerald_score = src[2084];
341 lev.diamond_score = src[2085];
342 lev.alien_score = src[2086];
343 lev.tank_score = src[2087];
344 lev.bug_score = src[2088];
345 lev.eater_score = src[2089];
346 lev.nut_score = src[2090];
347 lev.dynamite_score = src[2091];
348 lev.key_score = src[2092];
349 lev.exit_score = src[2093] * 8 / 5;
351 lev.lenses_score = src[2151];
352 lev.magnify_score = src[2152];
353 lev.slurp_score = src[2153];
357 lev.android_move_time = GET_BE16(src[2164]);
358 lev.android_clone_time = GET_BE16(src[2166]);
359 lev.ball_time = GET_BE16(src[2160]);
361 lev.lenses_time = GET_BE16(src[2154]);
362 lev.magnify_time = GET_BE16(src[2156]);
363 lev.wheel_time = GET_BE16(src[2104]);
365 temp = GET_BE16(src[2100]) * 28;
368 lev.amoeba_time = temp;
370 lev.wonderwall_time_initial = GET_BE16(src[2102]);
372 lev.wind_cnt_initial = src[2149] & 15 ? lev.wind_time : 0;
374 lev.wind_direction_initial = (temp & 8 ? 0 :
380 lev.ball_random = src[2162] & 1 ? 1 : 0;
381 lev.ball_state_initial = src[2162] & 128 ? 1 : 0;
383 for (temp = 1; temp < 2047; temp++)
387 case 36: /* wonderwall */
388 lev.wonderwall_state_initial = 1;
389 lev.wonderwall_time_initial = 9999;
393 lev.wheel_x_initial = temp & 63;
394 lev.wheel_y_initial = temp >> 6;
395 lev.wheel_cnt_initial = lev.wheel_time;
398 case 163: /* fake blank */
399 lev.lenses_cnt_initial = 9999;
402 case 164: /* fake grass */
403 lev.magnify_cnt_initial = 9999;
410 temp = GET_BE16(src[2168]);
412 init_android_clone_table(temp);
416 for (i = 0; i < 8; i++)
417 for (x = 0; x < 9; x++)
418 lev.eater_array[i][x] = map_emc[src[eater_offset[i] + x]];
422 temp = map_emc[src[2159]];
424 for (y = 0; y < 8; y++)
428 for (x = 0; x < 8; x++)
429 lev.ball_array[y][x] = temp;
433 lev.ball_array[y][1] = (src[2163] & 1) ? temp : Xblank; /* north */
434 lev.ball_array[y][6] = (src[2163] & 2) ? temp : Xblank; /* south */
435 lev.ball_array[y][3] = (src[2163] & 4) ? temp : Xblank; /* west */
436 lev.ball_array[y][4] = (src[2163] & 8) ? temp : Xblank; /* east */
437 lev.ball_array[y][7] = (src[2163] & 16) ? temp : Xblank; /* southeast */
438 lev.ball_array[y][5] = (src[2163] & 32) ? temp : Xblank; /* southwest */
439 lev.ball_array[y][2] = (src[2163] & 64) ? temp : Xblank; /* northeast */
440 lev.ball_array[y][0] = (src[2163] & 128)? temp : Xblank; /* northwest */
446 for (i = 0; i < 2; i++)
448 temp = GET_BE16(src[2096 + i * 2]);
450 ply[i].x_initial = (temp & 63);
451 ply[i].y_initial = (temp >> 6 & 31);
456 /* first fill the complete playfield with the default border element */
457 for (y = 0; y < CAVE_HEIGHT; y++)
458 for (x = 0; x < CAVE_WIDTH; x++)
459 native_em_level.cave[x][y] = Zborder;
461 /* then copy the real level contents from level file into the playfield */
463 for (y = 0; y < lev.height; y++)
464 for (x = 0; x < lev.width; x++)
465 native_em_level.cave[x][y] = map_emc[src[temp++]];
467 /* at last, set the two players at their positions in the playfield */
468 /* (native EM[C] levels always have exactly two players in a level) */
469 for (i = 0; i < 2; i++)
470 native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
472 native_em_level.file_version = file_version;
476 /* convert all emerald mine caves to emc version 6 cave format.
478 * caves are filtered to get rid of invalid or unsupported tiles.
480 * although the result is a somewhat clean cave, it is meant only
481 * to give a common structure for the binary cave format. it is not
482 * for archiving purposes (it is better to keep the raw cave as-is)
483 * and it is not meant for serializing (the intermediate structure
484 * is better defined).
486 * acid top is added to acid bottom in both the cave and the eaters.
487 * fake acid (only in v4) does not exist because it adds nothing to
488 * the game, and is different even in different versions of the emc
491 * v4/v5 time is converted to 10x old time (as it should be).
492 * the reason the kingsoft player used 5x time was copy protection.
494 * note: emc v6 converter has an error in converting v4 eaters to the
495 * wrong bug(24 instead of 20) and tank(12 instead of 8).
498 /* changes for game engine integration in Rocks'n'Diamonds:
500 * cave versions below V5 had no grass, but only sand/dirt
501 * - object code 130 (V6 grass) is changed to 189 (V6 dirt)
502 * - object codes are changed in both cave and eater arrays
503 * - only graphical change, as both objects behave the same
506 static const unsigned char map_v6[256] =
510 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
511 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
512 0,16,2,18, 36,37,37,37, 40,41,42,43, 44,45,128,128,
513 128,148,148, 148,45,45,45, 148,0,57,58, 59,60,61,62,63,
515 64,65,66,67, 68,69,69,71, 72,73,74,75, 118,75,75,75,
516 75,75,75,75, 75,153,153,153, 153,153,153,153, 153,153,153,153,
517 153,153,153,99, 100,68,68,68, 68,68,68,68, 68,118,118,118,
518 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
520 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
521 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
522 160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
523 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
525 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
526 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
527 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
528 240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
531 static const unsigned char map_v5[256] =
535 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
536 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
537 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
538 128,148,148,148, 45,45,45,148, 0,57,58,59, 60,61,62,63,
540 64,65,66,67, 68,153,153,153, 153,153,153,153, 153,153,153,153,
541 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
542 153,153,153,153, 153,68,68,68, 68,68,68,68, 68,118,118,118,
543 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
545 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
546 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
547 160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
548 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
550 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
551 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
552 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
553 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
556 static const unsigned char map_v4[256] =
560 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
561 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
562 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
563 128,148,148,148, 45,45,45,148, 0,153,153,59, 60,61,62,63,
565 64,65,66,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
566 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
567 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
568 153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
570 128,129,189,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
571 144,145,146,147, 148,149,150,151, 152,68,154,155, 156,157,158,160,
572 160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
573 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
575 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
576 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
577 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
578 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
581 static const unsigned char map_v4_eater[32] =
583 /* filter for v4 eater */
585 128,18,2,0, 4,8,16,20, 28,37,41,45, 189,129,131,132,
586 133,134,135,136, 146,147,175,65, 66,64,2,18, 128,128,128,128
589 static boolean filename_has_v1_format(char *filename)
591 char *basename = getBaseNamePtr(filename);
593 return (strlen(basename) == 3 &&
594 basename[0] == 'a' &&
595 basename[1] >= 'a' && basename[1] <= 'k' &&
596 basename[2] >= '0' && basename[2] <= '9');
599 int cleanup_em_level(unsigned char *src, int length, char *filename)
601 int file_version = FILE_VERSION_EM_UNKNOWN;
604 if (length >= 2172 &&
605 src[2106] == 255 && /* version id: */
606 src[2107] == 54 && /* '6' */
607 src[2108] == 48 && /* '0' */
608 src[2109] == 48) /* '0' */
610 /* ---------- this cave has V6 file format ---------- */
611 file_version = FILE_VERSION_EM_V6;
613 /* remap elements to internal EMC level format */
614 for (i = 0; i < 2048; i++)
615 src[i] = map_v6[src[i]];
616 for (i = 2048; i < 2084; i++)
617 src[i] = map_v6[src[i]];
618 for (i = 2112; i < 2148; i++)
619 src[i] = map_v6[src[i]];
621 else if (length >= 2110 &&
622 src[2106] == 255 && /* version id: */
623 src[2107] == 53 && /* '5' */
624 src[2108] == 48 && /* '0' */
625 src[2109] == 48) /* '0' */
627 /* ---------- this cave has V5 file format ---------- */
628 file_version = FILE_VERSION_EM_V5;
630 /* remap elements to internal EMC level format */
631 for (i = 0; i < 2048; i++)
632 src[i] = map_v5[src[i]];
633 for (i = 2048; i < 2084; i++)
634 src[i] = map_v5[src[i]];
635 for (i = 2112; i < 2148; i++)
636 src[i] = src[i - 64];
638 else if (length >= 2106 &&
639 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
640 src[1983] == 116 || /* unencrypted (usual case) */
641 src[1983] == 131)) /* unencrypted (rare case) */
643 /* ---------- this cave has V1, V2 or V3 file format ---------- */
645 boolean fix_copyright = FALSE;
648 byte at position 1983 (0x07bf) is used as "magic byte":
649 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
650 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
651 - 131 (0x83) => unencrypted level (happens only in very rare cases)
654 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
656 /* this is original (encrypted) Emerald Mine I, II or III level file */
658 int first_byte = src[0];
659 unsigned char code0 = 0x65;
660 unsigned char code1 = 0x11;
662 /* decode encrypted level data */
663 for (i = 0; i < 2106; i++)
668 code0 = (code0 + 7) & 0xff;
671 src[1] = 131; /* needed for all Emerald Mine levels */
673 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
674 if (first_byte == 0xf5)
676 src[0] = 131; /* only needed for Emerald Mine II levels */
678 fix_copyright = TRUE;
681 /* ---------- this cave has V3 file format ---------- */
682 file_version = FILE_VERSION_EM_V3;
684 else if (filename_has_v1_format(filename))
686 /* ---------- this cave has V1 file format ---------- */
687 file_version = FILE_VERSION_EM_V1;
691 /* ---------- this cave has V2 file format ---------- */
692 file_version = FILE_VERSION_EM_V2;
695 /* remap elements to internal EMC level format */
696 for (i = 0; i < 2048; i++)
697 src[i] = map_v4[src[i]];
698 for (i = 2048; i < 2084; i++)
699 src[i] = map_v4_eater[src[i] >= 28 ? 0 : src[i]];
700 for (i = 2112; i < 2148; i++)
701 src[i] = src[i - 64];
703 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
705 for (i = 0; i < 2048; i++)
707 src[i] = 254; /* replace 'Xdecor_1' with 'Xalpha_copyr' */
712 /* ---------- this cave has unknown file format ---------- */
714 /* if file has length of old-style level file, print (wrong) magic byte */
716 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
719 return FILE_VERSION_EM_UNKNOWN;
722 if (file_version < FILE_VERSION_EM_V6)
725 src[2106] = 255; /* version id: */
726 src[2107] = 54; /* '6' */
727 src[2108] = 48; /* '0' */
728 src[2109] = 48; /* '0' */
732 /* stored level time of levels for the V2 player was changed to 50% of the
733 time for the V1 player (original V3 levels already considered this) */
734 if (file_version != FILE_VERSION_EM_V1 &&
735 file_version != FILE_VERSION_EM_V3)
740 for (i = 2148; i < 2172; i++)
747 /* ---------- at this stage, the cave data always has V6 format ---------- */
750 for (i = 0; i < 2048; i++)
753 for (i++; i < 2048; i++)
758 for (i = 64; i < 2048; i++)
759 if (src[i] == 63) /* replace element above 'Xacid_s' ... */
760 src[i - 64] = 101; /* ... with 'Xacid_1' */
762 /* fix acid with no base beneath it (see below for details (*)) */
763 for (i = 64; i < 2048 - 1; i++)
765 if (file_version <= FILE_VERSION_EM_V2 &&
766 src[i - 64] == 101 && src[i] != 63) /* acid without base */
768 if (src[i - 1] == 101 || /* remove acid over acid row */
770 src[i - 64] = 6; /* replace element above with 'Xblank' */
772 src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
776 /* fix acid in eater 1 */
777 for (i = 2051; i < 2057; i++)
781 /* fix acid in eater 2 */
782 for (i = 2060; i < 2066; i++)
786 /* fix acid in eater 3 */
787 for (i = 2069; i < 2075; i++)
791 /* fix acid in eater 4 */
792 for (i = 2078; i < 2084; i++)
796 /* fix acid in eater 5 */
797 for (i = 2115; i < 2121; i++)
801 /* fix acid in eater 6 */
802 for (i = 2124; i < 2130; i++)
806 /* fix acid in eater 7 */
807 for (i = 2133; i < 2139; i++)
811 /* fix acid in eater 8 */
812 for (i = 2142; i < 2148; i++)
821 src[GET_BE16(src[2096])] = 128;
825 src[GET_BE16(src[2098])] = 128;
828 if (GET_BE16(src[2100]) > 9999)
829 PUT_BE16(src[2100], 9999);
831 /* time wonderwall */
832 if (GET_BE16(src[2102]) > 9999)
833 PUT_BE16(src[2102], 9999);
836 if (GET_BE16(src[2110]) > 9999)
837 PUT_BE16(src[2110], 9999);
846 if (GET_BE16(src[2154]) > 9999)
847 PUT_BE16(src[2154], 9999);
850 if (GET_BE16(src[2156]) > 9999)
851 PUT_BE16(src[2156], 9999);
855 src[2159] = map_v6[src[2159]];
858 if (GET_BE16(src[2160]) > 9999)
859 PUT_BE16(src[2160], 9999);
866 /* android move pause */
867 if (GET_BE16(src[2164]) > 9999)
868 PUT_BE16(src[2164], 9999);
870 /* android clone pause */
871 if (GET_BE16(src[2166]) > 9999)
872 PUT_BE16(src[2166], 9999);
877 /* size of v6 cave */
881 Error(ERR_DEBUG, "EM level file version: %d", file_version);
890 structure of emerald mine level disk files
891 ----------------------------------------------------------------------
893 if(len >= 2172 && (buf[2106] == 255 && buf[2107] == 54 && buf[2108] == 48 && buf[2109] == 48)) // v6
894 if(len >= 2110 && (buf[2106] == 255 && buf[2107] == 53 && buf[2108] == 48 && buf[2109] == 48)) // v5
895 if(len >= 2106 && (buf[1983] == 116 || buf[2047] == 116)) // v4
896 if(len >= 2106 && (buf[1983] == 27 || buf[2047] == 219)) // v3
898 buf[0]=241;buf[1]=248;for(i=0,j=101;i<2106;i++,j+=7)buf[i]=(buf[i]^j)-17; // decrypt
900 number of movements (calls to logic) = time * 50 / 8
902 {} reserved (but some broken levels use them)
904 ----------------------------------------------------------------------
924 2095: emeralds needed
928 2102: wonderwall time
930 2106: ID (0xff363030)
936 2148: flags bit#7=NOI #6=RIS
937 2149: wind direction bit#0=right #1=down #2=left #3=up
938 2150: cave number bit#7=teamwork
947 2162: ball info bit#15=switch state #8=random
948 ; bit#0=N #1=S #2=W #3=E #4=SE #5=SW #6=NE #7=NW
949 2164: android move speed
950 2166: android clone speed
952 ; bit#0=emerald #1=diamond #2=stone #3=bomb #4=nut #5=tank #6=eater
953 ; #7=bug #8=alien #9=spring #10=balloon #11=ameuba #12=dynamite
958 1: stone {stone_fall}
960 3: diamond {diamond_fall}
962 5: alien {alien_pause}
976 19: emerald {emerald_fall}
987 30: blank {drip_stretchB}
988 31: drip {drip_stretch}
989 32: stone {stone_pause}
990 33: bomb {bomb_pause}
991 34: diamond {diamond_pause}
992 35: emerald {emerald_pause}
993 36: wonderwall {wonderwallB}
1003 46: blank {sand_stonein_2}
1004 47: blank {sand_stonein_3}
1005 48: blank {sand_stonein_4}
1006 49: sand {sand_stonesand_2}
1007 50: sand {sand_stonesand_3}
1008 51: sand {sand_stonesand_4}
1009 52: sand_stone {sand_sandstone_2}
1010 53: sand_stone {sand_sandstone_3}
1011 54: sand_stone {sand_sandstone_4}
1012 55: sand {sand_stonesand_4}
1013 56: stone {sand_stoneout_2}
1027 70: spring {spring_fall}
1028 71: spring {spring_w}
1029 72: spring {spring_e}
1034 77: android {android_n_1}
1035 78: android {android_n_2}
1036 79: android {android_s_1}
1037 80: android {android_s_2}
1038 81: android {android_e_1}
1039 82: android {android_e_2}
1040 83: android {android_w_1}
1041 84: android {android_w_2}
1056 99: spring {push_spring_w}
1057 100: spring {push_spring_e}
1066 109: pause {grass_wB}
1067 110: pause {grass_eB}
1068 111: pause {grass_nB}
1069 112: pause {grass_sB}
1070 113: pause {dynamite_blank}
1071 114: nut {push_nut_w}
1072 115: nut {push_nut_e}
1073 116: steel_2 {end of level}
1075 118: pause {emerald_blank}
1076 119: bomb {push_bomb_w}
1077 120: bomb {push_bomb_e}
1078 121: stone {push_stone_w}
1079 122: stone {push_stone_e}
1080 123: pause {diamond_blank}
1081 124: pause {dirt_wB}
1082 125: pause {dirt_eB}
1083 126: pause {dirt_nB}
1084 127: pause {dirt_sB}
1121 163: fake_blank {fake_blankB}
1122 164: fake_grass {fake_grassB}
1124 166: switch {switchB}
1215 ----------------------------------------------------------------------
1231 2091: dynamite value
1235 2095: emeralds needed
1239 2102: wonderwall time
1241 2106: ID (0xff353030)
1245 1: stone {stone_fall}
1247 3: diamond {diamond_fall}
1249 5: alien {alien_pause}
1261 17: bomb {bomb_fall}
1263 19: emerald {emerald_fall}
1273 29: drip {drip_fall}
1274 30: blank {drip_stretchB}
1275 31: drip {drip_stretch}
1276 32: stone {stone_pause}
1277 33: bomb {bomb_pause}
1278 34: diamond {diamond_pause}
1279 35: emerald {emerald_pause}
1280 36: wonderwall {wonderwallB}
1290 46: blank {sand_stonein_2}
1291 47: blank {sand_stonein_3}
1292 48: blank {sand_stonein_4}
1293 49: sand {sand_stonesand_2}
1294 50: sand {sand_stonesand_3}
1295 51: sand {sand_stonesand_4}
1296 52: sand_stone {sand_sandstone_2}
1297 53: sand_stone {sand_sandstone_3}
1298 54: sand_stone {sand_sandstone_4}
1299 55: sand {sand_stonesand_4}
1300 56: stone {sand_stoneout_2}
1353 109: pause {grass_wB}
1354 110: pause {grass_eB}
1355 111: pause {grass_nB}
1356 112: pause {grass_sB}
1357 113: pause {dynamite_blank}
1358 114: nut {push_nut_w}
1359 115: nut {push_nut_e}
1360 116: steel_2 {end of level}
1361 117: dynamite_4 {boom_2}
1362 118: pause {emerald_blank}
1363 119: bomb {push_bomb_w}
1364 120: bomb {push_bomb_e}
1365 121: stone {push_stone_w}
1366 122: stone {push_stone_e}
1367 123: pause {diamond_blank}
1368 124: pause {dirt_wB}
1369 125: pause {dirt_eB}
1370 126: pause {dirt_nB}
1371 127: pause {dirt_sB}
1502 ----------------------------------------------------------------------
1518 2091: dynamite value
1522 2095: emeralds needed
1526 2102: wonderwall time
1556 26: diamond {diamond_shine}
1557 27: emerald {emerald_shine}
1560 1: stone {stone_fall}
1562 3: diamond {diamond_fall}
1564 5: alien {alien_pause}
1576 17: bomb {bomb_fall}
1578 19: emerald {emerald_fall}
1588 29: drip {drip_fall}
1589 30: blank {drip_stretchB}
1590 31: drip {drip_stretch}
1591 32: stone {stone_pause}
1592 33: bomb {bomb_pause}
1593 34: diamond {diamond_pause}
1594 35: emerald {emerald_pause}
1595 36: wonderwall {wonderwallB}
1605 46: blank {sand_stonein_2}
1606 47: blank {sand_stonein_3}
1607 48: blank {sand_stonein_4}
1608 49: sand {sand_stonesand_2}
1609 50: sand {sand_stonesand_3}
1610 51: sand {sand_stonesand_4}
1611 52: sand_stone {sand_sandstone_2}
1612 53: sand_stone {sand_sandstone_3}
1613 54: sand_stone {sand_sandstone_4}
1614 55: sand {sand_stonesand_4}
1615 56: stone {sand_stoneout_2}
1672 113: pause {dynamite_blank}
1673 114: nut {push_nut_w}
1674 115: nut {push_nut_e}
1675 116: steel_1 {end of level}
1676 117: dynamite_4 {boom_2}
1677 118: pause {emerald_blank}
1678 119: bomb {push_bomb_w}
1679 120: bomb {push_bomb_e}
1680 121: stone {push_stone_w}
1681 122: stone {push_stone_e}
1682 123: pause {diamond_blank}
1683 124: pause {dirt_wB}
1684 125: pause {dirt_eB}
1685 126: pause {dirt_nB}
1686 127: pause {dirt_sB}
1719 159: fake_grass {dirt}
1720 160: fake_grass {dirt}
1721 161: fake_grass {dirt}
1722 162: fake_grass {dirt}
1723 163: fake_grass {dirt}
1724 164: fake_grass {dirt}
1725 165: fake_grass {dirt}
1726 166: fake_grass {dirt}
1727 167: fake_grass {dirt}
1728 168: fake_grass {dirt}
1729 169: fake_grass {dirt}
1730 170: fake_grass {dirt}
1731 171: fake_grass {dirt}
1732 172: fake_grass {dirt}
1733 173: fake_grass {dirt}
1734 174: fake_grass {dirt}
1800 240: alpha_arrow_e {}
1801 241: decor_1 {alpha_copyr}
1817 ----------------------------------------------------------------------