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; }
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); }
void CRWSectionContainer::unserialize(void) { CDataReader *pDataReader = CDataReader::getInstance(); CRWSectionContainer *pParentRWSectionContainer = this; uint32 uiSectionDepth = 0; vector<uint32> vecSectionSizes, vecByteCountsRead; while (!pDataReader->isEOF()) { if (!pDataReader->canRead(12)) { break; } // read section header uint32 uiRWSectionId = pDataReader->readUint32(), uiRWSectionSize = pDataReader->readUint32(), uiRWSectionRWVersion = pDataReader->readUint32(); eRWSection eRWSectionValue = (eRWSection)uiRWSectionId; // enter new section if (uiRWSectionId != 1) { vecSectionSizes.push_back(uiRWSectionSize); vecByteCountsRead.push_back(0); uiSectionDepth++; } // read struct header if (CRWSection::doesRWSectionContainStruct(eRWSectionValue)) { uint32 uiRWSectionId2 = pDataReader->readUint32(), uiRWSectionSize2 = pDataReader->readUint32(), uiRWSectionRWVersion2 = pDataReader->readUint32(); } // create RW section CRWSection *pRWSection = CRWSection::createRWSection(eRWSectionValue); // unserialize RW section uint32 uiByteCountBefore = pDataReader->getSeek(); pRWSection->unserialize(); uint32 uiByteCountAfter = pDataReader->getSeek(); vecByteCountsRead[uiSectionDepth - 1] += uiByteCountAfter - uiByteCountBefore; // store RW section pParentRWSectionContainer->addEntry(pRWSection); // reset section depth if (vecByteCountsRead[uiSectionDepth - 1] >= vecSectionSizes[uiSectionDepth - 1]) { pParentRWSectionContainer = pParentRWSectionContainer->getParentNode(); vecSectionSizes.pop_back(); vecByteCountsRead[uiSectionDepth - 2] += vecByteCountsRead[uiSectionDepth - 1]; vecByteCountsRead.pop_back(); uiSectionDepth--; } } }