// For reading the master chunk (ideally, whole file)
static bool ReadMaster(OpenedFile& OFile, int32 ParentChunkEnd)
{
	int32 Location = 0;
	OFile.GetPosition(Location);
	
	while(Location < ParentChunkEnd)
	{
		ChunkHeaderData ChunkHeader;
		if (!ReadChunkHeader(OFile,ChunkHeader)) return false;
		
		switch(ChunkHeader.ID)
		{
		case EDITOR:
			if (!ReadContainer(OFile,ChunkHeader,ReadEditor)) return false;
			break;
				
		default:
			if (!SkipChunk(OFile,ChunkHeader)) return false;
		}
		
		// Where are we now?
		OFile.GetPosition(Location);
	}
	
	if (Location > ParentChunkEnd)
	{
		if (DBOut)
			fprintf(DBOut,"ERROR: Overran parent chunk: %ld > %ld\n",Location,ParentChunkEnd);
		return false;
	}
	return true;
}
Beispiel #2
0
// For reading the face-data chunk
static bool ReadFaceData(OpenedFile& OFile, int32 ParentChunkEnd)
{
	uint8 NFBuffer[2];
	uint16 NumFaces;
	if (!OFile.Read(2,NFBuffer))
	{
		logError1("ERROR reading number of faces in %s",Path);
		return false;
	}
	uint8 *S = NFBuffer;
	StreamToValue(S,NumFaces);
	
	int32 DataSize = 4*sizeof(uint16)*int(NumFaces);
	SetChunkBufferSize(DataSize);
	if (!OFile.Read(DataSize,ChunkBufferBase()))
	{
		logError1("ERROR reading face-chunk contents in %s",Path);
		return false;
	}
	
	S = ChunkBufferBase();
	ModelPtr->VertIndices.resize(3*NumFaces);
	for (int k=0; k<NumFaces; k++)
	{
		uint16 *CurrPoly = ModelPtr->VIBase() + 3*k;
		uint16 Flags;
		StreamToList(S,CurrPoly,3);
		StreamToValue(S,Flags);
	}
	
	int32 Location = 0;
	OFile.GetPosition(Location);
	
	while(Location < ParentChunkEnd)
	{
		ChunkHeaderData ChunkHeader;
		if (!ReadChunkHeader(OFile,ChunkHeader)) return false;
		
		switch(ChunkHeader.ID)
		{
		/*
		case OBJECT:
			if (!ReadContainer(OFile,ChunkHeader,ReadObject)) return false;
			break;
		*/
		default:
			if (!SkipChunk(OFile,ChunkHeader)) return false;
		}
		
		// Where are we now?
		OFile.GetPosition(Location);
	}
	
	if (Location > ParentChunkEnd)
	{
		logError3("ERROR: Overran parent chunk: %d > %d in %s",Location,ParentChunkEnd,Path);
		return false;
	}
	return true;
}
Beispiel #3
0
// For reading the editor-data chunk
static bool ReadEditor(OpenedFile& OFile, int32 ParentChunkEnd)
{
	int32 Location = 0;
	OFile.GetPosition(Location);
	
	while(Location < ParentChunkEnd)
	{
		ChunkHeaderData ChunkHeader;
		if (!ReadChunkHeader(OFile,ChunkHeader)) return false;
		
		switch(ChunkHeader.ID)
		{
		case OBJECT:
			if (!ReadContainer(OFile,ChunkHeader,ReadObject)) return false;
			break;
			
		default:
			if (!SkipChunk(OFile,ChunkHeader)) return false;
		}
		
		// Where are we now?
		OFile.GetPosition(Location);
	}
	
	if (Location > ParentChunkEnd)
	{
		logError3("ERROR: Overran parent chunk: %d > %d in %s",Location,ParentChunkEnd,Path);
		return false;
	}
	return true;
}
// For reading the object-data chunk
static bool ReadObject(OpenedFile& OFile, int32 ParentChunkEnd)
{
	// Read the name
	if (DBOut) fprintf(DBOut,"Object Name: ");
	while(true)
	{
		char c;
		if (!OFile.Read(1,&c))
		{
			if (DBOut) fprintf(DBOut,"ERROR in reading name");
			return false;
		}
		
		if (c == 0)
		{
			if (DBOut) fprintf(DBOut,"\n");
			break;
		}
		else
		{
			if (DBOut) fprintf(DBOut,"%c",c);
		}
	}
	
	int32 Location = 0;
	OFile.GetPosition(Location);
	
	while(Location < ParentChunkEnd)
	{
		ChunkHeaderData ChunkHeader;
		if (!ReadChunkHeader(OFile,ChunkHeader)) return false;
		
		switch(ChunkHeader.ID)
		{
		case TRIMESH:
			if (!ReadContainer(OFile,ChunkHeader,ReadTrimesh)) return false;
			break;
			
		default:
			if (!SkipChunk(OFile,ChunkHeader)) return false;
		}
		
		// Where are we now?
		OFile.GetPosition(Location);
	}
	
	if (Location > ParentChunkEnd)
	{
		if (DBOut)
			fprintf(DBOut,"ERROR: Overran parent chunk: %ld > %ld\n",Location,ParentChunkEnd);
		return false;
	}
	return true;
}
// For reading the triangle-mesh-data chunk
static bool ReadTrimesh(OpenedFile& OFile, int32 ParentChunkEnd)
{
	int32 Location = 0;
	OFile.GetPosition(Location);
	
	assert(ModelPtr);
	
	while(Location < ParentChunkEnd)
	{
		ChunkHeaderData ChunkHeader;
		if (!ReadChunkHeader(OFile,ChunkHeader)) return false;
		
		switch(ChunkHeader.ID)
		{
		case VERTICES:
			if (!LoadChunk(OFile,ChunkHeader)) return false;
			LoadVertices();
			break;
			
		case TXTR_COORDS:
			if (!LoadChunk(OFile,ChunkHeader)) return false;
			LoadTextureCoordinates();
			break;
			
		case FACE_DATA:
			if (!ReadContainer(OFile,ChunkHeader,ReadFaceData)) return false;
			break;
			
		default:
			if (!SkipChunk(OFile,ChunkHeader)) return false;
		}
		
		// Where are we now?
		OFile.GetPosition(Location);
	}
	
	if (Location > ParentChunkEnd)
	{
		if (DBOut)
			fprintf(DBOut,"ERROR: Overran parent chunk: %ld > %ld\n",Location,ParentChunkEnd);
		return false;
	}
	return true;
}
Beispiel #6
0
// For reading the object-data chunk
static bool ReadObject(OpenedFile& OFile, int32 ParentChunkEnd)
{
	// Read the name
	char c;
	do
	{
		if (!OFile.Read(1,&c))
		{
			logError1("ERROR when reading name in %s",Path);
			return false;
		}
	}
	while(c != 0);
	
	int32 Location = 0;
	OFile.GetPosition(Location);
	
	while(Location < ParentChunkEnd)
	{
		ChunkHeaderData ChunkHeader;
		if (!ReadChunkHeader(OFile,ChunkHeader)) return false;
		
		switch(ChunkHeader.ID)
		{
		case TRIMESH:
			if (!ReadContainer(OFile,ChunkHeader,ReadTrimesh)) return false;
			break;
			
		default:
			if (!SkipChunk(OFile,ChunkHeader)) return false;
		}
		
		// Where are we now?
		OFile.GetPosition(Location);
	}
	
	if (Location > ParentChunkEnd)
	{
		logError3("ERROR: Overran parent chunk: %d > %d in %s",Location,ParentChunkEnd,Path);
		return false;
	}
	return true;
}
Beispiel #7
0
bool SkipChunk(OpenedFile& OFile, ChunkHeaderData& ChunkHeader)
{
	logTrace2("Skipping chunk 0x%04hx size %u",ChunkHeader.ID,ChunkHeader.Size);
	int32 DataSize = ChunkHeader.Size - SIZEOF_ChunkHeaderData;
	
	int32 Location = 0;
	OFile.GetPosition(Location);
	if (!OFile.SetPosition(Location + DataSize)) return false;
	return true;
}
static void import_m1_physics_data()
{
	OpenedFile PhysicsFile;
	if (!PhysicsFileSpec.Open(PhysicsFile)) 
	{
		return;
	}

	int32 position  = 0;
	int32 length;
	PhysicsFile.GetLength(length);

	while (position < length)
	{
		std::vector<uint8> header(12);
		PhysicsFile.Read(header.size(), &header[0]);
		AIStreamBE header_stream(&header[0], header.size());

		uint32 tag;
		uint16 count;
		uint16 size;

		header_stream >> tag;
		header_stream.ignore(4); // unused
		header_stream >> count;
		header_stream >> size;

		std::vector<uint8> data(count * size);
		PhysicsFile.Read(data.size(), &data[0]);
		switch (tag) 
		{
		case M1_MONSTER_PHYSICS_TAG:
			unpack_m1_monster_definition(&data[0], count);
			break;
		case M1_EFFECTS_PHYSICS_TAG:
			unpack_m1_effect_definition(&data[0], count);
			break;
		case M1_PROJECTILE_PHYSICS_TAG:
			unpack_m1_projectile_definition(&data[0], count);
			break;
		case M1_PHYSICS_PHYSICS_TAG:
			unpack_m1_physics_constants(&data[0], count);
			break;
		case M1_WEAPONS_PHYSICS_TAG:
			unpack_m1_weapon_definition(&data[0], count);
			break;
		}

		PhysicsFile.GetPosition(position);
	}
}
Beispiel #9
0
// Generic container-chunk reader
bool ReadContainer(OpenedFile& OFile, ChunkHeaderData& ChunkHeader,
	bool (*ContainerCallback)(OpenedFile&,int32))
{
	logTrace2("Entering chunk 0x%04hx size %u",ChunkHeader.ID,ChunkHeader.Size);
	
	int32 ChunkEnd = 0;
	OFile.GetPosition(ChunkEnd);
	ChunkEnd += ChunkHeader.Size - SIZEOF_ChunkHeaderData;
	
	if (!ContainerCallback(OFile,ChunkEnd)) return false;
	
	logTrace2("Exiting chunk 0x%04hx size %u",ChunkHeader.ID,ChunkHeader.Size);
	return true;
}
Beispiel #10
0
/* This is gross, (Alain wrote it, not me!) but I don't have time to clean it up */
static bool vblFSRead(
	OpenedFile& File,
	int32 *count, 
	void *dest,
	bool& HitEOF)
{
	int32 fsread_count;
	bool status = true;
	
	assert(replay.fsread_buffer);
	
	// LP: way for testing whether hitting end-of-file;
	// doing that by testing for whether a read was complete.
	HitEOF = false;

	if (replay.bytes_in_cache < *count)
	{
		assert(replay.bytes_in_cache + *count < int(DISK_CACHE_SIZE));
		if (replay.bytes_in_cache)
		{
			memcpy(replay.fsread_buffer, replay.location_in_cache, replay.bytes_in_cache);
		}
		replay.location_in_cache = replay.fsread_buffer;
		fsread_count= DISK_CACHE_SIZE - replay.bytes_in_cache;
		int32 PrevPos;
		File.GetPosition(PrevPos);
		int32 replay_left= replay.header.length - PrevPos;
		if(replay_left < fsread_count)
			fsread_count= replay_left;
		if(fsread_count > 0)
		{
			assert(fsread_count > 0);
			// LP: wrapped the routines with some for finding out the file positions;
			// this finds out how much is read indirectly
			status = File.Read(fsread_count,replay.fsread_buffer+replay.bytes_in_cache);
			int32 CurrPos;
			File.GetPosition(CurrPos);
			int32 new_fsread_count = CurrPos - PrevPos;
			int32 FileLen;
			File.GetLength(FileLen);
			HitEOF = (new_fsread_count < fsread_count) && (CurrPos == FileLen);
			fsread_count = new_fsread_count;
			if(status) replay.bytes_in_cache += fsread_count;
		}
	}

	// If we're still low, then we've consumed the disk cache
	if(replay.bytes_in_cache < *count)
	{
		HitEOF = true;
	}

	// Ignore EOF if we still have cache
	if (HitEOF && replay.bytes_in_cache < *count)
	{
		*count= replay.bytes_in_cache;
	}
	else
	{
		status = true;
		HitEOF = false;
	}
	
	memcpy(dest, replay.location_in_cache, *count);
	replay.bytes_in_cache -= *count;
	replay.location_in_cache += *count;
	
	return status;
}