diff --git a/libs/zonefile/360/zonefile_cod10_360.cpp b/libs/zonefile/360/zonefile_cod10_360.cpp index 38c3295..aa722a2 100644 --- a/libs/zonefile/360/zonefile_cod10_360.cpp +++ b/libs/zonefile/360/zonefile_cod10_360.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD10_360::pParseZoneTags(QDataStream *aZoneFileStream, qui zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/360/zonefile_cod11_360.cpp b/libs/zonefile/360/zonefile_cod11_360.cpp index ac65795..7b00a7b 100644 --- a/libs/zonefile/360/zonefile_cod11_360.cpp +++ b/libs/zonefile/360/zonefile_cod11_360.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD11_360::pParseZoneTags(QDataStream *aZoneFileStream, qui zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/360/zonefile_cod12_360.cpp b/libs/zonefile/360/zonefile_cod12_360.cpp index bfe764c..e82d6ef 100644 --- a/libs/zonefile/360/zonefile_cod12_360.cpp +++ b/libs/zonefile/360/zonefile_cod12_360.cpp @@ -161,7 +161,7 @@ QStringList ZoneFile_COD12_360::pParseZoneTags(QDataStream *aZoneFileStream, qui zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/360/zonefile_cod2_360.cpp b/libs/zonefile/360/zonefile_cod2_360.cpp index aff7269..6a3f758 100644 --- a/libs/zonefile/360/zonefile_cod2_360.cpp +++ b/libs/zonefile/360/zonefile_cod2_360.cpp @@ -6,35 +6,44 @@ ZoneFile_COD2_360::ZoneFile_COD2_360() { - + } ZoneFile_COD2_360::~ZoneFile_COD2_360() { - + } bool ZoneFile_COD2_360::Load(const QByteArray aFileData) { // Open zone file as little endian stream QDataStream zoneFileStream(aFileData); zoneFileStream.setByteOrder(QDataStream::BigEndian); - + // Parse data from zone file header pParseZoneHeader(&zoneFileStream); + + zoneFileStream.skipRawData(4 * GetMiscCount()); + pParseMiscTags(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); - + return true; } void ZoneFile_COD2_360::pParseZoneHeader(QDataStream *aZoneFileStream) { SetTagCount(pParseZoneTagCount(aZoneFileStream)); - pParseZoneUnknownsB(aZoneFileStream); - pParseZoneUnknownsC(aZoneFileStream); - SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); - + aZoneFileStream->skipRawData(4); - + + SetMiscCount(pParseZoneTagCount(aZoneFileStream)); + + aZoneFileStream->skipRawData(4); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + aZoneFileStream->skipRawData(4); + quint32 tagCount = GetTagCount(); if (tagCount) { SetTags(pParseZoneTags(aZoneFileStream, tagCount)); @@ -63,28 +72,28 @@ void ZoneFile_COD2_360::pParseZoneUnknownsA(QDataStream *aZoneFileStream) { // Byte 4-7, 8-11, 12-15: unknown QByteArray unknown1(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown1.data(), 4); - + QByteArray unknown2(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown2.data(), 4); - + QByteArray unknown3(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown3.data(), 4); - + // Byte 16-19, 20-23: empty/unknown QByteArray unknown4(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown4.data(), 4); - + QByteArray unknown5(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown5.data(), 4); - + // Byte 24-27: somehow related to the filesize, but smaller value QByteArray unknown6(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown6.data(), 4); - + // Byte 28-31, 32-35: unknown QByteArray unknown7(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown7.data(), 4); - + QByteArray unknown8(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown8.data(), 4); } @@ -131,7 +140,7 @@ void ZoneFile_COD2_360::pParseZoneUnknownsC(QDataStream *aZoneFileStream) { // Byte 40-43: Unknown/empty? QByteArray unknown10(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown10.data(), 4); - + // Byte 44-47: Unknown/empty? QByteArray unknown11(4, Qt::Uninitialized); aZoneFileStream->readRawData(unknown11.data(), 4); @@ -144,10 +153,10 @@ void ZoneFile_COD2_360::pParseZoneUnknownsC(QDataStream *aZoneFileStream) { */ QStringList ZoneFile_COD2_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { QStringList tags; - + // Byte 48-51: Repeated separators? ÿÿÿÿ x i aZoneFileStream->skipRawData(4 * tagCount); - + // Parse tags/strings before index QString zoneTag; char zoneTagChar; @@ -157,7 +166,25 @@ QStringList ZoneFile_COD2_360::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } + zoneTag.clear(); + } + return tags; +} + +QStringList ZoneFile_COD2_360::pParseMiscTags(QDataStream *aZoneFileStream) { + QStringList tags; + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + while (aZoneFileStream->device()->peek(8).right(4).toHex() != "ffffffff") { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; @@ -170,17 +197,17 @@ QStringList ZoneFile_COD2_360::pParseZoneTags(QDataStream *aZoneFileStream, quin */ QStringList ZoneFile_COD2_360::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { QStringList result; - + // Don't parse if no records if (!recordCount) { return result; } - + // Parse index & map found asset types for (quint32 i = 0; i < recordCount; i++) { // Skip record start QByteArray rawAssetType(4, Qt::Uninitialized); aZoneFileStream->readRawData(rawAssetType.data(), 4); result << rawAssetType.toHex(); - + // Skip separator aZoneFileStream->skipRawData(4); } @@ -189,13 +216,13 @@ QStringList ZoneFile_COD2_360::pParseZoneIndex(QDataStream *aZoneFileStream, qui AssetMap ZoneFile_COD2_360::pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) { AssetMap result; - + //aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 8); - + for (int i = 0; i < assetOrder.size(); i++) { const QString typeHex = assetOrder[i]; const AssetType assetType = AssetStrToEnum(typeHex); - + if (assetType == ASSET_LOCAL_STRING) { // localized string asset result.localStrings << pParseAsset_LocalString(aZoneFileStream); } else if (assetType == ASSET_RAW_FILE) { // gsc @@ -250,7 +277,7 @@ AssetMap ZoneFile_COD2_360::pParseAssets(QDataStream *aZoneFileStream, QStringLi LocalString ZoneFile_COD2_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { LocalString result; - + quint32 stringPtr, aliasPtr; *aZoneFileStream >> stringPtr >> aliasPtr; if (stringPtr == 4294967295) { @@ -265,7 +292,7 @@ LocalString ZoneFile_COD2_360::pParseAsset_LocalString(QDataStream *aZoneFileStr } else { result.string = "String Ptr: " + QString::number(stringPtr); } - + if (aliasPtr == 4294967295) { // Parse rawfile name QString aliasName; @@ -278,41 +305,51 @@ LocalString ZoneFile_COD2_360::pParseAsset_LocalString(QDataStream *aZoneFileStr } else { result.string = "Alias Ptr: " + QString::number(aliasPtr); } - + return result; } RawFile ZoneFile_COD2_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { RawFile result; - - // Skip start separator FF FF FF FF (pointer?) - aZoneFileStream->skipRawData(4); - + + qint32 rawFilePtr; + *aZoneFileStream >> rawFilePtr; + *aZoneFileStream >> result.length; - + // Skip unknown 4 byte data aZoneFileStream->skipRawData(4); - + // Parse rawfile path - char scriptPathChar; - *aZoneFileStream >> scriptPathChar; - while (scriptPathChar != 0) { - result.path += scriptPathChar; + const QStringList tags = GetTags(); + if (rawFilePtr == -1) { + char scriptPathChar; *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + } else if (rawFilePtr > 0 && rawFilePtr < tags.size() + 2) { + result.path = tags[rawFilePtr - 1]; } - result.path.replace(",", ""); + const QStringList pathParts = result.path.split('/'); if (pathParts.size() == 0) { qDebug() << "Failed to parse ff path! " << result.path; exit(-1); } - + // Parse gsc contents - char rawFileContentsChar; - *aZoneFileStream >> rawFileContentsChar; - while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { - result.contents += rawFileContentsChar; + if (result.length) { + char rawFileContentsChar; *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } else { + aZoneFileStream->skipRawData(1); } return result; } @@ -323,48 +360,48 @@ void ZoneFile_COD2_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { Model ZoneFile_COD2_360::pParseAsset_Model(QDataStream *aZoneFileStream) { Model result; - + *aZoneFileStream >> result.namePtr >> result.tagCount >> result.rootTagCount - >> result.surfCount >> result.unknownCount >> result.boneNamePtr - >> result.parentListPtr >> result.quatsPtr >> result.transPtr - >> result.partClassPtr >> result.baseMatPtr - >> result.surfsPtr >> result.materialHandlesPtr; - + >> result.surfCount >> result.unknownCount >> result.boneNamePtr + >> result.parentListPtr >> result.quatsPtr >> result.transPtr + >> result.partClassPtr >> result.baseMatPtr + >> result.surfsPtr >> result.materialHandlesPtr; + // Parse XModelLodInfo for (int i = 1; i <= 4; i++) { quint32 intDist; *aZoneFileStream >> intDist; - + std::memcpy(&result.lodInfo[i].dist, &intDist, sizeof(result.lodInfo[i].dist)); *aZoneFileStream >> result.lodInfo[i].numsurfs >> result.lodInfo[i].surfIndex; - + aZoneFileStream->skipRawData(4); - + *aZoneFileStream >> result.lodInfo[i].partBits[0] - >> result.lodInfo[i].partBits[1] - >> result.lodInfo[i].partBits[2] - >> result.lodInfo[i].partBits[3]; + >> result.lodInfo[i].partBits[1] + >> result.lodInfo[i].partBits[2] + >> result.lodInfo[i].partBits[3]; } - + *aZoneFileStream >> result.collSurfsPtr >> result.numCollSurfs >> result.contents >> result.boneInfoPtr; - + quint32 intRadius, intMins[3], intMaxs[3]; *aZoneFileStream >> intRadius >> intMins[0] >> intMins[1] - >> intMins[2] >> intMaxs[0] >> intMaxs[1] >> intMaxs[2]; - + >> intMins[2] >> intMaxs[0] >> intMaxs[1] >> intMaxs[2]; + std::memcpy(&result.radius, &intRadius, sizeof(result.radius)); - + std::memcpy(&result.mins[0], &intMins[0], sizeof(result.mins[0])); std::memcpy(&result.mins[1], &intMins[1], sizeof(result.mins[1])); std::memcpy(&result.mins[2], &intMins[2], sizeof(result.mins[2])); - + std::memcpy(&result.maxs[0], &intMaxs[0], sizeof(result.maxs[0])); std::memcpy(&result.maxs[1], &intMaxs[1], sizeof(result.maxs[2])); std::memcpy(&result.maxs[2], &intMaxs[2], sizeof(result.maxs[3])); - + *aZoneFileStream >> result.numLods >> result.collLod >> result.streamInfoPtr - >> result.memUsage >> result.flags >> result.physPresetPtr >> result.physGeomsPtr; - + >> result.memUsage >> result.flags >> result.physPresetPtr >> result.physGeomsPtr; + // Parse model name char modelNameChar; *aZoneFileStream >> modelNameChar; @@ -380,16 +417,16 @@ Model ZoneFile_COD2_360::pParseAsset_Model(QDataStream *aZoneFileStream) { Shader ZoneFile_COD2_360::pParseAsset_Shader(QDataStream *aZoneFileStream) { Shader result = Shader(); - + quint8 minorVersion, majorVersion; *aZoneFileStream >> minorVersion >> majorVersion; - + quint32 magic; *aZoneFileStream >> magic; - + // Verify .fxc magic if (magic != 65534 && magic != 65535) { return result; } - + SHADER_TYPE type = SHADER_NONE; quint16 rawShaderType; *aZoneFileStream >> rawShaderType; @@ -399,13 +436,13 @@ Shader ZoneFile_COD2_360::pParseAsset_Shader(QDataStream *aZoneFileStream) { type = SHADER_VERTEX; } Q_UNUSED(type); - + while (true) { quint32 instructionToken; *aZoneFileStream >> instructionToken; - + SHADER_OPCODE opCode = (SHADER_OPCODE)(instructionToken & 0xffff); - + int size; if (opCode == OPCODE_End) { break; @@ -416,22 +453,22 @@ Shader ZoneFile_COD2_360::pParseAsset_Shader(QDataStream *aZoneFileStream) { } Q_UNUSED(size); } - - + + return result; } TechSet ZoneFile_COD2_360::pParseAsset_TechSet(QDataStream *aZoneFileStream) { TechSet result; - + for (int i = 1; i <= 62; i++) { quint32 ptr; *aZoneFileStream >> ptr; - + result.pointers << ptr; } qDebug() << aZoneFileStream->device()->pos(); - + // Parse techset name char techSetNameChar; *aZoneFileStream >> techSetNameChar; @@ -440,27 +477,30 @@ TechSet ZoneFile_COD2_360::pParseAsset_TechSet(QDataStream *aZoneFileStream) { *aZoneFileStream >> techSetNameChar; } result.name.replace(",", ""); - + return result; } Image ZoneFile_COD2_360::pParseAsset_Image(QDataStream *aZoneFileStream) { Image result; - + aZoneFileStream->skipRawData(4); - *aZoneFileStream >> result.unknowna >> result.unknownb - >> result.unknownc >> result.unknownd - >> result.unknowne >> result.unknownf - >> result.unknowng; - + *aZoneFileStream >> result.unknowna + >> result.unknownb + >> result.unknownc + >> result.unknownd + >> result.unknowne + >> result.unknownf + >> result.unknowng; + aZoneFileStream->skipRawData(15 * 4); *aZoneFileStream >> result.unknownh >> result.unknowni; - + aZoneFileStream->skipRawData(4); *aZoneFileStream >> result.unknownj; - + aZoneFileStream->skipRawData(4); - + char materialNameChar; *aZoneFileStream >> materialNameChar; while (materialNameChar != 0) { @@ -468,33 +508,33 @@ Image ZoneFile_COD2_360::pParseAsset_Image(QDataStream *aZoneFileStream) { *aZoneFileStream >> materialNameChar; } result.materialName.replace(",", ""); - + if (result.unknowna) { *aZoneFileStream >> result.unknownk; *aZoneFileStream >> result.unknownl; *aZoneFileStream >> result.unknownm; - + aZoneFileStream->skipRawData(4); - + *aZoneFileStream >> result.unknown1; - + aZoneFileStream->skipRawData(4); - + *aZoneFileStream >> result.unknown2 >> result.unknown3 - >> result.size1 >> result.size2 - >> result.unknown4 >> result.unknown5; - + >> result.size1 >> result.size2 + >> result.unknown4 >> result.unknown5; + aZoneFileStream->skipRawData(4); - + char imageNameChar; *aZoneFileStream >> imageNameChar; while (imageNameChar != 0) { result.name += imageNameChar; *aZoneFileStream >> imageNameChar; } - + *aZoneFileStream >> result.unknown6 >> result.unknown7; - + QByteArray compressionData(8, Qt::Uninitialized); aZoneFileStream->readRawData(compressionData.data(), 8); if (compressionData.contains("DXT1")) { @@ -506,16 +546,16 @@ Image ZoneFile_COD2_360::pParseAsset_Image(QDataStream *aZoneFileStream) { } else { result.compression = COMPRESSION_NONE; } - + *aZoneFileStream >> result.unknown8 >> result.unknown9; } - + return result; } Material ZoneFile_COD2_360::pParseAsset_Material(QDataStream *aZoneFileStream) { Material result; - + *aZoneFileStream >> result.namePtr; if (result.namePtr != quint32(-1) && result.namePtr > 0 && GetTagCount() > static_cast(result.namePtr - 1)) { @@ -526,33 +566,33 @@ Material ZoneFile_COD2_360::pParseAsset_Material(QDataStream *aZoneFileStream) { result.refName = GetTags()[result.refNamePtr - 1]; } aZoneFileStream->skipRawData(12); - + for (int i = 0; i < 13; i++) { qint32 unknownPtr; *aZoneFileStream >> unknownPtr; result.pointers << unknownPtr; } - + *aZoneFileStream >> result.stateBits[0] >> result.stateBits[1] >> result.textureCount >> result.constCount >> result.techSetPtr >> result.texturePtr >> result.constPtr; - - + + return result; } SoundAsset ZoneFile_COD2_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { SoundAsset result; - + qDebug() << aZoneFileStream->device()->pos(); - + QByteArray rootNamePtr(4, Qt::Uninitialized); aZoneFileStream->readRawData(rootNamePtr.data(), 4); - + aZoneFileStream->skipRawData(4); - + *aZoneFileStream >> result.count; - + if (rootNamePtr.toHex() == "ffffffff") { // Read in sound file name char soundNameChar; @@ -562,30 +602,30 @@ SoundAsset ZoneFile_COD2_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { *aZoneFileStream >> soundNameChar; } } - + int tagCount = 0; int resultCount = 0; for (quint32 i = 0; i < result.count; i++) { aZoneFileStream->skipRawData(12); - + QByteArray tagPtr(4, Qt::Uninitialized); aZoneFileStream->readRawData(tagPtr.data(), 4); - + if (tagPtr.toHex() == "ffffffff") { tagCount++; } aZoneFileStream->skipRawData(4); - + QByteArray pathPtr(4, Qt::Uninitialized); aZoneFileStream->readRawData(pathPtr.data(), 4); - + if (pathPtr.toHex() == "ffffffff") { resultCount++; } - + aZoneFileStream->skipRawData(160); } - + for (int i = 0; i < tagCount; i++) { // Read in tag? QString tag; @@ -596,25 +636,25 @@ SoundAsset ZoneFile_COD2_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { *aZoneFileStream >> tagChar; } } - + for (int i = 0; i < resultCount; i++) { Sound sound; - + if (aZoneFileStream->device()->peek(12).toHex().contains("ffffffff00000000")) { aZoneFileStream->skipRawData(12); } - + aZoneFileStream->skipRawData(8); - + qDebug() << "- " << aZoneFileStream->device()->pos(); QByteArray aliasPtr(4, Qt::Uninitialized); aZoneFileStream->readRawData(aliasPtr.data(), 4); - + QByteArray namePtr(4, Qt::Uninitialized); aZoneFileStream->readRawData(namePtr.data(), 4); - + *aZoneFileStream >> sound.dataLength; - + if (aliasPtr.toHex() == "ffffffff") { // Read in sound alias name char soundAliasChar; @@ -624,7 +664,7 @@ SoundAsset ZoneFile_COD2_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { *aZoneFileStream >> soundAliasChar; } } - + if (aZoneFileStream->device()->peek(4) == "RIFF") { sound.path = sound.alias; sound.alias = ""; @@ -638,7 +678,7 @@ SoundAsset ZoneFile_COD2_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { } sound.path.replace(",", ""); } - + if (sound.dataLength) { QByteArray data(sound.dataLength, Qt::Uninitialized); aZoneFileStream->readRawData(data.data(), sound.dataLength); @@ -646,7 +686,7 @@ SoundAsset ZoneFile_COD2_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { } result.sounds.append(sound); } - + return result; } @@ -684,48 +724,48 @@ void ZoneFile_COD2_360::pParseAsset_FX(QDataStream *aZoneFileStream) { Animation ZoneFile_COD2_360::pParseAsset_Animation(QDataStream *aZoneFileStream) { Animation result; - + aZoneFileStream->skipRawData(4); - + *aZoneFileStream - >> result.dataByteCount - >> result.dataShortCount - >> result.dataIntCount - >> result.randomDataByteCount - >> result.randomDataIntCount - >> result.numframes - >> result.isLooped - >> result.isDelta - >> result.noneRotatedBoneCount - >> result.twoDRotatedBoneCount - >> result.normalRotatedBoneCount - >> result.twoDRotatedBoneCount - >> result.normalRotatedBoneCount - >> result.normalTranslatedBoneCount - >> result.preciseTranslatedBoneCount - >> result.staticTranslatedBoneCount - >> result.noneTranslatedBoneCount - >> result.totalBoneCount - >> result.otherBoneCount1 - >> result.otherBoneCount2 - >> result.notifyCount - >> result.assetType - >> result.pad - >> result.randomDataShortCount - >> result.indexCount - >> result.frameRate - >> result.frequency - >> result.boneIDsPtr - >> result.dataBytePtr - >> result.dataShortPtr - >> result.dataIntPtr - >> result.randomDataShortPtr - >> result.randomDataBytePtr - >> result.randomDataIntPtr - >> result.longIndiciesPtr - >> result.notificationsPtr - >> result.deltaPartsPtr; - + >> result.dataByteCount + >> result.dataShortCount + >> result.dataIntCount + >> result.randomDataByteCount + >> result.randomDataIntCount + >> result.numframes + >> result.isLooped + >> result.isDelta + >> result.noneRotatedBoneCount + >> result.twoDRotatedBoneCount + >> result.normalRotatedBoneCount + >> result.twoDRotatedBoneCount + >> result.normalRotatedBoneCount + >> result.normalTranslatedBoneCount + >> result.preciseTranslatedBoneCount + >> result.staticTranslatedBoneCount + >> result.noneTranslatedBoneCount + >> result.totalBoneCount + >> result.otherBoneCount1 + >> result.otherBoneCount2 + >> result.notifyCount + >> result.assetType + >> result.pad + >> result.randomDataShortCount + >> result.indexCount + >> result.frameRate + >> result.frequency + >> result.boneIDsPtr + >> result.dataBytePtr + >> result.dataShortPtr + >> result.dataIntPtr + >> result.randomDataShortPtr + >> result.randomDataBytePtr + >> result.randomDataIntPtr + >> result.longIndiciesPtr + >> result.notificationsPtr + >> result.deltaPartsPtr; + // Read in x_anim file name QString xAnimName; char xAnimNameChar; @@ -734,7 +774,7 @@ Animation ZoneFile_COD2_360::pParseAsset_Animation(QDataStream *aZoneFileStream) result.name += xAnimNameChar; *aZoneFileStream >> xAnimNameChar; } - + // Parse x_anim index header QVector sectionLengths; for (int i = 0; i < result.numframes; i++) { @@ -746,19 +786,19 @@ Animation ZoneFile_COD2_360::pParseAsset_Animation(QDataStream *aZoneFileStream) } // Skip unknown section aZoneFileStream->skipRawData(2 * 8); - + return result; } MenuFile ZoneFile_COD2_360::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { //MENU_FILE MenuFile result; - + aZoneFileStream->skipRawData(4); // Separator - + // Parse menu def count *aZoneFileStream >> result.menuCount; - + // Clearly misparsed, never have this much if (result.menuCount > 1000) { qDebug() << "Failure reported when parsing menu file."; @@ -766,9 +806,9 @@ MenuFile ZoneFile_COD2_360::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { } for (uint i = 0; i < result.menuCount; i++) { Menu menu; - + aZoneFileStream->skipRawData(4); // Separator - + // Read in x_anim file name char menuFilepathChar; *aZoneFileStream >> menuFilepathChar; @@ -777,63 +817,63 @@ MenuFile ZoneFile_COD2_360::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { *aZoneFileStream >> menuFilepathChar; } aZoneFileStream->skipRawData(4); // Separator - + *aZoneFileStream >> menu.menuNamePtr; - + float menuRectX, menuRectY, menuRectWidth, menuRectHeight; *aZoneFileStream >> menuRectX >> menuRectY >> menuRectWidth >> menuRectHeight; menu.rect = QRectF(menuRectX, menuRectY, menuRectWidth, menuRectHeight); - + quint32 hAlignInt, vAlignInt; *aZoneFileStream >> hAlignInt >> vAlignInt; menu.hAlign = (MENU_H_ALIGNMENT)hAlignInt; menu.vAlign = (MENU_V_ALIGNMENT)vAlignInt; - + float rectClientX, rectClientY, rectClientWidth, rectClientHeight; *aZoneFileStream >> rectClientX >> rectClientY >> rectClientWidth >> rectClientHeight; menu.clientRect = QRectF(rectClientX, rectClientY, rectClientWidth, rectClientHeight); - + quint32 hClientAlignInt, vClientAlignInt, styleInt, borderInt; *aZoneFileStream >> hClientAlignInt >> vClientAlignInt >> menu.groupPtr - >> styleInt >> borderInt >> menu.ownerDraw >> menu.ownerDrawFlags - >> menu.borderSize >> menu.staticFlags >> menu.dynamicFlags >> menu.nextTime; + >> styleInt >> borderInt >> menu.ownerDraw >> menu.ownerDrawFlags + >> menu.borderSize >> menu.staticFlags >> menu.dynamicFlags >> menu.nextTime; menu.hClientAlign = (MENU_H_ALIGNMENT)hClientAlignInt; menu.vClientAlign = (MENU_V_ALIGNMENT)vClientAlignInt; menu.style = (MENU_WINDOW_STYLE)styleInt; menu.border = (MENU_WINDOW_BORDER)borderInt; - + float foregroundColorR, foregroundColorG, foregroundColorB, foregroundColorA, - backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA, - borderColorR, borderColorG, borderColorB, borderColorA, - outlineColorR, outlineColorG, outlineColorB, outlineColorA; + backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA, + borderColorR, borderColorG, borderColorB, borderColorA, + outlineColorR, outlineColorG, outlineColorB, outlineColorA; *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA - >> backgroundColorR >> backgroundColorG >> backgroundColorB >> backgroundColorA - >> borderColorR >> borderColorG >> borderColorB >> borderColorA - >> outlineColorR >> outlineColorG >> outlineColorB >> outlineColorA; - + >> backgroundColorR >> backgroundColorG >> backgroundColorB >> backgroundColorA + >> borderColorR >> borderColorG >> borderColorB >> borderColorA + >> outlineColorR >> outlineColorG >> outlineColorB >> outlineColorA; + menu.foregroundColor = QColor(foregroundColorR, foregroundColorG, foregroundColorB, foregroundColorA); menu.backgroundColor = QColor(backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA); menu.borderColor = QColor(borderColorR, borderColorG, borderColorB, borderColorA); menu.outlineColor = QColor(outlineColorR, outlineColorG, outlineColorB, outlineColorA); - + *aZoneFileStream >> menu.materialPtr >> menu.fontPtr >> menu.fullScreen >> menu.itemCount - >> menu.fontIndex >> menu.cursorItem >> menu.fadeCycle >> menu.fadeClamp - >> menu.fadeAmount >> menu.fadeInAmount >> menu.blurRadius >> menu.onOpenPtr - >> menu.onFocusPtr >> menu.onClosePtr >> menu.onESCPtr >> menu.onKeyPtr - >> menu.visibleExpCount >> menu.expEntryPtr >> menu.allowedBindingPtr - >> menu.soundNamePtr >> menu.imageTrack; - + >> menu.fontIndex >> menu.cursorItem >> menu.fadeCycle >> menu.fadeClamp + >> menu.fadeAmount >> menu.fadeInAmount >> menu.blurRadius >> menu.onOpenPtr + >> menu.onFocusPtr >> menu.onClosePtr >> menu.onESCPtr >> menu.onKeyPtr + >> menu.visibleExpCount >> menu.expEntryPtr >> menu.allowedBindingPtr + >> menu.soundNamePtr >> menu.imageTrack; + float focusColorR, focusColorG, focusColorB, focusColorA, - disabledColorR, disabledColorG, disabledColorB, disabledColorA; + disabledColorR, disabledColorG, disabledColorB, disabledColorA; *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA - >> disabledColorR >> disabledColorG >> disabledColorB >> disabledColorA; + >> disabledColorR >> disabledColorG >> disabledColorB >> disabledColorA; menu.focusColor = QColor(focusColorR, focusColorG, focusColorB, focusColorA); menu.disabledColor = QColor(disabledColorR, disabledColorG, disabledColorB, disabledColorA); - + *aZoneFileStream >> menu.rectXExpCount >> menu.rectXExpPtr >> menu.rectYExpCount >> menu.rectYExpPtr; - + aZoneFileStream->skipRawData(4); // Separator - + char menuDefNameChar; int menuDefNameLen = 0; *aZoneFileStream >> menuDefNameChar; @@ -842,7 +882,7 @@ MenuFile ZoneFile_COD2_360::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { menu.name += menuDefNameChar; *aZoneFileStream >> menuDefNameChar; } - + char defStringChar; int defStringLen = 0; *aZoneFileStream >> defStringChar; @@ -852,115 +892,115 @@ MenuFile ZoneFile_COD2_360::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { *aZoneFileStream >> defStringChar; } aZoneFileStream->skipRawData(4 * 10); - + *aZoneFileStream >> menu.itemWindowDefNamePtr; - + float itemRectX, itemRectY, itemRectWidth, itemRectHeight; *aZoneFileStream >> itemRectX >> itemRectY >> itemRectWidth >> itemRectHeight; menu.itemRect = QRectF(itemRectX, itemRectY, itemRectWidth, itemRectHeight); - + *aZoneFileStream >> menu.itemHAlignment >> menu.itemVAlignment >> menu.itemGroupPtr - >> menu.itemWindowStyle >> menu.itemWindowBorder >> menu.itemOwnerDraw - >> menu.itemOwnerDrawFlags >> menu.itemBorderSize >> menu.itemStaticFlags - >> menu.itemDynamicFlags >> menu.itemNextTime; - + >> menu.itemWindowStyle >> menu.itemWindowBorder >> menu.itemOwnerDraw + >> menu.itemOwnerDrawFlags >> menu.itemBorderSize >> menu.itemStaticFlags + >> menu.itemDynamicFlags >> menu.itemNextTime; + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, - itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA, - itemBorderColorR, itemBorderColorG, itemBorderColorB, itemBorderColorA, - itemOutlineColorR, itemOutlineColorG, itemOutlineColorB, itemOutlineColorA; + itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA, + itemBorderColorR, itemBorderColorG, itemBorderColorB, itemBorderColorA, + itemOutlineColorR, itemOutlineColorG, itemOutlineColorB, itemOutlineColorA; *aZoneFileStream >> itemForegroundColorR >> itemForegroundColorG >> itemForegroundColorB >> itemForegroundColorA - >> itemBackgroundColorR >> itemBackgroundColorG >> itemBackgroundColorB >> itemBackgroundColorA - >> itemBorderColorR >> itemBorderColorG >> itemBorderColorB >> itemBorderColorA - >> itemOutlineColorR >> itemOutlineColorG >> itemOutlineColorB >> itemOutlineColorA; - + >> itemBackgroundColorR >> itemBackgroundColorG >> itemBackgroundColorB >> itemBackgroundColorA + >> itemBorderColorR >> itemBorderColorG >> itemBorderColorB >> itemBorderColorA + >> itemOutlineColorR >> itemOutlineColorG >> itemOutlineColorB >> itemOutlineColorA; + menu.itemForegroundColor = QColor(itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA); menu.itemBackgroundColor = QColor(itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA); menu.itemBorderColor = QColor(itemBorderColorR, itemBorderColorG, itemBorderColorB, itemBorderColorA); menu.itemOutlineColor = QColor(itemOutlineColorR, itemOutlineColorG, itemOutlineColorB, itemOutlineColorA); - + *aZoneFileStream >> menu.itemMaterialPtr; - + float itemTextRectX, itemTextRectY, itemTextRectWidth, itemTextRectHeight; *aZoneFileStream >> itemTextRectX >> itemTextRectY >> itemTextRectWidth >> itemTextRectHeight; menu.itemTextRect = QRectF(itemTextRectX, itemTextRectY, itemTextRectWidth, itemTextRectHeight); - + quint32 hItemTextAlignInt, vItemTextAlignInt, itemType, fontTypeInt, textStyleInt; *aZoneFileStream >> hItemTextAlignInt >> vItemTextAlignInt >> itemType >> menu.dataType - >> menu.alignment >> fontTypeInt >> menu.textAlignMode >> menu.textalignx >> menu.textaligny - >> menu.textscale >> textStyleInt >> menu.gameMsgWindowIndex >> menu.gameMsgWindowMode - >> menu.testPtr >> menu.textSavegameInfo >> menu.parentPtr; + >> menu.alignment >> fontTypeInt >> menu.textAlignMode >> menu.textalignx >> menu.textaligny + >> menu.textscale >> textStyleInt >> menu.gameMsgWindowIndex >> menu.gameMsgWindowMode + >> menu.testPtr >> menu.textSavegameInfo >> menu.parentPtr; menu.itemText_hAlign = (MENU_H_ALIGNMENT)hItemTextAlignInt; menu.itemText_vAlign = (MENU_V_ALIGNMENT)vItemTextAlignInt; menu.itemType = (MENU_ITEM_TYPE)itemType; menu.fontEnum = (MENU_FONT_TYPE)fontTypeInt; menu.textStyle = (MENU_ITEM_TEXTSTYLE)textStyleInt; - + *aZoneFileStream >> menu.mouseEnterText >> menu.mouseExitText >> menu.mouseEnter >> menu.mouseExit - >> menu.action >> menu.onAccept >> menu.onFocus >> menu.leaveFocus >> menu.dvar >> menu.dvarTest - >> menu.keyHandlerPtr >> menu.enableDvarPtr >> menu.dvarFlags >> menu.focusSoundPtr - >> menu.special >> menu.cursorPos; - + >> menu.action >> menu.onAccept >> menu.onFocus >> menu.leaveFocus >> menu.dvar >> menu.dvarTest + >> menu.keyHandlerPtr >> menu.enableDvarPtr >> menu.dvarFlags >> menu.focusSoundPtr + >> menu.special >> menu.cursorPos; + // itemDefData_t typeData; - + // listBoxDef_s *listBox; - + *aZoneFileStream >> menu.startPos >> menu.endPos >> menu.drawPadding; - + *aZoneFileStream >> menu.elementWidth >> menu.elementHeight; - + *aZoneFileStream >> menu.elementStyle >> menu.numColumns; - + //columnInfo_s columnInfo[16]; - + *aZoneFileStream >> menu.doubleClickPtr; - - + + *aZoneFileStream >> menu.notselectable >> menu.noScrollBars >> menu.usePaging; - + float itemSelectBorderColorR, itemSelectBorderColorG, itemSelectBorderColorB, itemSelectBorderColorA, - itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA, - itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA; + itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA, + itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA; *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA - >> itemDisableColorR >> itemDisableColorG >> itemDisableColorB >> itemDisableColorA - >> itemFocusColorR >> itemFocusColorG >> itemFocusColorB >> itemFocusColorA; + >> itemDisableColorR >> itemDisableColorG >> itemDisableColorB >> itemDisableColorA + >> itemFocusColorR >> itemFocusColorG >> itemFocusColorB >> itemFocusColorA; menu.itemSelectBorderColor = QColor(itemSelectBorderColorR, itemSelectBorderColorG, itemSelectBorderColorB, itemSelectBorderColorA); menu.itemDisableColor = QColor(itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA); menu.itemFocusColor = QColor(itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA); - + *aZoneFileStream >> menu.selectIconPtr >> menu.backgroundItemListboxPtr >> menu.highlightTexturePtr; - + // editFieldDef_s *editField; - + *aZoneFileStream >> menu.minVal >> menu.maxVal >> menu.defVal >> menu.range >> menu.maxChars - >> menu.maxCharsGotoNext >> menu.maxPaintChars >> menu.paintOffset; - + >> menu.maxCharsGotoNext >> menu.maxPaintChars >> menu.paintOffset; + // multiDef_s *multi; - + for (int i = 0; i < 32; i++) { quint32 dvarList; *aZoneFileStream >> dvarList; menu.dvarListPtrs.push_back(dvarList); } - + for (int i = 0; i < 32; i++) { quint32 dvarStr; *aZoneFileStream >> dvarStr; menu.dvarStrPtrs.push_back(dvarStr); } - + for (int i = 0; i < 32; i++) { float dvarValue; *aZoneFileStream >> dvarValue; menu.dvarValues.push_back(dvarValue); } - + *aZoneFileStream >> menu.count >> menu.strDef >> menu.enumDvarNamePtr; aZoneFileStream->skipRawData(4); //>> menu.dataPtr *aZoneFileStream >> menu.itemImageTrack; - + qDebug() << aZoneFileStream->device()->pos(); - + //statement_s visibleExp; //statement_s textExp; //statement_s materialExp; @@ -986,19 +1026,19 @@ void ZoneFile_COD2_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { StringTable ZoneFile_COD2_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { StringTable result; - + aZoneFileStream->skipRawData(4); - + *aZoneFileStream - >> result.columnCount - >> result.rowCount; - + >> result.columnCount + >> result.rowCount; + // Todo fix this result.columnCount = 0; result.rowCount = 0; - + aZoneFileStream->skipRawData(4); - + QString stringTableName; char stringTableNameChar; *aZoneFileStream >> stringTableNameChar; @@ -1006,15 +1046,15 @@ StringTable ZoneFile_COD2_360::pParseAsset_StringTable(QDataStream *aZoneFileStr result.name += stringTableNameChar; *aZoneFileStream >> stringTableNameChar; } - + for (quint32 i = 0; i < result.rowCount; i++) { QByteArray pointerData(4, Qt::Uninitialized); aZoneFileStream->readRawData(pointerData.data(), 4); result.tablePointers.push_back(pointerData.toHex()); - + aZoneFileStream->skipRawData(4); } - + for (const QString &pointerAddr : result.tablePointers) { QString leadingContent = ""; if (pointerAddr == "FFFFFFFF") { @@ -1027,7 +1067,7 @@ StringTable ZoneFile_COD2_360::pParseAsset_StringTable(QDataStream *aZoneFileStr } else { leadingContent = pointerAddr; } - + QString content; char contentChar; *aZoneFileStream >> contentChar; @@ -1039,29 +1079,10 @@ StringTable ZoneFile_COD2_360::pParseAsset_StringTable(QDataStream *aZoneFileStr } return result; } -// "parts", -// ASSET_MODEL, -// ASSET_MATERIAL, -// ASSET_IMAGE, -// ASSET_SOUND, -// "sndCurve", -// "clipMap", -// "world", -// "lightDef", -// ASSET_FONT, -// "menuList", -// ASSET_MENU, -// "localize", -// ASSET_WEAPON, -// "sndDriverGlobals", -// "fx", -// "impactFx", -// "rawfile", -// "data" AssetType ZoneFile_COD2_360::AssetStrToEnum(const QString aAssetType) { const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "") { + if (cleanedType == "00000017") { return ASSET_RAW_FILE; } else if (cleanedType == "") { return ASSET_EFFECT; @@ -1087,7 +1108,7 @@ AssetType ZoneFile_COD2_360::AssetStrToEnum(const QString aAssetType) { return ASSET_FONT; } else if (cleanedType == "") { return ASSET_MODEL; - } else if (cleanedType == "") { + } else if (cleanedType == "00000006") { return ASSET_D3DBSP; } else if (cleanedType == "00000002") { return ASSET_MATERIAL; @@ -1099,14 +1120,14 @@ AssetType ZoneFile_COD2_360::AssetStrToEnum(const QString aAssetType) { return ASSET_PHYS_PRESET; } else if (cleanedType == "") { return ASSET_DESTRUCTIBLE; - } else if (cleanedType == "") { - return ASSET_MENU; + } else if (cleanedType == "00000004") { + return ASSET_SHOCK_FILE; } return ASSET_NONE; } QByteArray ZoneFile_COD2_360::GetBinaryData() { QByteArray result; - + return result; } diff --git a/libs/zonefile/360/zonefile_cod2_360.h b/libs/zonefile/360/zonefile_cod2_360.h index 0cdbbed..ac50d24 100644 --- a/libs/zonefile/360/zonefile_cod2_360.h +++ b/libs/zonefile/360/zonefile_cod2_360.h @@ -14,6 +14,14 @@ public: QByteArray GetBinaryData() override; + void SetMiscCount(quint32 aMiscCount) { + mMiscCount = aMiscCount; + } + + quint32 GetMiscCount() { + return mMiscCount; + } + protected: void pParseZoneHeader(QDataStream *aZoneFileStream) override; quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; @@ -23,6 +31,7 @@ protected: void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseMiscTags(QDataStream *aZoneFileStream); QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; @@ -47,6 +56,9 @@ protected: void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; + +private: + quint32 mMiscCount; }; #endif // ZONEFILE_COD2_360_H diff --git a/libs/zonefile/360/zonefile_cod4_360.cpp b/libs/zonefile/360/zonefile_cod4_360.cpp index 8e1955e..d9ecb43 100644 --- a/libs/zonefile/360/zonefile_cod4_360.cpp +++ b/libs/zonefile/360/zonefile_cod4_360.cpp @@ -1,4 +1,5 @@ #include "zonefile_cod4_360.h" +#include "utils.h" #include #include @@ -152,7 +153,7 @@ QStringList ZoneFile_COD4_360::pParseZoneTags(QDataStream *aZoneFileStream, quin // Parse tags/strings before index QString zoneTag; char zoneTagChar; - for (quint32 i = 0; i < tagCount - 1; i++) { + for (quint32 i = 0; i < tagCount; i++) { *aZoneFileStream >> zoneTagChar; while (zoneTagChar != 0) { zoneTag += zoneTagChar; @@ -177,6 +178,10 @@ QStringList ZoneFile_COD4_360::pParseZoneIndex(QDataStream *aZoneFileStream, qui // Don't parse if no records if (!recordCount) { return result; } + if (aZoneFileStream->device()->peek(4).toHex().contains("ff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 1); + } + // Parse index & map found asset types for (quint32 i = 0; i < recordCount; i++) { // Skip record start @@ -253,9 +258,9 @@ AssetMap ZoneFile_COD4_360::pParseAssets(QDataStream *aZoneFileStream, QStringLi LocalString ZoneFile_COD4_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { LocalString result; - quint32 stringPtr, aliasPtr; + qint32 stringPtr, aliasPtr; *aZoneFileStream >> stringPtr >> aliasPtr; - if (stringPtr == 4294967295) { + if (stringPtr == -1) { // Parse local string asset contents QString localStr; char localStrChar; @@ -268,7 +273,7 @@ LocalString ZoneFile_COD4_360::pParseAsset_LocalString(QDataStream *aZoneFileStr result.string = "String Ptr: " + QString::number(stringPtr); } - if (aliasPtr == 4294967295) { + if (aliasPtr == -1) { // Parse rawfile name QString aliasName; char aliasNameChar; @@ -287,6 +292,8 @@ LocalString ZoneFile_COD4_360::pParseAsset_LocalString(QDataStream *aZoneFileStr RawFile ZoneFile_COD4_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { RawFile result; + result.startPos = aZoneFileStream->device()->pos(); + // Skip start separator FF FF FF FF (pointer?) aZoneFileStream->skipRawData(4); @@ -330,6 +337,8 @@ RawFile ZoneFile_COD4_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { *aZoneFileStream >> rawFileContentsChar; } } + + result.endPos = aZoneFileStream->device()->pos(); return result; } @@ -340,57 +349,93 @@ void ZoneFile_COD4_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { Model ZoneFile_COD4_360::pParseAsset_Model(QDataStream *aZoneFileStream) { Model result; - *aZoneFileStream >> result.namePtr >> result.tagCount >> result.rootTagCount - >> result.surfCount >> result.unknownCount >> result.boneNamePtr - >> result.parentListPtr >> result.quatsPtr >> result.transPtr - >> result.partClassPtr >> result.baseMatPtr - >> result.surfsPtr >> result.materialHandlesPtr; + aZoneFileStream->skipRawData(4); - // Parse XModelLodInfo - for (int i = 1; i <= 4; i++) { - quint32 intDist; - *aZoneFileStream >> intDist; - - std::memcpy(&result.lodInfo[i].dist, &intDist, sizeof(result.lodInfo[i].dist)); - *aZoneFileStream >> result.lodInfo[i].numsurfs >> result.lodInfo[i].surfIndex; - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.lodInfo[i].partBits[0] - >> result.lodInfo[i].partBits[1] - >> result.lodInfo[i].partBits[2] - >> result.lodInfo[i].partBits[3]; + QByteArray modelMagic(4, Qt::Uninitialized); + aZoneFileStream->readRawData(modelMagic.data(), 4); + if (modelMagic.toHex() != "01010200") { + qDebug() << "Invalid model magic: " << modelMagic.toHex(); + return result; } + qDebug() << "Model Magic: " << modelMagic.toHex(); - *aZoneFileStream >> result.collSurfsPtr >> result.numCollSurfs >> result.contents >> result.boneInfoPtr; + aZoneFileStream->skipRawData(8 * 4); - quint32 intRadius, intMins[3], intMaxs[3]; - *aZoneFileStream >> intRadius >> intMins[0] >> intMins[1] - >> intMins[2] >> intMaxs[0] >> intMaxs[1] >> intMaxs[2]; + for (int i = 0; i < 4; i++) { - std::memcpy(&result.radius, &intRadius, sizeof(result.radius)); + QByteArray lodData(4, Qt::Uninitialized); + aZoneFileStream->readRawData(lodData.data(), 4); - std::memcpy(&result.mins[0], &intMins[0], sizeof(result.mins[0])); - std::memcpy(&result.mins[1], &intMins[1], sizeof(result.mins[1])); - std::memcpy(&result.mins[2], &intMins[2], sizeof(result.mins[2])); + float levelOfDetail = qFromBigEndian(reinterpret_cast(lodData.constData())); - std::memcpy(&result.maxs[0], &intMaxs[0], sizeof(result.maxs[0])); - std::memcpy(&result.maxs[1], &intMaxs[1], sizeof(result.maxs[2])); - std::memcpy(&result.maxs[2], &intMaxs[2], sizeof(result.maxs[3])); + quint16 surfacePresent; + *aZoneFileStream >> surfacePresent; - *aZoneFileStream >> result.numLods >> result.collLod >> result.streamInfoPtr - >> result.memUsage >> result.flags >> result.physPresetPtr >> result.physGeomsPtr; + quint16 surfaceIndex; + *aZoneFileStream >> surfaceIndex; - // Parse model name + if (surfacePresent) { + qDebug() << "Surface " << surfaceIndex << " detected"; + qDebug() << "- Level of Detail: " << levelOfDetail; + } + aZoneFileStream->skipRawData(4 * 4); + } + aZoneFileStream->skipRawData(17 * 4); + + qDebug() << "Name Char: " << aZoneFileStream->device()->pos(); + QString modelName; char modelNameChar; *aZoneFileStream >> modelNameChar; - while (modelNameChar == 0) { - *aZoneFileStream >> modelNameChar; - } while (modelNameChar != 0) { - result.modelName += modelNameChar; + modelName += modelNameChar; *aZoneFileStream >> modelNameChar; } + qDebug() << "Model Name: " << modelName; + + aZoneFileStream->skipRawData(4 * 9 + 1); + + quint16 vertCount, faceCount; + *aZoneFileStream >> vertCount >> faceCount; + qDebug() << "Vertex count 1: " << vertCount; + qDebug() << "Face count 1: " << faceCount; + + aZoneFileStream->skipRawData(57 * 4 - 2); + + qDebug() << "Vertex Listing: " << aZoneFileStream->device()->pos(); + for (int i = 0; i < vertCount; i++) { + qDebug() << "- Vertex " << i; + + QByteArray xOffData(4, Qt::Uninitialized); + aZoneFileStream->readRawData(xOffData.data(), 4); + float xOff = qFromBigEndian(reinterpret_cast(xOffData.constData())); + + QByteArray yOffData(4, Qt::Uninitialized); + aZoneFileStream->readRawData(yOffData.data(), 4); + float yOff = qFromBigEndian(reinterpret_cast(yOffData.constData())); + + QByteArray zOffData(4, Qt::Uninitialized); + aZoneFileStream->readRawData(zOffData.data(), 4); + float zOff = qFromBigEndian(reinterpret_cast(zOffData.constData())); + + qDebug() << " - Offset: " << xOff << ", " << yOff << ", " << zOff; + aZoneFileStream->skipRawData(20); + } + + qDebug() << "Count 2: " << aZoneFileStream->device()->pos(); + quint32 vertCount1, faceCount1; + *aZoneFileStream >> vertCount1 >> faceCount1; + qDebug() << "Vertex count 2: " << vertCount1; + qDebug() << "Face count 2: " << faceCount1; + + aZoneFileStream->skipRawData(1968); + + for (int i = 0; i < faceCount - 6; i++) { + aZoneFileStream->skipRawData(64); + } + aZoneFileStream->skipRawData(224); + + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() + aZoneFileStream->device()->peek(1024).toHex().indexOf("ffffffff")); + return result; } @@ -508,15 +553,13 @@ TechSet ZoneFile_COD4_360::pParseAsset_TechSet(QDataStream *aZoneFileStream) { *aZoneFileStream >> namePtr; - for (int i = 0; i < 53; i++) { + for (int i = 0; i < 28; i++) { quint32 ptr; *aZoneFileStream >> ptr; result.pointers << ptr; } - //aZoneFileStream->skipRawData(53 * 4); - if (namePtr == -1) { aZoneFileStream->skipRawData(1); @@ -536,68 +579,62 @@ TechSet ZoneFile_COD4_360::pParseAsset_TechSet(QDataStream *aZoneFileStream) { Image ZoneFile_COD4_360::pParseAsset_Image(QDataStream *aZoneFileStream) { Image result; - aZoneFileStream->skipRawData(4); - *aZoneFileStream >> result.unknowna >> result.unknownb - >> result.unknownc >> result.unknownd - >> result.unknowne >> result.unknownf - >> result.unknowng; + qDebug() << "Header" << aZoneFileStream->device()->pos(); + qDebug() << "- Start Pos: " << aZoneFileStream->device()->pos(); + aZoneFileStream->skipRawData(14); - aZoneFileStream->skipRawData(15 * 4); - *aZoneFileStream >> result.unknownh >> result.unknowni; + QByteArray sectionCountData(1, Qt::Uninitialized); + aZoneFileStream->readRawData(sectionCountData.data(), 1); - aZoneFileStream->skipRawData(4); - *aZoneFileStream >> result.unknownj; + QString sectionCountStr = sectionCountData.toHex(); + std::reverse(sectionCountStr.begin(), sectionCountStr.end()); - aZoneFileStream->skipRawData(4); + quint32 sectionCount = sectionCountStr.toInt(); + qDebug() << "- Section Count: " << sectionCountStr << " : " << sectionCount; - char materialNameChar; - *aZoneFileStream >> materialNameChar; - while (materialNameChar != 0) { - result.materialName += materialNameChar; - *aZoneFileStream >> materialNameChar; - } - result.materialName.replace(",", ""); + aZoneFileStream->skipRawData(25); - if (result.unknowna) { - *aZoneFileStream >> result.unknownk; - *aZoneFileStream >> result.unknownl; - *aZoneFileStream >> result.unknownm; - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.unknown1; - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.unknown2 >> result.unknown3 - >> result.size1 >> result.size2 - >> result.unknown4 >> result.unknown5; - - aZoneFileStream->skipRawData(4); - - char imageNameChar; + // Parse image name + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + result.name += imageNameChar; + result.materialName += imageNameChar; *aZoneFileStream >> imageNameChar; - while (imageNameChar != 0) { - result.name += imageNameChar; - *aZoneFileStream >> imageNameChar; - } - - *aZoneFileStream >> result.unknown6 >> result.unknown7; - - QByteArray compressionData(8, Qt::Uninitialized); - aZoneFileStream->readRawData(compressionData.data(), 8); - if (compressionData.contains("DXT1")) { - result.compression = COMPRESSION_DXT1; - } else if (compressionData.contains("DXT3")) { - result.compression = COMPRESSION_DXT3; - } else if (compressionData.contains("DXT5")) { - result.compression = COMPRESSION_DXT5; - } else { - result.compression = COMPRESSION_NONE; - } - - *aZoneFileStream >> result.unknown8 >> result.unknown9; } + qDebug() << "- Name: " << result.name; + qDebug() << "- End Pos: " << aZoneFileStream->device()->pos(); + + qDebug() << "Chunks [" << sectionCount << "]"; + for (int i = 0; i < sectionCount; i++) { + qDebug() << "- Chunk " << sectionCount; + qDebug() << " - Header" << sectionCount; + qDebug() << " - Start Pos: " << aZoneFileStream->device()->pos(); + + // TODO: Parse header/index/pointers? + for (int j = 0; j < 60; j++) { + quint32 unknownPtr; + *aZoneFileStream >> unknownPtr; + + result.unknowns.append(unknownPtr); + } + + qDebug() << " - End Pos: " << aZoneFileStream->device()->pos(); + qDebug() << " - Data" << sectionCount; + qDebug() << " - Start Pos: " << aZoneFileStream->device()->pos(); + + // TODO: Parse data chunks + aZoneFileStream->skipRawData(3856); + qDebug() << " - End Pos: " << aZoneFileStream->device()->pos(); + } + + qDebug() << "Footer"; + qDebug() << "- Start Pos: " << aZoneFileStream->device()->pos(); + // TODO: Parse pointers/footer? + for (int k = 0; k < 17; k++) { + aZoneFileStream->skipRawData(4); + } + qDebug() << "- End Pos: " << aZoneFileStream->device()->pos(); return result; } @@ -605,6 +642,9 @@ Image ZoneFile_COD4_360::pParseAsset_Image(QDataStream *aZoneFileStream) { SoundAsset ZoneFile_COD4_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { SoundAsset result; + // TODO Reimplement proper sound parsing + return result; + QByteArray rootNamePtr(4, Qt::Uninitialized); aZoneFileStream->readRawData(rootNamePtr.data(), 4); @@ -1100,13 +1140,13 @@ StringTable ZoneFile_COD4_360::pParseAsset_StringTable(QDataStream *aZoneFileStr AssetType ZoneFile_COD4_360::AssetStrToEnum(const QString aAssetType) { const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "00000021") { + if (cleanedType == "00000020") { return ASSET_RAW_FILE; } else if (cleanedType == "0000001A") { return ASSET_EFFECT; - } else if (cleanedType == "00000009") { - return ASSET_SOUND; - } else if (cleanedType == "00000004") { + } else if (cleanedType == "00000017") { + return ASSET_LOCAL_STRING; + } else if (cleanedType == "00000002") { return ASSET_ANIMATION; } else if (cleanedType == "0000000C") { return ASSET_COLLISION_MAP; @@ -1114,21 +1154,19 @@ AssetType ZoneFile_COD4_360::AssetStrToEnum(const QString aAssetType) { return ASSET_STRING_TABLE; } else if (cleanedType == "00000015") { return ASSET_MENU; - } else if (cleanedType == "00000008") { + } else if (cleanedType == "00000006") { return ASSET_TECH_SET; } else if (cleanedType == "00000018") { - return ASSET_LOCAL_STRING; + return ASSET_WEAPON; } else if (cleanedType == "00000011") { return ASSET_GFX_MAP; } else if (cleanedType == "00000012") { return ASSET_LIGHT_DEF; } else if (cleanedType == "00000014") { return ASSET_FONT; - } else if (cleanedType == "00000005") { - return ASSET_MODEL; } else if (cleanedType == "0000000D") { return ASSET_D3DBSP; - } else if (cleanedType == "00000006") { + } else if (cleanedType == "00000008") { return ASSET_MATERIAL; } else if (cleanedType == "0000000E") { return ASSET_GAME_MAP_SP; @@ -1137,9 +1175,17 @@ AssetType ZoneFile_COD4_360::AssetStrToEnum(const QString aAssetType) { } else if (cleanedType == "00000001") { return ASSET_PHYS_PRESET; } else if (cleanedType == "00000003") { - return ASSET_DESTRUCTIBLE; + return ASSET_MODEL; } else if (cleanedType == "00000016") { return ASSET_MENU; + } else if (cleanedType == "0000001B") { + return ASSET_UI_MAP; + } else if (cleanedType == "00000007") { + return ASSET_IMAGE; + } else if (cleanedType == "00000009") { + return ASSET_SOUND_DRIVER_GLOBALS; + } else if (cleanedType == "00000019") { + return ASSET_SOUND; } return ASSET_NONE; } diff --git a/libs/zonefile/360/zonefile_cod5_360.cpp b/libs/zonefile/360/zonefile_cod5_360.cpp index 1149637..b47b0b0 100644 --- a/libs/zonefile/360/zonefile_cod5_360.cpp +++ b/libs/zonefile/360/zonefile_cod5_360.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD5_360::pParseZoneTags(QDataStream *aZoneFileStream, quin *aZoneFileStream >> zoneTagChar; } if (!zoneTag.isEmpty()) { - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } } zoneTag.clear(); } diff --git a/libs/zonefile/360/zonefile_cod6_360.cpp b/libs/zonefile/360/zonefile_cod6_360.cpp index aaf7d38..5ab538c 100644 --- a/libs/zonefile/360/zonefile_cod6_360.cpp +++ b/libs/zonefile/360/zonefile_cod6_360.cpp @@ -28,7 +28,8 @@ bool ZoneFile_COD6_360::Load(const QByteArray aFileData) { void ZoneFile_COD6_360::pParseZoneHeader(QDataStream *aZoneFileStream) { SetSize(pParseZoneSize(aZoneFileStream)); - pParseZoneUnknownsA(aZoneFileStream); + + aZoneFileStream->skipRawData(28); SetTagCount(pParseZoneTagCount(aZoneFileStream)); pParseZoneUnknownsB(aZoneFileStream); @@ -51,7 +52,7 @@ quint32 ZoneFile_COD6_360::pParseZoneSize(QDataStream *aZoneFileStream) { qDebug() << "Tried to open empty zone file!"; exit(-1); } - zoneFileSize += 36; + zoneFileSize += 32; return zoneFileSize; } @@ -147,19 +148,19 @@ QStringList ZoneFile_COD6_360::pParseZoneTags(QDataStream *aZoneFileStream, quin QStringList tags; // Byte 48-51: Repeated separators? ÿÿÿÿ x i - aZoneFileStream->skipRawData(4 * (tagCount - 1)); + aZoneFileStream->skipRawData(4 * (tagCount + 1)); // Parse tags/strings before index QString zoneTag; char zoneTagChar; - for (quint32 i = 0; i < tagCount - 1; i++) { + for (quint32 i = 0; i < tagCount; i++) { *aZoneFileStream >> zoneTagChar; while (zoneTagChar != 0) { zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } if (!zoneTag.isEmpty()) { - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } } zoneTag.clear(); } @@ -604,6 +605,7 @@ Image ZoneFile_COD6_360::pParseAsset_Image(QDataStream *aZoneFileStream) { SoundAsset ZoneFile_COD6_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { SoundAsset result; + return result; QByteArray rootNamePtr(4, Qt::Uninitialized); aZoneFileStream->readRawData(rootNamePtr.data(), 4); diff --git a/libs/zonefile/360/zonefile_cod7_360.cpp b/libs/zonefile/360/zonefile_cod7_360.cpp index 4d745bb..f3a173c 100644 --- a/libs/zonefile/360/zonefile_cod7_360.cpp +++ b/libs/zonefile/360/zonefile_cod7_360.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD7_360::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/360/zonefile_cod8_360.cpp b/libs/zonefile/360/zonefile_cod8_360.cpp index c17fa3e..76eba46 100644 --- a/libs/zonefile/360/zonefile_cod8_360.cpp +++ b/libs/zonefile/360/zonefile_cod8_360.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD8_360::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/360/zonefile_cod9_360.cpp b/libs/zonefile/360/zonefile_cod9_360.cpp index 5155c1c..c944b25 100644 --- a/libs/zonefile/360/zonefile_cod9_360.cpp +++ b/libs/zonefile/360/zonefile_cod9_360.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD9_360::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod10_pc.cpp b/libs/zonefile/PC/zonefile_cod10_pc.cpp index 650d772..3cedc33 100644 --- a/libs/zonefile/PC/zonefile_cod10_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod10_pc.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD10_PC::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod11_pc.cpp b/libs/zonefile/PC/zonefile_cod11_pc.cpp index 516d83a..02969da 100644 --- a/libs/zonefile/PC/zonefile_cod11_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod11_pc.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD11_PC::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod12_pc.cpp b/libs/zonefile/PC/zonefile_cod12_pc.cpp index 28dcb7d..175bccc 100644 --- a/libs/zonefile/PC/zonefile_cod12_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod12_pc.cpp @@ -161,7 +161,7 @@ QStringList ZoneFile_COD12_PC::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod4_pc.cpp b/libs/zonefile/PC/zonefile_cod4_pc.cpp index 6359151..2b12310 100644 --- a/libs/zonefile/PC/zonefile_cod4_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod4_pc.cpp @@ -29,12 +29,13 @@ bool ZoneFile_COD4_PC::Load(const QByteArray aFileData) { void ZoneFile_COD4_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { SetSize(pParseZoneSize(aZoneFileStream)); - pParseZoneUnknownsA(aZoneFileStream); + + aZoneFileStream->skipRawData(40); SetTagCount(pParseZoneTagCount(aZoneFileStream)); pParseZoneUnknownsB(aZoneFileStream); - SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + SetRecordCount(pParseZoneRecordCount(aZoneFileStream) - 1); quint32 tagCount = GetTagCount(); if (tagCount) { @@ -159,7 +160,7 @@ QStringList ZoneFile_COD4_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; @@ -592,6 +593,9 @@ Image ZoneFile_COD4_PC::pParseAsset_Image(QDataStream *aZoneFileStream) { SoundAsset ZoneFile_COD4_PC::pParseAsset_Sound(QDataStream *aZoneFileStream) { SoundAsset result; + // TODO Reimplement proper sound parsing + return result; + qDebug() << aZoneFileStream->device()->pos(); QByteArray rootNamePtr(4, Qt::Uninitialized); @@ -1089,46 +1093,50 @@ StringTable ZoneFile_COD4_PC::pParseAsset_StringTable(QDataStream *aZoneFileStre AssetType ZoneFile_COD4_PC::AssetStrToEnum(const QString aAssetType) { const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + if (cleanedType == "1F000000") { return ASSET_RAW_FILE; - } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + } else if (cleanedType == "20000000") { return ASSET_SCRIPT_PARSE_TREE; - } else if (cleanedType == "1A000000") { // fx PARTIALLY VERIFIED + } else if (cleanedType == "19000000") { return ASSET_EFFECT; - } else if (cleanedType == "09000000") { // loaded_sound PARTIALLY VERIFIED + } else if (cleanedType == "16000000") { return ASSET_SOUND; - } else if (cleanedType == "04000000") { // x_anim PARTIALLY VERIFIED + } else if (cleanedType == "02000000") { return ASSET_ANIMATION; - } else if (cleanedType == "0C000000") { // collision_map PARTIALLY VERIFIED + } else if (cleanedType == "0B000000") { return ASSET_COLLISION_MAP; - } else if (cleanedType == "21000000") { // string_table PARTIALLY VERIFIED + } else if (cleanedType == "21000000") { return ASSET_STRING_TABLE; - } else if (cleanedType == "15000000") { // menu_file PARTIALLY VERIFIED + } else if (cleanedType == "14000000") { return ASSET_MENU; - } else if (cleanedType == "07000000") { // tech set PARTIALLY VERIFIED + } else if (cleanedType == "07000000") { return ASSET_TECH_SET; - } else if (cleanedType == "18000000") { // weapon PARTIALLY VERIFIED + } else if (cleanedType == "17000000") { return ASSET_WEAPON; - } else if (cleanedType == "11000000") { // gfx map PARTIALLY VERIFIED + } else if (cleanedType == "10000000") { return ASSET_GFX_MAP; - } else if (cleanedType == "12000000") { // light_def PARTIALLY VERIFIED + } else if (cleanedType == "12000000") { return ASSET_LIGHT_DEF; - } else if (cleanedType == "14000000") { // font PARTIALLY VERIFIED + } else if (cleanedType == "15000000") { return ASSET_FONT; - } else if (cleanedType == "05000000") { // xmodel PARTIALLY VERIFIED + } else if (cleanedType == "03000000") { return ASSET_MODEL; - } else if (cleanedType == "0D000000") { // d3dbsp PARTIALLY VERIFIED + } else if (cleanedType == "0C000000") { return ASSET_D3DBSP; - } else if (cleanedType == "06000000") { // image PARTIALLY VERIFIED + } else if (cleanedType == "06000000") { return ASSET_IMAGE; - } else if (cleanedType == "0E000000") { // game map sp PARTIALLY VERIFIED + } else if (cleanedType == "0D000000") { return ASSET_GAME_MAP_SP; - } else if (cleanedType == "0B000000") { // col map sp PARTIALLY VERIFIED + } else if (cleanedType == "0A000000") { return ASSET_COL_MAP_SP; - } else if (cleanedType == "01000000") { // physics preset PARTIALLY VERIFIED + } else if (cleanedType == "01000000") { return ASSET_PHYS_PRESET; - } else if (cleanedType == "03000000") { // destructible def PARTIALLY VERIFIED + } else if (cleanedType == "05000000") { return ASSET_DESTRUCTIBLE; + } else if (cleanedType == "18000000") { + return ASSET_LOCAL_STRING; + } else if (cleanedType == "1A000000") { + return ASSET_UI_MAP; } return ASSET_NONE; } diff --git a/libs/zonefile/PC/zonefile_cod5_pc.cpp b/libs/zonefile/PC/zonefile_cod5_pc.cpp index fc93a04..2a1ab72 100644 --- a/libs/zonefile/PC/zonefile_cod5_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod5_pc.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD5_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod6_pc.cpp b/libs/zonefile/PC/zonefile_cod6_pc.cpp index 1b2dfb6..29e99d4 100644 --- a/libs/zonefile/PC/zonefile_cod6_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod6_pc.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD6_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod7_pc.cpp b/libs/zonefile/PC/zonefile_cod7_pc.cpp index 9d491fa..a6f83bd 100644 --- a/libs/zonefile/PC/zonefile_cod7_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod7_pc.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD7_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod8_pc.cpp b/libs/zonefile/PC/zonefile_cod8_pc.cpp index 1d62c80..9b7d341 100644 --- a/libs/zonefile/PC/zonefile_cod8_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod8_pc.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD8_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PC/zonefile_cod9_pc.cpp b/libs/zonefile/PC/zonefile_cod9_pc.cpp index c4a2b83..a278b0a 100644 --- a/libs/zonefile/PC/zonefile_cod9_pc.cpp +++ b/libs/zonefile/PC/zonefile_cod9_pc.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD9_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod10_ps3.cpp b/libs/zonefile/PS3/zonefile_cod10_ps3.cpp index 243d594..8b92f1b 100644 --- a/libs/zonefile/PS3/zonefile_cod10_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod10_ps3.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD10_PS3::pParseZoneTags(QDataStream *aZoneFileStream, qui zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod11_ps3.cpp b/libs/zonefile/PS3/zonefile_cod11_ps3.cpp index 01fec6b..47f395a 100644 --- a/libs/zonefile/PS3/zonefile_cod11_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod11_ps3.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD11_PS3::pParseZoneTags(QDataStream *aZoneFileStream, qui zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod12_ps3.cpp b/libs/zonefile/PS3/zonefile_cod12_ps3.cpp index 9d6f3f1..d764d52 100644 --- a/libs/zonefile/PS3/zonefile_cod12_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod12_ps3.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD12_PS3::pParseZoneTags(QDataStream *aZoneFileStream, qui zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod4_ps3.cpp b/libs/zonefile/PS3/zonefile_cod4_ps3.cpp index 4e6243a..9cf17c4 100644 --- a/libs/zonefile/PS3/zonefile_cod4_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod4_ps3.cpp @@ -28,12 +28,13 @@ bool ZoneFile_COD4_PS3::Load(const QByteArray aFileData) { void ZoneFile_COD4_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { SetSize(pParseZoneSize(aZoneFileStream)); - pParseZoneUnknownsA(aZoneFileStream); + + aZoneFileStream->skipRawData(32); SetTagCount(pParseZoneTagCount(aZoneFileStream)); pParseZoneUnknownsB(aZoneFileStream); - SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + SetRecordCount(pParseZoneRecordCount(aZoneFileStream) - 1); quint32 tagCount = GetTagCount(); if (tagCount) { @@ -152,13 +153,13 @@ QStringList ZoneFile_COD4_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quin // Parse tags/strings before index QString zoneTag; char zoneTagChar; - for (quint32 i = 0; i < tagCount; i++) { + for (quint32 i = 0; i <= tagCount; i++) { *aZoneFileStream >> zoneTagChar; while (zoneTagChar != 0) { zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; @@ -591,6 +592,9 @@ Image ZoneFile_COD4_PS3::pParseAsset_Image(QDataStream *aZoneFileStream) { SoundAsset ZoneFile_COD4_PS3::pParseAsset_Sound(QDataStream *aZoneFileStream) { SoundAsset result; + // TODO Reimplement proper sound parsing + return result; + qDebug() << aZoneFileStream->device()->pos(); QByteArray rootNamePtr(4, Qt::Uninitialized); @@ -1088,46 +1092,28 @@ StringTable ZoneFile_COD4_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStr AssetType ZoneFile_COD4_PS3::AssetStrToEnum(const QString aAssetType) { const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED - return ASSET_RAW_FILE; - } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED - return ASSET_SCRIPT_PARSE_TREE; - } else if (cleanedType == "1A000000") { // fx PARTIALLY VERIFIED - return ASSET_EFFECT; - } else if (cleanedType == "09000000") { // loaded_sound PARTIALLY VERIFIED - return ASSET_SOUND; - } else if (cleanedType == "04000000") { // x_anim PARTIALLY VERIFIED - return ASSET_ANIMATION; - } else if (cleanedType == "0C000000") { // collision_map PARTIALLY VERIFIED - return ASSET_COLLISION_MAP; - } else if (cleanedType == "21000000") { // string_table PARTIALLY VERIFIED - return ASSET_STRING_TABLE; - } else if (cleanedType == "15000000") { // menu_file PARTIALLY VERIFIED - return ASSET_MENU; - } else if (cleanedType == "07000000") { // tech set PARTIALLY VERIFIED - return ASSET_TECH_SET; - } else if (cleanedType == "18000000") { // weapon PARTIALLY VERIFIED - return ASSET_WEAPON; - } else if (cleanedType == "11000000") { // gfx map PARTIALLY VERIFIED - return ASSET_GFX_MAP; - } else if (cleanedType == "12000000") { // light_def PARTIALLY VERIFIED - return ASSET_LIGHT_DEF; - } else if (cleanedType == "14000000") { // font PARTIALLY VERIFIED - return ASSET_FONT; - } else if (cleanedType == "05000000") { // xmodel PARTIALLY VERIFIED + if (cleanedType == "00000003") { return ASSET_MODEL; - } else if (cleanedType == "0D000000") { // d3dbsp PARTIALLY VERIFIED - return ASSET_D3DBSP; - } else if (cleanedType == "06000000") { // image PARTIALLY VERIFIED - return ASSET_IMAGE; - } else if (cleanedType == "0E000000") { // game map sp PARTIALLY VERIFIED - return ASSET_GAME_MAP_SP; - } else if (cleanedType == "0B000000") { // col map sp PARTIALLY VERIFIED + } else if (cleanedType == "00000002") { + return ASSET_ANIMATION; + } else if (cleanedType == "00000007") { + return ASSET_MATERIAL; + } else if (cleanedType == "00000009") { + return ASSET_TECH_SET; + } else if (cleanedType == "0000000C") { return ASSET_COL_MAP_SP; - } else if (cleanedType == "01000000") { // physics preset PARTIALLY VERIFIED - return ASSET_PHYS_PRESET; - } else if (cleanedType == "03000000") { // destructible def PARTIALLY VERIFIED - return ASSET_DESTRUCTIBLE; + } else if (cleanedType == "0000000E") { + return ASSET_D3DBSP; + } else if (cleanedType == "0000000F") { + return ASSET_GAME_MAP_SP; + } else if (cleanedType == "00000012") { + return ASSET_GFX_MAP; + } else if (cleanedType == "00000019") { + return ASSET_WEAPON; + } else if (cleanedType == "0000001B") { + return ASSET_EFFECT; + } else if (cleanedType == "00000018") { + return ASSET_SOUND; } return ASSET_NONE; } diff --git a/libs/zonefile/PS3/zonefile_cod5_ps3.cpp b/libs/zonefile/PS3/zonefile_cod5_ps3.cpp index 3eb2015..f97aa04 100644 --- a/libs/zonefile/PS3/zonefile_cod5_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod5_ps3.cpp @@ -158,7 +158,7 @@ QStringList ZoneFile_COD5_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod6_ps3.cpp b/libs/zonefile/PS3/zonefile_cod6_ps3.cpp index 9fb8d78..21c7506 100644 --- a/libs/zonefile/PS3/zonefile_cod6_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod6_ps3.cpp @@ -158,7 +158,7 @@ QStringList ZoneFile_COD6_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod7_ps3.cpp b/libs/zonefile/PS3/zonefile_cod7_ps3.cpp index 0386fc6..9a4c6b1 100644 --- a/libs/zonefile/PS3/zonefile_cod7_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod7_ps3.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD7_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod8_ps3.cpp b/libs/zonefile/PS3/zonefile_cod8_ps3.cpp index 00eaf6d..ec47ada 100644 --- a/libs/zonefile/PS3/zonefile_cod8_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod8_ps3.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD8_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/PS3/zonefile_cod9_ps3.cpp b/libs/zonefile/PS3/zonefile_cod9_ps3.cpp index 12ae674..abe6096 100644 --- a/libs/zonefile/PS3/zonefile_cod9_ps3.cpp +++ b/libs/zonefile/PS3/zonefile_cod9_ps3.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD9_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/Wii/zonefile_cod4_wii.cpp b/libs/zonefile/Wii/zonefile_cod4_wii.cpp index 6894d5a..d3d043f 100644 --- a/libs/zonefile/Wii/zonefile_cod4_wii.cpp +++ b/libs/zonefile/Wii/zonefile_cod4_wii.cpp @@ -21,7 +21,6 @@ bool ZoneFile_COD4_Wii::Load(const QByteArray aFileData) { // Parse data from zone file header pParseZoneHeader(&zoneFileStream); - zoneFileStream.device()->seek(zoneFileStream.device()->pos() - 1); SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); @@ -57,7 +56,7 @@ quint32 ZoneFile_COD4_Wii::pParseZoneSize(QDataStream *aZoneFileStream) { qDebug() << "Tried to open empty zone file!"; exit(-1); } - zoneFileSize += 36; + zoneFileSize += 40; return zoneFileSize; } @@ -164,9 +163,10 @@ QStringList ZoneFile_COD4_Wii::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } + *aZoneFileStream >> zoneTagChar; return tags; } @@ -186,7 +186,7 @@ QStringList ZoneFile_COD4_Wii::pParseZoneIndex(QDataStream *aZoneFileStream, qui } // Parse index & map found asset types - for (quint32 i = 0; i <= recordCount; i++) { + for (quint32 i = 0; i < recordCount; i++) { // Skip record start QByteArray rawAssetType(4, Qt::Uninitialized); aZoneFileStream->readRawData(rawAssetType.data(), 4); diff --git a/libs/zonefile/Wii/zonefile_cod7_wii.cpp b/libs/zonefile/Wii/zonefile_cod7_wii.cpp index 6ad2e54..19da359 100644 --- a/libs/zonefile/Wii/zonefile_cod7_wii.cpp +++ b/libs/zonefile/Wii/zonefile_cod7_wii.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD7_Wii::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/Wii/zonefile_cod8_wii.cpp b/libs/zonefile/Wii/zonefile_cod8_wii.cpp index 710f933..2585e96 100644 --- a/libs/zonefile/Wii/zonefile_cod8_wii.cpp +++ b/libs/zonefile/Wii/zonefile_cod8_wii.cpp @@ -164,7 +164,7 @@ QStringList ZoneFile_COD8_Wii::pParseZoneTags(QDataStream *aZoneFileStream, quin zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp b/libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp index f11bbdb..8ec25a4 100644 --- a/libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp +++ b/libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD10_WiiU::pParseZoneTags(QDataStream *aZoneFileStream, qu zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp b/libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp index 548d14c..100c0c6 100644 --- a/libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp +++ b/libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp @@ -159,7 +159,7 @@ QStringList ZoneFile_COD9_WiiU::pParseZoneTags(QDataStream *aZoneFileStream, qui zoneTag += zoneTagChar; *aZoneFileStream >> zoneTagChar; } - tags << zoneTag; + if (!zoneTag.isEmpty()) { tags << zoneTag; } zoneTag.clear(); } return tags; diff --git a/libs/zonefile/asset_structs.h b/libs/zonefile/asset_structs.h index 7d09096..26214fe 100644 --- a/libs/zonefile/asset_structs.h +++ b/libs/zonefile/asset_structs.h @@ -86,15 +86,24 @@ enum AssetType { ASSET_MODEL_MESH = 0x74, ASSET_S_ANIM = 0x75, ASSET_FONT_ICON = 0x76, - ASSET_CG_MEDIA_TABLE = 0x77 + ASSET_CG_MEDIA_TABLE = 0x77, + ASSET_SHOCK_FILE = 0x78, + ASSET_ZONE_FILE = 0x79, + ASSET_FAST_FILE = 0x80, + ASSET_SOUND_DRIVER_GLOBALS = 0x81 }; -struct LocalString { +struct Asset { + quint32 startPos; + quint32 endPos; +}; + +struct LocalString : Asset { QString string; QString alias; }; -struct RawFile { +struct RawFile : Asset { quint32 length; QString path; QString contents; @@ -183,6 +192,8 @@ struct Model { quint32 physGeomsPtr; QString modelName; + + QVector unknowns; }; struct Animation { @@ -237,9 +248,21 @@ struct StringTable { struct Image { QString name; QString materialName; + IMAGE_COMPRESSION compression; + quint32 size1; quint32 size2; - IMAGE_COMPRESSION compression; + + quint32 unknown1; + quint32 unknown2; + quint32 unknown3; + quint32 unknown4; + quint32 unknown5; + quint32 unknown6; + quint32 unknown7; + quint32 unknown8; + quint32 unknown9; + quint32 unknowna; quint32 unknownb; quint32 unknownc; @@ -253,15 +276,9 @@ struct Image { quint32 unknownk; quint32 unknownl; quint32 unknownm; - quint32 unknown1; - quint32 unknown2; - quint32 unknown3; - quint32 unknown4; - quint32 unknown5; - quint32 unknown6; - quint32 unknown7; - quint32 unknown8; - quint32 unknown9; + + int chunkCount; + QVector unknowns; }; struct Material { diff --git a/libs/zonefile/zonefile.cpp b/libs/zonefile/zonefile.cpp index 331de5b..ded7694 100644 --- a/libs/zonefile/zonefile.cpp +++ b/libs/zonefile/zonefile.cpp @@ -47,199 +47,339 @@ ZoneFile &ZoneFile::operator=(const ZoneFile &other) { QString ZoneFile::AssetEnumToStr(const AssetType aAssetType) { if (aAssetType == ASSET_LOCAL_STRING) { - return "ASSET_LOCAL_STRING"; + return "LOCAL_STRING"; } else if (aAssetType == ASSET_RAW_FILE) { - return "ASSET_RAW_FILE"; + return "RAW_FILE"; } else if (aAssetType == ASSET_SCRIPT_PARSE_TREE) { - return "ASSET_GSC_FILE"; + return "GSC_FILE"; } else if (aAssetType == ASSET_EFFECT) { - return "ASSET_EFFECT"; + return "EFFECT"; } else if (aAssetType == ASSET_SOUND) { - return "ASSET_SOUND"; + return "SOUND"; } else if (aAssetType == ASSET_ANIMATION) { - return "ASSET_ANIMATION"; + return "ANIMATION"; } else if (aAssetType == ASSET_COLLISION_MAP) { - return "ASSET_COLLISION_MAP"; + return "COLLISION_MAP"; } else if (aAssetType == ASSET_STRING_TABLE) { - return "ASSET_STRING_TABLE"; + return "STRING_TABLE"; } else if (aAssetType == ASSET_MENU) { - return "ASSET_MENU"; + return "MENU"; } else if (aAssetType == ASSET_TECH_SET) { - return "ASSET_TECH_SET"; + return "TECH_SET"; } else if (aAssetType == ASSET_WEAPON) { - return "ASSET_WEAPON"; + return "WEAPON"; } else if (aAssetType == ASSET_GFX_MAP) { - return "ASSET_GFX_MAP"; + return "GFX_MAP"; } else if (aAssetType == ASSET_LIGHT_DEF) { - return "ASSET_LIGHT_DEF"; + return "LIGHT_DEF"; } else if (aAssetType == ASSET_FONT) { - return "ASSET_FONT"; + return "FONT"; } else if (aAssetType == ASSET_MODEL) { - return "ASSET_MODEL"; + return "MODEL"; } else if (aAssetType == ASSET_D3DBSP) { - return "ASSET_D3DBSP"; + return "D3DBSP"; } else if (aAssetType == ASSET_IMAGE) { - return "ASSET_IMAGE"; + return "IMAGE"; } else if (aAssetType == ASSET_GAME_MAP_SP) { - return "ASSET_GAME_MAP_SP"; + return "GAME_MAP_SP"; } else if (aAssetType == ASSET_COL_MAP_SP) { - return "ASSET_COL_MAP_SP"; + return "COL_MAP_SP"; } else if (aAssetType == ASSET_COL_MAP_SP) { - return "ASSET_COL_MAP_SP"; + return "COL_MAP_SP"; + } else if (aAssetType == ASSET_UI_MAP) { + return "UI_MAP"; } else if (aAssetType == ASSET_DESTRUCTIBLE) { - return "ASSET_DESTRUCTIBLE"; + return "DESTRUCTIBLE"; } else if (aAssetType == ASSET_MATERIAL) { - return "ASSET_MATERIAL"; + return "MATERIAL"; } else if (aAssetType == ASSET_PHYS_PRESET) { - return "ASSET_PHYS_PRESET"; + return "PHYS_PRESET"; } else if (aAssetType == ASSET_COMPUTE_SHADER_SET) { - return "ASSET_COMPUTE_SHADER_SET"; + return "COMPUTE_SHADER_SET"; } else if (aAssetType == ASSET_STRUCTURED_TABLE) { - return "ASSET_STRUCTURED_TABLE"; + return "STRUCTURED_TABLE"; } else if (aAssetType == ASSET_LEADERBOARD_DEF) { - return "ASSET_LEADERBOARD_DEF"; + return "LEADERBOARD_DEF"; } else if (aAssetType == ASSET_DDL) { - return "ASSET_DDL"; + return "DDL"; } else if (aAssetType == ASSET_SCRIPT_PARSE_TREE) { - return "ASSET_SCRIPT_PARSE_TREE"; + return "SCRIPT_PARSE_TREE"; } else if (aAssetType == ASSET_KEY_VALUE_PAIRS) { - return "ASSET_KEY_VALUE_PAIRS"; + return "KEY_VALUE_PAIRS"; } else if (aAssetType == ASSET_SCRIPT_BUNDLE) { - return "ASSET_SCRIPT_BUNDLE"; + return "SCRIPT_BUNDLE"; } else if (aAssetType == ASSET_SCRIPT_BUNDLE_LIST) { - return "ASSET_SCRIPT_BUNDLE_LIST"; + return "SCRIPT_BUNDLE_LIST"; } else if (aAssetType == ASSET_LIGHT_DEF) { - return "ASSET_LIGHT_DEF"; + return "LIGHT_DEF"; } else if (aAssetType == ASSET_BIT_FIELD) { - return "ASSET_BIT_FIELD"; + return "BIT_FIELD"; } else if (aAssetType == ASSET_MAP_TABLE) { - return "ASSET_MAP_TABLE"; + return "MAP_TABLE"; } else if (aAssetType == ASSET_MAP_TABLE_LOADING_IMAGES) { - return "ASSET_MAP_TABLE_LOADING_IMAGES"; + return "MAP_TABLE_LOADING_IMAGES"; } else if (aAssetType == ASSET_SURFACE_SOUND_DEF) { - return "ASSET_SURFACE_SOUND_DEF"; + return "SURFACE_SOUND_DEF"; } else if (aAssetType == ASSET_SURFACE_FX_TABLE) { - return "ASSET_SURFACE_FX_TABLE"; + return "SURFACE_FX_TABLE"; } else if (aAssetType == ASSET_RUMBLE) { - return "ASSET_RUMBLE"; + return "RUMBLE"; } else if (aAssetType == ASSET_AIM_TABLE) { - return "ASSET_AIM_TABLE"; + return "AIM_TABLE"; } else if (aAssetType == ASSET_MEDAL) { - return "ASSET_MEDAL"; + return "MEDAL"; } else if (aAssetType == ASSET_MEDAL_TABLE) { - return "ASSET_MEDAL_TABLE"; + return "MEDAL_TABLE"; } else if (aAssetType == ASSET_OBJECTIVE) { - return "ASSET_OBJECTIVE"; + return "OBJECTIVE"; } else if (aAssetType == ASSET_OBJECTIVE_LIST) { - return "ASSET_OBJECTIVE_LIST"; + return "OBJECTIVE_LIST"; } else if (aAssetType == ASSET_LASER) { - return "ASSET_LASER"; + return "LASER"; } else if (aAssetType == ASSET_BEAM) { - return "ASSET_BEAM"; + return "BEAM"; } else if (aAssetType == ASSET_STREAMER_HINT) { - return "ASSET_STREAMER_HINT"; + return "STREAMER_HINT"; } else if (aAssetType == ASSET_ANIM_SELECTOR_TABLE) { - return "ASSET_ANIM_SELECTOR_TABLE"; + return "ANIM_SELECTOR_TABLE"; } else if (aAssetType == ASSET_ANIM_MAPPING_TABLE) { - return "ASSET_ANIM_MAPPING_TABLE"; + return "ANIM_MAPPING_TABLE"; } else if (aAssetType == ASSET_ANIM_STATE_MACHINE) { - return "ASSET_ANIM_STATE_MACHINE"; + return "ANIM_STATE_MACHINE"; } else if (aAssetType == ASSET_BEHAVIOR_TREE) { - return "ASSET_BEHAVIOR_TREE"; + return "BEHAVIOR_TREE"; } else if (aAssetType == ASSET_BEHAVIOR_STATE_MACHINE) { - return "ASSET_BEHAVIOR_STATE_MACHINE"; + return "BEHAVIOR_STATE_MACHINE"; } else if (aAssetType == ASSET_FOOTSTEP_TABLE) { - return "ASSET_FOOTSTEP_TABLE"; + return "FOOTSTEP_TABLE"; } else if (aAssetType == ASSET_ENTITY_FX_IMPACTS) { - return "ASSET_ENTITY_FX_IMPACTS"; + return "ENTITY_FX_IMPACTS"; } else if (aAssetType == ASSET_ENTITY_SOUND_IMPACTS) { - return "ASSET_ENTITY_SOUND_IMPACTS"; + return "ENTITY_SOUND_IMPACTS"; } else if (aAssetType == ASSET_VEHICLE_FX_DEF) { - return "ASSET_VEHICLE_FX_DEF"; + return "VEHICLE_FX_DEF"; } else if (aAssetType == ASSET_VEHICLE_SOUND_DEF) { - return "ASSET_VEHICLE_SOUND_DEF"; + return "VEHICLE_SOUND_DEF"; } else if (aAssetType == ASSET_VEHICLE) { - return "ASSET_VEHICLE"; + return "VEHICLE"; } else if (aAssetType == ASSET_VEHICLE_TRACER) { - return "ASSET_VEHICLE_TRACER"; + return "VEHICLE_TRACER"; } else if (aAssetType == ASSET_PLAYER_SOUNDS_TABLE) { - return "ASSET_PLAYER_SOUNDS_TABLE"; + return "PLAYER_SOUNDS_TABLE"; } else if (aAssetType == ASSET_PLAYER_FX_TABLE) { - return "ASSET_PLAYER_FX_TABLE"; + return "PLAYER_FX_TABLE"; } else if (aAssetType == ASSET_SHARED_WEAPON_SOUNDS) { - return "ASSET_SHARED_WEAPON_SOUNDS"; + return "SHARED_WEAPON_SOUNDS"; } else if (aAssetType == ASSET_ATTACHMENT) { - return "ASSET_ATTACHMENT"; + return "ATTACHMENT"; } else if (aAssetType == ASSET_ATTACHMENT_UNIQUE) { - return "ASSET_ATTACHMENT_UNIQUE"; + return "ATTACHMENT_UNIQUE"; } else if (aAssetType == ASSET_WEAPON_CAMO) { - return "ASSET_WEAPON_CAMO"; + return "WEAPON_CAMO"; } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE) { - return "ASSET_CUSTOMIZATION_TABLE"; + return "CUSTOMIZATION_TABLE"; } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE_FEIMAGES) { - return "ASSET_CUSTOMIZATION_TABLE_FEIMAGES"; + return "CUSTOMIZATION_TABLE_FEIMAGES"; } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE_COLOR) { - return "ASSET_CUSTOMIZATION_TABLE_COLOR"; + return "CUSTOMIZATION_TABLE_COLOR"; } else if (aAssetType == ASSET_PHYS_CONSTRAINTS) { - return "ASSET_PHYS_CONSTRAINTS"; + return "PHYS_CONSTRAINTS"; } else if (aAssetType == ASSET_DESTRUCTIBLE_DEF) { - return "ASSET_DESTRUCTIBLE_DEF"; + return "DESTRUCTIBLE_DEF"; } else if (aAssetType == ASSET_MODEL_MESH) { - return "ASSET_MODEL_MESH"; + return "MODEL_MESH"; } else if (aAssetType == ASSET_S_ANIM) { - return "ASSET_S_ANIM"; + return "S_ANIM"; } else if (aAssetType == ASSET_SOUND) { - return "ASSET_SOUND"; + return "SOUND"; } else if (aAssetType == ASSET_FONT_ICON) { - return "ASSET_FONT_ICON"; + return "FONT_ICON"; + } else if (aAssetType == ASSET_SHOCK_FILE) { + return "SHOCK_FILE"; + } else if (aAssetType == ASSET_FAST_FILE) { + return "FAST_FILE"; + } else if (aAssetType == ASSET_ZONE_FILE) { + return "ZONE_FILE"; + } else if (aAssetType == ASSET_SOUND_DRIVER_GLOBALS) { + return "SOUND_DRIVER_GLOBALS"; } - return "ASSET_UNKNOWN"; + return "UNKNOWN"; } QIcon ZoneFile::AssetTypeToIcon(const AssetType aAssetType) { - if (aAssetType == ASSET_LOCAL_STRING) { // localized string PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_StringFile.png"); - } else if (aAssetType == ASSET_RAW_FILE) { // raw_file PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_RawFile.png"); - } else if (aAssetType == ASSET_SCRIPT_PARSE_TREE) { // raw_file PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_GSCFile.png"); - } else if (aAssetType == ASSET_EFFECT) { // fx PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Effect.png"); - } else if (aAssetType == ASSET_SOUND) { // loaded_sound PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Sound.png"); - } else if (aAssetType == ASSET_ANIMATION) { // x_anim PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Animation.png"); - } else if (aAssetType == ASSET_COLLISION_MAP) { // collision_map PARTIALLY VERIFIED - //return ASSET_COLLISION_MAP; - } else if (aAssetType == ASSET_STRING_TABLE) { // string_table PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_StringTable.png"); - } else if (aAssetType == ASSET_MENU) { // menu_file PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_MenuFile.png"); - } else if (aAssetType == ASSET_TECH_SET) { // tech set PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_TechSetFile.png"); - } else if (aAssetType == ASSET_WEAPON) { // weapon PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Weapon.png"); - } else if (aAssetType == ASSET_GFX_MAP) { // gfx map PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_FXMap.png"); - } else if (aAssetType == ASSET_LIGHT_DEF) { // light_def PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_LightDef.png"); - } else if (aAssetType == ASSET_FONT) { // font PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Font.png"); - } else if (aAssetType == ASSET_MODEL) { // xmodel PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Model.png"); - } else if (aAssetType == ASSET_MATERIAL) { // xmodel PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Material.png"); - } else if (aAssetType == ASSET_D3DBSP) { // d3dbsp PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_BSP.png"); - } else if (aAssetType == ASSET_IMAGE) { // image PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Image.png"); - } else if (aAssetType == ASSET_GAME_MAP_SP) { // game map sp PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_GameMapSp.png"); - } else if (aAssetType == ASSET_COL_MAP_SP) { // col map sp PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_ColMapSp.png"); - } else if (aAssetType == ASSET_PHYS_PRESET) { // col map sp PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_PhysPreset.png"); - } else if (aAssetType == ASSET_DESTRUCTIBLE) { // col map sp PARTIALLY VERIFIED - return QIcon(":/icons/icons/Icon_Destructible.png"); + QString assetCode; + const QStringList parts = AssetEnumToStr(aAssetType).split('_'); + foreach (const QString part, parts) { + assetCode.append(part[0]); + } + if (parts.size() == 1) { + assetCode.append(parts[0][1]); + } + return Utils::CreateAssetIcon(assetCode); + + if (aAssetType == ASSET_NONE) { + return Utils::CreateAssetIcon("NO"); + } else if (aAssetType == ASSET_RAW_FILE) { + return Utils::CreateAssetIcon("RAW"); + } else if (aAssetType == ASSET_SCRIPT_PARSE_TREE) { + return Utils::CreateAssetIcon("PT"); + } else if (aAssetType == ASSET_EFFECT) { + return Utils::CreateAssetIcon("EF"); + } else if (aAssetType == ASSET_SOUND) { + return Utils::CreateAssetIcon("SN"); + } else if (aAssetType == ASSET_ANIMATION) { + return Utils::CreateAssetIcon("AN"); + } else if (aAssetType == ASSET_COLLISION_MAP) { + return Utils::CreateAssetIcon("CM"); + } else if (aAssetType == ASSET_STRING_TABLE) { + return Utils::CreateAssetIcon("ST"); + } else if (aAssetType == ASSET_MENU) { + return Utils::CreateAssetIcon("MN"); + } else if (aAssetType == ASSET_TECH_SET) { + return Utils::CreateAssetIcon("TS"); + } else if (aAssetType == ASSET_WEAPON) { + return Utils::CreateAssetIcon("WP"); + } else if (aAssetType == ASSET_GFX_MAP) { + return Utils::CreateAssetIcon("GFM"); + } else if (aAssetType == ASSET_LIGHT_DEF) { + return Utils::CreateAssetIcon("LDF"); + } else if (aAssetType == ASSET_FONT) { + return Utils::CreateAssetIcon("FN"); + } else if (aAssetType == ASSET_MODEL) { + return Utils::CreateAssetIcon("MD"); + } else if (aAssetType == ASSET_D3DBSP) { + return Utils::CreateAssetIcon("BSP"); + } else if (aAssetType == ASSET_IMAGE) { + return Utils::CreateAssetIcon("IM"); + } else if (aAssetType == ASSET_GAME_MAP_SP) { + return Utils::CreateAssetIcon("GMS"); + } else if (aAssetType == ASSET_COL_MAP_SP) { + return Utils::CreateAssetIcon("CMS"); + } else if (aAssetType == ASSET_PHYS_PRESET) { + return Utils::CreateAssetIcon("PP"); + } else if (aAssetType == ASSET_DESTRUCTIBLE) { + return Utils::CreateAssetIcon("DE"); + } else if (aAssetType == ASSET_LOCAL_STRING) { + return Utils::CreateAssetIcon("LS"); + } else if (aAssetType == ASSET_SHADER) { + return Utils::CreateAssetIcon("SH"); + } else if (aAssetType == ASSET_MP_MAP) { + return Utils::CreateAssetIcon("MM"); + } else if (aAssetType == ASSET_SP_MAP) { + return Utils::CreateAssetIcon("SM"); + } else if (aAssetType == ASSET_UI_MAP) { + return Utils::CreateAssetIcon("UM"); + } else if (aAssetType == ASSET_SND_DRIVER_GLOBALS) { + return Utils::CreateAssetIcon("DG"); + } else if (aAssetType == ASSET_AI_TYPE) { + return Utils::CreateAssetIcon("AT"); + } else if (aAssetType == ASSET_MATERIAL) { + return Utils::CreateAssetIcon("MT"); + } else if (aAssetType == ASSET_COMPUTE_SHADER_SET) { + return Utils::CreateAssetIcon("CSH"); + } else if (aAssetType == ASSET_LIGHT_DESCRIPTION) { + return Utils::CreateAssetIcon("LDS"); + } else if (aAssetType == ASSET_BIT_FIELD) { + return Utils::CreateAssetIcon("BF"); + } else if (aAssetType == ASSET_STRUCTURED_TABLE) { + return Utils::CreateAssetIcon("SDT"); + } else if (aAssetType == ASSET_LEADERBOARD_DEF) { + return Utils::CreateAssetIcon("LBD"); + } else if (aAssetType == ASSET_DDL) { + return Utils::CreateAssetIcon("DDL"); + } else if (aAssetType == ASSET_KEY_VALUE_PAIRS) { + return Utils::CreateAssetIcon("KV"); + } else if (aAssetType == ASSET_SCRIPT_BUNDLE) { + return Utils::CreateAssetIcon("SB"); + } else if (aAssetType == ASSET_SCRIPT_BUNDLE_LIST) { + return Utils::CreateAssetIcon("SBL"); + } else if (aAssetType == ASSET_MAP_TABLE) { + return Utils::CreateAssetIcon("MT"); + } else if (aAssetType == ASSET_MAP_TABLE_LOADING_IMAGES) { + return Utils::CreateAssetIcon("LI"); + } else if (aAssetType == ASSET_SURFACE_SOUND_DEF) { + return Utils::CreateAssetIcon("SSD"); + } else if (aAssetType == ASSET_SURFACE_FX_TABLE) { + return Utils::CreateAssetIcon("FT"); + } else if (aAssetType == ASSET_RUMBLE) { + return Utils::CreateAssetIcon("RM"); + } else if (aAssetType == ASSET_AIM_TABLE) { + return Utils::CreateAssetIcon("AMT"); + } else if (aAssetType == ASSET_MEDAL) { + return Utils::CreateAssetIcon("ME"); + } else if (aAssetType == ASSET_MEDAL_TABLE) { + return Utils::CreateAssetIcon("MET"); + } else if (aAssetType == ASSET_OBJECTIVE) { + return Utils::CreateAssetIcon("OB"); + } else if (aAssetType == ASSET_OBJECTIVE_LIST) { + return Utils::CreateAssetIcon("OBL"); + } else if (aAssetType == ASSET_LASER) { + return Utils::CreateAssetIcon("LS"); + } else if (aAssetType == ASSET_BEAM) { + return Utils::CreateAssetIcon("BM"); + } else if (aAssetType == ASSET_STREAMER_HINT) { + return Utils::CreateAssetIcon("SH"); + } else if (aAssetType == ASSET_ANIM_SELECTOR_TABLE) { + return Utils::CreateAssetIcon("AST"); + } else if (aAssetType == ASSET_ANIM_MAPPING_TABLE) { + return Utils::CreateAssetIcon("AMP"); + } else if (aAssetType == ASSET_ANIM_STATE_MACHINE) { + return Utils::CreateAssetIcon("ASM"); + } else if (aAssetType == ASSET_BEHAVIOR_TREE) { + return Utils::CreateAssetIcon("BT"); + } else if (aAssetType == ASSET_BEHAVIOR_STATE_MACHINE) { + return Utils::CreateAssetIcon("BSM"); + } else if (aAssetType == ASSET_FOOTSTEP_TABLE) { + return Utils::CreateAssetIcon("FT"); + } else if (aAssetType == ASSET_ENTITY_FX_IMPACTS) { + return Utils::CreateAssetIcon("FI"); + } else if (aAssetType == ASSET_ENTITY_SOUND_IMPACTS) { + return Utils::CreateAssetIcon("SI"); + } else if (aAssetType == ASSET_VEHICLE_FX_DEF) { + return Utils::CreateAssetIcon("FD"); + } else if (aAssetType == ASSET_VEHICLE_SOUND_DEF) { + return Utils::CreateAssetIcon("SDD"); + } else if (aAssetType == ASSET_VEHICLE) { + return Utils::CreateAssetIcon("VE"); + } else if (aAssetType == ASSET_VEHICLE_TRACER) { + return Utils::CreateAssetIcon("VT"); + } else if (aAssetType == ASSET_PLAYER_SOUNDS_TABLE) { + return Utils::CreateAssetIcon("SDT"); + } else if (aAssetType == ASSET_PLAYER_FX_TABLE) { + return Utils::CreateAssetIcon("FXT"); + } else if (aAssetType == ASSET_SHARED_WEAPON_SOUNDS) { + return Utils::CreateAssetIcon("SWS"); + } else if (aAssetType == ASSET_ATTACHMENT) { + return Utils::CreateAssetIcon("AT"); + } else if (aAssetType == ASSET_ATTACHMENT_UNIQUE) { + return Utils::CreateAssetIcon("AU"); + } else if (aAssetType == ASSET_WEAPON_CAMO) { + return Utils::CreateAssetIcon("WPC"); + } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE) { + return Utils::CreateAssetIcon("CT"); + } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE_FEIMAGES) { + return Utils::CreateAssetIcon("CI"); + } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE_COLOR) { + return Utils::CreateAssetIcon("CC"); + } else if (aAssetType == ASSET_PHYS_CONSTRAINTS) { + return Utils::CreateAssetIcon("PC"); + } else if (aAssetType == ASSET_DESTRUCTIBLE_DEF) { + return Utils::CreateAssetIcon("DD"); + } else if (aAssetType == ASSET_MODEL_MESH) { + return Utils::CreateAssetIcon("MM"); + } else if (aAssetType == ASSET_S_ANIM) { + return Utils::CreateAssetIcon("SA"); + } else if (aAssetType == ASSET_FONT_ICON) { + return Utils::CreateAssetIcon("FI"); + } else if (aAssetType == ASSET_CG_MEDIA_TABLE) { + return Utils::CreateAssetIcon("MT"); + } else if (aAssetType == ASSET_SHOCK_FILE) { + return Utils::CreateAssetIcon("SF"); + } else if (aAssetType == ASSET_FAST_FILE) { + return Utils::CreateAssetIcon("FF"); + } else if (aAssetType == ASSET_ZONE_FILE) { + return Utils::CreateAssetIcon("ZF"); + } else if (aAssetType == ASSET_SOUND_DRIVER_GLOBALS) { + return Utils::CreateAssetIcon("SDG"); } return QIcon(); } @@ -259,6 +399,10 @@ QString ZoneFile::GetStem() { return mStem; } +QString ZoneFile::GetBaseStem() { + return mStem.split('.').first(); +} + quint32 ZoneFile::GetSize() { return mSize; } diff --git a/libs/zonefile/zonefile.h b/libs/zonefile/zonefile.h index 30c2fc9..9d6ac53 100644 --- a/libs/zonefile/zonefile.h +++ b/libs/zonefile/zonefile.h @@ -16,13 +16,14 @@ public: virtual bool Load(const QByteArray aFileData) = 0; virtual AssetType AssetStrToEnum(const QString aAssetType) = 0; - virtual QString AssetEnumToStr(const AssetType aAssetType); - virtual QIcon AssetTypeToIcon(const AssetType aAssetType); + static QString AssetEnumToStr(const AssetType aAssetType); + static QIcon AssetTypeToIcon(const AssetType aAssetType); virtual QByteArray GetBinaryData() = 0; virtual bool SaveZoneFile(const QString aZoneFilePath); QString GetStem(); + QString GetBaseStem(); quint32 GetSize(); quint32 GetTagCount(); QStringList GetTags();