- new_element = EL_AMOEBA_DEAD;
-
- level->field[x][y] = new_element;
- }
-
- for (i = 0; i < MAX_PLAYERS; i++)
- {
- /* in case of all players set to the same field, use the first player */
- int nr = MAX_PLAYERS - i - 1;
- int jx = ply[nr]->x_initial - 1;
- int jy = ply[nr]->y_initial - 1;
-
- if (jx != -1 && jy != -1)
- level->field[jx][jy] = EL_PLAYER_1 + nr;
- }
-}
-
-
-/* ------------------------------------------------------------------------- */
-/* functions for loading SP level */
-/* ------------------------------------------------------------------------- */
-
-#if 0
-
-#define NUM_SUPAPLEX_LEVELS_PER_PACKAGE 111
-#define SP_LEVEL_SIZE 1536
-#define SP_LEVEL_XSIZE 60
-#define SP_LEVEL_YSIZE 24
-#define SP_LEVEL_NAME_LEN 23
-
-static void LoadLevelFromFileStream_SP(FILE *file, struct LevelInfo *level,
- int nr)
-{
- int initial_player_gravity;
- int num_special_ports;
- int i, x, y;
-
- /* for details of the Supaplex level format, see Herman Perk's Supaplex
- documentation file "SPFIX63.DOC" from his Supaplex "SpeedFix" package */
-
- /* read level body (width * height == 60 * 24 tiles == 1440 bytes) */
- for (y = 0; y < SP_LEVEL_YSIZE; y++)
- {
- for (x = 0; x < SP_LEVEL_XSIZE; x++)
- {
- int element_old = fgetc(file);
- int element_new;
-
- if (element_old <= 0x27)
- element_new = getMappedElement(EL_SP_START + element_old);
- else if (element_old == 0x28)
- element_new = EL_INVISIBLE_WALL;
- else
- {
- Error(ERR_WARN, "in level %d, at position %d, %d:", nr, x, y);
- Error(ERR_WARN, "invalid level element %d", element_old);
-
- element_new = EL_UNKNOWN;
- }
-
- level->field[x][y] = element_new;
- }
- }
-
- ReadUnusedBytesFromFile(file, 4); /* (not used by Supaplex engine) */
-
- /* initial gravity: 1 == "on", anything else (0) == "off" */
- initial_player_gravity = (fgetc(file) == 1 ? TRUE : FALSE);
-
- for (i = 0; i < MAX_PLAYERS; i++)
- level->initial_player_gravity[i] = initial_player_gravity;
-
- ReadUnusedBytesFromFile(file, 1); /* (not used by Supaplex engine) */
-
- /* level title in uppercase letters, padded with dashes ("-") (23 bytes) */
- for (i = 0; i < SP_LEVEL_NAME_LEN; i++)
- level->name[i] = fgetc(file);
- level->name[SP_LEVEL_NAME_LEN] = '\0';
-
- /* initial "freeze zonks": 2 == "on", anything else (0, 1) == "off" */
- ReadUnusedBytesFromFile(file, 1); /* (not used by R'n'D engine) */
-
- /* number of infotrons needed; 0 means that Supaplex will count the total
- amount of infotrons in the level and use the low byte of that number
- (a multiple of 256 infotrons will result in "0 infotrons needed"!) */
- level->gems_needed = fgetc(file);
-
- /* number of special ("gravity") port entries below (maximum 10 allowed) */
- num_special_ports = fgetc(file);
-
- /* database of properties of up to 10 special ports (6 bytes per port) */
- for (i = 0; i < 10; i++)
- {
- int port_location, port_x, port_y, port_element;
- int gravity;
-
- /* high and low byte of the location of a special port; if (x, y) are the
- coordinates of a port in the field and (0, 0) is the top-left corner,
- the 16 bit value here calculates as 2 * (x + (y * 60)) (this is twice
- of what may be expected: Supaplex works with a game field in memory
- which is 2 bytes per tile) */
- port_location = getFile16BitBE(file);
-
- /* change gravity: 1 == "turn on", anything else (0) == "turn off" */
- gravity = fgetc(file);
-
- /* "freeze zonks": 2 == "turn on", anything else (0, 1) == "turn off" */
- ReadUnusedBytesFromFile(file, 1); /* (not used by R'n'D engine) */
-
- /* "freeze enemies": 1 == "turn on", anything else (0) == "turn off" */
- ReadUnusedBytesFromFile(file, 1); /* (not used by R'n'D engine) */
-
- ReadUnusedBytesFromFile(file, 1); /* (not used by Supaplex engine) */
-
- if (i >= num_special_ports)
- continue;
-
- port_x = (port_location / 2) % SP_LEVEL_XSIZE;
- port_y = (port_location / 2) / SP_LEVEL_XSIZE;
-
- if (port_x < 0 || port_x >= SP_LEVEL_XSIZE ||
- port_y < 0 || port_y >= SP_LEVEL_YSIZE)
- {
- Error(ERR_WARN, "special port position (%d, %d) out of bounds",
- port_x, port_y);
-
- continue;
- }
-
- port_element = level->field[port_x][port_y];
-
- if (port_element < EL_SP_GRAVITY_PORT_RIGHT ||
- port_element > EL_SP_GRAVITY_PORT_UP)
- {
- Error(ERR_WARN, "no special port at position (%d, %d)", port_x, port_y);
-
- continue;
- }
-
- /* change previous (wrong) gravity inverting special port to either
- gravity enabling special port or gravity disabling special port */
- level->field[port_x][port_y] +=
- (gravity == 1 ? EL_SP_GRAVITY_ON_PORT_RIGHT :
- EL_SP_GRAVITY_OFF_PORT_RIGHT) - EL_SP_GRAVITY_PORT_RIGHT;
- }
-
- ReadUnusedBytesFromFile(file, 4); /* (not used by Supaplex engine) */
-
- /* change special gravity ports without database entries to normal ports */
- for (y = 0; y < SP_LEVEL_YSIZE; y++)
- for (x = 0; x < SP_LEVEL_XSIZE; x++)
- if (level->field[x][y] >= EL_SP_GRAVITY_PORT_RIGHT &&
- level->field[x][y] <= EL_SP_GRAVITY_PORT_UP)
- level->field[x][y] += EL_SP_PORT_RIGHT - EL_SP_GRAVITY_PORT_RIGHT;
-
- /* auto-determine number of infotrons if it was stored as "0" -- see above */
- if (level->gems_needed == 0)
- {
- for (y = 0; y < SP_LEVEL_YSIZE; y++)
- for (x = 0; x < SP_LEVEL_XSIZE; x++)
- if (level->field[x][y] == EL_SP_INFOTRON)
- level->gems_needed++;
-
- level->gems_needed &= 0xff; /* only use low byte -- see above */
- }
-
- level->fieldx = SP_LEVEL_XSIZE;
- level->fieldy = SP_LEVEL_YSIZE;
-
- level->time = 0; /* no time limit */
- level->amoeba_speed = 0;
- level->time_magic_wall = 0;
- level->time_wheel = 0;
- level->amoeba_content = EL_EMPTY;
-
-#if 1
- /* original Supaplex does not use score values -- use default values */
-#else
- for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
- level->score[i] = 0;
-#endif
-
- /* there are no yamyams in supaplex levels */
- for (i = 0; i < level->num_yamyam_contents; i++)
- for (y = 0; y < 3; y++)
- for (x = 0; x < 3; x++)
- level->yamyam_content[i].e[x][y] = EL_EMPTY;
-}
-
-static void LoadLevelFromFileInfo_SP(struct LevelInfo *level,
- struct LevelFileInfo *level_file_info,
- boolean level_info_only)
-{
- char *filename = level_file_info->filename;
- FILE *file;
- int nr = level_file_info->nr - leveldir_current->first_level;
- int i, l, x, y;
- char name_first, name_last;
- struct LevelInfo multipart_level;
- int multipart_xpos, multipart_ypos;
- boolean is_multipart_level;
- boolean is_first_part;
- boolean reading_multipart_level = FALSE;
- boolean use_empty_level = FALSE;
-
- if (!(file = fopen(filename, MODE_READ)))
- {
- level->no_valid_file = TRUE;
-
- if (!level_info_only)
- Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename);
-
- return;
- }
-
- /* position file stream to the requested level inside the level package */
- if (level_file_info->packed &&
- fseek(file, nr * SP_LEVEL_SIZE, SEEK_SET) != 0)
- {
- level->no_valid_file = TRUE;
-
- Error(ERR_WARN, "cannot fseek in file '%s' -- using empty level", filename);
-
- return;
- }
-
- /* there exist Supaplex level package files with multi-part levels which
- can be detected as follows: instead of leading and trailing dashes ('-')
- to pad the level name, they have leading and trailing numbers which are
- the x and y coordinations of the current part of the multi-part level;
- if there are '?' characters instead of numbers on the left or right side
- of the level name, the multi-part level consists of only horizontal or
- vertical parts */
-
- for (l = nr; l < NUM_SUPAPLEX_LEVELS_PER_PACKAGE; l++)
- {
- LoadLevelFromFileStream_SP(file, level, l);
-
- /* check if this level is a part of a bigger multi-part level */
-
- name_first = level->name[0];
- name_last = level->name[SP_LEVEL_NAME_LEN - 1];
-
- is_multipart_level =
- ((name_first == '?' || (name_first >= '0' && name_first <= '9')) &&
- (name_last == '?' || (name_last >= '0' && name_last <= '9')));
-
- is_first_part =
- ((name_first == '?' || name_first == '1') &&
- (name_last == '?' || name_last == '1'));
-
- /* correct leading multipart level meta information in level name */
- for (i = 0; i < SP_LEVEL_NAME_LEN && level->name[i] == name_first; i++)
- level->name[i] = '-';
-
- /* correct trailing multipart level meta information in level name */
- for (i = SP_LEVEL_NAME_LEN - 1; i >= 0 && level->name[i] == name_last; i--)
- level->name[i] = '-';
-
- /* ---------- check for normal single level ---------- */
-
- if (!reading_multipart_level && !is_multipart_level)
- {
- /* the current level is simply a normal single-part level, and we are
- not reading a multi-part level yet, so return the level as it is */
-
- break;
- }
-
- /* ---------- check for empty level (unused multi-part) ---------- */
-
- if (!reading_multipart_level && is_multipart_level && !is_first_part)
- {
- /* this is a part of a multi-part level, but not the first part
- (and we are not already reading parts of a multi-part level);
- in this case, use an empty level instead of the single part */
-
- use_empty_level = TRUE;
-
- break;
- }
-
- /* ---------- check for finished multi-part level ---------- */
-
- if (reading_multipart_level &&
- (!is_multipart_level ||
- !strEqual(level->name, multipart_level.name)))
- {
- /* we are already reading parts of a multi-part level, but this level is
- either not a multi-part level, or a part of a different multi-part
- level; in both cases, the multi-part level seems to be complete */
-
- break;
- }
-
- /* ---------- here we have one part of a multi-part level ---------- */
-
- reading_multipart_level = TRUE;
-
- if (is_first_part) /* start with first part of new multi-part level */
- {
- /* copy level info structure from first part */
- multipart_level = *level;
-
- /* clear playfield of new multi-part level */
- for (y = 0; y < MAX_LEV_FIELDY; y++)
- for (x = 0; x < MAX_LEV_FIELDX; x++)
- multipart_level.field[x][y] = EL_EMPTY;
- }
-
- if (name_first == '?')
- name_first = '1';
- if (name_last == '?')
- name_last = '1';
-
- multipart_xpos = (int)(name_first - '0');
- multipart_ypos = (int)(name_last - '0');
-
-#if 0
- printf("----------> part (%d/%d) of multi-part level '%s'\n",
- multipart_xpos, multipart_ypos, multipart_level.name);
-#endif
-
- if (multipart_xpos * SP_LEVEL_XSIZE > MAX_LEV_FIELDX ||
- multipart_ypos * SP_LEVEL_YSIZE > MAX_LEV_FIELDY)
- {
- Error(ERR_WARN, "multi-part level is too big -- ignoring part of it");
-
- break;
- }
-
- multipart_level.fieldx = MAX(multipart_level.fieldx,
- multipart_xpos * SP_LEVEL_XSIZE);
- multipart_level.fieldy = MAX(multipart_level.fieldy,
- multipart_ypos * SP_LEVEL_YSIZE);
-
- /* copy level part at the right position of multi-part level */
- for (y = 0; y < SP_LEVEL_YSIZE; y++)
- {
- for (x = 0; x < SP_LEVEL_XSIZE; x++)
- {
- int start_x = (multipart_xpos - 1) * SP_LEVEL_XSIZE;
- int start_y = (multipart_ypos - 1) * SP_LEVEL_YSIZE;
-
- multipart_level.field[start_x + x][start_y + y] = level->field[x][y];
- }
- }
- }
-
- fclose(file);
-
- if (use_empty_level)
- {
- setLevelInfoToDefaults(level);
-
- level->fieldx = SP_LEVEL_XSIZE;
- level->fieldy = SP_LEVEL_YSIZE;