示例#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);
}
示例#2
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;
}
示例#3
0
文件: wall.c 项目: CDarrow/DXX-Retro
/*
 * reads a v16_wall structure from a PHYSFS_file
 */
extern void v16_wall_read(v16_wall *w, PHYSFS_file *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);
}
示例#4
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);
}
示例#5
0
/*
 * reads a segment2 structure from a PHYSFS_file
 */
void segment2_read(segment *s2, PHYSFS_file *fp)
{
	s2->special = PHYSFSX_readByte(fp);
	if (s2->special >= MAX_CENTER_TYPES)
		s2->special = SEGMENT_IS_NOTHING; // remove goals etc.
	s2->matcen_num = PHYSFSX_readByte(fp);
	s2->value = PHYSFSX_readByte(fp);
	/*s2->s2_flags =*/ PHYSFSX_readByte(fp);	// descent 2 ambient sound handling
	s2->static_light = PHYSFSX_readFix(fp);
}
示例#6
0
文件: wall.c 项目: CDarrow/DXX-Retro
/*
 * 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);
}
示例#7
0
文件: bm.cpp 项目: btb/dxx-rebirth
static void tmap_info_read(tmap_info &ti, PHYSFS_File *fp)
{
	ti.flags = PHYSFSX_readByte(fp);
	PHYSFSX_readByte(fp);
	PHYSFSX_readByte(fp);
	PHYSFSX_readByte(fp);
	ti.lighting = PHYSFSX_readFix(fp);
	ti.damage = PHYSFSX_readFix(fp);
	ti.eclip_num = PHYSFSX_readShort(fp);
	ti.destroyed = PHYSFSX_readShort(fp);
	ti.slide_u = PHYSFSX_readShort(fp);
	ti.slide_v = PHYSFSX_readShort(fp);
}
示例#8
0
void read_special(int segnum,ubyte bit_mask,PHYSFS_file *LoadFile)
{
	if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) {
		// Read ubyte	Segment2s[segnum].special
		Segment2s[segnum].special = PHYSFSX_readByte(LoadFile);
		// Read byte	Segment2s[segnum].matcen_num
		Segment2s[segnum].matcen_num = PHYSFSX_readByte(LoadFile);
		// Read short	Segment2s[segnum].value
		Segment2s[segnum].value = PHYSFSX_readShort(LoadFile);
	} else {
		Segment2s[segnum].special = 0;
		Segment2s[segnum].matcen_num = -1;
		Segment2s[segnum].value = 0;
	}
}
示例#9
0
/*
 * reads a segment2 structure from a PHYSFS_File
 */
static void segment2_read(shared_segment &s2, unique_segment &u2, PHYSFS_File *fp)
{
	s2.special = PHYSFSX_readByte(fp);
	s2.matcen_num = PHYSFSX_readByte(fp);
	/* station_idx overwritten by caller */
	PHYSFSX_readByte(fp);
	const auto s2_flags = PHYSFSX_readByte(fp);
#if defined(DXX_BUILD_DESCENT_I)
	(void)s2_flags;	// descent 2 ambient sound handling
	if (s2.special >= MAX_CENTER_TYPES)
		s2.special = SEGMENT_IS_NOTHING; // remove goals etc.
#elif defined(DXX_BUILD_DESCENT_II)
	s2.s2_flags = s2_flags;
#endif
	u2.static_light = PHYSFSX_readFix(fp);
}
示例#10
0
文件: bm.cpp 项目: btb/dxx-rebirth
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);
}
示例#11
0
文件: bm.cpp 项目: Foran/dxx-rebirth
/*
 * reads n tmap_info structs from a PHYSFS_file
 */
static int tmap_info_read_n(tmap_info *ti, int n, PHYSFS_file *fp)
{
	int i;

	for (i = 0; i < n; i++) {
		ti[i].flags = PHYSFSX_readByte(fp);
		ti[i].pad[0] = PHYSFSX_readByte(fp);
		ti[i].pad[1] = PHYSFSX_readByte(fp);
		ti[i].pad[2] = PHYSFSX_readByte(fp);
		ti[i].lighting = PHYSFSX_readFix(fp);
		ti[i].damage = PHYSFSX_readFix(fp);
		ti[i].eclip_num = PHYSFSX_readShort(fp);
		ti[i].destroyed = PHYSFSX_readShort(fp);
		ti[i].slide_u = PHYSFSX_readShort(fp);
		ti[i].slide_v = PHYSFSX_readShort(fp);
	}
	return i;
}
示例#12
0
文件: wall.c 项目: CDarrow/DXX-Retro
/*
 * 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);
}
示例#13
0
文件: wall.c 项目: CDarrow/DXX-Retro
/*
 * reads a wclip structure from a PHYSFS_file
 */
int wclip_read_n(wclip *wc, int n, PHYSFS_file *fp)
{
	int i, j;

	for (i = 0; i < n; i++) {
		wc[i].play_time = PHYSFSX_readFix(fp);
		wc[i].num_frames = PHYSFSX_readShort(fp);
		for (j = 0; j < MAX_CLIP_FRAMES; j++)
			wc[i].frames[j] = PHYSFSX_readShort(fp);
		wc[i].open_sound = PHYSFSX_readShort(fp);
		wc[i].close_sound = PHYSFSX_readShort(fp);
		wc[i].flags = PHYSFSX_readShort(fp);
		PHYSFS_read(fp, wc[i].filename, 13, 1);
		wc[i].pad = PHYSFSX_readByte(fp);
	}
	return i;
}
示例#14
0
文件: pcx.cpp 项目: Foran/dxx-rebirth
/*
 * reads n PCXHeader structs from a PHYSFS_file
 */
static int PCXHeader_read_n(PCXHeader *ph, int n, PHYSFS_file *fp)
{
	int i;

	for (i = 0; i < n; i++) {
		ph->Manufacturer = PHYSFSX_readByte(fp);
		ph->Version = PHYSFSX_readByte(fp);
		ph->Encoding = PHYSFSX_readByte(fp);
		ph->BitsPerPixel = PHYSFSX_readByte(fp);
		ph->Xmin = PHYSFSX_readShort(fp);
		ph->Ymin = PHYSFSX_readShort(fp);
		ph->Xmax = PHYSFSX_readShort(fp);
		ph->Ymax = PHYSFSX_readShort(fp);
		ph->Hdpi = PHYSFSX_readShort(fp);
		ph->Vdpi = PHYSFSX_readShort(fp);
		PHYSFS_read(fp, &ph->ColorMap, 16*3, 1);
		ph->Reserved = PHYSFSX_readByte(fp);
		ph->Nplanes = PHYSFSX_readByte(fp);
		ph->BytesPerLine = PHYSFSX_readShort(fp);
		PHYSFS_read(fp, &ph->filler, 60, 1);
	}
	return i;
}
示例#15
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;
}
示例#16
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();

	}

}
示例#17
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;
}
示例#18
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;
}
示例#19
0
/*
 * reads n weapon_info structs from a PHYSFS_file
 */
int weapon_info_read_n(weapon_info *wi, int n, PHYSFS_file *fp, int file_version)
{
	int i, j;

	for (i = 0; i < n; i++) {
		wi[i].render_type = PHYSFSX_readByte(fp);
		wi[i].persistent = PHYSFSX_readByte(fp);
		wi[i].model_num = PHYSFSX_readShort(fp);
		wi[i].model_num_inner = PHYSFSX_readShort(fp);

		wi[i].flash_vclip = PHYSFSX_readByte(fp);
		wi[i].robot_hit_vclip = PHYSFSX_readByte(fp);
		wi[i].flash_sound = PHYSFSX_readShort(fp);

		wi[i].wall_hit_vclip = PHYSFSX_readByte(fp);
		wi[i].fire_count = PHYSFSX_readByte(fp);
		wi[i].robot_hit_sound = PHYSFSX_readShort(fp);

		wi[i].ammo_usage = PHYSFSX_readByte(fp);
		wi[i].weapon_vclip = PHYSFSX_readByte(fp);
		wi[i].wall_hit_sound = PHYSFSX_readShort(fp);

		wi[i].destroyable = PHYSFSX_readByte(fp);
		wi[i].matter = PHYSFSX_readByte(fp);
		wi[i].bounce = PHYSFSX_readByte(fp);
		wi[i].homing_flag = PHYSFSX_readByte(fp);

		wi[i].speedvar = PHYSFSX_readByte(fp);
		wi[i].flags = PHYSFSX_readByte(fp);
		wi[i].flash = PHYSFSX_readByte(fp);
		wi[i].afterburner_size = PHYSFSX_readByte(fp);

		if (file_version >= 3)
			wi[i].children = PHYSFSX_readByte(fp);
		else
			/* Set the type of children correctly when using old
			 * datafiles.  In earlier descent versions this was simply
			 * hard-coded in create_smart_children().
			 */
			switch (i)
			{
			case SMART_ID:
				wi[i].children = PLAYER_SMART_HOMING_ID;
				break;
			case SUPERPROX_ID:
				wi[i].children = SMART_MINE_HOMING_ID;
				break;
#if 0 /* not present in shareware */
			case ROBOT_SUPERPROX_ID:
				wi[i].children = ROBOT_SMART_MINE_HOMING_ID;
				break;
			case EARTHSHAKER_ID:
				wi[i].children = EARTHSHAKER_MEGA_ID;
				break;
#endif
			default:
				wi[i].children = -1;
				break;
			}

		wi[i].energy_usage = PHYSFSX_readFix(fp);
		wi[i].fire_wait = PHYSFSX_readFix(fp);

		if (file_version >= 3)
			wi[i].multi_damage_scale = PHYSFSX_readFix(fp);
		else /* FIXME: hack this to set the real values */
			wi[i].multi_damage_scale = F1_0;

		bitmap_index_read(&wi[i].bitmap, fp);

		wi[i].blob_size = PHYSFSX_readFix(fp);
		wi[i].flash_size = PHYSFSX_readFix(fp);
		wi[i].impact_size = PHYSFSX_readFix(fp);
		for (j = 0; j < NDL; j++)
			wi[i].strength[j] = PHYSFSX_readFix(fp);
		for (j = 0; j < NDL; j++)
			wi[i].speed[j] = PHYSFSX_readFix(fp);
		wi[i].mass = PHYSFSX_readFix(fp);
		wi[i].drag = PHYSFSX_readFix(fp);
		wi[i].thrust = PHYSFSX_readFix(fp);
		wi[i].po_len_to_width_ratio = PHYSFSX_readFix(fp);
		wi[i].light = PHYSFSX_readFix(fp);
		wi[i].lifetime = PHYSFSX_readFix(fp);
		wi[i].damage_radius = PHYSFSX_readFix(fp);
		bitmap_index_read(&wi[i].picture, fp);
		if (file_version >= 3)
			bitmap_index_read(&wi[i].hires_picture, fp);
		else
			wi[i].hires_picture.index = wi[i].picture.index;
	}
	return i;
}