Пример #1
0
void readStringtable(int pos, FILE* f, std::vector<std::string>& dest)
{
  long oldPos = ftell(f);

  fseek(f, pos, SEEK_SET);

  u16 count; fread(&count, 2, 1, f); toWORD(count);
  fseek(f, 2, SEEK_CUR); //skip pad bytes

  for(int i = 0; i < count; ++i)
  {
    u16 unknown, stringOffset;
    fread(&unknown, 2, 1, f); toWORD(unknown);
    fread(&stringOffset, 2, 1, f); toWORD(stringOffset);
    std::string s = getString(pos + stringOffset, f);
    dest.push_back(s);
  }

  fseek(f, oldPos, SEEK_SET);
}
Пример #2
0
void writeStringtable(std::ostream& out, FILE* f, int offset)
{
  int p = ftell(f);

  fseek(f, offset, SEEK_SET);

  u16 count; fread(&count, 2, 1, f); toWORD(count);
  fseek(f, 2, SEEK_CUR); //skip pad bytes

  out << "String table (" << count << " entries)" << std::endl;
  for(int i = 0; i < count; ++i)
  {
    u16 unknown, stringOffset;
    fread(&unknown, 2, 1, f); toWORD(unknown);
    fread(&stringOffset, 2, 1, f); toWORD(stringOffset);
    std::string s = getString(offset + stringOffset,
                              f);
    out << "  0x" << std::hex << unknown << " - " << s << std::endl;
  }

  fseek(f, p, SEEK_SET);
}
Пример #3
0
void clsMaterialHeader::ReadMaterialSegment(int index){
	u32 ReadBytes=0;
	u32 i=0;

	unsigned char* pnt=&MaterialSegments[index].front();
	mGroup* ThisSegment=&MaterialSegment[index];
	memcpy(&ThisSegment->groupheader,&pnt[ReadBytes],4);
	toDWORD((u32&)ThisSegment->groupheader);
	ReadBytes+=4;
	ReadBytes+=ReadTextureInfo(&ThisSegment->info,&pnt[ReadBytes]);
	if(fVersion==MP1){	
		memcpy(&ThisSegment->unknown0,&pnt[ReadBytes],4);
		toDWORD((u32&)ThisSegment->unknown0);
		ReadBytes+=4;
		memcpy(&ThisSegment->unknown1,&pnt[ReadBytes],4);
		toDWORD((u32&)ThisSegment->unknown1);
		ReadBytes+=4;
		/*								if ((unknown0x00 & 0xF) == 0xB)
		{

		}  leaving this segment from the bt out and just adding the sizes together to the current function
		you can implement if you want
		*/

		if ((ThisSegment->groupheader & 0x4000) != 0x0000)
			{
			
				memcpy(&ThisSegment->unknown0a[0],&pnt[ReadBytes],4);
		        toDWORD((u32&)ThisSegment->unknown1);
				ReadBytes+=4;
				memcpy(&ThisSegment->unknown0a[1],&pnt[ReadBytes],4);
		       toDWORD((u32&)ThisSegment->unknown1);
				ReadBytes+=4;
			}
		if ((ThisSegment->groupheader & 0xD00) == 0xD00)
			{
			
				memcpy(&ThisSegment->unknown1a,&pnt[ReadBytes],4);
		        toDWORD((u32&)ThisSegment->unknown1);
				ReadBytes+=4;
			}
								// unsure, this is just a hack for now
								// need to determine if this is present under any other circumstances

		if ((ThisSegment->groupheader & 0x08) != 0x00){

			memcpy(&ThisSegment->unknownCount0,&pnt[ReadBytes],4);
			toDWORD((u32&)ThisSegment->unknownCount0);
			ThisSegment->unknownData0.resize(ThisSegment->unknownCount0);
			ReadBytes+=4;
			for(i=0;i<ThisSegment->unknownCount0;i++){
				memcpy(&ThisSegment->unknownData0[i],&pnt[ReadBytes],4);
				toDWORD((u32&)ThisSegment->unknownData0[i]);
				ReadBytes+=4;
			}
		}
		for(i=0;i<3;i++){
			memcpy(&ThisSegment->unknown2[i],&pnt[ReadBytes],4);
			toDWORD((u32&)ThisSegment->unknown2[i]);
			ReadBytes+=4;

		}
		//Read Attribute info
		memcpy(&ThisSegment->AttribCount,&pnt[ReadBytes],4);
		toDWORD((u32&)ThisSegment->AttribCount);
		ReadBytes+=4;
		ThisSegment->Attributes.resize(ThisSegment->AttribCount);
		if(ThisSegment->AttribCount<10)ThisSegment->unknown4.resize(ThisSegment->AttribCount);
		for(i=0;i<ThisSegment->AttribCount;i++){
			memcpy(&ThisSegment->Attributes[i],&pnt[ReadBytes],20);//Struct size is 20 bytes
			//u8  Unknown0;
			//u8  Blend;
			//u8  Unknown1;
			//u8  Unknown2;
			toWORD((u16&)ThisSegment->Attributes[i].BlendNumber);
			toWORD((u16&)ThisSegment->Attributes[i].BlendType);
			ReadBytes+=20;


		}
		for(i=0;i<ThisSegment->AttribCount;i++){
			memcpy(&ThisSegment->unknown4[i],&pnt[ReadBytes],4);
			ReadBytes+=4;

		}
		memcpy(&ThisSegment->LayerInfo,&pnt[ReadBytes],4);
		ReadBytes+=4;
		toDWORD((u32&)ThisSegment->LayerInfo);
		ThisSegment->LayerData.resize(ThisSegment->LayerInfo);
		for(i=0;i<ThisSegment->LayerInfo;i++){
			memcpy(&ThisSegment->LayerData[i],&pnt[ReadBytes],4);
			toDWORD((u32&)ThisSegment->LayerData[i]);
			ReadBytes+=4;


		}
		memcpy(&ThisSegment->unknownsize,&pnt[ReadBytes],4);
		toDWORD((u32&)ThisSegment->unknownsize);
		ReadBytes+=4;
		memcpy(&ThisSegment->unknown5,&pnt[ReadBytes],4);
		toDWORD((u32&)ThisSegment->unknown5);
		ReadBytes+=4;
		memcpy(&ThisSegment->unknown6,&pnt[ReadBytes],4);
		toDWORD((u32&)ThisSegment->unknown6);

	}
	return;
}
Пример #4
0
int MREAData::ReadSubMesh(FILE* fp, MeshData & meshData)
{
	unsigned int maxVert = 0;
	unsigned int maxNorm = 0;
	unsigned int maxUV = 0;


	int startPos = ftell(fp);
	long GroupId = 0;
	fseek(fp,startPos + 0xC,SEEK_SET);
	fread(&GroupId,1,4,fp);
	toDWORD((u32&)GroupId);
	int dataFormat = 0;// MaterialHeader[0].MaterialSegment[GroupId].info.count-1;
	fseek(fp,startPos + 0x12,SEEK_SET);

	u16 dataSize = 0;
	fread(&dataSize,sizeof(u16),1,fp);
	toWORD((u16&)dataSize);

	fseek(fp,startPos + 0x60,SEEK_SET);

	meshData.subMeshes.push_back(struct_Mesh());

	struct_Mesh & mesh = meshData.subMeshes.back();
	mesh.GroupId = GroupId;
	mesh.format = 0;

	u32 const vertexcount = (u32)meshData.vertices.size();
	u32 const normalcount = (u32)meshData.normals.size();

	uint32 readBytes = 0;
	while (readBytes < dataSize)
	{
		mesh.subMeshes.push_back(struct_SubMesh());

		struct_SubMesh & submesh = mesh.subMeshes.back();

		fread(&(submesh.primitiveFlags), sizeof(unsigned char), 1, fp);
		readBytes += sizeof(unsigned char);

		submesh.indexCount = 0;

		if (submesh.primitiveFlags == 0 ||
			submesh.primitiveFlags < 0x80 ||
			submesh.primitiveFlags > 0xBF ||
			(readBytes + 2) >= dataSize)
		{
			submesh.primitiveFlags = 0;
			break;
		}

		fread(&(submesh.indexCount), sizeof(unsigned short), 1, fp);
		readBytes += sizeof(unsigned short);
		toWORD((u16&)submesh.indexCount);

		if (submesh.indexCount <= 0 ||
			readBytes >= dataSize)
		{
			submesh.primitiveFlags = 0;
			break;
		}

		submesh.indices.resize(submesh.indexCount);

		struct_Faces * pFaces = &submesh.indices.front();

		uint32 startReadBytes = readBytes;
		int currentPos = ftell(fp);

		bool bValid = false; //((0 == dataFormat) || (3 == dataFormat));

		int i=0;
		while (!bValid && (struct_Faces::MAX_UV_INDICES >= dataFormat))
		{
			fseek(fp, currentPos, SEEK_SET);
			readBytes = startReadBytes;

			bValid = true;

			for (i=0; (readBytes < dataSize) && (i < submesh.indexCount); i++)
			{
				fread(&(pFaces[i].vertexIndex), sizeof(unsigned short), 1, fp);
				readBytes += sizeof(unsigned short);
				fread(&(pFaces[i].normalIndex), sizeof(unsigned short), 1, fp);
				readBytes += sizeof(unsigned short);

				toWORD((u16&)pFaces[i].vertexIndex);
				toWORD((u16&)pFaces[i].normalIndex);

				if (maxVert < pFaces[i].vertexIndex)
				{
					maxVert = pFaces[i].vertexIndex;
				}
				if (maxNorm < pFaces[i].normalIndex)
				{
					maxNorm = pFaces[i].normalIndex;
				}

				for (int iUV = 0; iUV < dataFormat; ++iUV)
				{
					fread(&(pFaces[i].uvIndex[iUV]), sizeof(unsigned short), 1, fp);
					readBytes += sizeof(unsigned short);

					toWORD((u16&)pFaces[i].uvIndex[iUV]);

					if (maxUV < pFaces[i].uvIndex[iUV])
					{
						maxUV = pFaces[i].uvIndex[iUV];
					}
				}

				if (pFaces[i].vertexIndex >= vertexcount ||
					pFaces[i].normalIndex >= normalcount ||
					readBytes > dataSize
					)
				{
					bValid = false;
					break;
				}
			}

			if (bValid)
			{
				unsigned char peekByte = 0;
				unsigned short peekShort = 0;
				fread(&(peekByte), sizeof(unsigned char), 1, fp);
				fread(&(peekShort), sizeof(unsigned short), 1, fp);
				fseek(fp, ftell(fp) - 3, SEEK_SET);

				if (((readBytes + 3) < dataSize && ((peekByte == 0 && peekShort != 0) ||
					(peekByte != 0 && (peekByte < 0x80 ||
					peekByte > 0xBF || peekShort == 0)))) ||
					(readBytes < (dataSize - 32) && peekByte == 0 && peekShort == 0))
				{
					bValid = false;
				}
			}

			if (!bValid)
			{
				++dataFormat;
				maxVert = 0;
				maxNorm = 0;
				maxUV = 0;
			}
		}

		if (!bValid)
		{
			dataFormat = 0;
			readBytes = dataSize;
			submesh.primitiveFlags = 0;
			submesh.indexCount = 0;
			break;
		}

		mesh.format = (dataFormat & 0x7FFF);
	}

	fseek(fp, startPos + dataSize, SEEK_SET);

	char buff[256] = {0};
	sprintf(buff, "Max Vertex Index: %4d - Max Normal Index: %4d - Max UV Index: %4d\n", maxVert, maxNorm, maxUV);
	OutputDebugStr(buff);

	return 0;
}
Пример #5
0
int MREAData::ReadMesh(FILE* fp, int index, int segmentNum)
{
	MeshData & mesh = m_meshes[index];

	mesh.glList = 0;

	u32 nextOffset = ftell(fp) + m_sectionSizes[segmentNum];

	fread(&mesh.header.unknown0x00, 4, 1, fp);
	toDWORD(mesh.header.unknown0x00);

	fread(mesh.header.transformMatrix, 4, 12, fp);
	for (u32 i = 0; i < 12; ++i)
	{
		toDWORD((u32&)mesh.header.transformMatrix[i]);
	}

	fread(mesh.header.boundingBox, 4, 6, fp);
	for (u32 i = 0; i < 6; ++i)
	{
		toDWORD((u32&)mesh.header.boundingBox[i]);
	}

	if (0 == index)
	{
		// minimum
		if (mesh.header.boundingBox[0] < minBounds.X)
		{
			minBounds.X = mesh.header.boundingBox[0];
		}
		if (mesh.header.boundingBox[1] < minBounds.Y)
		{
			minBounds.Y = mesh.header.boundingBox[1];
		}
		if (mesh.header.boundingBox[2] < minBounds.Z)
		{
			minBounds.Z = mesh.header.boundingBox[2];
		}

		// maximum bounds
		if (mesh.header.boundingBox[3] > maxBounds.X)
		{
			maxBounds.X = mesh.header.boundingBox[3];
		}
		if (mesh.header.boundingBox[4] > maxBounds.Y)
		{
			maxBounds.Y = mesh.header.boundingBox[4];
		}
		if (mesh.header.boundingBox[5] > maxBounds.Z)
		{
			maxBounds.Z = mesh.header.boundingBox[5];
		}
	}

	// move to next section data
	fseek(fp, nextOffset, SEEK_SET);
	++segmentNum;
	nextOffset += m_sectionSizes[segmentNum];

	u32 dataCount = m_sectionSizes[segmentNum] / 0x0C;
	u32 dataNum = 0;

	mesh.vertices.resize(dataCount);
	for(dataNum=0; dataNum<dataCount; ++dataNum)
	{
		fread(&mesh.vertices[dataNum].X, sizeof(float), 1, fp);
		fread(&mesh.vertices[dataNum].Y, sizeof(float), 1, fp);
		fread(&mesh.vertices[dataNum].Z, sizeof(float), 1, fp);
		toDWORD((u32&)mesh.vertices[dataNum].X);
		toDWORD((u32&)mesh.vertices[dataNum].Y);
		toDWORD((u32&)mesh.vertices[dataNum].Z);

		const tex vert = mesh.vertices[dataNum];
		if (0) // == index)
		{
			// minimum bounds
			if (vert.X < minBounds.X)
			{
				minBounds.X = vert.X;
			}
			if (vert.Y < minBounds.Y)
			{
				minBounds.Y = vert.Y;
			}
			if (vert.Z < minBounds.Z)
			{
				minBounds.Z = vert.Z;
			}

			// maximum bounds
			if (vert.X > maxBounds.X)
			{
				maxBounds.X = vert.X;
			}
			if (vert.Y > maxBounds.Y)
			{
				maxBounds.Y = vert.Y;
			}
			if (vert.Z > maxBounds.Z)
			{
				maxBounds.Z = vert.Z;
			}
		}
	}

	// move to next section data
	fseek(fp, nextOffset, SEEK_SET);
	++segmentNum;
	nextOffset += m_sectionSizes[segmentNum];

	signed short x, y, z;
	dataCount = m_sectionSizes[segmentNum] / 0x06;
	mesh.normals.resize(dataCount);
	for(dataNum=0; dataNum<dataCount; ++dataNum)
	{
		fread(&x,sizeof(signed short),1,fp);
		fread(&y,sizeof(signed short),1,fp);
		fread(&z,sizeof(signed short),1,fp);
		toWORD((u16&)x);
		toWORD((u16&)y);
		toWORD((u16&)z);

		mesh.normals[dataNum].X = float(x) / 16834.0f;
		mesh.normals[dataNum].Y = float(y) / 16834.0f;
		mesh.normals[dataNum].Z = float(z) / 16834.0f;
	}

	// move to next section data
	fseek(fp, nextOffset, SEEK_SET);
	++segmentNum;
	nextOffset += m_sectionSizes[segmentNum];

	// read zero data

	// move to next section data
	fseek(fp, nextOffset, SEEK_SET);
	++segmentNum;
	nextOffset += m_sectionSizes[segmentNum];

	// read texture coordinate data
	dataCount = m_sectionSizes[segmentNum] / 0x08;
	mesh.uvs.resize(dataCount);
	for(dataNum=0; dataNum<dataCount; ++dataNum)
	{
		fread(&mesh.uvs[dataNum].U, sizeof(float), 1, fp);
		fread(&mesh.uvs[dataNum].V, sizeof(float), 1, fp);
		toDWORD((u32&)mesh.uvs[dataNum].U);
		toDWORD((u32&)mesh.uvs[dataNum].V);
	}

	// move to next section data
	fseek(fp, nextOffset, SEEK_SET);
	++segmentNum;
	nextOffset += m_sectionSizes[segmentNum];

	// read unknown data

	// move to next section data
	fseek(fp, nextOffset, SEEK_SET);
	++segmentNum;
	nextOffset += m_sectionSizes[segmentNum];

	// read sub mesh info data
	fread(&mesh.subMeshInfo.subMeshCount, 4, 1, fp);
	toDWORD(mesh.subMeshInfo.subMeshCount);

	mesh.subMeshInfo.subMeshOffsets.resize(mesh.subMeshInfo.subMeshCount);
	fread(&mesh.subMeshInfo.subMeshOffsets.front(), 4, mesh.subMeshInfo.subMeshCount, fp);
	for (u32 i = 0; i < mesh.subMeshInfo.subMeshCount; ++i)
	{
		toDWORD(mesh.subMeshInfo.subMeshOffsets[i]);
	}

	// move to next section data
	fseek(fp, nextOffset, SEEK_SET);
	++segmentNum;
	nextOffset += m_sectionSizes[segmentNum];

	// read sub mesh data
	for (u32 i = 0; i < mesh.subMeshInfo.subMeshCount; ++i)
	{
		ReadSubMesh(fp, mesh);

		// move to next section data
		fseek(fp, nextOffset, SEEK_SET);
		++segmentNum;
		nextOffset += m_sectionSizes[segmentNum];
	}

	return segmentNum;
}