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])
45 static const short map_emc[256] =
47 Cstone, Cstone, Cdiamond, Cdiamond,
48 Calien, Calien, Cblank, Cblank,
49 Ctank_1_n, Ctank_1_e, Ctank_1_s, Ctank_1_w,
50 Ctank_2_n, Ctank_2_e, Ctank_2_s, Ctank_2_w,
52 Cbomb, Cbomb, Cemerald, Cemerald,
53 Cbug_1_n, Cbug_1_e, Cbug_1_s, Cbug_1_w,
54 Cbug_2_n, Cbug_2_e, Cbug_2_s, Cbug_2_w,
55 Cdrip, Cdrip, Cdrip, Cdrip,
57 Cstone, Cbomb, Cdiamond, Cemerald,
58 Cwonderwall, Cnut, Cnut, Cnut,
59 Cwheel, Ceater_n, Ceater_s, Ceater_w,
60 Ceater_e, Csand_stone, Cblank, Cblank,
62 Cblank, Csand, Csand, Csand,
63 Csand_stone, Csand_stone, Csand_stone, Csand,
64 Cstone, Cslide_ew, Cslide_ns, Cdynamite_1,
65 Cdynamite_2, Cdynamite_3, Cdynamite_4, Cacid_s,
67 Cexit_1, Cexit_2, Cexit_3, Cballoon,
68 Cplant, Cspring, Cspring, Cpush_spring_w,
69 Cpush_spring_e, Cball_1, Cball_2, Candroid,
70 Cblank, Candroid, Candroid, Candroid,
72 Candroid, Candroid, Candroid, Candroid,
73 Candroid, Cblank, Cblank, Cblank,
74 Cblank, Cblank, Cblank, Cblank,
75 Cblank, Cblank, Cblank, Cblank,
77 Cblank, Cblank, Cblank, Cpush_spring_w,
78 Cpush_spring_e, Cacid_1, Cacid_2, Cacid_3,
79 Cacid_4, Cacid_5, Cacid_6, Cacid_7,
80 Cacid_8, Cblank, Cblank, Cblank,
82 Cblank, Cblank, Cpush_nut_w, Cpush_nut_e,
83 Csteel_1, Cblank, Cblank, Cpush_bomb_w,
84 Cpush_bomb_e, Cpush_stone_w, Cpush_stone_e, Cblank,
85 Cblank, Cblank, Cblank, Cblank,
87 Cblank, Croundwall_1, Cgrass, Csteel_1,
88 Cwall_1, Ckey_1, Ckey_2, Ckey_3,
89 Ckey_4, Cdoor_1, Cdoor_2, Cdoor_3,
90 Cdoor_4, Cfake_amoeba, Cfake_door_1, Cfake_door_2,
92 Cfake_door_3, Cfake_door_4, Cwonderwall, Cwheel,
93 Csand, Cacid_nw, Cacid_ne, Cacid_sw,
94 Cacid_se, Cfake_blank, Camoeba_1, Camoeba_2,
95 Camoeba_3, Camoeba_4, Cexit, Calpha_arrow_w,
97 Cfake_grass, Clenses, Cmagnify, Cfake_blank,
98 Cfake_grass, Cswitch, Cswitch, Cblank,
99 Cdecor_8, Cdecor_9, Cdecor_10, Cdecor_5,
100 Calpha_comma, Calpha_apost, Calpha_minus, Cdynamite,
102 Csteel_3, Cdecor_6, Cdecor_7, Csteel_2,
103 Croundwall_2, Cdecor_2, Cdecor_4, Cdecor_3,
104 Cwind_any, Cwind_e, Cwind_s, Cwind_w,
105 Cwind_n, Cdirt, Cplant, Ckey_5,
107 Ckey_6, Ckey_7, Ckey_8, Cdoor_5,
108 Cdoor_6, Cdoor_7, Cdoor_8, Cbumper,
109 Calpha_a, Calpha_b, Calpha_c, Calpha_d,
110 Calpha_e, Calpha_f, Calpha_g, Calpha_h,
112 Calpha_i, Calpha_j, Calpha_k, Calpha_l,
113 Calpha_m, Calpha_n, Calpha_o, Calpha_p,
114 Calpha_q, Calpha_r, Calpha_s, Calpha_t,
115 Calpha_u, Calpha_v, Calpha_w, Calpha_x,
117 Calpha_y, Calpha_z, Calpha_0, Calpha_1,
118 Calpha_2, Calpha_3, Calpha_4, Calpha_5,
119 Calpha_6, Calpha_7, Calpha_8, Calpha_9,
120 Calpha_perio, Calpha_excla, Calpha_colon, Calpha_quest,
122 Calpha_arrow_e, Cdecor_1, Cfake_door_5, Cfake_door_6,
123 Cfake_door_7, Cfake_door_8, Cblank, Cblank,
124 Cblank, Cblank, Cblank, Cblank,
125 Cblank, Cblank, Calpha_copyr, Cfake_acid_1
134 android_clone_table[] =
136 { 0, Xemerald, Cemerald },
137 { 0, Xemerald_pause, Cemerald },
138 { 0, Xemerald_fall, Cemerald },
139 { 0, Yemerald_sB, Cemerald },
140 { 0, Yemerald_eB, Cemerald },
141 { 0, Yemerald_wB, Cemerald },
143 { 1, Xdiamond, Cdiamond },
144 { 1, Xdiamond_pause, Cdiamond },
145 { 1, Xdiamond_fall, Cdiamond },
146 { 1, Ydiamond_sB, Cdiamond },
147 { 1, Ydiamond_eB, Cdiamond },
148 { 1, Ydiamond_wB, Cdiamond },
150 { 2, Xstone, Cstone },
151 { 2, Xstone_pause, Cstone },
152 { 2, Xstone_fall, Cstone },
153 { 2, Ystone_sB, Cstone },
154 { 2, Ystone_eB, Cstone },
155 { 2, Ystone_wB, Cstone },
158 { 3, Xbomb_pause, Cbomb },
159 { 3, Xbomb_fall, Cbomb },
160 { 3, Ybomb_sB, Cbomb },
161 { 3, Ybomb_eB, Cbomb },
162 { 3, Ybomb_wB, Cbomb },
165 { 4, Xnut_pause, Cnut },
166 { 4, Xnut_fall, Cnut },
167 { 4, Ynut_sB, Cnut },
168 { 4, Ynut_eB, Cnut },
169 { 4, Ynut_wB, Cnut },
171 { 5, Xtank_1_n, Ctank_1_n },
172 { 5, Xtank_2_n, Ctank_1_n },
173 { 5, Ytank_nB, Ctank_1_n },
174 { 5, Ytank_n_e, Ctank_1_n },
175 { 5, Ytank_n_w, Ctank_1_n },
176 { 5, Xtank_1_e, Ctank_1_e },
177 { 5, Xtank_2_e, Ctank_1_e },
178 { 5, Ytank_eB, Ctank_1_e },
179 { 5, Ytank_e_s, Ctank_1_e },
180 { 5, Ytank_e_n, Ctank_1_e },
181 { 5, Xtank_1_s, Ctank_1_s },
182 { 5, Xtank_2_s, Ctank_1_s },
183 { 5, Ytank_sB, Ctank_1_s },
184 { 5, Ytank_s_w, Ctank_1_s },
185 { 5, Ytank_s_e, Ctank_1_s },
186 { 5, Xtank_1_w, Ctank_1_w },
187 { 5, Xtank_2_w, Ctank_1_w },
188 { 5, Ytank_wB, Ctank_1_w },
189 { 5, Ytank_w_n, Ctank_1_w },
190 { 5, Ytank_w_s, Ctank_1_w },
192 { 6, Xeater_n, Ceater_n },
193 { 6, Yeater_nB, Ceater_n },
194 { 6, Xeater_e, Ceater_e },
195 { 6, Yeater_eB, Ceater_e },
196 { 6, Xeater_s, Ceater_s },
197 { 6, Yeater_sB, Ceater_s },
198 { 6, Xeater_w, Ceater_w },
199 { 6, Yeater_wB, Ceater_w },
201 { 7, Xbug_1_n, Cbug_2_n },
202 { 7, Xbug_2_n, Cbug_2_n },
203 { 7, Ybug_nB, Cbug_2_n },
204 { 7, Ybug_n_e, Cbug_2_n },
205 { 7, Ybug_n_w, Cbug_2_n },
206 { 7, Xbug_1_e, Cbug_2_e },
207 { 7, Xbug_2_e, Cbug_2_e },
208 { 7, Ybug_eB, Cbug_2_e },
209 { 7, Ybug_e_s, Cbug_2_e },
210 { 7, Ybug_e_n, Cbug_2_e },
211 { 7, Xbug_1_s, Cbug_2_s },
212 { 7, Xbug_2_s, Cbug_2_s },
213 { 7, Ybug_sB, Cbug_2_s },
214 { 7, Ybug_s_w, Cbug_2_s },
215 { 7, Ybug_s_e, Cbug_2_s },
216 { 7, Xbug_1_w, Cbug_2_w },
217 { 7, Xbug_2_w, Cbug_2_w },
218 { 7, Ybug_wB, Cbug_2_w },
219 { 7, Ybug_w_n, Cbug_2_w },
220 { 7, Ybug_w_s, Cbug_2_w },
222 { 8, Xalien, Calien },
223 { 8, Xalien_pause, Calien },
224 { 8, Yalien_nB, Calien },
225 { 8, Yalien_eB, Calien },
226 { 8, Yalien_sB, Calien },
227 { 8, Yalien_wB, Calien },
229 { 9, Xspring, Cspring },
230 { 9, Xspring_pause, Cspring },
231 { 9, Xspring_fall, Cspring },
232 { 9, Xspring_e, Cspring },
233 { 9, Xspring_w, Cspring },
234 { 9, Yspring_sB, Cspring },
235 { 9, Yspring_eB, Cspring },
236 { 9, Yspring_wB, Cspring },
237 { 9, Yspring_alien_eB, Cspring },
238 { 9, Yspring_alien_wB, Cspring },
240 { 10, Xballoon, Cballoon },
241 { 10, Yballoon_nB, Cballoon },
242 { 10, Yballoon_eB, Cballoon },
243 { 10, Yballoon_sB, Cballoon },
244 { 10, Yballoon_wB, Cballoon },
246 { 11, Xfake_amoeba, Cdrip },
247 { 11, Yfake_amoeba, Cdrip },
248 { 11, Xamoeba_1, Cdrip },
249 { 11, Xamoeba_2, Cdrip },
250 { 11, Xamoeba_3, Cdrip },
251 { 11, Xamoeba_4, Cdrip },
252 { 11, Xamoeba_5, Cdrip },
253 { 11, Xamoeba_6, Cdrip },
254 { 11, Xamoeba_7, Cdrip },
255 { 11, Xamoeba_8, Cdrip },
257 { 12, Xdynamite, Cdynamite },
262 void convert_em_level(unsigned char *src, int file_version)
264 static int eater_offset[8] =
266 2048, 2057, 2066, 2075,
267 2112, 2121, 2130, 2139
271 /* common to all emc caves */
273 cav.time_seconds = MIN(GET_BE16(src[2110]), 9999);
274 cav.gems_needed = src[2095];
278 cav.emerald_score = src[2084];
279 cav.diamond_score = src[2085];
280 cav.alien_score = src[2086];
281 cav.tank_score = src[2087];
282 cav.bug_score = src[2088];
283 cav.eater_score = src[2089];
284 cav.nut_score = src[2090];
285 cav.dynamite_score = src[2091];
286 cav.key_score = src[2092];
287 cav.exit_score = src[2093] * 8 / 5;
289 cav.lenses_score = src[2151];
290 cav.magnify_score = src[2152];
291 cav.slurp_score = src[2153];
295 cav.android_move_time = MIN(GET_BE16(src[2164]), 9999);
296 cav.android_clone_time = MIN(GET_BE16(src[2166]), 9999);
297 cav.ball_time = MIN(GET_BE16(src[2160]), 9999);
299 cav.lenses_time = MIN(GET_BE16(src[2154]), 9999);
300 cav.magnify_time = MIN(GET_BE16(src[2156]), 9999);
301 cav.wheel_time = MIN(GET_BE16(src[2104]), 9999);
303 cav.amoeba_time = MIN(GET_BE16(src[2100]) * 28, 9999);
304 cav.wonderwall_time = MIN(GET_BE16(src[2102]), 9999);
306 cav.wind_cnt = src[2149] & 15 ? cav.wind_time : 0;
308 cav.wind_direction = (temp & 8 ? 0 :
315 cav.ball_random = src[2162] & 1 ? 1 : 0;
316 cav.ball_state = src[2162] & 128 ? 1 : 0;
318 for (temp = 1; temp < 2047; temp++)
322 case 36: /* wonderwall */
323 cav.wonderwall_state = 1;
324 cav.wonderwall_time = 9999;
328 cav.wheel_x = temp & 63;
329 cav.wheel_y = temp >> 6;
330 cav.wheel_cnt = cav.wheel_time;
333 case 163: /* fake blank */
334 cav.lenses_cnt = 9999;
337 case 164: /* fake grass */
338 cav.magnify_cnt = 9999;
345 temp = GET_BE16(src[2168]);
347 for (i = 0; i < GAME_TILE_MAX; i++)
348 cav.android_array[i] = Cblank;
350 for (i = 0; android_clone_table[i].bit_nr != -1; i++)
351 if (temp & (1 << android_clone_table[i].bit_nr))
352 cav.android_array[android_clone_table[i].clone_from] =
353 android_clone_table[i].clone_to;
357 for (i = 0; i < 8; i++)
358 for (x = 0; x < 9; x++)
359 cav.eater_array[i][x] = map_emc[src[eater_offset[i] + x]];
363 temp = map_emc[src[2159]];
365 for (y = 0; y < 8; y++)
369 for (x = 0; x < 8; x++)
370 cav.ball_array[y][x] = temp;
374 cav.ball_array[y][1] = (src[2163] & 1) ? temp : Cblank; /* north */
375 cav.ball_array[y][6] = (src[2163] & 2) ? temp : Cblank; /* south */
376 cav.ball_array[y][3] = (src[2163] & 4) ? temp : Cblank; /* west */
377 cav.ball_array[y][4] = (src[2163] & 8) ? temp : Cblank; /* east */
378 cav.ball_array[y][7] = (src[2163] & 16) ? temp : Cblank; /* southeast */
379 cav.ball_array[y][5] = (src[2163] & 32) ? temp : Cblank; /* southwest */
380 cav.ball_array[y][2] = (src[2163] & 64) ? temp : Cblank; /* northeast */
381 cav.ball_array[y][0] = (src[2163] & 128)? temp : Cblank; /* northwest */
387 for (i = 0; i < 2; i++)
389 temp = GET_BE16(src[2096 + i * 2]);
391 cav.player_x[i] = (temp & 63);
392 cav.player_y[i] = (temp >> 6 & 31);
397 /* first fill the complete playfield with the empty space element */
398 for (y = 0; y < CAVE_HEIGHT; y++)
399 for (x = 0; x < CAVE_WIDTH; x++)
400 cav.cave[x][y] = Cblank;
402 /* then copy the real level contents from level file into the playfield */
404 for (y = 0; y < cav.height; y++)
405 for (x = 0; x < cav.width; x++)
406 cav.cave[x][y] = map_emc[src[temp++]];
408 native_em_level.file_version = file_version;
412 /* convert all emerald mine caves to emc version 6 cave format.
414 * caves are filtered to get rid of invalid or unsupported tiles.
416 * although the result is a somewhat clean cave, it is meant only
417 * to give a common structure for the binary cave format. it is not
418 * for archiving purposes (it is better to keep the raw cave as-is)
419 * and it is not meant for serializing (the intermediate structure
420 * is better defined).
422 * acid top is added to acid bottom in both the cave and the eaters.
423 * fake acid (only in v4) does not exist because it adds nothing to
424 * the game, and is different even in different versions of the emc
427 * v4/v5 time is converted to 10x old time (as it should be).
428 * the reason the kingsoft player used 5x time was copy protection.
430 * note: emc v6 converter has an error in converting v4 eaters to the
431 * wrong bug(24 instead of 20) and tank(12 instead of 8).
434 /* changes for game engine integration in Rocks'n'Diamonds:
436 * cave versions below V5 had no grass, but only sand/dirt
437 * - object code 130 (V6 grass) is changed to 189 (V6 dirt)
438 * - object codes are changed in both cave and eater arrays
439 * - only graphical change, as both objects behave the same
442 static const unsigned char map_v6[256] =
446 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
447 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
448 0,16,2,18, 36,37,37,37, 40,41,42,43, 44,45,128,128,
449 128,148,148, 148,45,45,45, 148,0,57,58, 59,60,61,62,63,
451 64,65,66,67, 68,69,69,71, 72,73,74,75, 118,75,75,75,
452 75,75,75,75, 75,153,153,153, 153,153,153,153, 153,153,153,153,
453 153,153,153,99, 100,68,68,68, 68,68,68,68, 68,118,118,118,
454 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
456 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
457 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
458 160,161,162,163, 164,165,165,118, 168,169,170,171, 172,173,174,175,
459 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,191,
461 192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
462 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
463 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
464 240,241,242,243, 244,245,153,153, 153,153,153,153, 153,153,153,153
467 static const unsigned char map_v5[256] =
471 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
472 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
473 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
474 128,148,148,148, 45,45,45,148, 0,57,58,59, 60,61,62,63,
476 64,65,66,67, 68,153,153,153, 153,153,153,153, 153,153,153,153,
477 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
478 153,153,153,153, 153,68,68,68, 68,68,68,68, 68,118,118,118,
479 118,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
481 128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
482 144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
483 160,153,153,153, 153,153,153,118, 168,169,170,171, 172,173,174,175,
484 176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,68,153,
486 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
487 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
488 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
489 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
492 static const unsigned char map_v4[256] =
496 0,0,2,2, 4,4,118,118, 8,9,10,11, 12,13,14,15,
497 16,16,18,18, 20,21,22,23, 24,25,26,27, 28,28,118,28,
498 0,16,2,18, 36,37,37,37, 147,41,42,43, 44,45,128,128,
499 128,148,148,148, 45,45,45,148, 0,153,153,59, 60,61,62,63,
501 64,65,66,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
502 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
503 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153,
504 153,118,114,115, 131,118,118,119, 120,121,122,118, 118,118,118,118,
506 128,129,189,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
507 144,145,146,147, 148,149,150,151, 152,68,154,155, 156,157,158,160,
508 160,160,160,160, 160,160,160,160, 160,160,160,160, 160,160,160,175,
509 153,153,153,153, 153,153,153,153, 153,153,153,153, 153,153,68,153,
511 153,153,153,153, 153,153,153,153, 200,201,202,203, 204,205,206,207,
512 208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
513 224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
514 240,241,153,153, 153,153,153,153, 153,153,153,153, 153,153,153,153
517 static const unsigned char map_v4_eater[32] =
519 /* filter for v4 eater */
521 128,18,2,0, 4,8,16,20, 28,37,41,45, 189,129,131,132,
522 133,134,135,136, 146,147,175,65, 66,64,2,18, 128,128,128,128
525 static boolean filename_has_v1_format(char *filename)
527 char *basename = getBaseNamePtr(filename);
529 return (strlen(basename) == 3 &&
530 basename[0] == 'a' &&
531 basename[1] >= 'a' && basename[1] <= 'k' &&
532 basename[2] >= '0' && basename[2] <= '9');
535 int cleanup_em_level(unsigned char *src, int length, char *filename)
537 int file_version = FILE_VERSION_EM_UNKNOWN;
540 if (length >= 2172 &&
541 src[2106] == 255 && /* version id: */
542 src[2107] == 54 && /* '6' */
543 src[2108] == 48 && /* '0' */
544 src[2109] == 48) /* '0' */
546 /* ---------- this cave has V6 file format ---------- */
547 file_version = FILE_VERSION_EM_V6;
549 /* remap elements to internal EMC level format */
550 for (i = 0; i < 2048; i++)
551 src[i] = map_v6[src[i]];
552 for (i = 2048; i < 2084; i++)
553 src[i] = map_v6[src[i]];
554 for (i = 2112; i < 2148; i++)
555 src[i] = map_v6[src[i]];
557 else if (length >= 2110 &&
558 src[2106] == 255 && /* version id: */
559 src[2107] == 53 && /* '5' */
560 src[2108] == 48 && /* '0' */
561 src[2109] == 48) /* '0' */
563 /* ---------- this cave has V5 file format ---------- */
564 file_version = FILE_VERSION_EM_V5;
566 /* remap elements to internal EMC level format */
567 for (i = 0; i < 2048; i++)
568 src[i] = map_v5[src[i]];
569 for (i = 2048; i < 2084; i++)
570 src[i] = map_v5[src[i]];
571 for (i = 2112; i < 2148; i++)
572 src[i] = src[i - 64];
574 else if (length >= 2106 &&
575 (src[1983] == 27 || /* encrypted (only EM I/II/III) */
576 src[1983] == 116 || /* unencrypted (usual case) */
577 src[1983] == 131)) /* unencrypted (rare case) */
579 /* ---------- this cave has V1, V2 or V3 file format ---------- */
581 boolean fix_copyright = FALSE;
584 byte at position 1983 (0x07bf) is used as "magic byte":
585 - 27 (0x1b) => encrypted level (V3 only / Kingsoft original games)
586 - 116 (0x74) => unencrypted level (byte is corrected to 131 (0x83))
587 - 131 (0x83) => unencrypted level (happens only in very rare cases)
590 if (src[1983] == 27) /* (0x1b) -- after decryption: 116 (0x74) */
592 /* this is original (encrypted) Emerald Mine I, II or III level file */
594 int first_byte = src[0];
595 unsigned char code0 = 0x65;
596 unsigned char code1 = 0x11;
598 /* decode encrypted level data */
599 for (i = 0; i < 2106; i++)
604 code0 = (code0 + 7) & 0xff;
607 src[1] = 131; /* needed for all Emerald Mine levels */
609 /* first byte is either 0xf1 (EM I and III) or 0xf5 (EM II) */
610 if (first_byte == 0xf5)
612 src[0] = 131; /* only needed for Emerald Mine II levels */
614 fix_copyright = TRUE;
617 /* ---------- this cave has V3 file format ---------- */
618 file_version = FILE_VERSION_EM_V3;
620 else if (filename_has_v1_format(filename))
622 /* ---------- this cave has V1 file format ---------- */
623 file_version = FILE_VERSION_EM_V1;
627 /* ---------- this cave has V2 file format ---------- */
628 file_version = FILE_VERSION_EM_V2;
631 /* remap elements to internal EMC level format */
632 for (i = 0; i < 2048; i++)
633 src[i] = map_v4[src[i]];
634 for (i = 2048; i < 2084; i++)
635 src[i] = map_v4_eater[src[i] >= 28 ? 0 : src[i]];
636 for (i = 2112; i < 2148; i++)
637 src[i] = src[i - 64];
639 if (fix_copyright) /* fix "(c)" sign in Emerald Mine II levels */
641 for (i = 0; i < 2048; i++)
643 src[i] = 254; /* replace 'Cdecor_1' with 'Calpha_copyr' */
648 /* ---------- this cave has unknown file format ---------- */
650 /* if file has length of old-style level file, print (wrong) magic byte */
652 Error(ERR_WARN, "unknown magic byte 0x%02x at position 0x%04x",
655 return FILE_VERSION_EM_UNKNOWN;
658 if (file_version < FILE_VERSION_EM_V6)
661 src[2106] = 255; /* version id: */
662 src[2107] = 54; /* '6' */
663 src[2108] = 48; /* '0' */
664 src[2109] = 48; /* '0' */
668 /* stored level time of levels for the V2 player was changed to 50% of the
669 time for the V1 player (original V3 levels already considered this) */
670 if (file_version != FILE_VERSION_EM_V1 &&
671 file_version != FILE_VERSION_EM_V3)
676 for (i = 2148; i < 2172; i++)
683 /* ---------- at this stage, the cave data always has V6 format ---------- */
686 for (i = 0; i < 2048; i++)
689 for (i++; i < 2048; i++)
694 for (i = 64; i < 2048; i++)
695 if (src[i] == 63) /* replace element above 'Cacid_s' ... */
696 src[i - 64] = 101; /* ... with 'Cacid_1' */
698 /* fix acid with no base beneath it (see below for details (*)) */
699 for (i = 64; i < 2048 - 1; i++)
701 if (file_version <= FILE_VERSION_EM_V2 &&
702 src[i - 64] == 101 && src[i] != 63) /* acid without base */
704 if (src[i - 1] == 101 || /* remove acid over acid row */
706 src[i - 64] = 6; /* replace element above with 'Cblank' */
708 src[i - 64] = 255; /* replace element above with 'Cfake_acid_1' */
712 /* fix acid in eater 1 */
713 for (i = 2051; i < 2057; i++)
717 /* fix acid in eater 2 */
718 for (i = 2060; i < 2066; i++)
722 /* fix acid in eater 3 */
723 for (i = 2069; i < 2075; i++)
727 /* fix acid in eater 4 */
728 for (i = 2078; i < 2084; i++)
732 /* fix acid in eater 5 */
733 for (i = 2115; i < 2121; i++)
737 /* fix acid in eater 6 */
738 for (i = 2124; i < 2130; i++)
742 /* fix acid in eater 7 */
743 for (i = 2133; i < 2139; i++)
747 /* fix acid in eater 8 */
748 for (i = 2142; i < 2148; i++)
757 src[GET_BE16(src[2096])] = 128;
761 src[GET_BE16(src[2098])] = 128;
771 src[2159] = map_v6[src[2159]];
781 /* size of v6 cave */
785 Error(ERR_DEBUG, "EM level file version: %d", file_version);
794 structure of emerald mine level disk files
795 ----------------------------------------------------------------------
797 if(len >= 2172 && (buf[2106] == 255 && buf[2107] == 54 && buf[2108] == 48 && buf[2109] == 48)) // v6
798 if(len >= 2110 && (buf[2106] == 255 && buf[2107] == 53 && buf[2108] == 48 && buf[2109] == 48)) // v5
799 if(len >= 2106 && (buf[1983] == 116 || buf[2047] == 116)) // v4
800 if(len >= 2106 && (buf[1983] == 27 || buf[2047] == 219)) // v3
802 buf[0]=241;buf[1]=248;for(i=0,j=101;i<2106;i++,j+=7)buf[i]=(buf[i]^j)-17; // decrypt
804 number of movements (calls to logic) = time * 50 / 8
806 {} reserved (but some broken levels use them)
808 ----------------------------------------------------------------------
828 2095: emeralds needed
832 2102: wonderwall time
834 2106: ID (0xff363030)
840 2148: flags bit#7=NOI #6=RIS
841 2149: wind direction bit#0=right #1=down #2=left #3=up
842 2150: cave number bit#7=teamwork
851 2162: ball info bit#15=switch state #8=random
852 ; bit#0=N #1=S #2=W #3=E #4=SE #5=SW #6=NE #7=NW
853 2164: android move speed
854 2166: android clone speed
856 ; bit#0=emerald #1=diamond #2=stone #3=bomb #4=nut #5=tank #6=eater
857 ; #7=bug #8=alien #9=spring #10=balloon #11=ameuba #12=dynamite
862 1: stone {stone_fall}
864 3: diamond {diamond_fall}
866 5: alien {alien_pause}
880 19: emerald {emerald_fall}
891 30: blank {drip_stretchB}
892 31: drip {drip_stretch}
893 32: stone {stone_pause}
894 33: bomb {bomb_pause}
895 34: diamond {diamond_pause}
896 35: emerald {emerald_pause}
897 36: wonderwall {wonderwallB}
907 46: blank {sand_stonein_2}
908 47: blank {sand_stonein_3}
909 48: blank {sand_stonein_4}
910 49: sand {sand_stonesand_2}
911 50: sand {sand_stonesand_3}
912 51: sand {sand_stonesand_4}
913 52: sand_stone {sand_sandstone_2}
914 53: sand_stone {sand_sandstone_3}
915 54: sand_stone {sand_sandstone_4}
916 55: sand {sand_stonesand_4}
917 56: stone {sand_stoneout_2}
931 70: spring {spring_fall}
932 71: spring {spring_w}
933 72: spring {spring_e}
938 77: android {android_n_1}
939 78: android {android_n_2}
940 79: android {android_s_1}
941 80: android {android_s_2}
942 81: android {android_e_1}
943 82: android {android_e_2}
944 83: android {android_w_1}
945 84: android {android_w_2}
960 99: spring {push_spring_w}
961 100: spring {push_spring_e}
970 109: pause {grass_wB}
971 110: pause {grass_eB}
972 111: pause {grass_nB}
973 112: pause {grass_sB}
974 113: pause {dynamite_blank}
975 114: nut {push_nut_w}
976 115: nut {push_nut_e}
977 116: steel_2 {end of level}
979 118: pause {emerald_blank}
980 119: bomb {push_bomb_w}
981 120: bomb {push_bomb_e}
982 121: stone {push_stone_w}
983 122: stone {push_stone_e}
984 123: pause {diamond_blank}
1025 163: fake_blank {fake_blankB}
1026 164: fake_grass {fake_grassB}
1028 166: switch {switchB}
1119 ----------------------------------------------------------------------
1135 2091: dynamite value
1139 2095: emeralds needed
1143 2102: wonderwall time
1145 2106: ID (0xff353030)
1149 1: stone {stone_fall}
1151 3: diamond {diamond_fall}
1153 5: alien {alien_pause}
1165 17: bomb {bomb_fall}
1167 19: emerald {emerald_fall}
1177 29: drip {drip_fall}
1178 30: blank {drip_stretchB}
1179 31: drip {drip_stretch}
1180 32: stone {stone_pause}
1181 33: bomb {bomb_pause}
1182 34: diamond {diamond_pause}
1183 35: emerald {emerald_pause}
1184 36: wonderwall {wonderwallB}
1194 46: blank {sand_stonein_2}
1195 47: blank {sand_stonein_3}
1196 48: blank {sand_stonein_4}
1197 49: sand {sand_stonesand_2}
1198 50: sand {sand_stonesand_3}
1199 51: sand {sand_stonesand_4}
1200 52: sand_stone {sand_sandstone_2}
1201 53: sand_stone {sand_sandstone_3}
1202 54: sand_stone {sand_sandstone_4}
1203 55: sand {sand_stonesand_4}
1204 56: stone {sand_stoneout_2}
1257 109: pause {grass_wB}
1258 110: pause {grass_eB}
1259 111: pause {grass_nB}
1260 112: pause {grass_sB}
1261 113: pause {dynamite_blank}
1262 114: nut {push_nut_w}
1263 115: nut {push_nut_e}
1264 116: steel_2 {end of level}
1265 117: dynamite_4 {boom_2}
1266 118: pause {emerald_blank}
1267 119: bomb {push_bomb_w}
1268 120: bomb {push_bomb_e}
1269 121: stone {push_stone_w}
1270 122: stone {push_stone_e}
1271 123: pause {diamond_blank}
1272 124: pause {dirt_wB}
1273 125: pause {dirt_eB}
1274 126: pause {dirt_nB}
1275 127: pause {dirt_sB}
1406 ----------------------------------------------------------------------
1422 2091: dynamite value
1426 2095: emeralds needed
1430 2102: wonderwall time
1460 26: diamond {diamond_shine}
1461 27: emerald {emerald_shine}
1464 1: stone {stone_fall}
1466 3: diamond {diamond_fall}
1468 5: alien {alien_pause}
1480 17: bomb {bomb_fall}
1482 19: emerald {emerald_fall}
1492 29: drip {drip_fall}
1493 30: blank {drip_stretchB}
1494 31: drip {drip_stretch}
1495 32: stone {stone_pause}
1496 33: bomb {bomb_pause}
1497 34: diamond {diamond_pause}
1498 35: emerald {emerald_pause}
1499 36: wonderwall {wonderwallB}
1509 46: blank {sand_stonein_2}
1510 47: blank {sand_stonein_3}
1511 48: blank {sand_stonein_4}
1512 49: sand {sand_stonesand_2}
1513 50: sand {sand_stonesand_3}
1514 51: sand {sand_stonesand_4}
1515 52: sand_stone {sand_sandstone_2}
1516 53: sand_stone {sand_sandstone_3}
1517 54: sand_stone {sand_sandstone_4}
1518 55: sand {sand_stonesand_4}
1519 56: stone {sand_stoneout_2}
1576 113: pause {dynamite_blank}
1577 114: nut {push_nut_w}
1578 115: nut {push_nut_e}
1579 116: steel_1 {end of level}
1580 117: dynamite_4 {boom_2}
1581 118: pause {emerald_blank}
1582 119: bomb {push_bomb_w}
1583 120: bomb {push_bomb_e}
1584 121: stone {push_stone_w}
1585 122: stone {push_stone_e}
1586 123: pause {diamond_blank}
1587 124: pause {dirt_wB}
1588 125: pause {dirt_eB}
1589 126: pause {dirt_nB}
1590 127: pause {dirt_sB}
1623 159: fake_grass {dirt}
1624 160: fake_grass {dirt}
1625 161: fake_grass {dirt}
1626 162: fake_grass {dirt}
1627 163: fake_grass {dirt}
1628 164: fake_grass {dirt}
1629 165: fake_grass {dirt}
1630 166: fake_grass {dirt}
1631 167: fake_grass {dirt}
1632 168: fake_grass {dirt}
1633 169: fake_grass {dirt}
1634 170: fake_grass {dirt}
1635 171: fake_grass {dirt}
1636 172: fake_grass {dirt}
1637 173: fake_grass {dirt}
1638 174: fake_grass {dirt}
1704 240: alpha_arrow_e {}
1705 241: decor_1 {alpha_copyr}
1721 ----------------------------------------------------------------------