int VDevicePrefs::delete_objects()
{
	delete output_title;
	delete channel_picker;
	delete buz_swap_channels;
	delete device_title;
	delete device_text;

	delete port_title;
	delete device_port;

	delete number_title;
	delete device_number;

	if(firewire_port) delete firewire_port;
	if(channel_title) delete channel_title;
	if(firewire_channel) delete firewire_channel;
	if(firewire_path) delete firewire_path;
	if(syt_title) delete syt_title;
	if(firewire_syt) delete firewire_syt;

	reset_objects();
	driver = -1;
	return 0;
}
VDevicePrefs::VDevicePrefs(int x, 
	int y, 
	PreferencesWindow *pwindow, 
	PreferencesDialog *dialog, 
	VideoOutConfig *out_config,
	VideoInConfig *in_config,
	int mode)
{
	this->pwindow = pwindow;
	this->dialog = dialog;
	this->driver = -1;
	this->mode = mode;
	this->out_config = out_config;
	this->in_config = in_config;
	this->x = x;
	this->y = y;
	menu = 0;
	reset_objects();

}
예제 #3
0
int load_mine_data_compiled_new(CFILE *LoadFile)
{
	int		i,segnum,sidenum;
	ubyte		version;
	short		temp_short;
	ushort	temp_ushort;
	ubyte		bit_mask;

	//	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 ==============================
	cfread( &version, sizeof(ubyte), 1, LoadFile );						// 1 byte = compiled version
	Assert( version==COMPILED_MINE_VERSION );

	cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );					// 2 bytes = Num_vertices
	Num_vertices = temp_ushort;
	Assert( Num_vertices <= MAX_VERTICES );

	cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );					// 2 bytes = Num_segments
	Num_segments = temp_ushort;
	Assert( Num_segments <= MAX_SEGMENTS );

	cfread( Vertices, sizeof(vms_vector), Num_vertices, LoadFile );

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

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

 		cfread( &bit_mask, sizeof(ubyte), 1, LoadFile );

		for (bit=0; bit<MAX_SIDES_PER_SEGMENT; bit++) {
			if (bit_mask & (1 << bit))
		 		cfread( &Segments[segnum].children[bit], sizeof(short), 1, LoadFile );
			else
				Segments[segnum].children[bit] = -1;
		}

		// Read short Segments[segnum].verts[MAX_VERTICES_PER_SEGMENT]
		cfread( Segments[segnum].verts, sizeof(short), MAX_VERTICES_PER_SEGMENT, LoadFile );
		Segments[segnum].objects = -1;

		if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) {
			// Read ubyte	Segments[segnum].special
			cfread( &Segments[segnum].special, sizeof(ubyte), 1, LoadFile );
			// Read byte	Segments[segnum].matcen_num
			cfread( &Segments[segnum].matcen_num, sizeof(ubyte), 1, LoadFile );
			// Read short	Segments[segnum].value
			cfread( &Segments[segnum].value, sizeof(short), 1, LoadFile );
		} else {
			Segments[segnum].special = 0;
			Segments[segnum].matcen_num = -1;
			Segments[segnum].value = 0;
		}

		// Read fix	Segments[segnum].static_light (shift down 5 bits, write as short)
		cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile );
		Segments[segnum].static_light	= ((fix)temp_ushort) << 4;
		//cfread( &Segments[segnum].static_light, sizeof(fix), 1, LoadFile );
	
		// Read the walls as a 6 byte array
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{
			Segments[segnum].sides[sidenum].pad = 0;
		}

 		cfread( &bit_mask, sizeof(ubyte), 1, LoadFile );
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
			ubyte byte_wallnum;

			if (bit_mask & (1 << sidenum)) {
				cfread( &byte_wallnum, sizeof(ubyte), 1, 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;
				cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );

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

				if (!(temp_ushort & 0x8000))
					Segments[segnum].sides[sidenum].tmap_num2 = 0;
				else {
					// Read short Segments[segnum].sides[sidenum].tmap_num2;
					cfread( &Segments[segnum].sides[sidenum].tmap_num2, sizeof(short), 1, LoadFile );
				}

				// 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++ )	{
					cfread( &temp_short, sizeof(short), 1, LoadFile );
					Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
					cfread( &temp_short, sizeof(short), 1, LoadFile );
					Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
					cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile );
					Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
					//cfread( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, LoadFile );
				}	
			} 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.

	// Activate fuelcentes
	for (i=0; i< Num_segments; i++ ) {
		fuelcen_activate( &Segments[i], Segments[i].special );
	}

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

	return 0;
}
예제 #4
0
// -----------------------------------------------------------------------------
//loads from an already-open file
// returns 0=everything ok, 1=old version, -1=error
int load_mine_data(CFILE *LoadFile)
{
	int   i, j;
	short tmap_xlate;
	int 	translate;
	char 	*temptr;
	int	mine_start = cftell(LoadFile);

	fuelcen_reset();

	for (i=0; i<MAX_TEXTURES; i++ )
		tmap_times_used[i] = 0;
	
	#ifdef EDITOR
	// Create a new mine to initialize things.
	//texpage_goto_first();
	create_new_mine();
	#endif

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

	// These are the default values... version and fileinfo_sizeof
	// don't have defaults.
	mine_fileinfo.header_offset     =   -1;
	mine_fileinfo.header_size       =   sizeof(mine_header);
	mine_fileinfo.editor_offset     =   -1;
	mine_fileinfo.editor_size       =   sizeof(mine_editor);
	mine_fileinfo.vertex_offset     =   -1;
	mine_fileinfo.vertex_howmany    =   0;
	mine_fileinfo.vertex_sizeof     =   sizeof(vms_vector);
	mine_fileinfo.segment_offset    =   -1;
	mine_fileinfo.segment_howmany   =   0;
	mine_fileinfo.segment_sizeof    =   sizeof(segment);
	mine_fileinfo.newseg_verts_offset     =   -1;
	mine_fileinfo.newseg_verts_howmany    =   0;
	mine_fileinfo.newseg_verts_sizeof     =   sizeof(vms_vector);
	mine_fileinfo.group_offset		  =	-1;
	mine_fileinfo.group_howmany	  =	0;
	mine_fileinfo.group_sizeof		  =	sizeof(group);
	mine_fileinfo.texture_offset    =   -1;
	mine_fileinfo.texture_howmany   =   0;
	mine_fileinfo.texture_sizeof    =   13;  // num characters in a name
 	mine_fileinfo.walls_offset		  =	-1;
	mine_fileinfo.walls_howmany	  =	0;
	mine_fileinfo.walls_sizeof		  =	sizeof(wall);  
 	mine_fileinfo.triggers_offset	  =	-1;
	mine_fileinfo.triggers_howmany  =	0;
	mine_fileinfo.triggers_sizeof	  =	sizeof(trigger);  
	mine_fileinfo.object_offset		=	-1;
	mine_fileinfo.object_howmany		=	1;
	mine_fileinfo.object_sizeof		=	sizeof(object);  

	// Read in mine_top_fileinfo to get size of saved fileinfo.
	
	memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) );

	if (cfseek( LoadFile, mine_start, SEEK_SET ))
		Error( "Error moving to top of file in gamemine.c" );

	if (cfread( &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1, LoadFile )!=1)
		Error( "Error reading mine_top_fileinfo in gamemine.c" );

	if (mine_top_fileinfo.fileinfo_signature != 0x2884)
		return -1;

	// Check version number
	if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION )
		return -1;

	// Now, Read in the fileinfo
	if (cfseek( LoadFile, mine_start, SEEK_SET ))
		Error( "Error seeking to top of file in gamemine.c" );

	if (cfread( &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1, LoadFile )!=1)
		Error( "Error reading mine_fileinfo in gamemine.c" );

	//===================== READ HEADER INFO ========================

	// Set default values.
	mine_header.num_vertices        =   0;
	mine_header.num_segments        =   0;

	if (mine_fileinfo.header_offset > -1 )
	{
		if (cfseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET ))
			Error( "Error seeking to header_offset in gamemine.c" );
	
		if (cfread( &mine_header, mine_fileinfo.header_size, 1, LoadFile )!=1)
			Error( "Error reading mine_header in gamemine.c" );
	}

	//===================== READ EDITOR INFO ==========================

	// Set default values
	mine_editor.current_seg         =   0;
	mine_editor.newsegment_offset   =   -1; // To be written
	mine_editor.newsegment_size     =   sizeof(segment);
	mine_editor.Curside             =   0;
	mine_editor.Markedsegp          =   -1;
	mine_editor.Markedside          =   0;

	if (mine_fileinfo.editor_offset > -1 )
	{
		if (cfseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET ))
			Error( "Error seeking to editor_offset in gamemine.c" );
	
		if (cfread( &mine_editor, mine_fileinfo.editor_size, 1, LoadFile )!=1)
			Error( "Error reading mine_editor in gamemine.c" );
	}

	//===================== READ TEXTURE INFO ==========================

	if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0))
	{
		if (cfseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET ))
			Error( "Error seeking to texture_offset in gamemine.c" );

		for (i=0; i< mine_fileinfo.texture_howmany; i++ )
		{
			if (cfread( &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1, LoadFile )!=1)
				Error( "Error reading old_tmap_list[i] in gamemine.c" );
		}
	}

	//=============== GENERATE TEXTURE TRANSLATION TABLE ===============

	translate = 0;
	
	Assert (NumTextures < MAX_TEXTURES);

	{
		hashtable ht;
	
		hashtable_init( &ht, NumTextures );
	
		// Remove all the file extensions in the textures list
	
		for (i=0;i<NumTextures;i++)	{
			temptr = strchr(TmapInfo[i].filename, '.');
			if (temptr) *temptr = '\0';
			hashtable_insert( &ht, TmapInfo[i].filename, i );
		}
	
		// For every texture, search through the texture list
		// to find a matching name.
		for (j=0;j<mine_fileinfo.texture_howmany;j++) 	{
			// Remove this texture name's extension
			temptr = strchr(old_tmap_list[j], '.');
			if (temptr) *temptr = '\0';
	
			tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]);
			if (tmap_xlate_table[j]	< 0 )	{
				//tmap_xlate_table[j] = 0;
				// mprintf( (0, "Couldn't find texture '%s'\n", old_tmap_list[j] ));
				;
			}
			if (tmap_xlate_table[j] != j ) translate = 1;
			if (tmap_xlate_table[j] >= 0)
				tmap_times_used[tmap_xlate_table[j]]++;
		}
	
		{
			int count = 0;
			for (i=0; i<MAX_TEXTURES; i++ )
				if (tmap_times_used[i])
					count++;
			mprintf( (0, "This mine has %d unique textures in it (~%d KB)\n", count, (count*4096) /1024 ));
		}
	
		mprintf( (0, "Translate=%d\n", translate ));
	
		hashtable_free( &ht );
	}

	//====================== READ VERTEX INFO ==========================

	// New check added to make sure we don't read in too many vertices.
	if ( mine_fileinfo.vertex_howmany > MAX_VERTICES )
		{
		mprintf((0, "Num vertices exceeds maximum.  Loading MAX %d vertices\n", MAX_VERTICES));
		mine_fileinfo.vertex_howmany = MAX_VERTICES;
		}

	if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0))
	{
		if (cfseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET ))
			Error( "Error seeking to vertex_offset in gamemine.c" );

		for (i=0; i< mine_fileinfo.vertex_howmany; i++ )
		{
			// Set the default values for this vertex
			Vertices[i].x = 1;
			Vertices[i].y = 1;
			Vertices[i].z = 1;

			if (cfread( &Vertices[i], mine_fileinfo.vertex_sizeof, 1, LoadFile )!=1)
				Error( "Error reading Vertices[i] in gamemine.c" );
		}
	}

	//==================== READ SEGMENT INFO ===========================

	// New check added to make sure we don't read in too many segments.
	if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) {
		mprintf((0, "Num segments exceeds maximum.  Loading MAX %d segments\n", MAX_SEGMENTS));
		mine_fileinfo.segment_howmany = MAX_SEGMENTS;
	}

	// [commented out by mk on 11/20/94 (weren't we supposed to hit final in October?) because it looks redundant.  I think I'll test it now...]  fuelcen_reset();

	if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0))	{

		if (cfseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET ))

			Error( "Error seeking to segment_offset in gamemine.c" );

		Highest_segment_index = mine_fileinfo.segment_howmany-1;

		for (i=0; i< mine_fileinfo.segment_howmany; i++ ) {
			segment v16_seg;

			// Set the default values for this segment (clear to zero )
			//memset( &Segments[i], 0, sizeof(segment) );

			if (mine_top_fileinfo.fileinfo_version >= 16) {

				Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg));

				if (cfread( &v16_seg, mine_fileinfo.segment_sizeof, 1, LoadFile )!=1)
					Error( "Error reading segments in gamemine.c" );

			}				
			else 
				Error("Invalid mine version");

			Segments[i] = v16_seg;

			Segments[i].objects = -1;
			#ifdef EDITOR
			Segments[i].group = -1;
			#endif

			if (mine_top_fileinfo.fileinfo_version < 15) {	//used old uvl ranges
				int sn,uvln;

				for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++)
					for (uvln=0;uvln<4;uvln++) {
						Segments[i].sides[sn].uvls[uvln].u /= 64;
						Segments[i].sides[sn].uvls[uvln].v /= 64;
						Segments[i].sides[sn].uvls[uvln].l /= 32;
					}
			}

			fuelcen_activate( &Segments[i], Segments[i].special );

			if (translate == 1)
				for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) {
					unsigned short orient;
					tmap_xlate = Segments[i].sides[j].tmap_num;
					Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate];
					if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
						if (Segments[i].sides[j].tmap_num < 0)	{
							mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
							Int3();
							Segments[i].sides[j].tmap_num = 0;
						}
					tmap_xlate = Segments[i].sides[j].tmap_num2 & 0x3FFF;
					orient = Segments[i].sides[j].tmap_num2 & (~0x3FFF);
					if (tmap_xlate != 0) {
						int xlated_tmap = tmap_xlate_table[tmap_xlate];

						if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
							if (xlated_tmap <= 0)	{
								mprintf( (0, "Couldn't find texture '%s' for Segment %d, side %d\n", old_tmap_list[tmap_xlate],i,j));
								Int3();
								Segments[i].sides[j].tmap_num2 = 0;
							}
						Segments[i].sides[j].tmap_num2 = xlated_tmap | orient;
					}
				}
		}
	}

	//===================== READ NEWSEGMENT INFO =====================

	#ifdef EDITOR

	{		// Default segment created.
		vms_vector	sizevec;
		med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE));		// New_segment = Segments[0];
		//memset( &New_segment, 0, sizeof(segment) );
	}

	if (mine_editor.newsegment_offset > -1)
	{
		if (cfseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET ))
			Error( "Error seeking to newsegment_offset in gamemine.c" );
		if (cfread( &New_segment, mine_editor.newsegment_size,1,LoadFile )!=1)
			Error( "Error reading new_segment in gamemine.c" );
	}

	if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0))
	{
		if (cfseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET ))
			Error( "Error seeking to newseg_verts_offset in gamemine.c" );
		for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ )
		{
			// Set the default values for this vertex
			Vertices[NEW_SEGMENT_VERTICES+i].x = 1;
			Vertices[NEW_SEGMENT_VERTICES+i].y = 1;
			Vertices[NEW_SEGMENT_VERTICES+i].z = 1;
			
			if (cfread( &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1,LoadFile )!=1)
				Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" );

			New_segment.verts[i] = NEW_SEGMENT_VERTICES+i;
		}
	}

	#endif
															
	//========================= UPDATE VARIABLES ======================

	#ifdef EDITOR

	// Setting to Markedsegp to NULL ignores Curside and Markedside, which
	// we want to do when reading in an old file.
	
 	Markedside = mine_editor.Markedside;
	Curside = mine_editor.Curside;
	for (i=0;i<10;i++)
		Groupside[i] = mine_editor.Groupside[i];

	if ( mine_editor.current_seg != -1 )
		Cursegp = mine_editor.current_seg + Segments;
	else
 		Cursegp = NULL;

	if (mine_editor.Markedsegp != -1 ) 
		Markedsegp = mine_editor.Markedsegp + Segments;
	else
		Markedsegp = NULL;

	num_groups = 0;
	current_group = -1;

	#endif

	Num_vertices = mine_fileinfo.vertex_howmany;
	Num_segments = mine_fileinfo.segment_howmany;
	Highest_vertex_index = Num_vertices-1;
	Highest_segment_index = Num_segments-1;

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

	#ifdef EDITOR
	Highest_vertex_index = MAX_SEGMENT_VERTICES-1;
	Highest_segment_index = MAX_SEGMENTS-1;
	set_vertex_counts();
	Highest_vertex_index = Num_vertices-1;
	Highest_segment_index = Num_segments-1;

	warn_if_concave_segments();
	#endif

	#ifdef EDITOR
		validate_segment_all();
	#endif

	//create_local_segment_data();

	//gamemine_find_textures();

	if (mine_top_fileinfo.fileinfo_version < MINE_VERSION )
		return 1;		//old version
	else
		return 0;

}
예제 #5
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;
}
예제 #6
0
// --------------------------------------------------------------------------------------
//	Create a new mine, set global variables.
int create_new_mine(void)
{
	int	s;
	vms_vector	sizevec;
	vms_matrix	m1 = IDENTITY_MATRIX;
	
	// initialize_mine_arrays();
	
	//	gamestate_not_restored = 1;
	
	// Clear refueling center code
	fuelcen_reset();
	hostage_init_all();
	
	init_all_vertices();
	
	Current_level_num = 0;		//0 means not a real level
	Current_level_name[0] = 0;
	Gamesave_current_version = LEVEL_FILE_VERSION;
	
	Cur_object_index = -1;
	reset_objects(1);		//just one object, the player
	
	num_groups = 0;
	current_group = -1;
	
	
	Num_vertices = 0;		// Number of vertices in global array.
	Highest_vertex_index = 0;
	Num_segments = 0;		// Number of segments in global array, will get increased in med_create_segment
	Highest_segment_index = 0;
	Cursegp = Segments;	// Say current segment is the only segment.
	Curside = WBACK;		// The active side is the back side
	Markedsegp = 0;		// Say there is no marked segment.
	Markedside = WBACK;	//	Shouldn't matter since Markedsegp == 0, but just in case...
	for (s=0;s<MAX_GROUPS+1;s++) {
		GroupList[s].num_segments = 0;		
		GroupList[s].num_vertices = 0;		
		Groupsegp[s] = NULL;
		Groupside[s] = 0;
	}
	
	Num_robot_centers = 0;
	Num_open_doors = 0;
	wall_init();
	trigger_init();
	
	// Create New_segment, which is the segment we will be adding at each instance.
	med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE));		// New_segment = Segments[0];
	//	med_create_segment(Segments,0,0,0,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE,vm_mat_make(&m1,F1_0,0,0,0,F1_0,0,0,0,F1_0));
	med_create_segment(Segments,0,0,0,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE,&m1);
	
	N_found_segs = 0;
	N_selected_segs = 0;
	N_warning_segs = 0;
	
	//--repair-- create_local_segment_data();
	
	ControlCenterTriggers.num_links = 0;
	
	create_new_mission();
	
    //editor_status("New mine created.");
	return	0;			// say no error
}
예제 #7
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;
}
예제 #8
0
// -----------------------------------------------------------------------------
//loads from an already-open file
// returns 0=everything ok, 1=old version, -1=error
int load_mine_data(PHYSFS_file *LoadFile)
{
	int   i, j;
	short tmap_xlate;
	int 	translate;
	char 	*temptr;
	int	mine_start = PHYSFS_tell(LoadFile);

	fuelcen_reset();

	for (i=0; i<sizeof(tmap_times_used)/sizeof(tmap_times_used[0]); i++ )
		tmap_times_used[i] = 0;

	#ifdef EDITOR
	// Create a new mine to initialize things.
	//texpage_goto_first();
	create_new_mine();
	#endif

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

	// These are the default values... version and fileinfo_sizeof
	// don't have defaults.
	mine_fileinfo.header_offset     =   -1;
	mine_fileinfo.header_size       =   sizeof(mine_header);
	mine_fileinfo.editor_offset     =   -1;
	mine_fileinfo.editor_size       =   sizeof(mine_editor);
	mine_fileinfo.vertex_offset     =   -1;
	mine_fileinfo.vertex_howmany    =   0;
	mine_fileinfo.vertex_sizeof     =   sizeof(vms_vector);
	mine_fileinfo.segment_offset    =   -1;
	mine_fileinfo.segment_howmany   =   0;
	mine_fileinfo.segment_sizeof    =   sizeof(segment);
	mine_fileinfo.newseg_verts_offset     =   -1;
	mine_fileinfo.newseg_verts_howmany    =   0;
	mine_fileinfo.newseg_verts_sizeof     =   sizeof(vms_vector);
	mine_fileinfo.group_offset		  =	-1;
	mine_fileinfo.group_howmany	  =	0;
	mine_fileinfo.group_sizeof		  =	sizeof(group);
	mine_fileinfo.texture_offset    =   -1;
	mine_fileinfo.texture_howmany   =   0;
 	mine_fileinfo.texture_sizeof    =   FILENAME_LEN;  // num characters in a name
 	mine_fileinfo.walls_offset		  =	-1;
	mine_fileinfo.walls_howmany	  =	0;
	mine_fileinfo.walls_sizeof		  =	sizeof(wall);  
 	mine_fileinfo.triggers_offset	  =	-1;
	mine_fileinfo.triggers_howmany  =	0;
	mine_fileinfo.triggers_sizeof	  =	sizeof(trigger);  
	mine_fileinfo.object_offset		=	-1;
	mine_fileinfo.object_howmany		=	1;
	mine_fileinfo.object_sizeof		=	sizeof(object);  

	mine_fileinfo.level_shake_frequency		=	0;
	mine_fileinfo.level_shake_duration		=	0;

	//	Delta light stuff for blowing out light sources.
//	if (mine_top_fileinfo.fileinfo_version >= 19) {
		mine_fileinfo.dl_indices_offset		=	-1;
		mine_fileinfo.dl_indices_howmany		=	0;
		mine_fileinfo.dl_indices_sizeof		=	sizeof(dl_index);  

		mine_fileinfo.delta_light_offset		=	-1;
		mine_fileinfo.delta_light_howmany		=	0;
		mine_fileinfo.delta_light_sizeof		=	sizeof(delta_light);  

//	}

	mine_fileinfo.segment2_offset		= -1;
	mine_fileinfo.segment2_howmany	= 0;
	mine_fileinfo.segment2_sizeof    = sizeof(segment2);

	// Read in mine_top_fileinfo to get size of saved fileinfo.
	
	memset( &mine_top_fileinfo, 0, sizeof(mine_top_fileinfo) );

	if (PHYSFSX_fseek( LoadFile, mine_start, SEEK_SET ))
		Error( "Error moving to top of file in gamemine.c" );

	if (PHYSFS_read( LoadFile, &mine_top_fileinfo, sizeof(mine_top_fileinfo), 1 )!=1)
		Error( "Error reading mine_top_fileinfo in gamemine.c" );

	if (mine_top_fileinfo.fileinfo_signature != 0x2884)
		return -1;

	// Check version number
	if (mine_top_fileinfo.fileinfo_version < COMPATIBLE_VERSION )
		return -1;

	// Now, Read in the fileinfo
	if (PHYSFSX_fseek( LoadFile, mine_start, SEEK_SET ))
		Error( "Error seeking to top of file in gamemine.c" );

	if (PHYSFS_read( LoadFile, &mine_fileinfo, mine_top_fileinfo.fileinfo_sizeof, 1 )!=1)
		Error( "Error reading mine_fileinfo in gamemine.c" );

	if (mine_top_fileinfo.fileinfo_version < 18) {
		Level_shake_frequency = 0;
		Level_shake_duration = 0;
		Secret_return_segment = 0;
		Secret_return_orient = vmd_identity_matrix;
	} else {
		Level_shake_frequency = mine_fileinfo.level_shake_frequency << 12;
		Level_shake_duration = mine_fileinfo.level_shake_duration << 12;
		Secret_return_segment = mine_fileinfo.secret_return_segment;
		Secret_return_orient = mine_fileinfo.secret_return_orient;
	}

	//===================== READ HEADER INFO ========================

	// Set default values.
	mine_header.num_vertices        =   0;
	mine_header.num_segments        =   0;

	if (mine_fileinfo.header_offset > -1 )
	{
		if (PHYSFSX_fseek( LoadFile, mine_fileinfo.header_offset, SEEK_SET ))
			Error( "Error seeking to header_offset in gamemine.c" );
	
		if (PHYSFS_read( LoadFile, &mine_header, mine_fileinfo.header_size, 1 )!=1)
			Error( "Error reading mine_header in gamemine.c" );
	}

	//===================== READ EDITOR INFO ==========================

	// Set default values
	mine_editor.current_seg         =   0;
	mine_editor.newsegment_offset   =   -1; // To be written
	mine_editor.newsegment_size     =   sizeof(segment);
	mine_editor.Curside             =   0;
	mine_editor.Markedsegp          =   -1;
	mine_editor.Markedside          =   0;

	if (mine_fileinfo.editor_offset > -1 )
	{
		if (PHYSFSX_fseek( LoadFile, mine_fileinfo.editor_offset, SEEK_SET ))
			Error( "Error seeking to editor_offset in gamemine.c" );
	
		if (PHYSFS_read( LoadFile, &mine_editor, mine_fileinfo.editor_size, 1 )!=1)
			Error( "Error reading mine_editor in gamemine.c" );
	}

	//===================== READ TEXTURE INFO ==========================

	if ( (mine_fileinfo.texture_offset > -1) && (mine_fileinfo.texture_howmany > 0))
	{
		if (PHYSFSX_fseek( LoadFile, mine_fileinfo.texture_offset, SEEK_SET ))
			Error( "Error seeking to texture_offset in gamemine.c" );

		for (i=0; i< mine_fileinfo.texture_howmany; i++ )
		{
			if (PHYSFS_read( LoadFile, &old_tmap_list[i], mine_fileinfo.texture_sizeof, 1 )!=1)
				Error( "Error reading old_tmap_list[i] in gamemine.c" );
		}
	}

	//=============== GENERATE TEXTURE TRANSLATION TABLE ===============

	translate = 0;
	
	Assert (NumTextures < MAX_TEXTURES);

	{
		hashtable ht;
	
		hashtable_init( &ht, NumTextures );
	
		// Remove all the file extensions in the textures list
	
		for (i=0;i<NumTextures;i++)	{
			temptr = strchr(TmapInfo[i].filename, '.');
			if (temptr) *temptr = '\0';
			hashtable_insert( &ht, TmapInfo[i].filename, i );
		}
	
		// For every texture, search through the texture list
		// to find a matching name.
		for (j=0;j<mine_fileinfo.texture_howmany;j++) 	{
			// Remove this texture name's extension
			temptr = strchr(old_tmap_list[j], '.');
			if (temptr) *temptr = '\0';
	
			tmap_xlate_table[j] = hashtable_search( &ht,old_tmap_list[j]);
			if (tmap_xlate_table[j]	< 0 )	{
				;
			}
			if (tmap_xlate_table[j] != j ) translate = 1;
			if (tmap_xlate_table[j] >= 0)
				tmap_times_used[tmap_xlate_table[j]]++;
		}
	
		{
			int count = 0;
			for (i=0; i<MAX_TEXTURES; i++ )
				if (tmap_times_used[i])
					count++;
		}
	
		hashtable_free( &ht );
	}

	//====================== READ VERTEX INFO ==========================

	// New check added to make sure we don't read in too many vertices.
	if ( mine_fileinfo.vertex_howmany > MAX_VERTICES )
		{
		mine_fileinfo.vertex_howmany = MAX_VERTICES;
		}

	if ( (mine_fileinfo.vertex_offset > -1) && (mine_fileinfo.vertex_howmany > 0))
	{
		if (PHYSFSX_fseek( LoadFile, mine_fileinfo.vertex_offset, SEEK_SET ))
			Error( "Error seeking to vertex_offset in gamemine.c" );

		for (i=0; i< mine_fileinfo.vertex_howmany; i++ )
		{
			// Set the default values for this vertex
			Vertices[i].x = 1;
			Vertices[i].y = 1;
			Vertices[i].z = 1;

			if (PHYSFS_read( LoadFile, &Vertices[i], mine_fileinfo.vertex_sizeof, 1 )!=1)
				Error( "Error reading Vertices[i] in gamemine.c" );
		}
	}

	//==================== READ SEGMENT INFO ===========================

	// New check added to make sure we don't read in too many segments.
	if ( mine_fileinfo.segment_howmany > MAX_SEGMENTS ) {
		mine_fileinfo.segment_howmany = MAX_SEGMENTS;
		mine_fileinfo.segment2_howmany = MAX_SEGMENTS;
	}

	// [commented out by mk on 11/20/94 (weren't we supposed to hit final in October?) because it looks redundant.  I think I'll test it now...]  fuelcen_reset();

	if ( (mine_fileinfo.segment_offset > -1) && (mine_fileinfo.segment_howmany > 0))	{

		if (PHYSFSX_fseek( LoadFile, mine_fileinfo.segment_offset,SEEK_SET ))

			Error( "Error seeking to segment_offset in gamemine.c" );

		Highest_segment_index = mine_fileinfo.segment_howmany-1;

		for (i=0; i< mine_fileinfo.segment_howmany; i++ ) {

			// Set the default values for this segment (clear to zero )
			//memset( &Segments[i], 0, sizeof(segment) );

			if (mine_top_fileinfo.fileinfo_version < 20) {
				v16_segment v16_seg;

				Assert(mine_fileinfo.segment_sizeof == sizeof(v16_seg));

				if (PHYSFS_read( LoadFile, &v16_seg, mine_fileinfo.segment_sizeof, 1 )!=1)
					Error( "Error reading segments in gamemine.c" );

				#ifdef EDITOR
				Segments[i].segnum = v16_seg.segnum;
				// -- Segments[i].pad = v16_seg.pad;
				#endif

				for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
					Segments[i].sides[j] = v16_seg.sides[j];

				for (j=0; j<MAX_SIDES_PER_SEGMENT; j++)
					Segments[i].children[j] = v16_seg.children[j];

				for (j=0; j<MAX_VERTICES_PER_SEGMENT; j++)
					Segments[i].verts[j] = v16_seg.verts[j];

				Segment2s[i].special = v16_seg.special;
				Segment2s[i].value = v16_seg.value;
				Segment2s[i].s2_flags = 0;
				Segment2s[i].matcen_num = v16_seg.matcen_num;
				Segment2s[i].static_light = v16_seg.static_light;
				fuelcen_activate( &Segments[i], Segment2s[i].special );

			} else  {
				if (PHYSFS_read( LoadFile, &Segments[i], mine_fileinfo.segment_sizeof, 1 )!=1)
					Error("Unable to read segment %i\n", i);
			}

			Segments[i].objects = -1;
			#ifdef EDITOR
			Segments[i].group = -1;
			#endif

			if (mine_top_fileinfo.fileinfo_version < 15) {	//used old uvl ranges
				int sn,uvln;

				for (sn=0;sn<MAX_SIDES_PER_SEGMENT;sn++)
					for (uvln=0;uvln<4;uvln++) {
						Segments[i].sides[sn].uvls[uvln].u /= 64;
						Segments[i].sides[sn].uvls[uvln].v /= 64;
						Segments[i].sides[sn].uvls[uvln].l /= 32;
					}
			}

			if (translate == 1)
				for (j=0;j<MAX_SIDES_PER_SEGMENT;j++) {
					unsigned short orient;
					tmap_xlate = Segments[i].sides[j].tmap_num;
					Segments[i].sides[j].tmap_num = tmap_xlate_table[tmap_xlate];
					if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
						if (Segments[i].sides[j].tmap_num < 0)	{
							Int3();
							Segments[i].sides[j].tmap_num = NumTextures-1;
						}
					tmap_xlate = Segments[i].sides[j].tmap_num2 & TMAP_NUM_MASK;
					orient = Segments[i].sides[j].tmap_num2 & (~TMAP_NUM_MASK);
					if (tmap_xlate != 0) {
						int xlated_tmap = tmap_xlate_table[tmap_xlate];

						if ((WALL_IS_DOORWAY(&Segments[i],j) & WID_RENDER_FLAG))
							if (xlated_tmap <= 0)	{
								Int3();
								Segments[i].sides[j].tmap_num2 = NumTextures-1;
							}
						Segments[i].sides[j].tmap_num2 = xlated_tmap | orient;
					}
				}
		}


		if (mine_top_fileinfo.fileinfo_version >= 20)
			for (i=0; i<=Highest_segment_index; i++) {
				PHYSFS_read(LoadFile, &Segment2s[i], sizeof(segment2), 1);
				fuelcen_activate( &Segments[i], Segment2s[i].special );
			}
	}

	//===================== READ NEWSEGMENT INFO =====================

	#ifdef EDITOR

	{		// Default segment created.
		vms_vector	sizevec;
		med_create_new_segment(vm_vec_make(&sizevec,DEFAULT_X_SIZE,DEFAULT_Y_SIZE,DEFAULT_Z_SIZE));		// New_segment = Segments[0];
		//memset( &New_segment, 0, sizeof(segment) );
	}

	if (mine_editor.newsegment_offset > -1)
	{
		if (PHYSFSX_fseek( LoadFile, mine_editor.newsegment_offset,SEEK_SET ))
			Error( "Error seeking to newsegment_offset in gamemine.c" );
		if (PHYSFS_read( LoadFile, &New_segment, mine_editor.newsegment_size,1 )!=1)
			Error( "Error reading new_segment in gamemine.c" );
	}

	if ( (mine_fileinfo.newseg_verts_offset > -1) && (mine_fileinfo.newseg_verts_howmany > 0))
	{
		if (PHYSFSX_fseek( LoadFile, mine_fileinfo.newseg_verts_offset, SEEK_SET ))
			Error( "Error seeking to newseg_verts_offset in gamemine.c" );
		for (i=0; i< mine_fileinfo.newseg_verts_howmany; i++ )
		{
			// Set the default values for this vertex
			Vertices[NEW_SEGMENT_VERTICES+i].x = 1;
			Vertices[NEW_SEGMENT_VERTICES+i].y = 1;
			Vertices[NEW_SEGMENT_VERTICES+i].z = 1;
			
			if (PHYSFS_read( LoadFile, &Vertices[NEW_SEGMENT_VERTICES+i], mine_fileinfo.newseg_verts_sizeof,1 )!=1)
				Error( "Error reading Vertices[NEW_SEGMENT_VERTICES+i] in gamemine.c" );

			New_segment.verts[i] = NEW_SEGMENT_VERTICES+i;
		}
	}

	#endif
															
	//========================= UPDATE VARIABLES ======================

	#ifdef EDITOR

	// Setting to Markedsegp to NULL ignores Curside and Markedside, which
	// we want to do when reading in an old file.
	
 	Markedside = mine_editor.Markedside;
	Curside = mine_editor.Curside;
	for (i=0;i<10;i++)
		Groupside[i] = mine_editor.Groupside[i];

	if ( mine_editor.current_seg != -1 )
		Cursegp = mine_editor.current_seg + Segments;
	else
 		Cursegp = NULL;

	if (mine_editor.Markedsegp != -1 ) 
		Markedsegp = mine_editor.Markedsegp + Segments;
	else
		Markedsegp = NULL;

	num_groups = 0;
	current_group = -1;

	#endif

	Num_vertices = mine_fileinfo.vertex_howmany;
	Num_segments = mine_fileinfo.segment_howmany;
	Highest_vertex_index = Num_vertices-1;
	Highest_segment_index = Num_segments-1;

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

	#ifdef EDITOR
	Highest_vertex_index = MAX_SEGMENT_VERTICES-1;
	Highest_segment_index = MAX_SEGMENTS-1;
	set_vertex_counts();
	Highest_vertex_index = Num_vertices-1;
	Highest_segment_index = Num_segments-1;

	warn_if_concave_segments();
	#endif

	#ifdef EDITOR
		validate_segment_all();
	#endif

	//create_local_segment_data();

	//gamemine_find_textures();

	if (mine_top_fileinfo.fileinfo_version < MINE_VERSION )
		return 1;		//old version
	else
		return 0;

}
예제 #9
0
파일: state.c 프로젝트: osgcc/descent-mac
int state_restore_all_sub(char *filename, int multi)
{
	int ObjectStartLocation;
	int BogusSaturnShit = 0;
	int version,i, j, segnum;
	object * obj;
	FILE *fp;
	int current_level, next_level;
	int between_levels;
	char mission[16];
	char desc[DESC_LENGTH+1];
	char id[5];
	char org_callsign[CALLSIGN_LEN+16];

	if ( Game_mode & GM_MULTI )	{
#ifdef MULTI_SAVE
		if ( !FindArg( "-multisave" ) ) 
#endif
			return 0;
	}

	fp = fopen( filename, "rb" );
	if ( !fp ) return 0;

//Read id
	fread( id, sizeof(char)*4, 1, fp );
	if ( memcmp( id, dgss_id, 4 )) {
		fclose(fp);
		return 0;
	}

//Read version
	fread( &version, sizeof(int), 1, fp );
	if (version < STATE_COMPATIBLE_VERSION)	{
		fclose(fp);
		return 0;
	}

// Read description
	fread( desc, sizeof(char)*DESC_LENGTH, 1, fp );

// Skip the current screen shot...
	fseek( fp, THUMBNAIL_W*THUMBNAIL_H, SEEK_CUR );

// Read the Between levels flag...
	fread( &between_levels, sizeof(int), 1, fp );

// Read the mission info...
	fread( mission, sizeof(char)*9, 1, fp );

#ifdef MAC_SHAREWARE
	if (strcmp(mission, "") ) {
		nm_messagebox( NULL, 1, "Ok", "Error!\nUnable to load mission\n'%s'\n", mission );
		fclose(fp);
		return 0;
	}
#else
	if (!load_mission_by_name( mission ))	{
		nm_messagebox( NULL, 1, "Ok", "Error!\nUnable to load mission\n'%s'\n", mission );
		fclose(fp);
		return 0;
	}
#endif

//Read level info
	fread( &current_level, sizeof(int), 1, fp );
	fread( &next_level, sizeof(int), 1, fp );

//Restore GameTime
	fread( &GameTime, sizeof(fix), 1, fp );

// Start new game....
	if (!multi)	{
		Game_mode = GM_NORMAL;
		Function_mode = FMODE_GAME;
		#ifdef NETWORK
		change_playernum_to(0);
		#endif
		strcpy( org_callsign, Players[0].callsign );
		N_players = 1;
		InitPlayerObject();				//make sure player's object set up
		init_player_stats_game();		//clear all stats
	} else {
		strcpy( org_callsign, Players[Player_num].callsign );
	}
//Read player info

	if ( between_levels )	{
		int saved_offset;
		fread( &Players[Player_num], sizeof(player), 1, fp );
		saved_offset = ftell(fp);
		fclose( fp );
		do_briefing_screens(next_level);
		fp = fopen( filename, "rb" );
		fseek( fp, saved_offset, SEEK_SET );
 		StartNewLevelSub( next_level, 0 );		
	} else {
		StartNewLevelSub(current_level, 0);		
		fread( &Players[Player_num], sizeof(player), 1, fp );
	}
	strcpy( Players[Player_num].callsign, org_callsign );

// Set the right level
	if ( between_levels )
		Players[Player_num].level = next_level;

// Restore the weapon states
	fread( &Primary_weapon, sizeof(byte), 1, fp );
	fread( &Secondary_weapon, sizeof(byte), 1, fp );

	select_weapon(Primary_weapon, 0, 0, 0);
	select_weapon(Secondary_weapon, 1, 0, 0);

// Restore the difficulty level
	fread( &Difficulty_level, sizeof(int), 1, fp );

// Restore the cheats enabled flag
	fread( &Cheats_enabled, sizeof(int), 1, fp );
	fread( &Game_turbo_mode, sizeof(int), 1, fp );

	if ( !between_levels )	{
		Do_appearance_effect = 0;			// Don't do this for middle o' game stuff.

		ObjectStartLocation = ftell( fp );
RetryObjectLoading:
		//Clear out all the objects from the lvl file
		for (segnum=0; segnum <= Highest_segment_index; segnum++)
			Segments[segnum].objects = -1;
		reset_objects(1);
	
		//Read objects, and pop 'em into their respective segments.
		fread( &i, sizeof(int), 1, fp );
		Highest_object_index = i-1;
		if ( !BogusSaturnShit )	
			fread( Objects, sizeof(object)*i, 1, fp );
		else {
			ubyte tmp_object[sizeof(object)];
			for (i=0; i<=Highest_object_index; i++ )	{
				fread( tmp_object, sizeof(object)-3, 1, fp );
				// Insert 3 bytes after the read in obj->rtype.pobj_info.alt_textures field.
				memcpy( &Objects[i], tmp_object, sizeof(object)-3 );
				Objects[i].rtype.pobj_info.alt_textures = -1;
			}
		}
	
		Object_next_signature = 0;
		for (i=0; i<=Highest_object_index; i++ )	{
			obj = &Objects[i];
			obj->rtype.pobj_info.alt_textures = -1;
			segnum = obj->segnum;
			obj->next = obj->prev = obj->segnum = -1;
			if ( obj->type != OBJ_NONE )	{
				// Check for a bogus Saturn version!!!!
				if (!BogusSaturnShit )	{
					if ( (segnum<0) || (segnum>Highest_segment_index) ) {
						BogusSaturnShit = 1;
						mprintf(( 1, "READING BOGUS SATURN VERSION OBJECTS!!! (Object:%d)\n", i ));
						fseek( fp, ObjectStartLocation, SEEK_SET );
						goto RetryObjectLoading;
					}
				}
				obj_link(i,segnum);
				if ( obj->signature > Object_next_signature )
					Object_next_signature = obj->signature;
			}
		}	
		special_reset_objects();
		Object_next_signature++;
	
		//Restore wall info
		fread( &i, sizeof(int), 1, fp );
		Num_walls = i;
		// Check for a bogus Saturn version!!!!
		if (!BogusSaturnShit )	{
			if ( (Num_walls<0) || (Num_walls>MAX_WALLS) ) {
				BogusSaturnShit = 1;
				mprintf(( 1, "READING BOGUS SATURN VERSION OBJECTS!!! (Num_walls)\n" ));
				fseek( fp, ObjectStartLocation, SEEK_SET );
				goto RetryObjectLoading;
			}
		}

		fread( Walls, sizeof(wall)*Num_walls, 1, fp );
		// Check for a bogus Saturn version!!!!
		if (!BogusSaturnShit )	{
			for (i=0; i<Num_walls; i++ )	{
				if ( (Walls[i].segnum<0) || (Walls[i].segnum>Highest_segment_index) || (Walls[i].sidenum<-1) || (Walls[i].sidenum>5) ) {
					BogusSaturnShit = 1;
					mprintf(( 1, "READING BOGUS SATURN VERSION OBJECTS!!! (Wall %d)\n", i ));
					fseek( fp, ObjectStartLocation, SEEK_SET );
					goto RetryObjectLoading;
				}
			}
		}
	
		//Restore door info
		fread( &i, sizeof(int), 1, fp );
		Num_open_doors = i;
		fread( ActiveDoors, sizeof(active_door)*Num_open_doors, 1, fp );
	
		//Restore trigger info
		fread( &Num_triggers, sizeof(int), 1, fp );
		fread( Triggers, sizeof(trigger)*Num_triggers, 1, fp );
	
		//Restore tmap info
		for (i=0; i<=Highest_segment_index; i++ )	{
			for (j=0; j<6; j++ )	{
				fread( &Segments[i].sides[j].wall_num, sizeof(short), 1, fp );
				fread( &Segments[i].sides[j].tmap_num, sizeof(short), 1, fp );
				fread( &Segments[i].sides[j].tmap_num2, sizeof(short), 1, fp );
			}
		}
	
		//Restore the fuelcen info
		fread( &Fuelcen_control_center_destroyed, sizeof(int), 1, fp );
		fread( &Fuelcen_seconds_left, sizeof(int), 1, fp );
		fread( &Num_robot_centers, sizeof(int), 1, fp );
		fread( RobotCenters, sizeof(matcen_info)*Num_robot_centers, 1, fp );
		fread( &ControlCenterTriggers, sizeof(control_center_triggers), 1, fp );
		fread( &Num_fuelcenters, sizeof(int), 1, fp );
		fread( Station, sizeof(FuelCenter)*Num_fuelcenters, 1, fp );
	
		// Restore the control cen info
		fread( &Control_center_been_hit, sizeof(int), 1, fp );
		fread( &Control_center_player_been_seen, sizeof(int), 1, fp );
		fread( &Control_center_next_fire_time, sizeof(int), 1, fp );
		fread( &Control_center_present, sizeof(int), 1, fp );
		fread( &Dead_controlcen_object_num, sizeof(int), 1, fp );
	
		// Restore the AI state
		ai_restore_state( fp );
	
		// Restore the automap visited info
		fread( Automap_visited, sizeof(ubyte)*MAX_SEGMENTS, 1, fp );

		//	Restore hacked up weapon system stuff.
		Fusion_next_sound_time = GameTime;
		Auto_fire_fusion_cannon_time = 0;
		Next_laser_fire_time = GameTime;
		Next_missile_fire_time = GameTime;
		Last_laser_fired_time = GameTime;

	}
	state_game_id = 0;

	if ( version >= 7 )	{
		int tmp_Lunacy;
		fread( &state_game_id, sizeof(uint), 1, fp );
		fread( &Laser_rapid_fire, sizeof(int), 1, fp );
		fread( &Ugly_robot_cheat, sizeof(int), 1, fp );
		fread( &Ugly_robot_texture, sizeof(int), 1, fp );
		fread( &Physics_cheat_flag, sizeof(int), 1, fp );
		fread( &tmp_Lunacy, sizeof(int), 1, fp );
		if ( tmp_Lunacy )
			do_lunacy_on();
	}

	fclose(fp);

// Load in bitmaps, etc..
	piggy_load_level_data();

	return 1;
}
예제 #10
0
파일: state.c 프로젝트: btb/d2x
int state_restore_all_sub(char *filename, int multi, int secret_restore)
{
	int ObjectStartLocation;
	int version,i, j, segnum;
	object * obj;
	PHYSFS_file *fp;
	int current_level, next_level;
	int between_levels;
	char mission[16];
	char desc[DESC_LENGTH+1];
	char id[5];
	char org_callsign[CALLSIGN_LEN+16];
#ifdef NETWORK
	int found;
	int nplayers = 0; //,playid[12],mynum;
	player restore_players[MAX_PLAYERS];
#endif
	fix	old_gametime = GameTime;
	short TempTmapNum[MAX_SEGMENTS][MAX_SIDES_PER_SEGMENT];
	short TempTmapNum2[MAX_SEGMENTS][MAX_SIDES_PER_SEGMENT];

	#if defined(MACINTOSH) && !defined(NDEBUG)
	if (strncmp(filename, PLAYER_DIR, 9))
		Int3();
	#endif

	fp = PHYSFSX_openReadBuffered(filename);
	if ( !fp ) return 0;

//Read id
	//FIXME: check for swapped file, react accordingly...
	PHYSFS_read(fp, id, sizeof(char) * 4, 1);
	if ( memcmp( id, dgss_id, 4 )) {
		PHYSFS_close(fp);
		return 0;
	}

//Read version
	PHYSFS_read(fp, &version, sizeof(int), 1);
	if (version < STATE_COMPATIBLE_VERSION)	{
		PHYSFS_close(fp);
		return 0;
	}

// Read description
	PHYSFS_read(fp, desc, sizeof(char) * DESC_LENGTH, 1);

// Skip the current screen shot...
	PHYSFS_seek(fp, PHYSFS_tell(fp) + THUMBNAIL_W * THUMBNAIL_H);

// And now...skip the goddamn palette stuff that somebody forgot to add
	PHYSFS_seek(fp, PHYSFS_tell(fp) + 768);

// Read the Between levels flag...
	PHYSFS_read(fp, &between_levels, sizeof(int), 1);

	Assert(between_levels == 0);	//between levels save ripped out

// Read the mission info...
	PHYSFS_read(fp, mission, sizeof(char) * 9, 1);
        mprintf ((0,"Missionname to load = %s\n",mission));

	if (!load_mission_by_name( mission ))	{
		nm_messagebox( NULL, 1, "Ok", "Error!\nUnable to load mission\n'%s'\n", mission );
		PHYSFS_close(fp);
		return 0;
	}

//Read level info
	PHYSFS_read(fp, &current_level, sizeof(int), 1);
	PHYSFS_read(fp, &next_level, sizeof(int), 1);

//Restore GameTime
	PHYSFS_read(fp, &GameTime, sizeof(fix), 1);

// Start new game....
	if (!multi)	{
		Game_mode = GM_NORMAL;
		Function_mode = FMODE_GAME;
#ifdef NETWORK
		change_playernum_to(0);
#endif
		strcpy( org_callsign, Players[0].callsign );
		N_players = 1;
		if (!secret_restore) {
			InitPlayerObject();				//make sure player's object set up
			init_player_stats_game();		//clear all stats
		}
	} else {
		strcpy( org_callsign, Players[Player_num].callsign );
	}

#ifdef NETWORK
   if (Game_mode & GM_MULTI)
	 {
		PHYSFS_read(fp, &state_game_id, sizeof(int), 1);
		PHYSFS_read(fp, &Netgame, sizeof(netgame_info), 1);
		PHYSFS_read(fp, &NetPlayers, sizeof(AllNetPlayers_info), 1);
		PHYSFS_read(fp, &nplayers, sizeof(N_players), 1);
		PHYSFS_read(fp, &Player_num, sizeof(Player_num), 1);
		for (i=0;i<nplayers;i++)
			PHYSFS_read(fp, &restore_players[i], sizeof(player), 1);
#ifdef RISKY_PROPOSITION
		PHYSFS_read(fp, &robot_controlled[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_read(fp, &robot_agitation[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_read(fp, &robot_controlled_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_read(fp, &robot_last_send_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_read(fp, &robot_last_message_time[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_read(fp, &robot_send_pending[0], 4 * MAX_ROBOTS_CONTROLLED, 1);
		PHYSFS_read(fp, &robot_fired[0], 4 * MAX_ROBOTS_CONTROLLED, 1);

      for (i=0;i<MAX_ROBOTS_CONTROLLED;i++)
			PHYSFS_read(fp, &robot_fire_buf[i][0],21,1);
#endif

	   for (i=0;i<nplayers;i++)
		 {
		  found=0;
		  for (j=0;j<nplayers;j++)
			 {
           if ((!strcmp (restore_players[i].callsign,Players[j].callsign)) && Players[j].connected==1)
				 found=1;
			 }
		  restore_players[i].connected=found;
	    }
		memcpy (&Players,&restore_players,sizeof(player)*nplayers);
		N_players=nplayers;

      if (network_i_am_master())
		 {
		  for (i=0;i<N_players;i++)
			{
			 if (i==Player_num)
				continue;
   		 Players[i].connected=0;
			}
	 	 }

	  	//Viewer = ConsoleObject = &Objects[Players[Player_num].objnum];
	 }

#endif

//Read player info

	{
		StartNewLevelSub(current_level, 1, secret_restore);

		if (secret_restore) {
			player	dummy_player;

			PHYSFS_read(fp, &dummy_player, sizeof(player), 1);
			if (secret_restore == 1) {		//	This means he didn't die, so he keeps what he got in the secret level.
				Players[Player_num].level = dummy_player.level;
				Players[Player_num].last_score = dummy_player.last_score;
				Players[Player_num].time_level = dummy_player.time_level;

				Players[Player_num].num_robots_level = dummy_player.num_robots_level;
				Players[Player_num].num_robots_total = dummy_player.num_robots_total;
				Players[Player_num].hostages_rescued_total = dummy_player.hostages_rescued_total;
				Players[Player_num].hostages_total = dummy_player.hostages_total;
				Players[Player_num].hostages_on_board = dummy_player.hostages_on_board;
				Players[Player_num].hostages_level = dummy_player.hostages_level;
				Players[Player_num].homing_object_dist = dummy_player.homing_object_dist;
				Players[Player_num].hours_level = dummy_player.hours_level;
				Players[Player_num].hours_total = dummy_player.hours_total;
				do_cloak_invul_secret_stuff(old_gametime);
			} else {
				Players[Player_num] = dummy_player;
			}
		} else {
			PHYSFS_read(fp, &Players[Player_num], sizeof(player), 1);
		}
	}
	strcpy( Players[Player_num].callsign, org_callsign );

// Set the right level
	if ( between_levels )
		Players[Player_num].level = next_level;

// Restore the weapon states
	PHYSFS_read(fp, &Primary_weapon, sizeof(sbyte), 1);
	PHYSFS_read(fp, &Secondary_weapon, sizeof(sbyte), 1);

	select_weapon(Primary_weapon, 0, 0, 0);
	select_weapon(Secondary_weapon, 1, 0, 0);

// Restore the difficulty level
	PHYSFS_read(fp, &Difficulty_level, sizeof(int), 1);

// Restore the cheats enabled flag
	{
		int cheats_enabled;

		PHYSFS_read(fp, &cheats_enabled, sizeof(int), 1);
		cvar_setint(&Cheats_enabled, cheats_enabled);
	}

	if ( !between_levels )	{
		Do_appearance_effect = 0;			// Don't do this for middle o' game stuff.

		ObjectStartLocation = (int)PHYSFS_tell(fp);
		//Clear out all the objects from the lvl file
		for (segnum=0; segnum <= Highest_segment_index; segnum++)
			Segments[segnum].objects = -1;
		reset_objects(1);
	
		//Read objects, and pop 'em into their respective segments.
		PHYSFS_read(fp, &i, sizeof(int), 1);
		Highest_object_index = i-1;
		PHYSFS_read(fp, Objects, sizeof(object) * i, 1);
	
		Object_next_signature = 0;
		for (i=0; i<=Highest_object_index; i++ )	{
			obj = &Objects[i];
			obj->rtype.pobj_info.alt_textures = -1;
			segnum = obj->segnum;
			obj->next = obj->prev = obj->segnum = -1;
			if ( obj->type != OBJ_NONE )	{
				obj_link(i,segnum);
				if ( obj->signature > Object_next_signature )
					Object_next_signature = obj->signature;
			}

			//look for, and fix, boss with bogus shields
			if (obj->type == OBJ_ROBOT && Robot_info[obj->id].boss_flag) {
				fix save_shields = obj->shields;

				copy_defaults_to_robot(obj);		//calculate starting shields

				//if in valid range, use loaded shield value
				if (save_shields > 0 && save_shields <= obj->shields)
					obj->shields = save_shields;
				else
					obj->shields /= 2;  //give player a break
			}

		}	
		special_reset_objects();
		Object_next_signature++;
	
		//	1 = Didn't die on secret level.
		//	2 = Died on secret level.
		if (secret_restore && (Current_level_num >= 0)) {
			set_pos_from_return_segment();
			if (secret_restore == 2)
				init_player_stats_new_ship();
		}

		//Restore wall info
		PHYSFS_read(fp, &i, sizeof(int), 1);
		Num_walls = i;
		PHYSFS_read(fp, Walls, sizeof(wall), Num_walls);

		//now that we have the walls, check if any sounds are linked to
		//walls that are now open
		for (i=0;i<Num_walls;i++) {
			if (Walls[i].type == WALL_OPEN)
				digi_kill_sound_linked_to_segment(Walls[i].segnum,Walls[i].sidenum,-1);	//-1 means kill any sound
		}

		//Restore exploding wall info
		if (version >= 10) {
			PHYSFS_read(fp, &i, sizeof(int), 1);
			PHYSFS_read(fp, expl_wall_list, sizeof(*expl_wall_list), i);
		}

		//Restore door info
		PHYSFS_read(fp, &i, sizeof(int), 1);
		Num_open_doors = i;
		PHYSFS_read(fp, ActiveDoors, sizeof(active_door), Num_open_doors);
	
		if (version >= 14) {		//Restore cloaking wall info
			PHYSFS_read(fp, &i, sizeof(int), 1);
			Num_cloaking_walls = i;
			PHYSFS_read(fp, CloakingWalls, sizeof(cloaking_wall), Num_cloaking_walls);
		}
	
		//Restore trigger info
		PHYSFS_read(fp, &Num_triggers, sizeof(int), 1);
		PHYSFS_read(fp, Triggers, sizeof(trigger), Num_triggers);
	
		//Restore tmap info (to temp values so we can use compiled-in tmap info to compute static_light)
		for (i=0; i<=Highest_segment_index; i++ )	{
			for (j=0; j<6; j++ )	{
				PHYSFS_read(fp, &Segments[i].sides[j].wall_num, sizeof(short), 1);
				PHYSFS_read(fp, &TempTmapNum[i][j], sizeof(short), 1);
				PHYSFS_read(fp, &TempTmapNum2[i][j], sizeof(short), 1);
			}
		}
	
		//Restore the fuelcen info
		PHYSFS_read(fp, &Control_center_destroyed, sizeof(int), 1);
		PHYSFS_read(fp, &Countdown_timer, sizeof(int), 1);
		PHYSFS_read(fp, &Num_robot_centers, sizeof(int), 1);
		PHYSFS_read(fp, RobotCenters, sizeof(matcen_info), Num_robot_centers);
		PHYSFS_read(fp, &ControlCenterTriggers, sizeof(control_center_triggers), 1);
		PHYSFS_read(fp, &Num_fuelcenters, sizeof(int), 1);
		PHYSFS_read(fp, Station, sizeof(FuelCenter), Num_fuelcenters);
	
		// Restore the control cen info
		PHYSFS_read(fp, &Control_center_been_hit, sizeof(int), 1);
		PHYSFS_read(fp, &Control_center_player_been_seen, sizeof(int), 1);
		PHYSFS_read(fp, &Control_center_next_fire_time, sizeof(int), 1);
		PHYSFS_read(fp, &Control_center_present, sizeof(int), 1);
		PHYSFS_read(fp, &Dead_controlcen_object_num, sizeof(int), 1);
	
		// Restore the AI state
		ai_restore_state( fp, version );
	
		// Restore the automap visited info
		PHYSFS_read(fp, Automap_visited, sizeof(ubyte), MAX_SEGMENTS);

		//	Restore hacked up weapon system stuff.
		Fusion_next_sound_time = GameTime;
		Auto_fire_fusion_cannon_time = 0;
		Next_laser_fire_time = GameTime;
		Next_missile_fire_time = GameTime;
		Last_laser_fired_time = GameTime;

	}
	state_game_id = 0;

	if ( version >= 7 )	{
		PHYSFS_read(fp, &state_game_id, sizeof(uint), 1);
		PHYSFS_read(fp, &Laser_rapid_fire, sizeof(int), 1);
		PHYSFS_read(fp, &Lunacy, sizeof(int), 1);		//	Yes, writing this twice.  Removed the Ugly robot system, but didn't want to change savegame format.
		PHYSFS_read(fp, &Lunacy, sizeof(int), 1);
		if ( Lunacy )
			do_lunacy_on();
	}

	if (version >= 17) {
		PHYSFS_read(fp, MarkerObject, sizeof(MarkerObject), 1);
		PHYSFS_read(fp, MarkerOwner, sizeof(MarkerOwner), 1);
		PHYSFS_read(fp, MarkerMessage, sizeof(MarkerMessage), 1);
	}
	else {
		int num,dummy;

		// skip dummy info

		PHYSFS_read(fp, &num,sizeof(int), 1);           // was NumOfMarkers
		PHYSFS_read(fp, &dummy,sizeof(int), 1);         // was CurMarker

		PHYSFS_seek(fp, PHYSFS_tell(fp) + num * (sizeof(vms_vector) + 40));

		for (num=0;num<NUM_MARKERS;num++)
			MarkerObject[num] = -1;
	}

	if (version>=11) {
		if (secret_restore != 1)
			PHYSFS_read(fp, &Afterburner_charge, sizeof(fix), 1);
		else {
			fix	dummy_fix;
			PHYSFS_read(fp, &dummy_fix, sizeof(fix), 1);
		}
	}
	if (version>=12) {
		//read last was super information
		PHYSFS_read(fp, &Primary_last_was_super, sizeof(Primary_last_was_super), 1);
		PHYSFS_read(fp, &Secondary_last_was_super, sizeof(Secondary_last_was_super), 1);
	}

	if (version >= 12) {
		PHYSFS_read(fp, &Flash_effect, sizeof(int), 1);
		PHYSFS_read(fp, &Time_flash_last_played, sizeof(int), 1);
		PHYSFS_read(fp, &PaletteRedAdd, sizeof(int), 1);
		PHYSFS_read(fp, &PaletteGreenAdd, sizeof(int), 1);
		PHYSFS_read(fp, &PaletteBlueAdd, sizeof(int), 1);
	} else {
		Flash_effect = 0;
		Time_flash_last_played = 0;
		PaletteRedAdd = 0;
		PaletteGreenAdd = 0;
		PaletteBlueAdd = 0;
	}

	//	Load Light_subtracted
	if (version >= 16) {
		PHYSFS_read(fp, Light_subtracted, sizeof(Light_subtracted[0]), MAX_SEGMENTS);
		apply_all_changed_light();
	} else {
		int	i;
		for (i=0; i<=Highest_segment_index; i++)
			Light_subtracted[i] = 0;
	}

	// static_light should now be computed - now actually set tmap info
	for (i=0; i<=Highest_segment_index; i++ )       {
		for (j=0; j<6; j++ )    {
			Segments[i].sides[j].tmap_num=TempTmapNum[i][j];
			Segments[i].sides[j].tmap_num2=TempTmapNum2[i][j];
		}
	}

	if (!secret_restore) {
		if (version >= 20) {
			PHYSFS_read(fp, &First_secret_visit, sizeof(First_secret_visit), 1);
			mprintf((0, "File: [%s] Read First_secret_visit: New value = %i\n", filename, First_secret_visit));
		} else
			First_secret_visit = 1;
	} else
		First_secret_visit = 0;

	if (version >= 22)
	{
		if (secret_restore != 1)
			PHYSFS_read(fp, &Omega_charge, sizeof(fix), 1);
		else {
			fix	dummy_fix;
			PHYSFS_read(fp, &dummy_fix, sizeof(fix), 1);
		}
	}

	PHYSFS_close(fp);

#ifdef NETWORK
   if (Game_mode & GM_MULTI)   // Get rid of ships that aren't
	 {									 // connected in the restored game
		for (i=0;i<nplayers;i++)
		 {
		  mprintf ((0,"Testing %s = %d\n",Players[i].callsign,Players[i].connected));
		  if (Players[i].connected!=1)
		   {
		    network_disconnect_player (i);
  	       create_player_appearance_effect(&Objects[Players[i].objnum]);
			 mprintf ((0,"Killing player ship %s!\n",Players[i].callsign));
	      }
		 }
			
	 }
#endif

// Load in bitmaps, etc..
//!!	piggy_load_level_data();	//already done by StartNewLevelSub()

	return 1;
}
예제 #11
0
int load_mine_data_compiled(CFILE *LoadFile)
{
	int		i,segnum,sidenum;
	ubyte		version;
	short		temp_short;
	ushort	temp_ushort;
	ubyte		bit_mask;

	//	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 ==============================
//	cfread( &version, sizeof(ubyte), 1, LoadFile );						// 1 byte = compiled version
	version = read_byte(LoadFile);
	Assert( version==COMPILED_MINE_VERSION );

//	cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );					// 2 bytes = Num_vertices
//	Num_vertices = temp_ushort;
	Num_vertices = read_short(LoadFile);
	Assert( Num_vertices <= MAX_VERTICES );

//	cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );					// 2 bytes = Num_segments
//	Num_segments = INTEL_SHORT(temp_ushort);
	Num_segments = read_short(LoadFile);
	Assert( Num_segments <= MAX_SEGMENTS );

//	cfread( Vertices, sizeof(vms_vector), Num_vertices, LoadFile );

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

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

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

 		cfread( &bit_mask, sizeof(ubyte), 1, LoadFile );

		#if defined(SHAREWARE) && !defined(MACINTOSH)
			// -- 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);
			// --read_special(segnum,bit_mask,LoadFile);
		#endif

		Segments[segnum].objects = -1;

		// Read fix	Segments[segnum].static_light (shift down 5 bits, write as short)
//		cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile );
//		temp_ushort = read_short(LoadFile);
//		Segment2s[segnum].static_light	= ((fix)temp_ushort) << 4;
		//cfread( &Segments[segnum].static_light, sizeof(fix), 1, LoadFile );
	
		// Read the walls as a 6 byte array
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ )	{
			Segments[segnum].sides[sidenum].pad = 0;
		}

 		cfread( &bit_mask, sizeof(ubyte), 1, LoadFile );
		for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
			ubyte byte_wallnum;

			if (bit_mask & (1 << sidenum)) {
				cfread( &byte_wallnum, sizeof(ubyte), 1, 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;
//				cfread( &temp_ushort, sizeof(ushort), 1, LoadFile );
				temp_ushort = read_short(LoadFile);
				Segments[segnum].sides[sidenum].tmap_num = temp_ushort & 0x7fff;

				if (!(temp_ushort & 0x8000))
					Segments[segnum].sides[sidenum].tmap_num2 = 0;
				else {
					// Read short Segments[segnum].sides[sidenum].tmap_num2;
//					cfread( &Segments[segnum].sides[sidenum].tmap_num2, sizeof(short), 1, LoadFile );
					Segments[segnum].sides[sidenum].tmap_num2 = read_short(LoadFile);
				}

				// 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++ )	{
//					cfread( &temp_short, sizeof(short), 1, LoadFile );
					temp_short = read_short(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].u = ((fix)temp_short) << 5;
//					cfread( &temp_short, sizeof(short), 1, LoadFile );
					temp_short = read_short(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].v = ((fix)temp_short) << 5;
//					cfread( &temp_ushort, sizeof(temp_ushort), 1, LoadFile );
					temp_ushort = read_short(LoadFile);
					Segments[segnum].sides[sidenum].uvls[i].l = ((fix)temp_ushort) << 1;
					//cfread( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, LoadFile );
				}	
			} 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++) {
	byte		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.

// MIKE!!!!! You should know better than this when the mac is involved!!!!!!

	for (i=0; i<Num_segments; i++) {
// NO NO!!!!		cfread( &Segment2s[i], sizeof(segment2), 1, LoadFile );
		Segment2s[i].special = read_byte(LoadFile);
		Segment2s[i].matcen_num = read_byte(LoadFile);
		Segment2s[i].value = read_byte(LoadFile);
		Segment2s[i].s2_flags = read_byte(LoadFile);
		Segment2s[i].static_light = read_fix(LoadFile);
		fuelcen_activate( &Segments[i], Segment2s[i].special );
	}

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

	return 0;
}
예제 #12
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;
}