+
+ lev.required_initial = src[0x82F];
+
+ for (i = 0; i < 2; i++)
+ {
+ temp = src[0x830 + i * 2] << 8 | src[0x831 + i * 2];
+ ply[i].x_initial = (temp & 63) + 1;
+ ply[i].y_initial = (temp >> 6 & 31) + 1;
+ }
+
+ temp = (src[0x834] << 8 | src[0x835]) * 28;
+ if (temp > 9999)
+ temp = 9999;
+ lev.amoeba_time = temp;
+
+ lev.android_move_time = src[0x874] << 8 | src[0x875];
+ lev.android_clone_time = src[0x876] << 8 | src[0x877];
+
+ lev.ball_random = src[0x872] & 1 ? 1 : 0;
+ lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
+ lev.ball_time = src[0x870] << 8 | src[0x871];
+
+ lev.emerald_score = src[0x824];
+ lev.diamond_score = src[0x825];
+ lev.alien_score = src[0x826];
+ lev.tank_score = src[0x827];
+ lev.bug_score = src[0x828];
+ lev.eater_score = src[0x829];
+ lev.nut_score = src[0x82A];
+ lev.dynamite_score = src[0x82B];
+ lev.key_score = src[0x82C];
+ lev.exit_score = src[0x82D] * 8 / 5;
+ lev.lenses_score = src[0x867];
+ lev.magnify_score = src[0x868];
+ lev.slurp_score = src[0x869];
+
+ lev.lenses_time = src[0x86A] << 8 | src[0x86B];
+ lev.magnify_time = src[0x86C] << 8 | src[0x86D];
+ lev.wheel_time = src[0x838] << 8 | src[0x839];
+
+ lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
+ temp = src[0x865];
+ lev.wind_direction_initial = (temp & 8 ? 0 :
+ temp & 1 ? 1 :
+ temp & 2 ? 2 :
+ temp & 4 ? 3 : 0);
+
+ lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
+
+ for (i = 0; i < 8; i++)
+ for (x = 0; x < 9; x++)
+ lev.eater_array[i][x] =
+ get_em_element(src[eater_offset[i] + x], file_version);
+
+ temp = get_em_element(src[0x86F], file_version);
+ for (y = 0; y < 8; y++)
+ {
+ if (src[0x872] & 1)
+ {
+ for (x = 0; x < 8; x++)
+ lev.ball_array[y][x] = temp;
+ }
+ else
+ {
+ lev.ball_array[y][1] = (src[0x873] & 1) ? temp : Xblank; /* north */
+ lev.ball_array[y][6] = (src[0x873] & 2) ? temp : Xblank; /* south */
+ lev.ball_array[y][3] = (src[0x873] & 4) ? temp : Xblank; /* west */
+ lev.ball_array[y][4] = (src[0x873] & 8) ? temp : Xblank; /* east */
+ lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* southeast */
+ lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
+ lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
+ lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
+ }
+ }
+
+ temp = src[0x878] << 8 | src[0x879];
+
+ if (temp & 1)
+ {
+ lev.android_array[Xemerald] = Xemerald;
+ lev.android_array[Xemerald_pause] = Xemerald;
+ lev.android_array[Xemerald_fall] = Xemerald;
+ lev.android_array[Yemerald_sB] = Xemerald;
+ lev.android_array[Yemerald_eB] = Xemerald;
+ lev.android_array[Yemerald_wB] = Xemerald;
+ }
+
+ if (temp & 2)
+ {
+ lev.android_array[Xdiamond] = Xdiamond;
+ lev.android_array[Xdiamond_pause] = Xdiamond;
+ lev.android_array[Xdiamond_fall] = Xdiamond;
+ lev.android_array[Ydiamond_sB] = Xdiamond;
+ lev.android_array[Ydiamond_eB] = Xdiamond;
+ lev.android_array[Ydiamond_wB] = Xdiamond;
+ }
+
+ if (temp & 4)
+ {
+ lev.android_array[Xstone] = Xstone;
+ lev.android_array[Xstone_pause] = Xstone;
+ lev.android_array[Xstone_fall] = Xstone;
+ lev.android_array[Ystone_sB] = Xstone;
+ lev.android_array[Ystone_eB] = Xstone;
+ lev.android_array[Ystone_wB] = Xstone;
+ }
+
+ if (temp & 8)
+ {
+ lev.android_array[Xbomb] = Xbomb;
+ lev.android_array[Xbomb_pause] = Xbomb;
+ lev.android_array[Xbomb_fall] = Xbomb;
+ lev.android_array[Ybomb_sB] = Xbomb;
+ lev.android_array[Ybomb_eB] = Xbomb;
+ lev.android_array[Ybomb_wB] = Xbomb;
+ }
+
+ if (temp & 16)
+ {
+ lev.android_array[Xnut] = Xnut;
+ lev.android_array[Xnut_pause] = Xnut;
+ lev.android_array[Xnut_fall] = Xnut;
+ lev.android_array[Ynut_sB] = Xnut;
+ lev.android_array[Ynut_eB] = Xnut;
+ lev.android_array[Ynut_wB] = Xnut;
+ }
+
+ if (temp & 32)
+ {
+ lev.android_array[Xtank_1_n] = Xtank_1_n;
+ lev.android_array[Xtank_2_n] = Xtank_1_n;
+ lev.android_array[Ytank_nB] = Xtank_1_n;
+ lev.android_array[Ytank_n_e] = Xtank_1_n;
+ lev.android_array[Ytank_n_w] = Xtank_1_n;
+
+ lev.android_array[Xtank_1_e] = Xtank_1_e;
+ lev.android_array[Xtank_2_e] = Xtank_1_e;
+ lev.android_array[Ytank_eB] = Xtank_1_e;
+ lev.android_array[Ytank_e_s] = Xtank_1_e;
+ lev.android_array[Ytank_e_n] = Xtank_1_e;
+
+ lev.android_array[Xtank_1_s] = Xtank_1_s;
+ lev.android_array[Xtank_2_s] = Xtank_1_s;
+ lev.android_array[Ytank_sB] = Xtank_1_s;
+ lev.android_array[Ytank_s_w] = Xtank_1_s;
+ lev.android_array[Ytank_s_e] = Xtank_1_s;
+
+ lev.android_array[Xtank_1_w] = Xtank_1_w;
+ lev.android_array[Xtank_2_w] = Xtank_1_w;
+ lev.android_array[Ytank_wB] = Xtank_1_w;
+ lev.android_array[Ytank_w_n] = Xtank_1_w;
+ lev.android_array[Ytank_w_s] = Xtank_1_w;
+ }
+
+ if (temp & 64)
+ {
+ lev.android_array[Xeater_n] = Xeater_n;
+ lev.android_array[Yeater_nB] = Xeater_n;
+
+ lev.android_array[Xeater_e] = Xeater_e;
+ lev.android_array[Yeater_eB] = Xeater_e;
+
+ lev.android_array[Xeater_s] = Xeater_s;
+ lev.android_array[Yeater_sB] = Xeater_s;
+
+ lev.android_array[Xeater_w] = Xeater_w;
+ lev.android_array[Yeater_wB] = Xeater_w;
+ }
+
+ if (temp & 128)
+ {
+ lev.android_array[Xbug_1_n] = Xbug_2_n;
+ lev.android_array[Xbug_2_n] = Xbug_2_n;
+ lev.android_array[Ybug_nB] = Xbug_2_n;
+ lev.android_array[Ybug_n_e] = Xbug_2_n;
+ lev.android_array[Ybug_n_w] = Xbug_2_n;
+
+ lev.android_array[Xbug_1_e] = Xbug_2_e;
+ lev.android_array[Xbug_2_e] = Xbug_2_e;
+ lev.android_array[Ybug_eB] = Xbug_2_e;
+ lev.android_array[Ybug_e_s] = Xbug_2_e;
+ lev.android_array[Ybug_e_n] = Xbug_2_e;
+
+ lev.android_array[Xbug_1_s] = Xbug_2_s;
+ lev.android_array[Xbug_2_s] = Xbug_2_s;
+ lev.android_array[Ybug_sB] = Xbug_2_s;
+ lev.android_array[Ybug_s_w] = Xbug_2_s;
+ lev.android_array[Ybug_s_e] = Xbug_2_s;
+
+ lev.android_array[Xbug_1_w] = Xbug_2_w;
+ lev.android_array[Xbug_2_w] = Xbug_2_w;
+ lev.android_array[Ybug_wB] = Xbug_2_w;
+ lev.android_array[Ybug_w_n] = Xbug_2_w;
+ lev.android_array[Ybug_w_s] = Xbug_2_w;
+ }
+
+ if (temp & 256)
+ {
+ lev.android_array[Xalien] = Xalien;
+ lev.android_array[Xalien_pause] = Xalien;
+ lev.android_array[Yalien_nB] = Xalien;
+ lev.android_array[Yalien_eB] = Xalien;
+ lev.android_array[Yalien_sB] = Xalien;
+ lev.android_array[Yalien_wB] = Xalien;
+ }
+
+ if (temp & 512)
+ {
+ lev.android_array[Xspring] = Xspring;
+ lev.android_array[Xspring_pause] = Xspring;
+ lev.android_array[Xspring_e] = Xspring;
+ lev.android_array[Yspring_eB] = Xspring;
+ lev.android_array[Yspring_alien_eB] = Xspring;
+ lev.android_array[Xspring_w] = Xspring;
+ lev.android_array[Yspring_wB] = Xspring;
+ lev.android_array[Yspring_alien_wB] = Xspring;
+ lev.android_array[Xspring_fall] = Xspring;
+ lev.android_array[Yspring_sB] = Xspring;
+ }
+
+ if (temp & 1024)
+ {
+ lev.android_array[Yballoon_nB] = Xballoon;
+ lev.android_array[Yballoon_eB] = Xballoon;
+ lev.android_array[Yballoon_sB] = Xballoon;
+ lev.android_array[Yballoon_wB] = Xballoon;
+ lev.android_array[Xballoon] = Xballoon;
+ }
+
+ if (temp & 2048)
+ {
+ lev.android_array[Xfake_amoeba] = Xdrip;
+ lev.android_array[Xfake_amoebaB] = Xdrip;
+ lev.android_array[Xamoeba_1] = Xdrip;
+ lev.android_array[Xamoeba_2] = Xdrip;
+ lev.android_array[Xamoeba_3] = Xdrip;
+ lev.android_array[Xamoeba_4] = Xdrip;
+ lev.android_array[Xamoeba_5] = Xdrip;
+ lev.android_array[Xamoeba_6] = Xdrip;
+ lev.android_array[Xamoeba_7] = Xdrip;
+ lev.android_array[Xamoeba_8] = Xdrip;
+ }
+
+ if (temp & 4096)
+ {
+ lev.android_array[Xdynamite] = Xdynamite;
+ }
+
+ for (temp = 1; temp < 2047; temp++)
+ {
+ switch (src[temp])
+ {
+ case 0x24: /* wonderwall */
+ lev.wonderwall_state_initial = 1;
+ lev.wonderwall_time_initial = 9999;
+ break;
+
+ case 0x28: /* wheel */
+ lev.wheel_x_initial = temp & 63;
+ lev.wheel_y_initial = temp >> 6;
+ lev.wheel_cnt_initial = lev.wheel_time;
+ break;
+
+ case 0xA3: /* fake blank */
+ lev.lenses_cnt_initial = 9999;
+ break;
+
+ case 0xA4: /* fake grass */
+ lev.magnify_cnt_initial = 9999;
+ break;
+ }
+ }
+
+ /* first fill the complete playfield with the default border element */
+ for (y = 0; y < HEIGHT; y++)
+ for (x = 0; x < WIDTH; x++)
+ native_em_level.cave[x][y] = Zborder;
+
+ /* then copy the real level contents from level file into the playfield */
+ temp = 0;
+ for (y = 0; y < lev.height; y++)
+ for (x = 0; x < lev.width; x++)
+ native_em_level.cave[x + 1][y + 1] =
+ get_em_element(src[temp++], file_version);
+
+ /* at last, set the two players at their positions in the playfield */
+ /* (native EM[C] levels always have exactly two players in a level) */
+ for (i = 0; i < 2; i++)
+ native_em_level.cave[ply[i].x_initial][ply[i].y_initial] = Zplayer;
+
+ native_em_level.file_version = file_version;
+}
+
+void prepare_em_level(void)
+{
+ int i, x, y;
+ int players_left;
+ boolean team_mode;
+
+ /* reset all runtime variables to their initial values */
+
+ for (y = 0; y < HEIGHT; y++)
+ for (x = 0; x < WIDTH; x++)
+ Cave[y][x] = native_em_level.cave[x][y];
+
+ for (y = 0; y < HEIGHT; y++)
+ for (x = 0; x < WIDTH; x++)
+ Next[y][x] = Cave[y][x];
+
+ for (y = 0; y < HEIGHT; y++)
+ for (x = 0; x < WIDTH; x++)
+ Draw[y][x] = Cave[y][x];
+
+ lev.time_initial = lev.time_seconds;
+ lev.time = lev.time_initial;
+
+ lev.required = lev.required_initial;
+ lev.score = 0;
+
+ lev.android_move_cnt = lev.android_move_time;
+ lev.android_clone_cnt = lev.android_clone_time;
+
+ lev.ball_pos = 0;
+ lev.ball_state = lev.ball_state_initial;
+ lev.ball_cnt = lev.ball_time;
+
+ lev.eater_pos = 0;
+ lev.shine_cnt = 0;
+
+ lev.lenses_cnt = lev.lenses_cnt_initial;
+ lev.magnify_cnt = lev.magnify_cnt_initial;
+
+ lev.wheel_cnt = lev.wheel_cnt_initial;
+ lev.wheel_x = lev.wheel_x_initial;
+ lev.wheel_y = lev.wheel_y_initial;
+
+ lev.wind_direction = lev.wind_direction_initial;
+ lev.wind_cnt = lev.wind_cnt_initial;
+
+ lev.wonderwall_state = lev.wonderwall_state_initial;
+ lev.wonderwall_time = lev.wonderwall_time_initial;
+
+ lev.killed_out_of_time = FALSE;
+
+ /* determine number of players in this level */
+ lev.home_initial = 0;
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ ply[i].exists = 0;
+ ply[i].alive_initial = FALSE;
+
+ if (ply[i].x_initial > 0 && ply[i].y_initial > 0)
+ {
+ ply[i].exists = 1;
+
+ lev.home_initial++;
+ }
+ }
+
+ team_mode = getTeamMode_EM();
+
+ if (!team_mode)
+ lev.home_initial = 1;
+
+ lev.home = lev.home_initial;
+ players_left = lev.home_initial;
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ if (ply[i].exists)
+ {
+ if (players_left)
+ {
+ ply[i].alive_initial = TRUE;
+ players_left--;
+ }
+ else
+ {
+ int x = ply[i].x_initial;
+ int y = ply[i].y_initial;
+
+ native_em_level.cave[x][y] = Xblank;
+
+ Cave[y][x] = Next[y][x] = Draw[y][x] = Xblank;
+ }
+ }
+ }
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ ply[i].num = i;
+ ply[i].alive = ply[i].alive_initial;
+ ply[i].dynamite = 0;
+ ply[i].dynamite_cnt = 0;
+ ply[i].keys = 0;
+ ply[i].anim = 0;
+ ply[i].oldx = ply[i].x = ply[i].x_initial;
+ ply[i].oldy = ply[i].y = ply[i].y_initial;
+ ply[i].last_move_dir = MV_NONE;
+ ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
+ ply[i].joy_snap = ply[i].joy_drop = 0;
+ ply[i].joy_stick = ply[i].joy_spin = 0;
+ }
+
+ // the following engine variables are initialized to version-specific values
+ // in function InitGameEngine() (src/game.c):
+ //
+ // - game_em.use_single_button (default: TRUE)
+ // - game_em.use_snap_key_bug (default: FALSE)
+
+ game_em.level_solved = FALSE;
+ game_em.game_over = FALSE;
+
+ game_em.any_player_moving = FALSE;
+ game_em.any_player_snapping = FALSE;
+
+ game_em.last_moving_player = 0; /* default: first player */
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ game_em.last_player_direction[i] = MV_NONE;
+
+ lev.exit_x = lev.exit_y = -1; /* kludge for playing player exit sound */
+}