Пример #1
0
uint8			CBMPFormat::detectBMPVersion(void)
{
	CDataReader *pDataReader = CDataReader::getInstance();

	uint8 uiBMPVersion = 0;
	pDataReader->setPeek(true);
	string strHeader = pDataReader->readString(2);
	if (strHeader.c_str()[0] == '\0' && strHeader.c_str()[1] == '\0')
	{
		// BMP version 1.x
		uiBMPVersion = 1;
	}
	else if (strHeader.c_str()[0] == 'B' && strHeader.c_str()[1] == 'M')
	{
		// BMP version 2.x, 3.x or 4.x
		pDataReader->setSeek(12);
		switch (pDataReader->readUint32())
		{
		case 12: // BMP version 2.x
			uiBMPVersion = 2;
			break;
		case 40: // BMP version 3.x
			uiBMPVersion = 3;
			break;
		case 108: // BMP version 4.x
			uiBMPVersion = 4;
		}
	}
	pDataReader->setPeek(false);
	pDataReader->setSeek(0);
	return uiBMPVersion;
}
Пример #2
0
uint32	CCOLEntry::calculateShadowMeshVertexCount(void)
{
	CDataReader *pDataReader = CDataReader::getInstance();
	eCOLVersion eCOLVersionValue = getCOLVersion() == nullptr ? COL_UNKNOWN : getCOLVersion()->getVersionId();

	//CDebugger::log("getHeaderStartOffset(): " + CStringUtility::toString(getHeaderStartOffset()));
	//CDebugger::log("getShadowMeshFacesOffset(): " + CStringUtility::toString(getShadowMeshFacesOffset()));
	//CDebugger::log("getShadowMeshFaceCount(): " + CStringUtility::toString(getShadowMeshFaceCount()));
	//CDebugger::log("getCOLVersion(): " + CStringUtility::toString(getCOLVersion()));
	pDataReader->setSeek(getHeaderStartOffset() + 4 + getShadowMeshFacesOffset());
	string strShadowMeshFacesData = pDataReader->readString(getShadowMeshFaceCount() * (eCOLVersionValue == 1 ? 16 : 8)); // 12 or 6 = sizeof(TVertex)
	//CDebugger::log("part 2 -- strShadowMeshFacesData.length(): " + CStringUtility::toString(strShadowMeshFacesData.length()));
	uint32 uiSeek = 0;
	uint32 uiHighestVertexIndex = 0;
	if (getShadowMeshFaceCount() == 0)
	{
		return 0;
	}
	if (eCOLVersionValue == COL_1)
	{
		// COL 1
		for (uint32 i = 0, j = getShadowMeshFaceCount(); i < j; i++)
		{
			for (uint8 i2 = 0; i2 < 3; i2++)
			{
				uint32 uiVertexIndex = CStringUtility::unpackUint32(strShadowMeshFacesData.substr(uiSeek, 4), false);
				if (uiVertexIndex > uiHighestVertexIndex)
				{
					uiHighestVertexIndex = uiVertexIndex;
				}
				uiSeek += 4; // 4 is sizeof(uint32)
			}
			uiSeek += 4; // 4 is sizeof(TSurface)
		}
	}
	else
	{
		// COL 2, 3 & 4
		for (uint32 i = 0, j = getShadowMeshFaceCount(); i < j; i++)
		{
			for (uint8 i2 = 0; i2 < 3; i2++)
			{
				uint32 uiVertexIndex = CStringUtility::unpackUint16(strShadowMeshFacesData.substr(uiSeek, 2), false);
				if (uiVertexIndex > uiHighestVertexIndex)
				{
					uiHighestVertexIndex = uiVertexIndex;
				}
				uiSeek += 2; // 2 is sizeof(uint16)
			}
			uiSeek += 2; // 1 byte for material, 1 byte for light
		}
	}
	return uiHighestVertexIndex + 1;
}
Пример #3
0
eDATPathFormat			CDATPathFormat::detectPathsFormat(void)
{
	CDataReader *pDataReader = CDataReader::getInstance();
	eDATPathFormat eDATPathFormatValue;

	uint32 uiPreviousSeek = pDataReader->getSeek();
	pDataReader->setPeek(true);

	if (CStringUtility::unpackUint32(pDataReader->readString(4), false) == 0xFFFFFFFF && pDataReader->readString(4) == "FM92")
	{
		eDATPathFormatValue = DAT_PATH_FASTMAN92;
	}
	else
	{
		eDATPathFormatValue = DAT_PATH_DEFAULT;
	}

	pDataReader->setSeek(uiPreviousSeek);
	pDataReader->setPeek(false);

	return eDATPathFormatValue;
}
Пример #4
0
void			CCOLEntry::unserialize(void)
{
	CDataReader *pDataReader = CDataReader::getInstance();

	uint32 uiHeaderStartPosition = pDataReader->getSeek();
	setHeaderStartOffset(uiHeaderStartPosition);

	// COL 1 2 3 & 4 header
	setCOLVersion(CCOLManager::getCOLVersionFromFourCC(pDataReader->readString(4)));
	if (getCOLVersion() == nullptr)
	{
		throw EXCEPTION_UNKNOWN_FORMAT;
	}
	uint32 uiEntrySize = pDataReader->readUint32(); // entry size from after this value
	setModelName(CStringUtility::rtrimFromLeft(pDataReader->readString(22)));
	setModelId(pDataReader->readUint16());
	parseBoundingObjects();

	eCOLVersion eCOLVersionValue = getCOLVersion() == nullptr ? COL_UNKNOWN : getCOLVersion()->getVersionId();
	if (eCOLVersionValue == COL_1)
	{
		// COL 1 header & body

		// read collision sphere count
		setCollisionSphereCount(pDataReader->readUint32());

		// read collision spheres array
		setCollisionSpheresOffset(pDataReader->getSeek());
		parseCollisionSpheres();

		// read unknown1 count
		setUnknown1(pDataReader->readUint32()); // number of unknown data (0)

		// read collision box count
		setCollisionBoxCount(pDataReader->readUint32());

		// read collision boxes array
		setCollisionBoxesOffset(pDataReader->getSeek());
		parseCollisionBoxes();

		// read collision mesh vertex count
		setCollisionMeshVertexCount(pDataReader->readUint32());

		// read collision mesh vertices array
		setCollisionMeshVerticesOffset(pDataReader->getSeek());
		parseCollisionMeshVertices();

		// read collision mesh face count
		setCollisionMeshFaceCount(pDataReader->readUint32());

		// read collision mesh faces array
		setCollisionMeshFacesOffset(pDataReader->getSeek());
		parseCollisionMeshFaces();
	}
	else
	{
		// COL 2 3 & 4 header
		setCollisionSphereCount(pDataReader->readUint16());
		setCollisionBoxCount(pDataReader->readUint16());
		setCollisionMeshFaceCount(pDataReader->readUint16());
		setCollisionConeCount(pDataReader->readUint8());
		uint8 ucPadding1 = pDataReader->readUint8(); // 1 byte padding
		setFlags(pDataReader->readUint32());
		setCollisionSpheresOffset(pDataReader->readUint32());
		setCollisionBoxesOffset(pDataReader->readUint32());
		setCollisionConesOffset(pDataReader->readUint32());
		setCollisionMeshVerticesOffset(pDataReader->readUint32());
		setCollisionMeshFacesOffset(pDataReader->readUint32());
		setTrianglePlanesOffset(pDataReader->readUint32());

		if ((getFlags() & 8) != 0)
		{
			// entry does have face groups
			uint32 uiCurrentSeek = pDataReader->getSeek();

			// read face group count
			uint32 uiFaceGroupCountSeek = (getHeaderStartOffset() + 4 + getCollisionMeshFacesOffset()) - 4;
			pDataReader->setSeek(uiFaceGroupCountSeek);
			setCollisionMeshFaceGroupCount(pDataReader->readUint32());

			// read face groups offset
			setCollisionMeshFaceGroupsOffset((getCollisionMeshFacesOffset() - 4) - (28 * getCollisionMeshFaceGroupCount())); // 28 = sizeof(TFaceGroup)

			// restore parser seek position
			pDataReader->setSeek(uiCurrentSeek);
		}
		else
		{
			// entry does not have face groups
			setCollisionMeshFaceGroupCount(0);
			setCollisionMeshFaceGroupsOffset(0);
		}

		if (eCOLVersionValue == COL_3 || eCOLVersionValue == COL_4)
		{
			// COL 3 & 4 header
			setShadowMeshFaceCount(pDataReader->readUint32());
			setShadowMeshVerticesOffset(pDataReader->readUint32());
			setShadowMeshFacesOffset(pDataReader->readUint32());

			if (eCOLVersionValue == COL_4)
			{
				// COL 4 header
				setUnknown1(pDataReader->readUint32());
			}
		}

		// calculate vertex counts

		// COL 2 3 & 4
		uint32 uiCollisionMeshVertexCount = calculateCollisionMeshVertexCount();
		setCollisionMeshVertexCount(uiCollisionMeshVertexCount);

		if (eCOLVersionValue == COL_3 || eCOLVersionValue == COL_4)
		{
			// COL 3 & 4
			uint32 uiShadowMeshVertexCount = calculateShadowMeshVertexCount();
			setShadowMeshVertexCount(uiShadowMeshVertexCount);
		}

		// COL 2 3 & 4 body
		pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionSpheresOffset());
		parseCollisionSpheres();

		pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionBoxesOffset());
		parseCollisionBoxes();

		pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionMeshVerticesOffset());
		parseCollisionMeshVertices();

		pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionMeshFaceGroupsOffset());
		parseCollisionMeshFaceGroups();

		pDataReader->setSeek(getHeaderStartOffset() + 4 + getCollisionMeshFacesOffset());
		parseCollisionMeshFaces();

		if (eCOLVersionValue == COL_3 || eCOLVersionValue == COL_4)
		{
			// COL 3 & 4 body
			pDataReader->setSeek(getHeaderStartOffset() + 4 + getShadowMeshVerticesOffset());
			parseShadowMeshVertices();

			pDataReader->setSeek(getHeaderStartOffset() + 4 + getShadowMeshFacesOffset());
			parseShadowMeshFaces();
		}
	}

	if (!pDataReader->canSeekTo(getHeaderStartOffset() + uiEntrySize + 8))
	{
		// EOF
		return;
	}
	pDataReader->setSeek(getHeaderStartOffset() + uiEntrySize + 8);
}