Esempio n. 1
0
/*
 * reads a polymodel structure from a PHYSFS_file
 */
extern void polymodel_read(polymodel *pm, PHYSFS_file *fp)
{
	int i;

	pm->n_models = PHYSFSX_readInt(fp);
	pm->model_data_size = PHYSFSX_readInt(fp);
	pm->model_data = (ubyte *)(size_t)PHYSFSX_readInt(fp); // garbage, read it anyway just for consistency
	for (i = 0; i < MAX_SUBMODELS; i++)
		pm->submodel_ptrs[i] = PHYSFSX_readInt(fp);
	for (i = 0; i < MAX_SUBMODELS; i++)
		PHYSFSX_readVector(&(pm->submodel_offsets[i]), fp);
	for (i = 0; i < MAX_SUBMODELS; i++)
		PHYSFSX_readVector(&(pm->submodel_norms[i]), fp);
	for (i = 0; i < MAX_SUBMODELS; i++)
		PHYSFSX_readVector(&(pm->submodel_pnts[i]), fp);
	for (i = 0; i < MAX_SUBMODELS; i++)
		pm->submodel_rads[i] = PHYSFSX_readFix(fp);
	PHYSFS_read(fp, pm->submodel_parents, MAX_SUBMODELS, 1);
	for (i = 0; i < MAX_SUBMODELS; i++)
		PHYSFSX_readVector(&(pm->submodel_mins[i]), fp);
	for (i = 0; i < MAX_SUBMODELS; i++)
		PHYSFSX_readVector(&(pm->submodel_maxs[i]), fp);
	PHYSFSX_readVector(&(pm->mins), fp);
	PHYSFSX_readVector(&(pm->maxs), fp);
	pm->rad = PHYSFSX_readFix(fp);
	pm->n_textures = PHYSFSX_readByte(fp);
	pm->first_texture = PHYSFSX_readShort(fp);
	pm->simpler_model = PHYSFSX_readByte(fp);
}
Esempio n. 2
0
/*
 * reads a DiskSoundHeader structure from a PHYSFS_file
 */
void DiskSoundHeader_read(DiskSoundHeader *dsh, PHYSFS_file *fp)
{
	PHYSFS_read(fp, dsh->name, 8, 1);
	dsh->length = PHYSFSX_readInt(fp);
	dsh->data_length = PHYSFSX_readInt(fp);
	dsh->offset = PHYSFSX_readInt(fp);
}
Esempio n. 3
0
/*
 * reads n polymodel structs from a PHYSFS_file
 */
extern int polymodel_read_n(polymodel *pm, int n, PHYSFS_file *fp)
{
	int i, j;

	for (i = 0; i < n; i++) {
		pm[i].n_models = PHYSFSX_readInt(fp);
		pm[i].model_data_size = PHYSFSX_readInt(fp);
		pm[i].model_data = (ubyte *) (size_t)PHYSFSX_readInt(fp);
		for (j = 0; j < MAX_SUBMODELS; j++)
			pm[i].submodel_ptrs[j] = PHYSFSX_readInt(fp);
		for (j = 0; j < MAX_SUBMODELS; j++)
			PHYSFSX_readVector(&(pm[i].submodel_offsets[j]), fp);
		for (j = 0; j < MAX_SUBMODELS; j++)
			PHYSFSX_readVector(&(pm[i].submodel_norms[j]), fp);
		for (j = 0; j < MAX_SUBMODELS; j++)
			PHYSFSX_readVector(&(pm[i].submodel_pnts[j]), fp);
		for (j = 0; j < MAX_SUBMODELS; j++)
			pm[i].submodel_rads[j] = PHYSFSX_readFix(fp);
		PHYSFS_read(fp, pm[i].submodel_parents, MAX_SUBMODELS, 1);
		for (j = 0; j < MAX_SUBMODELS; j++)
			PHYSFSX_readVector(&(pm[i].submodel_mins[j]), fp);
		for (j = 0; j < MAX_SUBMODELS; j++)
			PHYSFSX_readVector(&(pm[i].submodel_maxs[j]), fp);
		PHYSFSX_readVector(&(pm[i].mins), fp);
		PHYSFSX_readVector(&(pm[i].maxs), fp);
		pm[i].rad = PHYSFSX_readFix(fp);
		pm[i].n_textures = PHYSFSX_readByte(fp);
		pm[i].first_texture = PHYSFSX_readShort(fp);
		pm[i].simpler_model = PHYSFSX_readByte(fp);
	}
	return i;
}
Esempio n. 4
0
void load_hostage_data(PHYSFS_file * fp,int do_read)
{
	int version,i,num,num_hostages;

	hostage_init_all();

	num_hostages = 0;

	// Find number of hostages in mine...
	for (i=0; i<=Highest_object_index; i++ )	{
		if ( Objects[i].type == OBJ_HOSTAGE )	{
			num = Objects[i].id;
			if (num+1 > num_hostages)
				num_hostages = num+1;

			if (Hostages[num].objnum != -1) {		//slot already used
				num = hostage_get_next_slot();		//..so get new slot
				if (num+1 > num_hostages)
					num_hostages = num+1;
				Objects[i].id = num;
			}

			if ( num > -1 && num < MAX_HOSTAGES )	{
				Assert(Hostages[num].objnum == -1);		//make sure not used
				// -- Matt -- commented out by MK on 11/19/94, hit often in level 3, level 4.  Assert(Hostages[num].objnum == -1);		//make sure not used
				Hostages[num].objnum = i;
				Hostages[num].objsig = Objects[i].signature;
			}
		}
	}

	if (do_read) {
		version = PHYSFSX_readInt(fp);

		for (i=0;i<num_hostages;i++) {

			Assert(Hostages[i].objnum != -1);		//make sure slot filled in

			Hostages[i].vclip_num = PHYSFSX_readInt(fp);

			#ifndef SHAREWARE
			if (Hostages[i].vclip_num<0 || Hostages[i].vclip_num>=MAX_HOSTAGES || Hostage_face_clip[Hostages[i].vclip_num].num_frames<=0)
				Hostages[i].vclip_num=0;

			Assert(Hostage_face_clip[Hostages[i].vclip_num].num_frames);
			#endif

			PHYSFSX_fgets(Hostages[i].text, HOSTAGE_MESSAGE_LEN, fp);
		}
	}
	else
		for (i=0;i<num_hostages;i++) {
			Assert(Hostages[i].objnum != -1);		//make sure slot filled in
			Hostages[i].vclip_num = 0;
		}

}
Esempio n. 5
0
/*
 * reads n powerup_type_info structs from a PHYSFS_file
 */
int powerup_type_info_read_n(powerup_type_info *pti, int n, PHYSFS_file *fp)
{
	int i;

	for (i = 0; i < n; i++) {
		pti[i].vclip_num = PHYSFSX_readInt(fp);
		pti[i].hit_sound = PHYSFSX_readInt(fp);
		pti[i].size = PHYSFSX_readFix(fp);
		pti[i].light = PHYSFSX_readFix(fp);
	}
	return i;
}
Esempio n. 6
0
/*
 * reads a v19_wall structure from a PHYSFS_file
 */
extern void v19_wall_read(v19_wall *w, PHYSFS_file *fp)
{
	w->segnum = PHYSFSX_readInt(fp);
	w->sidenum = PHYSFSX_readInt(fp);
	w->type = PHYSFSX_readByte(fp);
	w->flags = PHYSFSX_readByte(fp);
	w->hps = PHYSFSX_readFix(fp);
	w->trigger = PHYSFSX_readByte(fp);
	w->clip_num = PHYSFSX_readByte(fp);
	w->keys = PHYSFSX_readByte(fp);
	w->linked_wall = PHYSFSX_readInt(fp);
}
Esempio n. 7
0
void player_ship_read(player_ship *ps, PHYSFS_file *fp)
{
	int i;
	ps->model_num = PHYSFSX_readInt(fp);
	ps->expl_vclip_num = PHYSFSX_readInt(fp);
	ps->mass = PHYSFSX_readFix(fp);
	ps->drag = PHYSFSX_readFix(fp);
	ps->max_thrust = PHYSFSX_readFix(fp);
	ps->reverse_thrust = PHYSFSX_readFix(fp);
	ps->brakes = PHYSFSX_readFix(fp);
	ps->wiggle = PHYSFSX_readFix(fp);
	ps->max_rotthrust = PHYSFSX_readFix(fp);
	for (i = 0; i < N_PLAYER_GUNS; i++)
		PHYSFSX_readVector(&ps->gun_points[i], fp);
}
Esempio n. 8
0
/*
 * reads a wall structure from a PHYSFS_file
 */
extern void wall_read(wall *w, PHYSFS_file *fp)
{
	w->segnum = PHYSFSX_readInt(fp);
	w->sidenum = PHYSFSX_readInt(fp);
	w->hps = PHYSFSX_readFix(fp);
	w->linked_wall = PHYSFSX_readInt(fp);
	w->type = PHYSFSX_readByte(fp);
	w->flags = PHYSFSX_readByte(fp);
	w->state = PHYSFSX_readByte(fp);
	w->trigger = PHYSFSX_readByte(fp);
	w->clip_num = PHYSFSX_readByte(fp);
	w->keys = PHYSFSX_readByte(fp);
	w->controlling_trigger = PHYSFSX_readByte(fp);
	w->cloak_value = PHYSFSX_readByte(fp);
}
Esempio n. 9
0
static void tmap_info_read(tmap_info &ti, PHYSFS_File *fp)
{
	PHYSFS_read(fp, ti.filename, 13, 1);
	ti.flags = PHYSFSX_readByte(fp);
	ti.lighting = PHYSFSX_readFix(fp);
	ti.damage = PHYSFSX_readFix(fp);
	ti.eclip_num = PHYSFSX_readInt(fp);
}
Esempio n. 10
0
/*
 * reads an active_door structure from a PHYSFS_file
 */
extern void active_door_read(active_door *ad, PHYSFS_file *fp)
{
	ad->n_parts = PHYSFSX_readInt(fp);
	ad->front_wallnum[0] = PHYSFSX_readShort(fp);
	ad->front_wallnum[1] = PHYSFSX_readShort(fp);
	ad->back_wallnum[0] = PHYSFSX_readShort(fp);
	ad->back_wallnum[1] = PHYSFSX_readShort(fp);
	ad->time = PHYSFSX_readFix(fp);
}
Esempio n. 11
0
/*
 * reads a DiskBitmapHeader structure from a PHYSFS_file
 */
void DiskBitmapHeader_read(DiskBitmapHeader *dbh, PHYSFS_file *fp)
{
	PHYSFS_read(fp, dbh->name, 8, 1);
	dbh->dflags = PHYSFSX_readByte(fp);
	dbh->width = PHYSFSX_readByte(fp);
	dbh->height = PHYSFSX_readByte(fp);
	dbh->flags = PHYSFSX_readByte(fp);
	dbh->avg_color = PHYSFSX_readByte(fp);
	dbh->offset = PHYSFSX_readInt(fp);
}
Esempio n. 12
0
/*
 * reads a v19_door structure from a PHYSFS_file
 */
extern void v19_door_read(v19_door *d, PHYSFS_file *fp)
{
	d->n_parts = PHYSFSX_readInt(fp);
	d->seg[0] = PHYSFSX_readShort(fp);
	d->seg[1] = PHYSFSX_readShort(fp);
	d->side[0] = PHYSFSX_readShort(fp);
	d->side[1] = PHYSFSX_readShort(fp);
	d->type[0] = PHYSFSX_readShort(fp);
	d->type[1] = PHYSFSX_readShort(fp);
	d->open = PHYSFSX_readFix(fp);
}
Esempio n. 13
0
/*
 * reads n eclip structs from a PHYSFS_file
 */
int eclip_read_n(eclip *ec, int n, PHYSFS_file *fp)
{
	int i;

	for (i = 0; i < n; i++) {
		vclip_read_n(&ec[i].vc, 1, fp);
		ec[i].time_left = PHYSFSX_readFix(fp);
		ec[i].frame_count = PHYSFSX_readInt(fp);
		ec[i].changing_wall_texture = PHYSFSX_readShort(fp);
		ec[i].changing_object_texture = PHYSFSX_readShort(fp);
		ec[i].flags = PHYSFSX_readInt(fp);
		ec[i].crit_clip = PHYSFSX_readInt(fp);
		ec[i].dest_bm_num = PHYSFSX_readInt(fp);
		ec[i].dest_vclip = PHYSFSX_readInt(fp);
		ec[i].dest_eclip = PHYSFSX_readInt(fp);
		ec[i].dest_size = PHYSFSX_readFix(fp);
		ec[i].sound_num = PHYSFSX_readInt(fp);
		ec[i].segnum = (segnum_t)PHYSFSX_readInt(fp);
		ec[i].sidenum = PHYSFSX_readInt(fp);
	}
	return i;
}
Esempio n. 14
0
void bm_read_all(PHYSFS_File * fp)
{
	unsigned t;

	NumTextures = PHYSFSX_readInt(fp);
	bitmap_index_read_n(fp, partial_range(Textures, NumTextures));
	range_for (tmap_info &ti, partial_range(TmapInfo, NumTextures))
		tmap_info_read(ti, fp);

	t = PHYSFSX_readInt(fp);
	PHYSFS_read( fp, Sounds, sizeof(ubyte), t );
	PHYSFS_read( fp, AltSounds, sizeof(ubyte), t );

	Num_vclips = PHYSFSX_readInt(fp);
	range_for (vclip &vc, partial_range(Vclip, Num_vclips))
		vclip_read(fp, vc);

	Num_effects = PHYSFSX_readInt(fp);
	range_for (eclip &ec, partial_range(Effects, Num_effects))
		eclip_read(fp, ec);

	Num_wall_anims = PHYSFSX_readInt(fp);
	range_for (auto &w, partial_range(WallAnims, Num_wall_anims))
		wclip_read(fp, w);

	N_robot_types = PHYSFSX_readInt(fp);
	range_for (auto &r, partial_range(Robot_info, N_robot_types))
		robot_info_read(fp, r);

	N_robot_joints = PHYSFSX_readInt(fp);
	range_for (auto &r, partial_range(Robot_joints, N_robot_joints))
		jointpos_read(fp, r);

	N_weapon_types = PHYSFSX_readInt(fp);
	weapon_info_read_n(Weapon_info, N_weapon_types, fp, Piggy_hamfile_version);

	N_powerup_types = PHYSFSX_readInt(fp);
	range_for (auto &p, partial_range(Powerup_info, N_powerup_types))
		powerup_type_info_read(fp, p);

	N_polygon_models = PHYSFSX_readInt(fp);
	{
		const auto &&r = partial_range(Polygon_models, N_polygon_models);
	range_for (auto &p, r)
		polymodel_read(&p, fp);

	range_for (auto &p, r)
		polygon_model_data_read(&p, fp);
	}

	range_for (auto &i, partial_range(Dying_modelnums, N_polygon_models))
		i = PHYSFSX_readInt(fp);
	range_for (auto &i, partial_range(Dead_modelnums, N_polygon_models))
		i = PHYSFSX_readInt(fp);

	t = PHYSFSX_readInt(fp);
	bitmap_index_read_n(fp, partial_range(Gauges, t));
	bitmap_index_read_n(fp, partial_range(Gauges_hires, t));

	N_ObjBitmaps = PHYSFSX_readInt(fp);
	bitmap_index_read_n(fp, partial_range(ObjBitmaps, N_ObjBitmaps));
	range_for (auto &i, partial_range(ObjBitmapPtrs, N_ObjBitmaps))
		i = PHYSFSX_readShort(fp);

	player_ship_read(&only_player_ship, fp);

	Num_cockpits = PHYSFSX_readInt(fp);
	bitmap_index_read_n(fp, partial_range(cockpit_bitmap, Num_cockpits));

//@@	PHYSFS_read( fp, &Num_total_object_types, sizeof(int), 1 );
//@@	PHYSFS_read( fp, ObjType, sizeof(byte), Num_total_object_types );
//@@	PHYSFS_read( fp, ObjId, sizeof(byte), Num_total_object_types );
//@@	PHYSFS_read( fp, ObjStrength, sizeof(fix), Num_total_object_types );

	First_multi_bitmap_num = PHYSFSX_readInt(fp);

	Num_reactors = PHYSFSX_readInt(fp);
	reactor_read_n(fp, partial_range(Reactors, Num_reactors));

	Marker_model_num = PHYSFSX_readInt(fp);

	//@@PHYSFS_read( fp, &N_controlcen_guns, sizeof(int), 1 );
	//@@PHYSFS_read( fp, controlcen_gun_points, sizeof(vms_vector), N_controlcen_guns );
	//@@PHYSFS_read( fp, controlcen_gun_dirs, sizeof(vms_vector), N_controlcen_guns );

	if (Piggy_hamfile_version < 3) {
		exit_modelnum = PHYSFSX_readInt(fp);
		destroyed_exit_modelnum = PHYSFSX_readInt(fp);
	}
	else
		exit_modelnum = destroyed_exit_modelnum = N_polygon_models;
}
Esempio n. 15
0
// Read compiled properties data from descent.pig
void properties_read_cmp(PHYSFS_File * fp)
{
	//  bitmap_index is a short
	
	NumTextures = PHYSFSX_readInt(fp);
	bitmap_index_read_n(fp, Textures);
	range_for (tmap_info &ti, TmapInfo)
		tmap_info_read(ti, fp);

	PHYSFS_read(fp, Sounds, sizeof(Sounds[0]), Sounds.size());
	PHYSFS_read(fp, AltSounds, sizeof(AltSounds[0]), AltSounds.size());
	
	Num_vclips = PHYSFSX_readInt(fp);
	range_for (vclip &vc, Vclip)
		vclip_read(fp, vc);

	Num_effects = PHYSFSX_readInt(fp);
	range_for (eclip &ec, Effects)
		eclip_read(fp, ec);

	Num_wall_anims = PHYSFSX_readInt(fp);
	range_for (auto &w, WallAnims)
		wclip_read(fp, w);

	N_robot_types = PHYSFSX_readInt(fp);
	range_for (auto &r, Robot_info)
		robot_info_read(fp, r);

	N_robot_joints = PHYSFSX_readInt(fp);
	range_for (auto &r, Robot_joints)
		jointpos_read(fp, r);

	N_weapon_types = PHYSFSX_readInt(fp);
	weapon_info_read_n(Weapon_info, MAX_WEAPON_TYPES, fp, 0);

	N_powerup_types = PHYSFSX_readInt(fp);
	range_for (auto &p, Powerup_info)
		powerup_type_info_read(fp, p);

	N_polygon_models = PHYSFSX_readInt(fp);
	{
		const auto &&r = partial_range(Polygon_models, N_polygon_models);
	range_for (auto &p, r)
		polymodel_read(&p, fp);

	range_for (auto &p, r)
		polygon_model_data_read(&p, fp);
	}

	bitmap_index_read_n(fp, partial_range(Gauges, MAX_GAUGE_BMS));
	
	range_for (auto &i, Dying_modelnums)
		i = PHYSFSX_readInt(fp);
	range_for (auto &i, Dead_modelnums)
		i = PHYSFSX_readInt(fp);

	bitmap_index_read_n(fp, ObjBitmaps);
	range_for (auto &i, ObjBitmapPtrs)
		i = PHYSFSX_readShort(fp);

	player_ship_read(&only_player_ship, fp);

	Num_cockpits = PHYSFSX_readInt(fp);
	bitmap_index_read_n(fp, cockpit_bitmap);

	PHYSFS_read(fp, Sounds, sizeof(Sounds[0]), Sounds.size());
	PHYSFS_read(fp, AltSounds, sizeof(AltSounds[0]), AltSounds.size());

	Num_total_object_types = PHYSFSX_readInt(fp);
	PHYSFS_read( fp, ObjType, sizeof(ubyte), MAX_OBJTYPE );
	PHYSFS_read( fp, ObjId, sizeof(ubyte), MAX_OBJTYPE );
	range_for (auto &i, ObjStrength)
		i = PHYSFSX_readFix(fp);

	First_multi_bitmap_num = PHYSFSX_readInt(fp);
	Reactors[0].n_guns = PHYSFSX_readInt(fp);

	range_for (auto &i, Reactors[0].gun_points)
		PHYSFSX_readVector(fp, i);
	range_for (auto &i, Reactors[0].gun_dirs)
		PHYSFSX_readVector(fp, i);

	exit_modelnum = PHYSFSX_readInt(fp);	
	destroyed_exit_modelnum = PHYSFSX_readInt(fp);

#if DXX_USE_EDITOR
        //Build tmaplist
	auto &&effect_range = partial_const_range(Effects, Num_effects);
	Num_tmaps = TextureEffects + std::count_if(effect_range.begin(), effect_range.end(), [](const eclip &e) { return e.changing_wall_texture >= 0; });
        #endif
}
Esempio n. 16
0
//read in the player's saved games.  returns errno (0 == no error)
int read_player_file()
{
	char filename[PATH_MAX];
	PHYSFS_file *file;
	int player_file_size, shareware_file = -1, id = 0;
	short saved_game_version, player_struct_version;

	Assert(Player_num>=0 && Player_num<MAX_PLAYERS);

	memset(filename, '\0', PATH_MAX);
	snprintf(filename, PATH_MAX, GameArg.SysUsePlayersDir? "Players/%.8s.plr" : "%.8s.plr", Players[Player_num].callsign);
	if (!PHYSFSX_exists(filename,0))
		return ENOENT;

	file = PHYSFSX_openReadBuffered(filename);

	if (!file)
		goto read_player_file_failed;

	new_player_config(); // Set defaults!

	// Unfortunatly d1x has been writing both shareware and registered
	// player files with a saved_game_version of 7 and 8, whereas the
	// original decent used 4 for shareware games and 7 for registered
	// games. Because of this the player files didn't get properly read
	// when reading d1x shareware player files in d1x registered or
	// vica versa. The problem is that the sizeof of the taunt macros
	// differ between the share and registered versions, causing the
	// reading of the player file to go wrong. Thus we now determine the
	// sizeof the player file to determine what kinda player file we are
	// dealing with so that we can do the right thing
	PHYSFS_seek(file, 0);
	player_file_size = PHYSFS_fileLength(file);

	PHYSFS_readSLE32(file, &id);
	saved_game_version = PHYSFSX_readShort(file);
	player_struct_version = PHYSFSX_readShort(file);
	PlayerCfg.NHighestLevels = PHYSFSX_readInt(file);
	PlayerCfg.DefaultDifficulty = PHYSFSX_readInt(file);
	PlayerCfg.AutoLeveling = PHYSFSX_readInt(file);

	if (id!=SAVE_FILE_ID) {
		nm_messagebox(TXT_ERROR, 1, TXT_OK, "Invalid player file");
		PHYSFS_close(file);
		return -1;
	}

	if (saved_game_version<COMPATIBLE_SAVED_GAME_VERSION || player_struct_version<COMPATIBLE_PLAYER_STRUCT_VERSION) {
		nm_messagebox(TXT_ERROR, 1, TXT_OK, TXT_ERROR_PLR_VERSION);
		PHYSFS_close(file);
		return -1;
	}

	/* determine if we're dealing with a shareware or registered playerfile */
	switch (saved_game_version)
	{
		case 4:
			shareware_file = 1;
			break;
		case 5:
		case 6:
			shareware_file = 0;
			break;
		case 7:
			/* version 7 doesn't have the saved games array */
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 - sizeof(saved_games)))
				shareware_file = 1;
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 - sizeof(saved_games)))
				shareware_file = 0;
			break;
		case 8:
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2212)
				shareware_file = 1;
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == 2252)
				shareware_file = 0;
			/* d1x-rebirth v0.31 to v0.42 broke things by adding stuff to the
			   player struct without thinking (sigh) */
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2212 + 2*sizeof(int)))
			{

				shareware_file = 1;
				/* skip the cruft added to the player_info struct */
				PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int));
			}
			if ((player_file_size - (sizeof(hli)*PlayerCfg.NHighestLevels)) == (2252 + 2*sizeof(int)))
			{
				shareware_file = 0;
				/* skip the cruft added to the player_info struct */
				PHYSFS_seek(file, PHYSFS_tell(file)+2*sizeof(int));
			}
	}

	if (shareware_file == -1) {
		nm_messagebox(TXT_ERROR, 1, TXT_OK, "Error invalid or unknown\nplayerfile-size");
		PHYSFS_close(file);
		return -1;
	}

	if (saved_game_version <= 5) {

		//deal with old-style highest level info

		PlayerCfg.HighestLevels[0].Shortname[0] = 0;							//no name for mission 0
		PlayerCfg.HighestLevels[0].LevelNum = PlayerCfg.NHighestLevels;	//was highest level in old struct

		//This hack allows the player to start on level 8 if he's made it to
		//level 7 on the shareware.  We do this because the shareware didn't
		//save the information that the player finished level 7, so the most
		//we know is that he made it to level 7.
		if (PlayerCfg.NHighestLevels==7)
			PlayerCfg.HighestLevels[0].LevelNum = 8;
		
	}
	else {	//read new highest level info
		if (PHYSFS_read(file,PlayerCfg.HighestLevels,sizeof(hli),PlayerCfg.NHighestLevels) != PlayerCfg.NHighestLevels)
			goto read_player_file_failed;
	}

	if ( saved_game_version != 7 ) {	// Read old & SW saved games.
		if (PHYSFS_read(file,saved_games,sizeof(saved_games),1) != 1)
			goto read_player_file_failed;
	}

	//read taunt macros
	{
		int i;
		int len = shareware_file? 25:35;

		#ifdef NETWORK
		for (i = 0; i < 4; i++)
			if (PHYSFS_read(file, PlayerCfg.NetworkMessageMacro[i], len, 1) != 1)
				goto read_player_file_failed;
		#else
		i = 0;
		PHYSFS_seek( file, PHYSFS_tell(file)+4*len );
		#endif
	}

	//read kconfig data
	{
		ubyte dummy_joy_sens;

		if (PHYSFS_read(file, &PlayerCfg.KeySettings[0], sizeof(PlayerCfg.KeySettings[0]),1)!=1)
			goto read_player_file_failed;
		if (PHYSFS_read(file, &PlayerCfg.KeySettings[1], sizeof(PlayerCfg.KeySettings[1]),1)!=1)
			goto read_player_file_failed;
		PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS*3) ); // Skip obsolete Flightstick/Thrustmaster/Gravis map fields
		if (PHYSFS_read(file, &PlayerCfg.KeySettings[2], sizeof(PlayerCfg.KeySettings[2]),1)!=1)
			goto read_player_file_failed;
		PHYSFS_seek( file, PHYSFS_tell(file)+(sizeof(ubyte)*MAX_CONTROLS) ); // Skip obsolete Cyberman map field
		if (PHYSFS_read(file, &PlayerCfg.ControlType, sizeof(ubyte), 1 )!=1)
			goto read_player_file_failed;
		else if (PHYSFS_read(file, &dummy_joy_sens, sizeof(ubyte), 1 )!=1)
			goto read_player_file_failed;
	}

	if ( saved_game_version != 7 ) 	{
		int i, found=0;
		
		Assert( N_SAVE_SLOTS == 10 );

		for (i=0; i<N_SAVE_SLOTS; i++ )	{
			if ( saved_games[i].name[0] )	{
				state_save_old_game(i, saved_games[i].name, &saved_games[i].sg_player, saved_games[i].difficulty_level, saved_games[i].primary_weapon, saved_games[i].secondary_weapon, saved_games[i].next_level_num );
				// make sure we do not do this again, which would possibly overwrite
				// a new newstyle savegame
				saved_games[i].name[0] = 0;
				found++;
			}
		}
		if (found)
			write_player_file();
	}

	if (!PHYSFS_close(file))
		goto read_player_file_failed;

	filename[strlen(filename) - 4] = 0;
	strcat(filename, ".plx");
	read_player_d1x(filename);
	kc_set_controls();

	return EZERO;

 read_player_file_failed:
	nm_messagebox(TXT_ERROR, 1, TXT_OK, "%s\n\n%s", "Error reading PLR file", PHYSFS_getLastError());
	if (file)
		PHYSFS_close(file);

	return -1;
}
Esempio n. 17
0
//type==1 means 1.1, type==2 means 1.2 (with weapons)
void bm_read_extra_robots(char *fname,int type)
{
	PHYSFS_file *fp;
	int t,i,version;

	fp = PHYSFSX_openReadBuffered(fname);
	if (!fp)
	{
		Error("Failed to open HAM file \"%s\"", fname);
		return;
	}

	if (type == 2) {
		int sig;

		sig = PHYSFSX_readInt(fp);
		if (sig != MAKE_SIG('X','H','A','M'))
			return;
		version = PHYSFSX_readInt(fp);
	}
	else
		version = 0;
	(void)version; // NOTE: we do not need it, but keep it for possible further use

	bm_free_extra_models();
	bm_free_extra_objbitmaps();

	//read extra weapons

	t = PHYSFSX_readInt(fp);
	N_weapon_types = N_D2_WEAPON_TYPES+t;
	if (N_weapon_types >= MAX_WEAPON_TYPES)
		Error("Too many weapons (%d) in <%s>.  Max is %d.",t,fname,MAX_WEAPON_TYPES-N_D2_WEAPON_TYPES);
	weapon_info_read_n(&Weapon_info[N_D2_WEAPON_TYPES], t, fp, 3);

	//now read robot info

	t = PHYSFSX_readInt(fp);
	N_robot_types = N_D2_ROBOT_TYPES+t;
	if (N_robot_types >= MAX_ROBOT_TYPES)
		Error("Too many robots (%d) in <%s>.  Max is %d.",t,fname,MAX_ROBOT_TYPES-N_D2_ROBOT_TYPES);
	robot_info_read_n(&Robot_info[N_D2_ROBOT_TYPES], t, fp);

	t = PHYSFSX_readInt(fp);
	N_robot_joints = N_D2_ROBOT_JOINTS+t;
	if (N_robot_joints >= MAX_ROBOT_JOINTS)
		Error("Too many robot joints (%d) in <%s>.  Max is %d.",t,fname,MAX_ROBOT_JOINTS-N_D2_ROBOT_JOINTS);
	jointpos_read_n(&Robot_joints[N_D2_ROBOT_JOINTS], t, fp);

	t = PHYSFSX_readInt(fp);
	N_polygon_models = N_D2_POLYGON_MODELS+t;
	if (N_polygon_models >= MAX_POLYGON_MODELS)
		Error("Too many polygon models (%d) in <%s>.  Max is %d.",t,fname,MAX_POLYGON_MODELS-N_D2_POLYGON_MODELS);
	polymodel_read_n(&Polygon_models[N_D2_POLYGON_MODELS], t, fp);

	for (i=N_D2_POLYGON_MODELS; i<N_polygon_models; i++ )
		polygon_model_data_read(&Polygon_models[i], fp);

	for (i = N_D2_POLYGON_MODELS; i < N_polygon_models; i++)
		Dying_modelnums[i] = PHYSFSX_readInt(fp);
	for (i = N_D2_POLYGON_MODELS; i < N_polygon_models; i++)
		Dead_modelnums[i] = PHYSFSX_readInt(fp);

	t = PHYSFSX_readInt(fp);
	if (N_D2_OBJBITMAPS+t >= MAX_OBJ_BITMAPS)
		Error("Too many object bitmaps (%d) in <%s>.  Max is %d.",t,fname,MAX_OBJ_BITMAPS-N_D2_OBJBITMAPS);
	bitmap_index_read_n(&ObjBitmaps[N_D2_OBJBITMAPS], t, fp);

	t = PHYSFSX_readInt(fp);
	if (N_D2_OBJBITMAPPTRS+t >= MAX_OBJ_BITMAPS)
		Error("Too many object bitmap pointers (%d) in <%s>.  Max is %d.",t,fname,MAX_OBJ_BITMAPS-N_D2_OBJBITMAPPTRS);
	for (i = N_D2_OBJBITMAPPTRS; i < (N_D2_OBJBITMAPPTRS + t); i++)
		ObjBitmapPtrs[i] = PHYSFSX_readShort(fp);

	PHYSFS_close(fp);
}
Esempio n. 18
0
int properties_init()
{
	int sbytes = 0;
	char temp_name_read[16];
	char temp_name[16];
	grs_bitmap temp_bitmap;
	digi_sound temp_sound;
	DiskBitmapHeader bmh;
	DiskSoundHeader sndh;
	int header_size, N_bitmaps, N_sounds;
	int i,size;
	int Pigdata_start;
	int pigsize;
	int retval;

	hashtable_init( &AllBitmapsNames, MAX_BITMAP_FILES );
	hashtable_init( &AllDigiSndNames, MAX_SOUND_FILES );

	
	for (i=0; i<MAX_SOUND_FILES; i++ )	{
#ifdef ALLEGRO
		GameSounds[i].len = 0;
#else
		GameSounds[i].length = 0;
#endif
		GameSounds[i].data = NULL;
		SoundOffset[i] = 0;

//added on 11/13/99 by Victor Rachels to ready for changing freq
                GameSounds[i].bits = 0;
                GameSounds[i].freq = 0;
//end this section addition - VR
	}

	for (i=0; i<MAX_BITMAP_FILES; i++ )		{
		GameBitmapXlat[i] = i;
		GameBitmaps[i].bm_flags = BM_FLAG_PAGED_OUT;
	}

	if ( !bogus_bitmap_initialized )	{
		int i;
		ubyte c;
		bogus_bitmap_initialized = 1;
		c = gr_find_closest_color( 0, 0, 63 );
		for (i=0; i<4096; i++ ) bogus_data[i] = c;
		c = gr_find_closest_color( 63, 0, 0 );
		// Make a big red X !
		for (i=0; i<64; i++ )	{
			bogus_data[i*64+i] = c;
			bogus_data[i*64+(63-i)] = c;
		}
		gr_init_bitmap (&bogus_bitmap, 0, 0, 0, 64, 64, 64, bogus_data);
		piggy_register_bitmap( &bogus_bitmap, "bogus", 1 );
#ifdef ALLEGRO
		bogus_sound.len = 64*64;
#else
        bogus_sound.length = 64*64;
#endif
		bogus_sound.data = bogus_data;
//added on 11/13/99 by Victor Rachels to ready for changing freq
                bogus_sound.freq = 11025;
                bogus_sound.bits = 8;
//end this section addition - VR
		GameBitmapOffset[0] = 0;
	}
	
	Piggy_fp = PHYSFSX_openReadBuffered(DEFAULT_PIGFILE_REGISTERED);
	if (Piggy_fp==NULL)
	{
		if (!PHYSFSX_exists("BITMAPS.TBL",1) && !PHYSFSX_exists("BITMAPS.BIN",1))
			Error("Cannot find " DEFAULT_PIGFILE_REGISTERED " or BITMAPS.TBL");
		return 1;	// need to run gamedata_read_tbl
	}

	pigsize = PHYSFS_fileLength(Piggy_fp);
	switch (pigsize) {
		case D1_SHARE_BIG_PIGSIZE:
		case D1_SHARE_10_PIGSIZE:
		case D1_SHARE_PIGSIZE:
			PCSharePig = 1;
			Pigdata_start = 0;
			break;
		case D1_10_BIG_PIGSIZE:
		case D1_10_PIGSIZE:
			Pigdata_start = 0;
			break;
		default:
			Warning("Unknown size for " DEFAULT_PIGFILE_REGISTERED);
			Int3();
			// fall through
		case D1_MAC_PIGSIZE:
		case D1_MAC_SHARE_PIGSIZE:
			MacPig = 1;
		case D1_PIGSIZE:
		case D1_OEM_PIGSIZE:
			Pigdata_start = PHYSFSX_readInt(Piggy_fp );
			break;
	}
	
	HiresGFXAvailable = MacPig;	// for now at least

	if (PCSharePig)
		retval = PIGGY_PC_SHAREWARE;	// run gamedata_read_tbl in shareware mode
	else if (GameArg.EdiNoBm || (!PHYSFSX_exists("BITMAPS.TBL",1) && !PHYSFSX_exists("BITMAPS.BIN",1)))
	{
		properties_read_cmp( Piggy_fp );	// Note connection to above if!!!
		for (i = 0; i < MAX_BITMAP_FILES; i++)
		{
			GameBitmapXlat[i] = PHYSFSX_readShort(Piggy_fp);
			if (PHYSFS_eof(Piggy_fp))
				break;
		}
		retval = 0;	// don't run gamedata_read_tbl
	}
	else
		retval = 1;	// run gamedata_read_tbl

	PHYSFSX_fseek( Piggy_fp, Pigdata_start, SEEK_SET );
	size = PHYSFS_fileLength(Piggy_fp) - Pigdata_start;

	N_bitmaps = PHYSFSX_readInt(Piggy_fp);
	size -= sizeof(int);
	N_sounds = PHYSFSX_readInt(Piggy_fp);
	size -= sizeof(int);

	header_size = (N_bitmaps*sizeof(DiskBitmapHeader)) + (N_sounds*sizeof(DiskSoundHeader));

	for (i=0; i<N_bitmaps; i++ )	{
		DiskBitmapHeader_read(&bmh, Piggy_fp);
		
		GameBitmapFlags[i+1] = 0;
		if ( bmh.flags & BM_FLAG_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_TRANSPARENT;
		if ( bmh.flags & BM_FLAG_SUPER_TRANSPARENT ) GameBitmapFlags[i+1] |= BM_FLAG_SUPER_TRANSPARENT;
		if ( bmh.flags & BM_FLAG_NO_LIGHTING ) GameBitmapFlags[i+1] |= BM_FLAG_NO_LIGHTING;
		if ( bmh.flags & BM_FLAG_RLE ) GameBitmapFlags[i+1] |= BM_FLAG_RLE;

		GameBitmapOffset[i+1] = bmh.offset + header_size + (sizeof(int)*2) + Pigdata_start;
		Assert( (i+1) == Num_bitmap_files );

		//size -= sizeof(DiskBitmapHeader);
		memcpy( temp_name_read, bmh.name, 8 );
		temp_name_read[8] = 0;
		if ( bmh.dflags & DBM_FLAG_ABM )	
			sprintf( temp_name, "%s#%d", temp_name_read, bmh.dflags & 63 );
		else
			strcpy( temp_name, temp_name_read );

		memset( &temp_bitmap, 0, sizeof(grs_bitmap) );
		gr_init_bitmap( &temp_bitmap, 0, 0, 0, 
			(bmh.dflags & DBM_FLAG_LARGE) ? bmh.width + 256 : bmh.width, bmh.height,
			(bmh.dflags & DBM_FLAG_LARGE) ? bmh.width + 256 : bmh.width, Piggy_bitmap_cache_data);
		temp_bitmap.bm_flags |= BM_FLAG_PAGED_OUT;
		temp_bitmap.avg_color = bmh.avg_color;

		if (MacPig)
		{
			// HACK HACK HACK!!!!!
			if (!strnicmp(bmh.name, "cockpit", 7) || !strnicmp(bmh.name, "status", 6) || !strnicmp(bmh.name, "rearview", 8)) {
				temp_bitmap.bm_w = temp_bitmap.bm_rowsize = 640;
				if (GameBitmapFlags[i+1] & BM_FLAG_RLE)
					GameBitmapFlags[i+1] |= BM_FLAG_RLE_BIG;
			}
			if (!strnicmp(bmh.name, "cockpit", 7) || !strnicmp(bmh.name, "rearview", 8))
				temp_bitmap.bm_h = 480;
		}
		
		piggy_register_bitmap( &temp_bitmap, temp_name, 1 );
	}

	for (i=0; !MacPig && i<N_sounds; i++ )     {
		DiskSoundHeader_read(&sndh, Piggy_fp);
		
		//size -= sizeof(DiskSoundHeader);
#ifdef ALLEGRO
		temp_sound.len = sndh.length;
#else
		temp_sound.length = sndh.length;
#endif

//added on 11/13/99 by Victor Rachels to ready for changing freq
                temp_sound.bits = 8;
                temp_sound.freq = 11025;
//end this section addition - VR
		temp_sound.data = (ubyte *)(sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start);
		SoundOffset[Num_sound_files] = sndh.offset + header_size + (sizeof(int)*2)+Pigdata_start;
		if (PCSharePig)
			SoundCompressed[Num_sound_files] = sndh.data_length;
		memcpy( temp_name_read, sndh.name, 8 );
		temp_name_read[8] = 0;
		piggy_register_sound( &temp_sound, temp_name_read, 1 );
                sbytes += sndh.length;
	}

	if (!MacPig)
	{
		SoundBits = d_malloc( sbytes + 16 );
		if ( SoundBits == NULL )
			Error( "Not enough memory to load DESCENT.PIG sounds\n");
	}

#if 1	//def EDITOR
	Piggy_bitmap_cache_size	= size - header_size - sbytes + 16;
	Assert( Piggy_bitmap_cache_size > 0 );
#else
	Piggy_bitmap_cache_size = PIGGY_BUFFER_SIZE;
	if (GameArg.SysLowMem)
		Piggy_bitmap_cache_size = PIGGY_SMALL_BUFFER_SIZE;
#endif
	BitmapBits = d_malloc( Piggy_bitmap_cache_size );
	if ( BitmapBits == NULL )
		Error( "Not enough memory to load DESCENT.PIG bitmaps\n" );
	Piggy_bitmap_cache_data = BitmapBits;	
	Piggy_bitmap_cache_next = 0;

	return retval;
}
Esempio n. 19
0
int load_mine_data_compiled(PHYSFS_file *LoadFile)
{
	int     i, segnum, sidenum;
	ubyte   compiled_version;
	short   temp_short;
	ushort  temp_ushort = 0;
	ubyte   bit_mask;

	d1_pig_present = PHYSFSX_exists(D1_PIGFILE,1);
#if 0 // the following will be deleted once reading old pigfiles works reliably
	if (d1_pig_present) {
		PHYSFS_file * d1_Piggy_fp = PHYSFSX_openReadBuffered( D1_PIGFILE );
		switch (PHYSFS_fileLength(d1_Piggy_fp)) {
		case D1_SHARE_BIG_PIGSIZE:
		case D1_SHARE_10_PIGSIZE:
		case D1_SHARE_PIGSIZE:
		case D1_10_BIG_PIGSIZE:
		case D1_10_PIGSIZE:
			//d1_pig_present = 0;
		}
		PHYSFS_close (d1_Piggy_fp);
	}
#endif

	if (!strcmp(strchr(Gamesave_current_filename, '.'), ".sdl"))
		New_file_format_load = 0; // descent 1 shareware
	else
		New_file_format_load = 1;

	//	For compiled levels, textures map to themselves, prevent tmap_override always being gray,
	//	bug which Matt and John refused to acknowledge, so here is Mike, fixing it.
#ifdef EDITOR
	for (i=0; i<MAX_TEXTURES; i++)
		tmap_xlate_table[i] = i;
#endif

//	memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS );
	fuelcen_reset();

	//=============================== Reading part ==============================
	compiled_version = PHYSFSX_readByte(LoadFile);
	(void)compiled_version;

	if (New_file_format_load)
		Num_vertices = PHYSFSX_readShort(LoadFile);
	else
		Num_vertices = PHYSFSX_readInt(LoadFile);
	Assert( Num_vertices <= MAX_VERTICES );

	if (New_file_format_load)
		Num_segments = PHYSFSX_readShort(LoadFile);
	else
		Num_segments = PHYSFSX_readInt(LoadFile);
	Assert( Num_segments <= MAX_SEGMENTS );

	for (i = 0; i < Num_vertices; i++)
		PHYSFSX_readVector( &(Vertices[i]), LoadFile);

	for (segnum=0; segnum<Num_segments; segnum++ )	{

		#ifdef EDITOR
		Segments[segnum].segnum = segnum;
		Segments[segnum].group = 0;
		#endif

		if (New_file_format_load)
			bit_mask = PHYSFSX_readByte(LoadFile);
		else
			bit_mask = 0x7f; // read all six children and special stuff...

		if (Gamesave_current_version == 5) { // d2 SHAREWARE level
			read_special(segnum,bit_mask,LoadFile);
			read_verts(segnum,LoadFile);
			read_children(segnum,bit_mask,LoadFile);
		} else {
			read_children(segnum,bit_mask,LoadFile);
			read_verts(segnum,LoadFile);
			if (Gamesave_current_version <= 1) { // descent 1 level
				read_special(segnum,bit_mask,LoadFile);
			}
		}

		Segments[segnum].objects = -1;

		if (Gamesave_current_version <= 5) { // descent 1 thru d2 SHAREWARE level
			// Read fix	Segments[segnum].static_light (shift down 5 bits, write as short)
			temp_ushort = PHYSFSX_readShort(LoadFile);
			Segment2s[segnum].static_light	= ((fix)temp_ushort) << 4;
			//PHYSFS_read( LoadFile, &Segments[segnum].static_light, sizeof(fix), 1 );
		}

		// Read the walls as a 6 byte array
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{
			Segments[segnum].sides[sidenum].pad = 0;
		}

		if (New_file_format_load)
			bit_mask = PHYSFSX_readByte(LoadFile);
		else
			bit_mask = 0x3f; // read all six sides
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
			ubyte byte_wallnum;

			if (bit_mask & (1 << sidenum)) {
				byte_wallnum = PHYSFSX_readByte(LoadFile);
				if ( byte_wallnum == 255 )
					Segments[segnum].sides[sidenum].wall_num = -1;
				else
					Segments[segnum].sides[sidenum].wall_num = byte_wallnum;
			} else
					Segments[segnum].sides[sidenum].wall_num = -1;
		}

		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{

			if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) )	{
				// Read short Segments[segnum].sides[sidenum].tmap_num;
				if (New_file_format_load) {
					temp_ushort = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff;
				} else
					Segments[segnum].sides[sidenum].tmap_num = PHYSFSX_readShort(LoadFile);

				if (Gamesave_current_version <= 1)
					Segments[segnum].sides[sidenum].tmap_num = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num);

				if (New_file_format_load && !(temp_ushort & 0x8000))
					Segments[segnum].sides[sidenum].tmap_num2 = 0;
				else {
					// Read short Segments[segnum].sides[sidenum].tmap_num2;
					Segments[segnum].sides[sidenum].tmap_num2 = PHYSFSX_readShort(LoadFile);
					if (Gamesave_current_version <= 1 && Segments[segnum].sides[sidenum].tmap_num2 != 0)
						Segments[segnum].sides[sidenum].tmap_num2 = convert_d1_tmap_num(Segments[segnum].sides[sidenum].tmap_num2);
				}

				// Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short)
				for (i=0; i<4; i++ )	{
					temp_short = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
					temp_short = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
					temp_ushort = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
					//PHYSFS_read( LoadFile, &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1 );
				}
			} else {
				Segments[segnum].sides[sidenum].tmap_num = 0;
				Segments[segnum].sides[sidenum].tmap_num2 = 0;
				for (i=0; i<4; i++ )	{
					Segments[segnum].sides[sidenum].uvls[i].u = 0;
					Segments[segnum].sides[sidenum].uvls[i].v = 0;
					Segments[segnum].sides[sidenum].uvls[i].l = 0;
				}
			}
		}
	}

#if 0
	{
		FILE *fp;

		fp = fopen("segments.out", "wt");
		for (i = 0; i <= Highest_segment_index; i++) {
			side	sides[MAX_SIDES_PER_SEGMENT];	// 6 sides
			short	children[MAX_SIDES_PER_SEGMENT];	// indices of 6 children segments, front, left, top, right, bottom, back
			short	verts[MAX_VERTICES_PER_SEGMENT];	// vertex ids of 4 front and 4 back vertices
			int		objects;								// pointer to objects in this segment

			for (j = 0; j < MAX_SIDES_PER_SEGMENT; j++) {
				sbyte   type;                           // replaces num_faces and tri_edge, 1 = quad, 2 = 0:2 triangulation, 3 = 1:3 triangulation
				ubyte	pad;									//keep us longword alligned
				short	wall_num;
				short	tmap_num;
				short	tmap_num2;
				uvl		uvls[4];
				vms_vector	normals[2];						// 2 normals, if quadrilateral, both the same.
				fprintf(fp, "%d\n", Segments[i].sides[j].type);
				fprintf(fp, "%d\n", Segments[i].sides[j].pad);
				fprintf(fp, "%d\n", Segments[i].sides[j].wall_num);
				fprintf(fp, "%d\n", Segments[i].tmap_num);

			}
			fclose(fp);
		}
	}
#endif

	Highest_vertex_index = Num_vertices-1;
	Highest_segment_index = Num_segments-1;

	validate_segment_all();			// Fill in side type and normals.

	for (i=0; i<Num_segments; i++) {
		if (Gamesave_current_version > 5)
			segment2_read(&Segment2s[i], LoadFile);
		fuelcen_activate( &Segments[i], Segment2s[i].special );
	}

	reset_objects(1);		//one object, the player

	return 0;
}
Esempio n. 20
0
int load_mine_data_compiled(PHYSFS_file *LoadFile)
{
	int     i, segnum, sidenum;
	ubyte   compiled_version;
	short   temp_short;
	ushort  temp_ushort = 0;
	ubyte   bit_mask;
	
	if (!strcmp(strchr(Gamesave_current_filename, '.'), ".sdl"))
		New_file_format_load = 0; // descent 1 shareware
	else
		New_file_format_load = 1;
	
	//	For compiled levels, textures map to themselves, prevent tmap_override always being gray,
	//	bug which Matt and John refused to acknowledge, so here is Mike, fixing it.
	// 
	// Although in a cloud of arrogant glee, he forgot to ifdef it on EDITOR!
	// (Matt told me to write that!)
#ifdef EDITOR
	for (i=0; i<MAX_TEXTURES; i++)
		tmap_xlate_table[i] = i;
#endif
//	memset( Segments, 0, sizeof(segment)*MAX_SEGMENTS );
	fuelcen_reset();

	//=============================== Reading part ==============================
	compiled_version = PHYSFSX_readByte(LoadFile);
	(void)compiled_version;

	if (New_file_format_load)
		Num_vertices = PHYSFSX_readShort(LoadFile);
	else
		Num_vertices = PHYSFSX_readInt(LoadFile);
	Assert( Num_vertices <= MAX_VERTICES );
	
	if (New_file_format_load)
		Num_segments = PHYSFSX_readShort(LoadFile);
	else
		Num_segments = PHYSFSX_readInt(LoadFile);
	Assert( Num_segments <= MAX_SEGMENTS );
	
	for (i = 0; i < Num_vertices; i++)
		PHYSFSX_readVector( &(Vertices[i]), LoadFile);
	
	for (segnum=0; segnum<Num_segments; segnum++ )	{

		#ifdef EDITOR
		Segments[segnum].segnum = segnum;
		Segments[segnum].group = 0;
		#endif

		if (New_file_format_load)
			bit_mask = PHYSFSX_readByte(LoadFile);
		else
			bit_mask = 0x7f; // read all six children and special stuff...
		
		if (Gamesave_current_version == 5) { // d2 SHAREWARE level
			read_special(segnum,bit_mask,LoadFile);
			read_verts(segnum,LoadFile);
			read_children(segnum,bit_mask,LoadFile);
		} else {
			read_children(segnum,bit_mask,LoadFile);
			read_verts(segnum,LoadFile);
			if (Gamesave_current_version <= 1) { // descent 1 level
				read_special(segnum,bit_mask,LoadFile);
			}
		}
		
		Segments[segnum].objects = -1;

		if (Gamesave_current_version <= 5) { // descent 1 thru d2 SHAREWARE level
											 // Read fix	Segments[segnum].static_light (shift down 5 bits, write as short)
			temp_ushort = PHYSFSX_readShort(LoadFile);
			Segments[segnum].static_light	= ((fix)temp_ushort) << 4;
			//PHYSFS_read( LoadFile, &Segments[segnum].static_light, sizeof(fix), 1 );
		}
		
		// Read the walls as a 6 byte array
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{
			Segments[segnum].sides[sidenum].pad = 0;
		}
		
		if (New_file_format_load)
			bit_mask = PHYSFSX_readByte(LoadFile);
		else
			bit_mask = 0x3f; // read all six sides
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
			ubyte byte_wallnum;
			
			if (bit_mask & (1 << sidenum)) {
				byte_wallnum = PHYSFSX_readByte(LoadFile);
				if ( byte_wallnum == 255 )
					Segments[segnum].sides[sidenum].wall_num = -1;
				else
					Segments[segnum].sides[sidenum].wall_num = byte_wallnum;
			} else
				Segments[segnum].sides[sidenum].wall_num = -1;
		}
		
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{
			
			if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) )	{
				// Read short Segments[segnum].sides[sidenum].tmap_num;
				temp_ushort = PHYSFSX_readShort(LoadFile);

				Segments[segnum].sides[sidenum].tmap_num = convert_tmap(temp_ushort & 0x7fff);

				if (New_file_format_load && !(temp_ushort & 0x8000))
					Segments[segnum].sides[sidenum].tmap_num2 = 0;
				else {
					// Read short Segments[segnum].sides[sidenum].tmap_num2;
					Segments[segnum].sides[sidenum].tmap_num2 = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].tmap_num2 =
						(convert_tmap(Segments[segnum].sides[sidenum].tmap_num2 & 0x3fff)) |
						(Segments[segnum].sides[sidenum].tmap_num2 & 0xc000);
				}
				
				// Read uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short)
				for (i=0; i<4; i++ )	{
					temp_short = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
					temp_short = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
					temp_ushort = PHYSFSX_readShort(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
					//PHYSFS_read( LoadFile, &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1 );
				}
			} else {
				Segments[segnum].sides[sidenum].tmap_num = 0;
				Segments[segnum].sides[sidenum].tmap_num2 = 0;
				for (i=0; i<4; i++ )	{
					Segments[segnum].sides[sidenum].uvls[i].u = 0;
					Segments[segnum].sides[sidenum].uvls[i].v = 0;
					Segments[segnum].sides[sidenum].uvls[i].l = 0;
				}
			}
		}
	}
	
	Highest_vertex_index = Num_vertices-1;
	Highest_segment_index = Num_segments-1;

	validate_segment_all();			// Fill in side type and normals.

	for (i=0; i<Num_segments; i++) {
		if (Gamesave_current_version > 5)
			segment2_read(&Segments[i], LoadFile);
		fuelcen_activate( &Segments[i], Segments[i].special );
	}
	
	reset_objects(1);		//one object, the player

	return 0;
}
Esempio n. 21
0
void bm_read_all(PHYSFS_file * fp)
{
	int i,t;

	NumTextures = PHYSFSX_readInt(fp);
	bitmap_index_read_n(Textures, NumTextures, fp );
	tmap_info_read_n(TmapInfo, NumTextures, fp);

	t = PHYSFSX_readInt(fp);
	PHYSFS_read( fp, Sounds, sizeof(ubyte), t );
	PHYSFS_read( fp, AltSounds, sizeof(ubyte), t );

	Num_vclips = PHYSFSX_readInt(fp);
	vclip_read_n(Vclip, Num_vclips, fp);

	Num_effects = PHYSFSX_readInt(fp);
	eclip_read_n(Effects, Num_effects, fp);

	Num_wall_anims = PHYSFSX_readInt(fp);
	wclip_read_n(WallAnims, Num_wall_anims, fp);

	N_robot_types = PHYSFSX_readInt(fp);
	robot_info_read_n(Robot_info, N_robot_types, fp);

	N_robot_joints = PHYSFSX_readInt(fp);
	jointpos_read_n(Robot_joints, N_robot_joints, fp);

	N_weapon_types = PHYSFSX_readInt(fp);
	weapon_info_read_n(Weapon_info, N_weapon_types, fp, Piggy_hamfile_version);

	N_powerup_types = PHYSFSX_readInt(fp);
	powerup_type_info_read_n(Powerup_info, N_powerup_types, fp);

	N_polygon_models = PHYSFSX_readInt(fp);
	polymodel_read_n(Polygon_models, N_polygon_models, fp);

	for (i=0; i<N_polygon_models; i++ )
		polygon_model_data_read(&Polygon_models[i], fp);

	for (i = 0; i < N_polygon_models; i++)
		Dying_modelnums[i] = PHYSFSX_readInt(fp);
	for (i = 0; i < N_polygon_models; i++)
		Dead_modelnums[i] = PHYSFSX_readInt(fp);

	t = PHYSFSX_readInt(fp);
	bitmap_index_read_n(Gauges, t, fp);
	bitmap_index_read_n(Gauges_hires, t, fp);

	N_ObjBitmaps = PHYSFSX_readInt(fp);
	bitmap_index_read_n(ObjBitmaps, N_ObjBitmaps, fp);
	for (i = 0; i < N_ObjBitmaps; i++)
		ObjBitmapPtrs[i] = PHYSFSX_readShort(fp);

	player_ship_read(&only_player_ship, fp);

	Num_cockpits = PHYSFSX_readInt(fp);
	bitmap_index_read_n(cockpit_bitmap, Num_cockpits, fp);

//@@	PHYSFS_read( fp, &Num_total_object_types, sizeof(int), 1 );
//@@	PHYSFS_read( fp, ObjType, sizeof(byte), Num_total_object_types );
//@@	PHYSFS_read( fp, ObjId, sizeof(byte), Num_total_object_types );
//@@	PHYSFS_read( fp, ObjStrength, sizeof(fix), Num_total_object_types );

	First_multi_bitmap_num = PHYSFSX_readInt(fp);

	Num_reactors = PHYSFSX_readInt(fp);
	reactor_read_n(Reactors, Num_reactors, fp);

	Marker_model_num = PHYSFSX_readInt(fp);

	//@@PHYSFS_read( fp, &N_controlcen_guns, sizeof(int), 1 );
	//@@PHYSFS_read( fp, controlcen_gun_points, sizeof(vms_vector), N_controlcen_guns );
	//@@PHYSFS_read( fp, controlcen_gun_dirs, sizeof(vms_vector), N_controlcen_guns );

	if (Piggy_hamfile_version < 3) {
		exit_modelnum = PHYSFSX_readInt(fp);
		destroyed_exit_modelnum = PHYSFSX_readInt(fp);
	}
	else
		exit_modelnum = destroyed_exit_modelnum = N_polygon_models;
}
Esempio n. 22
0
//type==1 means 1.1, type==2 means 1.2 (with weapons)
void bm_read_extra_robots(const char *fname, Mission::descent_version_type type)
{
	int t,version;

	auto fp = PHYSFSX_openReadBuffered(fname);
	if (!fp)
	{
		Error("Failed to open HAM file \"%s\"", fname);
		return;
	}

	if (type == Mission::descent_version_type::descent2z)
	{
		int sig;

		sig = PHYSFSX_readInt(fp);
		if (sig != MAKE_SIG('X','H','A','M'))
			return;
		version = PHYSFSX_readInt(fp);
	}
	else
		version = 0;
	(void)version; // NOTE: we do not need it, but keep it for possible further use

	bm_free_extra_models();
	bm_free_extra_objbitmaps();

	//read extra weapons

	t = PHYSFSX_readInt(fp);
	N_weapon_types = N_D2_WEAPON_TYPES+t;
	weapon_info_read_n(Weapon_info, N_weapon_types, fp, 3, N_D2_WEAPON_TYPES);

	//now read robot info

	t = PHYSFSX_readInt(fp);
	N_robot_types = N_D2_ROBOT_TYPES+t;
	if (N_robot_types >= MAX_ROBOT_TYPES)
		Error("Too many robots (%d) in <%s>.  Max is %d.",t,fname,MAX_ROBOT_TYPES-N_D2_ROBOT_TYPES);
	range_for (auto &r, partial_range(Robot_info, N_D2_ROBOT_TYPES.value, N_robot_types))
		robot_info_read(fp, r);

	t = PHYSFSX_readInt(fp);
	N_robot_joints = N_D2_ROBOT_JOINTS+t;
	if (N_robot_joints >= MAX_ROBOT_JOINTS)
		Error("Too many robot joints (%d) in <%s>.  Max is %d.",t,fname,MAX_ROBOT_JOINTS-N_D2_ROBOT_JOINTS);
	range_for (auto &r, partial_range(Robot_joints, N_D2_ROBOT_JOINTS.value, N_robot_joints))
		jointpos_read(fp, r);

	unsigned u = PHYSFSX_readInt(fp);
	N_polygon_models = N_D2_POLYGON_MODELS+u;
	if (N_polygon_models >= MAX_POLYGON_MODELS)
		Error("Too many polygon models (%d) in <%s>.  Max is %d.",u,fname,MAX_POLYGON_MODELS-N_D2_POLYGON_MODELS);
	{
		const auto &&r = partial_range(Polygon_models, N_D2_POLYGON_MODELS.value, N_polygon_models);
		range_for (auto &p, r)
		polymodel_read(&p, fp);

		range_for (auto &p, r)
			polygon_model_data_read(&p, fp);
	}

	range_for (auto &i, partial_range(Dying_modelnums, N_D2_POLYGON_MODELS.value, N_polygon_models))
		i = PHYSFSX_readInt(fp);
	range_for (auto &i, partial_range(Dead_modelnums, N_D2_POLYGON_MODELS.value, N_polygon_models))
		i = PHYSFSX_readInt(fp);

	t = PHYSFSX_readInt(fp);
	if (N_D2_OBJBITMAPS+t >= ObjBitmaps.size())
		Error("Too many object bitmaps (%d) in <%s>.  Max is %" DXX_PRI_size_type ".", t, fname, ObjBitmaps.size() - N_D2_OBJBITMAPS);
	bitmap_index_read_n(fp, partial_range(ObjBitmaps, N_D2_OBJBITMAPS.value, N_D2_OBJBITMAPS + t));

	t = PHYSFSX_readInt(fp);
	if (N_D2_OBJBITMAPPTRS+t >= ObjBitmapPtrs.size())
		Error("Too many object bitmap pointers (%d) in <%s>.  Max is %" DXX_PRI_size_type ".", t, fname, ObjBitmapPtrs.size() - N_D2_OBJBITMAPPTRS);
	range_for (auto &i, partial_range(ObjBitmapPtrs, N_D2_OBJBITMAPPTRS.value, N_D2_OBJBITMAPPTRS + t))
		i = PHYSFSX_readShort(fp);
}
Esempio n. 23
0
//loads a level (.LVL) file from disk
//returns 0 if success, else error code
int load_level(const char * filename_passed)
{
#ifdef EDITOR
	int use_compiled_level=1;
#endif
	PHYSFS_file * LoadFile;
	char filename[PATH_MAX];
	int sig, minedata_offset, gamedata_offset, hostagetext_offset;
	int mine_err, game_err;
#ifdef NETWORK
	int i;
#endif

#ifdef NETWORK
   if (Game_mode & GM_NETWORK)
	 {
	  for (i=0;i<MAX_POWERUP_TYPES;i++)
		{
			MaxPowerupsAllowed[i]=0;
			PowerupsInMine[i]=0;
		}
	 }
#endif

	#ifdef COMPACT_SEGS
	ncache_flush();
	#endif

	#ifndef RELEASE
	Level_being_loaded = filename_passed;
	#endif

	strcpy(filename,filename_passed);

#ifdef EDITOR
	//if we have the editor, try the LVL first, no matter what was passed.
	//if we don't have an LVL, try what was passed or SDL/RDL  
	//if we don't have the editor, we just use what was passed

	change_filename_extension(filename,filename_passed,".lvl");
	use_compiled_level = 0;

	if (!PHYSFSX_exists(filename,1))
	{
		char *p = strrchr(filename_passed, '.');

		if (d_stricmp(p, ".lvl"))
			strcpy(filename, filename_passed);	// set to what was passed
		else
			change_filename_extension(filename, filename, ".rdl");
		use_compiled_level = 1;
	}		
#endif

	if (!PHYSFSX_exists(filename,1))
		sprintf(filename,"%s%s",MISSION_DIR,filename_passed);

	LoadFile = PHYSFSX_openReadBuffered( filename );

	if (!LoadFile)	{
		#ifdef EDITOR
			return 1;
		#else
			Error("Can't open file <%s>\n",filename);
		#endif
	}

	strcpy( Gamesave_current_filename, filename );

	sig                      = PHYSFSX_readInt(LoadFile);
	Gamesave_current_version = PHYSFSX_readInt(LoadFile);
	minedata_offset          = PHYSFSX_readInt(LoadFile);
	gamedata_offset          = PHYSFSX_readInt(LoadFile);

	Assert(sig == MAKE_SIG('P','L','V','L'));
	(void)sig;

	if (Gamesave_current_version < 5)
		hostagetext_offset = PHYSFSX_readInt(LoadFile);

	PHYSFSX_fseek(LoadFile,minedata_offset,SEEK_SET);
	#ifdef EDITOR
	if (!use_compiled_level)
		mine_err = load_mine_data(LoadFile);
	else
	#endif
		//NOTE LINK TO ABOVE!!
		mine_err = load_mine_data_compiled(LoadFile);

	/* !!!HACK!!!
	 * Descent 1 - Level 19: OBERON MINE has some ugly overlapping rooms (segment 484).
	 * HACK to make this issue less visible by moving one vertex a little.
	 */
	if (Current_mission && !d_stricmp("Descent: First Strike",Current_mission_longname) && !d_stricmp("level19.rdl",filename) && PHYSFS_fileLength(LoadFile) == 136706)
		Vertices[1905].z =-385*F1_0;

	if (mine_err == -1) {   //error!!
		PHYSFS_close(LoadFile);
		return 2;
	}

	PHYSFSX_fseek(LoadFile,gamedata_offset,SEEK_SET);
	game_err = load_game_data(LoadFile);

	if (game_err == -1) {   //error!!
		PHYSFS_close(LoadFile);
		return 3;
	}

	(void)hostagetext_offset;

	//======================== CLOSE FILE =============================

	PHYSFS_close( LoadFile );

	#if 0	//def EDITOR
	#ifndef RELEASE
	write_game_text_file(filename);
	if (Errors_in_mine) {
		if (is_real_level(filename)) {
			char  ErrorMessage[200];

			sprintf( ErrorMessage, "Warning: %i errors in %s!\n", Errors_in_mine, Level_being_loaded );
			stop_time();
			gr_palette_load(gr_palette);
			nm_messagebox( NULL, 1, "Continue", ErrorMessage );
			start_time();
		}
	}
	#endif
	#endif

	#ifdef EDITOR
	//If an old version, ask the use if he wants to save as new version
	if (((LEVEL_FILE_VERSION>1) && Gamesave_current_version<LEVEL_FILE_VERSION) || mine_err==1 || game_err==1) {
		char  ErrorMessage[200];

		sprintf( ErrorMessage, "You just loaded a old version level.  Would\n"
						"you like to save it as a current version level?");

		gr_palette_load(gr_palette);
		if (nm_messagebox( NULL, 2, "Don't Save", "Save", ErrorMessage )==1)
			save_level(filename);
	}
	#endif

	#ifdef EDITOR
	if (EditorWindow)
		editor_status_fmt("Loaded NEW mine %s, \"%s\"",filename,Current_level_name);
	#endif

	#if !defined(NDEBUG) && !defined(COMPACT_SEGS)
	if (check_segment_connections())
		nm_messagebox( "ERROR", 1, "Ok", 
				"Connectivity errors detected in\n"
				"mine.  See monochrome screen for\n"
				"details, and contact Matt or Mike." );
	#endif

	return 0;
}
Esempio n. 24
0
void load_robot_replacements(const d_fname &level_name)
{
	int t,i,j;
	char ifile_name[FILENAME_LEN];

	change_filename_extension(ifile_name, level_name, ".HXM" );

	auto fp = PHYSFSX_openReadBuffered(ifile_name);
	if (!fp)		//no robot replacement file
		return;

	t = PHYSFSX_readInt(fp);			//read id "HXM!"
	if (t!= 0x21584d48)
		Error("ID of HXM! file incorrect");

	t = PHYSFSX_readInt(fp);			//read version
	if (t<1)
		Error("HXM! version too old (%d)",t);

	t = PHYSFSX_readInt(fp);			//read number of robots
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read robot number
		if (i<0 || i>=N_robot_types)
			Error("Robots number (%d) out of range in (%s).  Range = [0..%d].",i,static_cast<const char *>(level_name),N_robot_types-1);
		robot_info_read(fp, Robot_info[i]);
	}

	t = PHYSFSX_readInt(fp);			//read number of joints
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read joint number
		if (i<0 || i>=N_robot_joints)
			Error("Robots joint (%d) out of range in (%s).  Range = [0..%d].",i,static_cast<const char *>(level_name),N_robot_joints-1);
		jointpos_read(fp, Robot_joints[i]);
	}

	t = PHYSFSX_readInt(fp);			//read number of polygon models
	for (j=0;j<t;j++)
	{
		i = PHYSFSX_readInt(fp);		//read model number
		if (i<0 || i>=N_polygon_models)
			Error("Polygon model (%d) out of range in (%s).  Range = [0..%d].",i,static_cast<const char *>(level_name),N_polygon_models-1);

		free_model(Polygon_models[i]);
		polymodel_read(&Polygon_models[i], fp);
		polygon_model_data_read(&Polygon_models[i], fp);

		Dying_modelnums[i] = PHYSFSX_readInt(fp);
		Dead_modelnums[i] = PHYSFSX_readInt(fp);
	}

	t = PHYSFSX_readInt(fp);			//read number of objbitmaps
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read objbitmap number
		if (i < 0 || i >= ObjBitmaps.size())
			Error("Object bitmap number (%d) out of range in (%s).  Range = [0..%" DXX_PRI_size_type "].", i, static_cast<const char *>(level_name), ObjBitmaps.size() - 1);
		bitmap_index_read(fp, ObjBitmaps[i]);
	}

	t = PHYSFSX_readInt(fp);			//read number of objbitmapptrs
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read objbitmapptr number
		if (i < 0 || i >= ObjBitmapPtrs.size())
			Error("Object bitmap pointer (%d) out of range in (%s).  Range = [0..%" DXX_PRI_size_type "].", i, static_cast<const char *>(level_name), ObjBitmapPtrs.size() - 1);
		ObjBitmapPtrs[i] = PHYSFSX_readShort(fp);
	}
	Robot_replacements_loaded = 1;
}
Esempio n. 25
0
//reads one object of the given version from the given file
void read_object(object *obj,PHYSFS_file *f,int version)
{

	obj->type           = PHYSFSX_readByte(f);
	obj->id             = PHYSFSX_readByte(f);

	if (obj->type == OBJ_ROBOT && obj->id > 23) {
		obj->id = obj->id % 24;
	}
	
	obj->control_type   = PHYSFSX_readByte(f);
	obj->movement_type  = PHYSFSX_readByte(f);
	obj->render_type    = PHYSFSX_readByte(f);
	obj->flags          = PHYSFSX_readByte(f);

	obj->segnum         = PHYSFSX_readShort(f);
	obj->attached_obj   = -1;

	PHYSFSX_readVector(&obj->pos,f);
	PHYSFSX_readMatrix(&obj->orient,f);

	obj->size           = PHYSFSX_readFix(f);
	obj->shields        = PHYSFSX_readFix(f);

	PHYSFSX_readVector(&obj->last_pos,f);

	obj->contains_type  = PHYSFSX_readByte(f);
	obj->contains_id    = PHYSFSX_readByte(f);
	obj->contains_count = PHYSFSX_readByte(f);

	switch (obj->movement_type) {

		case MT_PHYSICS:

			PHYSFSX_readVector(&obj->mtype.phys_info.velocity,f);
			PHYSFSX_readVector(&obj->mtype.phys_info.thrust,f);

			obj->mtype.phys_info.mass		= PHYSFSX_readFix(f);
			obj->mtype.phys_info.drag		= PHYSFSX_readFix(f);
			obj->mtype.phys_info.brakes	= PHYSFSX_readFix(f);

			PHYSFSX_readVector(&obj->mtype.phys_info.rotvel,f);
			PHYSFSX_readVector(&obj->mtype.phys_info.rotthrust,f);

			obj->mtype.phys_info.turnroll	= PHYSFSX_readFixAng(f);
			obj->mtype.phys_info.flags		= PHYSFSX_readShort(f);

			break;

		case MT_SPINNING:

			PHYSFSX_readVector(&obj->mtype.spin_rate,f);
			break;

		case MT_NONE:
			break;

		default:
			Int3();
	}

	switch (obj->control_type) {

		case CT_AI: {
			int i;

			obj->ctype.ai_info.behavior				= PHYSFSX_readByte(f);

			for (i=0;i<MAX_AI_FLAGS;i++)
				obj->ctype.ai_info.flags[i]			= PHYSFSX_readByte(f);

			obj->ctype.ai_info.hide_segment			= PHYSFSX_readShort(f);
			obj->ctype.ai_info.hide_index			= PHYSFSX_readShort(f);
			obj->ctype.ai_info.path_length			= PHYSFSX_readShort(f);
			obj->ctype.ai_info.cur_path_index		= PHYSFSX_readShort(f);

			if (version <= 25) {
				obj->ctype.ai_info.follow_path_start_seg = PHYSFSX_readShort(f);
				obj->ctype.ai_info.follow_path_end_seg	 = PHYSFSX_readShort(f);
			}

			break;
		}

		case CT_EXPLOSION:

			obj->ctype.expl_info.spawn_time		= PHYSFSX_readFix(f);
			obj->ctype.expl_info.delete_time		= PHYSFSX_readFix(f);
			obj->ctype.expl_info.delete_objnum	= PHYSFSX_readShort(f);
			obj->ctype.expl_info.next_attach = obj->ctype.expl_info.prev_attach = obj->ctype.expl_info.attach_parent = -1;

			break;

		case CT_WEAPON:

			//do I really need to read these?  Are they even saved to disk?

			obj->ctype.laser_info.parent_type		= PHYSFSX_readShort(f);
			obj->ctype.laser_info.parent_num		= PHYSFSX_readShort(f);
			obj->ctype.laser_info.parent_signature	= PHYSFSX_readInt(f);

			break;

		case CT_LIGHT:

			obj->ctype.light_info.intensity = PHYSFSX_readFix(f);
			break;

		case CT_POWERUP:

			if (version >= 25)
				obj->ctype.powerup_info.count = PHYSFSX_readInt(f);
			else
				obj->ctype.powerup_info.count = 1;

			if (obj->id == POW_VULCAN_WEAPON)
					obj->ctype.powerup_info.count = VULCAN_WEAPON_AMMO_AMOUNT;

			break;


		case CT_NONE:
		case CT_FLYING:
		case CT_DEBRIS:
			break;

		case CT_SLEW:		//the player is generally saved as slew
			break;

		case CT_CNTRLCEN:
			break;

		case CT_MORPH:
		case CT_FLYTHROUGH:
		case CT_REPAIRCEN:
		default:
			Int3();
	
	}

	switch (obj->render_type) {

		case RT_NONE:
			break;

		case RT_MORPH:
		case RT_POLYOBJ: {
			int i,tmo;

			obj->rtype.pobj_info.model_num		= convert_polymod(PHYSFSX_readInt(f));

			for (i=0;i<MAX_SUBMODELS;i++)
				PHYSFSX_readAngleVec(&obj->rtype.pobj_info.anim_angles[i],f);

			obj->rtype.pobj_info.subobj_flags	= PHYSFSX_readInt(f);

			tmo = PHYSFSX_readInt(f);

			#ifndef EDITOR
			obj->rtype.pobj_info.tmap_override	= convert_tmap(tmo);
			#else
			if (tmo==-1)
				obj->rtype.pobj_info.tmap_override	= -1;
			else {
				int xlated_tmo = tmap_xlate_table[tmo];
				if (xlated_tmo < 0)	{
					Int3();
					xlated_tmo = 0;
				}
				obj->rtype.pobj_info.tmap_override	= xlated_tmo;
			}
			#endif

			obj->rtype.pobj_info.alt_textures	= 0;

			break;
		}

		case RT_WEAPON_VCLIP:
		case RT_HOSTAGE:
		case RT_POWERUP:
		case RT_FIREBALL:

			obj->rtype.vclip_info.vclip_num	= convert_vclip(PHYSFSX_readInt(f));
			obj->rtype.vclip_info.frametime	= PHYSFSX_readFix(f);
			obj->rtype.vclip_info.framenum	= PHYSFSX_readByte(f);

			break;

		case RT_LASER:
			break;

		default:
			Int3();

	}

}
Esempio n. 26
0
/*
 * reads n eclip structs from a PHYSFS_file
 */
int eclip_read_n(eclip *ec, int n, PHYSFS_file *fp)
{
	int i, j;

	for (i = 0; i < n; i++) {
		ec[i].vc.play_time = PHYSFSX_readFix(fp);
		ec[i].vc.num_frames = PHYSFSX_readInt(fp);
		ec[i].vc.frame_time = PHYSFSX_readFix(fp);
		ec[i].vc.flags = PHYSFSX_readInt(fp);
		ec[i].vc.sound_num = PHYSFSX_readShort(fp);
		for (j = 0; j < VCLIP_MAX_FRAMES; j++)
			ec[i].vc.frames[j].index = PHYSFSX_readShort(fp);
		ec[i].vc.light_value = PHYSFSX_readFix(fp);
		ec[i].time_left = PHYSFSX_readFix(fp);
		ec[i].frame_count = PHYSFSX_readInt(fp);
		ec[i].changing_wall_texture = PHYSFSX_readShort(fp);
		ec[i].changing_object_texture = PHYSFSX_readShort(fp);
		ec[i].flags = PHYSFSX_readInt(fp);
		ec[i].crit_clip = PHYSFSX_readInt(fp);
		ec[i].dest_bm_num = PHYSFSX_readInt(fp);
		ec[i].dest_vclip = PHYSFSX_readInt(fp);
		ec[i].dest_eclip = PHYSFSX_readInt(fp);
		ec[i].dest_size = PHYSFSX_readFix(fp);
		ec[i].sound_num = PHYSFSX_readInt(fp);
		ec[i].segnum = PHYSFSX_readInt(fp);
		ec[i].sidenum = PHYSFSX_readInt(fp);
	}
	return i;
}
Esempio n. 27
0
// --------------------------------------------------------------------
// Load game 
// Loads all the relevant data for a level.
// If level != -1, it loads the filename with extension changed to .min
// Otherwise it loads the appropriate level mine.
// returns 0=everything ok, 1=old version, -1=error
int load_game_data(PHYSFS_file *LoadFile)
{
	int i,j;

	short game_top_fileinfo_version;
	int object_offset;
	int gs_num_objects;
	int trig_size;

	//===================== READ FILE INFO ========================

#if 0
	PHYSFS_read(LoadFile, &game_top_fileinfo, sizeof(game_top_fileinfo), 1);
#endif

	// Check signature
	if (PHYSFSX_readShort(LoadFile) != 0x6705)
		return -1;

	// Read and check version number
	game_top_fileinfo_version = PHYSFSX_readShort(LoadFile);
	if (game_top_fileinfo_version < GAME_COMPATIBLE_VERSION )
		return -1;

	// We skip some parts of the former game_top_fileinfo
	PHYSFSX_fseek(LoadFile, 31, SEEK_CUR);

	object_offset = PHYSFSX_readInt(LoadFile);
	gs_num_objects = PHYSFSX_readInt(LoadFile);
	PHYSFSX_fseek(LoadFile, 8, SEEK_CUR);

	Num_walls = PHYSFSX_readInt(LoadFile);
	PHYSFSX_fseek(LoadFile, 20, SEEK_CUR);

	Num_triggers = PHYSFSX_readInt(LoadFile);
	PHYSFSX_fseek(LoadFile, 24, SEEK_CUR);

	trig_size = PHYSFSX_readInt(LoadFile);
	Assert(trig_size == sizeof(ControlCenterTriggers));
	(void)trig_size;
	PHYSFSX_fseek(LoadFile, 4, SEEK_CUR);

	Num_robot_centers = PHYSFSX_readInt(LoadFile);
	PHYSFSX_fseek(LoadFile, 4, SEEK_CUR);

	if (game_top_fileinfo_version >= 31) //load mine filename
		// read newline-terminated string, not sure what version this changed.
		PHYSFSX_fgets(Current_level_name,sizeof(Current_level_name),LoadFile);
	else if (game_top_fileinfo_version >= 14) { //load mine filename
		// read null-terminated string
		char *p=Current_level_name;
		//must do read one char at a time, since no PHYSFSX_fgets()
		do *p = PHYSFSX_fgetc(LoadFile); while (*p++!=0);
	}
	else
		Current_level_name[0]=0;

	if (game_top_fileinfo_version >= 19) {	//load pof names
		N_save_pof_names = PHYSFSX_readShort(LoadFile);
		if (N_save_pof_names != 0x614d && N_save_pof_names != 0x5547) { // "Ma"de w/DMB beta/"GU"ILE
			Assert(N_save_pof_names < MAX_POLYGON_MODELS);
			PHYSFS_read(LoadFile,Save_pof_names,N_save_pof_names,FILENAME_LEN);
		}
	}

	//===================== READ PLAYER INFO ==========================


	//===================== READ OBJECT INFO ==========================

	Gamesave_num_org_robots = 0;
	Gamesave_num_players = 0;

	if (object_offset > -1) {
		if (PHYSFSX_fseek( LoadFile, object_offset, SEEK_SET ))
			Error( "Error seeking to object_offset in gamesave.c" );

		for (i = 0; i < gs_num_objects; i++) {

			read_object(&Objects[i], LoadFile, game_top_fileinfo_version);

			Objects[i].signature = obj_get_signature();
			verify_object( &Objects[i] );
		}

	}

	//===================== READ WALL INFO ============================

	for (i = 0; i < Num_walls; i++) {
		if (game_top_fileinfo_version >= 20)
			wall_read(&Walls[i], LoadFile); // v20 walls and up.
		else if (game_top_fileinfo_version >= 17) {
			v19_wall w;
			v19_wall_read(&w, LoadFile);
			Walls[i].segnum	        = w.segnum;
			Walls[i].sidenum	= w.sidenum;
			Walls[i].linked_wall	= w.linked_wall;
			Walls[i].type		= w.type;
			Walls[i].flags		= w.flags;
			Walls[i].hps		= w.hps;
			Walls[i].trigger	= w.trigger;
			Walls[i].clip_num	= convert_wclip(w.clip_num);
			Walls[i].keys		= w.keys;
			Walls[i].state		= WALL_DOOR_CLOSED;
		} else {
			v16_wall w;
			v16_wall_read(&w, LoadFile);
			Walls[i].segnum = Walls[i].sidenum = Walls[i].linked_wall = -1;
			Walls[i].type		= w.type;
			Walls[i].flags		= w.flags;
			Walls[i].hps		= w.hps;
			Walls[i].trigger	= w.trigger;
			Walls[i].clip_num	= convert_wclip(w.clip_num);
			Walls[i].keys		= w.keys;
		}
	}

#if 0
	//===================== READ DOOR INFO ============================

	if (game_fileinfo.doors_offset > -1)
	{
		if (!PHYSFSX_fseek( LoadFile, game_fileinfo.doors_offset,SEEK_SET ))	{

			for (i=0;i<game_fileinfo.doors_howmany;i++) {

				if (game_top_fileinfo_version >= 20)
					active_door_read(&ActiveDoors[i], LoadFile); // version 20 and up
				else {
					v19_door d;
					int p;

					v19_door_read(&d, LoadFile);

					ActiveDoors[i].n_parts = d.n_parts;

					for (p=0;p<d.n_parts;p++) {
						int cseg,cside;

						cseg = Segments[d.seg[p]].children[d.side[p]];
						cside = find_connect_side(&Segments[d.seg[p]],&Segments[cseg]);

						ActiveDoors[i].front_wallnum[p] = Segments[d.seg[p]].sides[d.side[p]].wall_num;
						ActiveDoors[i].back_wallnum[p] = Segments[cseg].sides[cside].wall_num;
					}
				}

			}
		}
	}
#endif // 0

	//==================== READ TRIGGER INFO ==========================

	for (i = 0; i < Num_triggers; i++)
	{
		if (game_top_fileinfo_version <= 25)
			trigger_read(&Triggers[i], LoadFile);
		else {
			int type;
			switch ((type = PHYSFSX_readByte(LoadFile)))
			{
				case 0: // door
					Triggers[i].type = 0;
					Triggers[i].flags = TRIGGER_CONTROL_DOORS;
					break;
				case 2: // matcen
					Triggers[i].type = 0;
					Triggers[i].flags = TRIGGER_MATCEN;
					break;
				case 3: // exit
					Triggers[i].type = 0;
					Triggers[i].flags = TRIGGER_EXIT;
					break;
				case 4: // secret exit
					Triggers[i].type = 0;
					Triggers[i].flags = TRIGGER_SECRET_EXIT;
					break;
				case 5: // illusion off
					Triggers[i].type = 0;
					Triggers[i].flags = TRIGGER_ILLUSION_OFF;
					break;
				case 6: // illusion on
					Triggers[i].type = 0;
					Triggers[i].flags = TRIGGER_ILLUSION_ON;
					break;
				default:
					con_printf(CON_URGENT,"Warning: unsupported trigger type %d (%d)\n", type, i);
			}
			if (PHYSFSX_readByte(LoadFile) & 2)	// one shot
				Triggers[i].flags |= TRIGGER_ONE_SHOT;
			Triggers[i].num_links = PHYSFSX_readShort(LoadFile);
			Triggers[i].value = PHYSFSX_readInt(LoadFile);
			Triggers[i].time = PHYSFSX_readInt(LoadFile);
			for (j=0; j<MAX_WALLS_PER_LINK; j++ )	
				Triggers[i].seg[j] = PHYSFSX_readShort(LoadFile);
			for (j=0; j<MAX_WALLS_PER_LINK; j++ )
				Triggers[i].side[j] = PHYSFSX_readShort(LoadFile);
		}
	}

	//================ READ CONTROL CENTER TRIGGER INFO ===============

	control_center_triggers_read_n(&ControlCenterTriggers, 1, LoadFile);

	//================ READ MATERIALOGRIFIZATIONATORS INFO ===============

	for (i = 0; i < Num_robot_centers; i++) {
		matcen_info_read(&RobotCenters[i], LoadFile, game_top_fileinfo_version);
		
		//	Set links in RobotCenters to Station array
		for (j = 0; j <= Highest_segment_index; j++)
			if (Segments[j].special == SEGMENT_IS_ROBOTMAKER)
				if (Segments[j].matcen_num == i)
					RobotCenters[i].fuelcen_num = Segments[j].value;
	}


	//========================= UPDATE VARIABLES ======================

	reset_objects(gs_num_objects);

	for (i=0; i<MAX_OBJECTS; i++) {
		Objects[i].next = Objects[i].prev = -1;
		if (Objects[i].type != OBJ_NONE) {
			int objsegnum = Objects[i].segnum;

			if (objsegnum > Highest_segment_index)		//bogus object
				Objects[i].type = OBJ_NONE;
			else {
				Objects[i].segnum = -1;			//avoid Assert()
				obj_link(i,objsegnum);
			}
		}
	}

	clear_transient_objects(1);		//1 means clear proximity bombs

	// Make sure non-transparent doors are set correctly.
	for (i=0; i< Num_segments; i++)
		for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) {
			side	*sidep = &Segments[i].sides[j];
			if ((sidep->wall_num != -1) && (Walls[sidep->wall_num].clip_num != -1)) {
				if (WallAnims[Walls[sidep->wall_num].clip_num].flags & WCF_TMAP1) {
					sidep->tmap_num = WallAnims[Walls[sidep->wall_num].clip_num].frames[0];
					sidep->tmap_num2 = 0;
				}
			}
		}


	reset_walls();

#if 0
	Num_open_doors = game_fileinfo.doors_howmany;
#endif // 0
	Num_open_doors = 0;

	//go through all walls, killing references to invalid triggers
	for (i=0;i<Num_walls;i++)
		if (Walls[i].trigger >= Num_triggers) {
			Walls[i].trigger = -1;	//kill trigger
		}

	//go through all triggers, killing unused ones
	for (i=0;i<Num_triggers;) {
		int w;

		//	Find which wall this trigger is connected to.
		for (w=0; w<Num_walls; w++)
			if (Walls[w].trigger == i)
				break;

	#ifdef EDITOR
		if (w == Num_walls) {
			remove_trigger_num(i);
		}
		else
	#endif
			i++;
	}

	//	MK, 10/17/95: Make walls point back at the triggers that control them.
	//	Go through all triggers, stuffing controlling_trigger field in Walls.
	{
		int t;

		for (t=0; t<Num_triggers; t++) {
			int	l;
			for (l=0; l<Triggers[t].num_links; l++) {
				int	seg_num;

				seg_num = Triggers[t].seg[l];

				//check to see that if a trigger requires a wall that it has one,
				//and if it requires a matcen that it has one

				if (Triggers[t].type == TRIGGER_MATCEN) {
					if (Segments[seg_num].special != SEGMENT_IS_ROBOTMAKER)
						Int3();		//matcen trigger doesn't point to matcen
				}
			}
		}
	}

	//fix old wall structs
	if (game_top_fileinfo_version < 17) {
		int segnum,sidenum,wallnum;

		for (segnum=0; segnum<=Highest_segment_index; segnum++)
			for (sidenum=0;sidenum<6;sidenum++)
				if ((wallnum=Segments[segnum].sides[sidenum].wall_num) != -1) {
					Walls[wallnum].segnum = segnum;
					Walls[wallnum].sidenum = sidenum;
				}
	}

	#ifndef NDEBUG
	{
		int	sidenum;
		for (sidenum=0; sidenum<6; sidenum++) {
			int	wallnum = Segments[Highest_segment_index].sides[sidenum].wall_num;
			if (wallnum != -1)
				if ((Walls[wallnum].segnum != Highest_segment_index) || (Walls[wallnum].sidenum != sidenum))
					Int3();	//	Error.  Bogus walls in this segment.
								// Consult Yuan or Mike.
		}
	}
	#endif

	//create_local_segment_data();

	fix_object_segs();

	#ifndef NDEBUG
	dump_mine_info();
	#endif

	if (game_top_fileinfo_version < GAME_VERSION)
		return 1;		//means old version
	else
		return 0;
}
Esempio n. 28
0
void piggy_bitmap_page_in( bitmap_index bitmap )
{
	grs_bitmap * bmp;
	int i,org_i;

        org_i = 0;
			
	i = bitmap.index;
	Assert( i >= 0 );
	Assert( i < MAX_BITMAP_FILES );
	Assert( i < Num_bitmap_files );
	Assert( Piggy_bitmap_cache_size > 0 );

	if ( i < 1 ) return;
	if ( i >= MAX_BITMAP_FILES ) return;
	if ( i >= Num_bitmap_files ) return;

	if ( GameBitmapOffset[i] == 0 ) return;		// A read-from-disk bitmap!!!

	if ( GameArg.SysLowMem )	{
		org_i = i;
		i = GameBitmapXlat[i];		// Xlat for low-memory settings!
	}
	bmp = &GameBitmaps[i];
	
	if ( bmp->bm_flags & BM_FLAG_PAGED_OUT )	{
		stop_time();

	ReDoIt:
		descent_critical_error = 0;
		PHYSFSX_fseek( Piggy_fp, GameBitmapOffset[i], SEEK_SET );
		if ( descent_critical_error )	{
			piggy_critical_error();
			goto ReDoIt;
		}
		gr_set_bitmap_flags (bmp, GameBitmapFlags[i]);
		gr_set_bitmap_data (bmp, &Piggy_bitmap_cache_data [Piggy_bitmap_cache_next]);

		if ( bmp->bm_flags & BM_FLAG_RLE )	{
			int zsize = 0;
			descent_critical_error = 0;
			zsize = PHYSFSX_readInt(Piggy_fp);
			if ( descent_critical_error )	{
				piggy_critical_error();
				goto ReDoIt;
			}
	
			// GET JOHN NOW IF YOU GET THIS ASSERT!!!
			Assert( Piggy_bitmap_cache_next+zsize < Piggy_bitmap_cache_size );	
			if ( Piggy_bitmap_cache_next+zsize >= Piggy_bitmap_cache_size )	{
				piggy_bitmap_page_out_all();
				goto ReDoIt;
			}
			memcpy( &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], &zsize, sizeof(int) );
			Piggy_bitmap_cache_next += sizeof(int);
			descent_critical_error = 0;
			PHYSFS_read( Piggy_fp, &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, zsize-4 );
			if ( descent_critical_error )	{
				piggy_critical_error();
				goto ReDoIt;
			}
			if (MacPig)
			{
				rle_swap_0_255(bmp);
				memcpy(&zsize, bmp->bm_data, 4);
			}
			Piggy_bitmap_cache_next += zsize-4;
		} else {
			// GET JOHN NOW IF YOU GET THIS ASSERT!!!
			Assert( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) < Piggy_bitmap_cache_size );	
			if ( Piggy_bitmap_cache_next+(bmp->bm_h*bmp->bm_w) >= Piggy_bitmap_cache_size )	{
				piggy_bitmap_page_out_all();
				goto ReDoIt;
			}
			descent_critical_error = 0;
			PHYSFS_read( Piggy_fp, &Piggy_bitmap_cache_data[Piggy_bitmap_cache_next], 1, bmp->bm_h*bmp->bm_w );
			if ( descent_critical_error )	{
				piggy_critical_error();
				goto ReDoIt;
			}
			if (MacPig)
				swap_0_255(bmp);
			Piggy_bitmap_cache_next+=bmp->bm_h*bmp->bm_w;
		}
	
#ifdef BITMAP_SELECTOR
		if ( bmp->bm_selector ) {
			if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
				Error( "Error modifying selector base in piggy.c\n" );
		}
		#endif

		compute_average_rgb(bmp, bmp->avg_color_rgb);

		start_time();
	}

	if ( GameArg.SysLowMem )	{
		if ( org_i != i )
			GameBitmaps[org_i] = GameBitmaps[i];
	}
}
Esempio n. 29
0
void load_robot_replacements(char *level_name)
{
	PHYSFS_file *fp;
	int t,i,j;
	char ifile_name[FILENAME_LEN];

	change_filename_extension(ifile_name, level_name, ".HXM" );

	fp = PHYSFSX_openReadBuffered(ifile_name);

	if (!fp)		//no robot replacement file
		return;

	t = PHYSFSX_readInt(fp);			//read id "HXM!"
	if (t!= 0x21584d48)
		Error("ID of HXM! file incorrect");

	t = PHYSFSX_readInt(fp);			//read version
	if (t<1)
		Error("HXM! version too old (%d)",t);

	t = PHYSFSX_readInt(fp);			//read number of robots
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read robot number
		if (i<0 || i>=N_robot_types)
			Error("Robots number (%d) out of range in (%s).  Range = [0..%d].",i,level_name,N_robot_types-1);
		robot_info_read_n(&Robot_info[i], 1, fp);
	}

	t = PHYSFSX_readInt(fp);			//read number of joints
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read joint number
		if (i<0 || i>=N_robot_joints)
			Error("Robots joint (%d) out of range in (%s).  Range = [0..%d].",i,level_name,N_robot_joints-1);
		jointpos_read_n(&Robot_joints[i], 1, fp);
	}

	t = PHYSFSX_readInt(fp);			//read number of polygon models
	for (j=0;j<t;j++)
	{
		i = PHYSFSX_readInt(fp);		//read model number
		if (i<0 || i>=N_polygon_models)
			Error("Polygon model (%d) out of range in (%s).  Range = [0..%d].",i,level_name,N_polygon_models-1);

		free_model(&Polygon_models[i]);
		polymodel_read(&Polygon_models[i], fp);
		polygon_model_data_read(&Polygon_models[i], fp);

		Dying_modelnums[i] = PHYSFSX_readInt(fp);
		Dead_modelnums[i] = PHYSFSX_readInt(fp);
	}

	t = PHYSFSX_readInt(fp);			//read number of objbitmaps
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read objbitmap number
		if (i<0 || i>=MAX_OBJ_BITMAPS)
			Error("Object bitmap number (%d) out of range in (%s).  Range = [0..%d].",i,level_name,MAX_OBJ_BITMAPS-1);
		bitmap_index_read(&ObjBitmaps[i], fp);
	}

	t = PHYSFSX_readInt(fp);			//read number of objbitmapptrs
	for (j=0;j<t;j++) {
		i = PHYSFSX_readInt(fp);		//read objbitmapptr number
		if (i<0 || i>=MAX_OBJ_BITMAPS)
			Error("Object bitmap pointer (%d) out of range in (%s).  Range = [0..%d].",i,level_name,MAX_OBJ_BITMAPS-1);
		ObjBitmapPtrs[i] = PHYSFSX_readShort(fp);
	}

	PHYSFS_close(fp);
	Robot_replacements_loaded = 1;
}