From b58561eb788fa696d075a505606083705db45855 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 3 May 2025 09:57:47 -0400 Subject: [PATCH 01/32] add some bo3 ff processing logic. --- XPlor.pro | 2 + app/app.pro | 2 + app/fastfileviewer.cpp | 2 +- app/mainwindow.cpp | 8 +- app/materialviewer.cpp | 17 +- app/xtreewidget.cpp | 8 +- app/xtreewidget.h | 1 + app/zonefileviewer.cpp | 131 ++-- app/zonefileviewer.h | 8 +- app/zonefileviewer.ui | 36 +- data/Data.qrc | 3 + data/obj/defaultactor_LOD0.gltf | 4 +- libs/core/enums.h | 19 - libs/core/utils.h | 47 -- libs/ddsfile/enums.h | 19 - libs/fastfile/fastfile.cpp | 37 +- libs/fastfile/fastfile.h | 4 +- libs/fastfile/fastfile.pro | 44 +- libs/fastfile/fastfile_cod2.cpp | 83 --- libs/fastfile/fastfile_cod2.h | 18 - libs/fastfile/fastfile_cod5.cpp | 88 --- libs/fastfile/fastfile_cod5.h | 18 - libs/fastfile/fastfile_cod7.cpp | 168 ----- libs/fastfile/fastfile_cod7.h | 18 - libs/fastfile/fastfile_cod9.cpp | 114 --- libs/fastfile/fastfile_cod9.h | 18 - libs/fastfile/fastfile_factory.h | 305 ++++++++ libs/zonefile/asset_structs.h | 92 ++- libs/zonefile/zonefile.cpp | 200 ++++- libs/zonefile/zonefile.h | 10 +- libs/zonefile/zonefile.pro | 38 +- libs/zonefile/zonefile_cod2.cpp | 1093 ---------------------------- libs/zonefile/zonefile_cod2.h | 52 -- libs/zonefile/zonefile_cod5.cpp | 1167 ------------------------------ libs/zonefile/zonefile_cod5.h | 54 -- libs/zonefile/zonefile_cod7.cpp | 1103 ---------------------------- libs/zonefile/zonefile_cod7.h | 52 -- libs/zonefile/zonefile_cod9.cpp | 1093 ---------------------------- libs/zonefile/zonefile_cod9.h | 52 -- libs/zonefile/zonefile_factory.h | 18 + tests/360/autotest_cod2_360.cpp | 51 ++ tests/360/autotest_cod5_360.cpp | 51 ++ tests/autotest_cod.h | 2 + tests/test_main.cpp | 4 +- tests/tests.pro | 9 +- 45 files changed, 926 insertions(+), 5437 deletions(-) delete mode 100644 libs/fastfile/fastfile_cod2.cpp delete mode 100644 libs/fastfile/fastfile_cod2.h delete mode 100644 libs/fastfile/fastfile_cod5.cpp delete mode 100644 libs/fastfile/fastfile_cod5.h delete mode 100644 libs/fastfile/fastfile_cod7.cpp delete mode 100644 libs/fastfile/fastfile_cod7.h delete mode 100644 libs/fastfile/fastfile_cod9.cpp delete mode 100644 libs/fastfile/fastfile_cod9.h create mode 100644 libs/fastfile/fastfile_factory.h delete mode 100644 libs/zonefile/zonefile_cod2.cpp delete mode 100644 libs/zonefile/zonefile_cod2.h delete mode 100644 libs/zonefile/zonefile_cod5.cpp delete mode 100644 libs/zonefile/zonefile_cod5.h delete mode 100644 libs/zonefile/zonefile_cod7.cpp delete mode 100644 libs/zonefile/zonefile_cod7.h delete mode 100644 libs/zonefile/zonefile_cod9.cpp delete mode 100644 libs/zonefile/zonefile_cod9.h create mode 100644 libs/zonefile/zonefile_factory.h diff --git a/XPlor.pro b/XPlor.pro index 642f704..6ab867d 100644 --- a/XPlor.pro +++ b/XPlor.pro @@ -4,3 +4,5 @@ SUBDIRS += libs \ app \ tools \ tests + +QMAKE_PRE_BUILD += make clean diff --git a/app/app.pro b/app/app.pro index 011daaf..362fc8c 100644 --- a/app/app.pro +++ b/app/app.pro @@ -70,6 +70,8 @@ app.depends += \ libs/iwifile \ libs/zonefile +QMAKE_PRE_BUILD += make clean + LIBS += \ -L$$PWD/../third_party/devil_sdk/lib/ -lDevIL -lILU -lILUT \ -L$$PWD/../third_party/zlib/lib/ -lzlib \ diff --git a/app/fastfileviewer.cpp b/app/fastfileviewer.cpp index 2fb29bb..62e7044 100644 --- a/app/fastfileviewer.cpp +++ b/app/fastfileviewer.cpp @@ -18,7 +18,7 @@ FastFileViewer::~FastFileViewer() void FastFileViewer::SetFastFile(std::shared_ptr aFastFile) { mFastFile.swap(aFastFile); - ui->label_Title->setText(mFastFile->GetStem() + ".ff"); + ui->label_Title->setText(mFastFile->GetStem()); ui->comboBox_Company->setCurrentIndex(mFastFile->GetCompany()); ui->comboBox_FileType->setCurrentIndex(mFastFile->GetType()); ui->checkBox_Signed->setChecked(mFastFile->GetSignage() == SIGNAGE_SIGNED); diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index 475cb32..565b339 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -8,6 +8,7 @@ #include "techsetviewer.h" #include "ui_mainwindow.h" #include "compression.h" +#include "fastfile_factory.h" #include "iwifile.h" #include "ddsfile.h" #include "statusbarmanager.h" @@ -268,9 +269,9 @@ MainWindow::MainWindow(QWidget *parent) fastFileViewer->SetFastFile(aFastFile); fastFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); - QString fileStem = aFastFile->GetStem() + ".ff"; + QString fileStem = aFastFile->GetStem(); for (int i = 0; i < ui->tabWidget->count(); i++) { - if (ui->tabWidget->tabText(i) == fileStem) { + if (ui->tabWidget->tabText(i) == fileStem + ".ff") { return; } } @@ -481,8 +482,7 @@ bool MainWindow::OpenFastFile(const QString aFastFilePath) { return false; } - std::shared_ptr fastFile = FastFile::Open(aFastFilePath); - fastFile->SetStem(fastFileStem); + std::shared_ptr fastFile = FastFileFactory::Create(aFastFilePath); mTreeWidget->AddFastFile(fastFile); // Open zone file after decompressing ff and writing diff --git a/app/materialviewer.cpp b/app/materialviewer.cpp index 1a97977..08064e6 100644 --- a/app/materialviewer.cpp +++ b/app/materialviewer.cpp @@ -20,18 +20,11 @@ void MaterialViewer::SetMaterial(std::shared_ptr aMaterial) { ui->lineEdit_Name->setText(aMaterial->name); ui->lineEdit_RefPtr->setText(ToHexStr(aMaterial->refNamePtr)); ui->lineEdit_RefName->setText(aMaterial->refName); - ui->lineEdit_Unknowns->setText(ToHexStr(aMaterial->unknownA[0]) - + ToHexStr(aMaterial->unknownA[1]) - + ToHexStr(aMaterial->unknownA[2]) - + ToHexStr(aMaterial->unknownA[3]) - + ToHexStr(aMaterial->unknownA[4]) - + ToHexStr(aMaterial->unknownA[5]) - + ToHexStr(aMaterial->unknownA[6]) - + ToHexStr(aMaterial->unknownA[7]) - + ToHexStr(aMaterial->unknownA[8]) - + ToHexStr(aMaterial->unknownA[9]) - + ToHexStr(aMaterial->unknownA[10]) - + ToHexStr(aMaterial->unknownA[11])); + QString unknownStr = ""; + foreach (quint32 unknownPtr, aMaterial->pointers) { + unknownStr += ToHexStr(unknownPtr) + "\n"; + } + ui->lineEdit_Unknowns->setText(unknownStr); ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[0])); ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[1])); ui->spinBox_TextureCount->setValue(aMaterial->textureCount); diff --git a/app/xtreewidget.cpp b/app/xtreewidget.cpp index 043f5e4..e4c8747 100644 --- a/app/xtreewidget.cpp +++ b/app/xtreewidget.cpp @@ -63,6 +63,12 @@ void XTreeWidget::AddFastFile(std::shared_ptr aFastFile) { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD8.png")); } else if (aFastFile->GetGame() == "COD9") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD9.png")); + } else if (aFastFile->GetGame() == "COD10") { + fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD10.png")); + } else if (aFastFile->GetGame() == "COD11") { + fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD11.png")); + } else if (aFastFile->GetGame() == "COD12") { + fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD12.png")); } AddZoneFile(aFastFile->GetZoneFile(), fastFileItem); @@ -155,7 +161,7 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt menuFileRoot->setText(0, QString("Menu %1").arg(menuIndex)); for (Menu menu : menuFile.menuDefs) { XTreeWidgetItem *menuItem = new XTreeWidgetItem(menuFileRoot); - menuItem->setText(0, menu.name); + menuItem->setText(0, menu.filePath); menuItem->setIcon(0, QIcon(":/icons/icons/Icon_MenuFile.png")); } menuIndex++; diff --git a/app/xtreewidget.h b/app/xtreewidget.h index 37e3761..24db62e 100644 --- a/app/xtreewidget.h +++ b/app/xtreewidget.h @@ -10,6 +10,7 @@ #include "zonefile.h" #include +#include class XTreeWidget : public QTreeWidget { diff --git a/app/zonefileviewer.cpp b/app/zonefileviewer.cpp index 12c48a3..6e25c04 100644 --- a/app/zonefileviewer.cpp +++ b/app/zonefileviewer.cpp @@ -6,7 +6,7 @@ ZoneFileViewer::ZoneFileViewer(QWidget *parent) , ui(new Ui::ZoneFileViewer) { ui->setupUi(this); - aZoneFile = nullptr; + mZoneFile = nullptr; ui->tableWidget_RecordCounts->setColumnCount(4); ui->tableWidget_RecordCounts->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count", "Icon" }); @@ -15,20 +15,64 @@ ZoneFileViewer::ZoneFileViewer(QWidget *parent) ui->tableWidget_RecordOrder->setColumnCount(4); ui->tableWidget_RecordOrder->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count", "Icon" }); ui->tableWidget_RecordOrder->horizontalHeader()->setStretchLastSection(true); + + connect(ui->lineEdit_TagSearch, &QLineEdit::textChanged, this, &ZoneFileViewer::SortTags); + connect(ui->tableWidget_RecordCounts, &QTableWidget::itemSelectionChanged, this, &ZoneFileViewer::HighlightRecordInOrder); } ZoneFileViewer::~ZoneFileViewer() { delete ui; } +void ZoneFileViewer::HighlightRecordInOrder() { + ui->tableWidget_RecordOrder->clearSelection(); + + foreach (auto selectedItem, ui->tableWidget_RecordCounts->selectedItems()) { + int selectedRow = selectedItem->row(); + const QString assetId = ui->tableWidget_RecordCounts->item(selectedRow, 0)->text(); + + for (int i = 0; i < ui->tableWidget_RecordOrder->rowCount(); i++) { + const QString testAssetId = ui->tableWidget_RecordOrder->item(i, 0)->text(); + if (testAssetId != assetId) { continue; } + + ui->tableWidget_RecordOrder->selectRow(i); + ui->tableWidget_RecordOrder->item(i, 0)->setSelected(true); + ui->tableWidget_RecordOrder->item(i, 1)->setSelected(true); + ui->tableWidget_RecordOrder->item(i, 2)->setSelected(true); + ui->tableWidget_RecordOrder->item(i, 3)->setSelected(true); + } + } +} + +void ZoneFileViewer::SortTags(const QString &aSearchText) { + ui->listWidget_Tags->clear(); + + const QStringList tags = mZoneFile->GetTags(); + if (aSearchText.isEmpty()) { + ui->listWidget_Tags->addItems(tags); + return; + } + + QStringList sortedTags; + foreach (const QString tag, tags) { + if (tag.contains(aSearchText)) { + sortedTags << tag; + } + } + + ui->listWidget_Tags->addItems(sortedTags); +} + void ZoneFileViewer::SetZoneFile(std::shared_ptr aZoneFile) { + mZoneFile = aZoneFile; + ui->tableWidget_RecordCounts->clearContents(); ui->tableWidget_RecordOrder->clearContents(); ui->listWidget_Tags->clear(); - const QStringList tags = aZoneFile->GetTags(); + const QStringList tags = mZoneFile->GetTags(); ui->listWidget_Tags->addItems(tags); - ui->label_Title->setText(aZoneFile->GetStem() + ".zone"); + ui->label_Title->setText(mZoneFile->GetStem() + ".zone"); if (tags.isEmpty()) { ui->groupBox_Tags->hide(); @@ -36,79 +80,62 @@ void ZoneFileViewer::SetZoneFile(std::shared_ptr aZoneFile) { ui->groupBox_Tags->show(); } - QString lastAsset = ""; - QString lastRecord = ""; - QIcon assetIcon; - int consecutiveCount = 1; - int consecutiveIndex = 0; - const QStringList records = aZoneFile->GetRecords(); QMap recordCounts = QMap(); - for (const QString &record : records) { - lastRecord = record; - if (record == "ffffffff") { break; } + QVector> assetOccurances = QVector>(); + for (const QString &record : mZoneFile->GetRecords()) { if (!recordCounts.contains(record)) { recordCounts[record] = 0; } recordCounts[record]++; - QString assetType = aZoneFile->AssetTypeToString(record); + if (!assetOccurances.isEmpty() && assetOccurances.last().first == record) { + assetOccurances.last().second++; + continue; + } + + QPair assetOccurance(record, 1); + assetOccurances << assetOccurance; + } + ui->tableWidget_RecordOrder->setRowCount(assetOccurances.size()); + + int assetIndex = 0; + foreach (auto assetOccurance, assetOccurances) { + const QString record = assetOccurance.first; + AssetType assetType = mZoneFile->AssetStrToEnum(record); + int assetCount = assetOccurance.second; + + QIcon assetIcon = mZoneFile->AssetTypeToIcon(assetType); if (assetIcon.isNull()) { qDebug() << "Icon is null for record: " << record; } - if (lastAsset.isEmpty()) { - lastAsset = assetType; - lastRecord = record; - } else if (lastAsset == assetType) { - consecutiveCount++; - } else { - ui->tableWidget_RecordOrder->setRowCount(consecutiveIndex + 1); + QTableWidgetItem *recordItem = new QTableWidgetItem(record.toUpper()); + QTableWidgetItem *recordStrItem = new QTableWidgetItem(mZoneFile->AssetEnumToStr(assetType)); + QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(assetCount)); + QTableWidgetItem *recordIconItem = new QTableWidgetItem(); + recordIconItem->setIcon(assetIcon); - QTableWidgetItem *recordItem = new QTableWidgetItem(lastRecord.toUpper()); - QTableWidgetItem *recordStrItem = new QTableWidgetItem(lastAsset); - QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(consecutiveCount)); - QTableWidgetItem *recordIconItem = new QTableWidgetItem(); - assetIcon = aZoneFile->AssetStrToIcon(lastAsset); - recordIconItem->setIcon(assetIcon); + ui->tableWidget_RecordOrder->setItem(assetIndex, 0, recordItem); + ui->tableWidget_RecordOrder->setItem(assetIndex, 1, recordStrItem); + ui->tableWidget_RecordOrder->setItem(assetIndex, 2, recordCountItem); + ui->tableWidget_RecordOrder->setItem(assetIndex, 3, recordIconItem); - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 0, recordItem); - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 1, recordStrItem); - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 2, recordCountItem); - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 3, recordIconItem); - - consecutiveCount = 1; - consecutiveIndex++; - lastAsset = assetType; - lastRecord = record; - } + assetIndex++; } - ui->tableWidget_RecordOrder->setRowCount(consecutiveIndex + 1); - - QTableWidgetItem *recordItem = new QTableWidgetItem(lastRecord.toUpper()); - QTableWidgetItem *recordStrItem = new QTableWidgetItem(lastAsset); - QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(consecutiveCount)); - QTableWidgetItem *recordIconItem = new QTableWidgetItem(); - assetIcon = aZoneFile->AssetStrToIcon(lastAsset); - recordIconItem->setIcon(assetIcon); - - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 0, recordItem); - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 1, recordStrItem); - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 2, recordCountItem); - ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 3, recordIconItem); int recordIndex = 0; for (const QString &record : recordCounts.keys()) { int recordCount = recordCounts[record]; - QString assetType = aZoneFile->AssetTypeToString(record); - assetIcon = aZoneFile->AssetStrToIcon(assetType); + AssetType assetType = mZoneFile->AssetStrToEnum(record); + QIcon assetIcon = mZoneFile->AssetTypeToIcon(assetType); if (assetIcon.isNull()) { qDebug() << "Icon is null for record: " << record; } ui->tableWidget_RecordCounts->setRowCount(recordIndex + 1); - QTableWidgetItem *recordCountStrItem = new QTableWidgetItem(assetType); + QTableWidgetItem *recordCountStrItem = new QTableWidgetItem(mZoneFile->AssetEnumToStr(assetType)); QTableWidgetItem *recordItem = new QTableWidgetItem(record.toUpper()); QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(recordCount)); QTableWidgetItem *recordIconItem = new QTableWidgetItem(); diff --git a/app/zonefileviewer.h b/app/zonefileviewer.h index e335d2c..998d319 100644 --- a/app/zonefileviewer.h +++ b/app/zonefileviewer.h @@ -19,9 +19,15 @@ public: ~ZoneFileViewer(); void SetZoneFile(std::shared_ptr aZoneFile); + +public slots: + void SortTags(const QString &aSearchText); + + void HighlightRecordInOrder(); + private: Ui::ZoneFileViewer *ui; - std::shared_ptr aZoneFile; + std::shared_ptr mZoneFile; }; #endif // ZONEFILEVIEWER_H diff --git a/app/zonefileviewer.ui b/app/zonefileviewer.ui index 7b0755a..1845ca1 100644 --- a/app/zonefileviewer.ui +++ b/app/zonefileviewer.ui @@ -61,7 +61,14 @@ - + + + QAbstractItemView::EditTrigger::NoEditTriggers + + + true + + @@ -73,7 +80,20 @@ - + + + QAbstractItemView::EditTrigger::NoEditTriggers + + + true + + + QAbstractItemView::SelectionMode::SingleSelection + + + QAbstractItemView::SelectionBehavior::SelectRows + + @@ -85,7 +105,17 @@ - + + + QAbstractItemView::EditTrigger::NoEditTriggers + + + true + + + QAbstractItemView::SelectionMode::NoSelection + + diff --git a/data/Data.qrc b/data/Data.qrc index e1c377a..b0c1755 100644 --- a/data/Data.qrc +++ b/data/Data.qrc @@ -87,5 +87,8 @@ icons/Icon_PhysPreset.png icons/Icon_Wii.png icons/Icon_WiiU.png + icons/Icon_COD10.png + icons/Icon_COD11.png + icons/Icon_COD12.png diff --git a/data/obj/defaultactor_LOD0.gltf b/data/obj/defaultactor_LOD0.gltf index b1c0e0d..f31bc03 100644 --- a/data/obj/defaultactor_LOD0.gltf +++ b/data/obj/defaultactor_LOD0.gltf @@ -234,7 +234,7 @@ "WEIGHTS_0": 6 }, "indices": 1, - "material": 0, + ASSET_MATERIAL: 0, "mode": 4 } ] @@ -250,7 +250,7 @@ "WEIGHTS_0": 12 }, "indices": 7, - "material": 0, + ASSET_MATERIAL: 0, "mode": 4 } ] diff --git a/libs/core/enums.h b/libs/core/enums.h index 92a9739..77713ab 100644 --- a/libs/core/enums.h +++ b/libs/core/enums.h @@ -650,25 +650,6 @@ enum MENU_BUTTON { APAD_RIGHT = 31 }; -enum ASSET_TYPE { - ASSET_UNKNOWN = 0, - ASSET_ANIMATION = 4, // x_anim PARTIALLY VERIFIED - ASSET_MODEL = 5, // xmodel PARTIALLY VERIFIED - ASSET_MATERIAL = 6, // material VERIFIED - ASSET_BIK_FILE = 7, // .bik file PARTIALLY VERIFIED - ASSET_SOUND = 9, // loaded_sound VERIFIED - ASSET_COLLISION_MAP = 12, // collision_map PARTIALLY VERIFIED - ASSET_SHADER = 13, // shader PARTIALLY VERIFIED - ASSET_D3DBSP_DUMP = 17, // d3dbsp dump VERIFIED - ASSET_FONT = 20, // font PARTIALLY VERIFIED - ASSET_MENU = 21, // menu_file VERIFIED - ASSET_LOCAL_STRING = 23, // localized string VERIFIED - ASSET_WEAPON = 24, // weapon VERIFIED - ASSET_EFFECT = 26, // fx VERIFIED - ASSET_RAW_FILE = 32, // raw_file VERIFIED - ASSET_STRING_TABLE = 33 // string_table PARTIALLY VERIFIED -}; - enum SHADER_TYPE { SHADER_NONE = 0x00, SHADER_PIXEL = 0x01, diff --git a/libs/core/utils.h b/libs/core/utils.h index 9ebf74c..81acd20 100644 --- a/libs/core/utils.h +++ b/libs/core/utils.h @@ -90,53 +90,6 @@ public: return false; } - /* - AssetTypeToString() - - Convert asset type string to asset desc string -*/ - static QString AssetTypeToString(const QString aAssetType) { - const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED - return "LOCAL STRING"; - } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED - return "RAW FILE"; - } else if (cleanedType == "1A000000") { // fx PARTIALLY VERIFIED - return "EFFECT"; - } else if (cleanedType == "09000000") { // loaded_sound PARTIALLY VERIFIED - return "SOUND"; - } else if (cleanedType == "04000000") { // x_anim PARTIALLY VERIFIED - return "ANIMATION"; - } else if (cleanedType == "0C000000") { // collision_map PARTIALLY VERIFIED - return "COLLISION MAP"; - } else if (cleanedType == "21000000") { // string_table PARTIALLY VERIFIED - return "STRING TABLE"; - } else if (cleanedType == "15000000") { // menu_file PARTIALLY VERIFIED - return "MENU"; - } else if (cleanedType == "07000000") { // tech set PARTIALLY VERIFIED - return "TECH SET"; - } else if (cleanedType == "18000000") { // weapon PARTIALLY VERIFIED - return "WEAPON"; - } else if (cleanedType == "11000000") { // gfx map PARTIALLY VERIFIED - return "GFX MAP"; - } else if (cleanedType == "12000000") { // light_def PARTIALLY VERIFIED - return "LIGHT DEF"; - } else if (cleanedType == "14000000") { // font PARTIALLY VERIFIED - return "FONT"; - } else if (cleanedType == "05000000") { // xmodel PARTIALLY VERIFIED - return "MODEL"; - } else if (cleanedType == "0D000000") { // d3dbsp PARTIALLY VERIFIED - return "D3DBSP"; - } else if (cleanedType == "06000000") { // image PARTIALLY VERIFIED - return "IMAGE"; - } else if (cleanedType == "0E000000") { // game map sp PARTIALLY VERIFIED - return "GAME MAP SP"; - } else if (cleanedType == "0B000000") { // col map sp PARTIALLY VERIFIED - return "COL MAP SP"; - } - return aAssetType; - } - /* LumpTypeToString() diff --git a/libs/ddsfile/enums.h b/libs/ddsfile/enums.h index b5f8204..7d5f5c0 100644 --- a/libs/ddsfile/enums.h +++ b/libs/ddsfile/enums.h @@ -648,25 +648,6 @@ enum MENU_BUTTON { APAD_RIGHT = 31 }; -enum ASSET_TYPE { - ASSET_UNKNOWN = 0, - ASSET_ANIMATION = 4, // x_anim PARTIALLY VERIFIED - ASSET_MODEL = 5, // xmodel PARTIALLY VERIFIED - ASSET_MATERIAL = 6, // material VERIFIED - ASSET_BIK_FILE = 7, // .bik file PARTIALLY VERIFIED - ASSET_SOUND = 9, // loaded_sound VERIFIED - ASSET_COLLISION_MAP = 12, // collision_map PARTIALLY VERIFIED - ASSET_SHADER = 13, // shader PARTIALLY VERIFIED - ASSET_D3DBSP_DUMP = 17, // d3dbsp dump VERIFIED - ASSET_FONT = 20, // font PARTIALLY VERIFIED - ASSET_MENU = 21, // menu_file VERIFIED - ASSET_LOCAL_STRING = 23, // localized string VERIFIED - ASSET_WEAPON = 24, // weapon VERIFIED - ASSET_EFFECT = 26, // fx VERIFIED - ASSET_RAW_FILE = 32, // raw_file VERIFIED - ASSET_STRING_TABLE = 33 // string_table PARTIALLY VERIFIED -}; - enum SHADER_TYPE { SHADER_NONE = 0x00, SHADER_PIXEL = 0x01, diff --git a/libs/fastfile/fastfile.cpp b/libs/fastfile/fastfile.cpp index 6dcdcca..33a7687 100644 --- a/libs/fastfile/fastfile.cpp +++ b/libs/fastfile/fastfile.cpp @@ -1,9 +1,6 @@ #include "fastfile.h" -#include "fastfile_cod2.h" -#include "fastfile_cod5.h" -#include "fastfile_cod7.h" -#include "fastfile_cod9.h" +#include "fastfile_factory.h" #include "logmanager.h" #include @@ -22,6 +19,10 @@ FastFile::FastFile() } +FastFile::FastFile(const QByteArray &aData) { + Q_UNUSED(aData); +} + FastFile::FastFile(FastFile &fastFile) : mStem(fastFile.GetStem()), mType(fastFile.GetType()), @@ -297,32 +298,12 @@ std::shared_ptr FastFile::Open(const QString &aFilePath) { const QString fastFileStem = aFilePath.section("/", -1, -1).section('.', 0, 0); LogManager::instance().addEntry(QString("Stem: %1").arg(fastFileStem)); - FastFile *fastFile; - bool validff = true; - if (game == "COD2") { - fastFile = new FastFile_COD2(); - } else if (game == "COD5") { - fastFile = new FastFile_COD5(); - } else if (game == "COD7") { - fastFile = new FastFile_COD7(); - } else if (game == "COD9") { - fastFile = new FastFile_COD9(); - } else { - validff = false; - } + std::shared_ptr fastFile = FastFileFactory::Create(data); - LogManager::instance().addLine(); + fastFile->SetCompany(company); + fastFile->SetStem(fastFileStem); - if (validff) { - fastFile->SetCompany(company); - fastFile->SetStem(fastFileStem); - fastFile->Load(data); - return std::unique_ptr(fastFile); - } - - - // Open zone file after decompressing ff and writing - return nullptr; + return fastFile; } bool FastFile::ExportFastFile(const QString aFastFilePath) { QFile fastFile(aFastFilePath); diff --git a/libs/fastfile/fastfile.h b/libs/fastfile/fastfile.h index a1de1a2..553f4ec 100644 --- a/libs/fastfile/fastfile.h +++ b/libs/fastfile/fastfile.h @@ -6,12 +6,14 @@ #include #include -#include + +class ZoneFile; class FastFile { public: FastFile(); + FastFile(const QByteArray& aData); FastFile(FastFile &fastFile); ~FastFile(); diff --git a/libs/fastfile/fastfile.pro b/libs/fastfile/fastfile.pro index 9729134..63ec0f0 100644 --- a/libs/fastfile/fastfile.pro +++ b/libs/fastfile/fastfile.pro @@ -3,18 +3,37 @@ TEMPLATE = lib CONFIG += staticlib c++17 SOURCES += \ - fastfile_cod2.cpp \ - fastfile_cod5.cpp \ - fastfile_cod7.cpp \ - fastfile_cod9.cpp \ - fastfile.cpp + fastfile.cpp \ + 360/fastfile_cod2_360.cpp \ + 360/fastfile_cod5_360.cpp \ + 360/fastfile_cod7_360.cpp \ + 360/fastfile_cod9_360.cpp \ + PS3/fastfile_cod5_ps3.cpp \ + PS3/fastfile_cod7_ps3.cpp \ + PS3/fastfile_cod9_ps3.cpp \ + PC/fastfile_cod5_pc.cpp \ + PC/fastfile_cod7_pc.cpp \ + PC/fastfile_cod9_pc.cpp \ + PC/fastfile_cod12_pc.cpp \ + Wii/fastfile_cod7_wii.cpp \ + WiiU/fastfile_cod9_wiiu.cpp HEADERS += \ fastfile.h \ - fastfile_cod2.h \ - fastfile_cod5.h \ - fastfile_cod7.h \ - fastfile_cod9.h + 360/fastfile_cod2_360.h \ + 360/fastfile_cod5_360.h \ + 360/fastfile_cod7_360.h \ + 360/fastfile_cod9_360.h \ + PS3/fastfile_cod5_ps3.h \ + PS3/fastfile_cod7_ps3.h \ + PS3/fastfile_cod9_ps3.h \ + PC/fastfile_cod5_pc.h \ + PC/fastfile_cod7_pc.h \ + PC/fastfile_cod9_pc.h \ + PC/fastfile_cod12_pc.h \ + Wii/fastfile_cod7_wii.h \ + WiiU/fastfile_cod9_wiiu.h \ + fastfile_factory.h LIBS += \ -L$$OUT_PWD/../libs/core -lcore \ @@ -26,7 +45,12 @@ INCLUDEPATH += \ $$PWD/../core \ $$PWD/../compression \ $$PWD/../encryption \ - $$PWD/../zonefile + $$PWD/../zonefile \ + $$PWD/../zonefile/360 \ + $$PWD/../zonefile/PC \ + $$PWD/../zonefile/PS3 \ + $$PWD/../zonefile/Wii \ + $$PWD/../zonefile/WiiU DEPENDPATH += \ $$PWD/../core \ diff --git a/libs/fastfile/fastfile_cod2.cpp b/libs/fastfile/fastfile_cod2.cpp deleted file mode 100644 index 8c58687..0000000 --- a/libs/fastfile/fastfile_cod2.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "fastfile_cod2.h" - -#include "utils.h" -#include "compression.h" -#include "zonefile_cod2.h" - -#include -#include - -FastFile_COD2::FastFile_COD2() { - -} - -FastFile_COD2::~FastFile_COD2() { - -} - -QByteArray FastFile_COD2::GetBinaryData() { - return QByteArray(); -} - -bool FastFile_COD2::Load(const QString aFilePath) { - if (aFilePath.isEmpty()) { - return false; - } - - // Check fastfile can be read - QFile *file = new QFile(aFilePath); - if (!file->open(QIODevice::ReadOnly)) { - qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); - return false; - } - - // Decompress fastfile and close - const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); - qDebug() << "fastFileStem: " << fastFileStem; - SetStem(fastFileStem); - if (!Load(file->readAll())) { - qDebug() << "Error: Failed to load fastfile: " << fastFileStem; - return false; - } - - file->close(); - - // Open zone file after decompressing ff and writing - return true; -} - -bool FastFile_COD2::Load(const QByteArray aData) { - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - fastFileStream.setByteOrder(QDataStream::LittleEndian); - - // Parse header values. - SetCompany(COMPANY_INFINITY_WARD); - SetType(FILETYPE_FAST_FILE); - SetSignage(SIGNAGE_UNSIGNED); - SetMagic(0); - SetVersion(0); - SetPlatform("360"); - SetGame("COD2"); - - Utils::ReadUntilHex(&fastFileStream, "78"); - QByteArray compressedData = aData.mid(fastFileStream.device()->pos()); - QByteArray decompressedData = Compression::DecompressZLIB(compressedData); - - QDir exportsDir(QDir::currentPath()); - exportsDir.mkdir("exports"); - - QFile testFile("exports/" + GetStem() + ".zone"); - if(testFile.open(QIODevice::WriteOnly)) { - testFile.write(decompressedData); - testFile.close(); - } - - // Load the zone file with the decompressed data (using an Xbox platform flag). - ZoneFile_COD2 zoneFile; - zoneFile.SetStem(GetStem()); - zoneFile.Load(decompressedData, FF_PLATFORM_XBOX); - SetZoneFile(std::make_shared(zoneFile)); - - return true; -} diff --git a/libs/fastfile/fastfile_cod2.h b/libs/fastfile/fastfile_cod2.h deleted file mode 100644 index 91adfe9..0000000 --- a/libs/fastfile/fastfile_cod2.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FASTFILE_COD2_H -#define FASTFILE_COD2_H - -#include "fastfile.h" - -class FastFile_COD2 : public FastFile -{ -public: - FastFile_COD2(); - ~FastFile_COD2(); - - QByteArray GetBinaryData() override; - - bool Load(const QString aFilePath) override; - bool Load(const QByteArray aData) override; -}; - -#endif // FASTFILE_COD2_H diff --git a/libs/fastfile/fastfile_cod5.cpp b/libs/fastfile/fastfile_cod5.cpp deleted file mode 100644 index 50d11f2..0000000 --- a/libs/fastfile/fastfile_cod5.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "fastfile_cod5.h" -#include "zonefile_cod5.h" - -#include "utils.h" -#include "compression.h" -#include "statusbarmanager.h" - -#include -#include - -FastFile_COD5::FastFile_COD5() { - -} - -FastFile_COD5::~FastFile_COD5() { - -} - -QByteArray FastFile_COD5::GetBinaryData() { - return QByteArray(); -} - -bool FastFile_COD5::Load(const QString aFilePath) { - StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); - - if (aFilePath.isEmpty()) { - return false; - } - - // Check fastfile can be read - QFile *file = new QFile(aFilePath); - if (!file->open(QIODevice::ReadOnly)) { - qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); - return false; - } - - // Decompress fastfile and close - const QString fastFileStem = aFilePath.section("/", -1, -1); - SetStem(fastFileStem); - if (!Load(file->readAll())) { - qDebug() << "Error: Failed to load fastfile: " << fastFileStem; - return false; - } - - file->close(); - - // Open zone file after decompressing ff and writing - return true; -} - -bool FastFile_COD5::Load(const QByteArray aData) { - StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); - QByteArray decompressedData; - - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - fastFileStream.setByteOrder(QDataStream::LittleEndian); - - // Parse header values. - SetCompany(pParseFFCompany(&fastFileStream)); - SetType(pParseFFFileType(&fastFileStream)); - SetSignage(pParseFFSignage(&fastFileStream)); - SetMagic(pParseFFMagic(&fastFileStream)); - quint32 version = pParseFFVersion(&fastFileStream); - SetVersion(version); - const QString platformStr = pCalculateFFPlatform(version); - SetPlatform(platformStr); - SetGame("COD5"); - - // For COD5, simply decompress from offset 12. - decompressedData = Compression::DecompressZLIB(aData.mid(12)); - - Utils::ExportData(GetStem() + ".zone", decompressedData); - - FF_PLATFORM platform = FF_PLATFORM_NONE; - if (platformStr == "PC") { - platform = FF_PLATFORM_PC; - } else if (platformStr == "360") { - platform = FF_PLATFORM_XBOX; - } - - ZoneFile_COD5 zoneFile; - zoneFile.SetStem(GetStem()); - zoneFile.Load(decompressedData, platform); - SetZoneFile(std::make_shared(zoneFile)); - - return true; -} diff --git a/libs/fastfile/fastfile_cod5.h b/libs/fastfile/fastfile_cod5.h deleted file mode 100644 index 0622ce3..0000000 --- a/libs/fastfile/fastfile_cod5.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FASTFILE_COD5_H -#define FASTFILE_COD5_H - -#include "fastfile.h" - -class FastFile_COD5 : public FastFile -{ -public: - FastFile_COD5(); - ~FastFile_COD5(); - - QByteArray GetBinaryData() override; - - bool Load(const QString aFilePath) override; - bool Load(const QByteArray aData) override; -}; - -#endif // FASTFILE_COD5_H diff --git a/libs/fastfile/fastfile_cod7.cpp b/libs/fastfile/fastfile_cod7.cpp deleted file mode 100644 index 92f34c2..0000000 --- a/libs/fastfile/fastfile_cod7.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "fastfile_cod7.h" -#include "zonefile_cod7.h" - -#include "utils.h" -#include "compression.h" -#include "encryption.h" - -#include -#include - -FastFile_COD7::FastFile_COD7() { - -} - -FastFile_COD7::~FastFile_COD7() { - -} - -QByteArray FastFile_COD7::GetBinaryData() { - return QByteArray(); -} - -bool FastFile_COD7::Load(const QString aFilePath) { - if (aFilePath.isEmpty()) { - return false; - } - - // Check fastfile can be read - QFile *file = new QFile(aFilePath); - if (!file->open(QIODevice::ReadOnly)) { - qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); - return false; - } - - // Decompress fastfile and close - const QString fastFileStem = aFilePath.section("/", -1, -1); - SetStem(fastFileStem); - if (!Load(file->readAll())) { - qDebug() << "Error: Failed to load fastfile: " << fastFileStem; - return false; - } - - file->close(); - - // Open zone file after decompressing ff and writing - return true; -} - -bool FastFile_COD7::Load(const QByteArray aData) { - QByteArray decompressedData; - - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - fastFileStream.setByteOrder(QDataStream::LittleEndian); - - // Parse header values. - SetCompany(pParseFFCompany(&fastFileStream)); - SetType(pParseFFFileType(&fastFileStream)); - SetSignage(pParseFFSignage(&fastFileStream)); - SetMagic(pParseFFMagic(&fastFileStream)); - quint32 version = pParseFFVersion(&fastFileStream); - SetVersion(version); - SetPlatform(pCalculateFFPlatform(version)); - SetGame("COD7"); - - // Load the zone file with the decompressed data (using an Xbox platform flag). - ZoneFile_COD7 zoneFile; - zoneFile.SetStem(GetStem()); - - // For COD7/COD9, use BigEndian. - fastFileStream.setByteOrder(QDataStream::BigEndian); - if (GetPlatform() == "PC") { - fastFileStream.setByteOrder(QDataStream::LittleEndian); - - // Select key based on game. - QByteArray key; - fastFileStream.skipRawData(4); - if (GetPlatform() == "360") { - key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); - } else if (GetPlatform() == "PS3") { - key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); - // or - // key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370"); - } - - // Read the 8-byte magic. - QByteArray fileMagic(8, Qt::Uninitialized); - fastFileStream.readRawData(fileMagic.data(), 8); - if (fileMagic != "PHEEBs71") { - qWarning() << "Invalid fast file magic!"; - return false; - } - fastFileStream.skipRawData(4); - - // Read IV table name (32 bytes). - QByteArray fileName(32, Qt::Uninitialized); - fastFileStream.readRawData(fileName.data(), 32); - - // Build the IV table from the fileName. - QByteArray ivTable = Encryption::InitIVTable(fileName); - - // Skip the RSA signature (256 bytes). - QByteArray rsaSignature(256, Qt::Uninitialized); - fastFileStream.readRawData(rsaSignature.data(), 256); - - // Now the stream should be positioned at 0x13C, where sections begin. - int sectionIndex = 0; - while (true) { - qint32 sectionSize = 0; - fastFileStream >> sectionSize; - qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize - << "Pos:" << fastFileStream.device()->pos(); - if (sectionSize == 0) - break; - - // Read the section data. - QByteArray sectionData; - sectionData.resize(sectionSize); - fastFileStream.readRawData(sectionData.data(), sectionSize); - - // Compute the IV for this section. - QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); - - // Decrypt the section using Salsa20. - QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); - - // Compute SHA1 hash of the decrypted data. - QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); - - // Update the IV table based on the section hash. - Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); - - // Build a compressed data buffer by prepending the two-byte zlib header. - QByteArray compressedData; - compressedData.append(char(0x78)); - compressedData.append(char(0x01)); - compressedData.append(decData); - - decompressedData.append(Compression::DecompressZLIB(compressedData)); - - sectionIndex++; - } - - zoneFile.Load(decompressedData, FF_PLATFORM_XBOX); - } else if (GetPlatform() == "Wii") { - // For COD7, simply decompress from offset 12. - decompressedData = Compression::DecompressZLIB(aData.mid(12)); - - Utils::ExportData(GetStem() + ".zone", decompressedData); - - QDir workingDir = QDir::currentPath(); - workingDir.mkdir("exports"); - - QFile outputFile("exports/" + GetStem() + ".zone"); - if (!outputFile.open(QIODevice::WriteOnly)) { - qDebug() << "Failed to extract IPAK file."; - } - qDebug() << " - File Name: " << outputFile.fileName(); - outputFile.write(decompressedData); - outputFile.close(); - - zoneFile.Load(decompressedData, FF_PLATFORM_WII); - } - - SetZoneFile(std::make_shared(zoneFile)); - - return true; -} diff --git a/libs/fastfile/fastfile_cod7.h b/libs/fastfile/fastfile_cod7.h deleted file mode 100644 index ae2d478..0000000 --- a/libs/fastfile/fastfile_cod7.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FASTFILE_COD7_H -#define FASTFILE_COD7_H - -#include "fastfile.h" - -class FastFile_COD7 : public FastFile -{ -public: - FastFile_COD7(); - ~FastFile_COD7(); - - QByteArray GetBinaryData() override; - - bool Load(const QString aFilePath) override; - bool Load(const QByteArray aData) override; -}; - -#endif // FASTFILE_COD7_H diff --git a/libs/fastfile/fastfile_cod9.cpp b/libs/fastfile/fastfile_cod9.cpp deleted file mode 100644 index 353b0a0..0000000 --- a/libs/fastfile/fastfile_cod9.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "fastfile_cod9.h" -#include "zonefile_cod9.h" -#include "encryption.h" - -#include -#include - -FastFile_COD9::FastFile_COD9() { - -} - -FastFile_COD9::~FastFile_COD9() { - -} - -QByteArray FastFile_COD9::GetBinaryData() { - return QByteArray(); -} - -bool FastFile_COD9::Load(const QString aFilePath) { - if (aFilePath.isEmpty()) { - return false; - } - - // Check fastfile can be read - QFile *file = new QFile(aFilePath); - if (!file->open(QIODevice::ReadOnly)) { - qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); - return false; - } - - // Decompress fastfile and close - const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); - SetStem(fastFileStem); - if (!Load(file->readAll())) { - qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; - return false; - } - - file->close(); - - // Open zone file after decompressing ff and writing - return true; -} - -bool FastFile_COD9::Load(const QByteArray aData) { - QByteArray decompressedData; - - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - fastFileStream.setByteOrder(QDataStream::LittleEndian); - - // Parse header values. - SetCompany(pParseFFCompany(&fastFileStream)); - SetType(pParseFFFileType(&fastFileStream)); - SetSignage(pParseFFSignage(&fastFileStream)); - SetMagic(pParseFFMagic(&fastFileStream)); - quint32 version = pParseFFVersion(&fastFileStream); - SetVersion(version); - SetPlatform(pCalculateFFPlatform(version)); - SetGame("COD9"); - - // For COD7/COD9, use BigEndian. - fastFileStream.setByteOrder(QDataStream::BigEndian); - if (GetPlatform() == "PC") { - fastFileStream.setByteOrder(QDataStream::LittleEndian); - } - - // Select key based on game. - QByteArray key; - if (GetPlatform() == "360") { - key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); - } else if (GetPlatform() == "PC") { - key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); - } - - // Read the 8-byte magic. - QByteArray fileMagic(8, Qt::Uninitialized); - fastFileStream.readRawData(fileMagic.data(), 8); - if (fileMagic != "PHEEBs71") { - qWarning() << "Invalid fast file magic!"; - return false; - } - fastFileStream.skipRawData(4); - - // Read IV table name (32 bytes). - QByteArray fileName(32, Qt::Uninitialized); - fastFileStream.readRawData(fileName.data(), 32); - - // Skip the RSA signature (256 bytes). - QByteArray rsaSignature(256, Qt::Uninitialized); - fastFileStream.readRawData(rsaSignature.data(), 256); - - if (GetPlatform() == "360") { - //decompressedData = Compressor::cod9_decryptFastFile(aData); - } else if (GetPlatform() == "PC") { - decompressedData = Encryption::decryptFastFile(aData); - } - - // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); - if(testFile.open(QIODevice::WriteOnly)) { - testFile.write(decompressedData); - testFile.close(); - } - - // Load the zone file with the decompressed data (using an Xbox platform flag). - ZoneFile_COD9 zoneFile; - zoneFile.SetStem(GetStem()); - zoneFile.Load(decompressedData, FF_PLATFORM_PC); - SetZoneFile(std::make_shared(zoneFile)); - - return true; -} diff --git a/libs/fastfile/fastfile_cod9.h b/libs/fastfile/fastfile_cod9.h deleted file mode 100644 index fdc3d16..0000000 --- a/libs/fastfile/fastfile_cod9.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FASTFILE_COD9_H -#define FASTFILE_COD9_H - -#include "fastfile.h" - -class FastFile_COD9 : public FastFile -{ -public: - FastFile_COD9(); - ~FastFile_COD9(); - - QByteArray GetBinaryData() override; - - bool Load(const QString aFilePath) override; - bool Load(const QByteArray aData) override; -}; - -#endif // FASTFILE_COD9_H diff --git a/libs/fastfile/fastfile_factory.h b/libs/fastfile/fastfile_factory.h new file mode 100644 index 0000000..7b2186c --- /dev/null +++ b/libs/fastfile/fastfile_factory.h @@ -0,0 +1,305 @@ +#ifndef FASTFILE_FACTORY_H +#define FASTFILE_FACTORY_H + +#include "360/fastfile_cod2_360.h" +//#include "360/fastfile_cod3_360.h" +//#include "360/fastfile_cod4_360.h" +#include "360/fastfile_cod5_360.h" +//#include "360/fastfile_cod6_360.h" +#include "360/fastfile_cod7_360.h" +//#include "360/fastfile_cod8_360.h" +#include "360/fastfile_cod9_360.h" +//#include "360/fastfile_cod10_360.h" +//#include "360/fastfile_cod11_360.h" +//#include "360/fastfile_cod12_360.h" + +//#include "PS3/fastfile_cod3_ps3.h" +//#include "PS3/fastfile_cod4_ps3.h" +#include "PS3/fastfile_cod5_ps3.h" +//#include "PS3/fastfile_cod6_ps3.h" +#include "PS3/fastfile_cod7_ps3.h" +//#include "PS3/fastfile_cod8_ps3.h" +#include "PS3/fastfile_cod9_ps3.h" +//#include "PS3/fastfile_cod10_ps3.h" +//#include "PS3/fastfile_cod11_ps3.h" +//#include "PS3/fastfile_cod12_ps3.h" + +//#include "PC/fastfile_cod3_pc.h" +//#include "PC/fastfile_cod4_pc.h" +#include "PC/fastfile_cod5_pc.h" +//#include "PC/fastfile_cod6_pc.h" +#include "PC/fastfile_cod7_pc.h" +//#include "PC/fastfile_cod8_360.h" +#include "PC/fastfile_cod9_pc.h" +//#include "PC/fastfile_cod10_pc.h" +//#include "PC/fastfile_cod11_pc.h" +#include "PC/fastfile_cod12_pc.h" + +#include "Wii//fastfile_cod7_wii.h" + +#include "WiiU/fastfile_cod9_wiiu.h" +//#include "WiiU/fastfile_cod10_wiiu.h" + +#include +#include +#include +#include +#include + +class FastFile; + +enum FastFile_Platform { + PLATFORM_NONE = 0x00, + PLATFORM_PC = 0x01, + PLATFORM_360 = 0x02, + PLATFORM_PS3 = 0x03, + PLATFORM_WII = 0x04, + PLATFORM_WIIU = 0x05 +}; + +enum FastFile_Game { + GAME_NONE = 0x00, + GAME_COD2 = 0x01, + GAME_COD3 = 0x02, + GAME_COD4 = 0x03, + GAME_COD5 = 0x04, + GAME_COD6 = 0x05, + GAME_COD7 = 0x06, + GAME_COD8 = 0x07, + GAME_COD9 = 0x08, + GAME_COD10 = 0x09, + GAME_COD11 = 0x010, + GAME_COD12 = 0x011 +}; + +class FastFileFactory { +public: + static std::shared_ptr Create(const QString& aFilePath) { + QFile fastFile(aFilePath); + if (!fastFile.open(QIODevice::ReadOnly)) { + qDebug() << "Factory failed to open fast file: " << aFilePath; + return nullptr; + } + + const QString stem = aFilePath.split('/').last().split('.').first(); + const QByteArray data = fastFile.readAll(); + std::shared_ptr resultFF = nullptr; + if (pGetPlatform(data) == PLATFORM_360) { + if (pGetGame(data) == GAME_COD2) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD3) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD4) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD5) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD6) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD7) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD8) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD9) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD10) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD11) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD12) { + //resultFF = std::make_shared(aFilePath); + } + } else if (pGetPlatform(data) == PLATFORM_PC) { + if (pGetGame(data) == GAME_COD3) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD4) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD5) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD6) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD7) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD8) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD9) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD10) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD11) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD12) { + resultFF = std::make_shared(aFilePath); + } + } else if (pGetPlatform(data) == PLATFORM_PS3) { + if (pGetGame(data) == GAME_COD3) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD4) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD5) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD6) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD7) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD8) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD9) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD10) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD11) { + //resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD12) { + //resultFF = std::make_shared(aFilePath); + } + } else if (pGetPlatform(data) == PLATFORM_WII) { + if (pGetGame(data) == GAME_COD7) { + resultFF = std::make_shared(aFilePath); + } + } else if (pGetPlatform(data) == PLATFORM_WIIU) { + if (pGetGame(data) == GAME_COD9) { + resultFF = std::make_shared(aFilePath); + } else if (pGetGame(data) == GAME_COD10) { + //resultFF = std::make_shared(aFilePath); + } + } + return resultFF; + } + static std::shared_ptr Create(const QByteArray& aData, const QString aStem = "no_name") { + std::shared_ptr resultFF = nullptr; + if (pGetPlatform(aData) == PLATFORM_360) { + if (pGetGame(aData) == GAME_COD2) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD3) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD4) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD5) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD6) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD7) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD8) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD9) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD10) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD11) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD12) { + //resultFF = std::make_shared(data); + } + } else if (pGetPlatform(aData) == PLATFORM_PC) { + if (pGetGame(aData) == GAME_COD3) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD4) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD5) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD6) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD7) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD8) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD9) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD10) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD11) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD12) { + //resultFF = std::make_shared(data); + } + } else if (pGetPlatform(aData) == PLATFORM_PS3) { + if (pGetGame(aData) == GAME_COD3) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD4) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD5) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD6) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD7) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD8) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD9) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD10) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD11) { + //resultFF = std::make_shared(data); + } else if (pGetGame(aData) == GAME_COD12) { + //resultFF = std::make_shared(data); + } + } else if (pGetPlatform(aData) == PLATFORM_WII) { + if (pGetGame(aData) == GAME_COD7) { + resultFF = std::make_shared(aData); + } + } else if (pGetPlatform(aData) == PLATFORM_WIIU) { + if (pGetGame(aData) == GAME_COD9) { + resultFF = std::make_shared(aData); + } else if (pGetGame(aData) == GAME_COD10) { + //resultFF = std::make_shared(data); + } + } + if (resultFF) { + resultFF->SetStem(aStem); + } + return resultFF; + } +private: + static QStringList pGetDataSections(const QByteArray& aData) { + QStringList sections; + + sections << aData.mid(0, 2).toHex().toUpper(); + sections << aData.mid(2, 2).toHex().toUpper(); + sections << aData.mid(4, 2).toHex().toUpper(); + sections << aData.mid(6, 2).toHex().toUpper(); + sections << aData.mid(8, 2).toHex().toUpper(); + sections << aData.mid(10, 2).toHex().toUpper(); + + return sections; + } + + static FastFile_Platform pGetPlatform(const QByteArray& aData) { + const QStringList sections = pGetDataSections(aData); + if (sections[0] == "0000") { + return PLATFORM_360; + } else if (sections[4] == "0000") { + if (sections[5] == "0001" || + sections[5] == "0183" || + sections[5] == "010D" || + sections[5] == "01D9" || + sections[5] == "0070" || + sections[5] == "0092" || + sections[5] == "022E" || + sections[5] == "072E" || + sections[5] == "0253") { + return PLATFORM_360; + } + } else if (sections[5] == "0000") { + return PLATFORM_PC; + } + return PLATFORM_NONE; + } + + static FastFile_Game pGetGame(const QByteArray& aData) { + const QStringList sections = pGetDataSections(aData); + if (sections[0] == "0000") { + return GAME_COD2; + } else if (sections[5] == "0183") { + return GAME_COD5; + } else if (sections[0] == "5331") { + return GAME_COD11; + } else if (sections[2] == "3030") { + return GAME_COD12; + } + return GAME_NONE; + } +}; + +#endif // FASTFILE_FACTORY_H diff --git a/libs/zonefile/asset_structs.h b/libs/zonefile/asset_structs.h index 1ed6c16..7d09096 100644 --- a/libs/zonefile/asset_structs.h +++ b/libs/zonefile/asset_structs.h @@ -8,6 +8,87 @@ #include #include +enum AssetType { + ASSET_NONE = 0x00, + ASSET_RAW_FILE = 0x01, + ASSET_SCRIPT_PARSE_TREE = 0x02, + ASSET_EFFECT = 0x03, + ASSET_SOUND = 0x04, + ASSET_ANIMATION = 0x05, + ASSET_COLLISION_MAP = 0x06, + ASSET_STRING_TABLE = 0x07, + ASSET_MENU = 0x08, + ASSET_TECH_SET = 0x09, + ASSET_WEAPON = 0x10, + ASSET_GFX_MAP = 0x11, + ASSET_LIGHT_DEF = 0x12, + ASSET_FONT = 0x13, + ASSET_MODEL = 0x14, + ASSET_D3DBSP = 0x15, + ASSET_IMAGE = 0x16, + ASSET_GAME_MAP_SP = 0x17, + ASSET_COL_MAP_SP = 0x18, + ASSET_PHYS_PRESET = 0x19, + ASSET_DESTRUCTIBLE = 0x20, + ASSET_LOCAL_STRING = 0x21, + ASSET_SHADER = 0x22, + ASSET_MP_MAP = 0x23, + ASSET_SP_MAP = 0x24, + ASSET_UI_MAP = 0x25, + ASSET_SND_DRIVER_GLOBALS = 0x26, + ASSET_AI_TYPE = 0x27, + ASSET_MATERIAL = 0x28, + ASSET_COMPUTE_SHADER_SET = 0x29, + ASSET_LIGHT_DESCRIPTION = 0x30, + ASSET_BIT_FIELD = 0x31, + ASSET_STRUCTURED_TABLE = 0x32, + ASSET_LEADERBOARD_DEF = 0x33, + ASSET_DDL = 0x34, + ASSET_KEY_VALUE_PAIRS = 0x35, + ASSET_SCRIPT_BUNDLE = 0x36, + ASSET_SCRIPT_BUNDLE_LIST = 0x37, + ASSET_MAP_TABLE = 0x38, + ASSET_MAP_TABLE_LOADING_IMAGES = 0x39, + ASSET_SURFACE_SOUND_DEF = 0x40, + ASSET_SURFACE_FX_TABLE = 0x41, + ASSET_RUMBLE = 0x42, + ASSET_AIM_TABLE = 0x43, + ASSET_MEDAL = 0x44, + ASSET_MEDAL_TABLE = 0x45, + ASSET_OBJECTIVE = 0x46, + ASSET_OBJECTIVE_LIST = 0x47, + ASSET_LASER = 0x48, + ASSET_BEAM = 0x49, + ASSET_STREAMER_HINT = 0x50, + ASSET_ANIM_SELECTOR_TABLE = 0x51, + ASSET_ANIM_MAPPING_TABLE = 0x52, + ASSET_ANIM_STATE_MACHINE = 0x53, + ASSET_BEHAVIOR_TREE = 0x54, + ASSET_BEHAVIOR_STATE_MACHINE = 0x55, + ASSET_FOOTSTEP_TABLE = 0x56, + ASSET_ENTITY_FX_IMPACTS = 0x57, + ASSET_ENTITY_SOUND_IMPACTS = 0x58, + ASSET_VEHICLE_FX_DEF = 0x59, + ASSET_VEHICLE_SOUND_DEF = 0x60, + ASSET_VEHICLE = 0x61, + ASSET_VEHICLE_TRACER = 0x62, + ASSET_PLAYER_SOUNDS_TABLE = 0x63, + ASSET_PLAYER_FX_TABLE = 0x64, + ASSET_SHARED_WEAPON_SOUNDS = 0x65, + ASSET_ATTACHMENT = 0x66, + ASSET_ATTACHMENT_UNIQUE = 0x67, + ASSET_WEAPON_CAMO = 0x68, + ASSET_CUSTOMIZATION_TABLE = 0x69, + ASSET_CUSTOMIZATION_TABLE_FEIMAGES = 0x70, + ASSET_CUSTOMIZATION_TABLE_COLOR = 0x71, + ASSET_PHYS_CONSTRAINTS = 0x72, + ASSET_DESTRUCTIBLE_DEF = 0x73, + ASSET_MODEL_MESH = 0x74, + ASSET_S_ANIM = 0x75, + ASSET_FONT_ICON = 0x76, + ASSET_CG_MEDIA_TABLE = 0x77 +}; + struct LocalString { QString string; QString alias; @@ -19,6 +100,12 @@ struct RawFile { QString contents; }; +struct GscFile { + quint64 length; + QString path; + QString contents; +}; + struct TechSet { QString name; bool hasShaders = false; @@ -178,11 +265,11 @@ struct Image { }; struct Material { - quint32 namePtr; + qint32 namePtr; QString name; quint32 refNamePtr; QString refName; - quint8 unknownA[12]; + QVector pointers; quint32 stateBits[2]; quint16 textureCount; quint16 constCount; @@ -353,6 +440,7 @@ struct SoundAsset { struct AssetMap { QVector localStrings; QVector rawFiles; + QVector gscFiles; //QVector phyPresets; QVector models; QVector materials; diff --git a/libs/zonefile/zonefile.cpp b/libs/zonefile/zonefile.cpp index ac9aae8..331de5b 100644 --- a/libs/zonefile/zonefile.cpp +++ b/libs/zonefile/zonefile.cpp @@ -44,49 +44,201 @@ ZoneFile &ZoneFile::operator=(const ZoneFile &other) { return *this; } -QIcon ZoneFile::AssetStrToIcon(const QString aAssetStr) { - const QString cleanedType = aAssetStr.toUpper(); - if (cleanedType == "LOCAL STRING") { // localized string PARTIALLY VERIFIED +QString ZoneFile::AssetEnumToStr(const AssetType aAssetType) +{ + if (aAssetType == ASSET_LOCAL_STRING) { + return "ASSET_LOCAL_STRING"; + } else if (aAssetType == ASSET_RAW_FILE) { + return "ASSET_RAW_FILE"; + } else if (aAssetType == ASSET_SCRIPT_PARSE_TREE) { + return "ASSET_GSC_FILE"; + } else if (aAssetType == ASSET_EFFECT) { + return "ASSET_EFFECT"; + } else if (aAssetType == ASSET_SOUND) { + return "ASSET_SOUND"; + } else if (aAssetType == ASSET_ANIMATION) { + return "ASSET_ANIMATION"; + } else if (aAssetType == ASSET_COLLISION_MAP) { + return "ASSET_COLLISION_MAP"; + } else if (aAssetType == ASSET_STRING_TABLE) { + return "ASSET_STRING_TABLE"; + } else if (aAssetType == ASSET_MENU) { + return "ASSET_MENU"; + } else if (aAssetType == ASSET_TECH_SET) { + return "ASSET_TECH_SET"; + } else if (aAssetType == ASSET_WEAPON) { + return "ASSET_WEAPON"; + } else if (aAssetType == ASSET_GFX_MAP) { + return "ASSET_GFX_MAP"; + } else if (aAssetType == ASSET_LIGHT_DEF) { + return "ASSET_LIGHT_DEF"; + } else if (aAssetType == ASSET_FONT) { + return "ASSET_FONT"; + } else if (aAssetType == ASSET_MODEL) { + return "ASSET_MODEL"; + } else if (aAssetType == ASSET_D3DBSP) { + return "ASSET_D3DBSP"; + } else if (aAssetType == ASSET_IMAGE) { + return "ASSET_IMAGE"; + } else if (aAssetType == ASSET_GAME_MAP_SP) { + return "ASSET_GAME_MAP_SP"; + } else if (aAssetType == ASSET_COL_MAP_SP) { + return "ASSET_COL_MAP_SP"; + } else if (aAssetType == ASSET_COL_MAP_SP) { + return "ASSET_COL_MAP_SP"; + } else if (aAssetType == ASSET_DESTRUCTIBLE) { + return "ASSET_DESTRUCTIBLE"; + } else if (aAssetType == ASSET_MATERIAL) { + return "ASSET_MATERIAL"; + } else if (aAssetType == ASSET_PHYS_PRESET) { + return "ASSET_PHYS_PRESET"; + } else if (aAssetType == ASSET_COMPUTE_SHADER_SET) { + return "ASSET_COMPUTE_SHADER_SET"; + } else if (aAssetType == ASSET_STRUCTURED_TABLE) { + return "ASSET_STRUCTURED_TABLE"; + } else if (aAssetType == ASSET_LEADERBOARD_DEF) { + return "ASSET_LEADERBOARD_DEF"; + } else if (aAssetType == ASSET_DDL) { + return "ASSET_DDL"; + } else if (aAssetType == ASSET_SCRIPT_PARSE_TREE) { + return "ASSET_SCRIPT_PARSE_TREE"; + } else if (aAssetType == ASSET_KEY_VALUE_PAIRS) { + return "ASSET_KEY_VALUE_PAIRS"; + } else if (aAssetType == ASSET_SCRIPT_BUNDLE) { + return "ASSET_SCRIPT_BUNDLE"; + } else if (aAssetType == ASSET_SCRIPT_BUNDLE_LIST) { + return "ASSET_SCRIPT_BUNDLE_LIST"; + } else if (aAssetType == ASSET_LIGHT_DEF) { + return "ASSET_LIGHT_DEF"; + } else if (aAssetType == ASSET_BIT_FIELD) { + return "ASSET_BIT_FIELD"; + } else if (aAssetType == ASSET_MAP_TABLE) { + return "ASSET_MAP_TABLE"; + } else if (aAssetType == ASSET_MAP_TABLE_LOADING_IMAGES) { + return "ASSET_MAP_TABLE_LOADING_IMAGES"; + } else if (aAssetType == ASSET_SURFACE_SOUND_DEF) { + return "ASSET_SURFACE_SOUND_DEF"; + } else if (aAssetType == ASSET_SURFACE_FX_TABLE) { + return "ASSET_SURFACE_FX_TABLE"; + } else if (aAssetType == ASSET_RUMBLE) { + return "ASSET_RUMBLE"; + } else if (aAssetType == ASSET_AIM_TABLE) { + return "ASSET_AIM_TABLE"; + } else if (aAssetType == ASSET_MEDAL) { + return "ASSET_MEDAL"; + } else if (aAssetType == ASSET_MEDAL_TABLE) { + return "ASSET_MEDAL_TABLE"; + } else if (aAssetType == ASSET_OBJECTIVE) { + return "ASSET_OBJECTIVE"; + } else if (aAssetType == ASSET_OBJECTIVE_LIST) { + return "ASSET_OBJECTIVE_LIST"; + } else if (aAssetType == ASSET_LASER) { + return "ASSET_LASER"; + } else if (aAssetType == ASSET_BEAM) { + return "ASSET_BEAM"; + } else if (aAssetType == ASSET_STREAMER_HINT) { + return "ASSET_STREAMER_HINT"; + } else if (aAssetType == ASSET_ANIM_SELECTOR_TABLE) { + return "ASSET_ANIM_SELECTOR_TABLE"; + } else if (aAssetType == ASSET_ANIM_MAPPING_TABLE) { + return "ASSET_ANIM_MAPPING_TABLE"; + } else if (aAssetType == ASSET_ANIM_STATE_MACHINE) { + return "ASSET_ANIM_STATE_MACHINE"; + } else if (aAssetType == ASSET_BEHAVIOR_TREE) { + return "ASSET_BEHAVIOR_TREE"; + } else if (aAssetType == ASSET_BEHAVIOR_STATE_MACHINE) { + return "ASSET_BEHAVIOR_STATE_MACHINE"; + } else if (aAssetType == ASSET_FOOTSTEP_TABLE) { + return "ASSET_FOOTSTEP_TABLE"; + } else if (aAssetType == ASSET_ENTITY_FX_IMPACTS) { + return "ASSET_ENTITY_FX_IMPACTS"; + } else if (aAssetType == ASSET_ENTITY_SOUND_IMPACTS) { + return "ASSET_ENTITY_SOUND_IMPACTS"; + } else if (aAssetType == ASSET_VEHICLE_FX_DEF) { + return "ASSET_VEHICLE_FX_DEF"; + } else if (aAssetType == ASSET_VEHICLE_SOUND_DEF) { + return "ASSET_VEHICLE_SOUND_DEF"; + } else if (aAssetType == ASSET_VEHICLE) { + return "ASSET_VEHICLE"; + } else if (aAssetType == ASSET_VEHICLE_TRACER) { + return "ASSET_VEHICLE_TRACER"; + } else if (aAssetType == ASSET_PLAYER_SOUNDS_TABLE) { + return "ASSET_PLAYER_SOUNDS_TABLE"; + } else if (aAssetType == ASSET_PLAYER_FX_TABLE) { + return "ASSET_PLAYER_FX_TABLE"; + } else if (aAssetType == ASSET_SHARED_WEAPON_SOUNDS) { + return "ASSET_SHARED_WEAPON_SOUNDS"; + } else if (aAssetType == ASSET_ATTACHMENT) { + return "ASSET_ATTACHMENT"; + } else if (aAssetType == ASSET_ATTACHMENT_UNIQUE) { + return "ASSET_ATTACHMENT_UNIQUE"; + } else if (aAssetType == ASSET_WEAPON_CAMO) { + return "ASSET_WEAPON_CAMO"; + } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE) { + return "ASSET_CUSTOMIZATION_TABLE"; + } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE_FEIMAGES) { + return "ASSET_CUSTOMIZATION_TABLE_FEIMAGES"; + } else if (aAssetType == ASSET_CUSTOMIZATION_TABLE_COLOR) { + return "ASSET_CUSTOMIZATION_TABLE_COLOR"; + } else if (aAssetType == ASSET_PHYS_CONSTRAINTS) { + return "ASSET_PHYS_CONSTRAINTS"; + } else if (aAssetType == ASSET_DESTRUCTIBLE_DEF) { + return "ASSET_DESTRUCTIBLE_DEF"; + } else if (aAssetType == ASSET_MODEL_MESH) { + return "ASSET_MODEL_MESH"; + } else if (aAssetType == ASSET_S_ANIM) { + return "ASSET_S_ANIM"; + } else if (aAssetType == ASSET_SOUND) { + return "ASSET_SOUND"; + } else if (aAssetType == ASSET_FONT_ICON) { + return "ASSET_FONT_ICON"; + } + return "ASSET_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 (cleanedType == "RAW FILE") { // raw_file PARTIALLY VERIFIED + } else if (aAssetType == ASSET_RAW_FILE) { // raw_file PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_RawFile.png"); - } else if (cleanedType == "GSC FILE") { // raw_file PARTIALLY VERIFIED + } else if (aAssetType == ASSET_SCRIPT_PARSE_TREE) { // raw_file PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_GSCFile.png"); - } else if (cleanedType == "EFFECT") { // fx PARTIALLY VERIFIED + } else if (aAssetType == ASSET_EFFECT) { // fx PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Effect.png"); - } else if (cleanedType == "SOUND") { // loaded_sound PARTIALLY VERIFIED + } else if (aAssetType == ASSET_SOUND) { // loaded_sound PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Sound.png"); - } else if (cleanedType == "ANIMATION") { // x_anim PARTIALLY VERIFIED + } else if (aAssetType == ASSET_ANIMATION) { // x_anim PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Animation.png"); - } else if (cleanedType == "COLLISION MAP") { // collision_map PARTIALLY VERIFIED - //return "COLLISION MAP"; - } else if (cleanedType == "STRING TABLE") { // string_table PARTIALLY VERIFIED + } 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 (cleanedType == "MENU") { // menu_file PARTIALLY VERIFIED + } else if (aAssetType == ASSET_MENU) { // menu_file PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_MenuFile.png"); - } else if (cleanedType == "TECH SET") { // tech set PARTIALLY VERIFIED + } else if (aAssetType == ASSET_TECH_SET) { // tech set PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_TechSetFile.png"); - } else if (cleanedType == "WEAPON") { // weapon PARTIALLY VERIFIED + } else if (aAssetType == ASSET_WEAPON) { // weapon PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Weapon.png"); - } else if (cleanedType == "GFX MAP") { // gfx map PARTIALLY VERIFIED + } else if (aAssetType == ASSET_GFX_MAP) { // gfx map PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_FXMap.png"); - } else if (cleanedType == "LIGHT DEF") { // light_def PARTIALLY VERIFIED + } else if (aAssetType == ASSET_LIGHT_DEF) { // light_def PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_LightDef.png"); - } else if (cleanedType == "FONT") { // font PARTIALLY VERIFIED + } else if (aAssetType == ASSET_FONT) { // font PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Font.png"); - } else if (cleanedType == "MODEL") { // xmodel PARTIALLY VERIFIED + } else if (aAssetType == ASSET_MODEL) { // xmodel PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Model.png"); - } else if (cleanedType == "D3DBSP") { // d3dbsp PARTIALLY VERIFIED + } 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 (cleanedType == "IMAGE") { // image PARTIALLY VERIFIED + } else if (aAssetType == ASSET_IMAGE) { // image PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Image.png"); - } else if (cleanedType == "GAME MAP SP") { // game map sp PARTIALLY VERIFIED + } else if (aAssetType == ASSET_GAME_MAP_SP) { // game map sp PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_GameMapSp.png"); - } else if (cleanedType == "COL MAP SP") { // col map sp PARTIALLY VERIFIED + } else if (aAssetType == ASSET_COL_MAP_SP) { // col map sp PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_ColMapSp.png"); - } else if (cleanedType == "PHYS PRESET") { // col map sp PARTIALLY VERIFIED + } else if (aAssetType == ASSET_PHYS_PRESET) { // col map sp PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_PhysPreset.png"); - } else if (cleanedType == "DESTRUCTIBLE") { // col map sp PARTIALLY VERIFIED + } else if (aAssetType == ASSET_DESTRUCTIBLE) { // col map sp PARTIALLY VERIFIED return QIcon(":/icons/icons/Icon_Destructible.png"); } return QIcon(); diff --git a/libs/zonefile/zonefile.h b/libs/zonefile/zonefile.h index 1e08020..30c2fc9 100644 --- a/libs/zonefile/zonefile.h +++ b/libs/zonefile/zonefile.h @@ -14,10 +14,10 @@ public: ZoneFile(const ZoneFile &aZoneFile); ZoneFile &operator=(const ZoneFile &other); - virtual bool Load(const QByteArray aFileData, FF_PLATFORM platform = FF_PLATFORM_NONE) = 0; - virtual QString AssetTypeToString(const QString aAssetType) = 0; - - QIcon AssetStrToIcon(const QString aAssetStr); + 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); virtual QByteArray GetBinaryData() = 0; virtual bool SaveZoneFile(const QString aZoneFilePath); @@ -39,7 +39,7 @@ public: void SetAssetMap(const AssetMap aAssetMap); private slots: - virtual void pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) = 0; + virtual void pParseZoneHeader(QDataStream *aZoneFileStream) = 0; virtual quint32 pParseZoneSize(QDataStream *aZoneFileStream) = 0; virtual void pParseZoneUnknownsA(QDataStream *aZoneFileStream) = 0; virtual quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) = 0; diff --git a/libs/zonefile/zonefile.pro b/libs/zonefile/zonefile.pro index ec85195..7cc7681 100644 --- a/libs/zonefile/zonefile.pro +++ b/libs/zonefile/zonefile.pro @@ -4,24 +4,42 @@ CONFIG += staticlib c++17 SOURCES += \ zonefile.cpp \ - zonefile_cod2.cpp \ - zonefile_cod5.cpp \ - zonefile_cod7.cpp \ - zonefile_cod9.cpp + 360/zonefile_cod2_360.cpp \ + 360/zonefile_cod5_360.cpp \ + 360/zonefile_cod7_360.cpp \ + 360/zonefile_cod9_360.cpp \ + PS3/zonefile_cod5_ps3.cpp \ + PS3/zonefile_cod7_ps3.cpp \ + PS3/zonefile_cod9_ps3.cpp \ + PC/zonefile_cod5_pc.cpp \ + PC/zonefile_cod7_pc.cpp \ + PC/zonefile_cod9_pc.cpp \ + PC/zonefile_cod12_pc.cpp \ + Wii/zonefile_cod7_wii.cpp \ + WiiU/zonefile_cod9_wiiu.cpp HEADERS += \ - asset_structs.h \ zonefile.h \ - zonefile_cod2.h \ - zonefile_cod5.h \ - zonefile_cod7.h \ - zonefile_cod9.h + 360/zonefile_cod2_360.h \ + 360/zonefile_cod5_360.h \ + 360/zonefile_cod7_360.h \ + 360/zonefile_cod9_360.h \ + PS3/zonefile_cod5_ps3.h \ + PS3/zonefile_cod7_ps3.h \ + PS3/zonefile_cod9_ps3.h \ + PC/zonefile_cod5_pc.h \ + PC/zonefile_cod7_pc.h \ + PC/zonefile_cod9_pc.h \ + PC/zonefile_cod12_pc.h \ + Wii/zonefile_cod7_wii.h \ + WiiU/zonefile_cod9_wiiu.h \ + zonefile_factory.h LIBS += \ -L$$OUT_PWD/../libs/core -lcore INCLUDEPATH += \ - $$PWD/../core + $$PWD/../core \ DEPENDPATH += \ $$PWD/../core diff --git a/libs/zonefile/zonefile_cod2.cpp b/libs/zonefile/zonefile_cod2.cpp deleted file mode 100644 index 3e49715..0000000 --- a/libs/zonefile/zonefile_cod2.cpp +++ /dev/null @@ -1,1093 +0,0 @@ -#include "zonefile_cod2.h" - -#include -#include -#include - -ZoneFile_COD2::ZoneFile_COD2() -{ - -} - -ZoneFile_COD2::~ZoneFile_COD2() -{ - -} - -bool ZoneFile_COD2::Load(const QByteArray aFileData, FF_PLATFORM aPlatform) { - // Open zone file as little endian stream - QDataStream zoneFileStream(aFileData); - if (aPlatform == FF_PLATFORM_PC) { - zoneFileStream.setByteOrder(QDataStream::LittleEndian); - } else { - zoneFileStream.setByteOrder(QDataStream::BigEndian); - } - - // Parse data from zone file header - pParseZoneHeader(&zoneFileStream, aPlatform); - SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); - SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); - - return true; -} - -void ZoneFile_COD2::pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) { - Q_UNUSED(aPlatform); - - SetTagCount(pParseZoneTagCount(aZoneFileStream)); - pParseZoneUnknownsB(aZoneFileStream); - pParseZoneUnknownsC(aZoneFileStream); - SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); - - aZoneFileStream->skipRawData(4); - - quint32 tagCount = GetTagCount(); - if (tagCount) { - SetTags(pParseZoneTags(aZoneFileStream, tagCount)); - } else { - aZoneFileStream->skipRawData(4); - } -} - -quint32 ZoneFile_COD2::pParseZoneSize(QDataStream *aZoneFileStream) { - quint32 zoneFileSize; - *aZoneFileStream >> zoneFileSize; - if (zoneFileSize <= 0) { - qDebug() << "Tried to open empty zone file!"; - exit(-1); - } - zoneFileSize += 36; - return zoneFileSize; -} - -/* - ParseZoneUnknownsA() - - Parses the 1st section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD2::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); -} - -/* - ParseZoneTagCount() - - Parses the number of string tags in the zone index -*/ -quint32 ZoneFile_COD2::pParseZoneTagCount(QDataStream *aZoneFileStream) { - quint32 tagCount; - *aZoneFileStream >> tagCount; - return tagCount; -} - -/* - ParseZoneRecordCount() - - Parses the number of records in the zone index -*/ -quint32 ZoneFile_COD2::pParseZoneRecordCount(QDataStream *aZoneFileStream) { - quint32 recordCount; - *aZoneFileStream >> recordCount; - return recordCount; -} - -/* - ParseZoneUnknownsB() - - Parses the 2nd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD2::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { - // Byte 44-47: Unknown/empty? - QByteArray unknown9(4, Qt::Uninitialized); - aZoneFileStream->readRawData(unknown9.data(), 4); -} - -/* - pParseZoneUnknownsC() - - Parses the 3rd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD2::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); -} - -/* - ParseZoneTags() - - Parses the string tags ate the start of zone file -*/ -QStringList ZoneFile_COD2::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; - for (quint32 i = 0; i < tagCount; i++) { - *aZoneFileStream >> zoneTagChar; - while (zoneTagChar != 0) { - zoneTag += zoneTagChar; - *aZoneFileStream >> zoneTagChar; - } - tags << zoneTag; - zoneTag.clear(); - } - return tags; -} - -/* - ParseZoneIndex() - - Parse the binary zone index data and populate table -*/ -QStringList ZoneFile_COD2::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); - } - return result; -} - -AssetMap ZoneFile_COD2::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 QString typeStr = AssetTypeToString(typeHex); - - if (typeStr == "LOCAL STRING") { // localized string asset - result.localStrings << pParseAsset_LocalString(aZoneFileStream); - } else if (typeStr == "RAW FILE") { // gsc - auto rawFile = pParseAsset_RawFile(aZoneFileStream); - if (rawFile.length) { - result.rawFiles << rawFile; - } - } else if (typeStr == "PHYS PRESET") { // physpreset - pParseAsset_PhysPreset(aZoneFileStream); - } else if (typeStr == "MODEL") { // xmodel - result.models << pParseAsset_Model(aZoneFileStream); - } else if (typeStr == "MATERIAL") { // material - result.materials << pParseAsset_Material(aZoneFileStream); - } else if (typeStr == "SHADER") { // pixelshader - pParseAsset_Shader(aZoneFileStream); - } else if (typeStr == "TECH SET") { // techset include - result.techSets << pParseAsset_TechSet(aZoneFileStream); - } else if (typeStr == "IMAGE") { // image - result.images << pParseAsset_Image(aZoneFileStream); - } else if (typeStr == "SOUND") { // loaded_sound - result.sounds << pParseAsset_Sound(aZoneFileStream); - } else if (typeStr == "COLLISION MAP") { // col_map_mp - pParseAsset_ColMapMP(aZoneFileStream); - } else if (typeStr == "MP MAP") { // game_map_sp - pParseAsset_GameMapSP(aZoneFileStream); - } else if (typeStr == "SP MAP") { // game_map_mp - pParseAsset_GameMapMP(aZoneFileStream); - } else if (typeStr == "LIGHT DEF") { // lightdef - pParseAsset_LightDef(aZoneFileStream); - } else if (typeStr == "UI MAP") { // ui_map - pParseAsset_UIMap(aZoneFileStream); - } else if (typeStr == "SND DRIVER GLOBALS") { // snddriverglobals - pParseAsset_SNDDriverGlobals(aZoneFileStream); - } else if (typeStr == "AI TYPE") { // aitype - pParseAsset_AIType(aZoneFileStream); - } else if (typeStr == "EFFECT") { // aitype - pParseAsset_FX(aZoneFileStream); - } else if (typeStr == "ANIMATION") { // aitype - result.animations << pParseAsset_Animation(aZoneFileStream); - } else if (typeStr == "STRING TABLE") { // string_table - result.stringTables << pParseAsset_StringTable(aZoneFileStream); - } else if (typeStr == "MENU") { // string_table - result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); - } else if (typeStr == "WEAPON") { // string_table - pParseAsset_Weapon(aZoneFileStream); - } else if (typeStr == "D3DBSP DUMP") { // string_table - pParseAsset_D3DBSP(aZoneFileStream); - } else if (typeStr != "UNKNOWN") { - qDebug() << "Found bad asset type!" << typeStr; - } - } - return result; -} - -LocalString ZoneFile_COD2::pParseAsset_LocalString(QDataStream *aZoneFileStream) { - LocalString result; - - quint32 stringPtr, aliasPtr; - *aZoneFileStream >> stringPtr >> aliasPtr; - if (stringPtr == 4294967295) { - // Parse local string asset contents - QString localStr; - char localStrChar; - *aZoneFileStream >> localStrChar; - while (localStrChar != 0) { - result.string += localStrChar; - *aZoneFileStream >> localStrChar; - } - } else { - result.string = "String Ptr: " + QString::number(stringPtr); - } - - if (aliasPtr == 4294967295) { - // Parse rawfile name - QString aliasName; - char aliasNameChar; - *aZoneFileStream >> aliasNameChar; - while (aliasNameChar != 0) { - result.alias += aliasNameChar; - *aZoneFileStream >> aliasNameChar; - } - } else { - result.string = "Alias Ptr: " + QString::number(aliasPtr); - } - - return result; -} - -RawFile ZoneFile_COD2::pParseAsset_RawFile(QDataStream *aZoneFileStream) { - RawFile result; - - // Skip start separator FF FF FF FF (pointer?) - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.length; - - // Skip unknown 4 byte data - aZoneFileStream->skipRawData(4); - - // Parse rawfile path - char scriptPathChar; - *aZoneFileStream >> scriptPathChar; - while (scriptPathChar != 0) { - result.path += scriptPathChar; - *aZoneFileStream >> scriptPathChar; - } - 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; - *aZoneFileStream >> rawFileContentsChar; - } - return result; -} - -void ZoneFile_COD2::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Model ZoneFile_COD2::pParseAsset_Model(QDataStream *aZoneFileStream) { - Model result; - - qDebug() << "Model Info:"; - - *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; - - // Parse XModelLodInfo - for (int i = 1; i <= 4; i++) { - qDebug() << "- Lod Info " << 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]; - } - - *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]; - - 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; - - // Parse model name - char modelNameChar; - *aZoneFileStream >> modelNameChar; - while (modelNameChar == 0) { - *aZoneFileStream >> modelNameChar; - } - while (modelNameChar != 0) { - result.modelName += modelNameChar; - *aZoneFileStream >> modelNameChar; - } - return result; -} - -Shader ZoneFile_COD2::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; - if (rawShaderType == 65535) { // Pixel shader - type = SHADER_PIXEL; - } else if (rawShaderType == 65534) { // Vertex shader - 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; - } else if (opCode == OPCODE_Comment) { - size = (int)((instructionToken >> 16) & 0x7FFF); - } else { - size = (int)((instructionToken >> 24) & 0x0f); - } - Q_UNUSED(size); - } - - - return result; -} - -TechSet ZoneFile_COD2::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; - while (techSetNameChar != 0) { - result.name += techSetNameChar; - *aZoneFileStream >> techSetNameChar; - } - result.name.replace(",", ""); - - return result; -} - -Image ZoneFile_COD2::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->skipRawData(15 * 4); - *aZoneFileStream >> result.unknownh >> result.unknowni; - - aZoneFileStream->skipRawData(4); - *aZoneFileStream >> result.unknownj; - - aZoneFileStream->skipRawData(4); - - char materialNameChar; - *aZoneFileStream >> materialNameChar; - while (materialNameChar != 0) { - result.materialName += materialNameChar; - *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; - - 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")) { - 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; - } - - return result; -} - -Material ZoneFile_COD2::pParseAsset_Material(QDataStream *aZoneFileStream) { - Material result; - - *aZoneFileStream >> result.namePtr; - if (result.namePtr != 4294967295 && GetTagCount() > result.namePtr - 1) { - result.name = GetTags()[result.namePtr - 1]; - } - *aZoneFileStream >> result.refNamePtr; - if (result.refNamePtr != 4294967295 && GetTagCount() > result.refNamePtr - 1) { - result.refName = GetTags()[result.refNamePtr - 1]; - } - aZoneFileStream->skipRawData(12); - - *aZoneFileStream >> result.unknownA[0] >> result.unknownA[0] - >> result.unknownA[1] >> result.unknownA[2] >> result.unknownA[3] - >> result.unknownA[4] >> result.unknownA[5] >> result.unknownA[6] - >> result.unknownA[7] >> result.unknownA[8] >> result.unknownA[9] - >> result.unknownA[10] >> result.unknownA[11]; - - *aZoneFileStream >> result.stateBits[0] >> result.stateBits[1] - >> result.textureCount >> result.constCount >> result.techSetPtr - >> result.texturePtr >> result.constPtr; - - - return result; -} - -SoundAsset ZoneFile_COD2::pParseAsset_Sound(QDataStream *aZoneFileStream) { - SoundAsset result; - - qDebug() << aZoneFileStream->device()->pos(); - - QByteArray rootNamePtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(rootNamePtr.data(), 4); - qDebug() << "Root name ptr: " << (QString)rootNamePtr.toHex(); - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.count; - - if (rootNamePtr.toHex() == "ffffffff") { - // Read in sound file name - char soundNameChar; - *aZoneFileStream >> soundNameChar; - while (soundNameChar != 0) { - result.name += soundNameChar; - *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") { - qDebug() << "Tag Ptr: " << tagPtr.toHex(); - tagCount++; - } - aZoneFileStream->skipRawData(4); - - QByteArray pathPtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(pathPtr.data(), 4); - - if (pathPtr.toHex() == "ffffffff") { - qDebug() << "Path Ptr: " << pathPtr.toHex(); - resultCount++; - } - - aZoneFileStream->skipRawData(160); - } - - for (int i = 0; i < tagCount; i++) { - // Read in tag? - QString tag; - char tagChar; - *aZoneFileStream >> tagChar; - while (tagChar != 0) { - tag += tagChar; - *aZoneFileStream >> tagChar; - } - qDebug() << "Tag: " << tag; - } - - 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; - qDebug() << "- Data length: " << sound.dataLength; - - if (aliasPtr.toHex() == "ffffffff") { - // Read in sound alias name - char soundAliasChar; - *aZoneFileStream >> soundAliasChar; - while (soundAliasChar != 0) { - sound.alias += soundAliasChar; - *aZoneFileStream >> soundAliasChar; - } - qDebug() << "- Alias: " << sound.alias; - } - - if (aZoneFileStream->device()->peek(4) == "RIFF") { - sound.path = sound.alias; - sound.alias = ""; - } else if (namePtr.toHex() == "ffffffff") { - // Read in sound file path - char soundPathChar; - *aZoneFileStream >> soundPathChar; - while (soundPathChar != 0) { - sound.path += soundPathChar; - *aZoneFileStream >> soundPathChar; - } - sound.path.replace(",", ""); - qDebug() << "- Path: " << sound.path; - } - - if (sound.dataLength) { - QByteArray data(sound.dataLength, Qt::Uninitialized); - aZoneFileStream->readRawData(data.data(), sound.dataLength); - sound.data = data; - } - result.sounds.append(sound); - } - qDebug() << "- " << aZoneFileStream->device()->pos(); - - return result; -} - -void ZoneFile_COD2::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_LightDef(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_UIMap(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_AIType(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_FX(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Animation ZoneFile_COD2::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; - - // Read in x_anim file name - QString xAnimName; - char xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - while (xAnimNameChar != 0) { - result.name += xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - } - - // Parse x_anim index header - QVector sectionLengths; - for (int i = 0; i < result.numframes; i++) { - quint8 sectionlength; - *aZoneFileStream >> sectionlength; - sectionLengths.push_back(sectionlength); - // Skip padding - aZoneFileStream->skipRawData(1); - } - // Skip unknown section - aZoneFileStream->skipRawData(2 * 8); - - return result; -} - -MenuFile ZoneFile_COD2::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."; - return result; - } - for (uint i = 0; i < result.menuCount; i++) { - Menu menu; - - aZoneFileStream->skipRawData(4); // Separator - - // Read in x_anim file name - char menuFilepathChar; - *aZoneFileStream >> menuFilepathChar; - while (menuFilepathChar != 0) { - menu.filePath += menuFilepathChar; - *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; - 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; - *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA - >> 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; - - float focusColorR, focusColorG, focusColorB, focusColorA, - disabledColorR, disabledColorG, disabledColorB, disabledColorA; - *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA - >> 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; - while (menuDefNameChar != 0 && menuDefNameLen < 30) { - menuDefNameLen++; - menu.name += menuDefNameChar; - *aZoneFileStream >> menuDefNameChar; - } - - char defStringChar; - int defStringLen = 0; - *aZoneFileStream >> defStringChar; - while (defStringChar != 0 && defStringLen < 30) { - defStringLen++; - menu.definition += defStringChar; - *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; - - float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, - 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; - - 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.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; - - // 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; - *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA - >> 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; - - // 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; - //statement_s rectXExp; - //statement_s rectYExp; - //statement_s rectWExp; - //statement_s rectHExp; - //statement_s foreColorAExp; - result.menuDefs << menu; - } - return result; -} - -void ZoneFile_COD2::pParseAsset_Weapon(QDataStream *aZoneFileStream) { - //WEAPON_FILE - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD2::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { - //D3DBSP_DUMP - Q_UNUSED(aZoneFileStream); -} - -StringTable ZoneFile_COD2::pParseAsset_StringTable(QDataStream *aZoneFileStream) { - StringTable result; - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream - >> result.columnCount - >> result.rowCount; - - // Todo fix this - result.columnCount = 0; - result.rowCount = 0; - - aZoneFileStream->skipRawData(4); - - QString stringTableName; - char stringTableNameChar; - *aZoneFileStream >> stringTableNameChar; - while (stringTableNameChar != 0) { - 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") { - char leadingContentChar; - *aZoneFileStream >> leadingContentChar; - while (leadingContentChar != 0) { - leadingContent += leadingContentChar; - *aZoneFileStream >> leadingContentChar; - } - } else { - leadingContent = pointerAddr; - } - - QString content; - char contentChar; - *aZoneFileStream >> contentChar; - while (contentChar != 0) { - content += contentChar; - *aZoneFileStream >> contentChar; - } - result.content[leadingContent] = content; - } - return result; -} -// "parts", -// "model", -// "material", -// "image", -// "sound", -// "sndCurve", -// "clipMap", -// "world", -// "lightDef", -// "font", -// "menuList", -// "menu", -// "localize", -// "weapon", -// "sndDriverGlobals", -// "fx", -// "impactFx", -// "rawfile", -// "data" - -QString ZoneFile_COD2::AssetTypeToString(const QString aAssetType) { - const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "") { // localized string PARTIALLY VERIFIED - return ""; - } - return aAssetType; -} - -QByteArray ZoneFile_COD2::GetBinaryData() { - QByteArray result; - - return result; -} diff --git a/libs/zonefile/zonefile_cod2.h b/libs/zonefile/zonefile_cod2.h deleted file mode 100644 index 9d560f7..0000000 --- a/libs/zonefile/zonefile_cod2.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef ZONEFILE_COD2_H -#define ZONEFILE_COD2_H - -#include "zonefile.h" - -class ZoneFile_COD2 : public ZoneFile -{ -public: - ZoneFile_COD2(); - ~ZoneFile_COD2(); - - bool Load(const QByteArray aFileData, FF_PLATFORM aPlatform) override; - QString AssetTypeToString(const QString aAssetType); - - QByteArray GetBinaryData() override; - -protected: - void pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) override; - quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; - quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; - quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; - QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; - QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; - AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; - LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; - RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; - void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; - Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - Material pParseAsset_Material(QDataStream *aZoneFileStream) override; - Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; - TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; - Image pParseAsset_Image(QDataStream *aZoneFileStream) override; - SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; - void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; - void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; - void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; - void pParseAsset_AIType(QDataStream *aZoneFileStream) override; - void pParseAsset_FX(QDataStream *aZoneFileStream) override; - Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; - MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; - void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; - void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; - StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; -}; - -#endif // ZONEFILE_COD2_H diff --git a/libs/zonefile/zonefile_cod5.cpp b/libs/zonefile/zonefile_cod5.cpp deleted file mode 100644 index 75f9dbe..0000000 --- a/libs/zonefile/zonefile_cod5.cpp +++ /dev/null @@ -1,1167 +0,0 @@ -#include "zonefile_cod5.h" - -#include -#include -#include - -ZoneFile_COD5::ZoneFile_COD5() - : ZoneFile() { - -} - -ZoneFile_COD5::~ZoneFile_COD5() { - -} - -bool ZoneFile_COD5::Load(const QByteArray aFileData, FF_PLATFORM aPlatform) { - // Open zone file as little endian stream - QDataStream zoneFileStream(aFileData); - if (aPlatform == FF_PLATFORM_PC) { - zoneFileStream.setByteOrder(QDataStream::LittleEndian); - } else { - zoneFileStream.setByteOrder(QDataStream::BigEndian); - } - - // Parse data from zone file header - pParseZoneHeader(&zoneFileStream, aPlatform); - SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); - SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); - - return true; -} - -void ZoneFile_COD5::pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) { - Q_UNUSED(aPlatform); - - SetSize(pParseZoneSize(aZoneFileStream)); - pParseZoneUnknownsA(aZoneFileStream); - - SetTagCount(pParseZoneTagCount(aZoneFileStream)); - pParseZoneUnknownsB(aZoneFileStream); - - SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); - - quint32 tagCount = GetTagCount(); - if (tagCount) { - pParseZoneUnknownsC(aZoneFileStream); - SetTags(pParseZoneTags(aZoneFileStream, tagCount)); - } else { - aZoneFileStream->skipRawData(4); - } -} - -quint32 ZoneFile_COD5::pParseZoneSize(QDataStream *aZoneFileStream) { - quint32 zoneFileSize; - *aZoneFileStream >> zoneFileSize; - if (zoneFileSize <= 0) { - qDebug() << "Tried to open empty zone file!"; - exit(-1); - } - zoneFileSize += 36; - return zoneFileSize; -} - -/* - ParseZoneUnknownsA() - - Parses the 1st section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD5::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); -} - -/* - ParseZoneTagCount() - - Parses the number of string tags in the zone index -*/ -quint32 ZoneFile_COD5::pParseZoneTagCount(QDataStream *aZoneFileStream) { - quint32 tagCount; - *aZoneFileStream >> tagCount; - return tagCount; -} - -/* - ParseZoneRecordCount() - - Parses the number of records in the zone index -*/ -quint32 ZoneFile_COD5::pParseZoneRecordCount(QDataStream *aZoneFileStream) { - quint32 recordCount; - *aZoneFileStream >> recordCount; - return recordCount; -} - -/* - ParseZoneUnknownsB() - - Parses the 2nd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD5::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { - // Byte 44-47: Unknown/empty? - QByteArray unknown9(4, Qt::Uninitialized); - aZoneFileStream->readRawData(unknown9.data(), 4); -} - -/* - pParseZoneUnknownsC() - - Parses the 3rd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD5::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); -} - -/* - ParseZoneTags() - - Parses the string tags ate the start of zone file -*/ -QStringList ZoneFile_COD5::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { - QStringList tags; - - // Byte 48-51: Repeated separators? ÿÿÿÿ x i - aZoneFileStream->skipRawData(4 * (tagCount - 1)); - - // Parse tags/strings before index - QString zoneTag; - char zoneTagChar; - for (quint32 i = 0; i < tagCount; i++) { - *aZoneFileStream >> zoneTagChar; - while (zoneTagChar != 0) { - zoneTag += zoneTagChar; - *aZoneFileStream >> zoneTagChar; - } - tags << zoneTag; - zoneTag.clear(); - } - return tags; -} - -/* - ParseZoneIndex() - - Parse the binary zone index data and populate table -*/ -QStringList ZoneFile_COD5::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { - QStringList result; - - // Don't parse if no records - if (!recordCount) { return result; } - - if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { - aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); - } - - // 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); - } - return result; -} - -AssetMap ZoneFile_COD5::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 QString typeStr = AssetTypeToString(typeHex); - - if (typeStr == "LOCAL STRING") { // localized string asset - result.localStrings << pParseAsset_LocalString(aZoneFileStream); - } else if (typeStr == "RAW FILE") { // gsc - auto rawFile = pParseAsset_RawFile(aZoneFileStream); - if (rawFile.length) { - result.rawFiles << rawFile; - } - } else if (typeStr == "PHYS PRESET") { // physpreset - pParseAsset_PhysPreset(aZoneFileStream); - } else if (typeStr == "MODEL") { // xmodel - result.models << pParseAsset_Model(aZoneFileStream); - } else if (typeStr == "MATERIAL") { // material - pParseAsset_Material(aZoneFileStream); - } else if (typeStr == "SHADER") { // pixelshader - pParseAsset_Shader(aZoneFileStream); - } else if (typeStr == "TECH SET") { // techset include - result.techSets << pParseAsset_TechSet(aZoneFileStream); - } else if (typeStr == "IMAGE") { // image - result.images << pParseAsset_Image(aZoneFileStream); - } else if (typeStr == "SOUND") { // loaded_sound - result.sounds << pParseAsset_Sound(aZoneFileStream); - } else if (typeStr == "COLLISION MAP") { // col_map_mp - pParseAsset_ColMapMP(aZoneFileStream); - } else if (typeStr == "MP MAP") { // game_map_sp - pParseAsset_GameMapSP(aZoneFileStream); - } else if (typeStr == "SP MAP") { // game_map_mp - pParseAsset_GameMapMP(aZoneFileStream); - } else if (typeStr == "LIGHT DEF") { // lightdef - pParseAsset_LightDef(aZoneFileStream); - } else if (typeStr == "UI MAP") { // ui_map - pParseAsset_UIMap(aZoneFileStream); - } else if (typeStr == "SND DRIVER GLOBALS") { // snddriverglobals - pParseAsset_SNDDriverGlobals(aZoneFileStream); - } else if (typeStr == "AI TYPE") { // aitype - pParseAsset_AIType(aZoneFileStream); - } else if (typeStr == "EFFECT") { // aitype - pParseAsset_FX(aZoneFileStream); - } else if (typeStr == "ANIMATION") { // aitype - result.animations << pParseAsset_Animation(aZoneFileStream); - } else if (typeStr == "STRING TABLE") { // string_table - result.stringTables << pParseAsset_StringTable(aZoneFileStream); - } else if (typeStr == "MENU") { // string_table - result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); - } else if (typeStr == "WEAPON") { // string_table - pParseAsset_Weapon(aZoneFileStream); - } else if (typeStr == "D3DBSP DUMP") { // string_table - pParseAsset_D3DBSP(aZoneFileStream); - } else if (typeStr != "UNKNOWN") { - qDebug() << "Found bad asset type!" << typeStr; - } - } - return result; -} - -LocalString ZoneFile_COD5::pParseAsset_LocalString(QDataStream *aZoneFileStream) { - LocalString result; - - quint32 stringPtr, aliasPtr; - *aZoneFileStream >> stringPtr >> aliasPtr; - if (stringPtr == 4294967295) { - // Parse local string asset contents - QString localStr; - char localStrChar; - *aZoneFileStream >> localStrChar; - while (localStrChar != 0) { - result.string += localStrChar; - *aZoneFileStream >> localStrChar; - } - } else { - result.string = "String Ptr: " + QString::number(stringPtr); - } - - if (aliasPtr == 4294967295) { - // Parse rawfile name - QString aliasName; - char aliasNameChar; - *aZoneFileStream >> aliasNameChar; - while (aliasNameChar != 0) { - result.alias += aliasNameChar; - *aZoneFileStream >> aliasNameChar; - } - } else { - result.string = "Alias Ptr: " + QString::number(aliasPtr); - } - - return result; -} - -RawFile ZoneFile_COD5::pParseAsset_RawFile(QDataStream *aZoneFileStream) { - RawFile result; - - // Skip start separator FF FF FF FF (pointer?) - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.length; - - // Skip unknown 4 byte data - aZoneFileStream->skipRawData(4); - - // Parse rawfile path - char scriptPathChar; - *aZoneFileStream >> scriptPathChar; - while (scriptPathChar != 0) { - result.path += scriptPathChar; - *aZoneFileStream >> scriptPathChar; - } - result.path.replace(",", ""); - - const QStringList pathParts = result.path.split('/'); - if (pathParts.size() == 0) { - qDebug() << "Failed to parse ff path! " << result.path; - exit(-1); - } - if (result.path.contains(".bik")) { - qDebug() << "rawFileLength: " << result.length; - QByteArray bikData(result.length, Qt::Uninitialized); - aZoneFileStream->readRawData(bikData.data(), result.length); - - //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); - //qDebug() << bikFile.fileName(); - //if (!bikFile.open(QIODevice::WriteOnly)) { - // qWarning() << "Failed to open .bik file for writing!"; - // return; - //} - //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); - //bikFile.write(bikData); - } else { - // Parse gsc contents - char rawFileContentsChar; - *aZoneFileStream >> rawFileContentsChar; - while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { - result.contents += rawFileContentsChar; - *aZoneFileStream >> rawFileContentsChar; - } - } - return result; -} - -void ZoneFile_COD5::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Model ZoneFile_COD5::pParseAsset_Model(QDataStream *aZoneFileStream) { - Model result; - - qDebug() << "Model Info:"; - - *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; - - // Parse XModelLodInfo - for (int i = 1; i <= 4; i++) { - qDebug() << "- Lod Info " << 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]; - } - - *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]; - - 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; - - // Parse model name - char modelNameChar; - *aZoneFileStream >> modelNameChar; - while (modelNameChar == 0) { - *aZoneFileStream >> modelNameChar; - } - while (modelNameChar != 0) { - result.modelName += modelNameChar; - *aZoneFileStream >> modelNameChar; - } - return result; -} - -Material ZoneFile_COD5::pParseAsset_Material(QDataStream *aZoneFileStream) { - aZoneFileStream->skipRawData(27 * 4); - - qint32 materialNamePtr; - *aZoneFileStream >> materialNamePtr; - qDebug() << "materialNamePtr: " << materialNamePtr; - if (materialNamePtr == -1) { - QString materialName; - char materialNameChar; - *aZoneFileStream >> materialNameChar; - while (materialNameChar != 0) { - materialName += materialNameChar; - *aZoneFileStream >> materialNameChar; - } - qDebug() << "Parsing Material: " << materialName; - } - - aZoneFileStream->skipRawData(3 * 4); - - qint32 compressionPtr, compression, unknownSectionPtr; - *aZoneFileStream >> compressionPtr; - qDebug() << "compressionPtr: " << compressionPtr; - if (compressionPtr == -1) { - *aZoneFileStream >> compression; - qDebug() << QString("Found material with DXT%1 compression!").arg(compression); - - *aZoneFileStream >> unknownSectionPtr; - qDebug() << "unknownSectionPtr: " << unknownSectionPtr; - if (unknownSectionPtr == -2) { - aZoneFileStream->skipRawData(6 * 4); - } - } - - qint32 imageNamePtr; - *aZoneFileStream >> imageNamePtr; - qDebug() << "imageNamePtr: " << imageNamePtr; - if (imageNamePtr == -1) { - QString imageName; - char imageNameChar; - *aZoneFileStream >> imageNameChar; - while (imageNameChar != 0) { - imageName += imageNameChar; - *aZoneFileStream >> imageNameChar; - } - qDebug() << "- Embeded image: " << imageName; - } - - QByteArray compressionData(4, Qt::Uninitialized); - QString compressionStr; - if (compressionPtr == -1) { - aZoneFileStream->skipRawData(2 * 4); - aZoneFileStream->readRawData(compressionData.data(), 4); - aZoneFileStream->skipRawData(4); - compressionStr = QString::fromUtf8(compressionData); - aZoneFileStream->skipRawData(4); - } - aZoneFileStream->skipRawData(4); - - // TODO: Fill out this material - return Material(); -} - -Shader ZoneFile_COD5::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; - if (rawShaderType == 65535) { // Pixel shader - type = SHADER_PIXEL; - } else if (rawShaderType == 65534) { // Vertex shader - 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; - } else if (opCode == OPCODE_Comment) { - size = (int)((instructionToken >> 16) & 0x7FFF); - } else { - size = (int)((instructionToken >> 24) & 0x0f); - } - Q_UNUSED(size); - } - - - return result; -} - -TechSet ZoneFile_COD5::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; - while (techSetNameChar != 0) { - result.name += techSetNameChar; - *aZoneFileStream >> techSetNameChar; - } - result.name.replace(",", ""); - - return result; -} - -Image ZoneFile_COD5::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->skipRawData(15 * 4); - *aZoneFileStream >> result.unknownh >> result.unknowni; - - aZoneFileStream->skipRawData(4); - *aZoneFileStream >> result.unknownj; - - aZoneFileStream->skipRawData(4); - - char materialNameChar; - *aZoneFileStream >> materialNameChar; - while (materialNameChar != 0) { - result.materialName += materialNameChar; - *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; - - 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")) { - 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; - } - - return result; -} - -SoundAsset ZoneFile_COD5::pParseAsset_Sound(QDataStream *aZoneFileStream) { - SoundAsset result; - - qDebug() << aZoneFileStream->device()->pos(); - - QByteArray rootNamePtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(rootNamePtr.data(), 4); - qDebug() << "Root name ptr: " << (QString)rootNamePtr.toHex(); - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.count; - - if (rootNamePtr.toHex() == "ffffffff") { - // Read in sound file name - char soundNameChar; - *aZoneFileStream >> soundNameChar; - while (soundNameChar != 0) { - result.name += soundNameChar; - *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") { - qDebug() << "Tag Ptr: " << tagPtr.toHex(); - tagCount++; - } - aZoneFileStream->skipRawData(4); - - QByteArray pathPtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(pathPtr.data(), 4); - - if (pathPtr.toHex() == "ffffffff") { - qDebug() << "Path Ptr: " << pathPtr.toHex(); - resultCount++; - } - - aZoneFileStream->skipRawData(160); - } - - for (int i = 0; i < tagCount; i++) { - // Read in tag? - QString tag; - char tagChar; - *aZoneFileStream >> tagChar; - while (tagChar != 0) { - tag += tagChar; - *aZoneFileStream >> tagChar; - } - qDebug() << "Tag: " << tag; - } - - 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; - qDebug() << "- Data length: " << sound.dataLength; - - if (aliasPtr.toHex() == "ffffffff") { - // Read in sound alias name - char soundAliasChar; - *aZoneFileStream >> soundAliasChar; - while (soundAliasChar != 0) { - sound.alias += soundAliasChar; - *aZoneFileStream >> soundAliasChar; - } - qDebug() << "- Alias: " << sound.alias; - } - - if (aZoneFileStream->device()->peek(4) == "RIFF") { - sound.path = sound.alias; - sound.alias = ""; - } else if (namePtr.toHex() == "ffffffff") { - // Read in sound file path - char soundPathChar; - *aZoneFileStream >> soundPathChar; - while (soundPathChar != 0) { - sound.path += soundPathChar; - *aZoneFileStream >> soundPathChar; - } - sound.path.replace(",", ""); - qDebug() << "- Path: " << sound.path; - } - - if (sound.dataLength) { - QByteArray data(sound.dataLength, Qt::Uninitialized); - aZoneFileStream->readRawData(data.data(), sound.dataLength); - sound.data = data; - } - result.sounds.append(sound); - } - qDebug() << "- " << aZoneFileStream->device()->pos(); - - return result; -} - -void ZoneFile_COD5::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_LightDef(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_UIMap(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_AIType(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_FX(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Animation ZoneFile_COD5::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; - - // Read in x_anim file name - QString xAnimName; - char xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - while (xAnimNameChar != 0) { - result.name += xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - } - - // Parse x_anim index header - QVector sectionLengths; - for (int i = 0; i < result.numframes; i++) { - quint8 sectionlength; - *aZoneFileStream >> sectionlength; - sectionLengths.push_back(sectionlength); - // Skip padding - aZoneFileStream->skipRawData(1); - } - // Skip unknown section - aZoneFileStream->skipRawData(2 * 8); - - return result; -} - -MenuFile ZoneFile_COD5::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."; - return result; - } - for (uint i = 0; i < result.menuCount; i++) { - Menu menu; - - aZoneFileStream->skipRawData(4); // Separator - - // Read in x_anim file name - char menuFilepathChar; - *aZoneFileStream >> menuFilepathChar; - while (menuFilepathChar != 0) { - menu.filePath += menuFilepathChar; - *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; - 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; - *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA - >> 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; - - float focusColorR, focusColorG, focusColorB, focusColorA, - disabledColorR, disabledColorG, disabledColorB, disabledColorA; - *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA - >> 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; - while (menuDefNameChar != 0 && menuDefNameLen < 30) { - menuDefNameLen++; - menu.name += menuDefNameChar; - *aZoneFileStream >> menuDefNameChar; - } - - char defStringChar; - int defStringLen = 0; - *aZoneFileStream >> defStringChar; - while (defStringChar != 0 && defStringLen < 30) { - defStringLen++; - menu.definition += defStringChar; - *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; - - float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, - 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; - - 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.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; - - // 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; - *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA - >> 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; - - // 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; - //statement_s rectXExp; - //statement_s rectYExp; - //statement_s rectWExp; - //statement_s rectHExp; - //statement_s foreColorAExp; - result.menuDefs << menu; - } - return result; -} - -void ZoneFile_COD5::pParseAsset_Weapon(QDataStream *aZoneFileStream) { - //WEAPON_FILE - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD5::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { - //D3DBSP_DUMP - Q_UNUSED(aZoneFileStream); -} - -StringTable ZoneFile_COD5::pParseAsset_StringTable(QDataStream *aZoneFileStream) { - StringTable result; - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream - >> result.columnCount - >> result.rowCount; - - // Todo fix this - result.columnCount = 0; - result.rowCount = 0; - - aZoneFileStream->skipRawData(4); - - QString stringTableName; - char stringTableNameChar; - *aZoneFileStream >> stringTableNameChar; - while (stringTableNameChar != 0) { - 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") { - char leadingContentChar; - *aZoneFileStream >> leadingContentChar; - while (leadingContentChar != 0) { - leadingContent += leadingContentChar; - *aZoneFileStream >> leadingContentChar; - } - } else { - leadingContent = pointerAddr; - } - - QString content; - char contentChar; - *aZoneFileStream >> contentChar; - while (contentChar != 0) { - content += contentChar; - *aZoneFileStream >> contentChar; - } - result.content[leadingContent] = content; - } - return result; -} - -QString ZoneFile_COD5::AssetTypeToString(const QString aAssetType) { - const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED - return "RAW FILE"; - } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED - return "GSC FILE"; - } else if (cleanedType == "1A000000") { // fx PARTIALLY VERIFIED - return "EFFECT"; - } else if (cleanedType == "09000000") { // loaded_sound PARTIALLY VERIFIED - return "SOUND"; - } else if (cleanedType == "04000000") { // x_anim PARTIALLY VERIFIED - return "ANIMATION"; - } else if (cleanedType == "0C000000") { // collision_map PARTIALLY VERIFIED - return "COLLISION MAP"; - } else if (cleanedType == "21000000") { // string_table PARTIALLY VERIFIED - return "STRING TABLE"; - } else if (cleanedType == "15000000") { // menu_file PARTIALLY VERIFIED - return "MENU"; - } else if (cleanedType == "07000000") { // tech set PARTIALLY VERIFIED - return "TECH SET"; - } else if (cleanedType == "18000000") { // weapon PARTIALLY VERIFIED - return "WEAPON"; - } else if (cleanedType == "11000000") { // gfx map PARTIALLY VERIFIED - return "GFX MAP"; - } else if (cleanedType == "12000000") { // light_def PARTIALLY VERIFIED - return "LIGHT DEF"; - } else if (cleanedType == "14000000") { // font PARTIALLY VERIFIED - return "FONT"; - } else if (cleanedType == "05000000") { // xmodel PARTIALLY VERIFIED - return "MODEL"; - } else if (cleanedType == "0D000000") { // d3dbsp PARTIALLY VERIFIED - return "D3DBSP"; - } else if (cleanedType == "06000000") { // image PARTIALLY VERIFIED - return "IMAGE"; - } else if (cleanedType == "0E000000") { // game map sp PARTIALLY VERIFIED - return "GAME MAP SP"; - } else if (cleanedType == "0B000000") { // col map sp PARTIALLY VERIFIED - return "COL MAP SP"; - } else if (cleanedType == "01000000") { // physics preset PARTIALLY VERIFIED - return "PHYS PRESET"; - } else if (cleanedType == "03000000") { // destructible def PARTIALLY VERIFIED - return "DESTRUCTIBLE"; - } - return aAssetType; -} - -QByteArray ZoneFile_COD5::GetBinaryData() { - QByteArray result; - - return result; -} diff --git a/libs/zonefile/zonefile_cod5.h b/libs/zonefile/zonefile_cod5.h deleted file mode 100644 index b7294fb..0000000 --- a/libs/zonefile/zonefile_cod5.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef ZONEFILE_COD5_H -#define ZONEFILE_COD5_H - -#include - -#include "zonefile.h" - -class ZoneFile_COD5 : public ZoneFile -{ -public: - ZoneFile_COD5(); - ~ZoneFile_COD5(); - - bool Load(const QByteArray aFileData, FF_PLATFORM aPlatform) override; - QString AssetTypeToString(const QString aAssetType) override; - - QByteArray GetBinaryData() override; - -private: - void pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) override; - quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; - quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; - quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; - QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; - QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; - AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; - LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; - RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; - void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; - Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - Material pParseAsset_Material(QDataStream *aZoneFileStream) override; - Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; - TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; - Image pParseAsset_Image(QDataStream *aZoneFileStream) override; - SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; - void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; - void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; - void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; - void pParseAsset_AIType(QDataStream *aZoneFileStream) override; - void pParseAsset_FX(QDataStream *aZoneFileStream) override; - Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; - MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; - void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; - void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; - StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; -}; - -#endif // ZONEFILE_COD5_H diff --git a/libs/zonefile/zonefile_cod7.cpp b/libs/zonefile/zonefile_cod7.cpp deleted file mode 100644 index a6d6988..0000000 --- a/libs/zonefile/zonefile_cod7.cpp +++ /dev/null @@ -1,1103 +0,0 @@ -#include "zonefile_cod7.h" - -#include -#include -#include - -ZoneFile_COD7::ZoneFile_COD7() -{ - -} - -ZoneFile_COD7::~ZoneFile_COD7() -{ - -} - -bool ZoneFile_COD7::Load(const QByteArray aFileData, FF_PLATFORM aPlatform) { - // Open zone file as little endian stream - QDataStream zoneFileStream(aFileData); - if (aPlatform == FF_PLATFORM_PC) { - zoneFileStream.setByteOrder(QDataStream::LittleEndian); - } else { - zoneFileStream.setByteOrder(QDataStream::BigEndian); - } - - // Parse data from zone file header - pParseZoneHeader(&zoneFileStream, aPlatform); - zoneFileStream.device()->seek(zoneFileStream.device()->pos() - 1); - SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); - SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); - - return true; -} - -void ZoneFile_COD7::pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) { - quint32 size = pParseZoneSize(aZoneFileStream); - SetSize(size); - - if (aPlatform == FF_PLATFORM_WII) { - aZoneFileStream->skipRawData(36); - } else { - pParseZoneUnknownsA(aZoneFileStream); - } - - quint32 tagCount = pParseZoneTagCount(aZoneFileStream); - SetTagCount(tagCount); - if (aPlatform == FF_PLATFORM_WII) { - SetTagCount(GetTagCount() - 1); - } - - pParseZoneUnknownsB(aZoneFileStream); - - quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); - SetRecordCount(recordCount); - - if (tagCount) { - pParseZoneUnknownsC(aZoneFileStream); - SetTags(pParseZoneTags(aZoneFileStream, tagCount)); - } else { - aZoneFileStream->skipRawData(4); - } -} - -quint32 ZoneFile_COD7::pParseZoneSize(QDataStream *aZoneFileStream) { - quint32 zoneFileSize; - *aZoneFileStream >> zoneFileSize; - if (zoneFileSize <= 0) { - qDebug() << "Tried to open empty zone file!"; - exit(-1); - } - zoneFileSize += 36; - return zoneFileSize; -} - -/* - ParseZoneUnknownsA() - - Parses the 1st section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD7::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); -} - -/* - ParseZoneTagCount() - - Parses the number of string tags in the zone index -*/ -quint32 ZoneFile_COD7::pParseZoneTagCount(QDataStream *aZoneFileStream) { - quint32 tagCount; - *aZoneFileStream >> tagCount; - return tagCount; -} - -/* - ParseZoneRecordCount() - - Parses the number of records in the zone index -*/ -quint32 ZoneFile_COD7::pParseZoneRecordCount(QDataStream *aZoneFileStream) { - quint32 recordCount; - *aZoneFileStream >> recordCount; - return recordCount; -} - -/* - ParseZoneUnknownsB() - - Parses the 2nd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD7::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { - // Byte 44-47: Unknown/empty? - QByteArray unknown9(4, Qt::Uninitialized); - aZoneFileStream->readRawData(unknown9.data(), 4); -} - -/* - pParseZoneUnknownsC() - - Parses the 3rd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD7::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); -} - -/* - ParseZoneTags() - - Parses the string tags ate the start of zone file -*/ -QStringList ZoneFile_COD7::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { - QStringList tags; - - // Byte 48-51: Repeated separators? ÿÿÿÿ x i - aZoneFileStream->skipRawData(4 * (tagCount - 1)); - - // Parse tags/strings before index - QString zoneTag; - char zoneTagChar; - for (quint32 i = 0; i < tagCount; i++) { - *aZoneFileStream >> zoneTagChar; - while (zoneTagChar != 0) { - zoneTag += zoneTagChar; - *aZoneFileStream >> zoneTagChar; - } - tags << zoneTag; - zoneTag.clear(); - } - return tags; -} - -/* - ParseZoneIndex() - - Parse the binary zone index data and populate table -*/ -QStringList ZoneFile_COD7::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { - QStringList result; - - // Don't parse if no records - if (!recordCount) { return result; } - - if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { - aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); - } - - // 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); - } - return result; -} - -AssetMap ZoneFile_COD7::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 QString typeStr = AssetTypeToString(typeHex); - - if (typeStr == "LOCAL STRING") { // localized string asset - result.localStrings << pParseAsset_LocalString(aZoneFileStream); - } else if (typeStr == "RAW FILE") { // gsc - auto rawFile = pParseAsset_RawFile(aZoneFileStream); - if (rawFile.length) { - result.rawFiles << rawFile; - } - } else if (typeStr == "PHYS PRESET") { // physpreset - pParseAsset_PhysPreset(aZoneFileStream); - } else if (typeStr == "MODEL") { // xmodel - result.models << pParseAsset_Model(aZoneFileStream); - } else if (typeStr == "MATERIAL") { // material - pParseAsset_Material(aZoneFileStream); - } else if (typeStr == "SHADER") { // pixelshader - pParseAsset_Shader(aZoneFileStream); - } else if (typeStr == "TECH SET") { // techset include - result.techSets << pParseAsset_TechSet(aZoneFileStream); - } else if (typeStr == "IMAGE") { // image - result.images << pParseAsset_Image(aZoneFileStream); - } else if (typeStr == "SOUND") { // loaded_sound - result.sounds << pParseAsset_Sound(aZoneFileStream); - } else if (typeStr == "COLLISION MAP") { // col_map_mp - pParseAsset_ColMapMP(aZoneFileStream); - } else if (typeStr == "MP MAP") { // game_map_sp - pParseAsset_GameMapSP(aZoneFileStream); - } else if (typeStr == "SP MAP") { // game_map_mp - pParseAsset_GameMapMP(aZoneFileStream); - } else if (typeStr == "LIGHT DEF") { // lightdef - pParseAsset_LightDef(aZoneFileStream); - } else if (typeStr == "UI MAP") { // ui_map - pParseAsset_UIMap(aZoneFileStream); - } else if (typeStr == "SND DRIVER GLOBALS") { // snddriverglobals - pParseAsset_SNDDriverGlobals(aZoneFileStream); - } else if (typeStr == "AI TYPE") { // aitype - pParseAsset_AIType(aZoneFileStream); - } else if (typeStr == "EFFECT") { // aitype - pParseAsset_FX(aZoneFileStream); - } else if (typeStr == "ANIMATION") { // aitype - result.animations << pParseAsset_Animation(aZoneFileStream); - } else if (typeStr == "STRING TABLE") { // string_table - result.stringTables << pParseAsset_StringTable(aZoneFileStream); - } else if (typeStr == "MENU") { // string_table - result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); - } else if (typeStr == "WEAPON") { // string_table - pParseAsset_Weapon(aZoneFileStream); - } else if (typeStr == "D3DBSP DUMP") { // string_table - pParseAsset_D3DBSP(aZoneFileStream); - } else if (typeStr != "UNKNOWN") { - qDebug() << "Found bad asset type!" << typeStr; - } - } - return result; -} - -LocalString ZoneFile_COD7::pParseAsset_LocalString(QDataStream *aZoneFileStream) { - LocalString result; - - quint32 stringPtr, aliasPtr; - *aZoneFileStream >> stringPtr >> aliasPtr; - if (stringPtr == 4294967295) { - // Parse local string asset contents - QString localStr; - char localStrChar; - *aZoneFileStream >> localStrChar; - while (localStrChar != 0) { - result.string += localStrChar; - *aZoneFileStream >> localStrChar; - } - } else { - result.string = "String Ptr: " + QString::number(stringPtr); - } - - if (aliasPtr == 4294967295) { - // Parse rawfile name - QString aliasName; - char aliasNameChar; - *aZoneFileStream >> aliasNameChar; - while (aliasNameChar != 0) { - result.alias += aliasNameChar; - *aZoneFileStream >> aliasNameChar; - } - } else { - result.string = "Alias Ptr: " + QString::number(aliasPtr); - } - - return result; -} - -RawFile ZoneFile_COD7::pParseAsset_RawFile(QDataStream *aZoneFileStream) { - RawFile result; - - // Skip start separator FF FF FF FF (pointer?) - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.length; - - // Skip unknown 4 byte data - aZoneFileStream->skipRawData(4); - - // Parse rawfile path - char scriptPathChar; - *aZoneFileStream >> scriptPathChar; - while (scriptPathChar != 0) { - result.path += scriptPathChar; - *aZoneFileStream >> scriptPathChar; - } - 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; - *aZoneFileStream >> rawFileContentsChar; - } - return result; -} - -void ZoneFile_COD7::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Model ZoneFile_COD7::pParseAsset_Model(QDataStream *aZoneFileStream) { - Model result; - - qDebug() << "Model Info:"; - - *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; - - // Parse XModelLodInfo - for (int i = 1; i <= 4; i++) { - qDebug() << "- Lod Info " << 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]; - } - - *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]; - - 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; - - // Parse model name - char modelNameChar; - *aZoneFileStream >> modelNameChar; - while (modelNameChar == 0) { - *aZoneFileStream >> modelNameChar; - } - while (modelNameChar != 0) { - result.modelName += modelNameChar; - *aZoneFileStream >> modelNameChar; - } - return result; -} - -Material ZoneFile_COD7::pParseAsset_Material(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); - - return Material(); -} - -Shader ZoneFile_COD7::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; - if (rawShaderType == 65535) { // Pixel shader - type = SHADER_PIXEL; - } else if (rawShaderType == 65534) { // Vertex shader - 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; - } else if (opCode == OPCODE_Comment) { - size = (int)((instructionToken >> 16) & 0x7FFF); - } else { - size = (int)((instructionToken >> 24) & 0x0f); - } - Q_UNUSED(size); - } - - - return result; -} - -TechSet ZoneFile_COD7::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; - while (techSetNameChar != 0) { - result.name += techSetNameChar; - *aZoneFileStream >> techSetNameChar; - } - result.name.replace(",", ""); - - return result; -} - -Image ZoneFile_COD7::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->skipRawData(15 * 4); - *aZoneFileStream >> result.unknownh >> result.unknowni; - - aZoneFileStream->skipRawData(4); - *aZoneFileStream >> result.unknownj; - - aZoneFileStream->skipRawData(4); - - char materialNameChar; - *aZoneFileStream >> materialNameChar; - while (materialNameChar != 0) { - result.materialName += materialNameChar; - *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; - - 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")) { - 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; - } - - return result; -} - -SoundAsset ZoneFile_COD7::pParseAsset_Sound(QDataStream *aZoneFileStream) { - SoundAsset result; - - qDebug() << aZoneFileStream->device()->pos(); - - QByteArray rootNamePtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(rootNamePtr.data(), 4); - qDebug() << "Root name ptr: " << (QString)rootNamePtr.toHex(); - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.count; - - if (rootNamePtr.toHex() == "ffffffff") { - // Read in sound file name - char soundNameChar; - *aZoneFileStream >> soundNameChar; - while (soundNameChar != 0) { - result.name += soundNameChar; - *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") { - qDebug() << "Tag Ptr: " << tagPtr.toHex(); - tagCount++; - } - aZoneFileStream->skipRawData(4); - - QByteArray pathPtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(pathPtr.data(), 4); - - if (pathPtr.toHex() == "ffffffff") { - qDebug() << "Path Ptr: " << pathPtr.toHex(); - resultCount++; - } - - aZoneFileStream->skipRawData(160); - } - - for (int i = 0; i < tagCount; i++) { - // Read in tag? - QString tag; - char tagChar; - *aZoneFileStream >> tagChar; - while (tagChar != 0) { - tag += tagChar; - *aZoneFileStream >> tagChar; - } - qDebug() << "Tag: " << tag; - } - - 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; - qDebug() << "- Data length: " << sound.dataLength; - - if (aliasPtr.toHex() == "ffffffff") { - // Read in sound alias name - char soundAliasChar; - *aZoneFileStream >> soundAliasChar; - while (soundAliasChar != 0) { - sound.alias += soundAliasChar; - *aZoneFileStream >> soundAliasChar; - } - qDebug() << "- Alias: " << sound.alias; - } - - if (aZoneFileStream->device()->peek(4) == "RIFF") { - sound.path = sound.alias; - sound.alias = ""; - } else if (namePtr.toHex() == "ffffffff") { - // Read in sound file path - char soundPathChar; - *aZoneFileStream >> soundPathChar; - while (soundPathChar != 0) { - sound.path += soundPathChar; - *aZoneFileStream >> soundPathChar; - } - sound.path.replace(",", ""); - qDebug() << "- Path: " << sound.path; - } - - if (sound.dataLength) { - QByteArray data(sound.dataLength, Qt::Uninitialized); - aZoneFileStream->readRawData(data.data(), sound.dataLength); - sound.data = data; - } - result.sounds.append(sound); - } - qDebug() << "- " << aZoneFileStream->device()->pos(); - - return result; -} - -void ZoneFile_COD7::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_LightDef(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_UIMap(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_AIType(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_FX(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Animation ZoneFile_COD7::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; - - // Read in x_anim file name - QString xAnimName; - char xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - while (xAnimNameChar != 0) { - result.name += xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - } - - // Parse x_anim index header - QVector sectionLengths; - for (int i = 0; i < result.numframes; i++) { - quint8 sectionlength; - *aZoneFileStream >> sectionlength; - sectionLengths.push_back(sectionlength); - // Skip padding - aZoneFileStream->skipRawData(1); - } - // Skip unknown section - aZoneFileStream->skipRawData(2 * 8); - - return result; -} - -MenuFile ZoneFile_COD7::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."; - return result; - } - for (uint i = 0; i < result.menuCount; i++) { - Menu menu; - - aZoneFileStream->skipRawData(4); // Separator - - // Read in x_anim file name - char menuFilepathChar; - *aZoneFileStream >> menuFilepathChar; - while (menuFilepathChar != 0) { - menu.filePath += menuFilepathChar; - *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; - 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; - *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA - >> 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; - - float focusColorR, focusColorG, focusColorB, focusColorA, - disabledColorR, disabledColorG, disabledColorB, disabledColorA; - *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA - >> 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; - while (menuDefNameChar != 0 && menuDefNameLen < 30) { - menuDefNameLen++; - menu.name += menuDefNameChar; - *aZoneFileStream >> menuDefNameChar; - } - - char defStringChar; - int defStringLen = 0; - *aZoneFileStream >> defStringChar; - while (defStringChar != 0 && defStringLen < 30) { - defStringLen++; - menu.definition += defStringChar; - *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; - - float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, - 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; - - 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.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; - - // 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; - *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA - >> 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; - - // 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; - //statement_s rectXExp; - //statement_s rectYExp; - //statement_s rectWExp; - //statement_s rectHExp; - //statement_s foreColorAExp; - result.menuDefs << menu; - } - return result; -} - -void ZoneFile_COD7::pParseAsset_Weapon(QDataStream *aZoneFileStream) { - //WEAPON_FILE - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD7::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { - //D3DBSP_DUMP - Q_UNUSED(aZoneFileStream); -} - -StringTable ZoneFile_COD7::pParseAsset_StringTable(QDataStream *aZoneFileStream) { - StringTable result; - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream - >> result.columnCount - >> result.rowCount; - - // Todo fix this - result.columnCount = 0; - result.rowCount = 0; - - aZoneFileStream->skipRawData(4); - - QString stringTableName; - char stringTableNameChar; - *aZoneFileStream >> stringTableNameChar; - while (stringTableNameChar != 0) { - 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") { - char leadingContentChar; - *aZoneFileStream >> leadingContentChar; - while (leadingContentChar != 0) { - leadingContent += leadingContentChar; - *aZoneFileStream >> leadingContentChar; - } - } else { - leadingContent = pointerAddr; - } - - QString content; - char contentChar; - *aZoneFileStream >> contentChar; - while (contentChar != 0) { - content += contentChar; - *aZoneFileStream >> contentChar; - } - result.content[leadingContent] = content; - } - return result; -} - -QString ZoneFile_COD7::AssetTypeToString(const QString aAssetType) { - const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED - return "LOCAL STRING"; - } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED - return "RAW FILE"; - } else if (cleanedType == "1A000000") { // fx PARTIALLY VERIFIED - return "EFFECT"; - } else if (cleanedType == "09000000") { // loaded_sound PARTIALLY VERIFIED - return "SOUND"; - } else if (cleanedType == "04000000") { // x_anim PARTIALLY VERIFIED - return "ANIMATION"; - } else if (cleanedType == "0C000000") { // collision_map PARTIALLY VERIFIED - return "COLLISION MAP"; - } else if (cleanedType == "21000000") { // string_table PARTIALLY VERIFIED - return "STRING TABLE"; - } else if (cleanedType == "15000000") { // menu_file PARTIALLY VERIFIED - return "MENU"; - } else if (cleanedType == "07000000") { // tech set PARTIALLY VERIFIED - return "TECH SET"; - } else if (cleanedType == "18000000") { // weapon PARTIALLY VERIFIED - return "WEAPON"; - } else if (cleanedType == "11000000") { // gfx map PARTIALLY VERIFIED - return "GFX MAP"; - } else if (cleanedType == "12000000") { // light_def PARTIALLY VERIFIED - return "LIGHT DEF"; - } else if (cleanedType == "14000000") { // font PARTIALLY VERIFIED - return "FONT"; - } else if (cleanedType == "05000000") { // xmodel PARTIALLY VERIFIED - return "MODEL"; - } else if (cleanedType == "0D000000") { // d3dbsp PARTIALLY VERIFIED - return "D3DBSP"; - } else if (cleanedType == "06000000") { // image PARTIALLY VERIFIED - return "IMAGE"; - } else if (cleanedType == "0E000000") { // game map sp PARTIALLY VERIFIED - return "GAME MAP SP"; - } else if (cleanedType == "0B000000") { // col map sp PARTIALLY VERIFIED - return "COL MAP SP"; - } - return aAssetType; -} - -QByteArray ZoneFile_COD7::GetBinaryData() { - QByteArray result; - - return result; -} diff --git a/libs/zonefile/zonefile_cod7.h b/libs/zonefile/zonefile_cod7.h deleted file mode 100644 index 6509b4e..0000000 --- a/libs/zonefile/zonefile_cod7.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef ZONEFILE_COD7_H -#define ZONEFILE_COD7_H - -#include "zonefile.h" - -class ZoneFile_COD7 : public ZoneFile -{ -public: - ZoneFile_COD7(); - ~ZoneFile_COD7(); - - bool Load(const QByteArray aFileData, FF_PLATFORM aPlatform) override; - QString AssetTypeToString(const QString aAssetType); - - QByteArray GetBinaryData() override; - -protected: - void pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) override; - quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; - quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; - quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; - QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; - QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; - AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; - LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; - RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; - void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; - Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - Material pParseAsset_Material(QDataStream *aZoneFileStream) override; - Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; - TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; - Image pParseAsset_Image(QDataStream *aZoneFileStream) override; - SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; - void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; - void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; - void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; - void pParseAsset_AIType(QDataStream *aZoneFileStream) override; - void pParseAsset_FX(QDataStream *aZoneFileStream) override; - Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; - MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; - void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; - void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; - StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; -}; - -#endif // ZONEFILE_COD7_H diff --git a/libs/zonefile/zonefile_cod9.cpp b/libs/zonefile/zonefile_cod9.cpp deleted file mode 100644 index 9943633..0000000 --- a/libs/zonefile/zonefile_cod9.cpp +++ /dev/null @@ -1,1093 +0,0 @@ -#include "zonefile_cod9.h" - -#include -#include -#include - -ZoneFile_COD9::ZoneFile_COD9() -{ - -} - -ZoneFile_COD9::~ZoneFile_COD9() -{ - -} - -bool ZoneFile_COD9::Load(const QByteArray aFileData, FF_PLATFORM aPlatform) { - // Open zone file as little endian stream - QDataStream zoneFileStream(aFileData); - if (aPlatform == FF_PLATFORM_PC) { - zoneFileStream.setByteOrder(QDataStream::LittleEndian); - } else { - zoneFileStream.setByteOrder(QDataStream::BigEndian); - } - - // Parse data from zone file header - pParseZoneHeader(&zoneFileStream, aPlatform); - SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); - SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); - - return true; -} - -void ZoneFile_COD9::pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) { - Q_UNUSED(aPlatform); - - SetSize(pParseZoneSize(aZoneFileStream)); - pParseZoneUnknownsA(aZoneFileStream); - - SetTagCount(pParseZoneTagCount(aZoneFileStream)); - pParseZoneUnknownsB(aZoneFileStream); - - SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); - - quint32 tagCount = GetTagCount(); - if (tagCount) { - pParseZoneUnknownsC(aZoneFileStream); - SetTags(pParseZoneTags(aZoneFileStream, tagCount)); - } else { - aZoneFileStream->skipRawData(4); - } -} - -quint32 ZoneFile_COD9::pParseZoneSize(QDataStream *aZoneFileStream) { - quint32 zoneFileSize; - *aZoneFileStream >> zoneFileSize; - if (zoneFileSize <= 0) { - qDebug() << "Tried to open empty zone file!"; - exit(-1); - } - zoneFileSize += 36; - return zoneFileSize; -} - -/* - ParseZoneUnknownsA() - - Parses the 1st section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD9::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); -} - -/* - ParseZoneTagCount() - - Parses the number of string tags in the zone index -*/ -quint32 ZoneFile_COD9::pParseZoneTagCount(QDataStream *aZoneFileStream) { - quint32 tagCount; - *aZoneFileStream >> tagCount; - return tagCount; -} - -/* - ParseZoneRecordCount() - - Parses the number of records in the zone index -*/ -quint32 ZoneFile_COD9::pParseZoneRecordCount(QDataStream *aZoneFileStream) { - quint32 recordCount; - *aZoneFileStream >> recordCount; - return recordCount; -} - -/* - ParseZoneUnknownsB() - - Parses the 2nd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD9::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { - // Byte 44-47: Unknown/empty? - QByteArray unknown9(4, Qt::Uninitialized); - aZoneFileStream->readRawData(unknown9.data(), 4); -} - -/* - pParseZoneUnknownsC() - - Parses the 3rd section of unknowns as hex vals and uint32s -*/ -void ZoneFile_COD9::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); -} - -/* - ParseZoneTags() - - Parses the string tags ate the start of zone file -*/ -QStringList ZoneFile_COD9::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { - QStringList tags; - - // Byte 48-51: Repeated separators? ÿÿÿÿ x i - aZoneFileStream->skipRawData(4 * (tagCount - 1)); - - // Parse tags/strings before index - QString zoneTag; - char zoneTagChar; - for (quint32 i = 0; i < tagCount; i++) { - *aZoneFileStream >> zoneTagChar; - while (zoneTagChar != 0) { - zoneTag += zoneTagChar; - *aZoneFileStream >> zoneTagChar; - } - tags << zoneTag; - zoneTag.clear(); - } - return tags; -} - -/* - ParseZoneIndex() - - Parse the binary zone index data and populate table -*/ -QStringList ZoneFile_COD9::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { - QStringList result; - - // Don't parse if no records - if (!recordCount) { return result; } - - if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { - aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); - } - - // 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); - } - return result; -} - -AssetMap ZoneFile_COD9::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 QString typeStr = AssetTypeToString(typeHex); - - if (typeStr == "LOCAL STRING") { // localized string asset - result.localStrings << pParseAsset_LocalString(aZoneFileStream); - } else if (typeStr == "RAW FILE") { // gsc - auto rawFile = pParseAsset_RawFile(aZoneFileStream); - if (rawFile.length) { - result.rawFiles << rawFile; - } - } else if (typeStr == "PHYS PRESET") { // physpreset - pParseAsset_PhysPreset(aZoneFileStream); - } else if (typeStr == "MODEL") { // xmodel - result.models << pParseAsset_Model(aZoneFileStream); - } else if (typeStr == "MATERIAL") { // material - pParseAsset_Material(aZoneFileStream); - } else if (typeStr == "SHADER") { // pixelshader - pParseAsset_Shader(aZoneFileStream); - } else if (typeStr == "TECH SET") { // techset include - result.techSets << pParseAsset_TechSet(aZoneFileStream); - } else if (typeStr == "IMAGE") { // image - result.images << pParseAsset_Image(aZoneFileStream); - } else if (typeStr == "SOUND") { // loaded_sound - result.sounds << pParseAsset_Sound(aZoneFileStream); - } else if (typeStr == "COLLISION MAP") { // col_map_mp - pParseAsset_ColMapMP(aZoneFileStream); - } else if (typeStr == "MP MAP") { // game_map_sp - pParseAsset_GameMapSP(aZoneFileStream); - } else if (typeStr == "SP MAP") { // game_map_mp - pParseAsset_GameMapMP(aZoneFileStream); - } else if (typeStr == "LIGHT DEF") { // lightdef - pParseAsset_LightDef(aZoneFileStream); - } else if (typeStr == "UI MAP") { // ui_map - pParseAsset_UIMap(aZoneFileStream); - } else if (typeStr == "SND DRIVER GLOBALS") { // snddriverglobals - pParseAsset_SNDDriverGlobals(aZoneFileStream); - } else if (typeStr == "AI TYPE") { // aitype - pParseAsset_AIType(aZoneFileStream); - } else if (typeStr == "EFFECT") { // aitype - pParseAsset_FX(aZoneFileStream); - } else if (typeStr == "ANIMATION") { // aitype - result.animations << pParseAsset_Animation(aZoneFileStream); - } else if (typeStr == "STRING TABLE") { // string_table - result.stringTables << pParseAsset_StringTable(aZoneFileStream); - } else if (typeStr == "MENU") { // string_table - result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); - } else if (typeStr == "WEAPON") { // string_table - pParseAsset_Weapon(aZoneFileStream); - } else if (typeStr == "D3DBSP DUMP") { // string_table - pParseAsset_D3DBSP(aZoneFileStream); - } else if (typeStr != "UNKNOWN") { - qDebug() << "Found bad asset type!" << typeStr; - } - } - return result; -} - -LocalString ZoneFile_COD9::pParseAsset_LocalString(QDataStream *aZoneFileStream) { - LocalString result; - - quint32 stringPtr, aliasPtr; - *aZoneFileStream >> stringPtr >> aliasPtr; - if (stringPtr == 4294967295) { - // Parse local string asset contents - QString localStr; - char localStrChar; - *aZoneFileStream >> localStrChar; - while (localStrChar != 0) { - result.string += localStrChar; - *aZoneFileStream >> localStrChar; - } - } else { - result.string = "String Ptr: " + QString::number(stringPtr); - } - - if (aliasPtr == 4294967295) { - // Parse rawfile name - QString aliasName; - char aliasNameChar; - *aZoneFileStream >> aliasNameChar; - while (aliasNameChar != 0) { - result.alias += aliasNameChar; - *aZoneFileStream >> aliasNameChar; - } - } else { - result.string = "Alias Ptr: " + QString::number(aliasPtr); - } - - return result; -} - -RawFile ZoneFile_COD9::pParseAsset_RawFile(QDataStream *aZoneFileStream) { - RawFile result; - - // Skip start separator FF FF FF FF (pointer?) - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.length; - - // Skip unknown 4 byte data - aZoneFileStream->skipRawData(4); - - // Parse rawfile path - char scriptPathChar; - *aZoneFileStream >> scriptPathChar; - while (scriptPathChar != 0) { - result.path += scriptPathChar; - *aZoneFileStream >> scriptPathChar; - } - 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; - *aZoneFileStream >> rawFileContentsChar; - } - return result; -} - -void ZoneFile_COD9::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Model ZoneFile_COD9::pParseAsset_Model(QDataStream *aZoneFileStream) { - Model result; - - qDebug() << "Model Info:"; - - *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; - - // Parse XModelLodInfo - for (int i = 1; i <= 4; i++) { - qDebug() << "- Lod Info " << 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]; - } - - *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]; - - 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; - - // Parse model name - char modelNameChar; - *aZoneFileStream >> modelNameChar; - while (modelNameChar == 0) { - *aZoneFileStream >> modelNameChar; - } - while (modelNameChar != 0) { - result.modelName += modelNameChar; - *aZoneFileStream >> modelNameChar; - } - return result; -} - -Material ZoneFile_COD9::pParseAsset_Material(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); - - return Material(); -} - -Shader ZoneFile_COD9::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; - if (rawShaderType == 65535) { // Pixel shader - type = SHADER_PIXEL; - } else if (rawShaderType == 65534) { // Vertex shader - 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; - } else if (opCode == OPCODE_Comment) { - size = (int)((instructionToken >> 16) & 0x7FFF); - } else { - size = (int)((instructionToken >> 24) & 0x0f); - } - Q_UNUSED(size); - } - - - return result; -} - -TechSet ZoneFile_COD9::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; - while (techSetNameChar != 0) { - result.name += techSetNameChar; - *aZoneFileStream >> techSetNameChar; - } - result.name.replace(",", ""); - - return result; -} - -Image ZoneFile_COD9::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->skipRawData(15 * 4); - *aZoneFileStream >> result.unknownh >> result.unknowni; - - aZoneFileStream->skipRawData(4); - *aZoneFileStream >> result.unknownj; - - aZoneFileStream->skipRawData(4); - - char materialNameChar; - *aZoneFileStream >> materialNameChar; - while (materialNameChar != 0) { - result.materialName += materialNameChar; - *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; - - 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")) { - 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; - } - - return result; -} - -SoundAsset ZoneFile_COD9::pParseAsset_Sound(QDataStream *aZoneFileStream) { - SoundAsset result; - - qDebug() << aZoneFileStream->device()->pos(); - - QByteArray rootNamePtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(rootNamePtr.data(), 4); - qDebug() << "Root name ptr: " << (QString)rootNamePtr.toHex(); - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream >> result.count; - - if (rootNamePtr.toHex() == "ffffffff") { - // Read in sound file name - char soundNameChar; - *aZoneFileStream >> soundNameChar; - while (soundNameChar != 0) { - result.name += soundNameChar; - *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") { - qDebug() << "Tag Ptr: " << tagPtr.toHex(); - tagCount++; - } - aZoneFileStream->skipRawData(4); - - QByteArray pathPtr(4, Qt::Uninitialized); - aZoneFileStream->readRawData(pathPtr.data(), 4); - - if (pathPtr.toHex() == "ffffffff") { - qDebug() << "Path Ptr: " << pathPtr.toHex(); - resultCount++; - } - - aZoneFileStream->skipRawData(160); - } - - for (int i = 0; i < tagCount; i++) { - // Read in tag? - QString tag; - char tagChar; - *aZoneFileStream >> tagChar; - while (tagChar != 0) { - tag += tagChar; - *aZoneFileStream >> tagChar; - } - qDebug() << "Tag: " << tag; - } - - 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; - qDebug() << "- Data length: " << sound.dataLength; - - if (aliasPtr.toHex() == "ffffffff") { - // Read in sound alias name - char soundAliasChar; - *aZoneFileStream >> soundAliasChar; - while (soundAliasChar != 0) { - sound.alias += soundAliasChar; - *aZoneFileStream >> soundAliasChar; - } - qDebug() << "- Alias: " << sound.alias; - } - - if (aZoneFileStream->device()->peek(4) == "RIFF") { - sound.path = sound.alias; - sound.alias = ""; - } else if (namePtr.toHex() == "ffffffff") { - // Read in sound file path - char soundPathChar; - *aZoneFileStream >> soundPathChar; - while (soundPathChar != 0) { - sound.path += soundPathChar; - *aZoneFileStream >> soundPathChar; - } - sound.path.replace(",", ""); - qDebug() << "- Path: " << sound.path; - } - - if (sound.dataLength) { - QByteArray data(sound.dataLength, Qt::Uninitialized); - aZoneFileStream->readRawData(data.data(), sound.dataLength); - sound.data = data; - } - result.sounds.append(sound); - } - qDebug() << "- " << aZoneFileStream->device()->pos(); - - return result; -} - -void ZoneFile_COD9::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_LightDef(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_UIMap(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_AIType(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_FX(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - -Animation ZoneFile_COD9::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; - - // Read in x_anim file name - QString xAnimName; - char xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - while (xAnimNameChar != 0) { - result.name += xAnimNameChar; - *aZoneFileStream >> xAnimNameChar; - } - - // Parse x_anim index header - QVector sectionLengths; - for (int i = 0; i < result.numframes; i++) { - quint8 sectionlength; - *aZoneFileStream >> sectionlength; - sectionLengths.push_back(sectionlength); - // Skip padding - aZoneFileStream->skipRawData(1); - } - // Skip unknown section - aZoneFileStream->skipRawData(2 * 8); - - return result; -} - -MenuFile ZoneFile_COD9::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."; - return result; - } - for (uint i = 0; i < result.menuCount; i++) { - Menu menu; - - aZoneFileStream->skipRawData(4); // Separator - - // Read in x_anim file name - char menuFilepathChar; - *aZoneFileStream >> menuFilepathChar; - while (menuFilepathChar != 0) { - menu.filePath += menuFilepathChar; - *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; - 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; - *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA - >> 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; - - float focusColorR, focusColorG, focusColorB, focusColorA, - disabledColorR, disabledColorG, disabledColorB, disabledColorA; - *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA - >> 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; - while (menuDefNameChar != 0 && menuDefNameLen < 30) { - menuDefNameLen++; - menu.name += menuDefNameChar; - *aZoneFileStream >> menuDefNameChar; - } - - char defStringChar; - int defStringLen = 0; - *aZoneFileStream >> defStringChar; - while (defStringChar != 0 && defStringLen < 30) { - defStringLen++; - menu.definition += defStringChar; - *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; - - float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, - 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; - - 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.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; - - // 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; - *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA - >> 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; - - // 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; - //statement_s rectXExp; - //statement_s rectYExp; - //statement_s rectWExp; - //statement_s rectHExp; - //statement_s foreColorAExp; - result.menuDefs << menu; - } - return result; -} - -void ZoneFile_COD9::pParseAsset_Weapon(QDataStream *aZoneFileStream) { - //WEAPON_FILE - Q_UNUSED(aZoneFileStream); -} - -void ZoneFile_COD9::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { - //D3DBSP_DUMP - Q_UNUSED(aZoneFileStream); -} - -StringTable ZoneFile_COD9::pParseAsset_StringTable(QDataStream *aZoneFileStream) { - StringTable result; - - aZoneFileStream->skipRawData(4); - - *aZoneFileStream - >> result.columnCount - >> result.rowCount; - - // Todo fix this - result.columnCount = 0; - result.rowCount = 0; - - aZoneFileStream->skipRawData(4); - - QString stringTableName; - char stringTableNameChar; - *aZoneFileStream >> stringTableNameChar; - while (stringTableNameChar != 0) { - 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") { - char leadingContentChar; - *aZoneFileStream >> leadingContentChar; - while (leadingContentChar != 0) { - leadingContent += leadingContentChar; - *aZoneFileStream >> leadingContentChar; - } - } else { - leadingContent = pointerAddr; - } - - QString content; - char contentChar; - *aZoneFileStream >> contentChar; - while (contentChar != 0) { - content += contentChar; - *aZoneFileStream >> contentChar; - } - result.content[leadingContent] = content; - } - return result; -} - -QString ZoneFile_COD9::AssetTypeToString(const QString aAssetType) { - const QString cleanedType = aAssetType.toUpper(); - if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED - return "LOCAL STRING"; - } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED - return "RAW FILE"; - } else if (cleanedType == "1A000000") { // fx PARTIALLY VERIFIED - return "EFFECT"; - } else if (cleanedType == "09000000") { // loaded_sound PARTIALLY VERIFIED - return "SOUND"; - } else if (cleanedType == "04000000") { // x_anim PARTIALLY VERIFIED - return "ANIMATION"; - } else if (cleanedType == "0C000000") { // collision_map PARTIALLY VERIFIED - return "COLLISION MAP"; - } else if (cleanedType == "21000000") { // string_table PARTIALLY VERIFIED - return "STRING TABLE"; - } else if (cleanedType == "15000000") { // menu_file PARTIALLY VERIFIED - return "MENU"; - } else if (cleanedType == "07000000") { // tech set PARTIALLY VERIFIED - return "TECH SET"; - } else if (cleanedType == "18000000") { // weapon PARTIALLY VERIFIED - return "WEAPON"; - } else if (cleanedType == "11000000") { // gfx map PARTIALLY VERIFIED - return "GFX MAP"; - } else if (cleanedType == "12000000") { // light_def PARTIALLY VERIFIED - return "LIGHT DEF"; - } else if (cleanedType == "14000000") { // font PARTIALLY VERIFIED - return "FONT"; - } else if (cleanedType == "05000000") { // xmodel PARTIALLY VERIFIED - return "MODEL"; - } else if (cleanedType == "0D000000") { // d3dbsp PARTIALLY VERIFIED - return "D3DBSP"; - } else if (cleanedType == "06000000") { // image PARTIALLY VERIFIED - return "IMAGE"; - } else if (cleanedType == "0E000000") { // game map sp PARTIALLY VERIFIED - return "GAME MAP SP"; - } else if (cleanedType == "0B000000") { // col map sp PARTIALLY VERIFIED - return "COL MAP SP"; - } - return aAssetType; -} - -QByteArray ZoneFile_COD9::GetBinaryData() { - QByteArray result; - - return result; -} diff --git a/libs/zonefile/zonefile_cod9.h b/libs/zonefile/zonefile_cod9.h deleted file mode 100644 index a77aa9a..0000000 --- a/libs/zonefile/zonefile_cod9.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef ZONEFILE_COD9_H -#define ZONEFILE_COD9_H - -#include "zonefile.h" - -class ZoneFile_COD9 : public ZoneFile -{ -public: - ZoneFile_COD9(); - ~ZoneFile_COD9(); - - bool Load(const QByteArray aFileData, FF_PLATFORM aPlatform) override; - QString AssetTypeToString(const QString aAssetType); - - QByteArray GetBinaryData() override; - -protected: - void pParseZoneHeader(QDataStream *aZoneFileStream, FF_PLATFORM aPlatform) override; - quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; - quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; - quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; - void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; - QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; - QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; - AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; - LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; - RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; - void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; - Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - Material pParseAsset_Material(QDataStream *aZoneFileStream) override; - Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; - TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; - Image pParseAsset_Image(QDataStream *aZoneFileStream) override; - SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; - void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; - void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; - void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; - void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; - void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; - void pParseAsset_AIType(QDataStream *aZoneFileStream) override; - void pParseAsset_FX(QDataStream *aZoneFileStream) override; - Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; - MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; - void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; - void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; - StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; -}; - -#endif // ZONEFILE_COD9_H diff --git a/libs/zonefile/zonefile_factory.h b/libs/zonefile/zonefile_factory.h new file mode 100644 index 0000000..c22339f --- /dev/null +++ b/libs/zonefile/zonefile_factory.h @@ -0,0 +1,18 @@ +#ifndef ZONEFILE_FACTORY_H +#define ZONEFILE_FACTORY_H + +#include +#include + +class ZoneFile; + +class ZoneFileFactory { +public: + static std::shared_ptr Create(const QByteArray& data) { + return nullptr; + } + +private: +}; + +#endif // ZONEFILE_FACTORY_H diff --git a/tests/360/autotest_cod2_360.cpp b/tests/360/autotest_cod2_360.cpp index cd82e76..ab5a6d1 100644 --- a/tests/360/autotest_cod2_360.cpp +++ b/tests/360/autotest_cod2_360.cpp @@ -4,6 +4,7 @@ #include "autotest_cod.h" #include "compression.h" +#include "fastfile_factory.h" class AutoTest_COD2_360 : public AutoTest_COD { Q_OBJECT @@ -18,6 +19,10 @@ private slots: // Data-driven test for recompression (compression) void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -89,6 +94,7 @@ void AutoTest_COD2_360::testCompression_data() { for (const QString &filePath : zoneFiles) { QString fileName = QFileInfo(filePath).fileName(); QTest::newRow(qPrintable(fileName)) << filePath; + break; } } @@ -144,6 +150,51 @@ void AutoTest_COD2_360::testCompression() { recordResult(testName, true); } +void AutoTest_COD2_360::testFactory_data() { + QTest::addColumn("fastFilePath_cod2_360"); + + QStringList ffFiles = findFastFiles(getFastFileDirectory()); + for (const QString &filePath : ffFiles) { + QString fileName = QFileInfo(filePath).fileName(); + QTest::newRow(qPrintable(fileName)) << filePath; + } +} + +void AutoTest_COD2_360::testFactory() { + QFETCH(QString, fastFilePath_cod2_360); + + const QString testName = "Create w/ factory: " + fastFilePath_cod2_360; + + // Open the original .ff file. + QFile testFastFile(fastFilePath_cod2_360); + bool fastFileOpened = testFastFile.open(QIODevice::ReadOnly); + if (!fastFileOpened) { + recordResult(testName, false); + } + QVERIFY2(fastFileOpened + , qPrintable("Failed to open test fastfile: " + fastFilePath_cod2_360)); + const QByteArray testFFData = testFastFile.readAll(); + testFastFile.close(); + + std::shared_ptr fastFile = FastFileFactory::Create(testFFData); + + bool correctPlatform = fastFile->GetPlatform() == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory created fastfile for platform: " + fastFile->GetPlatform())); + + bool correctGame = fastFile->GetGame() == "COD2"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory created fastfile for game: " + fastFile->GetGame())); + + recordResult(testName, true); +} + void AutoTest_COD2_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/360/autotest_cod5_360.cpp b/tests/360/autotest_cod5_360.cpp index f9dff03..e0a3d92 100644 --- a/tests/360/autotest_cod5_360.cpp +++ b/tests/360/autotest_cod5_360.cpp @@ -2,6 +2,7 @@ #include #include +#include "fastfile_factory.h" #include "autotest_cod.h" #include "compression.h" @@ -18,6 +19,10 @@ private slots: // Data-driven test for recompression (compression) void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -30,9 +35,13 @@ void AutoTest_COD5_360::testDecompression_data() { QTest::addColumn("fastFilePath_cod5_360"); QStringList ffFiles = findFastFiles(getFastFileDirectory()); + int ffCount = 0; for (const QString &filePath : ffFiles) { QString fileName = QFileInfo(filePath).fileName(); QTest::newRow(qPrintable(fileName)) << filePath; + ffCount++; + + if (ffCount == FILE_MAX) { break; } } } @@ -81,9 +90,13 @@ void AutoTest_COD5_360::testCompression_data() { QTest::addColumn("zoneFilePath_cod5_360"); QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); + int zoneCount = 0; for (const QString &filePath : zoneFiles) { QString fileName = QFileInfo(filePath).fileName(); QTest::newRow(qPrintable(fileName)) << filePath; + zoneCount++; + + if (zoneCount == FILE_MAX) { break; } } } @@ -125,6 +138,44 @@ void AutoTest_COD5_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD5_360::testFactory_data() { + QTest::addColumn("fastFilePath_cod5_360"); + + QStringList ffFiles = findFastFiles(getFastFileDirectory()); + int ffCount = 0; + for (const QString &filePath : ffFiles) { + QString fileName = QFileInfo(filePath).fileName(); + QTest::newRow(qPrintable(fileName)) << filePath; + ffCount++; + + if (ffCount == FILE_MAX) { break; } + } +} + +void AutoTest_COD5_360::testFactory() { + QFETCH(QString, fastFilePath_cod5_360); + + const QString testName = "Create w/ factory: " + fastFilePath_cod5_360; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath_cod5_360); + + bool correctPlatform = fastFile->GetPlatform() == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory created fastfile for platform: " + fastFile->GetPlatform())); + + bool correctGame = fastFile->GetGame() == "COD5"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory created fastfile for game: " + fastFile->GetGame())); + + recordResult(testName, true); +} + void AutoTest_COD5_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/autotest_cod.h b/tests/autotest_cod.h index aa45d15..acb47d7 100644 --- a/tests/autotest_cod.h +++ b/tests/autotest_cod.h @@ -3,6 +3,8 @@ #include +#define FILE_MAX 1 + class AutoTest_COD : public QObject { Q_OBJECT diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 9860a28..acf3b48 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -47,10 +47,10 @@ // individual games #define TEST_COD2 0 #define TEST_COD4 0 -#define TEST_COD5 0 +#define TEST_COD5 1 #define TEST_COD6 0 #define TEST_COD7 0 -#define TEST_COD8 1 +#define TEST_COD8 0 #define TEST_COD9 0 #define TEST_COD10 0 #define TEST_COD11 0 diff --git a/tests/tests.pro b/tests/tests.pro index 798cf98..2374a7c 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -67,10 +67,11 @@ app.depends += \ libs/core \ libs/compression \ libs/encryption \ + libs/zonefile \ libs/fastfile LIBS += \ - -L$$OUT_PWD/../libs/ -lcore -lencryption -lcompression -lfastfile \ + -L$$OUT_PWD/../libs/ -lcore -lencryption -lcompression -lfastfile -lzonefile \ -L$$PWD/../third_party/xbox_sdk/lib -lxcompress64 INCLUDEPATH += \ @@ -78,14 +79,16 @@ INCLUDEPATH += \ $$PWD/../libs/core \ $$PWD/../libs/encryption \ $$PWD/../libs/compression \ - $$PWD/../libs/fastfile + $$PWD/../libs/fastfile \ + $$PWD/../libs/zonefile DEPENDPATH += \ $$PWD/../third_party/xbox_sdk/include \ $$PWD/../libs/core \ $$PWD/../libs/encryption \ $$PWD/../libs/compression \ - $$PWD/../libs/fastfile + $$PWD/../libs/fastfile \ + $$PWD/../libs/zonefile RESOURCES += From 588d03ad8f63736dd66d1a79981852fa541edac6 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 17 May 2025 22:54:28 -0400 Subject: [PATCH 02/32] Unify test factory methods and add Wii support --- libs/zonefile/zonefile_factory.h | 18 ---- tests/360/autotest_cod10_360.cpp | 74 +++++++++----- tests/360/autotest_cod11_360.cpp | 74 +++++++++----- tests/360/autotest_cod12_360.cpp | 74 +++++++++----- tests/360/autotest_cod2_360.cpp | 93 ++++++----------- tests/360/autotest_cod4_360.cpp | 74 +++++++++----- tests/360/autotest_cod5_360.cpp | 87 ++++++---------- tests/360/autotest_cod6_360.cpp | 74 +++++++++----- tests/360/autotest_cod7_360.cpp | 154 ++++++++++++++++++++--------- tests/360/autotest_cod8_360.cpp | 80 +++++++++------ tests/360/autotest_cod9_360.cpp | 74 +++++++++----- tests/PC/autotest_cod10_pc.cpp | 73 +++++++++----- tests/PC/autotest_cod11_pc.cpp | 73 +++++++++----- tests/PC/autotest_cod12_pc.cpp | 73 +++++++++----- tests/PC/autotest_cod4_pc.cpp | 72 +++++++++----- tests/PC/autotest_cod5_pc.cpp | 72 +++++++++----- tests/PC/autotest_cod6_pc.cpp | 72 +++++++++----- tests/PC/autotest_cod7_pc.cpp | 72 +++++++++----- tests/PC/autotest_cod8_pc.cpp | 73 +++++++++----- tests/PC/autotest_cod9_pc.cpp | 73 +++++++++----- tests/PS3/autotest_cod10_ps3.cpp | 72 +++++++++----- tests/PS3/autotest_cod11_ps3.cpp | 72 +++++++++----- tests/PS3/autotest_cod12_ps3.cpp | 62 ++++++++---- tests/PS3/autotest_cod4_ps3.cpp | 148 +++++++++++++++++++-------- tests/PS3/autotest_cod5_ps3.cpp | 150 +++++++++++++++++++--------- tests/PS3/autotest_cod6_ps3.cpp | 72 +++++++++----- tests/PS3/autotest_cod7_ps3.cpp | 145 +++++++++++++++++++++------ tests/PS3/autotest_cod8_ps3.cpp | 72 +++++++++----- tests/PS3/autotest_cod9_ps3.cpp | 72 +++++++++----- tests/Wii/autotest_cod4_wii.cpp | 147 +++++++++++++++++++++++++++ tests/Wii/autotest_cod7_wii.cpp | 72 +++++++++----- tests/Wii/autotest_cod8_wii.cpp | 147 +++++++++++++++++++++++++++ tests/WiiU/autotest_cod10_wiiu.cpp | 72 +++++++++----- tests/WiiU/autotest_cod9_wiiu.cpp | 72 +++++++++----- tests/autotest_cod.h | 96 ++++++++++++++---- tests/test_main.cpp | 98 +++++++++++------- tests/tests.pro | 11 +-- 37 files changed, 2101 insertions(+), 1008 deletions(-) delete mode 100644 libs/zonefile/zonefile_factory.h create mode 100644 tests/Wii/autotest_cod4_wii.cpp create mode 100644 tests/Wii/autotest_cod8_wii.cpp diff --git a/libs/zonefile/zonefile_factory.h b/libs/zonefile/zonefile_factory.h deleted file mode 100644 index c22339f..0000000 --- a/libs/zonefile/zonefile_factory.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef ZONEFILE_FACTORY_H -#define ZONEFILE_FACTORY_H - -#include -#include - -class ZoneFile; - -class ZoneFileFactory { -public: - static std::shared_ptr Create(const QByteArray& data) { - return nullptr; - } - -private: -}; - -#endif // ZONEFILE_FACTORY_H diff --git a/tests/360/autotest_cod10_360.cpp b/tests/360/autotest_cod10_360.cpp index 5bebf11..7da3e78 100644 --- a/tests/360/autotest_cod10_360.cpp +++ b/tests/360/autotest_cod10_360.cpp @@ -12,12 +12,16 @@ class AutoTest_COD10_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,24 +31,18 @@ void AutoTest_COD10_360::initTestCase() { } void AutoTest_COD10_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod10_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD10_360::testDecompression() { - QFETCH(QString, fastFilePath_cod10_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod10_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod10_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod10_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -58,10 +56,10 @@ void AutoTest_COD10_360::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod10_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod10_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -72,24 +70,18 @@ void AutoTest_COD10_360::testDecompression() { } void AutoTest_COD10_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod10_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD10_360::testCompression() { - QFETCH(QString, zoneFilePath_cod10_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod10_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod10_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod10_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -119,6 +111,36 @@ void AutoTest_COD10_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD10_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD10_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD10"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD10_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/360/autotest_cod11_360.cpp b/tests/360/autotest_cod11_360.cpp index 9b2a37f..74fe896 100644 --- a/tests/360/autotest_cod11_360.cpp +++ b/tests/360/autotest_cod11_360.cpp @@ -12,12 +12,16 @@ class AutoTest_COD11_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,24 +31,18 @@ void AutoTest_COD11_360::initTestCase() { } void AutoTest_COD11_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod11_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD11_360::testDecompression() { - QFETCH(QString, fastFilePath_cod11_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod11_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod11_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod11_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -58,10 +56,10 @@ void AutoTest_COD11_360::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod11_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod11_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -72,24 +70,18 @@ void AutoTest_COD11_360::testDecompression() { } void AutoTest_COD11_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod11_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD11_360::testCompression() { - QFETCH(QString, zoneFilePath_cod11_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod11_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod11_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod11_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -119,6 +111,36 @@ void AutoTest_COD11_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD11_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD11_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD11"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD11_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/360/autotest_cod12_360.cpp b/tests/360/autotest_cod12_360.cpp index dd7a1d0..5b90bea 100644 --- a/tests/360/autotest_cod12_360.cpp +++ b/tests/360/autotest_cod12_360.cpp @@ -12,12 +12,16 @@ class AutoTest_COD12_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,28 +31,22 @@ void AutoTest_COD12_360::initTestCase() { } void AutoTest_COD12_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod12_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD12_360::testDecompression() { - QFETCH(QString, fastFilePath_cod12_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod12_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod12_360); + QFile testFastFile(fastFilePath); bool fastFileOpened = testFastFile.open(QIODevice::ReadOnly); if (!fastFileOpened) { recordResult(testName, false); } QVERIFY2(fastFileOpened, - qPrintable("Failed to open test fastfile: " + fastFilePath_cod12_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -66,10 +64,10 @@ void AutoTest_COD12_360::testDecompression() { recordResult(testName, false); } QVERIFY2(sizeMatches, - qPrintable("Decompression validation failed for: " + fastFilePath_cod12_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod12_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -84,24 +82,18 @@ void AutoTest_COD12_360::testDecompression() { } void AutoTest_COD12_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod12_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD12_360::testCompression() { - QFETCH(QString, zoneFilePath_cod12_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod12_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod12_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod12_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -131,6 +123,36 @@ void AutoTest_COD12_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD12_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD12_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD12"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD12_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/360/autotest_cod2_360.cpp b/tests/360/autotest_cod2_360.cpp index ab5a6d1..11a8cc2 100644 --- a/tests/360/autotest_cod2_360.cpp +++ b/tests/360/autotest_cod2_360.cpp @@ -13,10 +13,10 @@ class AutoTest_COD2_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); @@ -32,28 +32,22 @@ void AutoTest_COD2_360::initTestCase() { } void AutoTest_COD2_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod2_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD2_360::testDecompression() { - QFETCH(QString, fastFilePath_cod2_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod2_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod2_360); + QFile testFastFile(fastFilePath); bool fastFileOpened = testFastFile.open(QIODevice::ReadOnly); if (!fastFileOpened) { recordResult(testName, false); } QVERIFY2(fastFileOpened - , qPrintable("Failed to open test fastfile: " + fastFilePath_cod2_360)); + , qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -68,10 +62,10 @@ void AutoTest_COD2_360::testDecompression() { zoneStream >> zoneSize; // TODO: Find new way to verify as cod2 doesn't store size in zone file //QVERIFY2(zoneSize + 44 == testZoneData.size(), - // qPrintable("Decompression validation failed for: " + fastFilePath_cod2_360)); + // qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod2_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -88,31 +82,24 @@ void AutoTest_COD2_360::testDecompression() { } void AutoTest_COD2_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod2_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - break; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD2_360::testCompression() { - QFETCH(QString, zoneFilePath_cod2_360); + QFETCH(QString, zoneFilePath); - const QString testName = "Compress: " + zoneFilePath_cod2_360; + const QString testName = "Compress: " + zoneFilePath; - QFile zoneFile(zoneFilePath_cod2_360); + QFile zoneFile(zoneFilePath); bool zoneFileOpened = zoneFile.open(QIODevice::ReadOnly); if (!zoneFileOpened) { recordResult(testName, false); } - QVERIFY2(zoneFileOpened, qPrintable("Failed to open zone file: " + zoneFilePath_cod2_360)); + QVERIFY2(zoneFileOpened, qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod2_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -126,10 +113,7 @@ void AutoTest_COD2_360::testCompression() { QByteArray header = originalFFData.left(20); - QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); - newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); - - QByteArray recompressedData = header + newCompressedData; + QByteArray recompressedData = header + Compression::CompressZLIB(decompressedData); QString recompressedFilePath = QDir(EXPORT_DIR).filePath(fi.completeBaseName() + ".ff"); QFile recompressedFile(recompressedFilePath); @@ -151,46 +135,31 @@ void AutoTest_COD2_360::testCompression() { } void AutoTest_COD2_360::testFactory_data() { - QTest::addColumn("fastFilePath_cod2_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testFactory_data(); } void AutoTest_COD2_360::testFactory() { - QFETCH(QString, fastFilePath_cod2_360); + QFETCH(QString, fastFilePath); - const QString testName = "Create w/ factory: " + fastFilePath_cod2_360; + const QString testName = "Factory ingest: " + fastFilePath; - // Open the original .ff file. - QFile testFastFile(fastFilePath_cod2_360); - bool fastFileOpened = testFastFile.open(QIODevice::ReadOnly); - if (!fastFileOpened) { - recordResult(testName, false); - } - QVERIFY2(fastFileOpened - , qPrintable("Failed to open test fastfile: " + fastFilePath_cod2_360)); - const QByteArray testFFData = testFastFile.readAll(); - testFastFile.close(); + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); - std::shared_ptr fastFile = FastFileFactory::Create(testFFData); - - bool correctPlatform = fastFile->GetPlatform() == "360"; - if (!correctPlatform) { - recordResult(testName, false); - } - QVERIFY2(correctPlatform - , qPrintable("Factory created fastfile for platform: " + fastFile->GetPlatform())); - - bool correctGame = fastFile->GetGame() == "COD2"; + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD2"; if (!correctGame) { recordResult(testName, false); } QVERIFY2(correctGame - , qPrintable("Factory created fastfile for game: " + fastFile->GetGame())); + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); recordResult(testName, true); } diff --git a/tests/360/autotest_cod4_360.cpp b/tests/360/autotest_cod4_360.cpp index 9446a47..a27f2da 100644 --- a/tests/360/autotest_cod4_360.cpp +++ b/tests/360/autotest_cod4_360.cpp @@ -12,12 +12,16 @@ class AutoTest_COD4_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,24 +31,18 @@ void AutoTest_COD4_360::initTestCase() { } void AutoTest_COD4_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod4_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD4_360::testDecompression() { - QFETCH(QString, fastFilePath_cod4_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod4_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod4_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod4_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -66,10 +64,10 @@ void AutoTest_COD4_360::testDecompression() { qDebug() << "Test zone Size: " << testZoneData.size(); } QVERIFY2(abs(zoneSize - testZoneData.size()) == 36, - qPrintable("Decompression validation failed for: " + fastFilePath_cod4_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod4_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -80,24 +78,18 @@ void AutoTest_COD4_360::testDecompression() { } void AutoTest_COD4_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod4_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD4_360::testCompression() { - QFETCH(QString, zoneFilePath_cod4_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod4_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod4_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod4_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -121,6 +113,36 @@ void AutoTest_COD4_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD4_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD4_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD4"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD4_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/360/autotest_cod5_360.cpp b/tests/360/autotest_cod5_360.cpp index e0a3d92..039c8a5 100644 --- a/tests/360/autotest_cod5_360.cpp +++ b/tests/360/autotest_cod5_360.cpp @@ -13,10 +13,10 @@ class AutoTest_COD5_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); @@ -32,29 +32,18 @@ void AutoTest_COD5_360::initTestCase() { } void AutoTest_COD5_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod5_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - int ffCount = 0; - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - ffCount++; - - if (ffCount == FILE_MAX) { break; } - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD5_360::testDecompression() { - QFETCH(QString, fastFilePath_cod5_360); - return; + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod5_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod5_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod5_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -73,10 +62,10 @@ void AutoTest_COD5_360::testDecompression() { qDebug() << "Difference: " << abs(zoneSize - testZoneData.size()); } QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod5_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod5_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -87,28 +76,18 @@ void AutoTest_COD5_360::testDecompression() { } void AutoTest_COD5_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod5_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - int zoneCount = 0; - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - zoneCount++; - - if (zoneCount == FILE_MAX) { break; } - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD5_360::testCompression() { - QFETCH(QString, zoneFilePath_cod5_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod5_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod5_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod5_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -139,39 +118,31 @@ void AutoTest_COD5_360::testCompression() { } void AutoTest_COD5_360::testFactory_data() { - QTest::addColumn("fastFilePath_cod5_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - int ffCount = 0; - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - ffCount++; - - if (ffCount == FILE_MAX) { break; } - } + AutoTest_COD::testFactory_data(); } void AutoTest_COD5_360::testFactory() { - QFETCH(QString, fastFilePath_cod5_360); + QFETCH(QString, fastFilePath); - const QString testName = "Create w/ factory: " + fastFilePath_cod5_360; + const QString testName = "Factory ingest: " + fastFilePath; - std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath_cod5_360); + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); - bool correctPlatform = fastFile->GetPlatform() == "360"; - if (!correctPlatform) { - recordResult(testName, false); - } - QVERIFY2(correctPlatform - , qPrintable("Factory created fastfile for platform: " + fastFile->GetPlatform())); - - bool correctGame = fastFile->GetGame() == "COD5"; + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD5"; if (!correctGame) { recordResult(testName, false); } QVERIFY2(correctGame - , qPrintable("Factory created fastfile for game: " + fastFile->GetGame())); + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); recordResult(testName, true); } diff --git a/tests/360/autotest_cod6_360.cpp b/tests/360/autotest_cod6_360.cpp index 7d550eb..0c47322 100644 --- a/tests/360/autotest_cod6_360.cpp +++ b/tests/360/autotest_cod6_360.cpp @@ -12,12 +12,16 @@ class AutoTest_COD6_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,24 +31,18 @@ void AutoTest_COD6_360::initTestCase() { } void AutoTest_COD6_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod6_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD6_360::testDecompression() { - QFETCH(QString, fastFilePath_cod6_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod6_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod6_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod6_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -82,10 +80,10 @@ void AutoTest_COD6_360::testDecompression() { qDebug() << "Difference: " << abs(zoneSize - testZoneData.size()); } QVERIFY2(zoneSize + 32 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod6_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod6_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -96,24 +94,18 @@ void AutoTest_COD6_360::testDecompression() { } void AutoTest_COD6_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod6_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD6_360::testCompression() { - QFETCH(QString, zoneFilePath_cod6_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod6_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod6_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod6_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -144,6 +136,36 @@ void AutoTest_COD6_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD6_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD6_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD6"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD6_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/360/autotest_cod7_360.cpp b/tests/360/autotest_cod7_360.cpp index ebdd0dc..2b32e58 100644 --- a/tests/360/autotest_cod7_360.cpp +++ b/tests/360/autotest_cod7_360.cpp @@ -13,12 +13,16 @@ class AutoTest_COD7_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -28,24 +32,18 @@ void AutoTest_COD7_360::initTestCase() { } void AutoTest_COD7_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod7_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD7_360::testDecompression() { - QFETCH(QString, fastFilePath_cod7_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod7_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod7_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod7_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -120,10 +118,10 @@ void AutoTest_COD7_360::testDecompression() { qDebug() << "Difference: " << abs(zoneSize - testZoneData.size()); } QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod7_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod7_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -134,51 +132,115 @@ void AutoTest_COD7_360::testDecompression() { } void AutoTest_COD7_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod7_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD7_360::testCompression() { - QFETCH(QString, zoneFilePath_cod7_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod7_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod7_360)); - QByteArray decompressedData = zoneFile.readAll(); + const QString testName = "Compress: " + zoneFilePath; + + // Open the original .zone file (decompressed zone data). + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), + qPrintable("Failed to open zone file: " + zoneFilePath)); + const QByteArray zoneData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod7_360); - QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); + QByteArray compressedData; + QByteArray key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); - QFile originalFile(originalFFPath); - QVERIFY2(originalFile.open(QIODevice::ReadOnly), qPrintable("Failed to open original .ff file: " + originalFFPath)); - QByteArray originalFFData = originalFile.readAll(); - originalFile.close(); + // Read the original fastfile header to recover metadata (filename, IV table, etc.) + QString ffPath = zoneFilePath; + ffPath.replace(".zone", ".ff"); + QFile originalFF(ffPath); + QVERIFY2(originalFF.open(QIODevice::ReadOnly), + qPrintable("Failed to open original fastfile: " + ffPath)); + QByteArray header = originalFF.read(0x13C); // Everything up to section data + originalFF.seek(24); // IV Table starts at 24 (after magic + skip + filename) + QByteArray fileName(32, Qt::Uninitialized); + originalFF.read(fileName.data(), 32); + originalFF.close(); - QByteArray header = originalFFData.left(12); + QByteArray ivTable = Encryption::InitIVTable(fileName); - QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); - newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); + // Rebuild sections from zone data + QDataStream zoneStream(zoneData); + zoneStream.setByteOrder(QDataStream::BigEndian); + quint32 zoneSize; + zoneStream >> zoneSize; - int remainder = (newCompressedData.size() + 12) % 32; - if (remainder != 0) { - int paddingNeeded = 32 - remainder; - newCompressedData.append(QByteArray(paddingNeeded, '\0')); + QByteArray remainingData = zoneData.mid(4); // exclude size field + const int chunkSize = 0x40000; // 256KB max section size + + QDataStream fastFileStreamOut(&compressedData, QIODevice::WriteOnly); + fastFileStreamOut.setByteOrder(QDataStream::BigEndian); + + int sectionIndex = 0; + int offset = 0; + while (offset < remainingData.size()) { + int sectionLen = qMin(chunkSize, remainingData.size() - offset); + QByteArray chunk = remainingData.mid(offset, sectionLen); + + QByteArray deflated = Compression::CompressDeflate(chunk); + + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + QByteArray encrypted = Encryption::salsa20DecryptSection(deflated, key, iv); + QByteArray sha1 = QCryptographicHash::hash(chunk, QCryptographicHash::Sha1); + Encryption::UpdateIVTable(ivTable, sectionIndex, sha1); + + fastFileStreamOut << static_cast(encrypted.size()); + fastFileStreamOut.writeRawData(encrypted.constData(), encrypted.size()); + + offset += sectionLen; + sectionIndex++; } - QByteArray recompressedData = header + newCompressedData; + // Write 0 section size terminator + fastFileStreamOut << static_cast(0); - QString recompressedFilePath = QDir(EXPORT_DIR).filePath(fi.completeBaseName() + ".ff"); - QFile recompressedFile(recompressedFilePath); - QVERIFY2(recompressedFile.open(QIODevice::WriteOnly), qPrintable("Failed to write recompressed file.")); - recompressedFile.write(recompressedData); - recompressedFile.close(); + // Combine with header + QByteArray fullFastFile = header + compressedData; - QCOMPARE(recompressedData, originalFFData); + // Save re-encoded fastfile + QFileInfo fi(zoneFilePath); + QString outputFileName = fi.completeBaseName() + "_recompressed.ff"; + QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); + QFile outputFile(outputFilePath); + QVERIFY2(outputFile.open(QIODevice::WriteOnly), + qPrintable("Failed to open output file for writing: " + outputFilePath)); + outputFile.write(fullFastFile); + outputFile.close(); +} + +void AutoTest_COD7_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD7_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD7"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); } void AutoTest_COD7_360::cleanupTestCase() { diff --git a/tests/360/autotest_cod8_360.cpp b/tests/360/autotest_cod8_360.cpp index 954d95d..18bc90b 100644 --- a/tests/360/autotest_cod8_360.cpp +++ b/tests/360/autotest_cod8_360.cpp @@ -12,12 +12,16 @@ class AutoTest_COD8_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,32 +31,21 @@ void AutoTest_COD8_360::initTestCase() { } void AutoTest_COD8_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod8_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - break; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD8_360::testDecompression() { - QFETCH(QString, fastFilePath_cod8_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod8_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod8_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod8_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); - //const QByteArray testData = Compression::CompressXMem("Hello World!"); - //const QByteArray testOutData = Compression::DecompressXMem(testData); - //qDebug() << "Input: Hello World! - Output: " << testData.toHex() << " - New: " << testOutData; - QByteArray pattern; pattern.append(static_cast(0xFF)); @@ -82,10 +75,10 @@ void AutoTest_COD8_360::testDecompression() { qDebug() << "Difference: " << abs(zoneSize - testZoneData.size()); } //QVERIFY2(zoneSize + 44 == testZoneData.size(), - // qPrintable("Decompression validation failed for: " + fastFilePath_cod8_360)); + // qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod8_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -96,25 +89,18 @@ void AutoTest_COD8_360::testDecompression() { } void AutoTest_COD8_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod8_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - break; - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD8_360::testCompression() { - QFETCH(QString, zoneFilePath_cod8_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod8_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod8_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod8_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -144,6 +130,36 @@ void AutoTest_COD8_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD8_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD8_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD8"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD8_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/360/autotest_cod9_360.cpp b/tests/360/autotest_cod9_360.cpp index 6807fa0..6df0cbc 100644 --- a/tests/360/autotest_cod9_360.cpp +++ b/tests/360/autotest_cod9_360.cpp @@ -12,12 +12,16 @@ class AutoTest_COD9_360 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,24 +31,18 @@ void AutoTest_COD9_360::initTestCase() { } void AutoTest_COD9_360::testDecompression_data() { - QTest::addColumn("fastFilePath_cod9_360"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD9_360::testDecompression() { - QFETCH(QString, fastFilePath_cod9_360); + QFETCH(QString, fastFilePath); - const QString testName = "Decompress: " + fastFilePath_cod9_360; + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod9_360); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod9_360)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -58,10 +56,10 @@ void AutoTest_COD9_360::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod9_360)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod9_360); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -72,24 +70,18 @@ void AutoTest_COD9_360::testDecompression() { } void AutoTest_COD9_360::testCompression_data() { - QTest::addColumn("zoneFilePath_cod9_360"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD9_360::testCompression() { - QFETCH(QString, zoneFilePath_cod9_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod9_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod9_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod9_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -119,6 +111,36 @@ void AutoTest_COD9_360::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD9_360::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD9_360::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD9"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "360"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD9_360::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod10_pc.cpp b/tests/PC/autotest_cod10_pc.cpp index ad2a304..ab58eef 100644 --- a/tests/PC/autotest_cod10_pc.cpp +++ b/tests/PC/autotest_cod10_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD10_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,23 +31,16 @@ void AutoTest_COD10_PC::initTestCase() { } void AutoTest_COD10_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod10_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } - void AutoTest_COD10_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod10_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod10_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod10_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -57,10 +54,10 @@ void AutoTest_COD10_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod10_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod10_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -71,24 +68,18 @@ void AutoTest_COD10_PC::testDecompression() { } void AutoTest_COD10_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod10_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD10_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod10_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod10_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod10_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod10_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -116,6 +107,36 @@ void AutoTest_COD10_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD10_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD10_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD10"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD10_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod11_pc.cpp b/tests/PC/autotest_cod11_pc.cpp index 999a038..9874b66 100644 --- a/tests/PC/autotest_cod11_pc.cpp +++ b/tests/PC/autotest_cod11_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD11_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,23 +31,16 @@ void AutoTest_COD11_PC::initTestCase() { } void AutoTest_COD11_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod11_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } - void AutoTest_COD11_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod11_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod11_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod11_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -57,10 +54,10 @@ void AutoTest_COD11_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod11_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod11_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -71,24 +68,18 @@ void AutoTest_COD11_PC::testDecompression() { } void AutoTest_COD11_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod11_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD11_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod11_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod11_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod11_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod11_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -116,6 +107,36 @@ void AutoTest_COD11_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD11_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD11_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD11"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD11_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod12_pc.cpp b/tests/PC/autotest_cod12_pc.cpp index ef8b276..f0677df 100644 --- a/tests/PC/autotest_cod12_pc.cpp +++ b/tests/PC/autotest_cod12_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD12_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,23 +31,16 @@ void AutoTest_COD12_PC::initTestCase() { } void AutoTest_COD12_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod12_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } - void AutoTest_COD12_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod12_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod12_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod12_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -57,10 +54,10 @@ void AutoTest_COD12_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod12_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod12_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -71,24 +68,18 @@ void AutoTest_COD12_PC::testDecompression() { } void AutoTest_COD12_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod12_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD12_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod12_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod12_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod12_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod12_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -116,6 +107,36 @@ void AutoTest_COD12_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD12_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD12_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD12"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD12_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod4_pc.cpp b/tests/PC/autotest_cod4_pc.cpp index b89ae4f..ab3cc1f 100644 --- a/tests/PC/autotest_cod4_pc.cpp +++ b/tests/PC/autotest_cod4_pc.cpp @@ -13,12 +13,16 @@ class AutoTest_COD4_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -28,22 +32,16 @@ void AutoTest_COD4_PC::initTestCase() { } void AutoTest_COD4_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod4_pc"); - - QStringList fastFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : fastFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD4_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod4_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod4_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod4_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -57,10 +55,10 @@ void AutoTest_COD4_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod4_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod4_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -71,24 +69,18 @@ void AutoTest_COD4_PC::testDecompression() { } void AutoTest_COD4_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod4_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD4_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod4_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod4_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod4_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod4_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -112,6 +104,36 @@ void AutoTest_COD4_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD4_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD4_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD4"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD4_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod5_pc.cpp b/tests/PC/autotest_cod5_pc.cpp index 4a1608e..6a8e3c4 100644 --- a/tests/PC/autotest_cod5_pc.cpp +++ b/tests/PC/autotest_cod5_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD5_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD5_PC::initTestCase() { } void AutoTest_COD5_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod5_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD5_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod5_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod5_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod5_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD5_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod5_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod5_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD5_PC::testDecompression() { } void AutoTest_COD5_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod5_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD5_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod5_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod5_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod5_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod5_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -116,6 +108,36 @@ void AutoTest_COD5_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD5_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD5_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath, true); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD5"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD5_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod6_pc.cpp b/tests/PC/autotest_cod6_pc.cpp index 33d0f48..4d0b75f 100644 --- a/tests/PC/autotest_cod6_pc.cpp +++ b/tests/PC/autotest_cod6_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD6_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD6_PC::initTestCase() { } void AutoTest_COD6_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod6_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD6_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod6_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod6_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod6_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD6_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 40 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod6_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod6_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD6_PC::testDecompression() { } void AutoTest_COD6_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod6_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD6_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod6_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod6_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod6_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod6_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -108,6 +100,36 @@ void AutoTest_COD6_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD6_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD6_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD6"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD6_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod7_pc.cpp b/tests/PC/autotest_cod7_pc.cpp index 3d26478..465d053 100644 --- a/tests/PC/autotest_cod7_pc.cpp +++ b/tests/PC/autotest_cod7_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD7_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD7_PC::initTestCase() { } void AutoTest_COD7_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod7_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD7_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod7_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod7_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod7_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD7_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod7_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod7_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD7_PC::testDecompression() { } void AutoTest_COD7_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod7_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD7_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod7_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod7_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod7_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod7_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -115,6 +107,36 @@ void AutoTest_COD7_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD7_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD7_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD7"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD7_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod8_pc.cpp b/tests/PC/autotest_cod8_pc.cpp index decf3b3..e4df99c 100644 --- a/tests/PC/autotest_cod8_pc.cpp +++ b/tests/PC/autotest_cod8_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD8_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,23 +31,16 @@ void AutoTest_COD8_PC::initTestCase() { } void AutoTest_COD8_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod8_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } - void AutoTest_COD8_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod8_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod8_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod8_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -57,10 +54,10 @@ void AutoTest_COD8_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod8_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod8_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -71,24 +68,18 @@ void AutoTest_COD8_PC::testDecompression() { } void AutoTest_COD8_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod8_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD8_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod8_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod8_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod8_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod8_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -116,6 +107,36 @@ void AutoTest_COD8_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD8_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD8_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD8"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD8_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PC/autotest_cod9_pc.cpp b/tests/PC/autotest_cod9_pc.cpp index f8a1e64..2d578e4 100644 --- a/tests/PC/autotest_cod9_pc.cpp +++ b/tests/PC/autotest_cod9_pc.cpp @@ -12,12 +12,16 @@ class AutoTest_COD9_PC : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,23 +31,16 @@ void AutoTest_COD9_PC::initTestCase() { } void AutoTest_COD9_PC::testDecompression_data() { - QTest::addColumn("fastFilePath_cod9_pc"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } - void AutoTest_COD9_PC::testDecompression() { - QFETCH(QString, fastFilePath_cod9_pc); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod9_pc); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod9_pc)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -57,10 +54,10 @@ void AutoTest_COD9_PC::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod9_pc)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod9_pc); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -71,24 +68,18 @@ void AutoTest_COD9_PC::testDecompression() { } void AutoTest_COD9_PC::testCompression_data() { - QTest::addColumn("zoneFilePath_cod9_pc"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD9_PC::testCompression() { - QFETCH(QString, zoneFilePath_cod9_pc); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod9_pc); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod9_pc)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod9_pc); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -116,6 +107,36 @@ void AutoTest_COD9_PC::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD9_PC::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD9_PC::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD9"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PC"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD9_PC::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod10_ps3.cpp b/tests/PS3/autotest_cod10_ps3.cpp index 6432d3b..204417d 100644 --- a/tests/PS3/autotest_cod10_ps3.cpp +++ b/tests/PS3/autotest_cod10_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD10_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD10_PS3::initTestCase() { } void AutoTest_COD10_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod10_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD10_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod10_ps3); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod10_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod10_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD10_PS3::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod10_ps3)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod10_ps3); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD10_PS3::testDecompression() { } void AutoTest_COD10_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod10_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD10_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod10_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod10_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod10_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod10_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD10_PS3::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD10_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD10_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD10"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD10_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod11_ps3.cpp b/tests/PS3/autotest_cod11_ps3.cpp index e20a48b..06d5af0 100644 --- a/tests/PS3/autotest_cod11_ps3.cpp +++ b/tests/PS3/autotest_cod11_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD11_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD11_PS3::initTestCase() { } void AutoTest_COD11_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod11_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD11_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod11_ps3); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod11_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod11_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD11_PS3::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod11_ps3)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod11_ps3); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD11_PS3::testDecompression() { } void AutoTest_COD11_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod11_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD11_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod11_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod11_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod11_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod11_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD11_PS3::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD11_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD11_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD11"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD11_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod12_ps3.cpp b/tests/PS3/autotest_cod12_ps3.cpp index 8a23cd2..1e10167 100644 --- a/tests/PS3/autotest_cod12_ps3.cpp +++ b/tests/PS3/autotest_cod12_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD12_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,13 +31,7 @@ void AutoTest_COD12_PS3::initTestCase() { } void AutoTest_COD12_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod12_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD12_PS3::testDecompression() { @@ -70,24 +68,18 @@ void AutoTest_COD12_PS3::testDecompression() { } void AutoTest_COD12_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod12_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD12_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod12_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod12_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod12_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod12_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD12_PS3::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD12_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD12_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD12"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD12_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod4_ps3.cpp b/tests/PS3/autotest_cod4_ps3.cpp index 8ca2dc2..8b1ae15 100644 --- a/tests/PS3/autotest_cod4_ps3.cpp +++ b/tests/PS3/autotest_cod4_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD4_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,67 +31,80 @@ void AutoTest_COD4_PS3::initTestCase() { } void AutoTest_COD4_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod4_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD4_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod4_ps3); + QFETCH(QString, fastFilePath); - // Open the original .ff file. - QFile testFastFile(fastFilePath_cod4_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod4_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); - // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. - const QByteArray compressedData = testFFData.mid(12); - const QByteArray testZoneData = Compression::DecompressDeflate(compressedData); + // Validate header + QVERIFY2(testFFData.size() > 12, "FastFile too small to contain header"); + QByteArray header = testFFData.left(8); + QVERIFY2(header == "IWffu100", "Invalid FastFile header!"); - // Verify the decompressed data via its embedded zone size. - QDataStream zoneStream(testZoneData); - zoneStream.setByteOrder(QDataStream::LittleEndian); - quint32 zoneSize; - zoneStream >> zoneSize; - //QVERIFY2(zoneSize + 44 == testZoneData.size(), - // qPrintable("Decompression validation failed for: " + fastFilePath_cod4_ps3)); + QDataStream headerStream(testFFData.mid(8, 6)); + headerStream.setByteOrder(QDataStream::BigEndian); + qint32 version; + qint16 identifier; + headerStream >> version >> identifier; + QVERIFY2(version == 1, "Unsupported game version"); - // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod4_ps3); + QByteArray decompressed; + int pos = 12; + + // Loop until EOF or invalid chunk + while (pos <= testFFData.size()) { + // Read 2-byte BIG-ENDIAN chunk size + quint16 chunkSize; + QDataStream chunkStream(testFFData.mid(pos, 2)); + chunkStream.setByteOrder(QDataStream::BigEndian); + chunkStream >> chunkSize; + + pos += 2; + + if (chunkSize == 0 || pos + chunkSize > testFFData.size()) { + qWarning() << "Invalid or incomplete chunk detected, stopping."; + break; + } + + const QByteArray compressedChunk = testFFData.mid(pos, chunkSize); + + decompressed.append(Compression::DecompressDeflate(compressedChunk)); + + pos += chunkSize; + } + + // Write decompressed .zone file + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); QVERIFY2(outputFile.open(QIODevice::WriteOnly), qPrintable("Failed to open output file for writing: " + outputFilePath)); - outputFile.write(testZoneData); + outputFile.write(decompressed); outputFile.close(); } -void AutoTest_COD4_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod4_ps3"); - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } +void AutoTest_COD4_PS3::testCompression_data() { + AutoTest_COD::testCompression_data(); } void AutoTest_COD4_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod4_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod4_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod4_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod4_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -96,26 +113,71 @@ void AutoTest_COD4_PS3::testCompression() { originalFile.close(); QByteArray header = originalFFData.left(12); + QByteArray recompressedData = header; - QByteArray newCompressedData = Compression::CompressDeflateWithSettings(decompressedData, Z_BEST_COMPRESSION); + // Split decompressed data into chunks (optional: same size as original or fixed 0x4000) + const int chunkSize = 0x4000; + int offset = 0; - int remainder = (newCompressedData.size() + 12) % 32; - if (remainder != 0) { - int paddingNeeded = 32 - remainder; - newCompressedData.append(QByteArray(paddingNeeded, '\0')); + while (offset < decompressedData.size()) { + QByteArray chunk = decompressedData.mid(offset, chunkSize); + offset += chunk.size(); + + QByteArray compressedChunk = Compression::CompressDeflate(chunk); + quint16 length = static_cast(compressedChunk.size()); + + // Write 2-byte big-endian chunk size + recompressedData.append(static_cast((length >> 8) & 0xFF)); + recompressedData.append(static_cast(length & 0xFF)); + + // Write compressed chunk + recompressedData.append(compressedChunk); } - QByteArray recompressedData = header + newCompressedData; + // No terminator chunk needed if original didn't have one + // Save new file QString recompressedFilePath = QDir(EXPORT_DIR).filePath(fi.completeBaseName() + ".ff"); QFile recompressedFile(recompressedFilePath); QVERIFY2(recompressedFile.open(QIODevice::WriteOnly), qPrintable("Failed to write recompressed file.")); recompressedFile.write(recompressedData); recompressedFile.close(); + // Validate byte-for-byte match QCOMPARE(recompressedData, originalFFData); } + +void AutoTest_COD4_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD4_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD4"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD4_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod5_ps3.cpp b/tests/PS3/autotest_cod5_ps3.cpp index 7b1ed14..df8e22a 100644 --- a/tests/PS3/autotest_cod5_ps3.cpp +++ b/tests/PS3/autotest_cod5_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD5_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,72 +31,79 @@ void AutoTest_COD5_PS3::initTestCase() { } void AutoTest_COD5_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod5_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD5_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod5_ps3); + QFETCH(QString, fastFilePath); - // Open the original .ff file. - QFile testFastFile(fastFilePath_cod5_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod5_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); - // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. - const QByteArray compressedData = testFFData.mid(12); - const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); + // Validate header + QVERIFY2(testFFData.size() > 12, "FastFile too small to contain header"); + QByteArray header = testFFData.left(8); + QVERIFY2(header == "IWffu100", "Invalid FastFile header!"); - // Verify the decompressed data via its embedded zone size. - QDataStream zoneStream(testZoneData); - zoneStream.setByteOrder(QDataStream::LittleEndian); - quint32 zoneSize; - zoneStream >> zoneSize; - if (abs(zoneSize - testZoneData.size()) != 36) { - qDebug() << "Zone Size: " << zoneSize; - qDebug() << "Test zone Size: " << testZoneData.size(); - qDebug() << "Difference: " << abs(zoneSize - testZoneData.size()); + QDataStream headerStream(testFFData.mid(8, 6)); + headerStream.setByteOrder(QDataStream::BigEndian); + qint32 version; + qint16 identifier; + headerStream >> version >> identifier; + QVERIFY2(version == 387, "Unsupported game version"); + + QByteArray decompressed; + int pos = 12; + + // Loop until EOF or invalid chunk + while (pos <= testFFData.size()) { + // Read 2-byte BIG-ENDIAN chunk size + quint16 chunkSize; + QDataStream chunkStream(testFFData.mid(pos, 2)); + chunkStream.setByteOrder(QDataStream::BigEndian); + chunkStream >> chunkSize; + + pos += 2; + + if (chunkSize == 0 || pos + chunkSize > testFFData.size()) { + qWarning() << "Invalid or incomplete chunk detected, stopping."; + break; + } + + const QByteArray compressedChunk = testFFData.mid(pos, chunkSize); + + decompressed.append(Compression::DecompressDeflate(compressedChunk)); + + pos += chunkSize; } - QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod5_ps3)); - // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod5_ps3); + // Write decompressed .zone file + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); QVERIFY2(outputFile.open(QIODevice::WriteOnly), qPrintable("Failed to open output file for writing: " + outputFilePath)); - outputFile.write(testZoneData); + outputFile.write(decompressed); outputFile.close(); } void AutoTest_COD5_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod5_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD5_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod5_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod5_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod5_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod5_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -101,27 +112,70 @@ void AutoTest_COD5_PS3::testCompression() { originalFile.close(); QByteArray header = originalFFData.left(12); + QByteArray recompressedData = header; - QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); - newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); + // Split decompressed data into chunks (optional: same size as original or fixed 0x4000) + const int chunkSize = 0x4000; + int offset = 0; - int remainder = (newCompressedData.size() + 12) % 32; - if (remainder != 0) { - int paddingNeeded = 32 - remainder; - newCompressedData.append(QByteArray(paddingNeeded, '\0')); + while (offset < decompressedData.size()) { + QByteArray chunk = decompressedData.mid(offset, chunkSize); + offset += chunk.size(); + + QByteArray compressedChunk = Compression::CompressDeflate(chunk); + quint16 length = static_cast(compressedChunk.size()); + + // Write 2-byte big-endian chunk size + recompressedData.append(static_cast((length >> 8) & 0xFF)); + recompressedData.append(static_cast(length & 0xFF)); + + // Write compressed chunk + recompressedData.append(compressedChunk); } - QByteArray recompressedData = header + newCompressedData; + // No terminator chunk needed if original didn't have one + // Save new file QString recompressedFilePath = QDir(EXPORT_DIR).filePath(fi.completeBaseName() + ".ff"); QFile recompressedFile(recompressedFilePath); QVERIFY2(recompressedFile.open(QIODevice::WriteOnly), qPrintable("Failed to write recompressed file.")); recompressedFile.write(recompressedData); recompressedFile.close(); + // Validate byte-for-byte match QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD5_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD5_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD5"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD5_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod6_ps3.cpp b/tests/PS3/autotest_cod6_ps3.cpp index b5b5234..42fbcac 100644 --- a/tests/PS3/autotest_cod6_ps3.cpp +++ b/tests/PS3/autotest_cod6_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD6_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD6_PS3::initTestCase() { } void AutoTest_COD6_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod6_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD6_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod6_ps3); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod6_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod6_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD6_PS3::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod6_ps3)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod6_ps3); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD6_PS3::testDecompression() { } void AutoTest_COD6_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod6_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD6_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod6_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod6_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod6_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod6_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD6_PS3::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD6_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD6_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD6"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD6_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod7_ps3.cpp b/tests/PS3/autotest_cod7_ps3.cpp index a49fa55..488c30b 100644 --- a/tests/PS3/autotest_cod7_ps3.cpp +++ b/tests/PS3/autotest_cod7_ps3.cpp @@ -4,6 +4,7 @@ #include "autotest_cod.h" #include "compression.h" +#include "encryption.h" class AutoTest_COD7_PS3 : public AutoTest_COD { Q_OBJECT @@ -12,12 +13,16 @@ class AutoTest_COD7_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,39 +32,95 @@ void AutoTest_COD7_PS3::initTestCase() { } void AutoTest_COD7_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod7_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD7_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod7_ps3); + QFETCH(QString, fastFilePath); + + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod7_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod7_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); - // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. - const QByteArray compressedData = testFFData.mid(12); - const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); + QByteArray decompressedData; + QByteArray key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); + + // Create a QDataStream on the input data. + QDataStream fastFileStream(testFFData); + fastFileStream.setByteOrder(QDataStream::BigEndian); + fastFileStream.skipRawData(16); + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + QVERIFY2(fileMagic == "PHEEBs71", + qPrintable("Invalid fast file magic: " + fileMagic)); + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Build the IV table from the fileName. + QByteArray ivTable = Encryption::InitIVTable(fileName); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + // Now the stream should be positioned at 0x13C, where sections begin. + int sectionIndex = 0; + while (true) { + qint32 sectionSize = 0; + fastFileStream >> sectionSize; + if (sectionSize == 0) + break; + + // Read the section data. + QByteArray sectionData; + sectionData.resize(sectionSize); + fastFileStream.readRawData(sectionData.data(), sectionSize); + + // Compute the IV for this section. + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + + // Decrypt the section using Salsa20. + QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); + + // Compute SHA1 hash of the decrypted data. + QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); + + // Update the IV table based on the section hash. + Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); + + // Build a compressed data buffer by prepending the two-byte zlib header. + decompressedData.append(Compression::DecompressDeflate(decData)); + + sectionIndex++; + } + + const QByteArray testZoneData = decompressedData; // Verify the decompressed data via its embedded zone size. QDataStream zoneStream(testZoneData); - zoneStream.setByteOrder(QDataStream::LittleEndian); + zoneStream.setByteOrder(QDataStream::BigEndian); quint32 zoneSize; zoneStream >> zoneSize; - QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod7_ps3)); + if (abs(zoneSize - testZoneData.size()) != 36) { + qDebug() << "Zone Size: " << zoneSize; + qDebug() << "Test zone Size: " << testZoneData.size(); + qDebug() << "Difference: " << abs(zoneSize - testZoneData.size()); + } + QVERIFY2(zoneSize + 36 == testZoneData.size(), + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod7_ps3); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +131,18 @@ void AutoTest_COD7_PS3::testDecompression() { } void AutoTest_COD7_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod7_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD7_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod7_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod7_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod7_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod7_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +172,36 @@ void AutoTest_COD7_PS3::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD7_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD7_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD7"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD7_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod8_ps3.cpp b/tests/PS3/autotest_cod8_ps3.cpp index fdae339..99d1bff 100644 --- a/tests/PS3/autotest_cod8_ps3.cpp +++ b/tests/PS3/autotest_cod8_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD8_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD8_PS3::initTestCase() { } void AutoTest_COD8_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod8_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD8_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod8_ps3); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod8_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod8_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD8_PS3::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod8_ps3)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod8_ps3); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD8_PS3::testDecompression() { } void AutoTest_COD8_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod8_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD8_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod8_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod8_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod8_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod8_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD8_PS3::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD8_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD8_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD8"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD8_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/PS3/autotest_cod9_ps3.cpp b/tests/PS3/autotest_cod9_ps3.cpp index 660f16b..c3b3f78 100644 --- a/tests/PS3/autotest_cod9_ps3.cpp +++ b/tests/PS3/autotest_cod9_ps3.cpp @@ -12,12 +12,16 @@ class AutoTest_COD9_PS3 : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD9_PS3::initTestCase() { } void AutoTest_COD9_PS3::testDecompression_data() { - QTest::addColumn("fastFilePath_cod9_ps3"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD9_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod9_ps3); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod9_ps3); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod9_ps3)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD9_PS3::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod9_ps3)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod9_ps3); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD9_PS3::testDecompression() { } void AutoTest_COD9_PS3::testCompression_data() { - QTest::addColumn("zoneFilePath_cod9_ps3"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD9_PS3::testCompression() { - QFETCH(QString, zoneFilePath_cod9_ps3); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod9_ps3); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod9_ps3)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod9_ps3); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD9_PS3::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD9_PS3::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD9_PS3::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD9"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "PS3"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD9_PS3::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/Wii/autotest_cod4_wii.cpp b/tests/Wii/autotest_cod4_wii.cpp new file mode 100644 index 0000000..a3ee6f0 --- /dev/null +++ b/tests/Wii/autotest_cod4_wii.cpp @@ -0,0 +1,147 @@ +#include +#include +#include + +#include "autotest_cod.h" +#include "compression.h" + +class AutoTest_COD4_Wii : public AutoTest_COD { + Q_OBJECT + + const QString EXPORT_DIR = "./exports/cod7/Wii"; + +private slots: + void initTestCase(); + + void testDecompression_data(); + void testDecompression(); + + void testCompression_data(); + void testCompression(); + + void testFactory_data(); + void testFactory(); + + void cleanupTestCase(); +}; + +void AutoTest_COD4_Wii::initTestCase() { + // Ensure the exports directory exists. + createDirectory(EXPORT_DIR); +} + +void AutoTest_COD4_Wii::testDecompression_data() { + AutoTest_COD::testDecompression_data(); +} + +void AutoTest_COD4_Wii::testDecompression() { + QFETCH(QString, fastFilePath); + + // Open the original .ff file. + QFile testFastFile(fastFilePath); + QVERIFY2(testFastFile.open(QIODevice::ReadOnly), + qPrintable("Failed to open test fastfile: " + fastFilePath)); + const QByteArray testFFData = testFastFile.readAll(); + testFastFile.close(); + + // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. + const QByteArray compressedData = testFFData.mid(12); + const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); + + // Verify the decompressed data via its embedded zone size. + QDataStream zoneStream(testZoneData); + zoneStream.setByteOrder(QDataStream::LittleEndian); + quint32 zoneSize; + zoneStream >> zoneSize; + QVERIFY2(zoneSize + 44 == testZoneData.size(), + qPrintable("Decompression validation failed for: " + fastFilePath)); + + // Write the decompressed zone data to the exports folder with a .zone extension. + QFileInfo fi(fastFilePath); + QString outputFileName = fi.completeBaseName() + ".zone"; + QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); + QFile outputFile(outputFilePath); + QVERIFY2(outputFile.open(QIODevice::WriteOnly), + qPrintable("Failed to open output file for writing: " + outputFilePath)); + outputFile.write(testZoneData); + outputFile.close(); +} + +void AutoTest_COD4_Wii::testCompression_data() { + AutoTest_COD::testCompression_data(); +} + +void AutoTest_COD4_Wii::testCompression() { + QFETCH(QString, zoneFilePath); + + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); + QByteArray decompressedData = zoneFile.readAll(); + zoneFile.close(); + + QFileInfo fi(zoneFilePath); + QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); + + QFile originalFile(originalFFPath); + QVERIFY2(originalFile.open(QIODevice::ReadOnly), qPrintable("Failed to open original .ff file: " + originalFFPath)); + QByteArray originalFFData = originalFile.readAll(); + originalFile.close(); + + QByteArray header = originalFFData.left(12); + + QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); + newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); + + int remainder = (newCompressedData.size() + 12) % 32; + if (remainder != 0) { + int paddingNeeded = 32 - remainder; + newCompressedData.append(QByteArray(paddingNeeded, '\0')); + } + + QByteArray recompressedData = header + newCompressedData; + + QString recompressedFilePath = QDir(EXPORT_DIR).filePath(fi.completeBaseName() + ".ff"); + QFile recompressedFile(recompressedFilePath); + QVERIFY2(recompressedFile.open(QIODevice::WriteOnly), qPrintable("Failed to write recompressed file.")); + recompressedFile.write(recompressedData); + recompressedFile.close(); + + QCOMPARE(recompressedData, originalFFData); +} + +void AutoTest_COD4_Wii::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD4_Wii::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD7"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "Wii"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + +void AutoTest_COD4_Wii::cleanupTestCase() { + // Any cleanup if necessary. +} + +// Don't generate a main() function +#include "AutoTest_COD4_Wii.moc" diff --git a/tests/Wii/autotest_cod7_wii.cpp b/tests/Wii/autotest_cod7_wii.cpp index 69948a5..c3a4251 100644 --- a/tests/Wii/autotest_cod7_wii.cpp +++ b/tests/Wii/autotest_cod7_wii.cpp @@ -12,12 +12,16 @@ class AutoTest_COD7_Wii : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD7_Wii::initTestCase() { } void AutoTest_COD7_Wii::testDecompression_data() { - QTest::addColumn("fastFilePath_cod7_wii"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD7_Wii::testDecompression() { - QFETCH(QString, fastFilePath_cod7_wii); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod7_wii); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod7_wii)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD7_Wii::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod7_wii)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod7_wii); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD7_Wii::testDecompression() { } void AutoTest_COD7_Wii::testCompression_data() { - QTest::addColumn("zoneFilePath_cod7_wii"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD7_Wii::testCompression() { - QFETCH(QString, zoneFilePath_cod2_360); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod2_360); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod2_360)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod2_360); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD7_Wii::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD7_Wii::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD7_Wii::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD7"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "Wii"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD7_Wii::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/Wii/autotest_cod8_wii.cpp b/tests/Wii/autotest_cod8_wii.cpp new file mode 100644 index 0000000..fce0ccc --- /dev/null +++ b/tests/Wii/autotest_cod8_wii.cpp @@ -0,0 +1,147 @@ +#include +#include +#include + +#include "autotest_cod.h" +#include "compression.h" + +class AutoTest_COD8_Wii : public AutoTest_COD { + Q_OBJECT + + const QString EXPORT_DIR = "./exports/cod7/Wii"; + +private slots: + void initTestCase(); + + void testDecompression_data(); + void testDecompression(); + + void testCompression_data(); + void testCompression(); + + void testFactory_data(); + void testFactory(); + + void cleanupTestCase(); +}; + +void AutoTest_COD8_Wii::initTestCase() { + // Ensure the exports directory exists. + createDirectory(EXPORT_DIR); +} + +void AutoTest_COD8_Wii::testDecompression_data() { + AutoTest_COD::testDecompression_data(); +} + +void AutoTest_COD8_Wii::testDecompression() { + QFETCH(QString, fastFilePath); + + // Open the original .ff file. + QFile testFastFile(fastFilePath); + QVERIFY2(testFastFile.open(QIODevice::ReadOnly), + qPrintable("Failed to open test fastfile: " + fastFilePath)); + const QByteArray testFFData = testFastFile.readAll(); + testFastFile.close(); + + // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. + const QByteArray compressedData = testFFData.mid(12); + const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); + + // Verify the decompressed data via its embedded zone size. + QDataStream zoneStream(testZoneData); + zoneStream.setByteOrder(QDataStream::LittleEndian); + quint32 zoneSize; + zoneStream >> zoneSize; + QVERIFY2(zoneSize + 44 == testZoneData.size(), + qPrintable("Decompression validation failed for: " + fastFilePath)); + + // Write the decompressed zone data to the exports folder with a .zone extension. + QFileInfo fi(fastFilePath); + QString outputFileName = fi.completeBaseName() + ".zone"; + QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); + QFile outputFile(outputFilePath); + QVERIFY2(outputFile.open(QIODevice::WriteOnly), + qPrintable("Failed to open output file for writing: " + outputFilePath)); + outputFile.write(testZoneData); + outputFile.close(); +} + +void AutoTest_COD8_Wii::testCompression_data() { + AutoTest_COD::testCompression_data(); +} + +void AutoTest_COD8_Wii::testCompression() { + QFETCH(QString, zoneFilePath); + + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); + QByteArray decompressedData = zoneFile.readAll(); + zoneFile.close(); + + QFileInfo fi(zoneFilePath); + QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); + + QFile originalFile(originalFFPath); + QVERIFY2(originalFile.open(QIODevice::ReadOnly), qPrintable("Failed to open original .ff file: " + originalFFPath)); + QByteArray originalFFData = originalFile.readAll(); + originalFile.close(); + + QByteArray header = originalFFData.left(12); + + QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); + newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); + + int remainder = (newCompressedData.size() + 12) % 32; + if (remainder != 0) { + int paddingNeeded = 32 - remainder; + newCompressedData.append(QByteArray(paddingNeeded, '\0')); + } + + QByteArray recompressedData = header + newCompressedData; + + QString recompressedFilePath = QDir(EXPORT_DIR).filePath(fi.completeBaseName() + ".ff"); + QFile recompressedFile(recompressedFilePath); + QVERIFY2(recompressedFile.open(QIODevice::WriteOnly), qPrintable("Failed to write recompressed file.")); + recompressedFile.write(recompressedData); + recompressedFile.close(); + + QCOMPARE(recompressedData, originalFFData); +} + +void AutoTest_COD8_Wii::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD8_Wii::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD7"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "Wii"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + +void AutoTest_COD8_Wii::cleanupTestCase() { + // Any cleanup if necessary. +} + +// Don't generate a main() function +#include "AutoTest_COD8_Wii.moc" diff --git a/tests/WiiU/autotest_cod10_wiiu.cpp b/tests/WiiU/autotest_cod10_wiiu.cpp index ec487f4..2eb61b0 100644 --- a/tests/WiiU/autotest_cod10_wiiu.cpp +++ b/tests/WiiU/autotest_cod10_wiiu.cpp @@ -12,12 +12,16 @@ class AutoTest_COD10_WiiU : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD10_WiiU::initTestCase() { } void AutoTest_COD10_WiiU::testDecompression_data() { - QTest::addColumn("fastFilePath_cod10_wiiu"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD10_WiiU::testDecompression() { - QFETCH(QString, fastFilePath_cod10_wiiu); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod10_wiiu); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod10_wiiu)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD10_WiiU::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod10_wiiu)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod10_wiiu); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD10_WiiU::testDecompression() { } void AutoTest_COD10_WiiU::testCompression_data() { - QTest::addColumn("zoneFilePath_cod10_wiiu"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD10_WiiU::testCompression() { - QFETCH(QString, zoneFilePath_cod10_wiiu); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod10_wiiu); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod10_wiiu)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod10_wiiu); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD10_WiiU::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD10_WiiU::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD10_WiiU::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD10"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "WiiU"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD10_WiiU::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/WiiU/autotest_cod9_wiiu.cpp b/tests/WiiU/autotest_cod9_wiiu.cpp index 819f170..8025fc6 100644 --- a/tests/WiiU/autotest_cod9_wiiu.cpp +++ b/tests/WiiU/autotest_cod9_wiiu.cpp @@ -12,12 +12,16 @@ class AutoTest_COD9_WiiU : public AutoTest_COD { private slots: void initTestCase(); - // Data-driven test for decompression + void testDecompression_data(); void testDecompression(); - // Data-driven test for recompression (compression) + void testCompression_data(); void testCompression(); + + void testFactory_data(); + void testFactory(); + void cleanupTestCase(); }; @@ -27,22 +31,16 @@ void AutoTest_COD9_WiiU::initTestCase() { } void AutoTest_COD9_WiiU::testDecompression_data() { - QTest::addColumn("fastFilePath_cod9_wiiu"); - - QStringList ffFiles = findFastFiles(getFastFileDirectory()); - for (const QString &filePath : ffFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testDecompression_data(); } void AutoTest_COD9_WiiU::testDecompression() { - QFETCH(QString, fastFilePath_cod9_wiiu); + QFETCH(QString, fastFilePath); // Open the original .ff file. - QFile testFastFile(fastFilePath_cod9_wiiu); + QFile testFastFile(fastFilePath); QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod9_wiiu)); + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); @@ -56,10 +54,10 @@ void AutoTest_COD9_WiiU::testDecompression() { quint32 zoneSize; zoneStream >> zoneSize; QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod9_wiiu)); + qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod9_wiiu); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); @@ -70,24 +68,18 @@ void AutoTest_COD9_WiiU::testDecompression() { } void AutoTest_COD9_WiiU::testCompression_data() { - QTest::addColumn("zoneFilePath_cod9_wiiu"); - - QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); - for (const QString &filePath : zoneFiles) { - QString fileName = QFileInfo(filePath).fileName(); - QTest::newRow(qPrintable(fileName)) << filePath; - } + AutoTest_COD::testCompression_data(); } void AutoTest_COD9_WiiU::testCompression() { - QFETCH(QString, zoneFilePath_cod9_wiiu); + QFETCH(QString, zoneFilePath); - QFile zoneFile(zoneFilePath_cod9_wiiu); - QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath_cod9_wiiu)); + QFile zoneFile(zoneFilePath); + QVERIFY2(zoneFile.open(QIODevice::ReadOnly), qPrintable("Failed to open zone file: " + zoneFilePath)); QByteArray decompressedData = zoneFile.readAll(); zoneFile.close(); - QFileInfo fi(zoneFilePath_cod9_wiiu); + QFileInfo fi(zoneFilePath); QString originalFFPath = QDir(getFastFileDirectory()).filePath(fi.completeBaseName() + ".ff"); QFile originalFile(originalFFPath); @@ -117,6 +109,36 @@ void AutoTest_COD9_WiiU::testCompression() { QCOMPARE(recompressedData, originalFFData); } +void AutoTest_COD9_WiiU::testFactory_data() { + AutoTest_COD::testFactory_data(); +} + +void AutoTest_COD9_WiiU::testFactory() { + QFETCH(QString, fastFilePath); + + const QString testName = "Factory ingest: " + fastFilePath; + + std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); + + const QString game = fastFile->GetGame(); + bool correctGame = game == "COD9"; + if (!correctGame) { + recordResult(testName, false); + } + QVERIFY2(correctGame + , qPrintable("Factory parsed wrong game [" + game + "] for fastfile: " + fastFilePath)); + + const QString platform = fastFile->GetPlatform(); + bool correctPlatform = platform == "WiiU"; + if (!correctPlatform) { + recordResult(testName, false); + } + QVERIFY2(correctPlatform + , qPrintable("Factory parsed wrong platform [" + platform + "] for fastfile: " + fastFilePath)); + + recordResult(testName, true); +} + void AutoTest_COD9_WiiU::cleanupTestCase() { // Any cleanup if necessary. } diff --git a/tests/autotest_cod.h b/tests/autotest_cod.h index acb47d7..5f09702 100644 --- a/tests/autotest_cod.h +++ b/tests/autotest_cod.h @@ -3,6 +3,8 @@ #include +#include "fastfile_factory.h" + #define FILE_MAX 1 class AutoTest_COD : public QObject { @@ -36,41 +38,93 @@ public: QDir newDir("."); newDir.mkpath(aDir); } - QStringList findFastFiles(const QString &aBaseDir, int aMaxIter = MAX_ITER) { - QStringList fastFiles; - - QDirIterator it(aBaseDir, QStringList() << "*.ff", QDir::Files, QDirIterator::Subdirectories); - - int i = 0; - while (it.hasNext() && i < aMaxIter) { - fastFiles << it.next(); - ++i; - } - - return fastFiles; - } - QStringList findZoneFiles(const QString &aBaseDir, int aMaxIter = MAX_ITER) { - QStringList zoneFiles; + QStringList findZoneFiles(const QString &aBaseDir, int aMaxIter = FILE_MAX) { + QList> fileList; QDirIterator it(aBaseDir, QStringList() << "*.zone", QDir::Files, QDirIterator::Subdirectories); - int i = 0; while (it.hasNext() && i < aMaxIter) { - zoneFiles << it.next(); + QString path = it.next(); + QFileInfo fi(path); + fileList.append(qMakePair(fi.size(), path)); ++i; } - return zoneFiles; + std::sort(fileList.begin(), fileList.end(), + [](const QPair &a, const QPair &b) { + return a.first < b.first; // sort by size + }); + + QStringList sorted; + for (const auto &pair : fileList) + sorted << pair.second; + + return sorted; } + + QStringList findFastFiles(const QString &aBaseDir, int aMaxIter = FILE_MAX) { + QList> fileList; + + QDirIterator it(aBaseDir, QStringList() << "*.ff", QDir::Files, QDirIterator::Subdirectories); + int i = 0; + while (it.hasNext() && i < aMaxIter) { + QString path = it.next(); + QFileInfo fi(path); + fileList.append(qMakePair(fi.size(), path)); + ++i; + } + + std::sort(fileList.begin(), fileList.end(), + [](const QPair &a, const QPair &b) { + return a.first < b.first; // sort by size + }); + + QStringList sorted; + for (const auto &pair : fileList) + sorted << pair.second; + + return sorted; + } + virtual void initTestCase() = 0; - virtual void testDecompression_data() = 0; + + void testDecompression_data() { + QTest::addColumn("fastFilePath"); + + QStringList ffFiles = findFastFiles(getFastFileDirectory()); + for (const QString &filePath : ffFiles) { + QString fileName = QFileInfo(filePath).fileName(); + QTest::newRow(qPrintable(fileName)) << filePath; + } + } virtual void testDecompression() = 0; - virtual void testCompression_data() = 0; + + void testCompression_data() { + QTest::addColumn("zoneFilePath"); + + QStringList zoneFiles = findZoneFiles(getZoneFileDirectory()); + for (const QString &filePath : zoneFiles) { + QString fileName = QFileInfo(filePath).fileName(); + QTest::newRow(qPrintable(fileName)) << filePath; + break; + } + } virtual void testCompression() = 0; + + void testFactory_data() { + QTest::addColumn("fastFilePath"); + + QStringList ffFiles = findFastFiles(getFastFileDirectory()); + for (const QString &filePath : ffFiles) { + QString fileName = QFileInfo(filePath).fileName(); + QTest::newRow(qPrintable(fileName)) << filePath; + } + } + virtual void testFactory() = 0; + virtual void cleanupTestCase() = 0; private: - static const int MAX_ITER = 10000; QString mFastFileDirectory; QString mZoneFileDirectory; }; diff --git a/tests/test_main.cpp b/tests/test_main.cpp index acf3b48..2fc99fd 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -32,7 +32,9 @@ #include "PS3/autotest_cod11_ps3.cpp" #include "PS3/autotest_cod12_ps3.cpp" +#include "Wii/autotest_cod4_wii.cpp" #include "Wii/autotest_cod7_wii.cpp" +#include "Wii/autotest_cod8_wii.cpp" #include "WiiU/autotest_cod9_wiiu.cpp" #include "WiiU/autotest_cod10_wiiu.cpp" @@ -47,10 +49,10 @@ // individual games #define TEST_COD2 0 #define TEST_COD4 0 -#define TEST_COD5 1 +#define TEST_COD5 0 #define TEST_COD6 0 #define TEST_COD7 0 -#define TEST_COD8 0 +#define TEST_COD8 1 #define TEST_COD9 0 #define TEST_COD10 0 #define TEST_COD11 0 @@ -185,7 +187,7 @@ int main(int argc, char *argv[]) { AutoTest_COD8_PC *test_cod8_pc = new AutoTest_COD8_PC(); test_cod8_pc->setFastFileDirectory("G:/Fast Files/PC/COD8"); test_cod8_pc->setZoneFileDirectory("./exports/cod8/PC"); - //cod8Tests << test_cod8_pc; + cod8Tests << test_cod8_pc; pcTests << test_cod8_pc; AutoTest_COD9_PC *test_cod9_pc = new AutoTest_COD9_PC(); @@ -225,7 +227,7 @@ int main(int argc, char *argv[]) { AutoTest_COD5_PS3 *test_cod5_ps3 = new AutoTest_COD5_PS3(); test_cod5_ps3->setFastFileDirectory("G:/Fast Files/PS3/COD5"); test_cod5_ps3->setZoneFileDirectory("./exports/cod5/PS3"); - //cod5Tests << test_cod5_ps3; + cod5Tests << test_cod5_ps3; ps3Tests << test_cod5_ps3; AutoTest_COD6_PS3 *test_cod6_ps3 = new AutoTest_COD6_PS3(); @@ -243,7 +245,7 @@ int main(int argc, char *argv[]) { AutoTest_COD8_PS3 *test_cod8_ps3 = new AutoTest_COD8_PS3(); test_cod8_ps3->setFastFileDirectory("G:/Fast Files/PS3/COD8"); test_cod8_ps3->setZoneFileDirectory("./exports/cod8/PS3"); - //cod8Tests << test_cod8_ps3; + cod8Tests << test_cod8_ps3; ps3Tests << test_cod8_ps3; AutoTest_COD9_PS3 *test_cod9_ps3 = new AutoTest_COD9_PS3(); @@ -274,12 +276,24 @@ int main(int argc, char *argv[]) { /********* Wii COD TESTS *********/ /**********************************/ + AutoTest_COD4_Wii *test_cod4_wii = new AutoTest_COD4_Wii(); + test_cod4_wii->setFastFileDirectory("G:/Fast Files/Wii/COD4"); + test_cod4_wii->setZoneFileDirectory("./exports/cod4/Wii"); + cod4Tests << test_cod4_wii; + wiiTests << test_cod4_wii; + AutoTest_COD7_Wii *test_cod7_wii = new AutoTest_COD7_Wii(); test_cod7_wii->setFastFileDirectory("G:/Fast Files/Wii/COD7"); test_cod7_wii->setZoneFileDirectory("./exports/cod7/Wii"); cod7Tests << test_cod7_wii; wiiTests << test_cod7_wii; + AutoTest_COD8_Wii *test_cod8_wii = new AutoTest_COD8_Wii(); + test_cod8_wii->setFastFileDirectory("G:/Fast Files/Wii/COD8"); + test_cod8_wii->setZoneFileDirectory("./exports/cod8/Wii"); + cod8Tests << test_cod8_wii; + wiiTests << test_cod8_wii; + /**********************************/ /********* WiiU COD TESTS *********/ /**********************************/ @@ -309,87 +323,101 @@ int main(int argc, char *argv[]) { qDebug() << "-- RUNNING TEST_COD4 --"; foreach (auto test, cod4Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD5) { qDebug() << "-- RUNNING TEST_COD5 --"; foreach (auto test, cod5Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD6) { qDebug() << "-- RUNNING TEST_COD6 --"; foreach (auto test, cod6Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD7) { qDebug() << "-- RUNNING TEST_COD7 --"; foreach (auto test, cod7Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD8) { qDebug() << "-- RUNNING TEST_COD8 --"; foreach (auto test, cod8Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD9) { qDebug() << "-- RUNNING TEST_COD9 --"; foreach (auto test, cod9Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD10) { qDebug() << "-- RUNNING TEST_COD10 --"; foreach (auto test, cod10Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD11) { qDebug() << "-- RUNNING TEST_COD11 --"; foreach (auto test, cod11Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } if (TEST_EVERYTHING || TEST_ALL_COD_GAMES || TEST_COD12) { qDebug() << "-- RUNNING TEST_COD12 --"; foreach (auto test, cod12Tests) { QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); } } - if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_360) { - qDebug() << "-- RUNNING TEST_360 --"; - foreach (auto test, xbox360Tests) { - QTest::qExec(test, argc, argv); - } - } - if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PC) { - qDebug() << "-- RUNNING TEST_PC --"; - foreach (auto test, pcTests) { - QTest::qExec(test, argc, argv); - } - } - if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PS3) { - qDebug() << "-- RUNNING TEST_PS3 --"; - foreach (auto test, ps3Tests) { - QTest::qExec(test, argc, argv); - } - } - if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WII) { - qDebug() << "-- RUNNING TEST_WII --"; - foreach (auto test, wiiTests) { - QTest::qExec(test, argc, argv); - } - } - if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WIIU) { - qDebug() << "-- RUNNING TEST_WIIU --"; - foreach (auto test, wiiUTests) { - QTest::qExec(test, argc, argv); - } - } + // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_360) { + // qDebug() << "-- RUNNING TEST_360 --"; + // foreach (auto test, xbox360Tests) { + // QTest::qExec(test, argc, argv); + // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + // } + // } + // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PC) { + // qDebug() << "-- RUNNING TEST_PC --"; + // foreach (auto test, pcTests) { + // QTest::qExec(test, argc, argv); + // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + // } + // } + // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PS3) { + // qDebug() << "-- RUNNING TEST_PS3 --"; + // foreach (auto test, ps3Tests) { + // QTest::qExec(test, argc, argv); + // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + // } + // } + // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WII) { + // qDebug() << "-- RUNNING TEST_WII --"; + // foreach (auto test, wiiTests) { + // QTest::qExec(test, argc, argv); + // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + // } + // } + // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WIIU) { + // qDebug() << "-- RUNNING TEST_WIIU --"; + // foreach (auto test, wiiUTests) { + // QTest::qExec(test, argc, argv); + // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + // } + // } QJsonObject root; root["project"] = "XPlor"; diff --git a/tests/tests.pro b/tests/tests.pro index 2374a7c..c0bbfc6 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -43,7 +43,9 @@ SOURCES += \ PS3/autotest_cod11_ps3.cpp \ PS3/autotest_cod12_ps3.cpp \ # Wii autotests + Wii/autotest_cod4_wii.cpp \ Wii/autotest_cod7_wii.cpp \ + Wii/autotest_cod8_wii.cpp \ # WiiU autotests WiiU/autotest_cod9_wiiu.cpp \ WiiU/autotest_cod10_wiiu.cpp \ @@ -63,13 +65,6 @@ HEADERS += \ # SOURCES -= autotest_cod5.cpp # } -app.depends += \ - libs/core \ - libs/compression \ - libs/encryption \ - libs/zonefile \ - libs/fastfile - LIBS += \ -L$$OUT_PWD/../libs/ -lcore -lencryption -lcompression -lfastfile -lzonefile \ -L$$PWD/../third_party/xbox_sdk/lib -lxcompress64 @@ -90,8 +85,6 @@ DEPENDPATH += \ $$PWD/../libs/fastfile \ $$PWD/../libs/zonefile -RESOURCES += - # Copy DLLs to Debug & Release folder QMAKE_POST_LINK += xcopy /Y /E /I \"$$PWD/../third_party/xbox_sdk/lib\\*.dll\" \"$$OUT_PWD/debug/\" $$escape_expand(\\n\\t) QMAKE_POST_LINK += xcopy /Y /E /I \"$$PWD/../third_party/xbox_sdk/lib\\*.dll\" \"$$OUT_PWD/release/\" $$escape_expand(\\n\\t) From a90f1017f7e48a2d4e017ab26e3ef91d482d1f58 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 17 May 2025 22:56:57 -0400 Subject: [PATCH 03/32] add fastfile and zonefile support for all cods --- libs/encryption/encryption.cpp | 68 +- libs/encryption/encryption.h | 3 +- libs/encryption/encryption.pro | 12 + libs/fastfile/360/fastfile_cod10_360.cpp | 115 ++ libs/fastfile/360/fastfile_cod10_360.h | 20 + libs/fastfile/360/fastfile_cod11_360.cpp | 107 ++ libs/fastfile/360/fastfile_cod11_360.h | 20 + libs/fastfile/360/fastfile_cod12_360.cpp | 107 ++ libs/fastfile/360/fastfile_cod12_360.h | 20 + libs/fastfile/360/fastfile_cod2_360.cpp | 89 ++ libs/fastfile/360/fastfile_cod2_360.h | 20 + libs/fastfile/360/fastfile_cod4_360.cpp | 93 ++ libs/fastfile/360/fastfile_cod4_360.h | 20 + libs/fastfile/360/fastfile_cod5_360.cpp | 89 ++ libs/fastfile/360/fastfile_cod5_360.h | 20 + libs/fastfile/360/fastfile_cod6_360.cpp | 151 +++ libs/fastfile/360/fastfile_cod6_360.h | 20 + libs/fastfile/360/fastfile_cod7_360.cpp | 151 +++ libs/fastfile/360/fastfile_cod7_360.h | 20 + libs/fastfile/360/fastfile_cod8_360.cpp | 115 ++ libs/fastfile/360/fastfile_cod8_360.h | 20 + libs/fastfile/360/fastfile_cod9_360.cpp | 115 ++ libs/fastfile/360/fastfile_cod9_360.h | 20 + libs/fastfile/PC/fastfile_cod10_pc.cpp | 137 +++ libs/fastfile/PC/fastfile_cod10_pc.h | 20 + libs/fastfile/PC/fastfile_cod11_pc.cpp | 137 +++ libs/fastfile/PC/fastfile_cod11_pc.h | 20 + libs/fastfile/PC/fastfile_cod12_pc.cpp | 151 +++ libs/fastfile/PC/fastfile_cod12_pc.h | 20 + libs/fastfile/PC/fastfile_cod4_pc.cpp | 93 ++ libs/fastfile/PC/fastfile_cod4_pc.h | 20 + libs/fastfile/PC/fastfile_cod5_pc.cpp | 93 ++ libs/fastfile/PC/fastfile_cod5_pc.h | 20 + libs/fastfile/PC/fastfile_cod6_pc.cpp | 93 ++ libs/fastfile/PC/fastfile_cod6_pc.h | 20 + libs/fastfile/PC/fastfile_cod7_pc.cpp | 170 +++ libs/fastfile/PC/fastfile_cod7_pc.h | 20 + libs/fastfile/PC/fastfile_cod8_pc.cpp | 170 +++ libs/fastfile/PC/fastfile_cod8_pc.h | 20 + libs/fastfile/PC/fastfile_cod9_pc.cpp | 137 +++ libs/fastfile/PC/fastfile_cod9_pc.h | 20 + libs/fastfile/PS3/fastfile_cod10_ps3.cpp | 137 +++ libs/fastfile/PS3/fastfile_cod10_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod11_ps3.cpp | 137 +++ libs/fastfile/PS3/fastfile_cod11_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod12_ps3.cpp | 137 +++ libs/fastfile/PS3/fastfile_cod12_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod4_ps3.cpp | 120 ++ libs/fastfile/PS3/fastfile_cod4_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod5_ps3.cpp | 120 ++ libs/fastfile/PS3/fastfile_cod5_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod6_ps3.cpp | 104 ++ libs/fastfile/PS3/fastfile_cod6_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod7_ps3.cpp | 173 +++ libs/fastfile/PS3/fastfile_cod7_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod8_ps3.cpp | 173 +++ libs/fastfile/PS3/fastfile_cod8_ps3.h | 20 + libs/fastfile/PS3/fastfile_cod9_ps3.cpp | 137 +++ libs/fastfile/PS3/fastfile_cod9_ps3.h | 20 + libs/fastfile/Wii/fastfile_cod4_wii.cpp | 114 ++ libs/fastfile/Wii/fastfile_cod4_wii.h | 20 + libs/fastfile/Wii/fastfile_cod7_wii.cpp | 114 ++ libs/fastfile/Wii/fastfile_cod7_wii.h | 20 + libs/fastfile/Wii/fastfile_cod8_wii.cpp | 114 ++ libs/fastfile/Wii/fastfile_cod8_wii.h | 20 + libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp | 135 +++ libs/fastfile/WiiU/fastfile_cod10_wiiu.h | 20 + libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp | 135 +++ libs/fastfile/WiiU/fastfile_cod9_wiiu.h | 20 + libs/fastfile/fastfile.pro | 56 +- libs/fastfile/fastfile_factory.h | 373 +++--- libs/zonefile/360/zonefile_cod10_360.cpp | 1072 +++++++++++++++++ libs/zonefile/360/zonefile_cod10_360.h | 52 + libs/zonefile/360/zonefile_cod11_360.cpp | 1072 +++++++++++++++++ libs/zonefile/360/zonefile_cod11_360.h | 52 + libs/zonefile/360/zonefile_cod12_360.cpp | 1207 ++++++++++++++++++++ libs/zonefile/360/zonefile_cod12_360.h | 53 + libs/zonefile/360/zonefile_cod2_360.cpp | 1112 ++++++++++++++++++ libs/zonefile/360/zonefile_cod2_360.h | 52 + libs/zonefile/360/zonefile_cod4_360.cpp | 1151 +++++++++++++++++++ libs/zonefile/360/zonefile_cod4_360.h | 54 + libs/zonefile/360/zonefile_cod5_360.cpp | 1151 +++++++++++++++++++ libs/zonefile/360/zonefile_cod5_360.h | 54 + libs/zonefile/360/zonefile_cod6_360.cpp | 1151 +++++++++++++++++++ libs/zonefile/360/zonefile_cod6_360.h | 54 + libs/zonefile/360/zonefile_cod7_360.cpp | 1077 +++++++++++++++++ libs/zonefile/360/zonefile_cod7_360.h | 52 + libs/zonefile/360/zonefile_cod8_360.cpp | 1077 +++++++++++++++++ libs/zonefile/360/zonefile_cod8_360.h | 52 + libs/zonefile/360/zonefile_cod9_360.cpp | 1072 +++++++++++++++++ libs/zonefile/360/zonefile_cod9_360.h | 52 + libs/zonefile/PC/zonefile_cod10_pc.cpp | 1072 +++++++++++++++++ libs/zonefile/PC/zonefile_cod10_pc.h | 52 + libs/zonefile/PC/zonefile_cod11_pc.cpp | 1072 +++++++++++++++++ libs/zonefile/PC/zonefile_cod11_pc.h | 52 + libs/zonefile/PC/zonefile_cod12_pc.cpp | 1207 ++++++++++++++++++++ libs/zonefile/PC/zonefile_cod12_pc.h | 53 + libs/zonefile/PC/zonefile_cod4_pc.cpp | 1140 ++++++++++++++++++ libs/zonefile/PC/zonefile_cod4_pc.h | 54 + libs/zonefile/PC/zonefile_cod5_pc.cpp | 1140 ++++++++++++++++++ libs/zonefile/PC/zonefile_cod5_pc.h | 54 + libs/zonefile/PC/zonefile_cod6_pc.cpp | 1140 ++++++++++++++++++ libs/zonefile/PC/zonefile_cod6_pc.h | 54 + libs/zonefile/PC/zonefile_cod7_pc.cpp | 1077 +++++++++++++++++ libs/zonefile/PC/zonefile_cod7_pc.h | 52 + libs/zonefile/PC/zonefile_cod8_pc.cpp | 1077 +++++++++++++++++ libs/zonefile/PC/zonefile_cod8_pc.h | 52 + libs/zonefile/PC/zonefile_cod9_pc.cpp | 1072 +++++++++++++++++ libs/zonefile/PC/zonefile_cod9_pc.h | 52 + libs/zonefile/PS3/zonefile_cod10_ps3.cpp | 1072 +++++++++++++++++ libs/zonefile/PS3/zonefile_cod10_ps3.h | 52 + libs/zonefile/PS3/zonefile_cod11_ps3.cpp | 1072 +++++++++++++++++ libs/zonefile/PS3/zonefile_cod11_ps3.h | 52 + libs/zonefile/PS3/zonefile_cod12_ps3.cpp | 1072 +++++++++++++++++ libs/zonefile/PS3/zonefile_cod12_ps3.h | 52 + libs/zonefile/PS3/zonefile_cod4_ps3.cpp | 1139 ++++++++++++++++++ libs/zonefile/PS3/zonefile_cod4_ps3.h | 54 + libs/zonefile/PS3/zonefile_cod5_ps3.cpp | 1139 ++++++++++++++++++ libs/zonefile/PS3/zonefile_cod5_ps3.h | 54 + libs/zonefile/PS3/zonefile_cod6_ps3.cpp | 1139 ++++++++++++++++++ libs/zonefile/PS3/zonefile_cod6_ps3.h | 54 + libs/zonefile/PS3/zonefile_cod7_ps3.cpp | 1077 +++++++++++++++++ libs/zonefile/PS3/zonefile_cod7_ps3.h | 52 + libs/zonefile/PS3/zonefile_cod8_ps3.cpp | 1077 +++++++++++++++++ libs/zonefile/PS3/zonefile_cod8_ps3.h | 52 + libs/zonefile/PS3/zonefile_cod9_ps3.cpp | 1072 +++++++++++++++++ libs/zonefile/PS3/zonefile_cod9_ps3.h | 52 + libs/zonefile/Wii/zonefile_cod4_wii.cpp | 1077 +++++++++++++++++ libs/zonefile/Wii/zonefile_cod4_wii.h | 52 + libs/zonefile/Wii/zonefile_cod7_wii.cpp | 1077 +++++++++++++++++ libs/zonefile/Wii/zonefile_cod7_wii.h | 52 + libs/zonefile/Wii/zonefile_cod8_wii.cpp | 1077 +++++++++++++++++ libs/zonefile/Wii/zonefile_cod8_wii.h | 52 + libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp | 1072 +++++++++++++++++ libs/zonefile/WiiU/zonefile_cod10_wiiu.h | 52 + libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp | 1072 +++++++++++++++++ libs/zonefile/WiiU/zonefile_cod9_wiiu.h | 52 + libs/zonefile/zonefile.pro | 55 +- 138 files changed, 43319 insertions(+), 180 deletions(-) create mode 100644 libs/fastfile/360/fastfile_cod10_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod10_360.h create mode 100644 libs/fastfile/360/fastfile_cod11_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod11_360.h create mode 100644 libs/fastfile/360/fastfile_cod12_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod12_360.h create mode 100644 libs/fastfile/360/fastfile_cod2_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod2_360.h create mode 100644 libs/fastfile/360/fastfile_cod4_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod4_360.h create mode 100644 libs/fastfile/360/fastfile_cod5_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod5_360.h create mode 100644 libs/fastfile/360/fastfile_cod6_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod6_360.h create mode 100644 libs/fastfile/360/fastfile_cod7_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod7_360.h create mode 100644 libs/fastfile/360/fastfile_cod8_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod8_360.h create mode 100644 libs/fastfile/360/fastfile_cod9_360.cpp create mode 100644 libs/fastfile/360/fastfile_cod9_360.h create mode 100644 libs/fastfile/PC/fastfile_cod10_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod10_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod11_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod11_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod12_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod12_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod4_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod4_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod5_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod5_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod6_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod6_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod7_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod7_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod8_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod8_pc.h create mode 100644 libs/fastfile/PC/fastfile_cod9_pc.cpp create mode 100644 libs/fastfile/PC/fastfile_cod9_pc.h create mode 100644 libs/fastfile/PS3/fastfile_cod10_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod10_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod11_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod11_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod12_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod12_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod4_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod4_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod5_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod5_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod6_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod6_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod7_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod7_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod8_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod8_ps3.h create mode 100644 libs/fastfile/PS3/fastfile_cod9_ps3.cpp create mode 100644 libs/fastfile/PS3/fastfile_cod9_ps3.h create mode 100644 libs/fastfile/Wii/fastfile_cod4_wii.cpp create mode 100644 libs/fastfile/Wii/fastfile_cod4_wii.h create mode 100644 libs/fastfile/Wii/fastfile_cod7_wii.cpp create mode 100644 libs/fastfile/Wii/fastfile_cod7_wii.h create mode 100644 libs/fastfile/Wii/fastfile_cod8_wii.cpp create mode 100644 libs/fastfile/Wii/fastfile_cod8_wii.h create mode 100644 libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp create mode 100644 libs/fastfile/WiiU/fastfile_cod10_wiiu.h create mode 100644 libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp create mode 100644 libs/fastfile/WiiU/fastfile_cod9_wiiu.h create mode 100644 libs/zonefile/360/zonefile_cod10_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod10_360.h create mode 100644 libs/zonefile/360/zonefile_cod11_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod11_360.h create mode 100644 libs/zonefile/360/zonefile_cod12_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod12_360.h create mode 100644 libs/zonefile/360/zonefile_cod2_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod2_360.h create mode 100644 libs/zonefile/360/zonefile_cod4_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod4_360.h create mode 100644 libs/zonefile/360/zonefile_cod5_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod5_360.h create mode 100644 libs/zonefile/360/zonefile_cod6_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod6_360.h create mode 100644 libs/zonefile/360/zonefile_cod7_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod7_360.h create mode 100644 libs/zonefile/360/zonefile_cod8_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod8_360.h create mode 100644 libs/zonefile/360/zonefile_cod9_360.cpp create mode 100644 libs/zonefile/360/zonefile_cod9_360.h create mode 100644 libs/zonefile/PC/zonefile_cod10_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod10_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod11_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod11_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod12_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod12_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod4_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod4_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod5_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod5_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod6_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod6_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod7_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod7_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod8_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod8_pc.h create mode 100644 libs/zonefile/PC/zonefile_cod9_pc.cpp create mode 100644 libs/zonefile/PC/zonefile_cod9_pc.h create mode 100644 libs/zonefile/PS3/zonefile_cod10_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod10_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod11_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod11_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod12_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod12_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod4_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod4_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod5_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod5_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod6_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod6_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod7_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod7_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod8_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod8_ps3.h create mode 100644 libs/zonefile/PS3/zonefile_cod9_ps3.cpp create mode 100644 libs/zonefile/PS3/zonefile_cod9_ps3.h create mode 100644 libs/zonefile/Wii/zonefile_cod4_wii.cpp create mode 100644 libs/zonefile/Wii/zonefile_cod4_wii.h create mode 100644 libs/zonefile/Wii/zonefile_cod7_wii.cpp create mode 100644 libs/zonefile/Wii/zonefile_cod7_wii.h create mode 100644 libs/zonefile/Wii/zonefile_cod8_wii.cpp create mode 100644 libs/zonefile/Wii/zonefile_cod8_wii.h create mode 100644 libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp create mode 100644 libs/zonefile/WiiU/zonefile_cod10_wiiu.h create mode 100644 libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp create mode 100644 libs/zonefile/WiiU/zonefile_cod9_wiiu.h diff --git a/libs/encryption/encryption.cpp b/libs/encryption/encryption.cpp index 613ea2e..81e2abe 100644 --- a/libs/encryption/encryption.cpp +++ b/libs/encryption/encryption.cpp @@ -1,6 +1,7 @@ #include "encryption.h" #include "QtZlib/zlib.h" #include "ecrypt-sync.h" +#include "compression.h" void Encryption::Convert32BitTo8Bit(quint32 value, quint8 *array) { array[0] = static_cast(value >> 0); @@ -350,7 +351,7 @@ void Encryption::generateNewIV(int index, const QByteArray &hash, QByteArray &iv ivCounter[index]++; } -QByteArray Encryption::decryptFastFile(const QByteArray &fastFileData) +QByteArray Encryption::decryptFastFile_BO2(const QByteArray &fastFileData) { const QByteArray bo2_salsa20_key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); @@ -438,3 +439,68 @@ QByteArray Encryption::decryptFastFile(const QByteArray &fastFileData) return finalFastFile; } + +QByteArray Encryption::decryptFastFile_BO3(const QByteArray &fastFileData) { + const QByteArray salsaKey = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + + QByteArray ivTable(0xFB0, 0); + fillIVTable(fastFileData, ivTable, 0xFB0 - 1); + + QVector ivCounter(4, 1); + QDataStream stream(fastFileData); + stream.setByteOrder(QDataStream::LittleEndian); + + QByteArray finalFastFile; + QByteArray sha1Hash(20, 0); + QByteArray ivPtr(8, 0); + int chunkIndex = 0; + + while (!stream.atEnd()) { + if (stream.device()->bytesAvailable() < 4) { + qWarning() << "No sufficient data for chunk size at offset:" << stream.device()->pos(); + break; + } + + quint32 dataLength; + stream >> dataLength; + + if (dataLength == 0 || dataLength > fastFileData.size() - stream.device()->pos()) { + qWarning() << "Invalid data length at offset:" << stream.device()->pos(); + break; + } + + fillIV(chunkIndex % 4, ivPtr, ivTable, ivCounter); + + ECRYPT_ctx x; + ECRYPT_keysetup(&x, reinterpret_cast(salsaKey.constData()), 256, 0); + ECRYPT_ivsetup(&x, reinterpret_cast(ivPtr.constData())); + + QByteArray encryptedBlock = fastFileData.mid(stream.device()->pos(), dataLength); + QByteArray decryptedBlock(dataLength, Qt::Uninitialized); + + ECRYPT_decrypt_bytes(&x, + reinterpret_cast(encryptedBlock.constData()), + reinterpret_cast(decryptedBlock.data()), + dataLength); + + // SHA1 hash update + sha1Hash = QCryptographicHash::hash(decryptedBlock, QCryptographicHash::Sha1); + + // Decompress (ZLIB raw DEFLATE) + QByteArray decompressedData = Compression::DecompressDeflate(decryptedBlock); + if (decompressedData.isEmpty()) { + qWarning() << "Failed decompression at chunk index:" << chunkIndex; + return QByteArray(); + } + + finalFastFile.append(decompressedData); + + // Update IV table using SHA1 + generateNewIV(chunkIndex % 4, sha1Hash, ivTable, ivCounter); + + stream.skipRawData(dataLength); + chunkIndex++; + } + + return finalFastFile; +} diff --git a/libs/encryption/encryption.h b/libs/encryption/encryption.h index 6b36041..f03d85e 100644 --- a/libs/encryption/encryption.h +++ b/libs/encryption/encryption.h @@ -46,7 +46,8 @@ public: static void generateNewIV(int index, const QByteArray& hash, QByteArray& ivTable, QVector& ivCounter); - static QByteArray decryptFastFile(const QByteArray& fastFileData); + static QByteArray decryptFastFile_BO2(const QByteArray& fastFileData); + static QByteArray decryptFastFile_BO3(const QByteArray& fastFileData); }; #endif // ENCRYPTION_H diff --git a/libs/encryption/encryption.pro b/libs/encryption/encryption.pro index 28d2cfb..d923b34 100644 --- a/libs/encryption/encryption.pro +++ b/libs/encryption/encryption.pro @@ -17,4 +17,16 @@ HEADERS += \ config_win32.h \ sha1.h +app.depends += \ + compression + +LIBS += \ + -L$$OUT_PWD/../ -lcompression + +INCLUDEPATH += \ + $$PWD/../compression + +DEPENDPATH += \ + $$PWD/../compression + DESTDIR = $$OUT_PWD/../ diff --git a/libs/fastfile/360/fastfile_cod10_360.cpp b/libs/fastfile/360/fastfile_cod10_360.cpp new file mode 100644 index 0000000..8ab1f72 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod10_360.cpp @@ -0,0 +1,115 @@ +#include "fastfile_cod10_360.h" +#include "zonefile_cod10_360.h" +#include "encryption.h" + +#include +#include + +FastFile_COD10_360::FastFile_COD10_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD10"); +} + +FastFile_COD10_360::FastFile_COD10_360(const QByteArray& aData) + : FastFile_COD10_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD10_360::FastFile_COD10_360(const QString aFilePath) + : FastFile_COD10_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD10_360::~FastFile_COD10_360() { + +} + +QByteArray FastFile_COD10_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD10_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD10_360::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // Select key based on game. + QByteArray key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + decompressedData = Encryption::decryptFastFile_BO2(aData); + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD10_360 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod10_360.h b/libs/fastfile/360/fastfile_cod10_360.h new file mode 100644 index 0000000..b0574a1 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod10_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD10_360_H +#define FASTFILE_COD10_360_H + +#include "fastfile.h" + +class FastFile_COD10_360 : public FastFile +{ +public: + FastFile_COD10_360(); + FastFile_COD10_360(const QByteArray& aData); + FastFile_COD10_360(const QString aFilePath); + ~FastFile_COD10_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD10_360_H diff --git a/libs/fastfile/360/fastfile_cod11_360.cpp b/libs/fastfile/360/fastfile_cod11_360.cpp new file mode 100644 index 0000000..990373f --- /dev/null +++ b/libs/fastfile/360/fastfile_cod11_360.cpp @@ -0,0 +1,107 @@ +#include "fastfile_cod11_360.h" +#include "zonefile_cod11_360.h" + +#include "utils.h" +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD11_360::FastFile_COD11_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD11"); + SetPlatform("PC"); +} + +FastFile_COD11_360::FastFile_COD11_360(const QByteArray& aData) + : FastFile_COD11_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD11_360::FastFile_COD11_360(const QString aFilePath) + : FastFile_COD11_360() { + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD11_360::~FastFile_COD11_360() { + +} + +QByteArray FastFile_COD11_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD11_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).split('.').first(); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD11_360::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Prepare data stream for parsing + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Verify magic header + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "TAff0000") { + qWarning() << "Invalid fast file magic for COD12!"; + return false; + } + + // Skip: File size (4 bytes), flags/version (4 bytes), unknown (8 bytes), build tag (32 bytes), RSA signature (256 bytes) + fastFileStream.skipRawData(4 + 4 + 8 + 32 + 256); // total 304 bytes skipped so far + 8 bytes magic = 312 bytes at correct position. + + // Correctly positioned at 0x138 + QByteArray encryptedData = aData.mid(0x138); + decompressedData = Encryption::decryptFastFile_BO3(encryptedData); + + // Output for verification/testing + Utils::ExportData(GetStem() + ".zone", decompressedData); + + // Load the zone file with decompressed data + ZoneFile_COD11_360 zoneFile; + zoneFile.SetStem(GetStem()); + if (!zoneFile.Load(decompressedData)) { + qWarning() << "Failed to load ZoneFile!"; + return false; + } + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod11_360.h b/libs/fastfile/360/fastfile_cod11_360.h new file mode 100644 index 0000000..a14c43c --- /dev/null +++ b/libs/fastfile/360/fastfile_cod11_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD11_360_H +#define FASTFILE_COD11_360_H + +#include "fastfile.h" + +class FastFile_COD11_360 : public FastFile +{ +public: + FastFile_COD11_360(); + FastFile_COD11_360(const QByteArray &aData); + FastFile_COD11_360(const QString aFilePath); + ~FastFile_COD11_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD11_360_H diff --git a/libs/fastfile/360/fastfile_cod12_360.cpp b/libs/fastfile/360/fastfile_cod12_360.cpp new file mode 100644 index 0000000..f0581a4 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod12_360.cpp @@ -0,0 +1,107 @@ +#include "fastfile_cod12_360.h" +#include "zonefile_cod12_360.h" + +#include "utils.h" +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD12_360::FastFile_COD12_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD12"); + SetPlatform("PC"); +} + +FastFile_COD12_360::FastFile_COD12_360(const QByteArray& aData) + : FastFile_COD12_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD12_360::FastFile_COD12_360(const QString aFilePath) + : FastFile_COD12_360() { + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD12_360::~FastFile_COD12_360() { + +} + +QByteArray FastFile_COD12_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD12_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).split('.').first(); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD12_360::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Prepare data stream for parsing + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Verify magic header + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "TAff0000") { + qWarning() << "Invalid fast file magic for COD12!"; + return false; + } + + // Skip: File size (4 bytes), flags/version (4 bytes), unknown (8 bytes), build tag (32 bytes), RSA signature (256 bytes) + fastFileStream.skipRawData(4 + 4 + 8 + 32 + 256); // total 304 bytes skipped so far + 8 bytes magic = 312 bytes at correct position. + + // Correctly positioned at 0x138 + QByteArray encryptedData = aData.mid(0x138); + decompressedData = Encryption::decryptFastFile_BO3(encryptedData); + + // Output for verification/testing + Utils::ExportData(GetStem() + ".zone", decompressedData); + + // Load the zone file with decompressed data + ZoneFile_COD12_360 zoneFile; + zoneFile.SetStem(GetStem()); + if (!zoneFile.Load(decompressedData)) { + qWarning() << "Failed to load ZoneFile!"; + return false; + } + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod12_360.h b/libs/fastfile/360/fastfile_cod12_360.h new file mode 100644 index 0000000..082d89a --- /dev/null +++ b/libs/fastfile/360/fastfile_cod12_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD12_360_H +#define FASTFILE_COD12_360_H + +#include "fastfile.h" + +class FastFile_COD12_360 : public FastFile +{ +public: + FastFile_COD12_360(); + FastFile_COD12_360(const QByteArray &aData); + FastFile_COD12_360(const QString aFilePath); + ~FastFile_COD12_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD12_360_H diff --git a/libs/fastfile/360/fastfile_cod2_360.cpp b/libs/fastfile/360/fastfile_cod2_360.cpp new file mode 100644 index 0000000..e61690b --- /dev/null +++ b/libs/fastfile/360/fastfile_cod2_360.cpp @@ -0,0 +1,89 @@ +#include "fastfile_cod2_360.h" + +#include "utils.h" +#include "compression.h" +#include "zonefile_cod2_360.h" + +#include +#include + +FastFile_COD2_360::FastFile_COD2_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD2"); +} + +FastFile_COD2_360::FastFile_COD2_360(const QByteArray& aData) + : FastFile_COD2_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD2_360::FastFile_COD2_360(const QString aFilePath) + : FastFile_COD2_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD2_360::~FastFile_COD2_360() { + +} + +QByteArray FastFile_COD2_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD2_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD2_360::Load(const QByteArray aData) { + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + Utils::ReadUntilHex(&fastFileStream, "78"); + QByteArray compressedData = aData.mid(fastFileStream.device()->pos()); + QByteArray decompressedData = Compression::DecompressZLIB(compressedData); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD2_360 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod2_360.h b/libs/fastfile/360/fastfile_cod2_360.h new file mode 100644 index 0000000..d1fe760 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod2_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD2_360_H +#define FASTFILE_COD2_360_H + +#include "fastfile.h" + +class FastFile_COD2_360 : public FastFile +{ +public: + FastFile_COD2_360(); + FastFile_COD2_360(const QByteArray& aData); + FastFile_COD2_360(const QString aFilePath); + ~FastFile_COD2_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD2_360_H diff --git a/libs/fastfile/360/fastfile_cod4_360.cpp b/libs/fastfile/360/fastfile_cod4_360.cpp new file mode 100644 index 0000000..5ac6889 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod4_360.cpp @@ -0,0 +1,93 @@ +#include "fastfile_cod4_360.h" +#include "zonefile_cod4_360.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD4_360::FastFile_COD4_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD4"); +} + +FastFile_COD4_360::FastFile_COD4_360(const QByteArray& aData) + : FastFile_COD4_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD4_360::FastFile_COD4_360(const QString aFilePath) + : FastFile_COD4_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD4_360::~FastFile_COD4_360() { + +} + +QByteArray FastFile_COD4_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD4_360::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + QString fastFileStem = aFilePath.split('/').last().replace(".ff", ""); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD4_360::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // For COD5, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD4_360 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod4_360.h b/libs/fastfile/360/fastfile_cod4_360.h new file mode 100644 index 0000000..5f8cdb2 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod4_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD4_360_H +#define FASTFILE_COD4_360_H + +#include "fastfile.h" + +class FastFile_COD4_360 : public FastFile +{ +public: + FastFile_COD4_360(); + FastFile_COD4_360(const QByteArray &aData); + FastFile_COD4_360(const QString aFilePath); + ~FastFile_COD4_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD4_360_H diff --git a/libs/fastfile/360/fastfile_cod5_360.cpp b/libs/fastfile/360/fastfile_cod5_360.cpp new file mode 100644 index 0000000..8608958 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod5_360.cpp @@ -0,0 +1,89 @@ +#include "fastfile_cod5_360.h" +#include "zonefile_cod5_360.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD5_360::FastFile_COD5_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD5"); +} + +FastFile_COD5_360::FastFile_COD5_360(const QByteArray& aData) + : FastFile_COD5_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD5_360::FastFile_COD5_360(const QString aFilePath) + : FastFile_COD5_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD5_360::~FastFile_COD5_360() { + +} + +QByteArray FastFile_COD5_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD5_360::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + QString fastFileStem = aFilePath.split('/').last().replace(".ff", ""); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD5_360::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // For COD5, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD5_360 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod5_360.h b/libs/fastfile/360/fastfile_cod5_360.h new file mode 100644 index 0000000..80ba475 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod5_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD5_360_H +#define FASTFILE_COD5_360_H + +#include "fastfile.h" + +class FastFile_COD5_360 : public FastFile +{ +public: + FastFile_COD5_360(); + FastFile_COD5_360(const QByteArray &aData); + FastFile_COD5_360(const QString aFilePath); + ~FastFile_COD5_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD5_360_H diff --git a/libs/fastfile/360/fastfile_cod6_360.cpp b/libs/fastfile/360/fastfile_cod6_360.cpp new file mode 100644 index 0000000..34ada0f --- /dev/null +++ b/libs/fastfile/360/fastfile_cod6_360.cpp @@ -0,0 +1,151 @@ +#include "fastfile_cod6_360.h" +#include "zonefile_cod6_360.h" + +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD6_360::FastFile_COD6_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD6"); +} + +FastFile_COD6_360::FastFile_COD6_360(const QByteArray& aData) + : FastFile_COD6_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD6_360::FastFile_COD6_360(const QString aFilePath) + : FastFile_COD6_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD6_360::~FastFile_COD6_360() { + +} + +QByteArray FastFile_COD6_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD6_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD6_360::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD6_360 zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // Select key based on game. + QByteArray key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); + fastFileStream.skipRawData(4); + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Build the IV table from the fileName. + QByteArray ivTable = Encryption::InitIVTable(fileName); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + // Now the stream should be positioned at 0x13C, where sections begin. + int sectionIndex = 0; + while (true) { + qint32 sectionSize = 0; + fastFileStream >> sectionSize; + qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize + << "Pos:" << fastFileStream.device()->pos(); + if (sectionSize == 0) + break; + + // Read the section data. + QByteArray sectionData; + sectionData.resize(sectionSize); + fastFileStream.readRawData(sectionData.data(), sectionSize); + + // Compute the IV for this section. + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + + // Decrypt the section using Salsa20. + QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); + + // Compute SHA1 hash of the decrypted data. + QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); + + // Update the IV table based on the section hash. + Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); + + // Build a compressed data buffer by prepending the two-byte zlib header. + QByteArray compressedData; + compressedData.append(char(0x78)); + compressedData.append(char(0x01)); + compressedData.append(decData); + + decompressedData.append(Compression::DecompressZLIB(compressedData)); + + sectionIndex++; + } + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod6_360.h b/libs/fastfile/360/fastfile_cod6_360.h new file mode 100644 index 0000000..8a7f430 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod6_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD6_360_H +#define FASTFILE_COD6_360_H + +#include "fastfile.h" + +class FastFile_COD6_360 : public FastFile +{ +public: + FastFile_COD6_360(); + FastFile_COD6_360(const QByteArray& aData); + FastFile_COD6_360(const QString aFilePath); + ~FastFile_COD6_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD6_360_H diff --git a/libs/fastfile/360/fastfile_cod7_360.cpp b/libs/fastfile/360/fastfile_cod7_360.cpp new file mode 100644 index 0000000..7da1f6e --- /dev/null +++ b/libs/fastfile/360/fastfile_cod7_360.cpp @@ -0,0 +1,151 @@ +#include "fastfile_cod7_360.h" +#include "zonefile_cod7_360.h" + +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD7_360::FastFile_COD7_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD7"); +} + +FastFile_COD7_360::FastFile_COD7_360(const QByteArray& aData) + : FastFile_COD7_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD7_360::FastFile_COD7_360(const QString aFilePath) + : FastFile_COD7_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD7_360::~FastFile_COD7_360() { + +} + +QByteArray FastFile_COD7_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD7_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD7_360::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD7_360 zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // Select key based on game. + QByteArray key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); + fastFileStream.skipRawData(4); + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Build the IV table from the fileName. + QByteArray ivTable = Encryption::InitIVTable(fileName); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + // Now the stream should be positioned at 0x13C, where sections begin. + int sectionIndex = 0; + while (true) { + qint32 sectionSize = 0; + fastFileStream >> sectionSize; + qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize + << "Pos:" << fastFileStream.device()->pos(); + if (sectionSize == 0) + break; + + // Read the section data. + QByteArray sectionData; + sectionData.resize(sectionSize); + fastFileStream.readRawData(sectionData.data(), sectionSize); + + // Compute the IV for this section. + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + + // Decrypt the section using Salsa20. + QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); + + // Compute SHA1 hash of the decrypted data. + QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); + + // Update the IV table based on the section hash. + Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); + + // Build a compressed data buffer by prepending the two-byte zlib header. + QByteArray compressedData; + compressedData.append(char(0x78)); + compressedData.append(char(0x01)); + compressedData.append(decData); + + decompressedData.append(Compression::DecompressZLIB(compressedData)); + + sectionIndex++; + } + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod7_360.h b/libs/fastfile/360/fastfile_cod7_360.h new file mode 100644 index 0000000..a30972c --- /dev/null +++ b/libs/fastfile/360/fastfile_cod7_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD7_360_H +#define FASTFILE_COD7_360_H + +#include "fastfile.h" + +class FastFile_COD7_360 : public FastFile +{ +public: + FastFile_COD7_360(); + FastFile_COD7_360(const QByteArray& aData); + FastFile_COD7_360(const QString aFilePath); + ~FastFile_COD7_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD7_360_H diff --git a/libs/fastfile/360/fastfile_cod8_360.cpp b/libs/fastfile/360/fastfile_cod8_360.cpp new file mode 100644 index 0000000..afdb404 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod8_360.cpp @@ -0,0 +1,115 @@ +#include "fastfile_cod8_360.h" +#include "zonefile_cod8_360.h" +#include "encryption.h" + +#include +#include + +FastFile_COD8_360::FastFile_COD8_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD8"); +} + +FastFile_COD8_360::FastFile_COD8_360(const QByteArray& aData) + : FastFile_COD8_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD8_360::FastFile_COD8_360(const QString aFilePath) + : FastFile_COD8_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD8_360::~FastFile_COD8_360() { + +} + +QByteArray FastFile_COD8_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD8_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD8_360::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // Select key based on game. + QByteArray key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + decompressedData = Encryption::decryptFastFile_BO2(aData); + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD8_360 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod8_360.h b/libs/fastfile/360/fastfile_cod8_360.h new file mode 100644 index 0000000..793cc5a --- /dev/null +++ b/libs/fastfile/360/fastfile_cod8_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD8_360_H +#define FASTFILE_COD8_360_H + +#include "fastfile.h" + +class FastFile_COD8_360 : public FastFile +{ +public: + FastFile_COD8_360(); + FastFile_COD8_360(const QByteArray& aData); + FastFile_COD8_360(const QString aFilePath); + ~FastFile_COD8_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD8_360_H diff --git a/libs/fastfile/360/fastfile_cod9_360.cpp b/libs/fastfile/360/fastfile_cod9_360.cpp new file mode 100644 index 0000000..04205f3 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod9_360.cpp @@ -0,0 +1,115 @@ +#include "fastfile_cod9_360.h" +#include "zonefile_cod9_360.h" +#include "encryption.h" + +#include +#include + +FastFile_COD9_360::FastFile_COD9_360() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("360"); + SetGame("COD9"); +} + +FastFile_COD9_360::FastFile_COD9_360(const QByteArray& aData) + : FastFile_COD9_360() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD9_360::FastFile_COD9_360(const QString aFilePath) + : FastFile_COD9_360() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD9_360::~FastFile_COD9_360() { + +} + +QByteArray FastFile_COD9_360::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD9_360::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD9_360::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // Select key based on game. + QByteArray key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + decompressedData = Encryption::decryptFastFile_BO2(aData); + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD9_360 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/360/fastfile_cod9_360.h b/libs/fastfile/360/fastfile_cod9_360.h new file mode 100644 index 0000000..84fa4a8 --- /dev/null +++ b/libs/fastfile/360/fastfile_cod9_360.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD9_360_H +#define FASTFILE_COD9_360_H + +#include "fastfile.h" + +class FastFile_COD9_360 : public FastFile +{ +public: + FastFile_COD9_360(); + FastFile_COD9_360(const QByteArray& aData); + FastFile_COD9_360(const QString aFilePath); + ~FastFile_COD9_360(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD9_360_H diff --git a/libs/fastfile/PC/fastfile_cod10_pc.cpp b/libs/fastfile/PC/fastfile_cod10_pc.cpp new file mode 100644 index 0000000..34ef0b8 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod10_pc.cpp @@ -0,0 +1,137 @@ +#include "fastfile_cod10_pc.h" +#include "zonefile_cod10_pc.h" +#include "encryption.h" + +#include +#include + +FastFile_COD10_PC::FastFile_COD10_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD10"); + SetPlatform("PC"); +} + +FastFile_COD10_PC::FastFile_COD10_PC(const QByteArray& aData) + : FastFile_COD10_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD10_PC::FastFile_COD10_PC(const QString aFilePath) + : FastFile_COD10_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD10_PC::~FastFile_COD10_PC() { + +} + +QByteArray FastFile_COD10_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD10_PC::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD10_PC::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD10_PC zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod10_pc.h b/libs/fastfile/PC/fastfile_cod10_pc.h new file mode 100644 index 0000000..c4041d4 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod10_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD10_PC_H +#define FASTFILE_COD10_PC_H + +#include "fastfile.h" + +class FastFile_COD10_PC : public FastFile +{ +public: + FastFile_COD10_PC(); + FastFile_COD10_PC(const QByteArray &aData); + FastFile_COD10_PC(const QString aFilePath); + ~FastFile_COD10_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD10_PC_H diff --git a/libs/fastfile/PC/fastfile_cod11_pc.cpp b/libs/fastfile/PC/fastfile_cod11_pc.cpp new file mode 100644 index 0000000..dafaf47 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod11_pc.cpp @@ -0,0 +1,137 @@ +#include "fastfile_cod11_pc.h" +#include "zonefile_cod11_pc.h" +#include "encryption.h" + +#include +#include + +FastFile_COD11_PC::FastFile_COD11_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD11"); + SetPlatform("PC"); +} + +FastFile_COD11_PC::FastFile_COD11_PC(const QByteArray& aData) + : FastFile_COD11_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD11_PC::FastFile_COD11_PC(const QString aFilePath) + : FastFile_COD11_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD11_PC::~FastFile_COD11_PC() { + +} + +QByteArray FastFile_COD11_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD11_PC::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD11_PC::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD11_PC zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod11_pc.h b/libs/fastfile/PC/fastfile_cod11_pc.h new file mode 100644 index 0000000..cf493d5 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod11_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD11_PC_H +#define FASTFILE_COD11_PC_H + +#include "fastfile.h" + +class FastFile_COD11_PC : public FastFile +{ +public: + FastFile_COD11_PC(); + FastFile_COD11_PC(const QByteArray &aData); + FastFile_COD11_PC(const QString aFilePath); + ~FastFile_COD11_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD11_PC_H diff --git a/libs/fastfile/PC/fastfile_cod12_pc.cpp b/libs/fastfile/PC/fastfile_cod12_pc.cpp new file mode 100644 index 0000000..5541223 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod12_pc.cpp @@ -0,0 +1,151 @@ +#include "fastfile_cod12_pc.h" +#include "zonefile_cod12_pc.h" + +#include "utils.h" +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD12_PC::FastFile_COD12_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD12"); + SetPlatform("PC"); +} + +FastFile_COD12_PC::FastFile_COD12_PC(const QByteArray& aData) + : FastFile_COD12_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD12_PC::FastFile_COD12_PC(const QString aFilePath) + : FastFile_COD12_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD12_PC::~FastFile_COD12_PC() { + +} + +QByteArray FastFile_COD12_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD12_PC::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).split('.').first(); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD12_PC::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD12_PC zoneFile; + zoneFile.SetStem(GetStem()); + + // Skip header magic + fastFileStream.skipRawData(8); + + quint32 version; + fastFileStream >> version; + + quint8 unknownFlag, compressionFlag, platformFlag, encryptionFlag; + fastFileStream >> unknownFlag >> compressionFlag >> platformFlag >> encryptionFlag; + + if (compressionFlag != 1) { + qDebug() << "Invalid fastfile compression: " << compressionFlag; + return false; + } else if (platformFlag != 0) { + qDebug() << "Invalid platform: " << platformFlag; + return false; + } else if (encryptionFlag != 0) { + qDebug() << "Decryption not supported yet!"; + return false; + } + + fastFileStream.skipRawData(128); + + quint64 size; + fastFileStream >> size; + + fastFileStream.skipRawData(432); + + int consumed = 0; + while(consumed < size) + { + // Read Block Header + quint32 compressedSize, decompressedSize, blockSize, blockPosition; + fastFileStream >> compressedSize >> decompressedSize >> blockSize >> blockPosition; + + // Validate the block position, it should match + if(blockPosition != fastFileStream.device()->pos() - 16) + { + qDebug() << "Block Position does not match Stream Position."; + return false; + } + + // Check for padding blocks + if(decompressedSize == 0) + { + fastFileStream.device()->read((((fastFileStream.device()->pos()) + ((0x800000) - 1)) & ~((0x800000) - 1)) - fastFileStream.device()->pos()); + continue; + } + + fastFileStream.device()->read(2); + + QByteArray compressedData(compressedSize - 2, Qt::Uninitialized); + qDebug() << "Data position: " << fastFileStream.device()->pos() << " - Size: " << compressedSize; + fastFileStream.readRawData(compressedData.data(), compressedSize - 2); + decompressedData.append(Compression::DecompressDeflate(compressedData)); + + consumed += decompressedSize; + + // Sinze Fast Files are aligns, we must skip the full block + fastFileStream.device()->seek(blockPosition + 16 + blockSize); + } + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod12_pc.h b/libs/fastfile/PC/fastfile_cod12_pc.h new file mode 100644 index 0000000..5613275 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod12_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD12_PC_H +#define FASTFILE_COD12_PC_H + +#include "fastfile.h" + +class FastFile_COD12_PC : public FastFile +{ +public: + FastFile_COD12_PC(); + FastFile_COD12_PC(const QByteArray &aData); + FastFile_COD12_PC(const QString aFilePath); + ~FastFile_COD12_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD12_PC_H diff --git a/libs/fastfile/PC/fastfile_cod4_pc.cpp b/libs/fastfile/PC/fastfile_cod4_pc.cpp new file mode 100644 index 0000000..c457d97 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod4_pc.cpp @@ -0,0 +1,93 @@ +#include "fastfile_cod4_pc.h" +#include "zonefile_cod4_pc.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD4_PC::FastFile_COD4_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("PC"); + SetGame("COD4"); +} + +FastFile_COD4_PC::FastFile_COD4_PC(const QByteArray& aData) + : FastFile_COD4_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD4_PC::FastFile_COD4_PC(const QString aFilePath) + : FastFile_COD4_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD4_PC::~FastFile_COD4_PC() { + +} + +QByteArray FastFile_COD4_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD4_PC::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD4_PC::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // For COD5, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD4_PC zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod4_pc.h b/libs/fastfile/PC/fastfile_cod4_pc.h new file mode 100644 index 0000000..3b5e3d0 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod4_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD4_PC_H +#define FASTFILE_COD4_PC_H + +#include "fastfile.h" + +class FastFile_COD4_PC : public FastFile +{ +public: + FastFile_COD4_PC(); + FastFile_COD4_PC(const QByteArray &aData); + FastFile_COD4_PC(const QString aFilePath); + ~FastFile_COD4_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD4_PC_H diff --git a/libs/fastfile/PC/fastfile_cod5_pc.cpp b/libs/fastfile/PC/fastfile_cod5_pc.cpp new file mode 100644 index 0000000..a277a56 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod5_pc.cpp @@ -0,0 +1,93 @@ +#include "fastfile_cod5_pc.h" +#include "zonefile_cod5_pc.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD5_PC::FastFile_COD5_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("PC"); + SetGame("COD5"); +} + +FastFile_COD5_PC::FastFile_COD5_PC(const QByteArray& aData) + : FastFile_COD5_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD5_PC::FastFile_COD5_PC(const QString aFilePath) + : FastFile_COD5_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD5_PC::~FastFile_COD5_PC() { + +} + +QByteArray FastFile_COD5_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD5_PC::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD5_PC::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // For COD5, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD5_PC zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod5_pc.h b/libs/fastfile/PC/fastfile_cod5_pc.h new file mode 100644 index 0000000..7251203 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod5_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD5_PC_H +#define FASTFILE_COD5_PC_H + +#include "fastfile.h" + +class FastFile_COD5_PC : public FastFile +{ +public: + FastFile_COD5_PC(); + FastFile_COD5_PC(const QByteArray &aData); + FastFile_COD5_PC(const QString aFilePath); + ~FastFile_COD5_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD5_PC_H diff --git a/libs/fastfile/PC/fastfile_cod6_pc.cpp b/libs/fastfile/PC/fastfile_cod6_pc.cpp new file mode 100644 index 0000000..df8c444 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod6_pc.cpp @@ -0,0 +1,93 @@ +#include "fastfile_cod6_pc.h" +#include "zonefile_cod6_pc.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD6_PC::FastFile_COD6_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetPlatform("PC"); + SetGame("COD6"); +} + +FastFile_COD6_PC::FastFile_COD6_PC(const QByteArray& aData) + : FastFile_COD6_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD6_PC::FastFile_COD6_PC(const QString aFilePath) + : FastFile_COD6_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD6_PC::~FastFile_COD6_PC() { + +} + +QByteArray FastFile_COD6_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD6_PC::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD6_PC::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // For COD5, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD6_PC zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod6_pc.h b/libs/fastfile/PC/fastfile_cod6_pc.h new file mode 100644 index 0000000..8670c99 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod6_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD6_PC_H +#define FASTFILE_COD6_PC_H + +#include "fastfile.h" + +class FastFile_COD6_PC : public FastFile +{ +public: + FastFile_COD6_PC(); + FastFile_COD6_PC(const QByteArray &aData); + FastFile_COD6_PC(const QString aFilePath); + ~FastFile_COD6_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD6_PC_H diff --git a/libs/fastfile/PC/fastfile_cod7_pc.cpp b/libs/fastfile/PC/fastfile_cod7_pc.cpp new file mode 100644 index 0000000..787688c --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod7_pc.cpp @@ -0,0 +1,170 @@ +#include "fastfile_cod7_pc.h" +#include "zonefile_cod7_pc.h" + +#include "utils.h" +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD7_PC::FastFile_COD7_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD7"); + SetPlatform("PC"); +} + +FastFile_COD7_PC::FastFile_COD7_PC(const QByteArray& aData) + : FastFile_COD7_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD7_PC::FastFile_COD7_PC(const QString aFilePath) + : FastFile_COD7_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD7_PC::~FastFile_COD7_PC() { + +} + +QByteArray FastFile_COD7_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD7_PC::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD7_PC::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD7"); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD7_PC zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Select key based on game. + QByteArray key; + fastFileStream.skipRawData(4); + if (GetPlatform() == "360") { + key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); + } else if (GetPlatform() == "PS3") { + key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); + // or + // key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Build the IV table from the fileName. + QByteArray ivTable = Encryption::InitIVTable(fileName); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + // Now the stream should be positioned at 0x13C, where sections begin. + int sectionIndex = 0; + while (true) { + qint32 sectionSize = 0; + fastFileStream >> sectionSize; + qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize + << "Pos:" << fastFileStream.device()->pos(); + if (sectionSize == 0) + break; + + // Read the section data. + QByteArray sectionData; + sectionData.resize(sectionSize); + fastFileStream.readRawData(sectionData.data(), sectionSize); + + // Compute the IV for this section. + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + + // Decrypt the section using Salsa20. + QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); + + // Compute SHA1 hash of the decrypted data. + QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); + + // Update the IV table based on the section hash. + Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); + + // Build a compressed data buffer by prepending the two-byte zlib header. + QByteArray compressedData; + compressedData.append(char(0x78)); + compressedData.append(char(0x01)); + compressedData.append(decData); + + decompressedData.append(Compression::DecompressZLIB(compressedData)); + + sectionIndex++; + } + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod7_pc.h b/libs/fastfile/PC/fastfile_cod7_pc.h new file mode 100644 index 0000000..5372582 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod7_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD7_PC_H +#define FASTFILE_COD7_PC_H + +#include "fastfile.h" + +class FastFile_COD7_PC : public FastFile +{ +public: + FastFile_COD7_PC(); + FastFile_COD7_PC(const QByteArray &aData); + FastFile_COD7_PC(const QString aFilePath); + ~FastFile_COD7_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD7_PC_H diff --git a/libs/fastfile/PC/fastfile_cod8_pc.cpp b/libs/fastfile/PC/fastfile_cod8_pc.cpp new file mode 100644 index 0000000..472098f --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod8_pc.cpp @@ -0,0 +1,170 @@ +#include "fastfile_cod8_pc.h" +#include "zonefile_cod8_pc.h" + +#include "utils.h" +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD8_PC::FastFile_COD8_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD8"); + SetPlatform("PC"); +} + +FastFile_COD8_PC::FastFile_COD8_PC(const QByteArray& aData) + : FastFile_COD8_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD8_PC::FastFile_COD8_PC(const QString aFilePath) + : FastFile_COD8_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD8_PC::~FastFile_COD8_PC() { + +} + +QByteArray FastFile_COD8_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD8_PC::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD8_PC::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD7"); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD8_PC zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Select key based on game. + QByteArray key; + fastFileStream.skipRawData(4); + if (GetPlatform() == "360") { + key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); + } else if (GetPlatform() == "PS3") { + key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); + // or + // key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Build the IV table from the fileName. + QByteArray ivTable = Encryption::InitIVTable(fileName); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + // Now the stream should be positioned at 0x13C, where sections begin. + int sectionIndex = 0; + while (true) { + qint32 sectionSize = 0; + fastFileStream >> sectionSize; + qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize + << "Pos:" << fastFileStream.device()->pos(); + if (sectionSize == 0) + break; + + // Read the section data. + QByteArray sectionData; + sectionData.resize(sectionSize); + fastFileStream.readRawData(sectionData.data(), sectionSize); + + // Compute the IV for this section. + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + + // Decrypt the section using Salsa20. + QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); + + // Compute SHA1 hash of the decrypted data. + QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); + + // Update the IV table based on the section hash. + Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); + + // Build a compressed data buffer by prepending the two-byte zlib header. + QByteArray compressedData; + compressedData.append(char(0x78)); + compressedData.append(char(0x01)); + compressedData.append(decData); + + decompressedData.append(Compression::DecompressZLIB(compressedData)); + + sectionIndex++; + } + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod8_pc.h b/libs/fastfile/PC/fastfile_cod8_pc.h new file mode 100644 index 0000000..2476836 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod8_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD8_PC_H +#define FASTFILE_COD8_PC_H + +#include "fastfile.h" + +class FastFile_COD8_PC : public FastFile +{ +public: + FastFile_COD8_PC(); + FastFile_COD8_PC(const QByteArray &aData); + FastFile_COD8_PC(const QString aFilePath); + ~FastFile_COD8_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD8_PC_H diff --git a/libs/fastfile/PC/fastfile_cod9_pc.cpp b/libs/fastfile/PC/fastfile_cod9_pc.cpp new file mode 100644 index 0000000..2b920c9 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod9_pc.cpp @@ -0,0 +1,137 @@ +#include "fastfile_cod9_pc.h" +#include "zonefile_cod9_pc.h" +#include "encryption.h" + +#include +#include + +FastFile_COD9_PC::FastFile_COD9_PC() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD9"); + SetPlatform("PC"); +} + +FastFile_COD9_PC::FastFile_COD9_PC(const QByteArray& aData) + : FastFile_COD9_PC() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD9_PC::FastFile_COD9_PC(const QString aFilePath) + : FastFile_COD9_PC() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD9_PC::~FastFile_COD9_PC() { + +} + +QByteArray FastFile_COD9_PC::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD9_PC::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD9_PC::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD9_PC zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PC/fastfile_cod9_pc.h b/libs/fastfile/PC/fastfile_cod9_pc.h new file mode 100644 index 0000000..144e680 --- /dev/null +++ b/libs/fastfile/PC/fastfile_cod9_pc.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD9_PC_H +#define FASTFILE_COD9_PC_H + +#include "fastfile.h" + +class FastFile_COD9_PC : public FastFile +{ +public: + FastFile_COD9_PC(); + FastFile_COD9_PC(const QByteArray &aData); + FastFile_COD9_PC(const QString aFilePath); + ~FastFile_COD9_PC(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD9_PC_H diff --git a/libs/fastfile/PS3/fastfile_cod10_ps3.cpp b/libs/fastfile/PS3/fastfile_cod10_ps3.cpp new file mode 100644 index 0000000..e0f1bca --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod10_ps3.cpp @@ -0,0 +1,137 @@ +#include "fastfile_cod10_ps3.h" +#include "zonefile_cod10_ps3.h" +#include "encryption.h" + +#include +#include + +FastFile_COD10_PS3::FastFile_COD10_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD10"); + SetPlatform("PS3"); +} + +FastFile_COD10_PS3::FastFile_COD10_PS3(const QByteArray& aData) + : FastFile_COD10_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD10_PS3::FastFile_COD10_PS3(const QString aFilePath) + : FastFile_COD10_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD10_PS3::~FastFile_COD10_PS3() { + +} + +QByteArray FastFile_COD10_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD10_PS3::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD10_PS3::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD10_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod10_ps3.h b/libs/fastfile/PS3/fastfile_cod10_ps3.h new file mode 100644 index 0000000..885d4cc --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod10_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD10_PS3_H +#define FASTFILE_COD10_PS3_H + +#include "fastfile.h" + +class FastFile_COD10_PS3 : public FastFile +{ +public: + FastFile_COD10_PS3(); + FastFile_COD10_PS3(const QByteArray &aData); + FastFile_COD10_PS3(const QString aFilePath); + ~FastFile_COD10_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD10_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod11_ps3.cpp b/libs/fastfile/PS3/fastfile_cod11_ps3.cpp new file mode 100644 index 0000000..34c7e91 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod11_ps3.cpp @@ -0,0 +1,137 @@ +#include "fastfile_cod11_ps3.h" +#include "zonefile_cod11_ps3.h" +#include "encryption.h" + +#include +#include + +FastFile_COD11_PS3::FastFile_COD11_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD11"); + SetPlatform("PS3"); +} + +FastFile_COD11_PS3::FastFile_COD11_PS3(const QByteArray& aData) + : FastFile_COD11_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD11_PS3::FastFile_COD11_PS3(const QString aFilePath) + : FastFile_COD11_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD11_PS3::~FastFile_COD11_PS3() { + +} + +QByteArray FastFile_COD11_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD11_PS3::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD11_PS3::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD11_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod11_ps3.h b/libs/fastfile/PS3/fastfile_cod11_ps3.h new file mode 100644 index 0000000..3424fb5 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod11_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD11_PS3_H +#define FASTFILE_COD11_PS3_H + +#include "fastfile.h" + +class FastFile_COD11_PS3 : public FastFile +{ +public: + FastFile_COD11_PS3(); + FastFile_COD11_PS3(const QByteArray &aData); + FastFile_COD11_PS3(const QString aFilePath); + ~FastFile_COD11_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD11_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod12_ps3.cpp b/libs/fastfile/PS3/fastfile_cod12_ps3.cpp new file mode 100644 index 0000000..b3768e1 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod12_ps3.cpp @@ -0,0 +1,137 @@ +#include "fastfile_cod12_ps3.h" +#include "zonefile_cod12_ps3.h" +#include "encryption.h" + +#include +#include + +FastFile_COD12_PS3::FastFile_COD12_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD12"); + SetPlatform("PS3"); +} + +FastFile_COD12_PS3::FastFile_COD12_PS3(const QByteArray& aData) + : FastFile_COD12_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD12_PS3::FastFile_COD12_PS3(const QString aFilePath) + : FastFile_COD12_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD12_PS3::~FastFile_COD12_PS3() { + +} + +QByteArray FastFile_COD12_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD12_PS3::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD12_PS3::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD12_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod12_ps3.h b/libs/fastfile/PS3/fastfile_cod12_ps3.h new file mode 100644 index 0000000..9f66318 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod12_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD12_PS3_H +#define FASTFILE_COD12_PS3_H + +#include "fastfile.h" + +class FastFile_COD12_PS3 : public FastFile +{ +public: + FastFile_COD12_PS3(); + FastFile_COD12_PS3(const QByteArray &aData); + FastFile_COD12_PS3(const QString aFilePath); + ~FastFile_COD12_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD12_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod4_ps3.cpp b/libs/fastfile/PS3/fastfile_cod4_ps3.cpp new file mode 100644 index 0000000..d6ccbe3 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod4_ps3.cpp @@ -0,0 +1,120 @@ +#include "fastfile_cod4_ps3.h" +#include "zonefile_cod4_ps3.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD4_PS3::FastFile_COD4_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD4"); + SetPlatform("PS3"); +} + +FastFile_COD4_PS3::FastFile_COD4_PS3(const QByteArray& aData) + : FastFile_COD4_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD4_PS3::FastFile_COD4_PS3(const QString aFilePath) + : FastFile_COD4_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD4_PS3::~FastFile_COD4_PS3() { + +} + +QByteArray FastFile_COD4_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD4_PS3::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD4_PS3::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + SetVersion(pParseFFVersion(&fastFileStream)); + + int pos = 12; + // Loop until EOF or invalid chunk + while (pos <= aData.size()) { + // Read 2-byte BIG-ENDIAN chunk size + quint16 chunkSize; + QDataStream chunkStream(aData.mid(pos, 2)); + chunkStream.setByteOrder(QDataStream::BigEndian); + chunkStream >> chunkSize; + + pos += 2; + + if (chunkSize == 0 || pos + chunkSize > aData.size()) { + qWarning() << "Invalid or incomplete chunk detected, stopping."; + break; + } + + const QByteArray compressedChunk = aData.mid(pos, chunkSize); + + decompressedData.append(Compression::DecompressDeflate(compressedChunk)); + + pos += chunkSize; + } + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD4_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod4_ps3.h b/libs/fastfile/PS3/fastfile_cod4_ps3.h new file mode 100644 index 0000000..78cc865 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod4_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD4_PS3_H +#define FASTFILE_COD4_PS3_H + +#include "fastfile.h" + +class FastFile_COD4_PS3 : public FastFile +{ +public: + FastFile_COD4_PS3(); + FastFile_COD4_PS3(const QByteArray &aData); + FastFile_COD4_PS3(const QString aFilePath); + ~FastFile_COD4_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD4_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod5_ps3.cpp b/libs/fastfile/PS3/fastfile_cod5_ps3.cpp new file mode 100644 index 0000000..4c84099 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod5_ps3.cpp @@ -0,0 +1,120 @@ +#include "fastfile_cod5_ps3.h" +#include "zonefile_cod5_ps3.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD5_PS3::FastFile_COD5_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD5"); + SetPlatform("PS3"); +} + +FastFile_COD5_PS3::FastFile_COD5_PS3(const QByteArray& aData) + : FastFile_COD5_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD5_PS3::FastFile_COD5_PS3(const QString aFilePath) + : FastFile_COD5_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD5_PS3::~FastFile_COD5_PS3() { + +} + +QByteArray FastFile_COD5_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD5_PS3::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD5_PS3::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + SetVersion(pParseFFVersion(&fastFileStream)); + + int pos = 12; + // Loop until EOF or invalid chunk + while (pos <= aData.size()) { + // Read 2-byte BIG-ENDIAN chunk size + quint16 chunkSize; + QDataStream chunkStream(aData.mid(pos, 2)); + chunkStream.setByteOrder(QDataStream::BigEndian); + chunkStream >> chunkSize; + + pos += 2; + + if (chunkSize == 0 || pos + chunkSize > aData.size()) { + qWarning() << "Invalid or incomplete chunk detected, stopping."; + break; + } + + const QByteArray compressedChunk = aData.mid(pos, chunkSize); + + decompressedData.append(Compression::DecompressDeflate(compressedChunk)); + + pos += chunkSize; + } + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD5_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod5_ps3.h b/libs/fastfile/PS3/fastfile_cod5_ps3.h new file mode 100644 index 0000000..2714960 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod5_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD5_PS3_H +#define FASTFILE_COD5_PS3_H + +#include "fastfile.h" + +class FastFile_COD5_PS3 : public FastFile +{ +public: + FastFile_COD5_PS3(); + FastFile_COD5_PS3(const QByteArray &aData); + FastFile_COD5_PS3(const QString aFilePath); + ~FastFile_COD5_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD5_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod6_ps3.cpp b/libs/fastfile/PS3/fastfile_cod6_ps3.cpp new file mode 100644 index 0000000..f0d0929 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod6_ps3.cpp @@ -0,0 +1,104 @@ +#include "fastfile_cod6_ps3.h" +#include "zonefile_cod6_ps3.h" + +#include "utils.h" +#include "compression.h" +#include "statusbarmanager.h" + +#include +#include + +FastFile_COD6_PS3::FastFile_COD6_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD6"); + SetPlatform("PS3"); +} + +FastFile_COD6_PS3::FastFile_COD6_PS3(const QByteArray& aData) + : FastFile_COD6_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD6_PS3::FastFile_COD6_PS3(const QString aFilePath) + : FastFile_COD6_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD6_PS3::~FastFile_COD6_PS3() { + +} + +QByteArray FastFile_COD6_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD6_PS3::Load(const QString aFilePath) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD6_PS3::Load(const QByteArray aData) { + StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + const QString platformStr = pCalculateFFPlatform(version); + SetPlatform(platformStr); + SetGame("COD5"); + + // For COD5, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + ZoneFile_COD6_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod6_ps3.h b/libs/fastfile/PS3/fastfile_cod6_ps3.h new file mode 100644 index 0000000..aecd2b0 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod6_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD6_PS3_H +#define FASTFILE_COD6_PS3_H + +#include "fastfile.h" + +class FastFile_COD6_PS3 : public FastFile +{ +public: + FastFile_COD6_PS3(); + FastFile_COD6_PS3(const QByteArray &aData); + FastFile_COD6_PS3(const QString aFilePath); + ~FastFile_COD6_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD6_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod7_ps3.cpp b/libs/fastfile/PS3/fastfile_cod7_ps3.cpp new file mode 100644 index 0000000..8bc980a --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod7_ps3.cpp @@ -0,0 +1,173 @@ +#include "fastfile_cod7_ps3.h" +#include "zonefile_cod7_ps3.h" + +#include "utils.h" +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD7_PS3::FastFile_COD7_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD7"); + SetPlatform("PS3"); +} + +FastFile_COD7_PS3::FastFile_COD7_PS3(const QByteArray& aData) + : FastFile_COD7_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD7_PS3::FastFile_COD7_PS3(const QString aFilePath) + : FastFile_COD7_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD7_PS3::~FastFile_COD7_PS3() { + +} + +QByteArray FastFile_COD7_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD7_PS3::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD7_PS3::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD7"); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD7_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Select key based on game. + QByteArray key; + fastFileStream.skipRawData(4); + if (GetPlatform() == "360") { + key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); + } else if (GetPlatform() == "PS3") { + key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); + // or + // key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Build the IV table from the fileName. + QByteArray ivTable = Encryption::InitIVTable(fileName); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + // Now the stream should be positioned at 0x13C, where sections begin. + int sectionIndex = 0; + while (true) { + qint32 sectionSize = 0; + fastFileStream >> sectionSize; + qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize + << "Pos:" << fastFileStream.device()->pos(); + if (sectionSize == 0) + break; + + // Read the section data. + QByteArray sectionData; + sectionData.resize(sectionSize); + fastFileStream.readRawData(sectionData.data(), sectionSize); + + // Compute the IV for this section. + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + + // Decrypt the section using Salsa20. + QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); + + // Compute SHA1 hash of the decrypted data. + QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); + + // Update the IV table based on the section hash. + Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); + + // Build a compressed data buffer by prepending the two-byte zlib header. + QByteArray compressedData; + compressedData.append(char(0x78)); + compressedData.append(char(0x01)); + compressedData.append(decData); + + decompressedData.append(Compression::DecompressZLIB(compressedData)); + + sectionIndex++; + } + + zoneFile.Load(decompressedData); + } + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod7_ps3.h b/libs/fastfile/PS3/fastfile_cod7_ps3.h new file mode 100644 index 0000000..3d1482d --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod7_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD7_PS3_H +#define FASTFILE_COD7_PS3_H + +#include "fastfile.h" + +class FastFile_COD7_PS3 : public FastFile +{ +public: + FastFile_COD7_PS3(); + FastFile_COD7_PS3(const QByteArray &aData); + FastFile_COD7_PS3(const QString aFilePath); + ~FastFile_COD7_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD7_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod8_ps3.cpp b/libs/fastfile/PS3/fastfile_cod8_ps3.cpp new file mode 100644 index 0000000..fef9e69 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod8_ps3.cpp @@ -0,0 +1,173 @@ +#include "fastfile_cod8_ps3.h" +#include "zonefile_cod8_ps3.h" + +#include "utils.h" +#include "compression.h" +#include "encryption.h" + +#include +#include + +FastFile_COD8_PS3::FastFile_COD8_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD8"); + SetPlatform("PS3"); +} + +FastFile_COD8_PS3::FastFile_COD8_PS3(const QByteArray& aData) + : FastFile_COD8_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD8_PS3::FastFile_COD8_PS3(const QString aFilePath) + : FastFile_COD8_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD8_PS3::~FastFile_COD8_PS3() { + +} + +QByteArray FastFile_COD8_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD8_PS3::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD8_PS3::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD7"); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD8_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Select key based on game. + QByteArray key; + fastFileStream.skipRawData(4); + if (GetPlatform() == "360") { + key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); + } else if (GetPlatform() == "PS3") { + key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); + // or + // key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Build the IV table from the fileName. + QByteArray ivTable = Encryption::InitIVTable(fileName); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + // Now the stream should be positioned at 0x13C, where sections begin. + int sectionIndex = 0; + while (true) { + qint32 sectionSize = 0; + fastFileStream >> sectionSize; + qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize + << "Pos:" << fastFileStream.device()->pos(); + if (sectionSize == 0) + break; + + // Read the section data. + QByteArray sectionData; + sectionData.resize(sectionSize); + fastFileStream.readRawData(sectionData.data(), sectionSize); + + // Compute the IV for this section. + QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); + + // Decrypt the section using Salsa20. + QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); + + // Compute SHA1 hash of the decrypted data. + QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); + + // Update the IV table based on the section hash. + Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); + + // Build a compressed data buffer by prepending the two-byte zlib header. + QByteArray compressedData; + compressedData.append(char(0x78)); + compressedData.append(char(0x01)); + compressedData.append(decData); + + decompressedData.append(Compression::DecompressZLIB(compressedData)); + + sectionIndex++; + } + + zoneFile.Load(decompressedData); + } + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod8_ps3.h b/libs/fastfile/PS3/fastfile_cod8_ps3.h new file mode 100644 index 0000000..02570b0 --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod8_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD8_PS3_H +#define FASTFILE_COD8_PS3_H + +#include "fastfile.h" + +class FastFile_COD8_PS3 : public FastFile +{ +public: + FastFile_COD8_PS3(); + FastFile_COD8_PS3(const QByteArray &aData); + FastFile_COD8_PS3(const QString aFilePath); + ~FastFile_COD8_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD8_PS3_H diff --git a/libs/fastfile/PS3/fastfile_cod9_ps3.cpp b/libs/fastfile/PS3/fastfile_cod9_ps3.cpp new file mode 100644 index 0000000..787c08d --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod9_ps3.cpp @@ -0,0 +1,137 @@ +#include "fastfile_cod9_ps3.h" +#include "zonefile_cod9_ps3.h" +#include "encryption.h" + +#include +#include + +FastFile_COD9_PS3::FastFile_COD9_PS3() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD9"); + SetPlatform("PS3"); +} + +FastFile_COD9_PS3::FastFile_COD9_PS3(const QByteArray& aData) + : FastFile_COD9_PS3() { + + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD9_PS3::FastFile_COD9_PS3(const QString aFilePath) + : FastFile_COD9_PS3() { + + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD9_PS3::~FastFile_COD9_PS3() { + +} + +QByteArray FastFile_COD9_PS3::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD9_PS3::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD9_PS3::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD9_PS3 zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/PS3/fastfile_cod9_ps3.h b/libs/fastfile/PS3/fastfile_cod9_ps3.h new file mode 100644 index 0000000..145f69f --- /dev/null +++ b/libs/fastfile/PS3/fastfile_cod9_ps3.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD9_PS3_H +#define FASTFILE_COD9_PS3_H + +#include "fastfile.h" + +class FastFile_COD9_PS3 : public FastFile +{ +public: + FastFile_COD9_PS3(); + FastFile_COD9_PS3(const QByteArray &aData); + FastFile_COD9_PS3(const QString aFilePath); + ~FastFile_COD9_PS3(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD9_PS3_H diff --git a/libs/fastfile/Wii/fastfile_cod4_wii.cpp b/libs/fastfile/Wii/fastfile_cod4_wii.cpp new file mode 100644 index 0000000..b661fc3 --- /dev/null +++ b/libs/fastfile/Wii/fastfile_cod4_wii.cpp @@ -0,0 +1,114 @@ +#include "fastfile_cod4_wii.h" +#include "zonefile_cod4_wii.h" + +#include "utils.h" +#include "compression.h" + +#include +#include + +FastFile_COD4_Wii::FastFile_COD4_Wii() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD4"); + SetPlatform("Wii"); +} + +FastFile_COD4_Wii::FastFile_COD4_Wii(const QByteArray& aData) + : FastFile_COD4_Wii() { + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD4_Wii::FastFile_COD4_Wii(const QString aFilePath) + : FastFile_COD4_Wii() { + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD4_Wii::~FastFile_COD4_Wii() { + +} + +QByteArray FastFile_COD4_Wii::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD4_Wii::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD4_Wii::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD7"); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD7_Wii zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // For COD7, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + QDir workingDir = QDir::currentPath(); + workingDir.mkdir("exports"); + + QFile outputFile("exports/" + GetStem() + ".zone"); + if (!outputFile.open(QIODevice::WriteOnly)) { + qDebug() << "Failed to extract IPAK file."; + } + qDebug() << " - File Name: " << outputFile.fileName(); + outputFile.write(decompressedData); + outputFile.close(); + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/Wii/fastfile_cod4_wii.h b/libs/fastfile/Wii/fastfile_cod4_wii.h new file mode 100644 index 0000000..d971c55 --- /dev/null +++ b/libs/fastfile/Wii/fastfile_cod4_wii.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD4_WII_H +#define FASTFILE_COD4_WII_H + +#include "fastfile.h" + +class FastFile_COD4_Wii : public FastFile +{ +public: + FastFile_COD4_Wii(); + FastFile_COD4_Wii(const QByteArray &aData); + FastFile_COD4_Wii(const QString aFilePath); + ~FastFile_COD4_Wii(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD4_WII_H diff --git a/libs/fastfile/Wii/fastfile_cod7_wii.cpp b/libs/fastfile/Wii/fastfile_cod7_wii.cpp new file mode 100644 index 0000000..26735d2 --- /dev/null +++ b/libs/fastfile/Wii/fastfile_cod7_wii.cpp @@ -0,0 +1,114 @@ +#include "fastfile_cod7_wii.h" +#include "zonefile_cod7_wii.h" + +#include "utils.h" +#include "compression.h" + +#include +#include + +FastFile_COD7_Wii::FastFile_COD7_Wii() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD7"); + SetPlatform("Wii"); +} + +FastFile_COD7_Wii::FastFile_COD7_Wii(const QByteArray& aData) + : FastFile_COD7_Wii() { + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD7_Wii::FastFile_COD7_Wii(const QString aFilePath) + : FastFile_COD7_Wii() { + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD7_Wii::~FastFile_COD7_Wii() { + +} + +QByteArray FastFile_COD7_Wii::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD7_Wii::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD7_Wii::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD7"); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD7_Wii zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // For COD7, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + QDir workingDir = QDir::currentPath(); + workingDir.mkdir("exports"); + + QFile outputFile("exports/" + GetStem() + ".zone"); + if (!outputFile.open(QIODevice::WriteOnly)) { + qDebug() << "Failed to extract IPAK file."; + } + qDebug() << " - File Name: " << outputFile.fileName(); + outputFile.write(decompressedData); + outputFile.close(); + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/Wii/fastfile_cod7_wii.h b/libs/fastfile/Wii/fastfile_cod7_wii.h new file mode 100644 index 0000000..7577422 --- /dev/null +++ b/libs/fastfile/Wii/fastfile_cod7_wii.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD7_WII_H +#define FASTFILE_COD7_WII_H + +#include "fastfile.h" + +class FastFile_COD7_Wii : public FastFile +{ +public: + FastFile_COD7_Wii(); + FastFile_COD7_Wii(const QByteArray &aData); + FastFile_COD7_Wii(const QString aFilePath); + ~FastFile_COD7_Wii(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD7_WII_H diff --git a/libs/fastfile/Wii/fastfile_cod8_wii.cpp b/libs/fastfile/Wii/fastfile_cod8_wii.cpp new file mode 100644 index 0000000..8252db3 --- /dev/null +++ b/libs/fastfile/Wii/fastfile_cod8_wii.cpp @@ -0,0 +1,114 @@ +#include "fastfile_cod8_wii.h" +#include "zonefile_cod8_wii.h" + +#include "utils.h" +#include "compression.h" + +#include +#include + +FastFile_COD8_Wii::FastFile_COD8_Wii() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD7"); + SetPlatform("Wii"); +} + +FastFile_COD8_Wii::FastFile_COD8_Wii(const QByteArray& aData) + : FastFile_COD8_Wii() { + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD8_Wii::FastFile_COD8_Wii(const QString aFilePath) + : FastFile_COD8_Wii() { + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD8_Wii::~FastFile_COD8_Wii() { + +} + +QByteArray FastFile_COD8_Wii::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD8_Wii::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD8_Wii::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD7"); + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD7_Wii zoneFile; + zoneFile.SetStem(GetStem()); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + + // For COD7, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + + Utils::ExportData(GetStem() + ".zone", decompressedData); + + QDir workingDir = QDir::currentPath(); + workingDir.mkdir("exports"); + + QFile outputFile("exports/" + GetStem() + ".zone"); + if (!outputFile.open(QIODevice::WriteOnly)) { + qDebug() << "Failed to extract IPAK file."; + } + qDebug() << " - File Name: " << outputFile.fileName(); + outputFile.write(decompressedData); + outputFile.close(); + + zoneFile.Load(decompressedData); + + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/Wii/fastfile_cod8_wii.h b/libs/fastfile/Wii/fastfile_cod8_wii.h new file mode 100644 index 0000000..e5a8bc2 --- /dev/null +++ b/libs/fastfile/Wii/fastfile_cod8_wii.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD8_WII_H +#define FASTFILE_COD8_WII_H + +#include "fastfile.h" + +class FastFile_COD8_Wii : public FastFile +{ +public: + FastFile_COD8_Wii(); + FastFile_COD8_Wii(const QByteArray &aData); + FastFile_COD8_Wii(const QString aFilePath); + ~FastFile_COD8_Wii(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD8_WII_H diff --git a/libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp b/libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp new file mode 100644 index 0000000..165dd42 --- /dev/null +++ b/libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp @@ -0,0 +1,135 @@ +#include "fastfile_cod10_wiiu.h" +#include "zonefile_cod10_wiiu.h" +#include "encryption.h" + +#include +#include + +FastFile_COD10_WiiU::FastFile_COD10_WiiU() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD10"); + SetPlatform("WiiU"); +} + +FastFile_COD10_WiiU::FastFile_COD10_WiiU(const QByteArray& aData) + : FastFile_COD10_WiiU() { + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD10_WiiU::FastFile_COD10_WiiU(const QString aFilePath) + : FastFile_COD10_WiiU() { + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD10_WiiU::~FastFile_COD10_WiiU() { + +} + +QByteArray FastFile_COD10_WiiU::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD10_WiiU::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD10_WiiU::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD10_WiiU zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/WiiU/fastfile_cod10_wiiu.h b/libs/fastfile/WiiU/fastfile_cod10_wiiu.h new file mode 100644 index 0000000..85d209d --- /dev/null +++ b/libs/fastfile/WiiU/fastfile_cod10_wiiu.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD10_WIIU_H +#define FASTFILE_COD10_WIIU_H + +#include "fastfile.h" + +class FastFile_COD10_WiiU : public FastFile +{ +public: + FastFile_COD10_WiiU(); + FastFile_COD10_WiiU(const QByteArray &aData); + FastFile_COD10_WiiU(const QString aFilePath); + ~FastFile_COD10_WiiU(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD10_WIIU_H diff --git a/libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp b/libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp new file mode 100644 index 0000000..52078d2 --- /dev/null +++ b/libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp @@ -0,0 +1,135 @@ +#include "fastfile_cod9_wiiu.h" +#include "zonefile_cod9_wiiu.h" +#include "encryption.h" + +#include +#include + +FastFile_COD9_WiiU::FastFile_COD9_WiiU() + : FastFile() { + SetCompany(COMPANY_INFINITY_WARD); + SetType(FILETYPE_FAST_FILE); + SetSignage(SIGNAGE_UNSIGNED); + SetMagic(0); + SetVersion(0); + SetGame("COD9"); + SetPlatform("WiiU"); +} + +FastFile_COD9_WiiU::FastFile_COD9_WiiU(const QByteArray& aData) + : FastFile_COD9_WiiU() { + if (!aData.isEmpty()) { + Load(aData); + } +} + +FastFile_COD9_WiiU::FastFile_COD9_WiiU(const QString aFilePath) + : FastFile_COD9_WiiU() { + if (!aFilePath.isEmpty()) { + Load(aFilePath); + } +} + +FastFile_COD9_WiiU::~FastFile_COD9_WiiU() { + +} + +QByteArray FastFile_COD9_WiiU::GetBinaryData() { + return QByteArray(); +} + +bool FastFile_COD9_WiiU::Load(const QString aFilePath) { + if (aFilePath.isEmpty()) { + return false; + } + + // Check fastfile can be read + QFile *file = new QFile(aFilePath); + if (!file->open(QIODevice::ReadOnly)) { + qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath); + return false; + } + + // Decompress fastfile and close + const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); + SetStem(fastFileStem); + if (!Load(file->readAll())) { + qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff"; + return false; + } + + file->close(); + + // Open zone file after decompressing ff and writing + return true; +} + +bool FastFile_COD9_WiiU::Load(const QByteArray aData) { + QByteArray decompressedData; + + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse header values. + SetCompany(pParseFFCompany(&fastFileStream)); + SetType(pParseFFFileType(&fastFileStream)); + SetSignage(pParseFFSignage(&fastFileStream)); + SetMagic(pParseFFMagic(&fastFileStream)); + quint32 version = pParseFFVersion(&fastFileStream); + SetVersion(version); + SetPlatform(pCalculateFFPlatform(version)); + SetGame("COD9"); + + // For COD7/COD9, use BigEndian. + fastFileStream.setByteOrder(QDataStream::BigEndian); + if (GetPlatform() == "PC") { + fastFileStream.setByteOrder(QDataStream::LittleEndian); + } + + // Select key based on game. + QByteArray key; + if (GetPlatform() == "360") { + key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); + } else if (GetPlatform() == "PC") { + key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + } + + // Read the 8-byte magic. + QByteArray fileMagic(8, Qt::Uninitialized); + fastFileStream.readRawData(fileMagic.data(), 8); + if (fileMagic != "PHEEBs71") { + qWarning() << "Invalid fast file magic!"; + return false; + } + fastFileStream.skipRawData(4); + + // Read IV table name (32 bytes). + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + // Skip the RSA signature (256 bytes). + QByteArray rsaSignature(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSignature.data(), 256); + + if (GetPlatform() == "360") { + //decompressedData = Compressor::cod9_decryptFastFile(aData); + } else if (GetPlatform() == "PC") { + decompressedData = Encryption::decryptFastFile_BO2(aData); + } + + // For COD9, write out the complete decompressed zone for testing. + QFile testFile("exports/" + GetStem() + ".zone"); + if(testFile.open(QIODevice::WriteOnly)) { + testFile.write(decompressedData); + testFile.close(); + } + + // Load the zone file with the decompressed data (using an Xbox platform flag). + ZoneFile_COD9_WiiU zoneFile; + zoneFile.SetStem(GetStem()); + zoneFile.Load(decompressedData); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/libs/fastfile/WiiU/fastfile_cod9_wiiu.h b/libs/fastfile/WiiU/fastfile_cod9_wiiu.h new file mode 100644 index 0000000..3ac7f58 --- /dev/null +++ b/libs/fastfile/WiiU/fastfile_cod9_wiiu.h @@ -0,0 +1,20 @@ +#ifndef FASTFILE_COD9_WIIU_H +#define FASTFILE_COD9_WIIU_H + +#include "fastfile.h" + +class FastFile_COD9_WiiU : public FastFile +{ +public: + FastFile_COD9_WiiU(); + FastFile_COD9_WiiU(const QByteArray &aData); + FastFile_COD9_WiiU(const QString aFilePath); + ~FastFile_COD9_WiiU(); + + QByteArray GetBinaryData() override; + + bool Load(const QString aFilePath) override; + bool Load(const QByteArray aData) override; +}; + +#endif // FASTFILE_COD9_WIIU_H diff --git a/libs/fastfile/fastfile.pro b/libs/fastfile/fastfile.pro index 63ec0f0..756d37b 100644 --- a/libs/fastfile/fastfile.pro +++ b/libs/fastfile/fastfile.pro @@ -3,37 +3,89 @@ TEMPLATE = lib CONFIG += staticlib c++17 SOURCES += \ + # Base class & factory fastfile.cpp \ + # 360 classes 360/fastfile_cod2_360.cpp \ + 360/fastfile_cod4_360.cpp \ 360/fastfile_cod5_360.cpp \ + 360/fastfile_cod6_360.cpp \ 360/fastfile_cod7_360.cpp \ + 360/fastfile_cod8_360.cpp \ 360/fastfile_cod9_360.cpp \ + 360/fastfile_cod10_360.cpp \ + 360/fastfile_cod11_360.cpp \ + 360/fastfile_cod12_360.cpp \ + # PS3 classes + PS3/fastfile_cod4_ps3.cpp \ PS3/fastfile_cod5_ps3.cpp \ + PS3/fastfile_cod6_ps3.cpp \ PS3/fastfile_cod7_ps3.cpp \ + PS3/fastfile_cod8_ps3.cpp \ PS3/fastfile_cod9_ps3.cpp \ + PS3/fastfile_cod10_ps3.cpp \ + PS3/fastfile_cod11_ps3.cpp \ + PS3/fastfile_cod12_ps3.cpp \ + # PC classes + PC/fastfile_cod4_pc.cpp \ PC/fastfile_cod5_pc.cpp \ + PC/fastfile_cod6_pc.cpp \ PC/fastfile_cod7_pc.cpp \ + PC/fastfile_cod8_pc.cpp \ PC/fastfile_cod9_pc.cpp \ + PC/fastfile_cod10_pc.cpp \ + PC/fastfile_cod11_pc.cpp \ PC/fastfile_cod12_pc.cpp \ + # Wii Classes + Wii/fastfile_cod4_wii.cpp \ Wii/fastfile_cod7_wii.cpp \ - WiiU/fastfile_cod9_wiiu.cpp + Wii/fastfile_cod8_wii.cpp \ + # WiiU Classes + WiiU/fastfile_cod9_wiiu.cpp \ + WiiU/fastfile_cod10_wiiu.cpp HEADERS += \ + # Base class & factory fastfile.h \ + fastfile_factory.h \ + # 360 classes 360/fastfile_cod2_360.h \ + 360/fastfile_cod4_360.h \ 360/fastfile_cod5_360.h \ + 360/fastfile_cod6_360.h \ 360/fastfile_cod7_360.h \ + 360/fastfile_cod8_360.h \ 360/fastfile_cod9_360.h \ + 360/fastfile_cod10_360.h \ + 360/fastfile_cod11_360.h \ + 360/fastfile_cod12_360.h \ + # PS3 classes + PS3/fastfile_cod4_ps3.h \ PS3/fastfile_cod5_ps3.h \ + PS3/fastfile_cod6_ps3.h \ PS3/fastfile_cod7_ps3.h \ + PS3/fastfile_cod8_ps3.h \ PS3/fastfile_cod9_ps3.h \ + PS3/fastfile_cod10_ps3.h \ + PS3/fastfile_cod11_ps3.h \ + PS3/fastfile_cod12_ps3.h \ + # PC classes + PC/fastfile_cod4_pc.h \ PC/fastfile_cod5_pc.h \ + PC/fastfile_cod6_pc.h \ PC/fastfile_cod7_pc.h \ + PC/fastfile_cod8_pc.h \ PC/fastfile_cod9_pc.h \ + PC/fastfile_cod10_pc.h \ + PC/fastfile_cod11_pc.h \ PC/fastfile_cod12_pc.h \ + # Wii Classes + Wii/fastfile_cod4_wii.h \ Wii/fastfile_cod7_wii.h \ + Wii/fastfile_cod8_wii.h \ + # WiiU classes WiiU/fastfile_cod9_wiiu.h \ - fastfile_factory.h + WiiU/fastfile_cod10_wiiu.h LIBS += \ -L$$OUT_PWD/../libs/core -lcore \ diff --git a/libs/fastfile/fastfile_factory.h b/libs/fastfile/fastfile_factory.h index 7b2186c..7707b25 100644 --- a/libs/fastfile/fastfile_factory.h +++ b/libs/fastfile/fastfile_factory.h @@ -3,42 +3,42 @@ #include "360/fastfile_cod2_360.h" //#include "360/fastfile_cod3_360.h" -//#include "360/fastfile_cod4_360.h" +#include "360/fastfile_cod4_360.h" #include "360/fastfile_cod5_360.h" -//#include "360/fastfile_cod6_360.h" +#include "360/fastfile_cod6_360.h" #include "360/fastfile_cod7_360.h" -//#include "360/fastfile_cod8_360.h" +#include "360/fastfile_cod8_360.h" #include "360/fastfile_cod9_360.h" -//#include "360/fastfile_cod10_360.h" -//#include "360/fastfile_cod11_360.h" -//#include "360/fastfile_cod12_360.h" +#include "360/fastfile_cod10_360.h" +#include "360/fastfile_cod11_360.h" +#include "360/fastfile_cod12_360.h" //#include "PS3/fastfile_cod3_ps3.h" -//#include "PS3/fastfile_cod4_ps3.h" +#include "PS3/fastfile_cod4_ps3.h" #include "PS3/fastfile_cod5_ps3.h" -//#include "PS3/fastfile_cod6_ps3.h" +#include "PS3/fastfile_cod6_ps3.h" #include "PS3/fastfile_cod7_ps3.h" -//#include "PS3/fastfile_cod8_ps3.h" +#include "PS3/fastfile_cod8_ps3.h" #include "PS3/fastfile_cod9_ps3.h" -//#include "PS3/fastfile_cod10_ps3.h" -//#include "PS3/fastfile_cod11_ps3.h" -//#include "PS3/fastfile_cod12_ps3.h" +#include "PS3/fastfile_cod10_ps3.h" +#include "PS3/fastfile_cod11_ps3.h" +#include "PS3/fastfile_cod12_ps3.h" //#include "PC/fastfile_cod3_pc.h" -//#include "PC/fastfile_cod4_pc.h" +#include "PC/fastfile_cod4_pc.h" #include "PC/fastfile_cod5_pc.h" -//#include "PC/fastfile_cod6_pc.h" +#include "PC/fastfile_cod6_pc.h" #include "PC/fastfile_cod7_pc.h" -//#include "PC/fastfile_cod8_360.h" +#include "PC/fastfile_cod8_pc.h" #include "PC/fastfile_cod9_pc.h" -//#include "PC/fastfile_cod10_pc.h" -//#include "PC/fastfile_cod11_pc.h" +#include "PC/fastfile_cod10_pc.h" +#include "PC/fastfile_cod11_pc.h" #include "PC/fastfile_cod12_pc.h" #include "Wii//fastfile_cod7_wii.h" #include "WiiU/fastfile_cod9_wiiu.h" -//#include "WiiU/fastfile_cod10_wiiu.h" +#include "WiiU/fastfile_cod10_wiiu.h" #include #include @@ -60,21 +60,20 @@ enum FastFile_Platform { enum FastFile_Game { GAME_NONE = 0x00, GAME_COD2 = 0x01, - GAME_COD3 = 0x02, - GAME_COD4 = 0x03, - GAME_COD5 = 0x04, - GAME_COD6 = 0x05, - GAME_COD7 = 0x06, - GAME_COD8 = 0x07, - GAME_COD9 = 0x08, - GAME_COD10 = 0x09, - GAME_COD11 = 0x010, - GAME_COD12 = 0x011 + GAME_COD4 = 0x02, + GAME_COD5 = 0x03, + GAME_COD6 = 0x04, + GAME_COD7 = 0x05, + GAME_COD8 = 0x06, + GAME_COD9 = 0x07, + GAME_COD10 = 0x08, + GAME_COD11 = 0x09, + GAME_COD12 = 0x010 }; class FastFileFactory { public: - static std::shared_ptr Create(const QString& aFilePath) { + static std::shared_ptr Create(const QString& aFilePath, bool aEmpty = false) { QFile fastFile(aFilePath); if (!fastFile.open(QIODevice::ReadOnly)) { qDebug() << "Factory failed to open fast file: " << aFilePath; @@ -82,168 +81,166 @@ public: } const QString stem = aFilePath.split('/').last().split('.').first(); + + const QString newPath = (aEmpty ? "" : aFilePath); + const QByteArray data = fastFile.readAll(); std::shared_ptr resultFF = nullptr; - if (pGetPlatform(data) == PLATFORM_360) { - if (pGetGame(data) == GAME_COD2) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD3) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD4) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD5) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD6) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD7) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD8) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD9) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD10) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD11) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD12) { - //resultFF = std::make_shared(aFilePath); + + const FastFile_Platform platform = pGetPlatform(data); + const FastFile_Game game = pGetGame(data); + + if (platform == PLATFORM_360) { + if (game == GAME_COD2) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD4) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD5) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD6) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD7) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD8) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD9) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD11) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD12) { + resultFF = std::make_shared(newPath); } - } else if (pGetPlatform(data) == PLATFORM_PC) { - if (pGetGame(data) == GAME_COD3) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD4) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD5) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD6) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD7) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD8) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD9) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD10) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD11) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD12) { - resultFF = std::make_shared(aFilePath); + } else if (platform == PLATFORM_PC) { + if (game == GAME_COD4) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD5) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD6) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD7) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD8) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD9) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD11) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD12) { + resultFF = std::make_shared(newPath); } - } else if (pGetPlatform(data) == PLATFORM_PS3) { - if (pGetGame(data) == GAME_COD3) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD4) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD5) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD6) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD7) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD8) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD9) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD10) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD11) { - //resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD12) { - //resultFF = std::make_shared(aFilePath); + } else if (platform == PLATFORM_PS3) { + if (game == GAME_COD4) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD5) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD6) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD7) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD8) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD9) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD11) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD12) { + resultFF = std::make_shared(newPath); } - } else if (pGetPlatform(data) == PLATFORM_WII) { - if (pGetGame(data) == GAME_COD7) { - resultFF = std::make_shared(aFilePath); + } else if (platform == PLATFORM_WII) { + if (game == GAME_COD7) { + resultFF = std::make_shared(newPath); } - } else if (pGetPlatform(data) == PLATFORM_WIIU) { - if (pGetGame(data) == GAME_COD9) { - resultFF = std::make_shared(aFilePath); - } else if (pGetGame(data) == GAME_COD10) { - //resultFF = std::make_shared(aFilePath); + } else if (platform == PLATFORM_WIIU) { + if (game == GAME_COD9) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(newPath); } } return resultFF; } static std::shared_ptr Create(const QByteArray& aData, const QString aStem = "no_name") { std::shared_ptr resultFF = nullptr; - if (pGetPlatform(aData) == PLATFORM_360) { - if (pGetGame(aData) == GAME_COD2) { + + const FastFile_Platform platform = pGetPlatform(aData); + const FastFile_Game game = pGetGame(aData); + if (platform == PLATFORM_360) { + if (game == GAME_COD2) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD3) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD4) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD5) { + } else if (game == GAME_COD4) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD5) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD6) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD7) { + } else if (game == GAME_COD6) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD7) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD8) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD9) { + } else if (game == GAME_COD8) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD9) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD10) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD11) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD12) { - //resultFF = std::make_shared(data); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD11) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD12) { + resultFF = std::make_shared(aData); } - } else if (pGetPlatform(aData) == PLATFORM_PC) { - if (pGetGame(aData) == GAME_COD3) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD4) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD5) { + } else if (platform == PLATFORM_PC) { + if (game == GAME_COD4) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD5) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD6) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD7) { + } else if (game == GAME_COD6) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD7) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD8) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD9) { + } else if (game == GAME_COD8) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD9) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD10) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD11) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD12) { - //resultFF = std::make_shared(data); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD11) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD12) { + resultFF = std::make_shared(aData); } - } else if (pGetPlatform(aData) == PLATFORM_PS3) { - if (pGetGame(aData) == GAME_COD3) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD4) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD5) { + } else if (platform == PLATFORM_PS3) { + if (game == GAME_COD4) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD5) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD6) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD7) { + } else if (game == GAME_COD6) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD7) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD8) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD9) { + } else if (game == GAME_COD8) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD9) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD10) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD11) { - //resultFF = std::make_shared(data); - } else if (pGetGame(aData) == GAME_COD12) { - //resultFF = std::make_shared(data); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD11) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD12) { + resultFF = std::make_shared(aData); } - } else if (pGetPlatform(aData) == PLATFORM_WII) { - if (pGetGame(aData) == GAME_COD7) { + } else if (platform == PLATFORM_WII) { + if (game == GAME_COD7) { resultFF = std::make_shared(aData); } - } else if (pGetPlatform(aData) == PLATFORM_WIIU) { - if (pGetGame(aData) == GAME_COD9) { + } else if (platform == PLATFORM_WIIU) { + if (game == GAME_COD9) { resultFF = std::make_shared(aData); - } else if (pGetGame(aData) == GAME_COD10) { - //resultFF = std::make_shared(data); + } else if (game == GAME_COD10) { + resultFF = std::make_shared(aData); } } if (resultFF) { @@ -261,6 +258,8 @@ private: sections << aData.mid(6, 2).toHex().toUpper(); sections << aData.mid(8, 2).toHex().toUpper(); sections << aData.mid(10, 2).toHex().toUpper(); + sections << aData.mid(12, 2).toHex().toUpper(); + sections << aData.mid(14, 2).toHex().toUpper(); return sections; } @@ -270,29 +269,55 @@ private: if (sections[0] == "0000") { return PLATFORM_360; } else if (sections[4] == "0000") { - if (sections[5] == "0001" || - sections[5] == "0183" || - sections[5] == "010D" || - sections[5] == "01D9" || - sections[5] == "0070" || - sections[5] == "0092" || - sections[5] == "022E" || - sections[5] == "072E" || - sections[5] == "0253") { + + if (sections[5] == "0001" && sections[6] == "78DA") { + return PLATFORM_360; + } else if (sections[5] == "0183" && sections[6] == "7801") { + return PLATFORM_360; + } else if (sections[6] == "0101" && sections[7] == "CA3E") { + return PLATFORM_360; + } else if (sections[6] == "0000" && sections[7] == "0001") { + return PLATFORM_360; + } else if (sections[6] == "0101" && sections[7] == "CC76") { + return PLATFORM_360; + } else if (sections[6] == "0101" && sections[7] == "0101") { + return PLATFORM_360; + } else if (sections[2] == "7831") { + return PLATFORM_360; + } else if (sections[0] == "5331" && sections[2] == "7531") { + return PLATFORM_360; + } else if (sections[2] == "3030" && sections[3] == "3030") { return PLATFORM_360; } } else if (sections[5] == "0000") { return PLATFORM_PC; + } else if (sections[5] == "01DD" && sections[6] == "7801") { + return PLATFORM_WII; + } else if (sections[5] == "0094" || sections[6] == "0100") { + return PLATFORM_WIIU; } - return PLATFORM_NONE; + return PLATFORM_PS3; } static FastFile_Game pGetGame(const QByteArray& aData) { const QStringList sections = pGetDataSections(aData); if (sections[0] == "0000") { return GAME_COD2; - } else if (sections[5] == "0183") { + } else if (sections[4] == "0500" || sections[5] == "0001") { + return GAME_COD4; + } else if (sections[4] == "8301" || sections[5] == "0183") { return GAME_COD5; + } else if (sections[4] == "1401" || sections[5] == "010D") { + return GAME_COD6; + } else if (sections[4] == "D901" || sections[5] == "01D9") { + return GAME_COD7; + } else if (sections[4] == "0100" || sections[5] == "0070") { + return GAME_COD8; + } else if (sections[4] == "9300" || sections[5] == "0092" + || sections[5] == "0094") { + return GAME_COD9; + } else if (sections[4] == "3502" || sections[5] == "022E") { + return GAME_COD10; } else if (sections[0] == "5331") { return GAME_COD11; } else if (sections[2] == "3030") { diff --git a/libs/zonefile/360/zonefile_cod10_360.cpp b/libs/zonefile/360/zonefile_cod10_360.cpp new file mode 100644 index 0000000..38c3295 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod10_360.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod10_360.h" + +#include +#include +#include + +ZoneFile_COD10_360::ZoneFile_COD10_360() +{ + +} + +ZoneFile_COD10_360::~ZoneFile_COD10_360() +{ + +} + +bool ZoneFile_COD10_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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD10_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD10_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD10_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD10_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD10_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD10_360::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD10_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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD10_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD10_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD10_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD10_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD10_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD10_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD10_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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD10_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD10_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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD10_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD10_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD10_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD10_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD10_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD10_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD10_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod10_360.h b/libs/zonefile/360/zonefile_cod10_360.h new file mode 100644 index 0000000..eae80e4 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod10_360.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD10_360_H +#define ZONEFILE_COD10_360_H + +#include "zonefile.h" + +class ZoneFile_COD10_360 : public ZoneFile +{ +public: + ZoneFile_COD10_360(); + ~ZoneFile_COD10_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD10_360_H diff --git a/libs/zonefile/360/zonefile_cod11_360.cpp b/libs/zonefile/360/zonefile_cod11_360.cpp new file mode 100644 index 0000000..ac65795 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod11_360.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod11_360.h" + +#include +#include +#include + +ZoneFile_COD11_360::ZoneFile_COD11_360() +{ + +} + +ZoneFile_COD11_360::~ZoneFile_COD11_360() +{ + +} + +bool ZoneFile_COD11_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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD11_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD11_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD11_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD11_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD11_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD11_360::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD11_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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD11_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD11_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD11_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD11_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD11_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD11_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD11_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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD11_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD11_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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD11_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD11_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD11_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD11_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD11_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD11_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD11_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod11_360.h b/libs/zonefile/360/zonefile_cod11_360.h new file mode 100644 index 0000000..b916039 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod11_360.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD11_360_H +#define ZONEFILE_COD11_360_H + +#include "zonefile.h" + +class ZoneFile_COD11_360 : public ZoneFile +{ +public: + ZoneFile_COD11_360(); + ~ZoneFile_COD11_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD11_360_H diff --git a/libs/zonefile/360/zonefile_cod12_360.cpp b/libs/zonefile/360/zonefile_cod12_360.cpp new file mode 100644 index 0000000..bfe764c --- /dev/null +++ b/libs/zonefile/360/zonefile_cod12_360.cpp @@ -0,0 +1,1207 @@ +#include "zonefile_cod12_360.h" + +#include +#include +#include + +ZoneFile_COD12_360::ZoneFile_COD12_360() +{ + +} + +ZoneFile_COD12_360::~ZoneFile_COD12_360() +{ + +} + +bool ZoneFile_COD12_360::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD12_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + aZoneFileStream->skipRawData(7 * 4); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream) - 1; + SetRecordCount(recordCount); + + aZoneFileStream->skipRawData(5 * 4); + + if (tagCount) { + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } +} + +quint32 ZoneFile_COD12_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD12_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD12_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD12_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(8 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + if (aZoneFileStream->device()->peek(8).toHex().contains("00000000")) { + break; + } + + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD12_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(8, Qt::Uninitialized); + aZoneFileStream->readRawData(rawAssetType.data(), 8); + result << rawAssetType.toHex(); + + // Skip separator + aZoneFileStream->skipRawData(8); + } + return result; +} + +AssetMap ZoneFile_COD12_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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // raw file + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_SCRIPT_PARSE_TREE) { // gsc + auto gscFile = pParseAsset_GSCFile(aZoneFileStream); + if (gscFile.length) { + result.gscFiles << gscFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD12_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD12_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +GscFile ZoneFile_COD12_360::pParseAsset_GSCFile(QDataStream *aZoneFileStream) { + GscFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(8); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(8); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD12_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD12_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD12_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD12_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD12_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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD12_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD12_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { + SoundAsset result; + return 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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD12_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD12_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD12_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD12_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD12_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD12_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "0000000000000000") { + return ASSET_PHYS_PRESET; + } else if (cleanedType == "0100000000000000") { + return ASSET_PHYS_CONSTRAINTS; + } else if (cleanedType == "0200000000000000") { + return ASSET_DESTRUCTIBLE_DEF; + } else if (cleanedType == "0300000000000000") { + return ASSET_ANIMATION; + } else if (cleanedType == "0400000000000000") { + return ASSET_MODEL; + } else if (cleanedType == "0500000000000000") { + return ASSET_MODEL_MESH; + } else if (cleanedType == "0600000000000000") { + return ASSET_MATERIAL; + } else if (cleanedType == "0700000000000000") { + return ASSET_COMPUTE_SHADER_SET; + } else if (cleanedType == "0800000000000000") { + return ASSET_TECH_SET; + } else if (cleanedType == "0900000000000000") { + return ASSET_IMAGE; + } else if (cleanedType == "0A00000000000000") { + return ASSET_SOUND; + } else if (cleanedType == "1100000000000000") { + return ASSET_LIGHT_DEF; + } else if (cleanedType == "1500000000000000") { + return ASSET_FONT_ICON; + } else if (cleanedType == "1700000000000000") { + return ASSET_WEAPON; + } else if (cleanedType == "1C00000000000000") { + return ASSET_PLAYER_SOUNDS_TABLE; + } else if (cleanedType == "1D00000000000000") { + return ASSET_PLAYER_FX_TABLE; + } else if (cleanedType == "1E00000000000000") { + return ASSET_SHARED_WEAPON_SOUNDS; + } else if (cleanedType == "1F00000000000000") { + return ASSET_ATTACHMENT; + } else if (cleanedType == "2000000000000000") { + return ASSET_ATTACHMENT_UNIQUE; + } else if (cleanedType == "2100000000000000") { + return ASSET_WEAPON_CAMO; + } else if (cleanedType == "2200000000000000") { + return ASSET_CUSTOMIZATION_TABLE; + } else if (cleanedType == "2300000000000000") { + return ASSET_CUSTOMIZATION_TABLE_FEIMAGES; + } else if (cleanedType == "2400000000000000") { + return ASSET_CUSTOMIZATION_TABLE_COLOR; + }else if (cleanedType == "2600000000000000") { + return ASSET_EFFECT; + } else if (cleanedType == "2F00000000000000") { + return ASSET_RAW_FILE; + } else if (cleanedType == "3000000000000000") { + return ASSET_STRING_TABLE; + } else if (cleanedType == "3100000000000000") { + return ASSET_STRUCTURED_TABLE; + } else if (cleanedType == "3200000000000000") { + return ASSET_LEADERBOARD_DEF; + } else if (cleanedType == "3300000000000000") { + return ASSET_DDL; + } else if (cleanedType == "3600000000000000") { + return ASSET_SCRIPT_PARSE_TREE; + } else if (cleanedType == "3700000000000000") { + return ASSET_KEY_VALUE_PAIRS; + } else if (cleanedType == "3800000000000000") { + return ASSET_VEHICLE; + } else if (cleanedType == "3A00000000000000") { + return ASSET_VEHICLE_TRACER; + } else if (cleanedType == "3C00000000000000") { + return ASSET_SURFACE_FX_TABLE; + } else if (cleanedType == "3D00000000000000") { + return ASSET_SURFACE_SOUND_DEF; + } else if (cleanedType == "3E00000000000000") { + return ASSET_FOOTSTEP_TABLE; + } else if (cleanedType == "3F00000000000000") { + return ASSET_ENTITY_FX_IMPACTS; + } else if (cleanedType == "4000000000000000") { + return ASSET_ENTITY_SOUND_IMPACTS; + } else if (cleanedType == "4200000000000000") { + return ASSET_VEHICLE_FX_DEF; + } else if (cleanedType == "4300000000000000") { + return ASSET_VEHICLE_SOUND_DEF; + } else if (cleanedType == "4500000000000000") { + return ASSET_SCRIPT_BUNDLE; + } else if (cleanedType == "4600000000000000") { + return ASSET_SCRIPT_BUNDLE_LIST; + } else if (cleanedType == "4700000000000000") { + return ASSET_RUMBLE; + } else if (cleanedType == "4A00000000000000") { + return ASSET_AIM_TABLE; + } else if (cleanedType == "4B00000000000000") { + return ASSET_ANIM_SELECTOR_TABLE; + } else if (cleanedType == "4C00000000000000") { + return ASSET_ANIM_MAPPING_TABLE; + } else if (cleanedType == "4D00000000000000") { + return ASSET_ANIM_STATE_MACHINE; + } else if (cleanedType == "4E00000000000000") { + return ASSET_BEHAVIOR_TREE; + } else if (cleanedType == "4F00000000000000") { + return ASSET_BEHAVIOR_STATE_MACHINE; + } else if (cleanedType == "5100000000000000") { + return ASSET_S_ANIM; + } else if (cleanedType == "5200000000000000") { + return ASSET_LIGHT_DEF; + } else if (cleanedType == "5300000000000000") { + return ASSET_BIT_FIELD; + } else if (cleanedType == "5400000000000000") { + return ASSET_SURFACE_SOUND_DEF; + } else if (cleanedType == "5500000000000000") { + return ASSET_SURFACE_FX_TABLE; + } else if (cleanedType == "5600000000000000") { + return ASSET_RUMBLE; + } else if (cleanedType == "5900000000000000") { + return ASSET_AIM_TABLE; + } else if (cleanedType == "5A00000000000000") { + return ASSET_MAP_TABLE; + } else if (cleanedType == "5B00000000000000") { + return ASSET_MAP_TABLE_LOADING_IMAGES; + } else if (cleanedType == "5C00000000000000") { + return ASSET_MEDAL; + } else if (cleanedType == "5D00000000000000") { + return ASSET_MEDAL_TABLE; + } else if (cleanedType == "5E00000000000000") { + return ASSET_OBJECTIVE; + } else if (cleanedType == "5F00000000000000") { + return ASSET_OBJECTIVE_LIST; + } else if (cleanedType == "6400000000000000") { + return ASSET_LASER; + } else if (cleanedType == "6500000000000000") { + return ASSET_BEAM; + } else if (cleanedType == "6600000000000000") { + return ASSET_STREAMER_HINT; + } else if (cleanedType == "1B00000000000000") { + return ASSET_CG_MEDIA_TABLE; + } + + return ASSET_NONE; +} + +QByteArray ZoneFile_COD12_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod12_360.h b/libs/zonefile/360/zonefile_cod12_360.h new file mode 100644 index 0000000..9aacabe --- /dev/null +++ b/libs/zonefile/360/zonefile_cod12_360.h @@ -0,0 +1,53 @@ +#ifndef ZONEFILE_COD12_360_H +#define ZONEFILE_COD12_360_H + +#include "zonefile.h" + +class ZoneFile_COD12_360: public ZoneFile +{ +public: + ZoneFile_COD12_360(); + ~ZoneFile_COD12_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + GscFile pParseAsset_GSCFile(QDataStream *aZoneFileStream) ; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD12_PC_H diff --git a/libs/zonefile/360/zonefile_cod2_360.cpp b/libs/zonefile/360/zonefile_cod2_360.cpp new file mode 100644 index 0000000..aff7269 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod2_360.cpp @@ -0,0 +1,1112 @@ +#include "zonefile_cod2_360.h" + +#include +#include +#include + +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); + 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); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD2_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD2_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD2_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD2_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +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; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +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); + } + return result; +} + +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 + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (assetType == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (assetType == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (assetType == ASSET_MATERIAL) { // material + result.materials << pParseAsset_Material(aZoneFileStream); + } else if (assetType == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (assetType == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (assetType == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (assetType == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (assetType == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (assetType == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (assetType == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (assetType == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (assetType == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (assetType == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (assetType == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (assetType == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (assetType == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (assetType == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (assetType == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (assetType == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (assetType == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD2_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } 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); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD2_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + 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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + 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)) { + result.name = GetTags()[result.namePtr - 1]; + } + *aZoneFileStream >> result.refNamePtr; + if (result.refNamePtr != 4294967295 && GetTagCount() > result.refNamePtr - 1) { + 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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD2_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // 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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD2_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD2_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD2_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + 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 == "") { + return ASSET_RAW_FILE; + } else if (cleanedType == "") { + return ASSET_EFFECT; + } else if (cleanedType == "") { + return ASSET_SOUND; + } else if (cleanedType == "") { + return ASSET_ANIMATION; + } else if (cleanedType == "") { + return ASSET_COLLISION_MAP; + } else if (cleanedType == "") { + return ASSET_STRING_TABLE; + } else if (cleanedType == "") { + return ASSET_MENU; + } else if (cleanedType == "") { + return ASSET_TECH_SET; + } else if (cleanedType == "") { + return ASSET_LOCAL_STRING; + } else if (cleanedType == "") { + return ASSET_GFX_MAP; + } else if (cleanedType == "") { + return ASSET_LIGHT_DEF; + } else if (cleanedType == "") { + return ASSET_FONT; + } else if (cleanedType == "") { + return ASSET_MODEL; + } else if (cleanedType == "") { + return ASSET_D3DBSP; + } else if (cleanedType == "00000002") { + return ASSET_MATERIAL; + } else if (cleanedType == "") { + return ASSET_GAME_MAP_SP; + } else if (cleanedType == "") { + return ASSET_COL_MAP_SP; + } else if (cleanedType == "") { + return ASSET_PHYS_PRESET; + } else if (cleanedType == "") { + return ASSET_DESTRUCTIBLE; + } else if (cleanedType == "") { + return ASSET_MENU; + } + 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 new file mode 100644 index 0000000..0cdbbed --- /dev/null +++ b/libs/zonefile/360/zonefile_cod2_360.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD2_360_H +#define ZONEFILE_COD2_360_H + +#include "zonefile.h" + +class ZoneFile_COD2_360 : public ZoneFile +{ +public: + ZoneFile_COD2_360(); + ~ZoneFile_COD2_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD2_360_H diff --git a/libs/zonefile/360/zonefile_cod4_360.cpp b/libs/zonefile/360/zonefile_cod4_360.cpp new file mode 100644 index 0000000..8e1955e --- /dev/null +++ b/libs/zonefile/360/zonefile_cod4_360.cpp @@ -0,0 +1,1151 @@ +#include "zonefile_cod4_360.h" + +#include +#include +#include + +ZoneFile_COD4_360::ZoneFile_COD4_360() + : ZoneFile() { + +} + +ZoneFile_COD4_360::~ZoneFile_COD4_360() { + +} + +bool ZoneFile_COD4_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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD4_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD4_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD4_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD4_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD4_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount - 1; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + if (!zoneTag.isEmpty()) { + tags << zoneTag; + } + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD4_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); + } + return result; +} + +AssetMap ZoneFile_COD4_360::pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) { + AssetMap result; + + for (int i = 0; i < assetOrder.size(); i++) { + const QString typeHex = assetOrder[i]; + const AssetType assetType = AssetStrToEnum(typeHex); + const QString typeStr = AssetEnumToStr(assetType); + + if (assetType == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (assetType == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (assetType == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (assetType == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (assetType == ASSET_MATERIAL) { // material + result.materials << pParseAsset_Material(aZoneFileStream); + } else if (assetType == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (assetType == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (assetType == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (assetType == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (assetType == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (assetType == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (assetType == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (assetType == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (assetType == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (assetType == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (assetType == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (assetType == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (assetType == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (assetType == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (assetType == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (assetType == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (assetType == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD4_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD4_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD4_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD4_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Material result; + + *aZoneFileStream >> result.namePtr; + + //aZoneFileStream->skipRawData(23 * 4); + + for (int i = 0; i < 23; i++) { + qint32 unknownPtr; + *aZoneFileStream >> unknownPtr; + result.pointers << unknownPtr; + } + + if (result.namePtr == -1) { + aZoneFileStream->skipRawData(1); + + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.name += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + return result; +} + +Shader ZoneFile_COD4_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD4_360::pParseAsset_TechSet(QDataStream *aZoneFileStream) { + TechSet result; + + qint32 namePtr; + *aZoneFileStream >> namePtr; + + + for (int i = 0; i < 53; i++) { + quint32 ptr; + *aZoneFileStream >> ptr; + + result.pointers << ptr; + } + + //aZoneFileStream->skipRawData(53 * 4); + + if (namePtr == -1) { + aZoneFileStream->skipRawData(1); + + // Parse techset name + char techSetNameChar; + *aZoneFileStream >> techSetNameChar; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + } + + //result.name.replace(",", ""); + return result; +} + +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; + + 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) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD4_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { + SoundAsset result; + + 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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD4_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD4_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD4_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD4_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD4_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD4_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "00000021") { + return ASSET_RAW_FILE; + } else if (cleanedType == "0000001A") { + return ASSET_EFFECT; + } else if (cleanedType == "00000009") { + return ASSET_SOUND; + } else if (cleanedType == "00000004") { + return ASSET_ANIMATION; + } else if (cleanedType == "0000000C") { + return ASSET_COLLISION_MAP; + } else if (cleanedType == "00000021") { + return ASSET_STRING_TABLE; + } else if (cleanedType == "00000015") { + return ASSET_MENU; + } else if (cleanedType == "00000008") { + return ASSET_TECH_SET; + } else if (cleanedType == "00000018") { + return ASSET_LOCAL_STRING; + } 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") { + return ASSET_MATERIAL; + } else if (cleanedType == "0000000E") { + return ASSET_GAME_MAP_SP; + } else if (cleanedType == "0000000B") { + return ASSET_COL_MAP_SP; + } else if (cleanedType == "00000001") { + return ASSET_PHYS_PRESET; + } else if (cleanedType == "00000003") { + return ASSET_DESTRUCTIBLE; + } else if (cleanedType == "00000016") { + return ASSET_MENU; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD4_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod4_360.h b/libs/zonefile/360/zonefile_cod4_360.h new file mode 100644 index 0000000..173db2d --- /dev/null +++ b/libs/zonefile/360/zonefile_cod4_360.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD4_360_H +#define ZONEFILE_COD4_360_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD4_360 : public ZoneFile +{ +public: + ZoneFile_COD4_360(); + ~ZoneFile_COD4_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD4_360_H diff --git a/libs/zonefile/360/zonefile_cod5_360.cpp b/libs/zonefile/360/zonefile_cod5_360.cpp new file mode 100644 index 0000000..1149637 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod5_360.cpp @@ -0,0 +1,1151 @@ +#include "zonefile_cod5_360.h" + +#include +#include +#include + +ZoneFile_COD5_360::ZoneFile_COD5_360() + : ZoneFile() { + +} + +ZoneFile_COD5_360::~ZoneFile_COD5_360() { + +} + +bool ZoneFile_COD5_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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD5_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD5_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD5_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD5_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD5_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount - 1; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + if (!zoneTag.isEmpty()) { + tags << zoneTag; + } + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD5_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); + } + return result; +} + +AssetMap ZoneFile_COD5_360::pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) { + AssetMap result; + + for (int i = 0; i < assetOrder.size(); i++) { + const QString typeHex = assetOrder[i]; + const AssetType assetType = AssetStrToEnum(typeHex); + const QString typeStr = AssetEnumToStr(assetType); + + if (assetType == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (assetType == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (assetType == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (assetType == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (assetType == ASSET_MATERIAL) { // material + result.materials << pParseAsset_Material(aZoneFileStream); + } else if (assetType == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (assetType == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (assetType == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (assetType == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (assetType == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (assetType == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (assetType == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (assetType == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (assetType == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (assetType == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (assetType == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (assetType == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (assetType == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (assetType == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (assetType == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (assetType == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (assetType == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD5_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD5_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD5_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD5_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD5_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Material result; + + *aZoneFileStream >> result.namePtr; + + //aZoneFileStream->skipRawData(23 * 4); + + for (int i = 0; i < 23; i++) { + qint32 unknownPtr; + *aZoneFileStream >> unknownPtr; + result.pointers << unknownPtr; + } + + if (result.namePtr == -1) { + aZoneFileStream->skipRawData(1); + + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.name += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + return result; +} + +Shader ZoneFile_COD5_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD5_360::pParseAsset_TechSet(QDataStream *aZoneFileStream) { + TechSet result; + + qint32 namePtr; + *aZoneFileStream >> namePtr; + + + for (int i = 0; i < 53; i++) { + quint32 ptr; + *aZoneFileStream >> ptr; + + result.pointers << ptr; + } + + //aZoneFileStream->skipRawData(53 * 4); + + if (namePtr == -1) { + aZoneFileStream->skipRawData(1); + + // Parse techset name + char techSetNameChar; + *aZoneFileStream >> techSetNameChar; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + } + + //result.name.replace(",", ""); + return result; +} + +Image ZoneFile_COD5_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD5_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { + SoundAsset result; + + 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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD5_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD5_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD5_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD5_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD5_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD5_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "00000021") { + return ASSET_RAW_FILE; + } else if (cleanedType == "0000001A") { + return ASSET_EFFECT; + } else if (cleanedType == "00000009") { + return ASSET_SOUND; + } else if (cleanedType == "00000004") { + return ASSET_ANIMATION; + } else if (cleanedType == "0000000C") { + return ASSET_COLLISION_MAP; + } else if (cleanedType == "00000021") { + return ASSET_STRING_TABLE; + } else if (cleanedType == "00000015") { + return ASSET_MENU; + } else if (cleanedType == "00000008") { + return ASSET_TECH_SET; + } else if (cleanedType == "00000018") { + return ASSET_LOCAL_STRING; + } 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") { + return ASSET_MATERIAL; + } else if (cleanedType == "0000000E") { + return ASSET_GAME_MAP_SP; + } else if (cleanedType == "0000000B") { + return ASSET_COL_MAP_SP; + } else if (cleanedType == "00000001") { + return ASSET_PHYS_PRESET; + } else if (cleanedType == "00000003") { + return ASSET_DESTRUCTIBLE; + } else if (cleanedType == "00000016") { + return ASSET_MENU; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD5_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod5_360.h b/libs/zonefile/360/zonefile_cod5_360.h new file mode 100644 index 0000000..b46409d --- /dev/null +++ b/libs/zonefile/360/zonefile_cod5_360.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD5_360_H +#define ZONEFILE_COD5_360_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD5_360 : public ZoneFile +{ +public: + ZoneFile_COD5_360(); + ~ZoneFile_COD5_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD5_360_H diff --git a/libs/zonefile/360/zonefile_cod6_360.cpp b/libs/zonefile/360/zonefile_cod6_360.cpp new file mode 100644 index 0000000..aaf7d38 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod6_360.cpp @@ -0,0 +1,1151 @@ +#include "zonefile_cod6_360.h" + +#include +#include +#include + +ZoneFile_COD6_360::ZoneFile_COD6_360() + : ZoneFile() { + +} + +ZoneFile_COD6_360::~ZoneFile_COD6_360() { + +} + +bool ZoneFile_COD6_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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD6_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD6_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD6_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD6_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD6_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount - 1; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + if (!zoneTag.isEmpty()) { + tags << zoneTag; + } + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD6_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); + } + return result; +} + +AssetMap ZoneFile_COD6_360::pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) { + AssetMap result; + + for (int i = 0; i < assetOrder.size(); i++) { + const QString typeHex = assetOrder[i]; + const AssetType assetType = AssetStrToEnum(typeHex); + const QString typeStr = AssetEnumToStr(assetType); + + if (assetType == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (assetType == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (assetType == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (assetType == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (assetType == ASSET_MATERIAL) { // material + result.materials << pParseAsset_Material(aZoneFileStream); + } else if (assetType == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (assetType == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (assetType == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (assetType == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (assetType == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (assetType == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (assetType == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (assetType == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (assetType == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (assetType == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (assetType == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (assetType == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (assetType == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (assetType == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (assetType == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (assetType == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (assetType == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD6_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD6_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD6_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD6_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD6_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Material result; + + *aZoneFileStream >> result.namePtr; + + //aZoneFileStream->skipRawData(23 * 4); + + for (int i = 0; i < 23; i++) { + qint32 unknownPtr; + *aZoneFileStream >> unknownPtr; + result.pointers << unknownPtr; + } + + if (result.namePtr == -1) { + aZoneFileStream->skipRawData(1); + + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.name += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + return result; +} + +Shader ZoneFile_COD6_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD6_360::pParseAsset_TechSet(QDataStream *aZoneFileStream) { + TechSet result; + + qint32 namePtr; + *aZoneFileStream >> namePtr; + + + for (int i = 0; i < 53; i++) { + quint32 ptr; + *aZoneFileStream >> ptr; + + result.pointers << ptr; + } + + //aZoneFileStream->skipRawData(53 * 4); + + if (namePtr == -1) { + aZoneFileStream->skipRawData(1); + + // Parse techset name + char techSetNameChar; + *aZoneFileStream >> techSetNameChar; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + } + + //result.name.replace(",", ""); + return result; +} + +Image ZoneFile_COD6_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD6_360::pParseAsset_Sound(QDataStream *aZoneFileStream) { + SoundAsset result; + + 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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD6_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD6_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD6_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD6_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD6_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD6_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "00000021") { + return ASSET_RAW_FILE; + } else if (cleanedType == "0000001A") { + return ASSET_EFFECT; + } else if (cleanedType == "00000009") { + return ASSET_SOUND; + } else if (cleanedType == "00000004") { + return ASSET_ANIMATION; + } else if (cleanedType == "0000000C") { + return ASSET_COLLISION_MAP; + } else if (cleanedType == "00000021") { + return ASSET_STRING_TABLE; + } else if (cleanedType == "00000015") { + return ASSET_MENU; + } else if (cleanedType == "00000008") { + return ASSET_TECH_SET; + } else if (cleanedType == "00000018") { + return ASSET_LOCAL_STRING; + } 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") { + return ASSET_MATERIAL; + } else if (cleanedType == "0000000E") { + return ASSET_GAME_MAP_SP; + } else if (cleanedType == "0000000B") { + return ASSET_COL_MAP_SP; + } else if (cleanedType == "00000001") { + return ASSET_PHYS_PRESET; + } else if (cleanedType == "00000003") { + return ASSET_DESTRUCTIBLE; + } else if (cleanedType == "00000016") { + return ASSET_MENU; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD6_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod6_360.h b/libs/zonefile/360/zonefile_cod6_360.h new file mode 100644 index 0000000..3086068 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod6_360.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD6_360_H +#define ZONEFILE_COD6_360_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD6_360 : public ZoneFile +{ +public: + ZoneFile_COD6_360(); + ~ZoneFile_COD6_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD6_360_H diff --git a/libs/zonefile/360/zonefile_cod7_360.cpp b/libs/zonefile/360/zonefile_cod7_360.cpp new file mode 100644 index 0000000..4d745bb --- /dev/null +++ b/libs/zonefile/360/zonefile_cod7_360.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod7_360.h" + +#include +#include +#include + +ZoneFile_COD7_360::ZoneFile_COD7_360() +{ + +} + +ZoneFile_COD7_360::~ZoneFile_COD7_360() +{ + +} + +bool ZoneFile_COD7_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.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD7_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + pParseZoneUnknownsA(aZoneFileStream); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD7_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD7_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD7_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD7_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD7_360::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD7_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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD7_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD7_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD7_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD7_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD7_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD7_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD7_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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD7_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD7_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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD7_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD7_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD7_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD7_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD7_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD7_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD7_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod7_360.h b/libs/zonefile/360/zonefile_cod7_360.h new file mode 100644 index 0000000..f61f040 --- /dev/null +++ b/libs/zonefile/360/zonefile_cod7_360.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD7_360_H +#define ZONEFILE_COD7_360_H + +#include "zonefile.h" + +class ZoneFile_COD7_360 : public ZoneFile +{ +public: + ZoneFile_COD7_360(); + ~ZoneFile_COD7_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD7_360_H diff --git a/libs/zonefile/360/zonefile_cod8_360.cpp b/libs/zonefile/360/zonefile_cod8_360.cpp new file mode 100644 index 0000000..c17fa3e --- /dev/null +++ b/libs/zonefile/360/zonefile_cod8_360.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod8_360.h" + +#include +#include +#include + +ZoneFile_COD8_360::ZoneFile_COD8_360() +{ + +} + +ZoneFile_COD8_360::~ZoneFile_COD8_360() +{ + +} + +bool ZoneFile_COD8_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.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD8_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + pParseZoneUnknownsA(aZoneFileStream); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD8_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD8_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD8_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD8_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD8_360::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD8_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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD8_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD8_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD8_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD8_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD8_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD8_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD8_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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD8_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD8_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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD8_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD8_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD8_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD8_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD8_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD8_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD8_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod8_360.h b/libs/zonefile/360/zonefile_cod8_360.h new file mode 100644 index 0000000..13c419e --- /dev/null +++ b/libs/zonefile/360/zonefile_cod8_360.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD8_360_H +#define ZONEFILE_COD8_360_H + +#include "zonefile.h" + +class ZoneFile_COD8_360 : public ZoneFile +{ +public: + ZoneFile_COD8_360(); + ~ZoneFile_COD8_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD8_360_H diff --git a/libs/zonefile/360/zonefile_cod9_360.cpp b/libs/zonefile/360/zonefile_cod9_360.cpp new file mode 100644 index 0000000..5155c1c --- /dev/null +++ b/libs/zonefile/360/zonefile_cod9_360.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod9_360.h" + +#include +#include +#include + +ZoneFile_COD9_360::ZoneFile_COD9_360() +{ + +} + +ZoneFile_COD9_360::~ZoneFile_COD9_360() +{ + +} + +bool ZoneFile_COD9_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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD9_360::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD9_360::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD9_360::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD9_360::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_360::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD9_360::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD9_360::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD9_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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD9_360::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD9_360::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD9_360::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD9_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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD9_360::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD9_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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD9_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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD9_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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD9_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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD9_360::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD9_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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD9_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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD9_360::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_360::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD9_360::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD9_360::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD9_360::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/360/zonefile_cod9_360.h b/libs/zonefile/360/zonefile_cod9_360.h new file mode 100644 index 0000000..f52fcde --- /dev/null +++ b/libs/zonefile/360/zonefile_cod9_360.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD9_360_H +#define ZONEFILE_COD9_360_H + +#include "zonefile.h" + +class ZoneFile_COD9_360 : public ZoneFile +{ +public: + ZoneFile_COD9_360(); + ~ZoneFile_COD9_360(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD9_360_H diff --git a/libs/zonefile/PC/zonefile_cod10_pc.cpp b/libs/zonefile/PC/zonefile_cod10_pc.cpp new file mode 100644 index 0000000..650d772 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod10_pc.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod10_pc.h" + +#include +#include +#include + +ZoneFile_COD10_PC::ZoneFile_COD10_PC() +{ + +} + +ZoneFile_COD10_PC::~ZoneFile_COD10_PC() +{ + +} + +bool ZoneFile_COD10_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD10_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD10_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD10_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD10_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD10_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD10_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD10_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD10_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD10_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD10_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD10_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD10_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD10_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD10_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD10_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD10_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD10_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD10_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD10_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD10_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD10_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD10_PC::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD10_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod10_pc.h b/libs/zonefile/PC/zonefile_cod10_pc.h new file mode 100644 index 0000000..8443654 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod10_pc.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD10_PC_H +#define ZONEFILE_COD10_PC_H + +#include "zonefile.h" + +class ZoneFile_COD10_PC : public ZoneFile +{ +public: + ZoneFile_COD10_PC(); + ~ZoneFile_COD10_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD10_PC_H diff --git a/libs/zonefile/PC/zonefile_cod11_pc.cpp b/libs/zonefile/PC/zonefile_cod11_pc.cpp new file mode 100644 index 0000000..516d83a --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod11_pc.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod11_pc.h" + +#include +#include +#include + +ZoneFile_COD11_PC::ZoneFile_COD11_PC() +{ + +} + +ZoneFile_COD11_PC::~ZoneFile_COD11_PC() +{ + +} + +bool ZoneFile_COD11_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD11_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD11_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD11_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD11_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD11_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD11_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD11_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD11_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD11_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD11_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD11_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD11_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD11_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD11_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD11_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD11_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD11_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD11_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD11_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD11_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD11_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD11_PC::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD11_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod11_pc.h b/libs/zonefile/PC/zonefile_cod11_pc.h new file mode 100644 index 0000000..27f0003 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod11_pc.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD11_H +#define ZONEFILE_COD11_H + +#include "zonefile.h" + +class ZoneFile_COD11_PC : public ZoneFile +{ +public: + ZoneFile_COD11_PC(); + ~ZoneFile_COD11_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD11_H diff --git a/libs/zonefile/PC/zonefile_cod12_pc.cpp b/libs/zonefile/PC/zonefile_cod12_pc.cpp new file mode 100644 index 0000000..28dcb7d --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod12_pc.cpp @@ -0,0 +1,1207 @@ +#include "zonefile_cod12_pc.h" + +#include +#include +#include + +ZoneFile_COD12_PC::ZoneFile_COD12_PC() +{ + +} + +ZoneFile_COD12_PC::~ZoneFile_COD12_PC() +{ + +} + +bool ZoneFile_COD12_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD12_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + aZoneFileStream->skipRawData(7 * 4); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream) - 1; + SetRecordCount(recordCount); + + aZoneFileStream->skipRawData(5 * 4); + + if (tagCount) { + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } +} + +quint32 ZoneFile_COD12_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD12_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD12_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD12_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(8 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + if (aZoneFileStream->device()->peek(8).toHex().contains("00000000")) { + break; + } + + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD12_PC::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(8, Qt::Uninitialized); + aZoneFileStream->readRawData(rawAssetType.data(), 8); + result << rawAssetType.toHex(); + + // Skip separator + aZoneFileStream->skipRawData(8); + } + return result; +} + +AssetMap ZoneFile_COD12_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // raw file + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_SCRIPT_PARSE_TREE) { // gsc + auto gscFile = pParseAsset_GSCFile(aZoneFileStream); + if (gscFile.length) { + result.gscFiles << gscFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD12_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD12_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +GscFile ZoneFile_COD12_PC::pParseAsset_GSCFile(QDataStream *aZoneFileStream) { + GscFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(8); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(8); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD12_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD12_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD12_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD12_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD12_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD12_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD12_PC::pParseAsset_Sound(QDataStream *aZoneFileStream) { + SoundAsset result; + return 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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD12_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD12_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD12_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD12_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD12_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD12_PC::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "0000000000000000") { + return ASSET_PHYS_PRESET; + } else if (cleanedType == "0100000000000000") { + return ASSET_PHYS_CONSTRAINTS; + } else if (cleanedType == "0200000000000000") { + return ASSET_DESTRUCTIBLE_DEF; + } else if (cleanedType == "0300000000000000") { + return ASSET_ANIMATION; + } else if (cleanedType == "0400000000000000") { + return ASSET_MODEL; + } else if (cleanedType == "0500000000000000") { + return ASSET_MODEL_MESH; + } else if (cleanedType == "0600000000000000") { + return ASSET_MATERIAL; + } else if (cleanedType == "0700000000000000") { + return ASSET_COMPUTE_SHADER_SET; + } else if (cleanedType == "0800000000000000") { + return ASSET_TECH_SET; + } else if (cleanedType == "0900000000000000") { + return ASSET_IMAGE; + } else if (cleanedType == "0A00000000000000") { + return ASSET_SOUND; + } else if (cleanedType == "1100000000000000") { + return ASSET_LIGHT_DEF; + } else if (cleanedType == "1500000000000000") { + return ASSET_FONT_ICON; + } else if (cleanedType == "1700000000000000") { + return ASSET_WEAPON; + } else if (cleanedType == "1C00000000000000") { + return ASSET_PLAYER_SOUNDS_TABLE; + } else if (cleanedType == "1D00000000000000") { + return ASSET_PLAYER_FX_TABLE; + } else if (cleanedType == "1E00000000000000") { + return ASSET_SHARED_WEAPON_SOUNDS; + } else if (cleanedType == "1F00000000000000") { + return ASSET_ATTACHMENT; + } else if (cleanedType == "2000000000000000") { + return ASSET_ATTACHMENT_UNIQUE; + } else if (cleanedType == "2100000000000000") { + return ASSET_WEAPON_CAMO; + } else if (cleanedType == "2200000000000000") { + return ASSET_CUSTOMIZATION_TABLE; + } else if (cleanedType == "2300000000000000") { + return ASSET_CUSTOMIZATION_TABLE_FEIMAGES; + } else if (cleanedType == "2400000000000000") { + return ASSET_CUSTOMIZATION_TABLE_COLOR; + }else if (cleanedType == "2600000000000000") { + return ASSET_EFFECT; + } else if (cleanedType == "2F00000000000000") { + return ASSET_RAW_FILE; + } else if (cleanedType == "3000000000000000") { + return ASSET_STRING_TABLE; + } else if (cleanedType == "3100000000000000") { + return ASSET_STRUCTURED_TABLE; + } else if (cleanedType == "3200000000000000") { + return ASSET_LEADERBOARD_DEF; + } else if (cleanedType == "3300000000000000") { + return ASSET_DDL; + } else if (cleanedType == "3600000000000000") { + return ASSET_SCRIPT_PARSE_TREE; + } else if (cleanedType == "3700000000000000") { + return ASSET_KEY_VALUE_PAIRS; + } else if (cleanedType == "3800000000000000") { + return ASSET_VEHICLE; + } else if (cleanedType == "3A00000000000000") { + return ASSET_VEHICLE_TRACER; + } else if (cleanedType == "3C00000000000000") { + return ASSET_SURFACE_FX_TABLE; + } else if (cleanedType == "3D00000000000000") { + return ASSET_SURFACE_SOUND_DEF; + } else if (cleanedType == "3E00000000000000") { + return ASSET_FOOTSTEP_TABLE; + } else if (cleanedType == "3F00000000000000") { + return ASSET_ENTITY_FX_IMPACTS; + } else if (cleanedType == "4000000000000000") { + return ASSET_ENTITY_SOUND_IMPACTS; + } else if (cleanedType == "4200000000000000") { + return ASSET_VEHICLE_FX_DEF; + } else if (cleanedType == "4300000000000000") { + return ASSET_VEHICLE_SOUND_DEF; + } else if (cleanedType == "4500000000000000") { + return ASSET_SCRIPT_BUNDLE; + } else if (cleanedType == "4600000000000000") { + return ASSET_SCRIPT_BUNDLE_LIST; + } else if (cleanedType == "4700000000000000") { + return ASSET_RUMBLE; + } else if (cleanedType == "4A00000000000000") { + return ASSET_AIM_TABLE; + } else if (cleanedType == "4B00000000000000") { + return ASSET_ANIM_SELECTOR_TABLE; + } else if (cleanedType == "4C00000000000000") { + return ASSET_ANIM_MAPPING_TABLE; + } else if (cleanedType == "4D00000000000000") { + return ASSET_ANIM_STATE_MACHINE; + } else if (cleanedType == "4E00000000000000") { + return ASSET_BEHAVIOR_TREE; + } else if (cleanedType == "4F00000000000000") { + return ASSET_BEHAVIOR_STATE_MACHINE; + } else if (cleanedType == "5100000000000000") { + return ASSET_S_ANIM; + } else if (cleanedType == "5200000000000000") { + return ASSET_LIGHT_DEF; + } else if (cleanedType == "5300000000000000") { + return ASSET_BIT_FIELD; + } else if (cleanedType == "5400000000000000") { + return ASSET_SURFACE_SOUND_DEF; + } else if (cleanedType == "5500000000000000") { + return ASSET_SURFACE_FX_TABLE; + } else if (cleanedType == "5600000000000000") { + return ASSET_RUMBLE; + } else if (cleanedType == "5900000000000000") { + return ASSET_AIM_TABLE; + } else if (cleanedType == "5A00000000000000") { + return ASSET_MAP_TABLE; + } else if (cleanedType == "5B00000000000000") { + return ASSET_MAP_TABLE_LOADING_IMAGES; + } else if (cleanedType == "5C00000000000000") { + return ASSET_MEDAL; + } else if (cleanedType == "5D00000000000000") { + return ASSET_MEDAL_TABLE; + } else if (cleanedType == "5E00000000000000") { + return ASSET_OBJECTIVE; + } else if (cleanedType == "5F00000000000000") { + return ASSET_OBJECTIVE_LIST; + } else if (cleanedType == "6400000000000000") { + return ASSET_LASER; + } else if (cleanedType == "6500000000000000") { + return ASSET_BEAM; + } else if (cleanedType == "6600000000000000") { + return ASSET_STREAMER_HINT; + } else if (cleanedType == "1B00000000000000") { + return ASSET_CG_MEDIA_TABLE; + } + + return ASSET_NONE; +} + +QByteArray ZoneFile_COD12_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod12_pc.h b/libs/zonefile/PC/zonefile_cod12_pc.h new file mode 100644 index 0000000..5d246a1 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod12_pc.h @@ -0,0 +1,53 @@ +#ifndef ZONEFILE_COD12_PC_H +#define ZONEFILE_COD12_PC_H + +#include "zonefile.h" + +class ZoneFile_COD12_PC : public ZoneFile +{ +public: + ZoneFile_COD12_PC(); + ~ZoneFile_COD12_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + GscFile pParseAsset_GSCFile(QDataStream *aZoneFileStream) ; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD12_PC_H diff --git a/libs/zonefile/PC/zonefile_cod4_pc.cpp b/libs/zonefile/PC/zonefile_cod4_pc.cpp new file mode 100644 index 0000000..6359151 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod4_pc.cpp @@ -0,0 +1,1140 @@ +#include "zonefile_cod4_pc.h" + +#include +#include +#include + +ZoneFile_COD4_PC::ZoneFile_COD4_PC() + : ZoneFile() { + +} + +ZoneFile_COD4_PC::~ZoneFile_COD4_PC() { + +} + +bool ZoneFile_COD4_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD4_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD4_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD4_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD4_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD4_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD4_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD4_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD4_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD4_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + qDebug() << "rawFileLength: " << result.length; + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD4_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD4_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD4_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + aZoneFileStream->skipRawData(27 * 4); + + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + // TODO: Fill out this material + return Material(); +} + +Shader ZoneFile_COD4_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD4_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD4_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD4_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD4_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD4_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD4_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD4_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD4_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD4_PC::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 + 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 + 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; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD4_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod4_pc.h b/libs/zonefile/PC/zonefile_cod4_pc.h new file mode 100644 index 0000000..be47e4f --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod4_pc.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD4_PC_H +#define ZONEFILE_COD4_PC_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD4_PC : public ZoneFile +{ +public: + ZoneFile_COD4_PC(); + ~ZoneFile_COD4_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD4_PC_H diff --git a/libs/zonefile/PC/zonefile_cod5_pc.cpp b/libs/zonefile/PC/zonefile_cod5_pc.cpp new file mode 100644 index 0000000..fc93a04 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod5_pc.cpp @@ -0,0 +1,1140 @@ +#include "zonefile_cod5_pc.h" + +#include +#include +#include + +ZoneFile_COD5_PC::ZoneFile_COD5_PC() + : ZoneFile() { + +} + +ZoneFile_COD5_PC::~ZoneFile_COD5_PC() { + +} + +bool ZoneFile_COD5_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD5_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD5_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD5_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD5_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD5_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD5_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD5_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD5_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD5_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + qDebug() << "rawFileLength: " << result.length; + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD5_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD5_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD5_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + aZoneFileStream->skipRawData(27 * 4); + + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + // TODO: Fill out this material + return Material(); +} + +Shader ZoneFile_COD5_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD5_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD5_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD5_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD5_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD5_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD5_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD5_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD5_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD5_PC::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 + 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 + 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; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD5_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod5_pc.h b/libs/zonefile/PC/zonefile_cod5_pc.h new file mode 100644 index 0000000..5125441 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod5_pc.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD5_PC_H +#define ZONEFILE_COD5_PC_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD5_PC : public ZoneFile +{ +public: + ZoneFile_COD5_PC(); + ~ZoneFile_COD5_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD5_PC_H diff --git a/libs/zonefile/PC/zonefile_cod6_pc.cpp b/libs/zonefile/PC/zonefile_cod6_pc.cpp new file mode 100644 index 0000000..1b2dfb6 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod6_pc.cpp @@ -0,0 +1,1140 @@ +#include "zonefile_cod6_pc.h" + +#include +#include +#include + +ZoneFile_COD6_PC::ZoneFile_COD6_PC() + : ZoneFile() { + +} + +ZoneFile_COD6_PC::~ZoneFile_COD6_PC() { + +} + +bool ZoneFile_COD6_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD6_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD6_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD6_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD6_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD6_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD6_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD6_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD6_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD6_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + qDebug() << "rawFileLength: " << result.length; + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD6_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD6_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD6_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + aZoneFileStream->skipRawData(27 * 4); + + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + // TODO: Fill out this material + return Material(); +} + +Shader ZoneFile_COD6_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD6_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD6_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD6_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD6_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD6_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD6_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD6_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD6_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD6_PC::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 + 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 + 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; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD6_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod6_pc.h b/libs/zonefile/PC/zonefile_cod6_pc.h new file mode 100644 index 0000000..4ecfed3 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod6_pc.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD6_PC_H +#define ZONEFILE_COD6_PC_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD6_PC : public ZoneFile +{ +public: + ZoneFile_COD6_PC(); + ~ZoneFile_COD6_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD6_PC_H diff --git a/libs/zonefile/PC/zonefile_cod7_pc.cpp b/libs/zonefile/PC/zonefile_cod7_pc.cpp new file mode 100644 index 0000000..9d491fa --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod7_pc.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod7_pc.h" + +#include +#include +#include + +ZoneFile_COD7_PC::ZoneFile_COD7_PC() +{ + +} + +ZoneFile_COD7_PC::~ZoneFile_COD7_PC() +{ + +} + +bool ZoneFile_COD7_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + zoneFileStream.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD7_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + pParseZoneUnknownsA(aZoneFileStream); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD7_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD7_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD7_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD7_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD7_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD7_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD7_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD7_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD7_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD7_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD7_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD7_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD7_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD7_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD7_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD7_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD7_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD7_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD7_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD7_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD7_PC::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD7_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod7_pc.h b/libs/zonefile/PC/zonefile_cod7_pc.h new file mode 100644 index 0000000..dec60e4 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod7_pc.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD7_PC_H +#define ZONEFILE_COD7_PC_H + +#include "zonefile.h" + +class ZoneFile_COD7_PC : public ZoneFile +{ +public: + ZoneFile_COD7_PC(); + ~ZoneFile_COD7_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD7_PC_H diff --git a/libs/zonefile/PC/zonefile_cod8_pc.cpp b/libs/zonefile/PC/zonefile_cod8_pc.cpp new file mode 100644 index 0000000..1d62c80 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod8_pc.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod8_pc.h" + +#include +#include +#include + +ZoneFile_COD8_PC::ZoneFile_COD8_PC() +{ + +} + +ZoneFile_COD8_PC::~ZoneFile_COD8_PC() +{ + +} + +bool ZoneFile_COD8_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + zoneFileStream.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD8_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + pParseZoneUnknownsA(aZoneFileStream); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD8_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD8_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD8_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD8_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD8_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD8_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD8_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD8_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD8_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD8_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD8_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD8_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD8_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD8_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD8_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD8_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD8_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD8_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD8_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD8_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD8_PC::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD8_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod8_pc.h b/libs/zonefile/PC/zonefile_cod8_pc.h new file mode 100644 index 0000000..5ba5f15 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod8_pc.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD7_PC_H +#define ZONEFILE_COD7_PC_H + +#include "zonefile.h" + +class ZoneFile_COD8_PC : public ZoneFile +{ +public: + ZoneFile_COD8_PC(); + ~ZoneFile_COD8_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD7_PC_H diff --git a/libs/zonefile/PC/zonefile_cod9_pc.cpp b/libs/zonefile/PC/zonefile_cod9_pc.cpp new file mode 100644 index 0000000..c4a2b83 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod9_pc.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod9_pc.h" + +#include +#include +#include + +ZoneFile_COD9_PC::ZoneFile_COD9_PC() +{ + +} + +ZoneFile_COD9_PC::~ZoneFile_COD9_PC() +{ + +} + +bool ZoneFile_COD9_PC::Load(const QByteArray aFileData) { + // Open zone file as little endian stream + QDataStream zoneFileStream(aFileData); + zoneFileStream.setByteOrder(QDataStream::LittleEndian); + + // Parse data from zone file header + pParseZoneHeader(&zoneFileStream); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD9_PC::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD9_PC::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_PC::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD9_PC::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD9_PC::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_PC::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_PC::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD9_PC::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD9_PC::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD9_PC::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD9_PC::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD9_PC::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD9_PC::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD9_PC::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD9_PC::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD9_PC::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD9_PC::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD9_PC::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD9_PC::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD9_PC::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD9_PC::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD9_PC::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD9_PC::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PC::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD9_PC::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD9_PC::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD9_PC::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PC/zonefile_cod9_pc.h b/libs/zonefile/PC/zonefile_cod9_pc.h new file mode 100644 index 0000000..e71ac54 --- /dev/null +++ b/libs/zonefile/PC/zonefile_cod9_pc.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD9_PC_H +#define ZONEFILE_COD9_PC_H + +#include "zonefile.h" + +class ZoneFile_COD9_PC : public ZoneFile +{ +public: + ZoneFile_COD9_PC(); + ~ZoneFile_COD9_PC(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD9_PC_H diff --git a/libs/zonefile/PS3/zonefile_cod10_ps3.cpp b/libs/zonefile/PS3/zonefile_cod10_ps3.cpp new file mode 100644 index 0000000..243d594 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod10_ps3.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod10_ps3.h" + +#include +#include +#include + +ZoneFile_COD10_PS3::ZoneFile_COD10_PS3() +{ + +} + +ZoneFile_COD10_PS3::~ZoneFile_COD10_PS3() +{ + +} + +bool ZoneFile_COD10_PS3::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD10_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD10_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD10_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD10_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD10_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD10_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD10_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD10_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD10_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD10_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD10_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD10_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD10_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD10_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD10_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD10_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD10_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD10_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD10_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD10_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD10_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD10_PS3::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD10_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod10_ps3.h b/libs/zonefile/PS3/zonefile_cod10_ps3.h new file mode 100644 index 0000000..90c07f8 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod10_ps3.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD10_PS3_H +#define ZONEFILE_COD10_PS3_H + +#include "zonefile.h" + +class ZoneFile_COD10_PS3 : public ZoneFile +{ +public: + ZoneFile_COD10_PS3(); + ~ZoneFile_COD10_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD10_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod11_ps3.cpp b/libs/zonefile/PS3/zonefile_cod11_ps3.cpp new file mode 100644 index 0000000..01fec6b --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod11_ps3.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod11_ps3.h" + +#include +#include +#include + +ZoneFile_COD11_PS3::ZoneFile_COD11_PS3() +{ + +} + +ZoneFile_COD11_PS3::~ZoneFile_COD11_PS3() +{ + +} + +bool ZoneFile_COD11_PS3::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD11_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD11_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD11_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD11_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD11_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD11_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD11_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD11_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD11_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD11_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD11_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD11_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD11_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD11_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD11_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD11_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD11_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD11_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD11_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD11_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD11_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD11_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD11_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD11_PS3::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD11_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod11_ps3.h b/libs/zonefile/PS3/zonefile_cod11_ps3.h new file mode 100644 index 0000000..a8c16f3 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod11_ps3.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD11_PS3_H +#define ZONEFILE_COD11_PS3_H + +#include "zonefile.h" + +class ZoneFile_COD11_PS3 : public ZoneFile +{ +public: + ZoneFile_COD11_PS3(); + ~ZoneFile_COD11_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD11_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod12_ps3.cpp b/libs/zonefile/PS3/zonefile_cod12_ps3.cpp new file mode 100644 index 0000000..9d6f3f1 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod12_ps3.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod12_ps3.h" + +#include +#include +#include + +ZoneFile_COD12_PS3::ZoneFile_COD12_PS3() +{ + +} + +ZoneFile_COD12_PS3::~ZoneFile_COD12_PS3() +{ + +} + +bool ZoneFile_COD12_PS3::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD12_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD12_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD12_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD12_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD12_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD12_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD12_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD12_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD12_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD12_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD12_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD12_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD12_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD12_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD12_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD12_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD12_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD12_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD12_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD12_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD12_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD12_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD12_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD12_PS3::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD12_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod12_ps3.h b/libs/zonefile/PS3/zonefile_cod12_ps3.h new file mode 100644 index 0000000..98c1b09 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod12_ps3.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD12_PS3_H +#define ZONEFILE_COD12_PS3_H + +#include "zonefile.h" + +class ZoneFile_COD12_PS3 : public ZoneFile +{ +public: + ZoneFile_COD12_PS3(); + ~ZoneFile_COD12_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD12_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod4_ps3.cpp b/libs/zonefile/PS3/zonefile_cod4_ps3.cpp new file mode 100644 index 0000000..4e6243a --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod4_ps3.cpp @@ -0,0 +1,1139 @@ +#include "zonefile_cod4_ps3.h" + +#include +#include +#include + +ZoneFile_COD4_PS3::ZoneFile_COD4_PS3() + : ZoneFile() { + +} + +ZoneFile_COD4_PS3::~ZoneFile_COD4_PS3() { + +} + +bool ZoneFile_COD4_PS3::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD4_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD4_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD4_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD4_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD4_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD4_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD4_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD4_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD4_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + qDebug() << "rawFileLength: " << result.length; + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD4_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD4_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD4_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + aZoneFileStream->skipRawData(27 * 4); + + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + // TODO: Fill out this material + return Material(); +} + +Shader ZoneFile_COD4_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD4_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD4_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD4_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD4_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD4_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD4_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD4_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD4_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +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 + 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 + 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; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD4_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod4_ps3.h b/libs/zonefile/PS3/zonefile_cod4_ps3.h new file mode 100644 index 0000000..90033c2 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod4_ps3.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD4_PS3_H +#define ZONEFILE_COD4_PS3_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD4_PS3 : public ZoneFile +{ +public: + ZoneFile_COD4_PS3(); + ~ZoneFile_COD4_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD4_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod5_ps3.cpp b/libs/zonefile/PS3/zonefile_cod5_ps3.cpp new file mode 100644 index 0000000..3eb2015 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod5_ps3.cpp @@ -0,0 +1,1139 @@ +#include "zonefile_cod5_ps3.h" + +#include +#include +#include + +ZoneFile_COD5_PS3::ZoneFile_COD5_PS3() + : ZoneFile() { + +} + +ZoneFile_COD5_PS3::~ZoneFile_COD5_PS3() { + +} + +bool ZoneFile_COD5_PS3::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD5_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD5_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD5_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD5_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD5_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD5_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD5_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD5_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD5_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD5_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + qDebug() << "rawFileLength: " << result.length; + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD5_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD5_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD5_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + aZoneFileStream->skipRawData(27 * 4); + + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + // TODO: Fill out this material + return Material(); +} + +Shader ZoneFile_COD5_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD5_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD5_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD5_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD5_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD5_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD5_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD5_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD5_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD5_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD5_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 + 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 + 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; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD5_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod5_ps3.h b/libs/zonefile/PS3/zonefile_cod5_ps3.h new file mode 100644 index 0000000..62260e0 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod5_ps3.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD5_PS3_H +#define ZONEFILE_COD5_PS3_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD5_PS3 : public ZoneFile +{ +public: + ZoneFile_COD5_PS3(); + ~ZoneFile_COD5_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD5_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod6_ps3.cpp b/libs/zonefile/PS3/zonefile_cod6_ps3.cpp new file mode 100644 index 0000000..9fb8d78 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod6_ps3.cpp @@ -0,0 +1,1139 @@ +#include "zonefile_cod6_ps3.h" + +#include +#include +#include + +ZoneFile_COD6_PS3::ZoneFile_COD6_PS3() + : ZoneFile() { + +} + +ZoneFile_COD6_PS3::~ZoneFile_COD6_PS3() { + +} + +bool ZoneFile_COD6_PS3::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD6_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD6_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD6_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD6_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD6_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD6_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD6_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD6_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD6_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD6_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + result.path.replace(",", ""); + + const QStringList pathParts = result.path.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << result.path; + exit(-1); + } + if (result.path.contains(".bik")) { + qDebug() << "rawFileLength: " << result.length; + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + } + return result; +} + +void ZoneFile_COD6_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD6_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD6_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + aZoneFileStream->skipRawData(27 * 4); + + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + + *aZoneFileStream >> unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + // TODO: Fill out this material + return Material(); +} + +Shader ZoneFile_COD6_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD6_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD6_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD6_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD6_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD6_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD6_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD6_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD6_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD6_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD6_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 + 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 + 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; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD6_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod6_ps3.h b/libs/zonefile/PS3/zonefile_cod6_ps3.h new file mode 100644 index 0000000..4be12ec --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod6_ps3.h @@ -0,0 +1,54 @@ +#ifndef ZONEFILE_COD6_PS3_H +#define ZONEFILE_COD6_PS3_H + +#include + +#include "zonefile.h" + +class ZoneFile_COD6_PS3 : public ZoneFile +{ +public: + ZoneFile_COD6_PS3(); + ~ZoneFile_COD6_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +private: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD6_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod7_ps3.cpp b/libs/zonefile/PS3/zonefile_cod7_ps3.cpp new file mode 100644 index 0000000..0386fc6 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod7_ps3.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod7_ps3.h" + +#include +#include +#include + +ZoneFile_COD7_PS3::ZoneFile_COD7_PS3() +{ + +} + +ZoneFile_COD7_PS3::~ZoneFile_COD7_PS3() +{ + +} + +bool ZoneFile_COD7_PS3::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.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD7_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + pParseZoneUnknownsA(aZoneFileStream); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD7_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD7_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD7_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD7_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD7_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD7_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD7_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD7_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD7_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD7_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD7_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD7_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD7_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD7_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD7_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD7_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD7_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD7_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD7_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD7_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD7_PS3::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD7_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod7_ps3.h b/libs/zonefile/PS3/zonefile_cod7_ps3.h new file mode 100644 index 0000000..73ddd3e --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod7_ps3.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD7_PS3_H +#define ZONEFILE_COD7_PS3_H + +#include "zonefile.h" + +class ZoneFile_COD7_PS3 : public ZoneFile +{ +public: + ZoneFile_COD7_PS3(); + ~ZoneFile_COD7_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD7_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod8_ps3.cpp b/libs/zonefile/PS3/zonefile_cod8_ps3.cpp new file mode 100644 index 0000000..00eaf6d --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod8_ps3.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod8_ps3.h" + +#include +#include +#include + +ZoneFile_COD8_PS3::ZoneFile_COD8_PS3() +{ + +} + +ZoneFile_COD8_PS3::~ZoneFile_COD8_PS3() +{ + +} + +bool ZoneFile_COD8_PS3::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.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD8_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + pParseZoneUnknownsA(aZoneFileStream); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD8_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD8_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD8_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD8_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD8_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD8_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD8_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD8_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD8_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD8_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD8_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD8_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD8_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD8_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD8_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD8_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD8_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD8_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD8_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD8_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD8_PS3::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD8_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod8_ps3.h b/libs/zonefile/PS3/zonefile_cod8_ps3.h new file mode 100644 index 0000000..5787d58 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod8_ps3.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD8_PS3_H +#define ZONEFILE_COD8_PS3_H + +#include "zonefile.h" + +class ZoneFile_COD8_PS3 : public ZoneFile +{ +public: + ZoneFile_COD8_PS3(); + ~ZoneFile_COD8_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD8_PS3_H diff --git a/libs/zonefile/PS3/zonefile_cod9_ps3.cpp b/libs/zonefile/PS3/zonefile_cod9_ps3.cpp new file mode 100644 index 0000000..12ae674 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod9_ps3.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod9_ps3.h" + +#include +#include +#include + +ZoneFile_COD9_PS3::ZoneFile_COD9_PS3() +{ + +} + +ZoneFile_COD9_PS3::~ZoneFile_COD9_PS3() +{ + +} + +bool ZoneFile_COD9_PS3::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD9_PS3::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD9_PS3::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_PS3::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD9_PS3::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD9_PS3::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_PS3::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_PS3::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD9_PS3::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD9_PS3::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD9_PS3::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD9_PS3::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD9_PS3::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD9_PS3::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD9_PS3::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD9_PS3::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD9_PS3::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD9_PS3::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD9_PS3::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD9_PS3::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD9_PS3::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD9_PS3::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD9_PS3::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD9_PS3::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_PS3::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD9_PS3::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD9_PS3::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD9_PS3::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/PS3/zonefile_cod9_ps3.h b/libs/zonefile/PS3/zonefile_cod9_ps3.h new file mode 100644 index 0000000..cba7420 --- /dev/null +++ b/libs/zonefile/PS3/zonefile_cod9_ps3.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD9_PS3_H +#define ZONEFILE_COD9_PS3_H + +#include "zonefile.h" + +class ZoneFile_COD9_PS3 : public ZoneFile +{ +public: + ZoneFile_COD9_PS3(); + ~ZoneFile_COD9_PS3(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD9_PS3_H diff --git a/libs/zonefile/Wii/zonefile_cod4_wii.cpp b/libs/zonefile/Wii/zonefile_cod4_wii.cpp new file mode 100644 index 0000000..6894d5a --- /dev/null +++ b/libs/zonefile/Wii/zonefile_cod4_wii.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod4_wii.h" + +#include +#include +#include + +ZoneFile_COD4_Wii::ZoneFile_COD4_Wii() +{ + +} + +ZoneFile_COD4_Wii::~ZoneFile_COD4_Wii() +{ + +} + +bool ZoneFile_COD4_Wii::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.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD4_Wii::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + aZoneFileStream->skipRawData(36); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount - 1); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD4_Wii::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_Wii::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD4_Wii::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD4_Wii::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_Wii::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD4_Wii::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD4_Wii::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD4_Wii::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD4_Wii::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD4_Wii::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD4_Wii::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD4_Wii::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD4_Wii::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD4_Wii::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD4_Wii::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD4_Wii::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD4_Wii::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD4_Wii::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD4_Wii::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD4_Wii::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD4_Wii::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD4_Wii::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD4_Wii::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD4_Wii::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD4_Wii::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD4_Wii::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/Wii/zonefile_cod4_wii.h b/libs/zonefile/Wii/zonefile_cod4_wii.h new file mode 100644 index 0000000..5f7d588 --- /dev/null +++ b/libs/zonefile/Wii/zonefile_cod4_wii.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD4_WII_H +#define ZONEFILE_COD4_WII_H + +#include "zonefile.h" + +class ZoneFile_COD4_Wii : public ZoneFile +{ +public: + ZoneFile_COD4_Wii(); + ~ZoneFile_COD4_Wii(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD4_WII_H diff --git a/libs/zonefile/Wii/zonefile_cod7_wii.cpp b/libs/zonefile/Wii/zonefile_cod7_wii.cpp new file mode 100644 index 0000000..6ad2e54 --- /dev/null +++ b/libs/zonefile/Wii/zonefile_cod7_wii.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod7_wii.h" + +#include +#include +#include + +ZoneFile_COD7_Wii::ZoneFile_COD7_Wii() +{ + +} + +ZoneFile_COD7_Wii::~ZoneFile_COD7_Wii() +{ + +} + +bool ZoneFile_COD7_Wii::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.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD7_Wii::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + aZoneFileStream->skipRawData(36); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount - 1); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD7_Wii::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_Wii::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD7_Wii::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD7_Wii::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_Wii::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD7_Wii::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD7_Wii::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD7_Wii::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD7_Wii::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD7_Wii::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD7_Wii::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD7_Wii::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD7_Wii::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD7_Wii::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD7_Wii::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD7_Wii::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD7_Wii::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD7_Wii::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD7_Wii::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD7_Wii::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD7_Wii::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD7_Wii::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD7_Wii::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD7_Wii::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD7_Wii::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD7_Wii::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/Wii/zonefile_cod7_wii.h b/libs/zonefile/Wii/zonefile_cod7_wii.h new file mode 100644 index 0000000..da140df --- /dev/null +++ b/libs/zonefile/Wii/zonefile_cod7_wii.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD7_WII_H +#define ZONEFILE_COD7_WII_H + +#include "zonefile.h" + +class ZoneFile_COD7_Wii : public ZoneFile +{ +public: + ZoneFile_COD7_Wii(); + ~ZoneFile_COD7_Wii(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD7_WII_H diff --git a/libs/zonefile/Wii/zonefile_cod8_wii.cpp b/libs/zonefile/Wii/zonefile_cod8_wii.cpp new file mode 100644 index 0000000..710f933 --- /dev/null +++ b/libs/zonefile/Wii/zonefile_cod8_wii.cpp @@ -0,0 +1,1077 @@ +#include "zonefile_cod8_wii.h" + +#include +#include +#include + +ZoneFile_COD8_Wii::ZoneFile_COD8_Wii() +{ + +} + +ZoneFile_COD8_Wii::~ZoneFile_COD8_Wii() +{ + +} + +bool ZoneFile_COD8_Wii::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.device()->seek(zoneFileStream.device()->pos() - 1); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD8_Wii::pParseZoneHeader(QDataStream *aZoneFileStream) { + quint32 size = pParseZoneSize(aZoneFileStream); + SetSize(size); + + aZoneFileStream->skipRawData(36); + + quint32 tagCount = pParseZoneTagCount(aZoneFileStream); + SetTagCount(tagCount - 1); + + pParseZoneUnknownsB(aZoneFileStream); + + quint32 recordCount = pParseZoneRecordCount(aZoneFileStream); + SetRecordCount(recordCount); + + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD8_Wii::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_Wii::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD8_Wii::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD8_Wii::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_Wii::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD8_Wii::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD8_Wii::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD8_Wii::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD8_Wii::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD8_Wii::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD8_Wii::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD8_Wii::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD8_Wii::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD8_Wii::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD8_Wii::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD8_Wii::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD8_Wii::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD8_Wii::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD8_Wii::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD8_Wii::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD8_Wii::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD8_Wii::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD8_Wii::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD8_Wii::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD8_Wii::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD8_Wii::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/Wii/zonefile_cod8_wii.h b/libs/zonefile/Wii/zonefile_cod8_wii.h new file mode 100644 index 0000000..14284e0 --- /dev/null +++ b/libs/zonefile/Wii/zonefile_cod8_wii.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD8_WII_H +#define ZONEFILE_COD8_WII_H + +#include "zonefile.h" + +class ZoneFile_COD8_Wii : public ZoneFile +{ +public: + ZoneFile_COD8_Wii(); + ~ZoneFile_COD8_Wii(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD8_WII_H diff --git a/libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp b/libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp new file mode 100644 index 0000000..f11bbdb --- /dev/null +++ b/libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod10_wiiu.h" + +#include +#include +#include + +ZoneFile_COD10_WiiU::ZoneFile_COD10_WiiU() +{ + +} + +ZoneFile_COD10_WiiU::~ZoneFile_COD10_WiiU() +{ + +} + +bool ZoneFile_COD10_WiiU::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD10_WiiU::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD10_WiiU::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_WiiU::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD10_WiiU::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD10_WiiU::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_WiiU::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD10_WiiU::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD10_WiiU::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD10_WiiU::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD10_WiiU::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD10_WiiU::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD10_WiiU::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD10_WiiU::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD10_WiiU::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD10_WiiU::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD10_WiiU::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD10_WiiU::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD10_WiiU::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD10_WiiU::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD10_WiiU::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD10_WiiU::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD10_WiiU::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD10_WiiU::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD10_WiiU::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD10_WiiU::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD10_WiiU::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD10_WiiU::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/WiiU/zonefile_cod10_wiiu.h b/libs/zonefile/WiiU/zonefile_cod10_wiiu.h new file mode 100644 index 0000000..b51d706 --- /dev/null +++ b/libs/zonefile/WiiU/zonefile_cod10_wiiu.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD10_WIIU_H +#define ZONEFILE_COD10_WIIU_H + +#include "zonefile.h" + +class ZoneFile_COD10_WiiU : public ZoneFile +{ +public: + ZoneFile_COD10_WiiU(); + ~ZoneFile_COD10_WiiU(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD10_WIIU_H diff --git a/libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp b/libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp new file mode 100644 index 0000000..548d14c --- /dev/null +++ b/libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp @@ -0,0 +1,1072 @@ +#include "zonefile_cod9_wiiu.h" + +#include +#include +#include + +ZoneFile_COD9_WiiU::ZoneFile_COD9_WiiU() +{ + +} + +ZoneFile_COD9_WiiU::~ZoneFile_COD9_WiiU() +{ + +} + +bool ZoneFile_COD9_WiiU::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); + SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount())); + SetAssetMap(pParseAssets(&zoneFileStream, GetRecords())); + + return true; +} + +void ZoneFile_COD9_WiiU::pParseZoneHeader(QDataStream *aZoneFileStream) { + SetSize(pParseZoneSize(aZoneFileStream)); + pParseZoneUnknownsA(aZoneFileStream); + + SetTagCount(pParseZoneTagCount(aZoneFileStream)); + pParseZoneUnknownsB(aZoneFileStream); + + SetRecordCount(pParseZoneRecordCount(aZoneFileStream)); + + quint32 tagCount = GetTagCount(); + if (tagCount) { + pParseZoneUnknownsC(aZoneFileStream); + SetTags(pParseZoneTags(aZoneFileStream, tagCount)); + } else { + aZoneFileStream->skipRawData(4); + } +} + +quint32 ZoneFile_COD9_WiiU::pParseZoneSize(QDataStream *aZoneFileStream) { + quint32 zoneFileSize; + *aZoneFileStream >> zoneFileSize; + if (zoneFileSize <= 0) { + qDebug() << "Tried to open empty zone file!"; + exit(-1); + } + zoneFileSize += 36; + return zoneFileSize; +} + +/* + ParseZoneUnknownsA() + + Parses the 1st section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_WiiU::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); +} + +/* + ParseZoneTagCount() + + Parses the number of string tags in the zone index +*/ +quint32 ZoneFile_COD9_WiiU::pParseZoneTagCount(QDataStream *aZoneFileStream) { + quint32 tagCount; + *aZoneFileStream >> tagCount; + return tagCount; +} + +/* + ParseZoneRecordCount() + + Parses the number of records in the zone index +*/ +quint32 ZoneFile_COD9_WiiU::pParseZoneRecordCount(QDataStream *aZoneFileStream) { + quint32 recordCount; + *aZoneFileStream >> recordCount; + return recordCount; +} + +/* + ParseZoneUnknownsB() + + Parses the 2nd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_WiiU::pParseZoneUnknownsB(QDataStream *aZoneFileStream) { + // Byte 44-47: Unknown/empty? + QByteArray unknown9(4, Qt::Uninitialized); + aZoneFileStream->readRawData(unknown9.data(), 4); +} + +/* + pParseZoneUnknownsC() + + Parses the 3rd section of unknowns as hex vals and uint32s +*/ +void ZoneFile_COD9_WiiU::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); +} + +/* + ParseZoneTags() + + Parses the string tags ate the start of zone file +*/ +QStringList ZoneFile_COD9_WiiU::pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) { + QStringList tags; + + // Byte 48-51: Repeated separators? ÿÿÿÿ x i + aZoneFileStream->skipRawData(4 * (tagCount - 1)); + + // Parse tags/strings before index + QString zoneTag; + char zoneTagChar; + for (quint32 i = 0; i < tagCount; i++) { + *aZoneFileStream >> zoneTagChar; + while (zoneTagChar != 0) { + zoneTag += zoneTagChar; + *aZoneFileStream >> zoneTagChar; + } + tags << zoneTag; + zoneTag.clear(); + } + return tags; +} + +/* + ParseZoneIndex() + + Parse the binary zone index data and populate table +*/ +QStringList ZoneFile_COD9_WiiU::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) { + QStringList result; + + // Don't parse if no records + if (!recordCount) { return result; } + + if (aZoneFileStream->device()->peek(4).toHex().contains("ffff")) { + aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 2); + } + + // 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); + } + return result; +} + +AssetMap ZoneFile_COD9_WiiU::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 typeStr = AssetStrToEnum(typeHex); + + if (typeStr == ASSET_LOCAL_STRING) { // localized string asset + result.localStrings << pParseAsset_LocalString(aZoneFileStream); + } else if (typeStr == ASSET_RAW_FILE) { // gsc + auto rawFile = pParseAsset_RawFile(aZoneFileStream); + if (rawFile.length) { + result.rawFiles << rawFile; + } + } else if (typeStr == ASSET_PHYS_PRESET) { // physpreset + pParseAsset_PhysPreset(aZoneFileStream); + } else if (typeStr == ASSET_MODEL) { // xmodel + result.models << pParseAsset_Model(aZoneFileStream); + } else if (typeStr == ASSET_MATERIAL) { // material + pParseAsset_Material(aZoneFileStream); + } else if (typeStr == ASSET_SHADER) { // pixelshader + pParseAsset_Shader(aZoneFileStream); + } else if (typeStr == ASSET_TECH_SET) { // techset include + result.techSets << pParseAsset_TechSet(aZoneFileStream); + } else if (typeStr == ASSET_IMAGE) { // image + result.images << pParseAsset_Image(aZoneFileStream); + } else if (typeStr == ASSET_SOUND) { // loaded_sound + result.sounds << pParseAsset_Sound(aZoneFileStream); + } else if (typeStr == ASSET_COLLISION_MAP) { // col_map_mp + pParseAsset_ColMapMP(aZoneFileStream); + } else if (typeStr == ASSET_MP_MAP) { // game_map_sp + pParseAsset_GameMapSP(aZoneFileStream); + } else if (typeStr == ASSET_SP_MAP) { // game_map_mp + pParseAsset_GameMapMP(aZoneFileStream); + } else if (typeStr == ASSET_LIGHT_DEF) { // lightdef + pParseAsset_LightDef(aZoneFileStream); + } else if (typeStr == ASSET_UI_MAP) { // ui_map + pParseAsset_UIMap(aZoneFileStream); + } else if (typeStr == ASSET_SND_DRIVER_GLOBALS) { // snddriverglobals + pParseAsset_SNDDriverGlobals(aZoneFileStream); + } else if (typeStr == ASSET_AI_TYPE) { // aitype + pParseAsset_AIType(aZoneFileStream); + } else if (typeStr == ASSET_EFFECT) { // aitype + pParseAsset_FX(aZoneFileStream); + } else if (typeStr == ASSET_ANIMATION) { // aitype + result.animations << pParseAsset_Animation(aZoneFileStream); + } else if (typeStr == ASSET_STRING_TABLE) { // string_table + result.stringTables << pParseAsset_StringTable(aZoneFileStream); + } else if (typeStr == ASSET_MENU) { // string_table + result.menuFiles << pParseAsset_MenuFile(aZoneFileStream); + } else if (typeStr == ASSET_WEAPON) { // string_table + pParseAsset_Weapon(aZoneFileStream); + } else if (typeStr == ASSET_D3DBSP) { // string_table + pParseAsset_D3DBSP(aZoneFileStream); + } + } + return result; +} + +LocalString ZoneFile_COD9_WiiU::pParseAsset_LocalString(QDataStream *aZoneFileStream) { + LocalString result; + + quint32 stringPtr, aliasPtr; + *aZoneFileStream >> stringPtr >> aliasPtr; + if (stringPtr == 4294967295) { + // Parse local string asset contents + QString localStr; + char localStrChar; + *aZoneFileStream >> localStrChar; + while (localStrChar != 0) { + result.string += localStrChar; + *aZoneFileStream >> localStrChar; + } + } else { + result.string = "String Ptr: " + QString::number(stringPtr); + } + + if (aliasPtr == 4294967295) { + // Parse rawfile name + QString aliasName; + char aliasNameChar; + *aZoneFileStream >> aliasNameChar; + while (aliasNameChar != 0) { + result.alias += aliasNameChar; + *aZoneFileStream >> aliasNameChar; + } + } else { + result.string = "Alias Ptr: " + QString::number(aliasPtr); + } + + return result; +} + +RawFile ZoneFile_COD9_WiiU::pParseAsset_RawFile(QDataStream *aZoneFileStream) { + RawFile result; + + // Skip start separator FF FF FF FF (pointer?) + aZoneFileStream->skipRawData(4); + + *aZoneFileStream >> result.length; + + // Skip unknown 4 byte data + aZoneFileStream->skipRawData(4); + + // Parse rawfile path + char scriptPathChar; + *aZoneFileStream >> scriptPathChar; + while (scriptPathChar != 0) { + result.path += scriptPathChar; + *aZoneFileStream >> scriptPathChar; + } + 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; + *aZoneFileStream >> rawFileContentsChar; + } + return result; +} + +void ZoneFile_COD9_WiiU::pParseAsset_PhysPreset(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Model ZoneFile_COD9_WiiU::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; + + // 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]; + } + + *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]; + + 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; + + // Parse model name + char modelNameChar; + *aZoneFileStream >> modelNameChar; + while (modelNameChar == 0) { + *aZoneFileStream >> modelNameChar; + } + while (modelNameChar != 0) { + result.modelName += modelNameChar; + *aZoneFileStream >> modelNameChar; + } + return result; +} + +Material ZoneFile_COD9_WiiU::pParseAsset_Material(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); + + return Material(); +} + +Shader ZoneFile_COD9_WiiU::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; + if (rawShaderType == 65535) { // Pixel shader + type = SHADER_PIXEL; + } else if (rawShaderType == 65534) { // Vertex shader + 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; + } else if (opCode == OPCODE_Comment) { + size = (int)((instructionToken >> 16) & 0x7FFF); + } else { + size = (int)((instructionToken >> 24) & 0x0f); + } + Q_UNUSED(size); + } + + + return result; +} + +TechSet ZoneFile_COD9_WiiU::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; + while (techSetNameChar != 0) { + result.name += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + result.name.replace(",", ""); + + return result; +} + +Image ZoneFile_COD9_WiiU::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->skipRawData(15 * 4); + *aZoneFileStream >> result.unknownh >> result.unknowni; + + aZoneFileStream->skipRawData(4); + *aZoneFileStream >> result.unknownj; + + aZoneFileStream->skipRawData(4); + + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + result.materialName += materialNameChar; + *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; + + 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")) { + 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; + } + + return result; +} + +SoundAsset ZoneFile_COD9_WiiU::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; + *aZoneFileStream >> soundNameChar; + while (soundNameChar != 0) { + result.name += soundNameChar; + *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; + char tagChar; + *aZoneFileStream >> tagChar; + while (tagChar != 0) { + tag += tagChar; + *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); + + 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; + *aZoneFileStream >> soundAliasChar; + while (soundAliasChar != 0) { + sound.alias += soundAliasChar; + *aZoneFileStream >> soundAliasChar; + } + } + + if (aZoneFileStream->device()->peek(4) == "RIFF") { + sound.path = sound.alias; + sound.alias = ""; + } else if (namePtr.toHex() == "ffffffff") { + // Read in sound file path + char soundPathChar; + *aZoneFileStream >> soundPathChar; + while (soundPathChar != 0) { + sound.path += soundPathChar; + *aZoneFileStream >> soundPathChar; + } + sound.path.replace(",", ""); + } + + if (sound.dataLength) { + QByteArray data(sound.dataLength, Qt::Uninitialized); + aZoneFileStream->readRawData(data.data(), sound.dataLength); + sound.data = data; + } + result.sounds.append(sound); + } + + return result; +} + +void ZoneFile_COD9_WiiU::pParseAsset_ColMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_GameMapSP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_GameMapMP(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_LightDef(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_UIMap(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_AIType(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_FX(QDataStream *aZoneFileStream) { + Q_UNUSED(aZoneFileStream); +} + +Animation ZoneFile_COD9_WiiU::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; + + // Read in x_anim file name + QString xAnimName; + char xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + while (xAnimNameChar != 0) { + result.name += xAnimNameChar; + *aZoneFileStream >> xAnimNameChar; + } + + // Parse x_anim index header + QVector sectionLengths; + for (int i = 0; i < result.numframes; i++) { + quint8 sectionlength; + *aZoneFileStream >> sectionlength; + sectionLengths.push_back(sectionlength); + // Skip padding + aZoneFileStream->skipRawData(1); + } + // Skip unknown section + aZoneFileStream->skipRawData(2 * 8); + + return result; +} + +MenuFile ZoneFile_COD9_WiiU::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."; + return result; + } + for (uint i = 0; i < result.menuCount; i++) { + Menu menu; + + aZoneFileStream->skipRawData(4); // Separator + + // Read in x_anim file name + char menuFilepathChar; + *aZoneFileStream >> menuFilepathChar; + while (menuFilepathChar != 0) { + menu.filePath += menuFilepathChar; + *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; + 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; + *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA + >> 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; + + float focusColorR, focusColorG, focusColorB, focusColorA, + disabledColorR, disabledColorG, disabledColorB, disabledColorA; + *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA + >> 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; + while (menuDefNameChar != 0 && menuDefNameLen < 30) { + menuDefNameLen++; + menu.name += menuDefNameChar; + *aZoneFileStream >> menuDefNameChar; + } + + char defStringChar; + int defStringLen = 0; + *aZoneFileStream >> defStringChar; + while (defStringChar != 0 && defStringLen < 30) { + defStringLen++; + menu.definition += defStringChar; + *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; + + float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, + 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; + + 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.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; + + // 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; + *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA + >> 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; + + // 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; + //statement_s rectXExp; + //statement_s rectYExp; + //statement_s rectWExp; + //statement_s rectHExp; + //statement_s foreColorAExp; + result.menuDefs << menu; + } + return result; +} + +void ZoneFile_COD9_WiiU::pParseAsset_Weapon(QDataStream *aZoneFileStream) { + //WEAPON_FILE + Q_UNUSED(aZoneFileStream); +} + +void ZoneFile_COD9_WiiU::pParseAsset_D3DBSP(QDataStream *aZoneFileStream) { + //D3DBSP_DUMP + Q_UNUSED(aZoneFileStream); +} + +StringTable ZoneFile_COD9_WiiU::pParseAsset_StringTable(QDataStream *aZoneFileStream) { + StringTable result; + + aZoneFileStream->skipRawData(4); + + *aZoneFileStream + >> result.columnCount + >> result.rowCount; + + // Todo fix this + result.columnCount = 0; + result.rowCount = 0; + + aZoneFileStream->skipRawData(4); + + QString stringTableName; + char stringTableNameChar; + *aZoneFileStream >> stringTableNameChar; + while (stringTableNameChar != 0) { + 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") { + char leadingContentChar; + *aZoneFileStream >> leadingContentChar; + while (leadingContentChar != 0) { + leadingContent += leadingContentChar; + *aZoneFileStream >> leadingContentChar; + } + } else { + leadingContent = pointerAddr; + } + + QString content; + char contentChar; + *aZoneFileStream >> contentChar; + while (contentChar != 0) { + content += contentChar; + *aZoneFileStream >> contentChar; + } + result.content[leadingContent] = content; + } + return result; +} + +AssetType ZoneFile_COD9_WiiU::AssetStrToEnum(const QString aAssetType) { + const QString cleanedType = aAssetType.toUpper(); + if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED + return ASSET_LOCAL_STRING; + } else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED + return ASSET_RAW_FILE; + } 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 + 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 + return ASSET_COL_MAP_SP; + } + return ASSET_NONE; +} + +QByteArray ZoneFile_COD9_WiiU::GetBinaryData() { + QByteArray result; + + return result; +} diff --git a/libs/zonefile/WiiU/zonefile_cod9_wiiu.h b/libs/zonefile/WiiU/zonefile_cod9_wiiu.h new file mode 100644 index 0000000..a69625b --- /dev/null +++ b/libs/zonefile/WiiU/zonefile_cod9_wiiu.h @@ -0,0 +1,52 @@ +#ifndef ZONEFILE_COD9_H +#define ZONEFILE_COD9_H + +#include "zonefile.h" + +class ZoneFile_COD9_WiiU : public ZoneFile +{ +public: + ZoneFile_COD9_WiiU(); + ~ZoneFile_COD9_WiiU(); + + bool Load(const QByteArray aFileData) override; + AssetType AssetStrToEnum(const QString aAssetType) override; + + QByteArray GetBinaryData() override; + +protected: + void pParseZoneHeader(QDataStream *aZoneFileStream) override; + quint32 pParseZoneSize(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsA(QDataStream *aZoneFileStream) override; + quint32 pParseZoneTagCount(QDataStream *aZoneFileStream) override; + quint32 pParseZoneRecordCount(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsB(QDataStream *aZoneFileStream) override; + void pParseZoneUnknownsC(QDataStream *aZoneFileStream) override; + QStringList pParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) override; + QStringList pParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) override; + AssetMap pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) override; + LocalString pParseAsset_LocalString(QDataStream *aZoneFileStream) override; + RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; + void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; + Model pParseAsset_Model(QDataStream *aZoneFileStream) override; + Material pParseAsset_Material(QDataStream *aZoneFileStream) override; + Shader pParseAsset_Shader(QDataStream *aZoneFileStream) override; + TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) override; + Image pParseAsset_Image(QDataStream *aZoneFileStream) override; + SoundAsset pParseAsset_Sound(QDataStream *aZoneFileStream) override; + void pParseAsset_ColMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapSP(QDataStream *aZoneFileStream) override; + void pParseAsset_GameMapMP(QDataStream *aZoneFileStream) override; + void pParseAsset_LightDef(QDataStream *aZoneFileStream) override; + void pParseAsset_UIMap(QDataStream *aZoneFileStream) override; + void pParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) override; + void pParseAsset_AIType(QDataStream *aZoneFileStream) override; + void pParseAsset_FX(QDataStream *aZoneFileStream) override; + Animation pParseAsset_Animation(QDataStream *aZoneFileStream) override; + MenuFile pParseAsset_MenuFile(QDataStream *aZoneFileStream) override; + void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; + void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; + StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; +}; + +#endif // ZONEFILE_COD9_H diff --git a/libs/zonefile/zonefile.pro b/libs/zonefile/zonefile.pro index 7cc7681..b296b04 100644 --- a/libs/zonefile/zonefile.pro +++ b/libs/zonefile/zonefile.pro @@ -3,37 +3,88 @@ TEMPLATE = lib CONFIG += staticlib c++17 SOURCES += \ + # Base class zonefile.cpp \ + # 360 classes 360/zonefile_cod2_360.cpp \ + 360/zonefile_cod4_360.cpp \ 360/zonefile_cod5_360.cpp \ + 360/zonefile_cod6_360.cpp \ 360/zonefile_cod7_360.cpp \ + 360/zonefile_cod8_360.cpp \ 360/zonefile_cod9_360.cpp \ + 360/zonefile_cod10_360.cpp \ + 360/zonefile_cod11_360.cpp \ + 360/zonefile_cod12_360.cpp \ + # PS3 classes + PS3/zonefile_cod4_ps3.cpp \ PS3/zonefile_cod5_ps3.cpp \ + PS3/zonefile_cod6_ps3.cpp \ PS3/zonefile_cod7_ps3.cpp \ + PS3/zonefile_cod8_ps3.cpp \ PS3/zonefile_cod9_ps3.cpp \ + PS3/zonefile_cod10_ps3.cpp \ + PS3/zonefile_cod11_ps3.cpp \ + PS3/zonefile_cod12_ps3.cpp \ + # PC classes + PC/zonefile_cod4_pc.cpp \ PC/zonefile_cod5_pc.cpp \ + PC/zonefile_cod6_pc.cpp \ PC/zonefile_cod7_pc.cpp \ + PC/zonefile_cod8_pc.cpp \ PC/zonefile_cod9_pc.cpp \ + PC/zonefile_cod10_pc.cpp \ + PC/zonefile_cod11_pc.cpp \ PC/zonefile_cod12_pc.cpp \ + # Wii classes + Wii/zonefile_cod4_wii.cpp \ Wii/zonefile_cod7_wii.cpp \ - WiiU/zonefile_cod9_wiiu.cpp + Wii/zonefile_cod8_wii.cpp \ + # WiiU classes + WiiU/zonefile_cod9_wiiu.cpp \ + WiiU/zonefile_cod10_wiiu.cpp HEADERS += \ + # Base class zonefile.h \ + # 360 classes 360/zonefile_cod2_360.h \ + 360/zonefile_cod4_360.h \ 360/zonefile_cod5_360.h \ + 360/zonefile_cod6_360.h \ 360/zonefile_cod7_360.h \ + 360/zonefile_cod8_360.h \ 360/zonefile_cod9_360.h \ + 360/zonefile_cod10_360.h \ + 360/zonefile_cod11_360.h \ + 360/zonefile_cod12_360.h \ + # PS3 classes + PS3/zonefile_cod4_ps3.h \ PS3/zonefile_cod5_ps3.h \ + PS3/zonefile_cod6_ps3.h \ PS3/zonefile_cod7_ps3.h \ + PS3/zonefile_cod8_ps3.h \ PS3/zonefile_cod9_ps3.h \ + PS3/zonefile_cod10_ps3.h \ + PS3/zonefile_cod11_ps3.h \ + PS3/zonefile_cod12_ps3.h \ + # PC classes + PC/zonefile_cod4_pc.h \ PC/zonefile_cod5_pc.h \ + PC/zonefile_cod6_pc.h \ PC/zonefile_cod7_pc.h \ + PC/zonefile_cod8_pc.h \ PC/zonefile_cod9_pc.h \ + PC/zonefile_cod10_pc.h \ + PC/zonefile_cod11_pc.h \ PC/zonefile_cod12_pc.h \ + # Wii classes + Wii/zonefile_cod4_wii.h \ Wii/zonefile_cod7_wii.h \ + Wii/zonefile_cod8_wii.h \ + # WiiU classes WiiU/zonefile_cod9_wiiu.h \ - zonefile_factory.h + WiiU/zonefile_cod10_wiiu.h LIBS += \ -L$$OUT_PWD/../libs/core -lcore From 87cbdeeefc5b720ab73502fae221d8ce42524e1e Mon Sep 17 00:00:00 2001 From: = Date: Sat, 17 May 2025 23:42:30 -0400 Subject: [PATCH 04/32] feat(XPlor): Add dependencies for libs in app, tests and tools projects Added dependencies for the libs in the app, tests and tools projects. This change ensures that these components depend on the correct libraries. --- XPlor.pro | 4 +++- app/app.pro | 12 ------------ data/icons/Icon_COD10.png | Bin 0 -> 2945 bytes data/icons/Icon_COD11.png | Bin 0 -> 2080 bytes data/icons/Icon_COD12.png | Bin 0 -> 2483 bytes tools/zentry/zentry.pro | 5 ----- 6 files changed, 3 insertions(+), 18 deletions(-) create mode 100644 data/icons/Icon_COD10.png create mode 100644 data/icons/Icon_COD11.png create mode 100644 data/icons/Icon_COD12.png diff --git a/XPlor.pro b/XPlor.pro index 6ab867d..4cf1c89 100644 --- a/XPlor.pro +++ b/XPlor.pro @@ -5,4 +5,6 @@ SUBDIRS += libs \ tools \ tests -QMAKE_PRE_BUILD += make clean +tests.depends = libs +app.depends = libs +tools.depends = libs diff --git a/app/app.pro b/app/app.pro index 362fc8c..f10aa63 100644 --- a/app/app.pro +++ b/app/app.pro @@ -60,18 +60,6 @@ FORMS += \ RESOURCES += ../data/data.qrc -app.depends += \ - libs/core \ - libs/compression \ - libs/encryption \ - libs/fastfile \ - libs/ddsfile \ - libs/ipakfile \ - libs/iwifile \ - libs/zonefile - -QMAKE_PRE_BUILD += make clean - LIBS += \ -L$$PWD/../third_party/devil_sdk/lib/ -lDevIL -lILU -lILUT \ -L$$PWD/../third_party/zlib/lib/ -lzlib \ diff --git a/data/icons/Icon_COD10.png b/data/icons/Icon_COD10.png new file mode 100644 index 0000000000000000000000000000000000000000..3f1cd3d18b3736d65e5ace235b0af8c0f98ef8b9 GIT binary patch literal 2945 zcmV-{3x4#8P)L9zP!SgqB@2k)6_opsOF$45K~Y3e2!cvHP$LE+ifFQGB;vgbYOGxjK~z8y z5AH+!?)$!Rdft28^XAPABdOi}R&`C)^mqF8_w&Bp{q1k}eDHxpK8Y)X|K=jKmy*8j zV4nf#>yGs~h`#Pnp8@FWj`Ver1u!nY9F`q^1d*rfA?ZQ`1b$x&_L&c1d_sAjcif}^ z(D2lv=kTJn8(7lT(FsY13Sg9NFbr9?55}y&-RFk%8h|f$RKndS?M%a^($vxpb377w z2v`j5#N_Q2V3{cIRTC2{VE@%dD64OUmiA6)eBA=K?^nUP-6vttf*2U#mD@W2PThH} z$au9pdG-QE%?|{#nLaRd>{x;z-e9d=;18_W0Lp6TmUL{Ohxd{eYdBfBd8)4^>Lg?y#BhpDaSO6b>xf=S- zUJGNQ{-Nl>e@(B3Qh}#gt=`PF;m$)4>MiArZ|!^|?G`09b z>%;tVYN7TO+aMNz+*199BTC4QY`%>F3u5&HVDn8i)mUKSAp&5qOPc7177;gKi0fWb zFD%lB%-a0`u2!|mc3cWzYH}s?ynU-TfLd-&Qn#aIP9gwY4?Ut9Te5BsF=}-9RqDrs zT~aCI@jG?>`1mr|b?G^@cj+F(QUJ*p8}v3_EsFwosD{GqK;;0uPduR-vhz>U`c`$7 zC8rOW5;Bsef&bb|l{ za3Qn4BJ=>S?`UsCu@6ilI=I}KJEuVW;Y&>2PZkF8dUBI8wF>k|=A3}U!%P5{+#7P^ zTwGXi$?7ctS=U}r^>qy|Nj(;Iz=M+|OIB^zORXxh0I)oIDIT*&&Rih?J`TA|^n6ax z22NQPLnc9E0bH(Vrs|IuUM2PYti+QWYiZq@l~44?M3*Q7kXhU)Y6JtJ362rGVdhS| zh~72HlGeoO^_%WNU}*zz{cZ*LCS)<|gmXY;13j*z_M9N~=8ii>MqDbB2gVAonE=p@ zo7==RYdO~o-*p@u!%`vU*e$qMM|Ung=kJ1m$%g`f?z?(pCf}L4+~$cTLJ#PE(?iv- zh)yTh9*l=AmE);^e7Z|j?=bxiMI#0qQe6Mve>P3S>L`8mKDEBt3@`lwcyeoTWi36nP%dA+1rx0t;CG{^!iUp5c;kn;AEnwD;gioB zkDu!AoU+&e)E+R;YYVe}l5->zz*w#nKWJh8#%$VZ)o-S)(GNhvkI$G53Z=QF6|7yj zu|3@rhPY+QuC>CV3&6sFBxe2ROV|LUE0<7&QKMo2m;hBOm>b0PAGgXwTr+wF07iQ( zVR?WrWB($Q5jKAM0hpQcfXco+c>D~4ld{1vbT>q&=0JOgI9MtzdkFn!c!JqBN@u1>ZvawvYJAnq#ni!qi7o`3!}d@Qa*a&m>-*1-d@lejx0Wl~Y3dC? z8VZX7oLPQkqARI6>-wD(hq{<0Hsh8W^)N9NfW>Q*sqb?y+ywX7 z4C4WK9H(bgoZML3VdrmYBgWVTsdQ!5Tw?%Wnyaa$P4pcmNCwaL?i~Puj2)b|M5i6Y zTPC|iF?D+j046(yf}yUZQw0ATlX<{!Yd@w@cwj0O3){6O1t653o*r-tO(Dju-gLlt z0E;r|w`%DW$uue`PaJ#W{y;qkybl1vWCuRaC+&jq0KQ0~XHsoBK|I+J3I;=R=K{S6 z;L^?eq8%nCJA(7*&5+&zut$@NcA&nPOj-DfWx`H8H0POs?Yc(FX-^1r= zj2gHwj!$<5<+3wS!>oPv1CUlEezTbBn&`YpnAXID3Txnd(R z9{2uo#w!7UZZXiK75wcTS#uDU8$sVf*B_-5dA@mw;B$>J3dP^%VRly?i!_c z`~Cw`FLz^034k;Any7kV03^MU_Ke{%5h=%szT8XE3BV`eTPnhv6kWux08*Lxb)0H7 zu#Gkf04phrbJ0i}e-Z$x+q27{Z?>S!_ufj{V_ohr$ODAB1*LQ+H>91^84fD};INP0 zm!L$as?P^C?X$)|<|hVOdFqS-4E6vl`xxnH)y<4|S8CQ38w>z*{Vg4I!n32Z3)~`8 zRl{IuI;=VNn7LeEyHl=-0l4MaC;-|#AnqLP0fkpeiSFPf>=i)?0Mt7zGa*;h)Nw|# z(_knXPr-A+7}EfVK0^l|KV82^bO$clVibTCN9de`5z8{D#-rq46fVR6r+5|U1QmqA-!&9-=SXpzwXuw1;O9Kx>bLeU0jR6wC=0I(9Mc#}j)T1;O6 zcwX^q)l=qggo5`5h5LV{2ex`og8nCKp{avjdScUai5}h>?=1jWCWQY4=Wmv2HU41! zWs&g%?c>2BQa&%C7(m&>IzH)9@~>)m)y%%Vi6=9{GXy1fbcM+ZX<_LPUvmP!irCM` z_=Q(WAphsvyvqy6JQj23-7wPstRmwT0njCwryK7OMvTWR^-3PBx@SxqFSnx{6>ts) zF5bfY9lAUkKRWam#l{;2ptZdNwjRjmTu*#WMt!B;lm%mZ+~6RLK@N$$@k(9ZU;w!J zsi|+|-92pQG0~w3=IFFtlliR|>i>gyx+~rOYAfjOXuQ(fA-|=f^`E17zAp=b+g#wa rGc^8vxchqp@W1j;(*OT^Tq6Ggx60h-v@5WX00000NkvXXu0mjf3*>l2 literal 0 HcmV?d00001 diff --git a/data/icons/Icon_COD11.png b/data/icons/Icon_COD11.png new file mode 100644 index 0000000000000000000000000000000000000000..b160db3338a46163716ec238374e6342f191d560 GIT binary patch literal 2080 zcmV+*2;cXKP)S&82Wx86D1k=h zsvIqHict8=|JL1i%-h|!yXfxHPV#4yeKY^e|Gjzt{PVwgLxyn5(9eg$U>2^uL^1RL z4FF-U1%$Jtzn$ z12G`mJ+?3=WsJ`4?GM=N2cSq+B*=J0sjjbvv3_GgG*1K;t1a|0enZIyXlQEyk7N%J zdG+fH6RyuX#Tt&>J_1#LSAjTK45In{?bm2-&jR3;=S3KJ_wikr9Wfg$=UakvxHF`m zNr ZdRSNQ)yuCW=?fFG+ukdopYSwe${=YKDQ`0xxRh~LfWr8w+`xB>ZrE0jkQ!; z<#@CKkpCc`Wms!RD~y(orWN{$sNd|OY*xLe&z~ymSbQk_u37D}f}EQ<1W*M46m{*V zXH18if81oXt!-cc@YVtVI=<%4W|p$Nl02m{bI*R`qU6T;9P%M%iqje=d8blgcP;E} z7*sb`^FCIZ0N^TwPP(hRi)gDe0H-V`LRrlI7^O0Nu9yuapGiO*BBlW`L|umt2OQvf z<#k@eg#ZXR8351zdZx0i&H#Lm`4Y+k69SdWB%8>k4xw<3=Ymqm$mEfb`co=&zUfqJ zyea^b(k8*h-!5uwt22O*f)GNPZ=A27yQ)brn5t~7)HrxP0K=1p!}hD&p{=V;P+Oe= z;MC%lg`X_c8^E%Y%LE&)D6Ubi%6^aka$KvnHT5;R0dUN8B$S0Fh3XApP0<>y0WfDk z@uOm`+Um6m^!D|#lrfzkvk^vWe#iY-Vv}lP+5k|v-ZlSnKJ5hKXeYR;U=`7^Vj1K* zL6ZWIbt8+V3FI&P z-yVjeB}a*CI{N?=oW`x4t!#x2HLy8nGx%@yhb;wLKvp9oI?X+w%Ll#(s4it|0B@d-3{4=*)U2v zN?F(QW8nbm8tWh;HG&m$WSq|!cmS3=EMfOIyP@Zw9*xFVR8@dum?Nu0j1aj1FkYV? zI-MObtrCORE^_n51yCp}goEE7WP!tea9@)7L*~E(P>5Ti8D%>X_yquJ>=6_Q%8Iv6o4vuCjc-3Dzsp3kXrveb%S7Z z0POeM6Pu38>Pm>qh=YJF0g!ko5jwlryE$383?%a;)J(95&@LrrbO5*tn_e}6oxdHe zaDfPxZ(UAw8oWJNe%)7CGQ?;Ba6@5cfI}rI-#WSn6%SbT3a=H?A#<$o6uD6Wz$lPg znE3!^fV1t&HdZ}+OqBHkh5G`d0x&msE}?A7$|>}nWh_5og<-6EnA8-xi0l@cu+`#b&XMX#;RQWhD zkgCVUWB{O4G*+;boxXaSUIjMNs{l7%$T*upcdA7&WOM-VbrZ8-s%u)vH2M1eHYFBW z97%NQv(bmO&o@~B_-?-bRXs~#`HOOhO^=13q#!tR>kQE$<_wtAU$WUmBS92=byfDf zjCW9crRz->%nF}HcevQZ_X5lWBzksDMY>iBW>d_-+({k)F_Rr84}cE@CN{ZcrsqsB zb1);a!Gi{Xkg_y-sXQ~J;?1zh05~T*rxO62C5oM+HV}*s0N)IV-W$#G@+bvA77+FB z{eDk*-6B$$FEBX(ihAP{#`7Leafx)1ckCx@H845=e2)Mh0F(=|3q;+-!--mj!$t={ z=nO!~F3l$DG7nWrKGhr$865y^W;)uG}?p~t- z_z!Xb+>H~K6PHfV0G14L00m{_QkZfqg$A&45Cg#TL@!%k5_P4qQrZc|nV=IC3V<(x ziYH05O^cZ%fYpVoq2+Z8Q7zfz>8=*Qf8|Tk|GysRlz#yt&XzSugAH#00000< KMNUMnLSTa6U9|rI literal 0 HcmV?d00001 diff --git a/data/icons/Icon_COD12.png b/data/icons/Icon_COD12.png new file mode 100644 index 0000000000000000000000000000000000000000..119fb0693b035139667b34701f1e9c9c04c275d9 GIT binary patch literal 2483 zcmV;k2~75hP)@l~ojexFpj!Rtz>e%{V$` zj#(~a<}!|Hj*gm+C|gRFxICg1F(FC8)Fc%gr@*BY3R9=V5;F%1HE?54Nyimba={Hj z9Z>{?^mfkk{lE9W|M|Dai>KB%bLP#wcka3OeE(g}Isbh&n}BqijXlXC`m2Jc2k0>Z zJUuXv6XEFrd5i#055&`=OTfk^O<3-L0qnqp3G7Hr49g1+X4zf4vY(!M%Hsq7R|!DJ zkI$daYRbzQg_=8e*v9yH_WrZave}@Y_6RuQHUfU}^<~%h?QFZeso7uCcgM`^` z8c@b_&#_I-o9pTvu-jSr-o5Phl`D>MTseK3?MY8(Ukn_`BH;Jr`Veq-?OIdLODMl^ zfsOO=VS&*0v-&vi<;C{HQmZa2V=Lcyg9XEPv4YNTue`!;fwOwZ&&Xgio_?B50sXJ6 z60jYfrih}vJT@KHeUP^|i|pK){k&)qtE;V5=xkiDfcZiDF(7MPa2_4IzHgswFB%9y zd%^tJdi7$pFyqYN6wF|3k0dOzLcp1n6osLxTesLdFdfkt$|UFK<|RuMdKZg|WF0F@ z;b(YKMTv>*Z-G#W06(YRW|(0(Gpt}!LV~0H1dwmd5P%!s-5WO)MlzQzlLrz2ve>Dc z*|)E%!-!6u9D3tSI=|Q7pH-HWkb@TqxSW}3$$1GMzWlPo#;0Zo$m-BRWncwtHqt;o z5gMj~#5jKwMbGiAZQHV|J9g*}oF`!Cpg}GcD73Y+NDdfewZEsD7Vj?Q8eDp?V>9=y}f>Zs*WOFeU;ndqT(@DRZ+o4H)=%A7A*pB9VbKRO9A(Q z)e#Z8&Y-Lk`ohhY!q{h?(Ok+30&p7FfHORS1=b_iJhuB$V2{_?3)YznZ> zuQBncK?1Jk=CThV(&V2W?#Qcj2>2cz#GlaaC?{K!lH~Ri2xoqSaGXMD>(=H8kR<8# z*V!@XwEFgKhmrgD??3p2lL9lub+cx%z-G;4!n9upMI@F+-e zz)%|my^SW!@1kl_8`JS=jUtKktEUSd?NSV z4xJew4S0#O9WUs73em?Acqk$;ZqVB|NCLEu6CRatLQI77AJ1aFY)enf5Mae#>9%bu zTex)ixWSNs0~$vY1*{F?`5)jS3GO5SPcRCb;Aod@*^LPJ6?V~D=bD#*^|o)q!`T8@ zUujWM?5>c_{dMpl3xFsR+5N(U1QdjYk+$Z;@h#b!Wki4&2vwAqE8^~VLE?uGS9P** z)F{XAp&lgQ=JDeyJJm2l1HHXvTi+QGAcn$xfP?ipX`?FZqN*2#LyJwSj~(Pa0A z4Z7=JK>)Re_<8^z;2fGhU7?4|MAD1&00CFwRHCo|W~*c;!ia$EE?rax>}}hUxpbbt zzd{eAyis0W@-k^i0<>(Doj0+|RYq`gqXx30Pal=;_~)N@=#6S%0<;RI ztENuX4VzU2;Cnw2S^>oGoja>^KjK2&h9V%lTQ{=(&9XA)-?XW0W3Cwjs2MP}MGJBu z_`+1gdo5cwI05*2j6w=zt^DS#XXD`>K(P72i!YJ`$saRDp@;c_v$Z+ZNYmL?nH zOJZWYkimtUR)Qf{2`I4J$#$hMEg84ZBBF5B9wWq5P-%@iJG4lYHMm(Bm_`;*_JyAz-U!W)+Bt=tC!q{sur0d z;N1H4vcY@8I|2$}F!j4ZyMeX`g^@%H9lJun>EvWmA1_7lPk*612%w0l72e|`26pPi zdfL?0V0ROM15G1b?X)xilMLV9IA(TxO9ISK-U9zNuy%3W?* z0{jf%b&J!}Rk~@>(U!ttLjoYG(+YX{peMvd=UtuwD1`|LD&5TG%Vk~aN{v+llAv!b z{4jT}EV&@Z3`Fboy~{J;;MA!q-Thm($hu}u1S10QMXI}CcfREo$7N{~pMQEsH%C1c;kpUO)hOYkO@>jI2jpMtVF5AdbNcg@uly2VPIPBV4AI zfES+lcL-MhHz0=E|F&3~0Y<=UGLyJVNRuo&kD_%8BwFV;S4BS#u#gSn&5Iu)!U}X= zMn=J#B4!hzM@38%faR~UbLSk>eKkaZ{7Vymo4IQ;kD{plKNx9YI!$sq@9GtqN5XND xfaL}xVC^r&>HOn1-E|50ul$qr|9_7Q_y@lqQ!Rv&paK8@002ovPDHLkV1mnIsw)5h literal 0 HcmV?d00001 diff --git a/tools/zentry/zentry.pro b/tools/zentry/zentry.pro index 06c4b31..68b8e1e 100644 --- a/tools/zentry/zentry.pro +++ b/tools/zentry/zentry.pro @@ -13,11 +13,6 @@ SOURCES += \ HEADERS += \ zentrywindow.h -FORMS += - -app.depends += \ - libs/compression - LIBS += \ -L$$OUT_PWD/../../libs/ -lcompression \ -L$$PWD/../../third_party/xbox_sdk/lib -lxcompress64 From 6e7a83d4739759ce67069506fcb301a7179dcccc Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:08:44 -0400 Subject: [PATCH 05/32] Remove png files. --- data/icons/Icon_COD10.png | Bin 2945 -> 0 bytes data/icons/Icon_COD11.png | Bin 2080 -> 0 bytes data/icons/Icon_COD12.png | Bin 2483 -> 0 bytes data/icons/Icon_COD2.png | Bin 2771 -> 0 bytes data/icons/Icon_COD4.png | Bin 1888 -> 0 bytes data/icons/Icon_COD5.png | Bin 2239 -> 0 bytes data/icons/Icon_COD6.png | Bin 2270 -> 0 bytes data/icons/Icon_COD7.png | Bin 1981 -> 0 bytes data/icons/Icon_COD8.png | Bin 2396 -> 0 bytes data/icons/Icon_COD9.png | Bin 2196 -> 0 bytes data/icons/Icon_Copy.png | Bin 316 -> 0 bytes data/icons/Icon_Cut.png | Bin 1100 -> 0 bytes data/icons/Icon_DDSFile.png | Bin 2217 -> 0 bytes data/icons/Icon_Editor.png | Bin 210 -> 0 bytes data/icons/Icon_FastFile.png | Bin 855 -> 0 bytes data/icons/Icon_Find.png | Bin 1337 -> 0 bytes data/icons/Icon_GSCFile.png | Bin 2558 -> 0 bytes data/icons/Icon_IWIFile.png | Bin 2041 -> 0 bytes data/icons/Icon_MenuFile.png | Bin 1444 -> 0 bytes data/icons/Icon_NewFile.png | Bin 1087 -> 0 bytes data/icons/Icon_OpenFile.png | Bin 317 -> 0 bytes data/icons/Icon_Paste.png | Bin 537 -> 0 bytes data/icons/Icon_Pause.png | Bin 213 -> 0 bytes data/icons/Icon_Play.png | Bin 318 -> 0 bytes data/icons/Icon_RawFile.png | Bin 2484 -> 0 bytes data/icons/Icon_Save.png | Bin 371 -> 0 bytes data/icons/Icon_SkipBack.png | Bin 488 -> 0 bytes data/icons/Icon_SkipForward.png | Bin 532 -> 0 bytes data/icons/Icon_Stop.png | Bin 195 -> 0 bytes data/icons/Icon_StringFile.png | Bin 1956 -> 0 bytes data/icons/Icon_TechSetFile.png | Bin 1762 -> 0 bytes data/icons/Icon_Tree.png | Bin 321 -> 0 bytes data/icons/Icon_Views.png | Bin 1650 -> 0 bytes data/icons/Icon_WAVFile.png | Bin 2550 -> 0 bytes data/icons/Icon_ZoneFile.png | Bin 1283 -> 0 bytes 35 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/icons/Icon_COD10.png delete mode 100644 data/icons/Icon_COD11.png delete mode 100644 data/icons/Icon_COD12.png delete mode 100644 data/icons/Icon_COD2.png delete mode 100644 data/icons/Icon_COD4.png delete mode 100644 data/icons/Icon_COD5.png delete mode 100644 data/icons/Icon_COD6.png delete mode 100644 data/icons/Icon_COD7.png delete mode 100644 data/icons/Icon_COD8.png delete mode 100644 data/icons/Icon_COD9.png delete mode 100644 data/icons/Icon_Copy.png delete mode 100644 data/icons/Icon_Cut.png delete mode 100644 data/icons/Icon_DDSFile.png delete mode 100644 data/icons/Icon_Editor.png delete mode 100644 data/icons/Icon_FastFile.png delete mode 100644 data/icons/Icon_Find.png delete mode 100644 data/icons/Icon_GSCFile.png delete mode 100644 data/icons/Icon_IWIFile.png delete mode 100644 data/icons/Icon_MenuFile.png delete mode 100644 data/icons/Icon_NewFile.png delete mode 100644 data/icons/Icon_OpenFile.png delete mode 100644 data/icons/Icon_Paste.png delete mode 100644 data/icons/Icon_Pause.png delete mode 100644 data/icons/Icon_Play.png delete mode 100644 data/icons/Icon_RawFile.png delete mode 100644 data/icons/Icon_Save.png delete mode 100644 data/icons/Icon_SkipBack.png delete mode 100644 data/icons/Icon_SkipForward.png delete mode 100644 data/icons/Icon_Stop.png delete mode 100644 data/icons/Icon_StringFile.png delete mode 100644 data/icons/Icon_TechSetFile.png delete mode 100644 data/icons/Icon_Tree.png delete mode 100644 data/icons/Icon_Views.png delete mode 100644 data/icons/Icon_WAVFile.png delete mode 100644 data/icons/Icon_ZoneFile.png diff --git a/data/icons/Icon_COD10.png b/data/icons/Icon_COD10.png deleted file mode 100644 index 3f1cd3d18b3736d65e5ace235b0af8c0f98ef8b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2945 zcmV-{3x4#8P)L9zP!SgqB@2k)6_opsOF$45K~Y3e2!cvHP$LE+ifFQGB;vgbYOGxjK~z8y z5AH+!?)$!Rdft28^XAPABdOi}R&`C)^mqF8_w&Bp{q1k}eDHxpK8Y)X|K=jKmy*8j zV4nf#>yGs~h`#Pnp8@FWj`Ver1u!nY9F`q^1d*rfA?ZQ`1b$x&_L&c1d_sAjcif}^ z(D2lv=kTJn8(7lT(FsY13Sg9NFbr9?55}y&-RFk%8h|f$RKndS?M%a^($vxpb377w z2v`j5#N_Q2V3{cIRTC2{VE@%dD64OUmiA6)eBA=K?^nUP-6vttf*2U#mD@W2PThH} z$au9pdG-QE%?|{#nLaRd>{x;z-e9d=;18_W0Lp6TmUL{Ohxd{eYdBfBd8)4^>Lg?y#BhpDaSO6b>xf=S- zUJGNQ{-Nl>e@(B3Qh}#gt=`PF;m$)4>MiArZ|!^|?G`09b z>%;tVYN7TO+aMNz+*199BTC4QY`%>F3u5&HVDn8i)mUKSAp&5qOPc7177;gKi0fWb zFD%lB%-a0`u2!|mc3cWzYH}s?ynU-TfLd-&Qn#aIP9gwY4?Ut9Te5BsF=}-9RqDrs zT~aCI@jG?>`1mr|b?G^@cj+F(QUJ*p8}v3_EsFwosD{GqK;;0uPduR-vhz>U`c`$7 zC8rOW5;Bsef&bb|l{ za3Qn4BJ=>S?`UsCu@6ilI=I}KJEuVW;Y&>2PZkF8dUBI8wF>k|=A3}U!%P5{+#7P^ zTwGXi$?7ctS=U}r^>qy|Nj(;Iz=M+|OIB^zORXxh0I)oIDIT*&&Rih?J`TA|^n6ax z22NQPLnc9E0bH(Vrs|IuUM2PYti+QWYiZq@l~44?M3*Q7kXhU)Y6JtJ362rGVdhS| zh~72HlGeoO^_%WNU}*zz{cZ*LCS)<|gmXY;13j*z_M9N~=8ii>MqDbB2gVAonE=p@ zo7==RYdO~o-*p@u!%`vU*e$qMM|Ung=kJ1m$%g`f?z?(pCf}L4+~$cTLJ#PE(?iv- zh)yTh9*l=AmE);^e7Z|j?=bxiMI#0qQe6Mve>P3S>L`8mKDEBt3@`lwcyeoTWi36nP%dA+1rx0t;CG{^!iUp5c;kn;AEnwD;gioB zkDu!AoU+&e)E+R;YYVe}l5->zz*w#nKWJh8#%$VZ)o-S)(GNhvkI$G53Z=QF6|7yj zu|3@rhPY+QuC>CV3&6sFBxe2ROV|LUE0<7&QKMo2m;hBOm>b0PAGgXwTr+wF07iQ( zVR?WrWB($Q5jKAM0hpQcfXco+c>D~4ld{1vbT>q&=0JOgI9MtzdkFn!c!JqBN@u1>ZvawvYJAnq#ni!qi7o`3!}d@Qa*a&m>-*1-d@lejx0Wl~Y3dC? z8VZX7oLPQkqARI6>-wD(hq{<0Hsh8W^)N9NfW>Q*sqb?y+ywX7 z4C4WK9H(bgoZML3VdrmYBgWVTsdQ!5Tw?%Wnyaa$P4pcmNCwaL?i~Puj2)b|M5i6Y zTPC|iF?D+j046(yf}yUZQw0ATlX<{!Yd@w@cwj0O3){6O1t653o*r-tO(Dju-gLlt z0E;r|w`%DW$uue`PaJ#W{y;qkybl1vWCuRaC+&jq0KQ0~XHsoBK|I+J3I;=R=K{S6 z;L^?eq8%nCJA(7*&5+&zut$@NcA&nPOj-DfWx`H8H0POs?Yc(FX-^1r= zj2gHwj!$<5<+3wS!>oPv1CUlEezTbBn&`YpnAXID3Txnd(R z9{2uo#w!7UZZXiK75wcTS#uDU8$sVf*B_-5dA@mw;B$>J3dP^%VRly?i!_c z`~Cw`FLz^034k;Any7kV03^MU_Ke{%5h=%szT8XE3BV`eTPnhv6kWux08*Lxb)0H7 zu#Gkf04phrbJ0i}e-Z$x+q27{Z?>S!_ufj{V_ohr$ODAB1*LQ+H>91^84fD};INP0 zm!L$as?P^C?X$)|<|hVOdFqS-4E6vl`xxnH)y<4|S8CQ38w>z*{Vg4I!n32Z3)~`8 zRl{IuI;=VNn7LeEyHl=-0l4MaC;-|#AnqLP0fkpeiSFPf>=i)?0Mt7zGa*;h)Nw|# z(_knXPr-A+7}EfVK0^l|KV82^bO$clVibTCN9de`5z8{D#-rq46fVR6r+5|U1QmqA-!&9-=SXpzwXuw1;O9Kx>bLeU0jR6wC=0I(9Mc#}j)T1;O6 zcwX^q)l=qggo5`5h5LV{2ex`og8nCKp{avjdScUai5}h>?=1jWCWQY4=Wmv2HU41! zWs&g%?c>2BQa&%C7(m&>IzH)9@~>)m)y%%Vi6=9{GXy1fbcM+ZX<_LPUvmP!irCM` z_=Q(WAphsvyvqy6JQj23-7wPstRmwT0njCwryK7OMvTWR^-3PBx@SxqFSnx{6>ts) zF5bfY9lAUkKRWam#l{;2ptZdNwjRjmTu*#WMt!B;lm%mZ+~6RLK@N$$@k(9ZU;w!J zsi|+|-92pQG0~w3=IFFtlliR|>i>gyx+~rOYAfjOXuQ(fA-|=f^`E17zAp=b+g#wa rGc^8vxchqp@W1j;(*OT^Tq6Ggx60h-v@5WX00000NkvXXu0mjf3*>l2 diff --git a/data/icons/Icon_COD11.png b/data/icons/Icon_COD11.png deleted file mode 100644 index b160db3338a46163716ec238374e6342f191d560..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2080 zcmV+*2;cXKP)S&82Wx86D1k=h zsvIqHict8=|JL1i%-h|!yXfxHPV#4yeKY^e|Gjzt{PVwgLxyn5(9eg$U>2^uL^1RL z4FF-U1%$Jtzn$ z12G`mJ+?3=WsJ`4?GM=N2cSq+B*=J0sjjbvv3_GgG*1K;t1a|0enZIyXlQEyk7N%J zdG+fH6RyuX#Tt&>J_1#LSAjTK45In{?bm2-&jR3;=S3KJ_wikr9Wfg$=UakvxHF`m zNr ZdRSNQ)yuCW=?fFG+ukdopYSwe${=YKDQ`0xxRh~LfWr8w+`xB>ZrE0jkQ!; z<#@CKkpCc`Wms!RD~y(orWN{$sNd|OY*xLe&z~ymSbQk_u37D}f}EQ<1W*M46m{*V zXH18if81oXt!-cc@YVtVI=<%4W|p$Nl02m{bI*R`qU6T;9P%M%iqje=d8blgcP;E} z7*sb`^FCIZ0N^TwPP(hRi)gDe0H-V`LRrlI7^O0Nu9yuapGiO*BBlW`L|umt2OQvf z<#k@eg#ZXR8351zdZx0i&H#Lm`4Y+k69SdWB%8>k4xw<3=Ymqm$mEfb`co=&zUfqJ zyea^b(k8*h-!5uwt22O*f)GNPZ=A27yQ)brn5t~7)HrxP0K=1p!}hD&p{=V;P+Oe= z;MC%lg`X_c8^E%Y%LE&)D6Ubi%6^aka$KvnHT5;R0dUN8B$S0Fh3XApP0<>y0WfDk z@uOm`+Um6m^!D|#lrfzkvk^vWe#iY-Vv}lP+5k|v-ZlSnKJ5hKXeYR;U=`7^Vj1K* zL6ZWIbt8+V3FI&P z-yVjeB}a*CI{N?=oW`x4t!#x2HLy8nGx%@yhb;wLKvp9oI?X+w%Ll#(s4it|0B@d-3{4=*)U2v zN?F(QW8nbm8tWh;HG&m$WSq|!cmS3=EMfOIyP@Zw9*xFVR8@dum?Nu0j1aj1FkYV? zI-MObtrCORE^_n51yCp}goEE7WP!tea9@)7L*~E(P>5Ti8D%>X_yquJ>=6_Q%8Iv6o4vuCjc-3Dzsp3kXrveb%S7Z z0POeM6Pu38>Pm>qh=YJF0g!ko5jwlryE$383?%a;)J(95&@LrrbO5*tn_e}6oxdHe zaDfPxZ(UAw8oWJNe%)7CGQ?;Ba6@5cfI}rI-#WSn6%SbT3a=H?A#<$o6uD6Wz$lPg znE3!^fV1t&HdZ}+OqBHkh5G`d0x&msE}?A7$|>}nWh_5og<-6EnA8-xi0l@cu+`#b&XMX#;RQWhD zkgCVUWB{O4G*+;boxXaSUIjMNs{l7%$T*upcdA7&WOM-VbrZ8-s%u)vH2M1eHYFBW z97%NQv(bmO&o@~B_-?-bRXs~#`HOOhO^=13q#!tR>kQE$<_wtAU$WUmBS92=byfDf zjCW9crRz->%nF}HcevQZ_X5lWBzksDMY>iBW>d_-+({k)F_Rr84}cE@CN{ZcrsqsB zb1);a!Gi{Xkg_y-sXQ~J;?1zh05~T*rxO62C5oM+HV}*s0N)IV-W$#G@+bvA77+FB z{eDk*-6B$$FEBX(ihAP{#`7Leafx)1ckCx@H845=e2)Mh0F(=|3q;+-!--mj!$t={ z=nO!~F3l$DG7nWrKGhr$865y^W;)uG}?p~t- z_z!Xb+>H~K6PHfV0G14L00m{_QkZfqg$A&45Cg#TL@!%k5_P4qQrZc|nV=IC3V<(x ziYH05O^cZ%fYpVoq2+Z8Q7zfz>8=*Qf8|Tk|GysRlz#yt&XzSugAH#00000< KMNUMnLSTa6U9|rI diff --git a/data/icons/Icon_COD12.png b/data/icons/Icon_COD12.png deleted file mode 100644 index 119fb0693b035139667b34701f1e9c9c04c275d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2483 zcmV;k2~75hP)@l~ojexFpj!Rtz>e%{V$` zj#(~a<}!|Hj*gm+C|gRFxICg1F(FC8)Fc%gr@*BY3R9=V5;F%1HE?54Nyimba={Hj z9Z>{?^mfkk{lE9W|M|Dai>KB%bLP#wcka3OeE(g}Isbh&n}BqijXlXC`m2Jc2k0>Z zJUuXv6XEFrd5i#055&`=OTfk^O<3-L0qnqp3G7Hr49g1+X4zf4vY(!M%Hsq7R|!DJ zkI$daYRbzQg_=8e*v9yH_WrZave}@Y_6RuQHUfU}^<~%h?QFZeso7uCcgM`^` z8c@b_&#_I-o9pTvu-jSr-o5Phl`D>MTseK3?MY8(Ukn_`BH;Jr`Veq-?OIdLODMl^ zfsOO=VS&*0v-&vi<;C{HQmZa2V=Lcyg9XEPv4YNTue`!;fwOwZ&&Xgio_?B50sXJ6 z60jYfrih}vJT@KHeUP^|i|pK){k&)qtE;V5=xkiDfcZiDF(7MPa2_4IzHgswFB%9y zd%^tJdi7$pFyqYN6wF|3k0dOzLcp1n6osLxTesLdFdfkt$|UFK<|RuMdKZg|WF0F@ z;b(YKMTv>*Z-G#W06(YRW|(0(Gpt}!LV~0H1dwmd5P%!s-5WO)MlzQzlLrz2ve>Dc z*|)E%!-!6u9D3tSI=|Q7pH-HWkb@TqxSW}3$$1GMzWlPo#;0Zo$m-BRWncwtHqt;o z5gMj~#5jKwMbGiAZQHV|J9g*}oF`!Cpg}GcD73Y+NDdfewZEsD7Vj?Q8eDp?V>9=y}f>Zs*WOFeU;ndqT(@DRZ+o4H)=%A7A*pB9VbKRO9A(Q z)e#Z8&Y-Lk`ohhY!q{h?(Ok+30&p7FfHORS1=b_iJhuB$V2{_?3)YznZ> zuQBncK?1Jk=CThV(&V2W?#Qcj2>2cz#GlaaC?{K!lH~Ri2xoqSaGXMD>(=H8kR<8# z*V!@XwEFgKhmrgD??3p2lL9lub+cx%z-G;4!n9upMI@F+-e zz)%|my^SW!@1kl_8`JS=jUtKktEUSd?NSV z4xJew4S0#O9WUs73em?Acqk$;ZqVB|NCLEu6CRatLQI77AJ1aFY)enf5Mae#>9%bu zTex)ixWSNs0~$vY1*{F?`5)jS3GO5SPcRCb;Aod@*^LPJ6?V~D=bD#*^|o)q!`T8@ zUujWM?5>c_{dMpl3xFsR+5N(U1QdjYk+$Z;@h#b!Wki4&2vwAqE8^~VLE?uGS9P** z)F{XAp&lgQ=JDeyJJm2l1HHXvTi+QGAcn$xfP?ipX`?FZqN*2#LyJwSj~(Pa0A z4Z7=JK>)Re_<8^z;2fGhU7?4|MAD1&00CFwRHCo|W~*c;!ia$EE?rax>}}hUxpbbt zzd{eAyis0W@-k^i0<>(Doj0+|RYq`gqXx30Pal=;_~)N@=#6S%0<;RI ztENuX4VzU2;Cnw2S^>oGoja>^KjK2&h9V%lTQ{=(&9XA)-?XW0W3Cwjs2MP}MGJBu z_`+1gdo5cwI05*2j6w=zt^DS#XXD`>K(P72i!YJ`$saRDp@;c_v$Z+ZNYmL?nH zOJZWYkimtUR)Qf{2`I4J$#$hMEg84ZBBF5B9wWq5P-%@iJG4lYHMm(Bm_`;*_JyAz-U!W)+Bt=tC!q{sur0d z;N1H4vcY@8I|2$}F!j4ZyMeX`g^@%H9lJun>EvWmA1_7lPk*612%w0l72e|`26pPi zdfL?0V0ROM15G1b?X)xilMLV9IA(TxO9ISK-U9zNuy%3W?* z0{jf%b&J!}Rk~@>(U!ttLjoYG(+YX{peMvd=UtuwD1`|LD&5TG%Vk~aN{v+llAv!b z{4jT}EV&@Z3`Fboy~{J;;MA!q-Thm($hu}u1S10QMXI}CcfREo$7N{~pMQEsH%C1c;kpUO)hOYkO@>jI2jpMtVF5AdbNcg@uly2VPIPBV4AI zfES+lcL-MhHz0=E|F&3~0Y<=UGLyJVNRuo&kD_%8BwFV;S4BS#u#gSn&5Iu)!U}X= zMn=J#B4!hzM@38%faR~UbLSk>eKkaZ{7Vymo4IQ;kD{plKNx9YI!$sq@9GtqN5XND xfaL}xVC^r&>HOn1-E|50ul$qr|9_7Q_y@lqQ!Rv&paK8@002ovPDHLkV1mnIsw)5h diff --git a/data/icons/Icon_COD2.png b/data/icons/Icon_COD2.png deleted file mode 100644 index 470c389cc148e10081ffec6eaa57677c2f9e8fa4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2771 zcmV;^3M}=BP)O z%9Dwv0v=t*ktrC@DO^jkiYe_MhaPiDb_sl4|3YozlRpD>ne7$Vw!W@i(&8oN*C08s4Gn+3<#a|SiP3P!9XAOEdjI_|$;fz|DJ)^Rex}!qgirKm^c*!47Y&s~U;a)VmJ^*+z1`~d zTsW5$OYR;YzYyrE&flBQsApHFEZvglsIYjMFqHIC~HtiMKXaL~C1q%QU zF3O%fYKDsG`BA8&WSz#MNcz2w)kkz}$$b;YwoybzMtb$VVCI(2tD=N$ZS4Tu8#fuH zLc!NhHe&0z%A@8T*l6jZ8bcTnvL+rrH<;U>iS~+FPgs*TkC!9%P`Xx4iatg5cd}Kl zR64Urbzneun<~JMf9ThF!KM>YGgLkm-i1|b7P0YiAtm`Gr0P>;edBc~JkZ2JrBgCJ zKWc!ZNaOMKSyZK;pwv_EJwCDSRS{;lbKZkwn4lsP8KZ)s~vIH3jrcO&H zbLAusY&*cx$fX`>MVGs=rd`mMm$wXsLcv9AGqbnq+=K@(*O|#SEhgLanB-*R9t@N0 z^EEPNr&2~4-|^Q>R>EuypQ_IMX`? z95)X^c=SfgT8RHlyNhfLnpKhxaB~D0)78M>~$BuUah#*$9 zKWc`Gzz}&p*J^EL$pQm+rRK6~SrNs{{>?|rYI!(x4__WWCu%cR?6JQC5Wy54(EmY{E>ssF+TI)H z$|{PseFi`_*>1uE*lO%leApywEZy*709-=)G>}w)Qla3hwe=jxt>)}^Lhs(t&_sUz ztE8ttN^^57Fp_6SEti}qG+N%#_sOxZ0Ej1^aeDE+TX#n2q{R>$>kNzQsFS4e$W?tu zJCmns89Odq_@O^kSD(dZgAv@x(@Bd^Dik84I1#9pxBuVx=P>}1NtUFsHF}p0ds2WT zSB>!uN~x)oVu~fl)1qY# zb3A5s+TZnEsRC$jZt0UoQ~@!IgU}?%ulO1aS?u2ZKAX<%V}m}^BW;R4g%spxYrUb; zDP_kKHPz1JJQ(TNLDZI}EYS$sYHKgEefv9*}@?`~ptyPcbETE_YFKLKhE?%zVjJ>%VI5)D4g_fh zkzSR|%#~H$4mDmQtpI@qgvSU27FRV0BA65x%atpg0-E76f{y+`rBgCv>oB4x$d4oe z4($IJaIU^5hbmBjLMim(%I+G0lU&Tv`}w(O8oXlE6T&C@bKB-&3>_)Y>$_mF)RVjR z4L~|Hcfrfbgq*5~Zz?BIGgREMC0e$_>xqJ`PT{p^`z(zKonWU>0K45i@)D~KbxIUd z`-8+BHEB=uuWWYQSjLw8g8KhXve5Gz*OGgjTo5QAG{7Irxi$ge_U&sqeY%jG@&rcQEUfw%jm`im6!AMf zPf+QU-1T-$zw3qO$||xKY^2iEfEFz);#SE1R@7ck?iKgs=^)cr{`8Ou!W;{j7Q8V$xvr@AXwOYC?*BhdzKxL7Y`YfC5eBgx_ z_R`SM1SrUkyHob$1M&3W6h3X@;{c3hEZK3{UI`Bp7Eq_K@!@k8+M0w8u{Yj(&&Y-i zI{+9?IvTaSl}yZ0b9Z5EzlHzcu+dHUm3r@1-UU$$$bNGq36nezR#$hK0|!c2y7XB9 z{1{JOQkJYq2jb}gcJ18Hs%1rhGtkNGBLnpWQ3d#``d$^SHiDd-KM@?<#KMIK*_rgD ztO?T!A_sIi^758F-BI3bW;3%NZxMPzRMI|*J8sC#%w+xgR92X_c%&Psrw7=WTi7l9 zeC7{Wc<|9XL4zR+zp%6X&9qOFW+0y4YHelppP%oJ@N&qJef!%NM7MxgsB1KyqNAge zl$0dG!`=NuNJtR(+>^$hJ%?%QxSyZ^_ee3>FvRPGrYF?uU|!t1ju*FjcNO2>V&|hZ zKT&(kCP^dP0_M##aNBK<5FfvqlP7-=^iQ371JFT{`G}xTqyJ?dR0f79@xRZ^6Q(CP zfBw8Ejcf%ty3Ar#z;enq3r$3)bLQNY2%pMnM)iO7eSsEQFt!;*`(!IX(d8KxC}^zd z5cEe!JCC(1TtsCNI}|&)ooFwYIWn*CCHIK6$V9w1D}5SH3bFlbgg_SQ<%$q{iH!; zb#S2Q@xQ}@bwD=QCBBNP7YVI|+@^oEtcvQf34h6Vx0oUPoy({9k{~qs& Z{{mZh4nF9NP@@0<002ovPDHLkV1h9BHEaL? diff --git a/data/icons/Icon_COD4.png b/data/icons/Icon_COD4.png deleted file mode 100644 index fa0df534f65aa652749dbba38c89aed939bf2d59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 zcmV-m2cP(fP)=pnbun6)pmIYBZ zS#$+gdGxjCc=w8X?z;Ex-n+Yi-^}@kbNRmW{q~&ie&;*qB4i{1C>z>yGxnDfdk@fV z0PH<5yMwUzfb0gq-UG3Bdj^2dL%}aAVBhTPaAZv-{I)^`d*3gCO#>8mAH3uMf(I&~ zJiQ)FiQ>E(*1mSx?oLPoVDr#?xKsVmr1J(*tLtFcuppR+PTSoX(EzOJCWl+aI>?#^=MCcJ6{3f*P_%(<=$i*=QU5|o>OJ1=Xke8%0E&{e zl!N#0KY-ZS({T3e6;1%BPNnMsxWT(9N)!O9>;}O<0+taYf?+uN&N=`O>YFLWGiGcc z4kF|ZVWFp~ewC_*^gE#?Ry%)axymBvvADahB;)WzNtOXv**S+(aqr$!iQ@OrL0H{I z4)UWKNKaLg^^Y5#9ghG_x61jzUb#?T+hjF>N$8Me0D@l1<5b+G%S58s2VG#FU5e7d z1qJB;?!&h3XpL0>@Vd7~tOl^Y4>y2r-98|SvD0F#ajv#wWFfS){O8yJmLTa8pYjaT zNtew4;5Eo4UAsyP;NZe?tDP4Gz;dT-Xl|sZVZVMKvjFhkz&KE;%XAhyzt&X_+L}hk z0DxPq@&TndDk>42oW_HX%Q;Xa-l6(4G76cuz)Zmal6TjL;=E`8F2~&FR9;bW3+go7 z2}*SINd~}tLC$X-UI5KaEsg~s?44_Z4UZk`OAPlyfr0>(o~N@;y90PMEpPEQx_|!( z=GS+FY3L|#=c7EYi|V|n0B}agwbqU0;>CP$b)6*m*T?#~VvWN9z-{?++3@@3Dk!>k zlQN{yXdyH-23%Y`m|x!;7NbkN0VIW1i|)MW0C3ssYSLX!Lt3pCe0?|Rjd{Q;C=`~V z4BpOvH7Fk%b>am+NdWAfSOPjNy(=`9oYhw zN^kTF@I{$s4TeuH735G}UYYFy2wk5#-9s2OXbucR-#pdW3g;Y9m+~*Q9Y1~nWU^zn z2f!7baq$xmCM`|DX*e)2f)q=<&|fBv9Sf@B?MP!|6M<@T0IOe+Q(MxOmKGR1*prF& zQy}Sh0cAKcGJ*7)Do1VXr{JtKnUb)uUx_}MEWx$_w!K9=r&Qi#oF7kqVXg$`%$ZE` zOdqs?(@;iiEpI1kYBX#C=AbOowg7PSHUsVD%roGU4*WCk?bWF#*xRx!`ap^Q|@`B!*za*ElsdK8L;b27Cf0hq-D z!0adV#RpUfa$wAurHr0W$^Y9Nzz-fzTLQC8LMkXIrvL=@%!LLG{|fKp%CZ}LgpLs% zsS!2?u>I{qN-2H?wstQ1vwx^(9vzS2XFOS5hgVe!8azH-!VXMxkAOYyC8SxKHR4KB z_>@xq08AA{{r$fuufTP^b3vI&7cb-D&M*Lc9!LIP_(y&z1t(NEpn9M<^8j$GDdEo6 z@HB6@$9-ZP5U`5?a7C+GJ=upfQu@VPl9RK^*g7FUegK4~!c9%h?8(tcwAWz);Qb0O z0C<`U*$nO68OJ6{txt~HEP%~J^5IZ`O1~X8AHh$YxCqY96NrI$H&Kmlhfy%ub4Iqp!zC*09ZC|{0X|EmEe!E zIwpXI1|4+oJ{ev|JKF~Ut|frW-#FX5dzU*tczcJE0%_~YaJvF9V8AS*q(_gXkd;+V z_2bG7?jM8pv3jn=J4Pmm?=@Kspnw0FM9Bj5H|(EB?*$SP&Qk@EQ`@Ae{R@@w@FNU> zMb^&%ZcPj}C%06?o{)185^}(zR$nhH9>v5YQ92A+YG1U; z@*rpcfM);~fXqz8@whjo566X9(GD1jwhL~xYGJoV4BO$J=u1jh>nv450A8Fqfu&8W z7Itw$l(M+F7_fUh4Im{Yr(*!XG2rI~ zeE>o;K`e9UeoYL&fx<)uP^&b5WxutI9=*i&0Pw+y;U3{Q6fG)%KeqDEC3161+1=@M zlwdmmg{^`$4>UFg?v?f-~}iH_^9}-XE6S@s9cdWrzKS_}SOv aM)E&{)cZ+k$y-<6;~7;o3_@vq}DcVZS4|G zo3?4v#M)T*9kHl&t-Io`RlzE*sDK-;bw!JaA|h&46c+>+5K%vfpdtvUtcr*%@68Q#73{5SXAaoB<_g$)$a(0~o3YUEUNSgmr^B?YH0Y9=2u;~*Hdo%#1boICsVOZ1Aw=foLh~yZ zY;S}m2>2@D8st2CCTP44c}0cL!o>-g&|upeV=e;f$7>*^yiC$~9U|hd0b|z*nA68> zZ;&|%7@Kidw(&X)bz2C`=pm8<-(ksh&&h^xZ81cYn1A5Bj;#JB5pYiXglAw`MFseW zo`N%1qp1XhXxRU4*9sW#&7uPR3i1?_s|HP`O#sI0FLeZzR#x&R>^=8SVqm9Vz=I{i z7+H^U$^G#oMFrC4wgkQ%K8WZOc}5ulZ^vDsPT1JK3z^W*8|tyk_;6u9L}a9K?>`P) z9o&6~?t;Ra+=#J?@wEsz6{L&+Atmc|ZAT`&c-HW|hTQ_Ejss@QP{VMZA}H*e#Q0aA zfDZ%+sNbyvnNXvC-*1% zya_+<(^F3X<^}~Xp4Ym6x4c}EfCUdSt!2M@0&rwhl=CL^4i17k?SF>47s4R;Ng?lk zbkZ#%uy0R6Ve4}rSi^P>CK0eZpB}7a=01eNr%$Q(cAhv!1P&V@D9qnVK@h?u0$Sa^ zsaRm^NsdI|tZ9P6PEl5lrO^EMe(DKOx?FvZSO5Ar4(}5b7W=f+f+ib~@i51rk5rZ_ zbOR$o+PiLyO9?liLHCZ5zdq+%o>j;)K$DmNou*G#J(~4*Ao}#~A-y|^-F$-`i|%K@ zZI)4E6tY>D$8H~}+qo?fHiCWUE{BT>tEj4yMSwo69zGD5{eJ4l*^{ObfMu^!#YI#l zwOTDqn(qQk=QhB2u&Ho#q^KawALL@qK7T?$by)pH!Zj|69GQLx=H1VPDOvZx{!S7! zW@8pf1Jx4HH8l~ml`kZfJr@@XZ*5s8DF}^_3m30V904;!jzjSaaUFuQGofXCw0Q}r z8>fNH3VH7%Bi8(3?0WyH0R4k)PIj1sx*y*DRw7nwgz$6#@{wT%3Vfu|ypK z-zV~aVSQl1<^uQ&54e}YdnPPKL!O!IOck{Jp|aP?6yz2ZKqIVD`}-&-0KLC4k~1@E z1s2`!@SjP_NF&dT8$lK1{W#Yew(GIde>X5aI|Fm+yfOl4#-(Ow5###x;-2Y2acC)7 zndF)NzfuJS6%|;+Zas=iOGz2eZN3=^_|0CLfNGMAM^uT{8g|#hj16mnK@!Buc*Ykx zr{3aCq<;mf380abn4Ts|K(c~PlevI-3a69U)@Xd;ha|oe#4WIF_SO^h@rE!X& zr3!*8*B#poHOL-pra65g^xfyDihwqg$B}vD5`ZIBV7cNlFA?Y%PhGc)2y&V%?sPD5 z(&g$>1NZV8MOZaEiQ@_nGS{I1`2;8pgKL zxXhI#L!Nv641rS3&XJi%n`GsUmF0VOiAJbY0={HZ*QspIt(8bc5yvlGgf~03CPJ3X zSdUpE>gK*cJ^`^J$6|EIFDe4x6E$jq6GsDc zHHtTvPyQoC3a8~gg7;lrs7aL?A24tG7NQ@{DVKnRGJ5HohQPo;s3Wq?Y|m4!G`FSp zv8(ku(ee*D81K1^5a8)9pMYBm2taTwvs)Dtd&y*nssko8zLDXuHSeKGQKZA1nS=nL zs+Bnicv@Z#4RODwuq_AObVn%mEra&{LtE3 z(6{SwM1-0~KvT>E*ohiV7zMFxKx7Q87IA|9-o%?P@A-4y^VWdg0gANiWE1d7UqS$L zK7<;O1Vu&&7DR-4jg~|SYr}^QJ;WWLniar=pQfJlxSVj4+@CU*H{Xv*@+-pTg2yf& zqEDB$z+4DZMgYwT>Iq<10F8i{q(no9h%%?I!g#=5-?DVFF@9uYTQ6#=Xd7@nTW zyN@SG#OeXMfgPg93X3Chp=+rr%1V_I&@ny+9#9OJy5&_O3#~~y}16rA6JZ3Y|?MIJ53*9jo-Qf&5=K(B1fWGdAjT5!!2r-0S zw*r1zwirfvF6H)dEQ(^s3IAfG>E`PV9sZbTFdFlZIZmd1ry$n{(D10R0EW4{8Wa+$ zyQvvL`+?cEf$Za$X=29-|6-)MY!NUA{mmnXcJW*>|9b%)?%vOa;HXHLy>+8u*<%Yz z;yZy?c8GpIh=(48DzKt(hOw5*UM6EjBh5jr*biqJ$ca?EgqL@k1RAR=;sD=1gN3nB^v z%H=K47kf_Upm+D&d-k4lxijT&=KE{Ue82De?VjClch5n{2yPb;{Flu*Ujnuc&}IVI zIxw3HVe5cwCV;I2v9&!EK+Z#cIZwk^1=HY%>mR|+;-&Dp&I#t{46u3dRu{l8XCUO) zrhydBm!E{0XP>uu5>^plk@h*LY$}yZUO@Ssau^&k7~VK;`(#uTV1}j(lr-dkObPA6tlLm&_`VXFtIV}8|z`; z@qO_7`QNDmB&H<-8jD~+r1Io{ED2!}zowxEkRO79Q7Q@0&{9i~xUF#G5=3ty2tOW9 zv=^5Z^X-e2C68B^#+EuJ0n&2Qcy1>Z1elij7?q^QlpY+(bI}OAG@T%|>JX&pQ@HmZ z8y+285L1;2kW?AXlstxes5{R+M+E_9XZNC#baL**kvN}ff7Ugv%|Q_2hM#C3S)Tl| zyjPf$*XT5S@@@9)9u)+bliiz2)Ma89jsz#I^c|P7OEsy?0=Ndd@&fo+#>p&z%USCr zk7sgLoXa~W_Ws})l?0fX^(2+7^Tf_p69CUUWlef!0i2gP^8(DaoSP89{em4d|9y`j z>*wB26aeoH49%4fw3jwqwK$0Al2GR4x#H{J-X9vPq5#;+8p+;>JQ4|ZRe+?5Jyg=7TSZV+S4C~xm9WdA;dtV96m#+? z(ocxJ|8kra1o-6ADCVF>2aM)}3YJeElsgPs|88aG5_^B4vg9QNz;^i77TEzs#Yc%f zGUAYYa$Lu=A|W+Fwca-=0G^p?@47M0XwSeClb&GieSE-T2|PkQV8px;fEFuH-lPE7 z+%G%=`%1##(#=amAXSDc2;UP94ig;sZ8;E3y`0)j`v5llHJpETj%#tT%Cc#r% zAC*n$t?3Na_in2yfPjd&2pGEGUbz6%GaaD3u}C)Y%E*;~79e;#-8^B;ja61jUckZR zgMh*iymMZG06&+K`+ZYrXlj5#(+7dWdeda@W_5?!mb+F;y&Y?IuK~0~fdI5h5FdVS z`*jK=z)SNuQJi3h&v-q<&-N~DHA3!T zf^>V_cCNk4*K{J!OnazlrdN^HfKZyh8qX-elH3;wXZo9ZKKXHc53euqBAyY;(-m~0 zbp@Usk@o{|`q0U2X-)`$XMbZ{F1pMo=f*!1c4ZRrOrAc^WOMN6pXYz~l`DdoniC7Oh)c`KmxR^rJ62Mc20Mkg4(ERZokuMco z**u9sfR(xlgcI=<@RSxQ_gb!`06&$k>4;pZ@L%t5axx?YSeiG2aDtb>`;*&LIFoor zJfZO-Nwfy`T_2uQ9hW*ncbD!kz;gi12%7a$Iz08)pdff0e+5;!ZX z2k2_kiT0QiF}whNBuRC11yj&*C*#B|FP>C~9Y8SgGy>PZxb%uv|ZBq@kEogHPPqd8m$BH2{hw#1vNnd#P#{zL=zQ-T{YsJ>w(k$K__4xKd zU-NSMG5ZpFpLW|EeEBsde;JoEOr9N51;E3cWizxPW`kHL-G6h0Ehu+5Q^4ZVHI5!| zz{MAs{E3IPvls+esC^c86bC_Fv-$0C{F!*LceLk8z94*#hnV+ov^!ovRX{vg8FE>G7G?MtlE6Ol|uT{RMW5Lr4XGM%{~X{ z>$S28Vq;^$Zmu2Gxuug}b!|0_2^>Rgtnf!#tcZw>;05@YL4czAi%cY;J3|3|fM99{ zousfXi#c$NE!69-cJ#hWl~{q_mS^OKyJEfVMy@&QVS$6$*gMQS7MOd)*-8 z8aYV{C1?NdNq_Tl`gcUW1VXll@B(;C&rh-i=bxwcj33HGf@a(Hsz(KaOZm z&P+Bd05)7^S2o_XngGkUE$8DHFYor4SpYl-Y`!*!XcrD3Y3BjPhQC6;YOt)Zkpe!t z|8)DO;<9II;!`BRhZ;wyY`Q_Ti{vH_An!N)vE|9~I8~CzTWIf9-eU5dHp+{EX$~+4 zApjO~Y-@Gipev&vz{mlb%7 diff --git a/data/icons/Icon_COD7.png b/data/icons/Icon_COD7.png deleted file mode 100644 index d237f37f5433390c977842502c88ec397aa84295..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1981 zcmV;u2SWIXP)(Z ztB!warXr%EqM`z3;)YvpQBsCGDp-n|mZ)Texh8qU2rv;8L6mJ+W!Q#g7`9;%2WD7@ z#jm+n=c(K`%)4(Myd(OZ^ZmoUe9Q0M`QE+XdyiqdNPH>-eObHaONi6~N(Mmcz$6DD zbwH8HZK&kI_c(x*%=e+8F%e8jRZT41 zN*FGA5Kxl;Y$%qCZF?}F3wWMKg6bx}lut*y;)HR2p3 zC12+R5T6(hqsB9E)St8`%Xo_#s2FmuwgeWhWZ-llC4i2OM#9+ln;me1pHE~AAiRn3 zs_IfazGM|?FD+|$Z{$meUf+sivYSN#AR+A)PGgho2V-OYXHbn80JWOSpj5@+-#=2c zI!rl}8o(GE3IMXZZ*v+OKY0K)cH{QrxwjG-Sh=17mt~K2o%=Hn;2ln56Q&Hr#!%9< zm9|d-h)L+{05aa>G-f^JwdVsse5w^Zc+f@|n?8F83jm!B+S>0wHQv%v*jE5B(9)_R zj0K1K!)R+Oh`iMwH1(mxcvemlb~b%Z9{^BOdz#Z=WmO3@HEB4Sme%DD>%P1Yq|08rbjPJ5NpxK5`7kF9H9tStlEy%~s2 zGM~IqP0#*>I(Z~(+-xv_O`ZY(ptE#)ht8~%l(Z-~bnN9GOCD)ujW2cb6>25Bdd^;? z1dy24-%vqIcsuj+-v$epGjLlbe)6amb#&BI12_@jiIbl;yL#xeiAfRc^1l{M2_P~3Rl`}JlOXEgJPaE|%};suzl77EU_U(m<3aI~PszyuykiXOg-s63=npEFJ)LHUG_+Q5qWR4LiSnIF{o9 z0sx@u-&Is4dD!4ohevY??1(u^RSuqmnvh~7pODs1Q1QDM#;)0T5dJ4jgvFF*q*Z?~5#gIU@|7-#SH{&b-fV8u~^UH&_Nhp`1^h zJQBC>?6CjU-_ZFJWh>m#(at_OI&j1?0QEZVXOG=Ubxk>2{7zjE0RUR&G>4%x=Y80X z(vwe)Xf;(njM#0doga1^63nBRodIG zQCwGzviJzj8-V@Xq1f5duLc=5L}Zaf-6CO2(F$7i71YTWt8&@m_jhn_0C?163%|*| zTZ@Se7IZc83g=KKkL0kgyC}zR>J@-`Y;whTVmwnGkH=T6qYFS&A4Z-0lLw!@hk676 zSpFDm+ypo34Z0B~~Q@4QUCn>u+U?jAF+uT@`L zmb~B^kfpFD##7RwDFFy8e(2zXUerLo0?tVQ0M&r};zh(bdV_?fACOx(lR9}Mr_TPw z9(*j>cnJm|OSj>?a!36(;qh-h_&L5`M?PENBgTWzHZRMQr>X(wWXq0uI56-1{2X(= zj%!Zh60TZw@aZuC=)sBcJwm^e{2W)-{6^)YNSOtWUk-n?851XY(EzMmJC=QLLi--! zhD~%YN;u48MEy9!qT}#=O*QQBTF3_XSCDvt^_FsfFQ6sA7cfd$c_GB!356rae_)rr z?R4(%1fB)$_WME9WH7Z9(F>8w)-tf?fUwtRrPdc;jy|v75Wo0(yo>w~6Fw+B=F_1n P00000NkvXXu0mjfkLi;~ diff --git a/data/icons/Icon_COD8.png b/data/icons/Icon_COD8.png deleted file mode 100644 index 57f6d4557b75d48c5fa180b23628968cd8192cd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2396 zcmV-i38VIjP)@RaF>%R7NVLR8}r&P1?TL zWDccfW|*ZWB$G*6S`tEHBuZv!ge@;c9SbN)4bw0y#K8?U#Bc*tP!VL4RZ);#79UH0 z_djxP@4a*Gd-vS8HPttB=FM;}-~a#LJ@=gd{O4Yc#t6sX)4;#E8OKY((GEIH07pCK za3LJ+ki!IUv?Gpg{|lhxqEn0e!r8T+P_`uyN`IRTdEw6qf9vCL=WQ;)sZaVrV{r<| zp)xZWjs)N1@E~j=KxXLOpsOpF4PHcTWhKlXI1qNf?)YG=CP2pg?$A<^Yc_Zh8Ty}i33RpR6xpgjmj~yQzJ;8XZnhDiAuo|KdZoD;c5m1KNB8b!I+e0( z7Yr9hLDX>N#tWk-Lv#6QZn5=In34?1A3bYb0ot!LQieX5Fo6X4tk8BZ3#IxiN=r%q z%KiHUzkmT7qKNG0{psLB*3jq;^(_}Cjwy5YM-~W>%43lyok@IPlpA4Y$U)D zKXt*M_|R3DTQ1v0fR?5v7~8WaM7pUE;KYKSYyrA;vq*r8Nh|CUyol(~P#7ind+;4j z0geYc!JqA|6yeKv+#v~odxN&dYJ>ikO9iq<(&u)8c3qRbVkfAns387^4&)U;XjiI> zDZ==uC>Y`71b_HALtSP()t{Z3N(@e9tO5m5tSx)MzH*#gYxr=Vs|MPcGl@^}UYr7)S^gxqF<&<~Vl1c^&DT_x zuG)EQ&kHRkIGCH`2Vow-{|_I^DFE-JwQbEB$=TS6G?%WXl*{oIvu8_u`p)xakGs~d zCmc%#sSp4&Le{fxjLbuaz}>|~_U>bAyfT8m3f>bvqhrm9LTyf$bMaom_E`>RK}cw&|>4}LD?$*WRQp39n;F3F>QDCVRHefu!lo)vy4d4_YJ;)iZ)RZVT6t!?6%(zwq zX|vfz)a(HgH*ba&qaKBf`Q6}5*bt~cvzwbkoJ&ll#7qIo6X^ZEDd<{S;FUY?gfAap z8_5W|fyx|hjpM?|l$%S;3c$()vG|Ew%~J;tG7W|Y1(9OO?{BaT@rr6G-gkE=!Q;p@ z^>|VO;NAMOqr-pt!L z`tl))@IrAhAsf+ohp~uhjI=#_$Tc7ImN%BO@+nGOYons9Ov+1?6h8r8pN<3?f(OXKEN6?>t*tqsQa>IFW| z90HiSV>rxpP3+3m)vgB6xv!_VP!yol+3sbZL_f7=unYE?2nBl9Lpc$5CDfc&t_<&Rx2e+ z`X@)&no5sxJB?{I@;zfz6uJ1jmYYi~*5V14VgWKgy$ecz^@lbE+u=jow!z5jt|LZ1 zxtr$VUHdVU6Yo4Lt!~#f^YL{a+OmqZvH~8c93_{#G0 zrOGmg0DLbke79f$1oU8MT@3}vTwDmR0Ru>l(U=PhBfL0~oNSQ9*+c+5j2v_0ji7yy z=BhmO9kfu5ibQi z9X3}PQalNY0^kT>36PzZCY=y5*Y84hG1XSkzx&*$!_lCmoY+1eACJT;2co&en|*C6z~af1rH$FI6HNP}N`MUQNYK@tr}`sBH)W{XZh`|LO;n|JiSd|Nna22!8>(vor=*{)7tv O0000roMOI z``&%uCNqA?`9tq>?m54A?z!il`@S+|%m7`x!hc!J{Z+u(20D!ZXB*~pBAjiI(+F_3 zAg_9uWGkBI>_;gG8RYvSZ@?Xox3}Lw>Q9+ zEdV=r0&Lg-;N=A{ZJL7!@bS^@yo}%p6JR@%V91dE{XgfIM~^JdQ;1QS9UKfWbEX{$ zh>TQBT=3xoJUns);;&!l8us||Wmtp+M2V2ly*t3RZ6IZ53lmOw9~A|EPn`(_=HH^=LU2#Bs6dg3~t%rbd<3P&Hw2AXFvfjLbqo_N#b!#gLplyu< zkE&IfgZXXRn4T@{&;j=0-+n43hb<9+xkAdzv#IkkXqoOno02gaj1w?$AXm9(_3DfO za@ugx>C*=!8-=|ZGLn*DB}VI;1`X^(KtcQVh6#|u!tCn2j7Z!iyv?FjKLP#v@d>C_ z%{l@WEO3bP1gWG1Hlm$JbmSu?0d8&pMMVmwt1zTY1YofuWo3Om>8n@Tlj+#wZ3)_z z-O=8+4I2s)K%x5ftwLc$P!PD6EeqLg+XCFatr&m#-~l7ZhsXM?S&r~o0iPBvEN;vE zLg@T?u0l#M1sNIKvHSb?GXnfM6G~^!*war{oLab$*_7V2sUQJUrU*|K(4z;N>==&# zPDD8ZahEPJn{I1Ff$C{cI(k(1MECdYV-u15Rk!Zfx<-sJWPEyJB0M;B2ySfJ#2hgS zs$T+)5Wp%z&RRD|Vt6=s)u^HR_JLD2Tf)`#>rI5NMLCLc1GluS=g)<8`C;9nRljIA zMDUPNvTGM)K6#>0oR7KS3Ocu>a%DC_0LrI!?Ua#3CpQ5+#S&X~{=7M%2A1YlJlc~k zwZcf70BU>PyT?_WpOXWDbLM~tD!+hI)UhLfDV;hcWbo<5i<2Qob=PNJMaK+O&U9oxBJT=u{DQ4<5|){aLP@egdSudxa(`{P+>Pn>2x| zye%*!L`c`Yz(8j3AG`<{G)PDn!5{M&>3f2uynX^W`!+Q{?_xrHp^_6qJv>;mB%^ur zuk{@~C}ePPVIiz>ae-fW1gI2fTA*r>2uP||PbUEs{&<)u4f;13MT)5T`I=MN-QB&L zjo&mkeEW7`qqFb@oR~2KGUe0U=+PiuxgxBGAnzz@)u57qapM$9-s8F>CGPSYrVgzc z;;&s}&-`jmfTyP+!wCiX`H&wMXZZh9w8{jiC21uAnElO>5+Bc$tdSMXo2Pi@-Q&mX znO)|SsdShefv|u8X46(70yxg4CL}OLzOthE^A*peJblWZSelh-#W2L*H}_)tYZ8j z9-kL|X^nFy8#M}~;$nOI%^>#y7U{UJBiY3tPw0wD^=p+dfAkcd| zcj5#DV8J2exS7!T;!^9@5QIyQIyeOeB4gi}F{ayTk=rY)31B2(U2xDs!J$|30t1De zr;j$|NPJYjywH3$A%NbPSIwGmO(68RVxU%_{(%oh5IMio!2G%ip!PRadmmLkXE{81 zGHa0XI>Wlf!2RJ>Uti|@VhcAwRuizgQKQc+*Qy06QBjI<>K4)XL!(hZUxf*RuIhfM zREf=d!Qi~Q30Q?ig=u?PwoEY|9U97Si0F~NeL+&WbJW6KTrzUv<27XM5&_w+t^m`g zE5;KeBG~v|0|ZDXPYOFZ$a-MM6$H(-^o{_|7eGZs0Loxmg&-=mz(3j_eD4qB&TD$EUA%Nw8l`9qF z;dp}7><5_3fB}X+my@r~tVw)U5s)`=B1oyJit)2cm$LB_dI>Oa$w3D%Iq|7oo!N~5 zOOP)iuj?d0^zDDb=hrrCW;%G;!g-q!Ko=+ScZ6z}kP10|T(^Gu4EAR{qLY5AHs2!= z-xL8`d-XD1oQQr$_}iC|)+4J>Vk=j+ne$c?kdu-E!I%?d0~71iv8i#65IzB%-wVh{ zLvmuyor5!;o~E#0QAY500^g8m{(f+WMmW+3kwGXo421o+Am4vE`hWcm@%LYko8cdJ W6<-aCgCD^F0000p+$ diff --git a/data/icons/Icon_Copy.png b/data/icons/Icon_Copy.png deleted file mode 100644 index 2246199450b1a04cf3773b8ef5df03db4fffae32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 316 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#flK9sE~8?@6fQ-kg{uXb8doQ9vS=}!RH$Ha;AA`T zp^4ie=H#kt4B`)>7?N5K<~p*52rA6k%sGvZ;Zk44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8paPu$pAc7|WO;e{|NsAijEahi+S=N#uC6Uxw%ose-`?K7x3~A_&z~nw zoLIbgadmZdU0vP9ix;`Lxc>b4)85{mn3ycg;o0~T_HeR@JfsKtV zGBUEVvhv-#cMl&vjE#-8v9Zz7(Q$Qkt*@`2IB{Y@LBag_^QTRl#=*g%udnay?CkIF z|KPy`Nl8f&5s_1;PF=ZjMNm*MFE6jDsma5`eQ+E`S~g;DyF8U z-@ku<^5jW;e0*7186zX(>({UO`T6(n-=CJ2wrJ6!d-v|0Idg`Slhf1FQ%y}RG&I!0 z!a`bFIyW~rI5^nO&TgrL{xe`OrIZBu1v3DHjMkt;-M*E9fyvX;#WAE}&fDpCy`>#R zjy_*-sVn05f&f-mmq5qd6=6=RTU-QGl_GSGvi~=aXVDDeo}@H2N@JlykjqPF-Ci+~ zKMamvJSXO)e^a)$zPWR=XV%As%$u!?&(D!BFHhIgk;qSYYI^!}7>CC7cM4kUAxYwI z?H~9tC?&M&@roW|wE9_>I^|# zE%BQtiZs1reZ_dNeSweyV;N3lk5X%Ts8i7z<8Q$DX;)DmgNM6E z@H0*a(L84N4Gs^QBmuj)QJz0`h5 zxTYiH6?NAFsR+reO+SUVzMr2T)Wnn!yMM-=xQDT;>RLra7^?T`te<^q!_Dn%j<&t| zc5xzY&*$HGFfB0Pwd3m(lZ-1S#UvGX3$`rkx?;EKFHbhJbdDT%V9TRPX2HSjhyT7_ zJ~QJ`?VtD`&l$F+OuP2)*!;M1& diff --git a/data/icons/Icon_DDSFile.png b/data/icons/Icon_DDSFile.png deleted file mode 100644 index d9aa7eb254f57823883c8626674e812fa2c9e557..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2217 zcmV;a2v+xrP)rs?Sch?|{{N-R6&9&YZF zj2ie`R{X~HB1Kv$r*lwacV2POn`)FyM_f)9}`@5`$W$rDfQ|!5ux|p!ESz;2(7O5r@Ni zJ@L$N!-48rPIdvdY%~ggfPJz7$9pTw(D;~Z*r3K>oD0XT3xMq6`BZFF%L(VfNwWZu zg@wdmV;GLh;euYU0neo4gZxK|wMIBC!uBxH;54-e0J55Xq(d-Yh53eOHvPG2}P0uz>MhjtD z96-^%Vr*DzFm?qmvjLn>Okn^9!AeOh@cDEsD^i~R+`Og*VjXZqKS;7J0J1N8&%p-Z zBu#^iQ02RTuC;DF8r#BnDXx7TZ>iD=-yh3hiWX^$1DH8wBYPO%e$-|F*`R(tOluib z)CUot-%+J=DLI|#bb{&D2e2g|l0D2BHkb`y_S68TH5Edc*6}g9s&uF(s8h`mTfw*1 z2aphZodw+se9Z>1E%1m|>c)D?@BddXXX5=L`De9$brjZxfw&%0)dN`Pe*k^Gw&AMf zAy|+vUX6>3A7H&21F;=UFt`RRoEyZn{?J5}uhim&EitYFW>1*Mw31hd<038cd$-N^ zvRbsQR-R6(0CcsV%tStcU(s*KL7@*B(XJ1JS@9tUpwV+q(kj2xJ4Wb3RU!Gj3E#80 zZUl*;_wM2$Y0&{IHL?(oMkYxk`fw69tK%%(R!suHDf++(+)ynIi*G*^`Z=^3FVU8p z0vx~^xXw zLafmYAONJ5cd=CH*Wj5!Z0?fJ#g*c?%E}(HY3XSnEL-dt8tO8j-0#wAv0vY=GngNp z3zTF4X~~`Ln%8q-epFW^%rkxnIv1ISYdR!Y2S7K6DOwqDZhnE#&#~`Z<~I`}Wsk$U z0Mhn}v#DKESLXLST*A|CcZ~wz7OXjgi|U-QECAgpkl-VJBQ66MGCy|+Q#=L!-Yo{u zvF!xrw*(R~+9gLZ0J7sz=dn+X`NDZ`ktvYqE6#wCLl!YVH`uFq3Zw>$L3OcnV}A4D zEbg((G6?{gW@RYa!xYOLhdBVA0mcB(5!6xuc$cW)dYQ=(sHCQ?`>6n+rb_*5_bIKC z`iTY*+Vi%_07^?AvhDN(nDyiXpaLu--1H;%$M1WvdZKc->d6EE755fJnWn7;lU)7v zszs{-aCTf^F#voU)NPfAe0Uolo6sEM2PRk8W;pc;tJ ztDAUYX*%ZT8SfMFK1Jmgo7n)a28bX0S&v!Ls;d+LU2lo3WuuYIZ!yT1w~K4Vq4%eI zFghYh7QlhMXSDhh76FhQBM!P(=V{Du1{_iZfbJMe3&r{T+Dl(CKhYh5?$A^(KQ9E` z6zUubi)T7rz*9Yd%BAqO#+gDNGP)%qKQD+@R0@ZFB)_%QuQ`bMt*?EZohxoemi#vk zm*8H9EUno0cN1$JiAZER?}3N;0DNnml&#&#sGG}AgT?>^)J?(MbK*>*xlKMacG-!6 z#~;0c?^bh{vNCG8_`I-d`>~3y5xA=d5O?+}>#*df%J<%=B}NTM-Vl)ka6IY)(<;sp zH&yuaNaqz8hC7O|>~@ z0~pZ9n`u#hkF@S4iQ8sM?2BGrOlv&+X$t$e2(9$yX`+&pY z2~r_70s{4dr7y(poDx@#x|W+$fGrx1kgoGY|GW@@T)$sr^l=m~eOrL5-WyBZD_=6} zT103ZHhy6!)9MJ*gg3b~f|_MwQHJ4$2rbC;u?A_q3SZ$0NLCKO*oR0oug;#jjMK_f zmDlw2ag^xhHD-FAL9IKt^H@pz&9Eg{x4NVBA;W68CL1t=&@>b8B#PnQ%DRjFy3dpr zWMkh7%6=<68TL!_S~O^0*?}8NRer9Q8^d6oL9Hg>j1KSn~O{(r_E=FTIr4zy&?wuu+{S{$ptZM&PJoeK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#khF4Ec;Y>*rMa)9fSquIc{M% uGp$~br&;NU+h3U3J@HTA!W{Hn5m+_STLe>vxz&CsQ>7+eMbmPW16 zQ!M+3FoN3E&aw%LXcm3i2Aba^JVA-@LUpzUh?xHmG*niR)I&su)}W-0-M~AudCX?> z=j6QBYKKco2J`c0W@a2h;YHvjNw!$6Wx(jMV+YjgB%mJX6N_sd4jW)jPrnZMl9KLM zR1^V~z(HWIQt6XO?vpyu(`0(XH;Kr`^At}Zk> z>S41@K*^RZ8-W&J9g}%DE9(l-0XP6DgJCroKD~e631o{zmw~at!QC>MULcSIhcYws zQ&a1JG~g!i5U2p|0K*oG*X`~V2znC|et-RXx}aby5a{W7*3|R>NCnOUn}J+lX!++U zDvsh`NTltT<$($tvGja0f;khWffgi zAd%dNGugb=7ix25^j7D9Zho@t&w^NDrLLSSTEG;wM<(N_HMv#g!+1S2C9Q~SJd*uQ zw2%W9P)IHYS7*(QkKzB=%vq8N^0WTz{-{fJ`SzxA9{` q_hp{&K`_efa)ox>_VP2O>?7asX4`DLy+;0=DjXW6PVsPq@#J6FbZ~qC diff --git a/data/icons/Icon_Find.png b/data/icons/Icon_Find.png deleted file mode 100644 index 936c4313aa003d57792e2f81914a86ccfe8b4aeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1337 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pn|plpAc7|WO;dcMMXt*b#;Ax{ltkA_w3p8{rmU-|Nnpa@@4z>?Gq+U zm^^v%=g*&CzkZ#UmzR~5RaI4W`SN9FXXnz=(zdp?ckkXA8X6`gCAGJ=|N8Z7-@biK zO-=s({`&g*0RaIA4jizsu<-WwuC1+IxNsp44-e2rX=!P5b8{abA2TyEH8nLE85uV> zw}%fOy12Nsw6vT)eVUPxF*-VW(xgcrK70@s7Phsu_4W1r`0-;;PtU7YuQ)k5=gysL zXJ?n2o4a@KUT$t~K0dx_)22Op_N=k7F*`eZ?b@~1uU{7w6#V=5Z(Lm5tXZ>|n3(MC z?e+BZy1Tmt1O)2p>U4B;9336y<>gaTQ~mt>L_|a)A|lqTS;NN0cJboHYuBz76cnsp zy;@FAuClT+GBWbUjT>*?ya^5to;r2v-Me>LSXkWM-AznPJUu;&ii&!Bd#$alfByX0 z(b2Jg|NfOLS2i~{uUoh7_wV1|zI`h$F6QOsO-@dpGiQ#nvT|l-W=2MagoFe?KYv+S zS!ifzI(L06FkG5Sg8YIRfI&a7!127E6$1m)K2I0Nkcv6UDGW?*Y@ZI)&xqsVRS35} z!f}dsfr~Xqk5t2D1~<23K(|iLWKcF%b`kNYRnOp9#(1Y^zo3kn+p+#7k_rcY@P#3S(YqjW5*yz*o3MZ6O#_?NXvI6lxny}mqQoyy}{CEkE4re`M`SPrKBsbLCR ze5Rt+g1IE0k<;wxd!GOC&dq-RZ>lS-Jb9v`PlCC}@!JcdxmR&n7U%v>VP{*G;M-jHN4i~j0#AY6p#urOCpadW&l1|+%)`U?eM-52$$?_|3lnblY`-wI;(cO5 zLDIg;*%KIF7n_1*2^&1KFuzJLaiJ8ynU!|0(IU(T3^8IZK75H@LiUyz;{< zmPO@}hh6EY?s|{Nk#<+~kd~ z-Axq&%G5e0J>17KbxJj3;t4~6U^xayyCaL89`>}q;kP=o`3C#s35NyQC6*T1Y4a_A zWWu;NuE4S}Y~AL+hw_=+&K{YeWWd=u{rHY|f^otduJo=u*7MtOsdDqWAE{5(c^3BA z{_r^vWqo}OZ{m;BH9s^BIM?&#HKrKHs6EJ%zapP(YW?;0D#1gClbI&+^4w7qxb1W> zlj)+bOpKbqeYZo2Oq{(sZ`3AS@;aQwFVdQ&MBb@ E0JF+^lK=n! diff --git a/data/icons/Icon_GSCFile.png b/data/icons/Icon_GSCFile.png deleted file mode 100644 index 9a5fad0d282a92af2fdde70e8e64b33a87665489..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2558 zcmVTACN0g+~ z#>pRAjIEY2?1~Foa2e=`0aKugQcaPBCLt06#Y&Qni2_onOByLwB7sOXY9ts`EIf=* z*+kh~-tV6G`_6aIa_=K#lmw9i_X-`7aY z?V#BRFt=l7C&JtgnT-H*J7R7fBf#7am|MpPFt-Ed)-eL)80}eD0)=V!psl7K26~5} zM$-+M;q?$Q^_rr^f+uPqEu@ZqzQ6kcv{v=Q<-;uy{(O-t=To-UKyg+(bhiycN7DdQ z=5|8j+R8^uz`vpzfhTo!t>FCAc-Tz7m0alc9~HvwD_u;S-rj!jSegJ{;O6t*xw9f*-la#L9T5UKUP4K^cr6 z?+9zi7hH!=?5vfAg|cc@C|HtUbp%viGX2Cx%e;BMl=0Cx+sA95t94K|j+fWFS~9(v zPj07WA@p@Ukd2j}U#i7g0uJP;G6G_3OB8*1l$4ZnbTJQ-X@GTLWrZS~GiUNB&SLUc z<4rH9TCraX7y45|6%lZD?;XVp;X6Ei`YNN4%loud5zf%i5X_wEp>^8d$gie~Ud4Vz zMjoPsx|5Ug38>Cz@77Wh6!f8XF?;YOITUBdxgoh_lr#F(XMW139m#Xqf zqbZ|UHspPI1cW?&P1QmuX=&MXv3X=4#oD__ozv&f7f_s^kUxoj9S^Qi?Uyd1yyOv( zxUN$5Le0(hsN<7J5XCy^p$_ZTtpOF?BAaT+1Z6$tn~DY)Te1=mox#q zitW;+B5jdkPl24AqPUBBd+(+;E654Bn9#(u2?+QzwXw8Z4pq0eQ)j)XtXdhi?;P*LVc_HuU(*CUL*7sn znTiP*c?EO?JQ&~;kevJ_wY4Il)V8gbomF_!)N~J?eRegtl9b1rfTu|awdG|3Q-W!b z5I5LFvLAl})bs;YRgDw_)8J!I0A?07?e&~F>$NzmAAbT+-+iH&TVV0T$0w5F;BNju zBVfmrhtC2+=cP{o>fe7`rHFv2s3R2Tm*gNfoj!5`aC|L?fZh)N(>!qCb0z_(@vCn_ zbvb{YuP;J6olV|@qz&vE|B(}*3vc65cvn}C0RebkP?5v#8e?ORQQH|LjJaU2g$6#} zaaG$2v&&mSbfb1%I{joBd$20JZu$h^}EHUT~D>=E|l$SQCyh+<& z;o#$ASN5xrnVBngdf_%jOdAwky7Z)2yb~xqanfO}kS5^98FonG0p{}MA@Jgp(Qwp{ zzoWak{edp#W_^fjz=Wj_%)5*WCb;^1%v{VGgjkJsc#bo5bfYBnO^pr`tCfsxsp zZnLZ{>{gBC?*4{2HxyE@TJiLJOROm*2?%|LKY^7Jp$ZgcZ+Lq{tt?pZ8t9+wCVR7s zAt}KTybzVFVGHwYu%Vcp38ZA>#z=$tdwN)%DxAi~7IE6Unxs>#UDK|?gF$`?&J*Fd z4r>@8g-a4}>OJM*hFRjNr`*K)9dZ6R^E!9;HYLL0D5fp_djh7e#qdOEs)XY@SphuVa_C_OkTI!l;#74_VBsp;}a&Za3V{*KDCP#z@h>%xk`qRh34znUh`cf0h-MekH zsNtn7RNjPmwA9r#!K6t}%t(?&0O~%Ma_H+e&G>~28nCoiHIfiE_it>kmRW&05xVo2~=o|ixAxOKKdvXEG!&{7xDvta+!;R zB;3}pBLO=<8=LhY9CAusl|#j5>`uKg9$t*n-3!uT3B8MI0tDT)_#5!|KM0|rarB^6 z2vywlo+EG5_Eri5@A&OoU!*N_|4H9Z>(v~t8# zAl^+L06JAdhq!o*-H;fO@%5?@ys7TD;$8nOyXc2$x@6XD5gq0j-N|n zY2}EgK)8mS&yHP|Hn#)j)-eLi?SQ#;i~w^xU~c`v{(f-mm!m(_-w==edVG}p7xy8x UJH_lg)c^nh07*qoM6N<$g6~Vu=l}o! diff --git a/data/icons/Icon_IWIFile.png b/data/icons/Icon_IWIFile.png deleted file mode 100644 index 0a9e2fdfb65cee23fb3a50be56a8daab7256e766..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2041 zcmd^9i9ZyG7k^{I5|N`ws$F-oQfUiYR>lxJxr!u5S#pmfGOlr(O0w3F`$!sLWyD0Y zj&+S=NJvs9_sz_>$FbAz-}t@H=e_s&e!lPXKJWA1_wxv*7__k95kUYDHZs&V=VsmS z{sWR5v#KNJxe4KCj@CnbqMZuo0s*YyO+SGB;@=$s>6uahJOidCmMAU>`^N+%#zUi) z@iEM^Iy08H<}Vq{x_U3&bz9uq+pDS?1xN>InP1r6+1ZtmDFh%R4~$7l<^vSHeYfu5 zP!Es+d|&-=OKojK0NincnXH|wSEB(e0Q!DZojQKpg+^QR^UDP&q0zWCK4aq?JG(yt z-fCz~i;LUSXsZBu0NBByEjPDk0Hr$mv;6#4o%Bru%p9#_qpooyG_=UndVYSMRZ+DT z7gq+5Y2&!SV9Wy87Lrzzk}3g+PVS4ny$pc6X<6*_^csMtUj9ohErS5=4-;7h1r1VC z#Oj(gYW=$Uh3SBhw6rxcvZ=VZ7a%YqVjKY1)Vkr}k)e5MCMKo? zz~3)uxvHv*O#bxfQA=)a9RQw?$lBT2IeYd#0Cz3Tot?w#>b?M}E}o0^^?m*QGf1Rm zO3FXU$yEUH0DsBJxeX3-JGZsBe_mVLQc!Tu&ZYt+%AJ}5a51r*`|#nLwDesRDuP66 z#^DMtqi2VQr?jPh z9!kqiayZ+0d38NKBWQFaK&9~E@u8tfEv+DcT7=M;s;W0YBb&W*;>10G_NnP@fcHbg zTL6Py-J8HaQvdIIW%XLotJRg2_4Mo&7Hh4puCKXyaAJ}}BvSBr5*|PPB$?gV*k4oA zlSE|C%`x$KazrfC%PR{Y$RD@lHlW=Aafx#)Fi=2qP5!(O|*WzD7*LG4cgE< z<9L&w*j49_+!$BW)F%dNe)KYDi)o(oEKN&A*-mYH&0MmXvGUxVS#RA83-9&|%Nb!0 zPX*CGp>iX7s`9+8KVx)nrOJpd@K?HAOvLD-5vGI&tl5%ojX7`Js2T7xj=e(6H)&{n@aWHdS>PKIE#C>5#1re`V)>-Xb=Haz|+Vk&P! zl*+EDq}|jV(G$@9MV3@!`HR2uZb0th&zcb-vZGS zSc1Pz_B!t}T1RR7f{B$Aubub4Q|%j$A#U{R$8}Iz>h8WLcW@S%KkczWCtpY@#V|Id z`5E0Gr2-B(ANzxB;vpU%ryQI8ELhY*!Pm~(4SQ5S$2zUP=wIQN*K!&*{EnG9L3ESe zPQfD+J24T_m|FbtnTjs?TLDKv_5Ar$?tG%;tVXS210SSUAw|VZr}qYOv?-v?RfCd! z$0Nj&B2?e^xbeVa=R;+Ml;GM8nvJlb%@s!x1JmK)O~vMDwb40mO-7rWAVJE&hlG<9 z|JWMa2IhJ}`QNB<>h`}evHrH@LMQI4TwBxMCA8*`MmYf%r=i@!jHi+d!F7KM9?{Qn zHbT((R1r@kImqWA&6b!W$t!LeBYy6@4lm_>^HRY!vj9wu-YM`?&V9z7Q#1V`rODkF z-+6PCaZ^Y%{dLntGB19bZnfP^mD|F)bTP$?&d$BqPdzgtmsRWcM7_JBF0g;QKs%hC zAz!jyL(nUlC=4ogs$tjGj>S-YR1K6Dve{*djgzC+dA4F-oVFqtld8*G z<$lJ!_BHwoDe>4buvO&DuY*`FxQ8a!E@dRhefkb0YF>BbJdnNpKSn~E{K3uFtSihy5*t5_bLH;NX&SF<}Gnyd(*2JFAQ sO(+oWIf&oe>wdF)W{C0*xl7&SE64W6vjmh9xql3dP#FC(J%`Bu0Qmk@FaQ7m diff --git a/data/icons/Icon_MenuFile.png b/data/icons/Icon_MenuFile.png deleted file mode 100644 index 7d4094622736d1f0d9a848b4db5fc6ffe05789eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1444 zcmd6m`BTz)7{@<=d{YD$@(5ul)V8fvXHm@Bv<;0+Egd}4tgXJ5tLBMoDVZVQ=9N=u zr6!cn;cjWAX=&v_iY8KNo_T<&Yo(Lsg(IoC^k3{V^L}3Q%=66i%lmmUS>Ahb7!n2m zfb(!?`s&E|E`5|PU$5eS)&UXkyVn)br?5%U6$Whgpm+cbjlT;43dKa-z8(@(6%t#rfLK6W~~cDSYIsg0XtQhokN}AlKro$w2q+;Z~|)83>o5*VJZmLK}O7Bz3xZ@Y)PMq$jB~*<2B2&vh98G7gR*Czs}K)!rh9k-Oe^l}sxG(gMu0 z9NSgxPi8yp2LudtR-s(7bx z96aCD)6_8EADAA7)jivKg za?01+59qx7KgTD_h$aA#2tc|)v$B+eqZk}D&`GY}ijy#%^s`9}Ta=`j z_U*i3#WKq8RXtyiJQ{05>f=()WeWY#WIl}}bt|XYb7A~)=IhXl^)|7=P+2(x{gjxJ z0_buWS~qY}v|l5zVM5 z(46vLvLrEZYNEV{L)ORA_202wu>DH+ISJb87ualh_@t{8;B6t2iecrWVm8|qcs&JNT3>U>|?C@ zcq`)QM^k@ik3U)|(dD!A8s+a;pES^m(ZX9sA6}CZHNo zZJn1kHJj^$f^rbGkMYvHgaX7$H~!gu({P#GvlKez(1_!0y|+U&5ifbf@*;@HkIaj& z!kw{%L%m`IoyQLj#T7(&rCJvpK^OP?@#KS;D7S*YHd$b)8*~SVLqT;PF{hzx{de2X Zt^sz0$PDgnQl0M6fX5zh<^xw)@E=X-)bjuU diff --git a/data/icons/Icon_NewFile.png b/data/icons/Icon_NewFile.png deleted file mode 100644 index 0e9d05c36eb595c1b43c5111c36160db768640d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1087 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8paSs#pAc7|WO;e{|NsAi3}LZgq9_uV24}g@u)sl@~8w zoRpNbZQC|=b@kuBe}Dh}otc@Li;GK2N-8HOM^;vrkB=`SBjfVr%R6`OEGsLUJ$p72 z6VtbE-*|X<^!4@Eu3fug#fp-WlKlMqpFe*pDJiwJwRLrMWoBl&ySq=CG$}YZxS^rp z>C>n8?%mVW)HE?M;o#s13=G_}XHQB>inO$JUS6JnfPl8Pc4}&BWMt%N`J;1yAre~> z}(*&ks{s85o!%JY5_^D(1Ys{?Pljg9yWi?_6SAlse`Xm+_>CoLUy7rfsoY zzGQ)hl^gqSY4%+wS7+R?Wxb8?K{-sv%u&iczOdAqm# z{dMn4_qKAZQFO^}iU=6H#Ohb#QkIU~3S#!sx`oThS`eV9WYZc_mv!e)mPjh4t4P!a4XW zS~wUS4po^gVzRrLrf@JXl4k*H{*6LWS%!?GQcG@p|8Aspp|2va{$k_w>wmGf0-Epqz$U21wx)Xe3Lel$8{O!J%NFFnLQT2Y4UAMPWJ>UKVx6j*s^_BMC zwBdYtTgmm!t`*xKgzMkDrFN>hcaqX0891AhPj diff --git a/data/icons/Icon_OpenFile.png b/data/icons/Icon_OpenFile.png deleted file mode 100644 index a7166b5260dab69d60805e3e5c1913b920ee4e3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#Xhv z3gdIpg)5jG_#cTgwAytsoM_iz;)&v2ufLdsfmyF2q@j#S@xhkE4IQThG8P@xWH_IC zP*B5jcB9}72}LF!Z3V4$rWdr_1<&1N@n&aW7O0fe2;2S?=nDok44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pkP{nPlzj!E-x?d>FN3Z|9@?5?Su&v)YQ}>BO@O^e7Jk}?sxCrEnT`) zKtKSf?8=oZTeoiI;^JavW|otai-?HO*VlJ;cJ}e{2?`3bx3@oh`0%r5&(5Ab>+9=V zUteEYS;^1OfAZwXw6ru+kM3rm5lSUNe!&btoA3j@zmxX^Js{`l;uumf=k4`q?j{2X zwg>q$(==V!Up)E$KekCARl$=rm3{Ndr^nKY%L2E(KezFFq2EolrX>O=Lg%DsGi~}f zWd;A0PWx2{87}s%o7(uTcgK|g6_%27f2>neWxN~Sz08$6;KD9#GQLjy%^&^KA*+wZ1k^j|99(2EXo~%f*zBA;mY9Y>gTe~DWM4fvFYw^ diff --git a/data/icons/Icon_Pause.png b/data/icons/Icon_Pause.png deleted file mode 100644 index 8d46f91b78a9a64666c056fb17dc681882a4d5ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#x#m6N0T+${r3{w^yLpOQ9LrcM!W)%XZ<#i@^E_DB zy6tsBpUj!va<2sWOU)hj{pEgH@@>Oye!fp1AK7hV`{(=n`U3^|b?;7ZJ>bO6ld!;{ zk%^T_#=zr%0%Ic^hnj%TUy{(Ao*`_H;)Ni&;XZ=g3AJYD@<);T3K F0RaE&aiRbK diff --git a/data/icons/Icon_RawFile.png b/data/icons/Icon_RawFile.png deleted file mode 100644 index 1281b712a29d6ed7120907c42113ec93dab01353..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2484 zcmV;l2}|~gP)JN%h}ibw|_K;HLe=FOS+?z#8Qqv`yoKIrg7Z}^hIr2g@h zof^ge3(TtTU-l<2Anwxy?9Bj}v3s7p9#4S18L&sd9sxT&fSty!C%~*X{QSkcu%%A_$7><3$f>LSvrZW_K_c> z=R%m8Dt^soI|=czcC`ni=R!y(lZx$`mcVyUeGlKSAH&tFg$LAL_X2A_+;$iMaPJ;% zOXk*yt*)jH01yrrADhiwLu`|?lK_B7WI?e#vky2MJd5^)Gq`@8C!xmNXgI4}P8R@R zGeX;v+i_xRbTtA1QmNwOvh9LrZY%ke0G&Ik8UalWO#pz1&Y>NWItm`=>yYItou+N+?If`^A7}j)r$kRGws7_R;Kn)3VfiPPxt(3=vHrhk&0Gg8BS&<%hR2LS2Z7O}aW zlh2ncw!W(g#+OT^~bFW*5bmBO1xKSI6bAOK)3yMj0GzXSkqT0P`AL4du|C17>}fq)Nz zfDhxTU$cGm>$5`|DCyiICq{~{Yvr8H^6YCgpHOZd0O~CV@rR#1!RSx;mb#zjnWTZc{gD3-|*-9QfLQ z>C%{4m;vw%Ge8f{LkpyzdNfV~??1RtY(fg-ajhpzG2yU)*Kv&4#OyF-Y@{u|E>AJN z5BNgU;U=kz*e0hZiLKc!&m6r2jb*0|`_@`1xng!$K-*%EqFeF99?F$QY`?$B{h*YL5{12#vbES;{X7=ZVgmSKrwma`ovaa2*<+24+trw z1W*+a`9MRxo3sfcZC}-9g6iuzolZ?#MFhC5eHsreAhIpdM=ycVl_&sUIkBv+(XfQBN<~C3sz4C0G&=#Dn_A;(?I+pc`Yaj=@v|cn(?d!hs>U?QNu=KHDl3 zj7%pcF$irS)z#7kd;-MdaZQBBB}4&#z;L|&PCv1UJizQEO~natIbAp#JX@?=p5>=9 zn$ zEYwLoj64JYtmI}$n~@Zzw`o2g`f}jf7NW9m(g#666$$t(^ceu4rA7YDN#K=Ft^fdL z|NRkZGm^q|Zj%A)pU}fGQD?OeOK|U*83gCxDYcfm(N#RC|O6*AtN1 z-XPag3L^}-OjYCo9I8UV%{w<`1+W8NZ*xHj6h1;9N(&F3)1}3!93`M!807&#l?b?W zS&r@+zAh_3Aqf;d;xUs;_&fbTN-Kqh@_|xelm`G+AmIJqzpsRu!^83wJQ95mAS6&M zk;UXg(nn;4an(BD@_}-3cls^>ng;+S$Y3#C_{{|XK>Kh$%(R(nNx$ySZj8M;25S@0 zaLCFgN}LpO{X0t%$0wx~R#8%B7&eDJM9~IwdGnd|6yxR4Tq4jLP8xWjVn}k`^jjatO(&J!M4i_kkfX~H5$Ngi&3K@0=R(a=#isJ zGNXnFQjBysk)>g*c*UjO&BZM{A%9LMu#%Z2?Zxr{ph5zS0;2xDeqt9-$%ue>c9GbG z6sjE|mk)>%o5Nwla(0Te>x(cPDk8urAQEA*8tSLSf%EX36fUK-UVdgiUs&~cJnWbX zmBR%z1Vl3vWUAenxWgX!dEyqaP0wkI7qQit<|%QQN!})Jf5fs;&wv~M(r&5!@J}Dg zUs{aE^!7V%129$q05F~Z)W`l~Wb}=YW;fQ6Z^|1a^tgUKga_BOHnR`NsrM-uD1aKt zWD;X8?o!4yec<757pa2281-pK`{2l>2J%F9Y yt|!2Z{C{b8n={<|=P01f26xL$*!%am8vg?lB9J5x2`+p90000eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#m>g4=216FL1A7^C8VY88;4xu*CMwW)q2a1R za+tMD46A5_*sHk=Ce{hfWz1a-=fxCSwHUUrMINZuz7QhP7<4_=fN{cPr@g_>51A6u z9|#MSGE|=CR%9r%T^*$z(~v0Y;Vq%<#K81IXM>c`s{Pv!v6NXmJj$^3d0-yWeK6Fd zv0<$Nm4~*+#5t%lvo@btv)a{{=dk=B(Z>rXUz>(fs>OQOQf<6r7~0rsT_F9 z`?S5zyJ1ObV1_`Is)MloWv-5{Y~C%W0$YmB4qjqpP-B}XDcr{;3iLaJr>mdKI;Vst E04V}@o&W#< diff --git a/data/icons/Icon_SkipBack.png b/data/icons/Icon_SkipBack.png deleted file mode 100644 index fd217d8883eb4fa2382623fa6ed86166cb1760e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pkQEtPlzj!E-x?t|NlRbv2NYEii(OCFJ5$ZcJAN5fAZwX)z#IPE?o)= z3OaV|SY~GC!-o&GwYBHZpKoVpw_(EuNlD3`o*pSFDGd#c#>Pf}fB!vu_Uz9$djvE~ zx+KUim;q=m4say1$Q0;EPEQxdkcv5PuZQzD8HlhxV9tAd@BjbnlHcz=3JY+{udXp@ z`|Y6crABf3G7;|Sn-ap7r%z+?d0gJaKI6yMqzCgGZhutq-+6d%1FQQaKMVh(h76P3 z&nHVTtZc4c$G_xz{`6f9?@M1Ya{kxlJ#g7lSYb1FTI&J#=Ov9RI@hsny4|ruisRiJ z369rucuwR_d8whWf7%geM%U*e4KjV?T}l*?Oa!aE72#Ob(fTOb(T9 zOb)4DOmDhMR=;XtX}C3mrQufxOT)1VEKO=VzFpsGsnB@->A8&Ni?1d#TzEH;;ljpU zG9T>zY`wT;J-g-u$$!StcO@1uyi8ZwvG3#aUllxuEh--H+k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pkPRVPlzj!E-x?t|NsAPf}fB*UO=UZD_pFMjvC@9Fr#%A~K z-EMAfO-)U9c6LvmJju+=G&MDql9HM?Z(eL{EDsM4A0J;?b4)x5T}@@uj2$ea^nT97Ho;mZT!!ovwmlNxanTL z31^%ermW!<+4@^V!BW%$oRspn?c5=lR@U33qzlrYr{2JIkpSc z0*o*2cQf$31B&IlHbl+Y=uny9!u*<7k0ER)*OD{;jV{E>m0xT)E9bL#{-F!oio^W) zS^RR;`SVvSV`p5}L?yF*+cIW2P?}h#gCdMdS z*u4GJ^e2ZJly-h}t=`UlVcs15g1pmt-sgljJc%(cXFm7DjCtErnUj`{k3OH#lfE7o yX8HGe&8s{{PL3LF(^u;McGl@BZ<3XbV8}B{ue@5beK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#gTe~DWM4f_Y*eC diff --git a/data/icons/Icon_StringFile.png b/data/icons/Icon_StringFile.png deleted file mode 100644 index ac3e25f0b1b2832f5d3a7d49001670660a7e433a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1956 zcmV;V2V3}wP)qP!kUI>>wf{xTLrN z{bKHPuRPw|_vSw0-FK4TIlq5+zxn=VKFpgtznS|Gs$)(^oZRV5ht8G-RC6Hf0;@mc1!$}%M=b~uCmA*cEQ*j2DwYqIG<(*Z3+YHdSu z*3@VGoVB)U4agFK!(j#FlwFe4w&ZRJbR5|cI&SZ*8-RIf3z!l;eDn}H*mr;?OPi^* z56ubFWy~tp)}}3>&IoMw^@p6h(g0vPkaz%4Uj#jN_LdIdd`TK}qD@ho0QEr7dzV#% z0I=R`D|rU+X61Oo45uj+vG))g~e1WfT2f+>zt^KbsIpv3=hEiZ`X4=%~rI~4q(D5 zZ=Dm_jYyLh5f$=k3yG5I;y`fg$F2R%is^Ccb6WHUr+- zY9XrsqVfgN@5umQ{)L620C>wU%7;mZrU<(}IRVt30q(~=sWG@<ZiC0hlm%0@0tz2mpKJ^&OHEEec&EtjLB0pk2Rqoc?PeE!hF!#Sq^G zNU^A&qR2o#r4K|709W#_5bb|!3T6P4|^~Cb6nZE&xk6EG61b5>A9_yIayI z*!as=puDNnnk?^+JfUDR1OOFJD!{alDbe=V5diPjdu&0mNdXbD5uyq4S%Fy5QEvb` z9E&HXB@^9l2yFM$cdU{xNAU{3;>;>)LSfI{$1rAqPz8>Va4!&h;}A!?w&T;Cx&x{H zyIL*bqsNa#_uLIN10wfEa_0vaKFvBgccNB-q5x=%UfIJkXg|I^G+ox5ixE3`P!=l5 zK)UO12JppDT0Z?I%WJk5_j&j4d$9qyRZ&b8O1YQ<6F-{>YqP>3?|wctMmT!vuYUl0 zuI;6M&hG+ELR+x`$Su#M3b7b}IYK*nYG?o<=jg|6i7APqyFe;{l;TvK0c_j3P33Y# zp8zHw@u7Y$EQBK&0US`q>I^{Gbol5WfWuBF(SBJtS%@x#Y5?#_uCC_tv5Uq{M?(U@ z^@msi=Q-1pi|P48AMF66RKkR-nPJrJo4KMM==8M zJmDp2@VR-pLdmJ=rKE-ipy?#b+|itSfrAME_T2?BOoPXFcuwP-$N&`L1JDNm@8n6M z{dD(r=i++(*q04}bNpbYH$?*11q%Otv3CY}$A>Jm8shNr!&(8Pmu67&TYYFH0Khj^ z6_rn@asDg)xj55xZP)q qz^nTE!Ny;XzN)_=Zv6Fl9s38doYcpk*+I4d0000XK=wYX)XIO1+3d$?c-oD`5h#s3$yuL2JaA{9QCZLTUC6kFR=Rse;*31w8^X^+? z;{bEz$*m|WzTiVclcE@+iN$O5@&1O!0xqv235}3Q=Br+&c=;&P>1`vUor!2L&anL4 zmRMSr`0ZO;a|_{R4cOS=Uc9t7^$DPlo3J@GbUJxxn2alkymlQ>zUpMr8 zjP3mdAdxKLi(`Ag>>K`m_{L3;kCQ!!BfV1)iU!*|!l!3_R{0GQiC~#YT3Ecx<`hAY zV01L&`>5&CGFl|!e`<~HryO8RIY_0O_3yCQJizBSW@d#vcnGGZ5lAmJJOK!WT?ix? z9MYYbw1FV{1Y?jsVan%sdwOpV`U~)Q4KcBHj7gU|QdmzfNhst$!$s89%YSZH#}$IK zbmOd?t6kl-HLspLD*zu`RU4X4i^Z#Tq}-HLFuxEk6!kGzGFa?qO-)6~7*Ih(u{rpJ zB(Tb_dsCa))_!GnE{MykE+)irxMi4!KG|5X%*6NyXcMbsrF@5Cp# zy1Ic+WVPIU@ahfF8@{qr7SoyANH;LSvOal?QOkci`djlPCGp`xA3^q zK>NVyWDiyJZ)YVshPjm?1@n3)L5Esi)K!fF6^n4914qQ4@3^}(3%1DSCt>4NYuITYwd(Ry}2Z1l<0K zV(F};!v}kQZ2i#N?bcd!L%6g5V+v8=|2BqU?07<6snyM}u`|>zp=?BF|LL`k`aUpZ zzF5UldlbgWkS5fs4?EQCFKal)2q@I>$_8nC$DoV zL>gdaU{QU}#T5?|RVwg1n9B#Fc5S<+=15*LFw*Zmbs0yIn``&8xY`;%K;!Rn;{?Ne zP0BBp9@pH1tTue~9wRaxPG7jcsBA=T{!_cDnRpDN!1`Ee)oNDA%(-CWN84phxKG8X zbjU5`*{ar}O!bb#K6b|0*AH4MWa?DG)mA*m)*vsRlXzkU7I>M^RHk&l>q zjnU}>q_vCl{_w1Dc*3tQ-j};fiGyv_jd1*` VYKm*Nhl#A?z}dmg{z0YLx& diff --git a/data/icons/Icon_Tree.png b/data/icons/Icon_Tree.png deleted file mode 100644 index d3d29b1349c3e11f9f928936a8d1ec416eba38c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#iaG zUKO7xFjw|~fDEJ9gQx=nY+biQdF~6b>FgIccaz1No#B6WiKNie>ghnAFnGH9xvXwbLRKB!UuYZLtq6wWqdXgi`yyRVJ!xZN)kULtA2~ zp(s^qi=}ZyE2z?9icC8H#k_OwyXT(w;eELG+)M|1YXM$qUH||DP)G!Z#pXZ2&Bof5 z-N_6Vf$$h>IA~#1D~Tm|!jZ0c0N@k-0T4hWNdf@)f`cvAl68!UiHVDgBM=BVIXQK8 zbrcF^c6OFVqcIqafq{YA+S=^w?A+Yko}QkAg99d$xxc^P(a|wBHrChIM4tgNhwiAh32!twF3gM$M>%LS65dH3k&u2^+Q8LwY9aOP$&ol;^pNH z4-YpqG>ngr-`d(*Sy|E4)C>*|?(gqcQBjGGj(+_3@$1*G%gV|c8X7b-G^VGgdwYAm zyu9#ud__ftgoK2!urN0_x1*zDW@e_5kx^4q69fWrb93|d_NG#)jg5_#mX=*zU0hsT zySuwYB2h<2XK-+EV`GC(rzFN3V`_IhGJb3WH%F0SaLMVl9Cc#UETTld0$`O(b3Vgv@|ptJvTQuH8rKCrgnOIdUke(!C>0j z+Td`wjg8ID&Q5W0v6-2fg@r|AWTcFYjHsxnxw$zQ494Mb5Ve3~mSJsoG4@UX%k2Nt zjQ!nM4*+atD1-$zmb6ozq*dxDInw{8?$oVF%(?SCBP$@L*v?&hy5KhV6@d!ajAc=g z#x|Y!b~k`b&M9j~O#D;bq=)dZn{ItNx7hNuLSKw3+0=dTa(8wZZRy@jrRU>U=p!d2 z{G%gNIu-2=fA}c8xBUvcZOk#Z?}|g1OteA>;`t@4GhOIu&a&-DV}G z4AvojzmWi=t%UUhZBlQ$$JIiS*Y#9Ck)*w^SEc=GZ+1s3EjL``)10ehm2RaIK)S~5 z!F+phAdl0>>V+0A$WCs+H%Nkn-Wsh1My@Hr;b9BEqYQ%O1LfoorCsdby@IyfO%fR( z(#g~0-GL7c1ajqsd13b#oB(?xgZLyg&k!8H>9tY$n+(~V9Ye5rCITA5 zf+$}-RWlsG)qkvDs}EB9nYS0gh~<54_|#QJ%tsF`us0*>%~}#?@MdF>;U(>vIGnM8 z_(P)NKUNOc3NTqAHz>Tq=5Ciiw88~kl7_$8G{%%{n+g)!oNmgBv>-M*aDvMFksCb1 zgm#X#ISTNdFS)=t>SppJL~i-svIz2}WFlf7{wXc4S(zZ)MeZ!>kyVoVIK0o5&^e-5 zv)yZlyx1Q#!Z{A(`X>ITa~3eyWGlHGY=&Fi=RuDjwzblBT(R7@s%V7gS}v45sHdCa zDgn+uxK06~8n1#Kn*Ogv6TJ3Tc zTL`uDsWhdiAyeG-eJUc!jtop`y>UW^jr1L;O4O<Zb?Gc)HMSiRAy(CLdLuJYT5 VaWT(Y1z9x!pe*eXEpYFYe*r*6T>=0A diff --git a/data/icons/Icon_WAVFile.png b/data/icons/Icon_WAVFile.png deleted file mode 100644 index f7e43e8958c78074b45b24f627f5fb9c79d42629..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2550 zcmVo{s`?O+klKVlwa^C;Ehwc3LLX=WAsP@rLP4lP zrAbw_5)hiUN$fZ{_S%rdKe6%J8#`J5FlX*~_uiRrzB%X2 z%m%@Q7@XaBKPPv8gYJyG4J86h487mr?&p>Q?v{~vL-u=10o86mwXsD&wHr`vY!Tqj zc<|vEeCesqQhMYw+sZy<&qt!#J&%2%-B|ad4>V|XovD9Eo${oA1j-Ze^fO5~_GD)%o%l%_QuqE9a_|>p<6e9@quukZ<0*(|-V*nm zA$5QDYrU>BJ$oW5?)jrgGul1j`XHQmDNXDDFlN`E)arlr=`Q&4H@dXCPku8AyY~-? zx_^Ro@i7t*3Q?8@2j|51&&AExNm*-K2)cXkA^G9(TjKjS;+`9&yi9)`#9M1AgEsc= zO+X;AnOL<6u7aAJsp`&A4@jV-$VzbrN4VcW{X79;lI>q+{EW>gsuQ$WL zXKd`6eWlvW5J0JpM#J{i5-F>X@OD%Ypw!Wmrb=-moyHE`hDGslB0F}At)EI+_NHJf z4cpTgql2=#x&{*yQ}%!HQa)+@;vyxWzFsm)MQZaU-4Xu&-`t z`D3Fd0^01We|x?|jebCc!7ZhHUkZpsWG4!wj8nk!@+~oEt>@H>kAxou^!7>u=Cu6m zI6noFNu7YMl!<_=_ElWVC#_#vq&A>Z1t|H41mDW2-U$KYS9k?5HMQS=#-0Noh*vjHXocm+rspcG&tKq^3wYkVmn5|KubP618~%DpoED4lMzfN<%rq@B>8uYkNZ@>VvZ^x9JWTTvoiuO|GppoaC#@~e=t_e zs|$M(5H97V`|g2Ykj5Bp^!F!4EP(ZN0%m7cg>9jO<2HgO8=w?W&IT}XfSdw{4-dk_ z2b$nxpJ;%iUk{2P=XnT5W=VZD1rz~2Y3~?7qP8{!i3D2dSuGYojE+zhM5Fa07;1p> zHozwVoEN|V1+imCTPbhXuB7<>hbS8(^*I}m>Y*buH8n@_5IsE!@x9K(0$z5YPz;7R z1uQHq!Th}StWbFZ%nHb4;#yuj9uqczHfnM4rhVm%0qDpK4^P0{T#n>h(H&x5%O5uq zU=7ShXaTmxL!^9kRE~ZaBA|!Kz5*c`3HJ5rtGvFxEZ%@b+uwC859;*cOe+Isvt>$^8&pYDou>ely%mh zYr*Xayj@``#jKdX83o2k8RG`INH7fBx2H%xN>#-Oj%P47fD2Kv^V#ea$v4LW-U>*i z_^{j*1tNTTfmkeBl)D?4r(y)>Go%f$$}k4#=%P~vJI^V=7!Dg0Aj9EglFomG$pavK zDFCr^XE(`10@O-TK^Z}7)KUIi3}CVWCIzglti!ddlmtmYcQ?NeP|+0NyZ~ZgAVczS z3dkVI2}OWK4rc&yd5WFq6o9H~Z^u}Gx=Bt2atb7qQMT=)qyMt6d=P+(xSM%O0!M&l z1UUuhHh^0LOioT0|Bj6OlWnx6f`YGDprxg;*p5`HnUvukz}lLn>IOev0Fh%n!N5S8 z%2)dz+UtADC zJEfvQf1Y4)a6lMZ+8w0;Dt`n^z#_9Gt_1E-n41E)zSy_#!^N}#)I*pQFlJD|{r3;B z`Cc9XVNk%Got8@@SR)89#Q;w{@hN!iweN}aX*hU@O4p=->sJd!cj(5RJs)7(vZ*P+ zZHo8>?gieyZEc){#RolrpM3x~OayF*vEjDJ)z-ZZX>2Q+0(U}yTz2B_YmNB$*#_f) zZmqSo3ET@Jgvk)Pft$0}uF3oPBR<{+FmBKZ73)*va&rD#dkB6vLO58iumE|;YxyQa z=!Wt%A&5bYt-~w8!wX;p_v))>jpZZ?WcC64LWaa^K9|LAl=A=x!xS(RaOu(nT)04Y zfh6*IcNDmJ1sJ!;eJVf^U_RllSOG&rSr{IsXN2lroq+EDf&%=;0&aM1gh&|NpxFjs z=aB>x+%Z7!|3U%2r+|4GEKzYJh*Q9?0x$;XH0;y+foW$bx3C6tH~8%@C%pCnBr1*s zarCj1lautM*t%CK0M`JUi2)?~`{gDKT^4ie2RANXmMhH)3Ggz4=g(g${v96XU7^zp zY&Hgvz*qoxp7D&pjdIgqdU{?&j221t&}OVxkqyA8>eekQ%DX(olcXttISW9XJ$nhx zoH?f@lU=da1T+>fofS$b56}R$V4jACDZqD5HL^tzz>k2_25_rD#Gyl95sRQBB7Iw= z=Zfj^$A8P#l_BvOIV12^K)E%5L`9)68bAvP7#Zdp;8XzjQx*M}8iz%EcBGhQ#vWpy z*V`)%p*tAztAI@qfL4~n(9pPjB?uTQZv(g(Kv`z}ml~!HnHELmY``56fct{nN$kao zatb71dTN#3%F-0T!~mw?1edr|*Xi-QDHtl}1^fg-2;(nB-7mmpuJix^R-?|pOI0v3 zB7d`22k|z#Pk-*5{D~SJnYaITljJ25GK|#;SXITHx%97O>+|1{b)I$A*)HaH z96p%7V3!{(mNzy&WGeu@!+qqPzx&m^UH`|$`j`$LJZ6{DKpZPq`GxPlL`D8G>J#cy^dH{g) zq|=xhrhb7gs_Dh`sS6rHVwfIo$Z+?O6ph%)rJs!f*k$wu2owqlnuDi|Q!IDQa)JlT z&teo3-fZE~`N~sEjj@Y$k=xtbt8wCn4ZK^ex~(#M z(;)|mJX0*~>e|53qqn6|_J=3J8jvKHnnQAq8ot(UJ?FqvS@-(qBNnBanQCn}{dRJD z6i;H%kKchCPs|#C#V`>DOGYckI6fq00TRMnIJ|&KPoWXa2R8QI(R&y#TPJWUX~fQ< z;CkZtFg;VDo&Q_N-#YC3YSz>tRE%eti3p_U2^q+Kv$-*zo&A#C!D0_P>gK+iUJM+i zMJsI1_C3?3gL)sC;!n#XMHdZa&*}COB~}=oSm3%u$-iO0w~uHLY$K673d1`R-h^1A zQ79pjNQ^Hx9q(^2>yLBl^9AQcmuyHb>HTh@X$A$eQwYkN!>0S*xoflb*n?Ixt|ojK}P#8E4~1B|_{qQ0of z$fKTA7TYpyWKhQNzxEC=H{X-7#Oh*q&L3tGuIG`;9OpRoGeK3mCBpy87y=i~BajyLbyHJO9 From 2495fbfdef11a9f09d02cd20f4be58b08c253f38 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:09:30 -0400 Subject: [PATCH 06/32] Only keep non-generated png files. --- data/icons/Icon_Animation.png | Bin 1958 -> 0 bytes data/icons/Icon_BSP.png | Bin 2233 -> 0 bytes data/icons/Icon_ColMapSp.png | Bin 2483 -> 0 bytes data/icons/Icon_Copy.png | Bin 0 -> 316 bytes data/icons/Icon_Cut.png | Bin 0 -> 1100 bytes data/icons/Icon_Destructible.png | Bin 2138 -> 0 bytes data/icons/Icon_Editor.png | Bin 0 -> 210 bytes data/icons/Icon_Effect.png | Bin 1563 -> 0 bytes data/icons/Icon_FXMap.png | Bin 1804 -> 0 bytes data/icons/Icon_Find.png | Bin 0 -> 1337 bytes data/icons/Icon_Font.png | Bin 1144 -> 0 bytes data/icons/Icon_GameMapSp.png | Bin 2601 -> 0 bytes data/icons/Icon_Image.png | Bin 1884 -> 0 bytes data/icons/Icon_LightDef.png | Bin 1218 -> 0 bytes data/icons/Icon_Material.png | Bin 1916 -> 0 bytes data/icons/Icon_Model.png | Bin 1931 -> 0 bytes data/icons/Icon_NewFile.png | Bin 0 -> 1087 bytes data/icons/Icon_OpenFile.png | Bin 0 -> 317 bytes data/icons/Icon_PC.png | Bin 1710 -> 0 bytes data/icons/Icon_Paste.png | Bin 0 -> 537 bytes data/icons/Icon_Pause.png | Bin 0 -> 213 bytes data/icons/Icon_PhysPreset.png | Bin 1585 -> 0 bytes data/icons/Icon_Play.png | Bin 0 -> 318 bytes data/icons/Icon_Playstation.png | Bin 1751 -> 0 bytes data/icons/Icon_Save.png | Bin 0 -> 371 bytes data/icons/Icon_SkipBack.png | Bin 0 -> 488 bytes data/icons/Icon_SkipForward.png | Bin 0 -> 532 bytes data/icons/Icon_Sound.png | Bin 1848 -> 0 bytes data/icons/Icon_Stop.png | Bin 0 -> 195 bytes data/icons/Icon_StringTable.png | Bin 1964 -> 0 bytes data/icons/Icon_Tree.png | Bin 0 -> 321 bytes data/icons/Icon_Views.png | Bin 0 -> 1650 bytes data/icons/Icon_Weapon.png | Bin 1880 -> 0 bytes data/icons/Icon_Wii.png | Bin 1509 -> 0 bytes data/icons/Icon_WiiU.png | Bin 1821 -> 0 bytes data/icons/Icon_Xbox.png | Bin 2123 -> 0 bytes data/obj/diffusemap.png | Bin 6211 -> 0 bytes data/obj/normalmap.png | Bin 146 -> 0 bytes 38 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 data/icons/Icon_Animation.png delete mode 100644 data/icons/Icon_BSP.png delete mode 100644 data/icons/Icon_ColMapSp.png create mode 100644 data/icons/Icon_Copy.png create mode 100644 data/icons/Icon_Cut.png delete mode 100644 data/icons/Icon_Destructible.png create mode 100644 data/icons/Icon_Editor.png delete mode 100644 data/icons/Icon_Effect.png delete mode 100644 data/icons/Icon_FXMap.png create mode 100644 data/icons/Icon_Find.png delete mode 100644 data/icons/Icon_Font.png delete mode 100644 data/icons/Icon_GameMapSp.png delete mode 100644 data/icons/Icon_Image.png delete mode 100644 data/icons/Icon_LightDef.png delete mode 100644 data/icons/Icon_Material.png delete mode 100644 data/icons/Icon_Model.png create mode 100644 data/icons/Icon_NewFile.png create mode 100644 data/icons/Icon_OpenFile.png delete mode 100644 data/icons/Icon_PC.png create mode 100644 data/icons/Icon_Paste.png create mode 100644 data/icons/Icon_Pause.png delete mode 100644 data/icons/Icon_PhysPreset.png create mode 100644 data/icons/Icon_Play.png delete mode 100644 data/icons/Icon_Playstation.png create mode 100644 data/icons/Icon_Save.png create mode 100644 data/icons/Icon_SkipBack.png create mode 100644 data/icons/Icon_SkipForward.png delete mode 100644 data/icons/Icon_Sound.png create mode 100644 data/icons/Icon_Stop.png delete mode 100644 data/icons/Icon_StringTable.png create mode 100644 data/icons/Icon_Tree.png create mode 100644 data/icons/Icon_Views.png delete mode 100644 data/icons/Icon_Weapon.png delete mode 100644 data/icons/Icon_Wii.png delete mode 100644 data/icons/Icon_WiiU.png delete mode 100644 data/icons/Icon_Xbox.png delete mode 100644 data/obj/diffusemap.png delete mode 100644 data/obj/normalmap.png diff --git a/data/icons/Icon_Animation.png b/data/icons/Icon_Animation.png deleted file mode 100644 index 0dc0e31c8efbdb25ba5146a241cd6a67f1ab7372..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1958 zcmV;X2U+-uP)I&0P-q0x;pBx#AH+PU^*D>oto13mhrs zNBx^mBKe*KqSI!uX9zi?Ii$APZL$P1Srl5Zd=Xv8m%xhV`m0{K5&3La8WewY19fFf*J~H zgl*XpP?YQDwpDM{nHD6#Zs4L&suXxPdx7u*)z;?TLoF#Q*b=bKxtZHmxT#Ppn5GpE zRs)ws;9vlVfm%-cTsx)g*b-3V+RkmORcf`ug7^!aI(CXVa9Qw{({^W>lpR|F%JWLN zZ51BfKg7fdsM}Ge6?%Gv`>;@1Ua3EuTuzMzwNiF03Gh0KE!R_-M`v4X1pojV>Ke2{ z>~HZ-R(7UW$oD#mq2yOe*|8+R=iFv%z+dYJ#C#wC!0mFQZGRh(nGi7T1PY#(wqr>^ zO&(tYlW4AQ)(V1-5CB^Cw`iI?G9uhZ#7@0ik+xw;K(({n)_@^}64GY)fpA#3kBA-F z^$*w(V3t5NL3?glDFprlKcL&Oa@agr60jxDLtIZxPhfI-lBhGhv4j+^rXTRv`hkf2 z1}F(j0xFy&qvKQK7@r;|@7b*TiD|jbjj?{G=A`M5VqABndF~^BLm!E63CB%O#-DK{MJF?!wjRRjR(IphznS zhQ&!3;c#uv${UhdKTh0O{W7#g7J(pd)4k!VKk zsbCV|chZ__$X_WilpvMB?Q(09W<$Wxogu2u*hfg9??zun?WtfAQ0LrA)fw_vT7tP{ zdMf)ApSH8J$n?y`=cK+J9%5rL=5hiwUp0S!Uf33s09Gd0kUx(H(ZzA9eczM&w1SNi zoWFElcyLx=EhhlDJ$zfr4wC>@Ud@od(ozg9-lN(LDYOZTJ9|5&2FSzc#3-|#wal!* zJQ_1gAfP8R0pO_;;BmU!whCP}Y@{&Q8^pIu-@%>dk{YNPgONcTefcO=-`U%#1zLh& z&VUMMDOGpkwG-N>`c<6RdYEe8Qnp1a%-F~H1Ebf42gpO{0)5P-CR7A_gHm>w1f-K# zFfzmfo57)}3=;v+He}J6zlb`+FXW2bp$M?c1oKelDbu7-AROo%`CZyR3w@*g#I>>h z3&d?u1Xvx0+QFyzv>9M?=n))i$K+CG=`a9@&5@4Kkm^n1Q-C7C>M+y}GKZxXX0N6F zoFu*p|6r8Wgu3Dv@`Zl(0Dz$aR)?W>kU1@F$p+;oYk`Ej?LbTnjpfkGuT0gqNT|y5J#joJK<=4~NcdQnO8NkZ~ z0|4^rL9)VPED1~v zgUw)t#fB8d7lj7U8E41!YXyP;vjnOMRoh$uOai(V>GOSqfTd-j0R+_>RF-)yK@bpL zAYbU>m5W-z1;EYTUA50#BCeCU!;Z*r)Qg?#ImfgSoFJ1Vm;bzMlsghPh3zEKpSVL@ zs|l6sm~+q(CAeu4yhSM_B+&q` zAcbU<*bfqZJTod#_s6xt_Px)3zcRXpPeR;x?|J8aK0fE(d(M4M;Cm2_ g-7ZSoR z9$GFIUlbU^+F$l>K7`QcOaN9q00ulb-+VMa2Ua{_#Q-Y?SZ)H#4MThp{ZW+aLauQ= z0APAy5-0romxBfXAc60RTm@S5hLD|XlXde)nNR zNtvcMn{Z%$Ki03O$CUDFzu1mFBjw1=jV-5n4lo%_II`miaFWBw2wNuIz@hQ+)|ek2 z0BT;S!B3~_;OW-N3Ml(_85#|*!*e>eoGz1~)nY~M4{LGzBp{0Pc%`KlmQ_|+x~hL% z4bIKs$`$Rrs>-Wizh#H#jI@kytAL}_0gMBEp2+@m1BcQKhipAoixssyYcYG8ZA_)8 zeW4cU00ehCGmV=|hsyL30urIQ!ztOY!5UAh`z;}aVJ0JFEqb-IC*y`)BCQ{g5c z0Q6ne&MWV+JOFff0y-NY!;(Q7gXG@^<5tzW3i1jfbZJ3mdM0VyqQ_+I1l#}Gj;Wcc z#p~3RRFsvJQF11uiNxEu7XTJ_d(rUpcyO%c7YhubT?$%^LX zD0RSOq~{x3cF+sQX&tf*@aj9S!ae8)wg5;beTTnt7&Z19N;WGk3tqn$q6nlIQmOH4 z1J|&5-)3@A2skH-@$PsxzGdbq*}Qdma1XjAXYgoV&SOpt?HYnDoen#Dj-ALxK~V^B zJiu=yf9EZ~W6I>MBk?vn3z!mV16;m#nKW_$eix9P4YUf!n7V9_k`E$f02Z%PlT9&s zMe9;M2l(f`2rNiX(eX%wTWVes+t725o}n)PlNf7);kr_Ymjgue(v%Gb7Q~oqd`jZO zR9|We?G*s9cbJ5Q=LCSOkz-kFmGKfj^HDp`kT*p`lL6vwZ)X;!slJl$mcagw9qw87 z?K{F|uFRonT*oA88l? zlL;7|yD95F+Zr2w`E)%F8M-y6!P{2vX7-0dGdVf3UsnV45A~BqaEUuN{g$Hp`FtKX zwhob%Kn03YUD&yXZGiC542Nz-Q86H*v9*z01eY!UycZ+0!-^6jTeb~vm%NSgL*?Lq z7F$+rXof>K4_JJN5hw`T)&Aq|hl+KTm6XAi=Zag-l8ZaS9nuJfW;k>+fYoBf;TI1B z$&n9f5gKFe7^P78gG%5mFfgEC&NZEgn8LAID3R1*kb! zjp5N@rc9(RNJXunG*JpOqv&P{fp+*GCL z`K-_c0Bj@wco{`$O$J~UJwtFk;X?Tu`U7=zb>r^|Zfb%Y2&m73I36)irei_VGMKUI zQN{OErdDG1Bwd?JO-$25MKx3#AScO=jbEdu*4tyZ0Ra8}e&&6SQU~lgc6g({@M6mj zN_I>bQ%g@aWQD+<=l7s;rV>duU{x@kjCbPeo@dwmLM5^0wr0E~G~lJj>+qe`#mIe_ zUJgI?eM%ZC-CGW18Gv;PB!!!!OGOZ=RM={|6Z4$>&pL@6$GGk{OA@~GC<7>&w0wdOO>Z=z_!q^bg9rG{Y}rd< z8x9OPaYJB-gQv%X?JsX9DXfuBVWWBZ1RwK-2c@81m0cus2+VhCm@os_BK_f`kvHSO z)8ZB&czE2{+PGM^MY5ZD%r5n`D}#>0r_c_@mQCK9aP>j0^!WaYja?f(w4IYgm;P z z`Rc|03seDrKj|YcK={rOV9^4g!onH(nRoy!TEHR!3!VU#yaqM?k4nd zRo`2uf$24glyFd>a!!M^N=cj$C9r!3eblTN2*GGrCk!xvi@ORUO$#NTAo- z7+rxM#vJfJU$|3=^Svd^&g8_^AjMFis7|!jitVfZf@Mn#qVoT=RO0$n3A9?KDnFQ0 zAWUUK{@P>2#{)px>MXpP*@dG=>2+gu8%57Q@a3Yk6liRe)@P2)6Fm=o8%M1Zp|;@1 zYbuD32Y{Ed4j{>0!_*T9CIQ*8A5fJDFeVuBo4gvl^NzeCV}cRpC=)JSqQ8&UTCpUQ zK5Ron;^!U4k0oURV0T^tQq+e~S0~>uNdl6>55g3=Q?`NKc?I}Uj8&1cUC$Q660VCf@+~IUl*yC@Xhx-!I{^nb6k8mXjo4oxWI6hXCNWufBn%CZM~UEtg_S0RT8C zeoC)dr$|?_{wIp$40;1zFZwm=>ga?Epb`+Fwje1YOOYY~NJ&mbuGxa)$Juh3>o))Z zTrTpRUb9A4PqfymX!HfVV9CeO5YW;hEkh+>?F!|iFTlF972W*s?hn0A%M}nlY2`1BtpqMLK5Fub*!H8HR?Wrze$w z7+qS>isZb!fUTSOQ4I9#QQ8zmI%d-^v(XFylKmnGkXnv9I@_`1z*g)nD?&$SJGC)O z#&$_BFCcj}KZ=3VAV#-Ay23+*sZ7*oQG6wOjr$o?sotR0S3)R zLWuKlD0-s+r|iwJja1>wy9Mz6msFOXoWWEE0BP&eL^5G2lOo3!q0S`A8csK$=#P5< z0N;$fiF18#5i(khmf0tQ0AXJpi2AQiz&_xBMg#2M4``M<;21tZ$b~NpXDSmqv}cpm zzZ5E+|6!q#MA_BrR{#K6S-^`g0`}oIF*eyx$mN+;|QS+M~7dLu*V+Y zItV%4LjuOfCBEVzwr<)6kB4_m;p#-Tu)klVmE7oY0s!LUr^{@8{}9P=9uBAM%>d{t z6hVM)$uoq|XJ1znif*~92|1ls2LO_63y6*8Nw(W(=h+1aQ!X;VINArw@L_8R_Wd;k zPv?XnV#hK7fJOu8^<*2e;V|dnU?1S^)nuA3pYS;_ImL+_lTOPklOtel(pmugN}$xU zdwnBB*_O?@zz6)4OHLNQ%g*M1av&{09W8nmJgY_nBE-DowuzqYPTsZ4O#xxaG>1zE zKr`W;x<_rNwZevwdlp4)&>(98eS^IKfTc^xclA!5;-g2!>ulguk;1NL3y~P3Z2kkl z#MBVAJS905pS^VwpVU{PE3|}a<}4`A2(cP|<(1%+0(@W;vocn({DhD6?tv(N{s1_S z75_f_H;hJ`iBmS_f21kytF|z0<6(knAxg1BcOkz3wo$D?mf(k(UKpAe1Fj71-AeX0@Qvyz&Ym$6-;p%zC?bJK7 zgCc>Ir!9jRk3^|Nek2GlmPpH12=Ay&W`09 zSZE(8L#=ZqzWAmR+_N`3T95kHOn{J5qAeptD0|P0(o!(j-78&WB8BA} zf`QHZ96I`IiE<(TK!dCWXf;}xqfA7IOG{F^Ile9{C3gI*IFX`s{+m}E!p7(d|IfVQ z5LNEm;m;-8piKcH8l0SR6GCamOxVvkz;V+#0a`B4&GB_DRY-k0{l;}IugSjT!ak_iItPhKa440;2O z9j=A%t_2ZKS@GPeT52lmQYXLPWK98pkL}O*mf*@n2~3+E$j|39&MXX$+lexR-hkE$ z8%Db<2veDm6IUa;mE!*<_kGEB2_MkQRbg_fg80Cc{J40x6_|JR!TrHaJgr{R0=y#TED0S40?j!m_g;noE+o^hDyMM&jH5}ds`WZ zj?Q-f@l)WM{HSqx;G>}H$gMJx!BE$*%zc*t{ORMv006U@oj(7r81Xg-H82gQ8~o-k zwaQ2maC5X=k+M%u)cUuw`T2_bHfx;eDOHpf>mTe#*?Xk`#D}^w!3>AxlsUVd{`2{5 z+aP&s^ig8M=Ro6)*JR~>b@(;d2ONluWDg9JfC--i$FCQm=RSEOq~&4@%*Fiei}-l{ zd_E98ZgGaE?W)Y>Apm#XVm(q@*j}y*|FRe1zK0wfXSWl3%ZmI~`SQ!`RY~@)uz*M$ zgs(3H6K+0y6%?eWvya9a8zH(rmz4!rt!!Q8<>D(e`T5ctCc}e67;`0JYLefHe)wfM z0De#k3+1g+F#!TPJEy~4vw3dJUJ2UTrgIkY@#Jy26oMw;NyB4xGW305k%0N`zeK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#flK9sE~8?@6fQ-kg{uXb8doQ9vS=}!RH$Ha;AA`T zp^4ie=H#kt4B`)>7?N5K<~p*52rA6k%sGvZ;Zk44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8paPu$pAc7|WO;e{|NsAijEahi+S=N#uC6Uxw%ose-`?K7x3~A_&z~nw zoLIbgadmZdU0vP9ix;`Lxc>b4)85{mn3ycg;o0~T_HeR@JfsKtV zGBUEVvhv-#cMl&vjE#-8v9Zz7(Q$Qkt*@`2IB{Y@LBag_^QTRl#=*g%udnay?CkIF z|KPy`Nl8f&5s_1;PF=ZjMNm*MFE6jDsma5`eQ+E`S~g;DyF8U z-@ku<^5jW;e0*7186zX(>({UO`T6(n-=CJ2wrJ6!d-v|0Idg`Slhf1FQ%y}RG&I!0 z!a`bFIyW~rI5^nO&TgrL{xe`OrIZBu1v3DHjMkt;-M*E9fyvX;#WAE}&fDpCy`>#R zjy_*-sVn05f&f-mmq5qd6=6=RTU-QGl_GSGvi~=aXVDDeo}@H2N@JlykjqPF-Ci+~ zKMamvJSXO)e^a)$zPWR=XV%As%$u!?&(D!BFHhIgk;qSYYI^!}7>CC7cM4kUAxYwI z?H~9tC?&M&@roW|wE9_>I^|# zE%BQtiZs1reZ_dNeSweyV;N3lk5X%Ts8i7z<8Q$DX;)DmgNM6E z@H0*a(L84N4Gs^QBmuj)QJz0`h5 zxTYiH6?NAFsR+reO+SUVzMr2T)Wnn!yMM-=xQDT;>RLra7^?T`te<^q!_Dn%j<&t| zc5xzY&*$HGFfB0Pwd3m(lZ-1S#UvGX3$`rkx?;EKFHbhJbdDT%V9TRPX2HSjhyT7_ zJ~QJ`?VtD`&l$F+OuP2)*!;M1& literal 0 HcmV?d00001 diff --git a/data/icons/Icon_Destructible.png b/data/icons/Icon_Destructible.png deleted file mode 100644 index 06f5eb11ff51da2fb39831f3d2adeccb59163dde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2138 zcmV-g2&MOlP){n?+Dz(?CV`2G37KgVMRb^`4Wb0AQ`e9>;mZsx1_H|p z!h#Cn^3l+-KQ4RS-FxoG?!A_f@ccUWocFxv?6dDV?|a^JZx~a%9|5=-Sn)kWnD4_K zQ#Fh43Uof@@B2URh4*)c0W%f=9ez0fd?0QDGZrvIzzhLXJ%Oo)PG01@iySH*KZ#D_ zpI`017_<%n0Y}pcu`p_`WGBz~Fiv?|6%D9F9|^mhRj3&3B(`Nn#NZF}ek#!WL|i&v zJN553rc#q4LS!!TI{@U|Cj;Dsgmm`8^ghtDv8Cr(~C( zui1dzY&@K&Ps^%Ty$M>(DLB00PjHu%s8uD4-HA&O7j94_yYq$ZNUd#=wFFJPz}m;w zAeXYhdF+@L>WE0tMPPM8hGKb2PvMQCeLz{6q;+cM26t>M0;;Rg-`}s5N_rhe#nYS45{Ca^)CSqho}{38VJb^7Ag{S z5g~h%oCk6M0B(na*sdu7>G!5d4i+kwQSl-7wU|?oYFq%+*Av?nMS|u3ID(z}w~TqNe36uzWf2RU~p-PT`<^7mP8qpB$y9@bm*~aH!!E<@zEc$wCXF zfCUAhtybKn6K;Ne{e5`w*SXw7Ru)!!&f!>35|$^V3uG;(6aav`s|!q8nqON`X93z~ zLu_m;t^g<iuB3BFe_Y8ceeK2q!Jp;rcD5VcRWo* z0(cAz2&zKf14;*4;Tazm)JGYj005&-XQ-+bfnP#aD__?*b_2(*UJ}T*yT2CIqv|wx z;d%!O=lTaH_ry=StI<(4s{LRfECDakflFwI%Yhv(2N#qDx@6ja$pR_~_-5iif;t0r z7gx|QAQ~o&vnuCN^G= zsjBEx6#+LU#>E>ow1A%RZ;18ASR?knxCb@!3-J_75oP3{c}9rR%TMHmwa;VSupP7J zGnlOxxyIKVeZFj;+m{p_840gTFkUf{EBA{)2P)&DvOp@3$F@}zjYe99jm{U+{e+BN6lK)RW;CAEuwT__s z*p}F^b>S+w%gRJ$rVRlH`YvJQzruJx4!^K(2I}ht$yG0=4FNq9W2op6hPiUcOurww zY1zQ1pAy?u5pZvKw3_Zg8bCoy1}HWuK;bC;`vCc%4d7$9Vb zH79@_QJ)U0`?6lL{kh9k*yXH3V|%kAeT;?S3WV51^FW9vK(7~-$=i_6B}C-FFrrNr zgPo{AC#=pIyl7eq+x^k z#cwPR!IB`6gwc8rFoj16>aKcv)u;>^RkK;F>N<(`>sJMB##p0hKUEe$%GC|ClP5Qo z|Ew=|Cob`OmO3nzUu(h6yG2sygp`;n0x}7g6<2z@xq^ZvpaiR3lgEe_@b==01zqR!sHSn z0C0)*pklBSjbk^6?cS8wTL<4pNq;}KGdASRNx{;)lLfN;#!UEA6cHeo!0@8o^)*`i zE&~8)LIyS%eU7gh@aNM9fTSdJWLzUIH*ZR8uZ%8d`(%oquq-u=1kYSJ!xfT}1XobO z!tm`KTvEj0K;uxiDqT&^OZ>b7p(z3UeO^|Uc1lM_Q9012N=4Z}k8*|ENkC(B6Cd8v z0j^0c&ak~fXN0_PTy*fu(v+GiXxEH@cghZM1%^=_-jY!13GJ%wqZ7BRlC&%}A)xB) zDHNZa{PH9(PYaa-{I$0UUk(YwTq!g*H{F_-%|?__O+a6NAGYl);s*)5e%2Cy>^P@5 zEyj+pc%ike3H$#R_RT zrTR!HC=k`ZY$6g5U7rOEj{)G^FrR2)7|?dR?1n5#z;uGkHq)$07*qoM6N<$f{@tjkN^Mx diff --git a/data/icons/Icon_Editor.png b/data/icons/Icon_Editor.png new file mode 100644 index 0000000000000000000000000000000000000000..f3b72af85bf02bf510389a60ff205fea24889793 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#khF4Ec;Y>*rMa)9fSquIc{M% uGp$~br&;NU+h3GB)J}0C(OJtxYuiCE z?15dRz323vLL;}*?^FBxo%_q}_kMrpch0ZpW*no37)-_*UNB_L{PNO#-Gy0@Ipgz- z{^T`izcT~U3Luk(^WIw&Z*_sq}LZUE~WC&8lC;zr#HCO{8(q#DPT4~ z9$;CXh5giXgd+efFR{)lPL^#EeU;yFfCId`;$@vb+nz0OXRZ^O>FiZ_7iW-Db1mbZ*9l3xM3RCBkw2{oZN$J8MRn*eyd?q5Us=aVn=D-qy!_tMaCiggqV^GHJ#)w(h>6QNL; z+S=n-u(FM9apM3KQV2j_Q-DqTR_eyt?KwD|n<=bVCX8bwe^4YqLjeVpQI^OhLRhd+ zNu~1mh;M?C!3fLpEIQxz?VBmDC=p&~B!5VOIY7hBF7agObXH-vi`sRecUgJKmZEiLB6iF)j;W;rW_WBQr`M0^uUH#l3|YYj2-nYbFvgsS{O zkpPEd0}jWAxMO^ey!_D6jRS|Y;Uw=KN(VvfTG5w z(ycGRmMx_Kx{k37DMx^;^P?dz?=7}&EzmVgWk?zU=g+&66)G;`$zMZF%?^gSLjdvr z3NxX!4mf)BBn=IxRE8=~J~BLc5|a9i;QE7>JJpZ@3 z(XaN5Y! zAd|oLukYEjKe1=ePMu$+8YHbD0`RlP%`eS=COp9zK_-8uv4>BbmU zgQTXw5Z7qqobDLPTwo-Bm|A?vw#Y_lVEQ@0Nd7Rj_xGI@cZ`jyf$0e_lD~H7Azr5_ zUNtZ^0jl!XFqFiZhM=jK( z1S}Mob`E%6NE0yMH!$B=@C0P?>|NT0HW{Yh9EIqH$U;#<`t9+V_zzG+5kobE{ZRk_ N002ovPDHLkV1iQ*<3s=e diff --git a/data/icons/Icon_FXMap.png b/data/icons/Icon_FXMap.png deleted file mode 100644 index f43404814d0373254349f025d17f44ad5a0bcfda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1804 zcmV+n2lM!eP)mo>M^L5AnFM@2RIO^LP`o%MNz)B0S(kLlFTj6y8ube=7z470}b?n)1%K5g-Ys7

t_?2rrQ~`Lu{t5_%xVHU- z{q35a0XjQ@-d;3l+MCNWef9PVWjS8X%is3HIo4+)!QIb^P$ld-KSuBUPS&>ve8BLq zN&v3|@DmDnl}fQfEQSrlM6?Hdz}Oi1G5|QGsSt~CRhIgIo{@1Rh_vc(Fu)4ouw2(( zMqAp|@d;LNxyUhg@9=PaDM2Y!50*Q@@g=^_zq5uFMn~nk-GY$^?@qEpAV9V^zQ2nV zh}rBAC{+)ZD`1jPfZORrN8K*ftThrNCsHYdqzCMxu8!=#cH35XD>nj?#I>~+@HUn! z;PfJ0-|A}sl1U&Mh1ZdBoErRi^ENBETtIcTaE$hVk6D1m59ogX0$8qqa2kjZR`98R zH!DaIPL|WpPCU+-b#t@s7(2FX&J3pZ17^Q}z@|iKgiwHNx?^Kx_yd5xvAe9`@#yy7 z;MvX!&!5Y6g?#^jnh+5p5}(d_X9E8wlB(;Ai@-6W=abF*@a5&7;4e!f8oT1el|0dcV6QHjvSFgS7-@1o91U^f4vtSj~>JA z;HPRb_JkDz0l@9nl_%>|LyAwpQ^4#41{IJS#RIgp8M<|RiDhm|_;=PYXGlN}e|gM5 zi&kF)ix|-;P+d(%6(g{1F?3xN4nO&rtB=H|^M*eyWIrHD!l+^dwkhCyK{#|fom}0> zROaP99^LS#gwhYR7x5OhDL@nsDahf^;OqnH0GM z&mx;#H7>p>Ksp9n6)&RcVg;8A*t^$M{|%n)@K$a_?K%TQfdIBDAhZN>b*O|K z{_@0r3jUonEG;eqwo_u%>QIT(13$BZN%IGoA84sJ?l&kH$^#BH1(9wF3fsS!19}86 zdU=u02eOF7r*qj~p8Q`=wqjt31?;^#z$mBt_qnz{9Se}tYmX;y_GcHY{R9Y-LN6TV zBR`e{%R-A&+@1<1;(sJQT~xakwkx2c40uqU%%TnrQ9ji5zSnxw22yQWBgr#*mojBF#N6#d^(?g+e>@K=KSJ%mls&aEAmu-~T zDHAO1fe-4?GcwLH$@==d_lIX+BJySdwQFSYhd9p8Z|UVcXAHr=7Dq3IJ){Su*#|`;GIpTWHsjl4C1)J{4d_T zgOKz9XXoePUZXxb(&Wv229ji$7(KB7V9Pe(y=wL=fK#x=0;o+&<<9T5TE@BW~x{=t&a0VW|Q{d-S)$ zihaKf_jg{fX>xR5P(Der9I#XYBJx9y{R-~?ihwJWvqBTA!(zaR{7(^`QRIi-&adbs z2>?Kn@M;|PceC#?i#(auXY&B&0bIHS3=XOriDmSaG~jp*cGjn>OWjyi zg%b;zY;Rxy=k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pn|plpAc7|WO;dcMMXt*b#;Ax{ltkA_w3p8{rmU-|Nnpa@@4z>?Gq+U zm^^v%=g*&CzkZ#UmzR~5RaI4W`SN9FXXnz=(zdp?ckkXA8X6`gCAGJ=|N8Z7-@biK zO-=s({`&g*0RaIA4jizsu<-WwuC1+IxNsp44-e2rX=!P5b8{abA2TyEH8nLE85uV> zw}%fOy12Nsw6vT)eVUPxF*-VW(xgcrK70@s7Phsu_4W1r`0-;;PtU7YuQ)k5=gysL zXJ?n2o4a@KUT$t~K0dx_)22Op_N=k7F*`eZ?b@~1uU{7w6#V=5Z(Lm5tXZ>|n3(MC z?e+BZy1Tmt1O)2p>U4B;9336y<>gaTQ~mt>L_|a)A|lqTS;NN0cJboHYuBz76cnsp zy;@FAuClT+GBWbUjT>*?ya^5to;r2v-Me>LSXkWM-AznPJUu;&ii&!Bd#$alfByX0 z(b2Jg|NfOLS2i~{uUoh7_wV1|zI`h$F6QOsO-@dpGiQ#nvT|l-W=2MagoFe?KYv+S zS!ifzI(L06FkG5Sg8YIRfI&a7!127E6$1m)K2I0Nkcv6UDGW?*Y@ZI)&xqsVRS35} z!f}dsfr~Xqk5t2D1~<23K(|iLWKcF%b`kNYRnOp9#(1Y^zo3kn+p+#7k_rcY@P#3S(YqjW5*yz*o3MZ6O#_?NXvI6lxny}mqQoyy}{CEkE4re`M`SPrKBsbLCR ze5Rt+g1IE0k<;wxd!GOC&dq-RZ>lS-Jb9v`PlCC}@!JcdxmR&n7U%v>VP{*G;M-jHN4i~j0#AY6p#urOCpadW&l1|+%)`U?eM-52$$?_|3lnblY`-wI;(cO5 zLDIg;*%KIF7n_1*2^&1KFuzJLaiJ8ynU!|0(IU(T3^8IZK75H@LiUyz;{< zmPO@}hh6EY?s|{Nk#<+~kd~ z-Axq&%G5e0J>17KbxJj3;t4~6U^xayyCaL89`>}q;kP=o`3C#s35NyQC6*T1Y4a_A zWWu;NuE4S}Y~AL+hw_=+&K{YeWWd=u{rHY|f^otduJo=u*7MtOsdDqWAE{5(c^3BA z{_r^vWqo}OZ{m;BH9s^BIM?&#HKrKHs6EJ%zapP(YW?;0D#1gClbI&+^4w7qxb1W> zlj)+bOpKbqeYZo2Oq{(sZ`3AS@;aQwFVdQ&MBb@ E0JF+^lK=n! literal 0 HcmV?d00001 diff --git a/data/icons/Icon_Font.png b/data/icons/Icon_Font.png deleted file mode 100644 index 1af47b29408b73350a471a4f52aa54cd0c293e20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1144 zcmV-;1c&>HP)TiKu@ z^NnD}-i_{+0bjHtzL}!iTM=JG5C(f21r;itgO(PhcAIXrYpL~8MqMs0`_rgfm$a7F z_@YaeOYWAt^>R;G@_BXn<@ftN&wcN?-=F91T%pJXO30NKJYu+te>^7TMXlg2I)2oz ze4hMyx}XsOxT&8jUrG)d5zr8zA%L_4($u{GZoR^9`dZn!b(7`JhA-XXozruM{q&Ds z=lxhhx9#S~-3)xxj(6jRLfQ1(9p3u%cL2UPx|OaMp0Vsxp6t>pZ+v{2)WV9UTsHz9 z=HvmM3%F3C@1n$Fy8XQQ>a*kqPonhqm$mI~dqQ*a`S!WNlPJ+BZQCBsr##+`8`!zf zj}rZWOeRw(ug)!yRt*0NhxdUxq;UdZlUFww*|Oy+K!KcH%atriRW1B-d<^LBehq+R zJZ`C7&NczGI4(eY`;N7P@o}e3>*BZoO-){oAAcJbtwlh!5Sa$s+Co4Ur3RuvM1aoD zm)8!81|unK72xjOtf_i_zmLO*_kikb1f$GX+#CszI_`2X~F4G zRDh0-7inqni%y5)`G9bEA1qF=y7I4xeQ^Quo1^91GUI@_0ENxb!VMAo;sP`^d5J{2 z;lF=G?3-Q(^!6U3xA&Og|3)b%Gjw+DMpaXm+u4C_5nz;ZGDBf=BtR8z0d2~uluV|4 z!{qn-2n06U?}`Z=9|O*u8PP45iUP+4P}P)S6i6U43m8R#1R?@VO&O=nokm1}6DPhV zlU=S{(E-F3LYJqLQl>T7ni7jf&zd%T_QzQ|b~l@@UoGrSiQP*%g<4xH_V?A$9G|>r z)_V02ONqsAEb_~5fAi9gC)eHAdJx?V%_glanX7@Q0H;Q7N}30R1xPKd@JGtr!<1?v zo)7qW>Mv3I;sT7$ls~R=5^(`WW;3F9Mr#ZIDb>cb%Xs!1P@Cs5~$*YPoZ({e1V6_SwMX z8q#1AL29d2FQB)Q3eMg{(VtNh)^VAtBpJl z6rdicnK3|$h5*tINK^L$xVir=ZM_YKjW0(*n-#8?NN9XLUd;c-T~=}2M%f|&0000< KMNUMnLSTYNYbFo? diff --git a/data/icons/Icon_GameMapSp.png b/data/icons/Icon_GameMapSp.png deleted file mode 100644 index 6b72e9ab020160481a8a297449d1100df2d93b6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2601 zcmV+^3fA?BP)Sp?-1G{tnUjQ&;oOFlQ4GMSznNg5 z@wy2W53&}#L}Joy01WlM$ke1auJH+N&BjhJMRJo{_zI3$D^%@Yd0O$bZDww^HbYyI zi)AIpNVM4jn4Su9s&$p2fGLuj!h4!jV>%9}Ytq^?)^kVEZ%9s^qiS#cpn>Vp8titX zRYhQU1Z+tz78mal77uV|K?%!C_w(kP5DbcArHlu|3js*9*=hN#njJf|=>cYCZxqJV zzu{)b4mDkht4D0?_~&}d~57%E`?;@32pD9Fvrr@VR(ufJ}MnX9k} zSq86;5lD_Dn(eX-Lqn0z`9*K26cvl|$|_Q3KTT7UxlFnW$Z&4Mne&k81m%@g%*$VI ziP`eIR|C+~quuYAb+_ppSqokwEj{0q?upGmrQ?)~_I6`BT?J&$-)PE2!NyHLqq!Nn zyN&5`^YY2capCcZefEs?hPxV(>oH3*WoFG`!{%So)TDppKt};7lAGJJN-Qw~Sbc8^ z1x0R}#mrK`+I7|R^oT-98TXiuwP&oiwEGI&>nia3p|w??MpFT^vaRpFf`=+La{RdZ ztZKnkSOkcEASG>~DG!IUEH0Tcv*vK$+V$}(K+hQ&;r=xb0GOV+?78y+(GNIguQuf| z6S=% z#sdH;eU;GmQOo;0`_zvB80o8H@cawnI4Ptw%L-89>S%n}yboW$7fFImn_%{BE%^K2 z7w8<0+YFg0xN~vnEGyTcmGhsJ>=fG0dQSmRQUaBgFg#Gl#MO%eT|to>S=OFcP(VuB z0)fbT=46(3x&%< z*{L(iIDEae96OZ2Z-1S@nq>*ByC?k`Psq#^=P*r&WjTniKjg7oE_L6z_8J_{GCn;D z)6=l)trr1EOEVX~XjLhmlPx5sS-aaOCq{&}``0|cYlJMRuu$DsS{nK@gP?$vw7II! z@->$(NeC%sFwjUa&`9DKob$l_-wm~wSO_AOfGAnAcDGNCUlQ7K^YYobw}ZFpe-5-* znkN>f7BJ)+0E~AvH#hVb50u0xd!DtseR4wkYAIa0f*0x!vHzV060g>1nz<1ym&D?o z*bKRO`K)_%8!4&Q&i~|u=-s37$fH|WQ*nin@t5L~!*WSX!Q4A`GB1CNX5WR*1_sX8 zSf1+#k6F(-lr7&#MMDdbOlRRu&!!9_4US4Da=3ti8k#T9e_PO)Mpk5%@m`T+AP!N=H>JFCi805 zbt#LR#Q`%#;L_o^=*ugskZyMyR;zC4yMSI2Wwk%xuh$H9jqp&#Mw*-T>l8Os0bg_& zo3L3wh@q|-%<2?3Q~~`LdNfm3fFa+-a42mAUvDiVK7$fZ49w~jH~eYr^cNkP?Oo^3 zS)QZwL}^?~D8BbW-8x0w3Yea{67LWd1_$~y+rK({I<9#-Pn6Q*d6|(*=00J5ZYYz~ zx}D-yz);`cxzO3bfp;5p&DjV_Y8{IspI9g<$H3QHOJ{pFM?Y?0%s>{UPN7w(5fl)+ z!L=8VVQ{h}N#F=Iy`K5e!CZ0#e3<0^LA=ukHe(ad|}TjV|#QG+HM<0IzSyn%K7(MH0ZH%CR3Hhu*BuRFj zdu=a+!)}t(x3PHDe$Bl6C*>>#V6&=tU2u5 z+rd}eZfr>|7A)SQS*sWwy{tR0-~)nzMy98B3JWY;x`N;T^^opF(dFlb=I@+gSSefr zOipNr$%RW-@aj%|xd6UA@i`ExYsNzJCLbNv4p)t!TxELY=l>S|f%pR@1)bhwfcC~{ zDnK5MFD!+~RTf)1|6k#BZ=G&hhK5BVCtYs^20yBlL?+6d$fWO`nvwcl_!->rG+ z#>dk1yTV~4ZDVk_n9(bt;)TLs<;qYLr^h51gt|I)F8<6j#<9YgGpOqMk_68`uTA@P z^3(JTn2) zFjoTOa)BGZ5#9(q4JqgT#@dszi-q=A15O%@*_U_tUfm{ zB!%b7;H9Yv;1F`5=>Uo<>&yla8F`QoFkFHAU<+gy-^bc(YU-d(n{mK(TWT=o%!D#x zfByd8i2Y66ZD7CiWR*!@&YaP~GabEzAEU(pXf%gJhX<}B0zl&A`~W2T+IN3@jz zjE)iP9K*FxSzWK#pN9|Yp-Y!ffEyHPIRIi}QbilL9rBo0Za*N}8UqM8T+w8ogjvA3 zL6@bcECWD(zE-s9vsxH$P*gFsKVtx=%l>JyPZbqaU}rauItyAH0GgI<+qwhyqNgz4 zTz>nbi9Uc4(U;BkYxwX0;Oss!Sa(zdfTVx_1;VsMi<9QqO{$$f06%`uH&;SKzZd#x zH#glf0C;+C671T4kqPM+$O|A6eE<)PWM4}G> zMSSK8dhOb^n+RMdAJYKNS2TU0kz~!9y@~)76o?Dq3qvB9{pkZJzx$ACS5;LFIvsn5 zaCGz*UOVHc5(AKU%KWM3>KY_EJVe6;AT5MrK8$AeCjn^d5(kg|Bim$UofY~*D}8)? z2DPt|BbNz%b@0hz1CSe>z7}ri-hDQ)L$tjJ4@=S+hnWD73>>%!0t0s{0?>U%BGqQV zfQ90ioqfS|8-1skJbASUb5^P{0Ft_F{fiBN-(E=fnF8SDwF#1vauop>H2();dueH< z4E;H;3}M_o`F9{kdsmnl`s(2DxoA7>pk)9+3n6*{B>+bH{YY%j$+;lP1F*q)No2mqzvSP~w- z56dk)od5=}w*gQM0Ez%HLR$%d*w{2;Unql{ zpI?MsmtTR_0s!Ub%FAzI*LUs8WCEBJluq#Ukhhx_}beO^fFmyo@(T7Wyu8KZ%^p?l<+(S;X`uJ>BKM+CydiVA; zxF#KGSpfQZ9w7RFwp9d=dv>NgE-lGAYnDdzckH)p0LIl}S~9Y_x)y?ick_CHSRJMT zK()cT2aWMSa`NvYfC3#Az-!ZX5q&_iaAAy)>gu-Y47|HeOHG}*y9bK^CM2){G*@*v zOG^fToH$X~I88%B5=8)K@dByz-r70GKs_ZVh61R?i{oHY@KHFSqx&xA1bF}+hu8p` zt2#`|2cQK|INhyChP*4akd;#eJ$ud-0bIoM1ML+JGq;HENkHwHiAx5!^6tMMLebKrB^ar$#jSK*tSP)m^Sscedt{!5>1^9NTG#z+?8TsTj{cF*TWVg1&vbNR&CdYsDX8AdU6j* zw$Z#vCV$3xHTj(M_ujnUZ@!uLo8P>7Q*-F|bBx2|hEqmO=0D$<6@@I+W&C~GfB7`& z^Q?jD6+j)8^UELS5UN)|Re-7hW(Qz46)!-Y&^k5-=gu9q-Mol5eNG(?ef=66p}(K#_3Qlc;Y04e z#hg44KYNy&fdHXUD66gDDX_Y_T2v7Eu(!9NQm?XkGHXt*ya1!%O}Ie+5@zs%1Y z?n_Dm0D6Xp*#RPvh@pO@72x}e7Xb)|!zGWE*x%P|6Bj}Tkx*5B&$t&m+-}@nuduI0 zQTT3jlyE4-XpS*gUcO{&WhJNI*t>TCSOsk-F2JnMhZX4ec-R7VySg|(F+qdfp4Hzy zFueX6+S=NLW3DYM@Z9g`LQ@k?r&HL+1`K;V*lf0}wi6W~O+7F;IQYddHzzEc z9d0*}EWWe^NaJ$3=Ur28V-BVA!*PJObo7!GnVXL)=O)fIW35Fba7D z$b(U91g6vh;TNBDuCGmn2kIFD2mV=&9mB5D)JOU8Umydt>%EfC9$PoP_s=Q0a{vw=KZa$ zoQLUI5*zk-0O;)O%xaTIfac~bQ$khwcWn)T`uh5uhkxBmVgT*!S*CdEb-Wc&@=TFp zkwbv)Zb+^FWwN)u4S;xZln3(#Xl;d&5n)q0xwSMk8RlMh4(RCZ#X2>Gv!MYrGBO7T z@ZyE$7#2lgcxnm@BsV)WH$zX4X8)CE&j2)&TRG4zfZOZUe2bIGueWbwwOZ*L8p>+3 zC<=pDuj=xbP*vWf-XghNF1=wEOxdTvUp5;v3kxNW^Y_vckW7I2UW$~0VL3qk{JEs# z!%v?A&|%>G2N{x}fOs^@pLg#9(32xalmjUR`0ddnAbI<%I03fT*Lj}$ie;d;*KmJQ z36M}#rmtNCzzIc_wuMr50rEY(Xc3P_dEoQ$&-^@A;EJAIre#1}2fTe-)UM3!_4WTB zUTSp;k=`{j>+=E0d4J{7CGq30Ag<*nPYRAR6R`l3lK=#RK~@uqf(La1mbEpwb&E(O z!jC$FOz#>wvT>q-xQZ>7Y7YJWO8sO8kSqzBK~(^=12CJ47od(W-_llEGOT_%3P$3S)kWC_R;km(6z8hWYWm&*6x$SV=9ug%}VJJXla zc68dj4~H$U2-mTd1PH~1;$7uiHBpe&aWeRu%aTiAr94}XB)=S$i7?gE$S+LV)r`fn%UfB!64R{Vk9 zD)JH^9sr6BMQHss0slwjJpfRZUz&0b>9FHg0{(Z;VsLO!u!#t;<}lP7+r90;%`xhv z06K93Vn8Sq5}CH;7-c8vD0Ki)AQ%V`bu`k}f|aECDDnY~I~oDdCj|ieOfITj4mEl5 z-=yog)xIJTRei1%iU`>0-pLgt-z1L~(+*XGrdrCS*3y(?Z8Q`SP;IY<)9eI>hN$(s z3hEUPSeDDAT*}q0|AL2c-~Z{YCt7~6*7ffL9znAie5#z!Hk7JMu7h~o9j6jT0O0zc5Ix5 z?+O{WT)cXbuqh@0;QT=6FuUrmm`vE5zd>``7>W008{4K7pK1 zO5R2*Bm~4*9Q*PZU;^-J%ae)*01Yj$c|3wi6#>b9!0qv<-v0nltbl-YN1;3E1DJ{` z*tlaiGOw!twLldC(s)4a{%_8&By7`> zX@sL;vaO>Th(b2}-YBS+!zcEi076S>eO#t`|Cbxggl#xDjH$>JVXv*I1pq`f4v16} zu&Z$w_dljynbAbhM0f&2_sIy8KMEf`Z3HycHvs@##`FP=6f_YOoC;!|CHMMfi6T{} z001yX1|6ObG*vdL9*lMZ3{MPG+isR9QcVB=9C_mi7$ZG*AcwMC2E~RV!rmL~MR<;M zf+g0~{KC_=1pr|G?)|Fop^2byG>pJ(0M|yZ5p|4_;Y3kXTT!%WNzp2Um9Pok-vR^^ z(?q???gC=kilR*;fOZ55-rrh?>BWacy~oK#d>JQTG&GvBo{h8AU?v%~s8R6#b~~mh z1n{D0MMFoZh=AMv+bQes4BkoG2TcS8r-EF;Xv9B@vqXKlt(+@JMA1e<5dr-p{VD4Q z#s<>%K|2Dw?{#wps}*+>1ObyGzPkFK7sl=tsp=(3sj{x-WEfyEi3 zUJykg(m`$%6gxq=WzNP~`1(>mG;uNIge}>xSglq}F0+WOB#3reiz3B=(7@OLk$C}t z8@F$81szc(;Kl7Vgss3-fD6Yj045#s&0Hp!U0xtoN^M0g(8q})hEW%MDS=`Fx_Y{B z^v$D$z5DL!KGw@KP-q}0ZnM~^{YfDbMU|wSUN01H0bidF?9u{Zztp|@;8ZW)RkrT-p0-iqtDd9<>fGFQAnsP({EHD?X}( z_`t3Qbo4FYG&^B4l2M>i2%<=%U`Q1K-$!nVu7&uZu1@xzW=FI7StWrnGTc$9ktk9n zhyPl5fG@&VU`*(+^!EdFUhd>7?D9*TPi?ISZH;XRTn`B8_>F|>e86XOzXJgL^WDG! zF6W+{rj~;D;_HFO=>e{D?-|tBD}NBH1Zzr&0D#-;Rn$)K;_HA&6m2j8n#*Cqi?0J( ziXzPk5WIL24xK&(-RnB)-4}vNPY0kuETky`d`c@BBjc;lqzSS|8tpv* z{x}^UAK$nMLSq8Bc%X&)(gVw~2%h>>Y<#T&?t=$Yjv-6HR>78kT|P@drYDeT zWC_Uh1Tqaho@Dg5+G&ve4^=RLQEY zs1mk9De4T3dl5?A5@)1|tG@Q%_|AJX^XAR3^CsB}eMd~>tOx)=%)}UFbK;19Da3oC zg$;4c6N7}>+(AMndNg8Bf^e|0V<-TklK&C{@(N@C;CW?bZfA5-PQr?2(WLdP&oju^ z3my&3=lxTfFBiPtGcyO4e{216`wdsLI@4+T#pUWi} zdUr{uRwg~m22Sjb1%J3M8c0m27p|rD=7&Da11^W#+|}8ycA{tN1s=XhPJ0Th(mnlK zppSPNW^%y2#-dkPAU~p#lL{(cX+2riPm%w{}k(J>c z*eDV+Mg5!twW%TGlmIUaeu)fYpN-{}aD-`gU>L3WVZ$==^518L9 z1SFHO9(F&RpVlLeU&{Brti3unzZ}_iz}@eDS3lD~JcFp%UuBPd>Mp}Q`Gos(&gSjH zr}47bgn8=t9)~m3+CJ9Wb;LRF0Wf-X?>qaHZ@tTtt$m&<@Kx&cyXQH-16?Lzpb`WH z0!`N7GU1n?C%|;Hqsv$0r()pwE4a$u-uZYsq4`yX75MQX3LOm)%!Nf$hXuzZ!TNZ# zxrMt7*jjdUg<+W&jBKZ-X+&>=!97$m62Je&f_OE>~EOq$>t;K z6B54Mu5Sm z?Zw@g{+8BM{21LzHp8@w{vEDEXJxGlpbF2xBO#cy`|E322v@lD7D{7TunAkZ6}O=b z6gr%maQ9P19V`IT_rc{Q{=>8SFgKo7S5?>oKV8~ASHx{h5kL;se0?md?#jbK9HvxU zNU(=qJ!~G#{=KIIgu-dbBBV;oTROg1^sor6xvUu3LxjqbzkD3|6nY_}sC;nXdW<6M zZidt>_cTr?k+_7dV^zmhW>7->>m`yXDBHpEr9fMVj%`vlZ6xDd)Ms;HnPTLSQC`Xw z5mTDv4`YW0xc`c7;LYPF&bMfb&7yRtIbmo|+<#UxAtA77L-v)zTqNdYr(+U@Dp=6@ zqlDxKBE#iz2R$zBCeB?VnZ&5WQBhbKXWbq@FNk_{lnT@jLWsadI9%&V=-?rSs1%(W z;d{_wKKCdIpLeMHHrYTpJw^!yskpj$IA3?QNn&P;Zm!)P(xo`xq;p$Ns8hLapgMy- zz@%8m%OD%ZzrC^ic)KV}=z-*O=ukP+Bktx70q+*0RtLL*fT%g$>ex~JO%b1|&{skN zqb{T}sV=V#TqPpNbi~AluHMbxAKvqG*iXLAg(j3}ovu4I0=*7r7BM8@bg|G0U&FC- zK~_^8?y$e*lpU%~$}$?)yA>~10=1IDstpNNbe3EQkH+OiUlg1q3I(@7k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8paSs#pAc7|WO;e{|NsAi3}LZgq9_uV24}g@u)sl@~8w zoRpNbZQC|=b@kuBe}Dh}otc@Li;GK2N-8HOM^;vrkB=`SBjfVr%R6`OEGsLUJ$p72 z6VtbE-*|X<^!4@Eu3fug#fp-WlKlMqpFe*pDJiwJwRLrMWoBl&ySq=CG$}YZxS^rp z>C>n8?%mVW)HE?M;o#s13=G_}XHQB>inO$JUS6JnfPl8Pc4}&BWMt%N`J;1yAre~> z}(*&ks{s85o!%JY5_^D(1Ys{?Pljg9yWi?_6SAlse`Xm+_>CoLUy7rfsoY zzGQ)hl^gqSY4%+wS7+R?Wxb8?K{-sv%u&iczOdAqm# z{dMn4_qKAZQFO^}iU=6H#Ohb#QkIU~3S#!sx`oThS`eV9WYZc_mv!e)mPjh4t4P!a4XW zS~wUS4po^gVzRrLrf@JXl4k*H{*6LWS%!?GQcG@p|8Aspp|2va{$k_w>wmGf0-Epqz$U21wx)Xe3Lel$8{O!J%NFFnLQT2Y4UAMPWJ>UKVx6j*s^_BMC zwBdYtTgmm!t`*xKgzMkDrFN>hcaqX0891AhPj literal 0 HcmV?d00001 diff --git a/data/icons/Icon_OpenFile.png b/data/icons/Icon_OpenFile.png new file mode 100644 index 0000000000000000000000000000000000000000..a7166b5260dab69d60805e3e5c1913b920ee4e3a GIT binary patch literal 317 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#Xhv z3gdIpg)5jG_#cTgwAytsoM_iz;)&v2ufLdsfmyF2q@j#S@xhkE4IQThG8P@xWH_IC zP*B5jcB9}72}LF!Z3V4$rWdr_1<&1N@n&aW7O0fe2;2S?=nDoWC#~8O=0O zYLi2b)xekxBp8M|3Zo%Sd|)eJ!F0K`@^0L>p(jVQm)i&=<7P^(RJ4_eMuuG zy;p}J!%GDVFnmlo9$9-0i}uR!a$!5RwcJM{txet7RNRRLDJ>W^zDhU%zihmThKjta z2XoWvG4d7tK}5Vzfxmuxi?`384pw0B_|t|1_%lsrFo3?YDku{d!U>&%+GJOa^7aQh z`|9kxhY_LKxX2<`e*i`4!U7=TcVS#roR`=fhF0!CcC{E2vK!8&8}9 zNzwp7#M?VY0bxX-07^<~D1dRWj`~|+QH=5qVP<}9;^7gg@ac>JP$NJ>3mm09V{BNCXA|kd^pYOmfVE|NDH!275u0s77jgLRhE1=P% z-RLWk_{$7w=4I2~-i1@A`YZiT$4QfdvA&+)QhE389BT6_#0m|-UCovhE_`Id1TSju z3k7&GmS64R>-&|`=M0<+hpE3f`)Xdcg@u*W))GDyW)7&WZSEHU(e{7tbK2Y4Ev5Dg z;5ZiUy3KigbMr0c$-f2L)ciFRb#U6ZwzetlKN30v=Cf`nYm{@^ySRi<``M6$0LEyGZ`pEyS&C}z4_rCNUCgAW9?=Sb z>>%B18~AS|yU~R+VLy7osmBW-H}^c++Xpg(e;(Gb0;o93T@2;qoTc{9LKw^bc+7QP zv5>YH!27}gAk7KQf+H_aQJH0&!i0oOT(&F@t*mA<0|)R&H^}NY1<&o__NVIWS-{6E zd$LK&B`q!gGO=j3#q^p3NJ~o9oM0Cni)qm@79#NtNTf}VfhM6-@%$PhiHV0;eZBMm ze%<6VXDXHPx(YK1J_4}N;8|Fg4H1%Ifs6LjiEUpXzdisFRZ9%OTY3P(t@yRk43V{K zcL>`O6A}PXa?rt;;^`ShV2B$9;fJ7JW?ds*rX(a&!K&Y2UA*4FNQV)DbOkgU_apSZ))WJj4aR42kFdKmIeNI^&V0Y8L1z3%tK z0T5cv0K^VJY&8QAI{>lOWWOIYe>rNZ-w>O>9@min0XpMWqbG#uBLDyZ07*qoM6N<$ Ef~Ju-jsO4v diff --git a/data/icons/Icon_Paste.png b/data/icons/Icon_Paste.png new file mode 100644 index 0000000000000000000000000000000000000000..65d704cd31ace15db8673f541ab2275908727de2 GIT binary patch literal 537 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pkP{nPlzj!E-x?d>FN3Z|9@?5?Su&v)YQ}>BO@O^e7Jk}?sxCrEnT`) zKtKSf?8=oZTeoiI;^JavW|otai-?HO*VlJ;cJ}e{2?`3bx3@oh`0%r5&(5Ab>+9=V zUteEYS;^1OfAZwXw6ru+kM3rm5lSUNe!&btoA3j@zmxX^Js{`l;uumf=k4`q?j{2X zwg>q$(==V!Up)E$KekCARl$=rm3{Ndr^nKY%L2E(KezFFq2EolrX>O=Lg%DsGi~}f zWd;A0PWx2{87}s%o7(uTcgK|g6_%27f2>neWxN~Sz08$6;KD9#GQLjy%^&^KA*+wZ1k^j|99(2EXo~%f*zBA;mY9Y>gTe~DWM4fvFYw^ literal 0 HcmV?d00001 diff --git a/data/icons/Icon_Pause.png b/data/icons/Icon_Pause.png new file mode 100644 index 0000000000000000000000000000000000000000..8d46f91b78a9a64666c056fb17dc681882a4d5ea GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#>zk7a>M{!1!X22a_rxDyYE}iZM_jM#{E8I}0t))B~l&m>K#>^*UHuU#ipzqR; z40P<*wTbR)Sn0!a=y{>-?D7xDFMmbF$qnx_*!>+dOW$SAGjFTT^|d!}<o zNH#SMSlKNAgFPpO{L+<`1Om|6*$IFnXCGu|BH*&yrlx@g`^cw`c4Szz|?6O z0Lb!f05WGU6Sf!SKL{2=BK&mdAVatO;p5fos>sgOhMDAWP*Sl9@3{su-Np@n?|Ehv zEKzY~PcH`GcJTUz>j}O52a^IE{PGLh8XKsr3{D}JkHfZ)+R2$+q_LgrDy6NlVa)14 zv;c*V6_Hz1j4THWLB`CdH0|{AAL2}biV7!gw+px1h0n8BXp=D`3xNLq@v8$XHf*7* z3+~*@iYxyiff}HflNp)Qfk;SN3B55x3!;CeN?|*_{D%aK;IQJ;Jr~gWX$eH@fza$T zEw@bThe7^Bf&$#VqiDEknVE@n855%QKxp>Ko4;6d&M5z344wzv8XN@1E&@b#Kyo-( z``UJ96=;jHQT{`M0;C!2;3RD=vIN8aHX*-qU6qhG%6~994GJ6TY&m0L(;IIww0SG@ zOHz@hJQC*9r)t*~BHSImPT=pWnz5I=*Jx~Gex{>u3k`^B+c;0-5!k>TXVhe2a^%-)z9Yl zxa}=x0gxnd$XS8Gzm5X6G413FEr78Amd*nGJ|Di0;F8oih9MBD1F`Vy_ul~HD8SYB z%Rn&v9S;2&!V36rG#j4pywVZA8O6oVTR22a5y#YaO=0A+`nP3Q?y!R#$TxwQVLrIB=5iP{s z;p;-a`SdBk+-x+eXM!PA{l5WoyT|v!&7z~_FzBn7bB0lSeDz-|ZZMp6K~9SGr`;CIIHfJOj+?*-Lyzt2Zo;VBbC&dBiJ!PA741gw7uczOcA=udI4+NYq!4XE!~b z-PG61966%y$7oxt=dUE0^Ec(p0oO$RWCnPEYJgox3ShSbc4NW|kVfQN+KE;SlV6U4 jdL1xPA|d(p_(=Q*Q7{Eg-H=yF00000NkvXXu0mjfTe=6C diff --git a/data/icons/Icon_Play.png b/data/icons/Icon_Play.png new file mode 100644 index 0000000000000000000000000000000000000000..47d198f5d38e7d89ace6c4e6d51688ef5abe60f2 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#x#m6N0T+${r3{w^yLpOQ9LrcM!W)%XZ<#i@^E_DB zy6tsBpUj!va<2sWOU)hj{pEgH@@>Oye!fp1AK7hV`{(=n`U3^|b?;7ZJ>bO6ld!;{ zk%^T_#=zr%0%Ic^hnj%TUy{(Ao*`_H;)Ni&;XZ=g3AJYD@<);T3K F0RaE&aiRbK literal 0 HcmV?d00001 diff --git a/data/icons/Icon_Playstation.png b/data/icons/Icon_Playstation.png deleted file mode 100644 index c706d5371d279c9501f5f14a5f927da29167bfb8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1751 zcmV;|1}OQ7P)2nuCrGiaKVKS=l(* z#84(`L!%BDDyU;(B}us<7z!Aa8Wjd=g}8vJsN)u*f#&iUNS48cPz(?dgdUqa0^x!_ zmgj=@brC_nz;3=Us$!K2iGK*`$eai*W z!ny_K^B1D&;bSVk0%Z-1T6&`62JFqbBZ&bmp-|+4jq6^sL=6rpg2JjMQG8)x3P5fO z@doTWC#?ZEGBOIFtMy_)3(uGoG;)0j+-i8#A-<@nqkvuumB$QdiHL}U9N8Q|OLC2h zu?Z@Gs(TM5;ajw5J)jqZL}%Z&2%m$451{^m@-blFzEm;` zTw(>zE&+K^f1hr-GdJSmjuXBQ4$H#;wfX^c@9qSsUx2{*_FARI_{z&Gi2*iCBk$PtilHqYsM=(9y3k_4Q4V zn_CJ^P4}sDoSc>rK0|egSOa?W7*GBwUfa9Qd7hqO z8qP7$v!^R(#AT{HUtf*klMh(HfW=u_`FMk3Dt7EhAh|Lulw82tC%?JvvdYqRQpBtJnZdF*IZq{SrzONvXv!Y;meM13IG+ zTE2WMF`&(MwWwMxDaY;G_u!4URsfonEI$KWT)rX(*oF(dAMUv%InRw7H^Ihc2B1%p zREt;)EtwIccVJn0KANmf@UlrpR-!r?$LCWojLL3$rBhf zXu42yFgL*8Kav>G&C{Tu;A2&s=zk>T3<}y#IOm;YYd}MT8hZDhq_qz)glRi3LZe!m z-XIQK4)dIEu3>8cUN*_}=W2-0GuwSS+lKuG*J>Li;caYG6W%U!*%^?NqXa7}CnDta zAE?%7t1t6mT*z6@xLAJs{peA%X#Sx?-8pV2(*{_gEnZf39R>`Ts=4~J0Qs3&t>N!a z{f#$n&b=@u$tw;OOX2_&riO&wz@GO7Qj$Z{5ZsH$V&iFmLe2;HH4#pB;dz z>bq20gxW*5Cm_}UL;G%pA_KNR zy~3ywbN64N(mQQhkiptR^fN#hoS}VpuSI}fSWce0A0@PVB?FFDn&eWc)bQTepY+9Z z@Hu#mO0RGWjE|PsfDTS&e56hjxCa;#vKKzxki+jD9XFRl#3}k-qOI+0x?7;L4e*G$ zLOlqvfmaW{6_54K{9RrKj96D<;o$>hXDc;&#|f=?*%*LNg=l{SAvVa#G}h~(uYt7z z7-?no7B#@$egV-s_&a$TFo$v}6BD?C6tvEWm!|>vHYls5Kj|?ig!LaE;27eUg8>-h zHkC;}_{7A_R-L-*zuXMKSaOYcT@^a97ZI=1y3# z;umrdqXT#M?_1k!7~Q>1ZoudakR$L9Du(??I!d}2yVGQw?Z0n;CBR$&YcLnU8q5W- t26F+d@zlOQ`0UNmr}Z7;XK#;d$G?lZG7;@`U3>rl002ovPDHLkV1g`}MjHSC diff --git a/data/icons/Icon_Save.png b/data/icons/Icon_Save.png new file mode 100644 index 0000000000000000000000000000000000000000..587ea2ea269fc352012c2cb0afaf1da7b39de1a6 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#m>g4=216FL1A7^C8VY88;4xu*CMwW)q2a1R za+tMD46A5_*sHk=Ce{hfWz1a-=fxCSwHUUrMINZuz7QhP7<4_=fN{cPr@g_>51A6u z9|#MSGE|=CR%9r%T^*$z(~v0Y;Vq%<#K81IXM>c`s{Pv!v6NXmJj$^3d0-yWeK6Fd zv0<$Nm4~*+#5t%lvo@btv)a{{=dk=B(Z>rXUz>(fs>OQOQf<6r7~0rsT_F9 z`?S5zyJ1ObV1_`Is)MloWv-5{Y~C%W0$YmB4qjqpP-B}XDcr{;3iLaJr>mdKI;Vst E04V}@o&W#< literal 0 HcmV?d00001 diff --git a/data/icons/Icon_SkipBack.png b/data/icons/Icon_SkipBack.png new file mode 100644 index 0000000000000000000000000000000000000000..fd217d8883eb4fa2382623fa6ed86166cb1760e9 GIT binary patch literal 488 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!7>k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pkQEtPlzj!E-x?t|NlRbv2NYEii(OCFJ5$ZcJAN5fAZwX)z#IPE?o)= z3OaV|SY~GC!-o&GwYBHZpKoVpw_(EuNlD3`o*pSFDGd#c#>Pf}fB!vu_Uz9$djvE~ zx+KUim;q=m4say1$Q0;EPEQxdkcv5PuZQzD8HlhxV9tAd@BjbnlHcz=3JY+{udXp@ z`|Y6crABf3G7;|Sn-ap7r%z+?d0gJaKI6yMqzCgGZhutq-+6d%1FQQaKMVh(h76P3 z&nHVTtZc4c$G_xz{`6f9?@M1Ya{kxlJ#g7lSYb1FTI&J#=Ov9RI@hsny4|ruisRiJ z369rucuwR_d8whWf7%geM%U*e4KjV?T}l*?Oa!aE72#Ob(fTOb(T9 zOb)4DOmDhMR=;XtX}C3mrQufxOT)1VEKO=VzFpsGsnB@->A8&Ni?1d#TzEH;;ljpU zG9T>zY`wT;J-g-u$$!StcO@1uyi8ZwvG3#aUllxuEh--H+k44ofvPP)Tsw@I14-?iy0WW zg+Z8+Vb&Z8pkPRVPlzj!E-x?t|NsAPf}fB*UO=UZD_pFMjvC@9Fr#%A~K z-EMAfO-)U9c6LvmJju+=G&MDql9HM?Z(eL{EDsM4A0J;?b4)x5T}@@uj2$ea^nT97Ho;mZT!!ovwmlNxanTL z31^%ermW!<+4@^V!BW%$oRspn?c5=lR@U33qzlrYr{2JIkpSc z0*o*2cQf$31B&IlHbl+Y=uny9!u*<7k0ER)*OD{;jV{E>m0xT)E9bL#{-F!oio^W) zS^RR;`SVvSV`p5}L?yF*+cIW2P?}h#gCdMdS z*u4GJ^e2ZJly-h}t=`UlVcs15g1pmt-sgljJc%(cXFm7DjCtErnUj`{k3OH#lfE7o yX8HGe&8s{{PL3LF(^u;McGl@BZ<3XbV8}B{ue@5b8VAYC8trm)widx5;awupK#shKcF`!fNC`u6zwAQ18VjWPdXw?9L z7)Xo|2!#+x2#vqyJ>5)9HrbcWZnmxY&iww#QmptgCD;J`Ibq-1CYiJfrj%tz+^N4 ziOSC$gp%chh)q-`d`NU%XR0kc1T{Nn@ee?jG7b!?a+eM1nwntm^g#GyaX(fQvXt>| z1E8fWErv@`1NZ?@ojw&hS~Q%^7+PB)e(YE{J^eYSCQ#Y%sk-WFi1mL9N*49y4nP_| z42+Er+&0tN+zfMkeIb9EkH-KYHPzR{s=Ru)X5D7d-gO^*RU zs*}s%vo2lW()^cP1AywDZ!H-<9OB=gJPH75TX;CkHp4Gl?N1J%u^@wYBUPoPFu`o( z!kq3N1%O7u#7>tkm4i~tOERf3pVHgY6HbhbAlBmkuKAt87al&=}c4xln|q+mvN zMn~gOaBfytj{-QedpBx11*8-I(PGCqCBMCOPAud3&VY#18BUmpY>uDB_)>5pPJeQ=T&VO1DcW(ASoz- z+YW-R#R(KQ0CX-|S<-R$U>s5I+00Cwn=zVV83DiTA-dqw5hEbd$9_nmwSP<>3Kn;F z9JaMc0>Ef6Fv6?&ZZH`CVqdXd&CA2N>-)0+K##kmx_sma+{;)5^0ZKgD=m_6WdsB> z)G>NIW)m8LD1X%}EC7`Iz9I%-Ekm;g)J3`Q@aP)zuWUgr$} z(+E)RWgoSMwlGIK|*g(O&9{+v- zDC*761&f7N*v5@eR$L5! zcXV(9P?(d0P3#!P4FJ;!P#yY~HD9Ar;rtM;0O+{8;vKxjoj#%~qy~<`yF60!(;=x4 zJY;0etNZ~_=Wk-oSCp0E{2A^7unknpXTx5E^D$G20MMJG3!mo?fUdldHJ=9mg);!M zN-gN zXdwJD;{`ha+FNH>^XXq=9>ooS^-WBXF&{d#4Me#I*R8WFJ$nG=DUU>2jRp>^TnUn0 z5oQzf%y;2PXt{HaD7QF2pHm4S(K}0MG#VQfL^-rJOq+(=-Tr|S05!X2yL3@5I-Zt> zjVyoJbpY-t($5dKn={b~fU2a?f*VPmITIV%vsxq=y?r$7`%3wwJE06qM-1`q&HW`+x9Bsnb1ZVD6{0KFT` zH2fVdg!GC(c{ft8P~f+;w!>dY0PT7`%W3uzG%79-An1@vB#4@qy_ zz=tsCHk03V+$J#qdVy4NawpzYU{hO53w{Y2*0U!z5o!)c$5X6>j-z*$wudm>0zd~k<&_;V5e_FL;JUVsthhLc2@0~92z_!O!O_VuN3pC2Ww{1P zpmshtM|3v|(uOdfLE;U7bsP_+AbsfLy0#AV8U4!qzYyNj;$j;RJG=nIHXwF*0X(b! mAN2ln^jZB6vG?EOHu?v9ZpI3}KcJQX0000P diff --git a/data/icons/Icon_Stop.png b/data/icons/Icon_Stop.png new file mode 100644 index 0000000000000000000000000000000000000000..fb18f609eb89042034c29c78425fa28fbdf92791 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0L3?#3!&-4XSjKx9jPK-BC>eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#gTe~DWM4f_Y*eC literal 0 HcmV?d00001 diff --git a/data/icons/Icon_StringTable.png b/data/icons/Icon_StringTable.png deleted file mode 100644 index 9ca4722ab4628ecd84e23dfeb240a01ab0ea60b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1964 zcmV;d2UGZoP)@D4^zoxdWDIa8Se*Q$!^f@IXq63qpvbrh>661S&fsy8?nC0|WRq z_dVvt%-pxkL+8D6zH`36=DXi_@9*7r@BO~}h9J~rSmr+XKdbt9HAL(ViUvUJj)@LJ z><)cgt6JaTDL# zLghy44a!gOB7OjZtM6zP;C9Y!D!@_87Y3j;GXTjub_0M|K8PE@h^+lk(^#){fDc!U z24Z0!NzMQycDw9IU%g`8*Z~M#ybgpNBm;E3;w(u3hr)d+UxBvl0MMQJJrZ#QYgb!W zOWDkPjU7OBBYuF&Rn&N?3CJ7eSQ{%(E7GPz#A;Yjcuv@;TS&l_Ku!QDxha%Q^A6-t z$b5z&U(so8nE`x|<-^#xvt<{075%aF3Pe}s!nMDyEA$$z!Nc?QgVa2jh@ zBdeiblOgFpF~0&#hamJ0dH(7NMiCo8y^S`?lw&9XbiV#QwjEypn@TTZ?TX5aD7&xP zv9AF|@+VjaE#+cfJec10mIQ#(%2Mi;3E5571MbQmV(o6;y-5ME>ckEpt*(p{fKrYp zoQJ`Gvgg~+3qWhPL7z|`3c#{~>;R%_?rY^3O+iCN^D79;(3(N{y53w0>i~({>aw!1c^wSvtdiR$L}<)c4YMLs)SNHULU>$C8fgVn=aBF%`i2Eu8^SuLmH_sC$I9wb@}y*`8W}2f$Pj zJ`nW_5Nn1)za$UR&b90+)~@Ar)cFi(aVJsAFazdpx1nrL%*O-pW?A*Oob&+mAZIwF z$Q8;Po?>mn6E12z4PDQGG1&(h$Dl0g5GU>M0GOUEUpW@(N7wLl1wg$X5LS(^I3bz5 z(M;oxPzAuUq6@78fM$vEI{SG8Xze)w$(U6ikueNHmf-<>oqw`b0UY-`QUJUrNfJQM zIlVNF!zutwbMQ5FzCu@VkIj}G0Q%-i5kt9{YXCr+TVE+C0DVQSP*la08i2&CM5=$y zH&=`Rc07y{6kxUQ8jbBpN&uAEAhEc=ieC)?=&P^>MdF~1phTm)bq^}Q&od8T9Mf{^BZb0F(2M^ZrVt`e`-vo!5^F;5?jl z@M6t?FE>u6`qzAQ&j|o2Iupp78d)8qm6bkSS#*Hj@$Q@e5^IaFz6LKeVg-PzR6=A& z@J{;a8-zIW2Y?h+h00|3n<8`qo8U5$URiNpVByraB0;FBjCjS77ZHOTl$}KDa0000eK@{oCO|{#S9GG z!XV7ZFl&wkP>?6UC&U#iaG zUKO7xFjw|~fDEJ9gQx=nY+biQdF~6b>FgIccaz1No#B6WiKNie>ghnAFnGH9xvXwbLRKB!UuYZLtq6wWqdXgi`yyRVJ!xZN)kULtA2~ zp(s^qi=}ZyE2z?9icC8H#k_OwyXT(w;eELG+)M|1YXM$qUH||DP)G!Z#pXZ2&Bof5 z-N_6Vf$$h>IA~#1D~Tm|!jZ0c0N@k-0T4hWNdf@)f`cvAl68!UiHVDgBM=BVIXQK8 zbrcF^c6OFVqcIqafq{YA+S=^w?A+Yko}QkAg99d$xxc^P(a|wBHrChIM4tgNhwiAh32!twF3gM$M>%LS65dH3k&u2^+Q8LwY9aOP$&ol;^pNH z4-YpqG>ngr-`d(*Sy|E4)C>*|?(gqcQBjGGj(+_3@$1*G%gV|c8X7b-G^VGgdwYAm zyu9#ud__ftgoK2!urN0_x1*zDW@e_5kx^4q69fWrb93|d_NG#)jg5_#mX=*zU0hsT zySuwYB2h<2XK-+EV`GC(rzFN3V`_IhGJb3WH%F0SaLMVl9Cc#UETTld0$`O(b3Vgv@|ptJvTQuH8rKCrgnOIdUke(!C>0j z+Td`wjg8ID&Q5W0v6-2fg@r|AWTcFYjHsxnxw$zQ494Mb5Ve3~mSJsoG4@UX%k2Nt zjQ!nM4*+atD1-$zmb6ozq*dxDInw{8?$oVF%(?SCBP$@L*v?&hy5KhV6@d!ajAc=g z#x|Y!b~k`b&M9j~O#D;bq=)dZn{ItNx7hNuLSKw3+0=dTa(8wZZRy@jrRU>U=p!d2 z{G%gNIu-2=fA}c8xBUvcZOk#Z?}|g1OteA>;`t@4GhOIu&a&-DV}G z4AvojzmWi=t%UUhZBlQ$$JIiS*Y#9Ck)*w^SEc=GZ+1s3EjL``)10ehm2RaIK)S~5 z!F+phAdl0>>V+0A$WCs+H%Nkn-Wsh1My@Hr;b9BEqYQ%O1LfoorCsdby@IyfO%fR( z(#g~0-GL7c1ajqsd13b#oB(?xgZLyg&k!8H>9tY$n+(~V9Ye5rCITA5 zf+$}-RWlsG)qkvDs}EB9nYS0gh~<54_|#QJ%tsF`us0*>%~}#?@MdF>;U(>vIGnM8 z_(P)NKUNOc3NTqAHz>Tq=5Ciiw88~kl7_$8G{%%{n+g)!oNmgBv>-M*aDvMFksCb1 zgm#X#ISTNdFS)=t>SppJL~i-svIz2}WFlf7{wXc4S(zZ)MeZ!>kyVoVIK0o5&^e-5 zv)yZlyx1Q#!Z{A(`X>ITa~3eyWGlHGY=&Fi=RuDjwzblBT(R7@s%V7gS}v45sHdCa zDgn+uxK06~8n1#Kn*Ogv6TJ3Tc zTL`uDsWhdiAyeG-eJUc!jtop`y>UW^jr1L;O4O<Zb?Gc)HMSiRAy(CLdLuJYT5 VaWT(Y1z9x!pe*eXEpYFYe*r*6T>=0A literal 0 HcmV?d00001 diff --git a/data/icons/Icon_Weapon.png b/data/icons/Icon_Weapon.png deleted file mode 100644 index 76e98e7c18d1f09535fb540d3407ce3a05fe4e44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1880 zcmV-e2dDUnP)y>R~*MbG>tAS2nt!*1ZqTGYAYg=7_0Um(Zo}a zLeG$RFyYji^gx={n`dn}K2Z@=^2@Avz@H5U_i<(4nWMhGyU|uRjk^U2Q8qjz(z);)=1QXl!Jz zuaAMcIu@O6`}adQoGwQqTxx0I2iZ8gcG-$6J9f|vTyS)=6EHg~jFY=*697+jjJFyG ztSl@fhXu&b*BJqTqDX|#FJ0oNSd1BKLvgXtx4f!~SzyH3;J9DNu+8~D>;z0t3pdC! z2w3*Ax~@*BTArT=AlK_!35p^S_MJJy1rTR~1v_hN0nG;lEIG<{0(yIe3vvqzq!$W^ zM1-o@XU_o0(=^VBFB=+o8;ddM(x zhdFTS6xVT|1$*l2dFs(e1y2GtmzDw=OQ51cs9JjUDu79L#10;03HZ~cPvzmm0E`6~ zUnC%ruoX?`F(Y*J#?1IQ5PS&$Y&Rl{+Z6xo$Pv#zDu@Iap4)^;faeS-EEK91ji?fI z37GdUh{ar=ZYUgPXG4SQEKxxu!0_BwMC5OW5-wmo_N{mfJlJhxn-D*#q8NtXJ@)mLcpXERa6A@wYGA(sfp#L zCYDd0x78cT0ARdQ7G3ezP%S)V_X_&r3HyMP5-60IQB^ZaOGgs{7K2Ccd-45h1D7MtM~gOGwgU z7l;H%^nf`9H&#{(ZKi{AW`d>;@S6TQ$d&jP8T_WjAR|Dc2TTJt8cC5AC6WXP)}{l5 zv0lFh;H^i$AZf8kfJ6_Nf+!@(_wx!1iAsb}U>#ui8yPleTyCbtx?A1yDBwtka|;Tj ze-fa$tcVArx2#96cKBIs;}n z^ja<^gRO0lG+xk261(%b6IcgGaR25_0K^F|#emj32NJf%RUHUzY$9X4lhB}ZFAkhPU zkO>_yeDx~7pFIn}R~r4N6-QrQkP{%$16Dk~bH}xPt>*!wgM(Z&Qrbg+I{u{b(q$jP z4e~??lIgI*lRmt4i|u>&dJgWT1NytVQcBOnlaZ0sy59#hc-|$62j|YQr?FA9cN&2R zn3VQD- z84lG1C_MQy;|447xU@Z!Iv@~yrp0Ok6nel6apfS*7&D~<0wW&xT8Pz+p+> z8Q@1txe~Cx{k;CkOtuZkHr5HqwgK732T#EIm!sLXBHPH3Jofi}CaixwZpFV(a&G`y S%22-m0000( zfLwCwwWmrsR6X?6-g@hyhpLC>5VfjQwH23Ek(yMLl2mCCA0=^uV@z!P1;)l0d%=(% zEIYP$XLb!VvjM-8cYp6UGk!b!+h@hPrg#1Vt8`rrhsQD_BR)#syr<;y64 zPaV*l0pM_au6#Y70L>ZD6rd>p>jALFu@``=KXJwTCC*tcNQh}MiO*)4=vcuxS zPGNt>v4eAfZ)qpSgDZaUrj~uReGo_l$QR}B6#%gH+V?#Jtoj$J@rC6n7`ikdz?v8) zk}YN%^7|B^m+vFSR#TOu5HCdiJ zbg70%^8le(fXNd8APA5Wqr?Qk*ol0)^u;*wN(T1 zyBov=TdxB}u~Y+wO&5tg@5#Z6XRz@jMBY|Dhj=;&-lU;hV6CuBOtALYD^r{HX!E$d z(C3|{9Q^>1mrNzV@w!S)dDf8aH6aFw2}Xmla%Ek{7pRRp`C;r7_RzzVADxM{7_;dQ z5Co{M-u37;TPwc@?CoA^<7!thW<6EIj}~5rF0e-1a_n>s*SBmkXg* zJpe!vK*Y(W05mV)u(;sv?pM{p`Lko-Ir%?ASbG3~A^^<` zcux+(EYJ&J8Lz(lCNaj^0{|2OXkNhMqCfuBa#?!-fFc0R3mg_$djLRTWr*el4g;(` z0H7!U*$W&7SbG3KK>(T;ki%AR(TS3J}LXjZi=^z9f zM_pU2#=XESa}NNh5P-H^UPkcoA_N&D^XhXz3lgg=V=NUJpe9Xv^hgOwNzP>}jhUD-}YP z%i;A<6d)nqr^Z8(Qjx5_pZ%FXs5$XfZFm4cg#eqyDAnA|`KKktOi8q8GV=Tg008N2 z@;$wh2&4N{Tg^G8LYU2MJU_Pp07P?-h_Rn;U6Z|<|E4F2ITQc<%4AEN98?ML^W#qu zPA*B#fA!rLh^K?F4Cy7YiNx24tVwge9sdRk%Tws~v`J#s2|y4Iv}8A@?`;9j5ko^c{jYbxGfLhwSe<|O`nv4aJm(n$eD4Sc;sXr` za8$wGj59`40M-LwjbkqWho|q-9=BrHd~+12-6?upWs zj#C4ytN>`Sd}h87_kfiZutLBJ0j2Ihsj=({&=wY~+jSh~)f*I!qh0M7yY$JD8}ht% z5H;SHx%E0W?LkA^ZiQcJb{yS@+PLjB?Kpxe&lW{_$oDITJ3dmBD^>t$@BpBxeI8wX zac&1_APpV>lIGUDdQEnPGzS3aD{F8*{2aF((%=C==h}+%JuyYOf`HWQII)6N)ppzn zB)J_R!BEvowZ-Kah9haAdddt{2v5x|sSg0qKblgM5eSG7A2ymKz~Ej|!+Psls%;_? zgrQtRwHG3J=kAjFKm&n*Fx9!HZUd6(;ya)!mTE-h z;t9~3>!`MHa2WdX(!GonEoV|QRA;BFaY;*1YpA5!LL&pPs%Zrzqr+5Zsltq?oGH2y zeWjCX8};|VVp0(Ssp$c#bB)7=WV-mnW0_temM7verYHQcNGjR_$tfSz*=BbxaRu0k z<+mpzFz7Te=t@U`LJ0!%T0mb}qbN5@6?p_$JUijt@p+z4CLKrjkvA}xSPZ75x&UA@ z5`sl4-SP)0X91cPSXFIDDklh9+)8CurZZuneCNXJk|lyBBEgdGe}GB=Sql`3A(M?P zaH{Qf=nu@RE|v%?wFUqv1Y}Z5&76h4!m%*BlFdW(aeJB;whB)Kl~Mx$6awawv(yJx zH+Ye{a}QGOODNNsh(0d&ngz|y5<#KBAPhQj8T=?f-U2hD)CZidMoh~Y7_5y{AEQY^ z_1f(K*dl0bs85|iFgZO)eIP4_B>Q@1#nrX*tAHhfhHrGjszw4*)4kLOvSNreFaTK7 z)PiU{Llr@{C+FWZs$2nci6G`u*QxgLa6sh*%!Y{N zMw0}ytzM||%`d!3waKv=brZnS0voryC{(%I(?qqYK?4BHEkM@-u6nWpEX0%Ro}${+ zpaB2|0W2->FrWqv0I*g7Lkm18)S>|ZRt#Whfd@q*E~{ej04Fz?Nz1|&CF0_~laY`r z0wBO4fOauLLifM_2>U*&ix91`mTIF-5QhMIlB5t9|NdRrmvs@sx{GkS8kzO#t?Q_^ zgd8KTIyM1}BuOp;BYyN=?GW+>*vSx<{;)gin3uAwBYIqp5!+~ILR*HH43R?@na^*3`vVLS(&?U8_AyVW-Cbvk z-vX>8NiIhHJ!r7&5FNh2_2nf)<`O~XR&v#Q(DweHaBSKGU_LiN`znOg$3hSjBe|d@ zNwNrx`0vlCO-Mb8Btv3jK2+Emsdi_b2dLXk{FH_S-<8gVJ{E#|C(Y9WlaUY{RazKy zPjF`s5YqtB;Z9z+io$i@Wi-3=#8oFi09y+T-RjF55HAplBtxS9pAnCeKh-G~iMWh& zrw+sIP%eK!gaA%p8|d@FUR5saFPaP)_x;565y6>L$B>*EM6*jzv~zpH(*nI$JK(5V z3?;lkD0&eRzWOb0hX%QREF|JGP96OY&o)ccpvxtI^6T0I7;4}S|Vv_NhE%z_sPi@6AqgJ;om`k;_+Ax<7Ugfl0;!K=@hncpAq zSHP5ydM|L@cbOQ`V`F6faI^OsfZ{Gf;=TLParCpIj@u`X9YXtoz1Y@LLEZaV2&HBR zPAfl=z1e#Wza0LU7+uG@zQ*iSeiTo{W&HTV7jP5A2oJ`{5&ZVmcAWd;1k=xVr4yfi z`0m2sw|LpP3joku+V2(m=w~RB#_{vhd1Y?94sW$tiT=s-U9|r-m3MeC=rq{1ttu~Q z7K3E^E-v@SVcGB=9JTo$ZMGlS3jk<#>9N@>3AZ6kfZEU>NMSmbe=-!A@j@(ZDpUa8 z-WJ8O|GmHp0j2IhsiDQm|1GdwR>I1!$8+%?%2TR+3`pcI00000 LNkvXXu0mjfzd1&O diff --git a/data/icons/Icon_Xbox.png b/data/icons/Icon_Xbox.png deleted file mode 100644 index c25da9a5c693dfbee635bf2326895539ff4468b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2123 zcmd^9`8N~_8-8aohOtY=%*|Sw47U=Augr{QGPX&w9&48?k?JxrWErGMx%NHMg3sl; z)}$s(g%J0X$P$y?7fs4CQTbf`9p7`#^FHS}&pGc;&-*6Xvn*w$3DN){YsI8HY%BE# zv8e4?^f2zjwje?sEG-ZtUHY-xM(PsNEffH!{DTN6D8vIGU)b9^GPXmxNZBimk-X+> zF-_4w#S^{Cye#uia396`SNzJzqn|1F+1lC?^a$WENc@JTWSa|Tgm4hR6^v7j#Ovb9 z&dPmBB$s>6W@cs}3#GlK0|NuwYwe2c7|skh2TDPbj?B?dCnwlCIK}Sai_yUbadpa(7{P;1Phm$8yf)otD zAI{CqCHNEE+}uC`Dl03&4x%4Mi$o$M5*e8sxw5h%DJcn-u(q~_#bN;u+KE~W216(m z=H%o^he=VXRH@5Y{s_OjyW7af2zG;?pC35EFXd;3hK9fcqNAgM1}p0;moHyVN=h;{ zHHAZP_vPIkJ9dBxfIif`t_CtN3oPsF>roexxgEKMg@vF46CWoW9UVa#?sOOPcs$U8 zYflnCe*B0=qrn>`cdU|>$CML|Yk0snl z$Z5~{IoUv2Sy|zV{KCpYZ*Q-LhKAE!N00yrfWP{y&V3A9MpCGX69DzUx3kxfFkHwg3ThVEboI=r1gsr0` z9zHGE7@es4tZD75Lbjf!)zFCfzp9>6DiKNIB;|36m_5 z>fj>%RHytwj-FyW_r{H>^nfRUzDDBa@%)HG(=D4QTccMSzWEnZ-raifchr(Wyo181 zv#|e>2t8^xPHWHz_z(L*6h=s-;@gJAt-IbGG5gn(DILrA*VmVK-NDsii;?WuD%lwH zg{>}CQSv$!Jy!g>hS-Q)jkdU_jy34pO3zH>Pui)k7bJbGHuEGVhg+=vMvuv{_66;Q1B6eTxWt?+Fb&X%q}55C4CY@43Lt!0z-T>}z6 zqu%$ejlqAEd8O}^nf7|m@a7$Pd{BpKD0Svc1hvx&OA0|;RWEMfp)jeNPJ{!M)+3Cg z3SNIi**1q~B)$#{fwrADSDL?{r@h^+$stq6yp+BkCYr2JE$(9T-^1?O8kSymK4o+&?Mmq$p8KF#}DBisH#tfC?{$2uSS1F;{`wVpx=X0S9 ztIz1+u3l!h)x2rSMnYxX5l!RR7`^LU*ZvB^)#y7}5B#g#N6@&_9>`W#t$l9jkjAlJ z*Gep2==Mn%9t`i&RzP&RKdlI=6Pc9D`&IF>5|wHYxvv7n1lRNlr2}tD+7r+S{ju%zY7R?7cJ2xW?fVKuv+$<2_@;*DK1WizRsIQgs- zH_5ho>_Y#IBe{%MiVWO92{Z0Eejl=3%8zUX>{1=;sX-h2JKrVKy19iuYWAt2#j0$s zX}EhDX4t=*$|;?m+*3t;*-~1&;IB(%kb=ceSbCDaAILe&2*;~^>Br7|@xugIZghTW z5W6?zWtTdrON>1fWOOZ2L^y3HcfT)@s)Aaq+;BGY7CB~&lI=)VwB$p@^KKcLBO27b zr9&DwO3zLWB@X zYW!d17COYV_OpBcLaOW>-oV7`J8Pq?2$dN$*>y-0wo*##hN74pcB5hEzBD`~-Op2{ zPj0GIs(Aqlc(2!&n|3xCua0j>_;v_JVq}_DWY5VTlbin8 diff --git a/data/obj/diffusemap.png b/data/obj/diffusemap.png deleted file mode 100644 index de266f376bc75b1bddae6cdc9bc5f6d0df3c7204..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6211 zcmV-J7`*3+P)S`Jsr8;ib4N>JoO}-tc6R2ynSGx3eSW^r7?1wz-$@?& z_$tS4YXg9(KdR{aik9sV8`E>rg#Y%!72ddbF+aDoxWq@+e`Pwxnaz&@etP~@E?qdA zfA4Jd+3s$$FuwqRkkua`m~~x-p2yW|+Ym#&=Fl7T0a!ZFLa6|NvGUpKY;)|`D)aN2 zpEyte%*?h3CJGfqcq+hkB(7s)y#3@?lfu((Du4``0Q?Br4m^KV^8II?1>iS+{WGk7 z?EdmUR1w0(x6bnHQ{MsL;!if&?ryVsXcYjb;Q$a!eEdm(U2}2)3_K5E+5o7@nDIo> zZtC#>N(BrC9`p09T>_A{9;bo`0N2s?c^7tX4qJd1z}nHHkTRbgzZ;I;c_Ke{XWY^? zZ{Xn#Jp4&O;QI_bFTXa}@#tLZ&>Qp^Pc&n_zL(Qj`2cjgeY)Kq-EI#G% z9eFDP5IIG0gku3jY+vi(SP;e0FC;9$f=d@J0uIC}v#}4ck1z#}Q%9JBC z_7(t9q;+gBWY;d9KbN2D4+n)2dt-Q`&+tZ{!3}NrW@lZ7Lyy78!ykA=6FvLU#Ai4T zY3Nzm6Kdk4CR*tIfrt6j|2tnDb4$4LcBgu37laViQ?zEA)l(%j=i1E9wbJ7j%|_W~ z0En7I)U;76qTyI9&+i^zgn9n$ZuQ(P;r82>s;6#>qsP}ca(pfSzP`3btJ$PK9I)N( z;q8ps?)KR3_PKgxgL8j(hO1XL^6{Avioy^znIDrf4=~)(vppCGH0#qbYT~1OAG1GF zxn5$WX0b@S5alFHfx_XHv*&Q!7K)o&+bUL%9A`XIxNehnt3|ujVtH|e$X7&RfFlL- zb1v;Um->vPJ?G-u;CTaJ%<|GK3-d0b2EEP}z0MY%H^dYcrmzUZkT4AKJr5J`c6@pY z9Jh(%Hi;8~K-jsGmn!J=ufU`f{&j0cK;_RDKgLbRf?)Er)VT0{%AKwpCx zCWQ2}3fFa5SZL(}aGR~1GS{beyj&0&pE zcmaSPd{0M$RoJ%7383$J^maTt{XV@N4=DwH8qGb(jiZ9%$j*zmELiDo7wHPz7?-p+8cbdHE!*(FS#^ zj)=vcWE(c)(U|}B?f-#F|7;<0YS$f_ZXH34Ag0sVqO(1u-%~jSSt#pDY$*s5=#LaZ z0``mphR8`+5@zOEI=lw539?DOv6K_S)hpmfe|M$KRo#Y_HoS`qDdNx<^1_+G6dkKemui$!MZmaF3U>`Ic2l%c|pDsJZ~Bqno{N@ z>-s*O&CUFJ_gdLq8(;kGhZBJR{M(<@XR0woWktsYrI99_e5=Px=d_DD_2y+-4ehgY zgq5(ha(^|_*Mo_VH}r5DHnRmffld*L`Q_v zL8)G4sN6sF^>twh)Q)1i+r_Eb3{oQ%#!$1TMltYxq-`QheWREJ&r^8bm>>voXJ$y^ z7}FG(rXY$ddRzHD#^)b;ARqCie|9e?Zl5m=P^rNF)z_ckPyXQZI2BhP6zf&d+7hpOqn+hol@|PXHIeY;wJYTUFP3??%v|?k^m@Z zOeO>&1X4y}pfY3H&g^b!?o93aQHdZJ}`My92IqnhnOOj&5JuX7%tY z<0Pito@e9IdHTIB3kR22PHPW?8$HC@@zuwQH#&1^i=}-HmiEnZ=2D06|IHgY^8htl zu+%Bug`#C(C>9wyzLM*rw%~PsqbC^ zRUBQM=bk&4x##E#K&}E`NoV-chd#lFjxI4sjakv;JpRL1ICEhWY1^sp+DIwcQ3_8f zJT+$4(kmheBU+96o-4o`4R9M;4Qw%0k!&Rt1yEc8?u^Uqf&BnnzNC}Bg@a4XHd{33 z+S3)FJcVUz^Sp7j!|~+|?_dFOoDiq0z_w~gw^qtU{0I_% zOk#jxS;TROv?MdNx*lL8NGV977}J2d9WopZ8SW@Hx4IaH$!O$p?dN@zA2R&8hvnGx z`+Y8+yNKD}?xDOfTbDa*T`v2`Km5%HSlz#bw?_r0h|_QFoeH~B@_P^7T|VcQV~ggD z%i7^pmJcj2TeuddQKMON5NSwT#Mt*4S1L!gGc}0ao;HG=cRF<5>9BNgiKT-}EU&IG z=nok52Q06yXs4uhb~E^gzxe>byD|@O`r;O+FYXqC7wDz=$b;+EOSm&`sUFy@Fz*Ke zN-5$!o?o|Z+OA7G{U2Wi1j@%xtHVVs9h@5U^^fY`(QIjTI(Oz=)hlac%va&2GjZl( zhi^V}rgZHa&z#}(#SX5V&Vrp<{PiPC+a-Ub)ag+7@6S3=7K?Sf=3rytauYB95)JF^mMmnA+F% zBTGF0w?AXXHnA;J2PARGWHP2vmsnOpl0J4U{2AylyIWX7eV5^1lL;BaZu`H7)s?-EO zwSJsm`zObXr*fRRw9Pkvc$Po~$W+&aW#Xiv|QF0Sk1G@7W<05uw-Mnizy%Vc8#uJ?3F{M}F%z}?4+Uvp&4lQNyb zv_!tqP{h+OU8F+zV`N&-Ge|I_1S3qaq{OYy;MQlTTN2BzG2_mmc08m#gRmqKCNTzXV~(BC znEnk#qwa8Mu}xHS@Fyb<-nPi$V|Oy&-bWNgjD`a&%bKo$Pu`{D<07_t9^-M0Q{SWX z^B(Y@{pE!5tQ10^I+x z-OOiDI}vKUThI4G!0zS!^(RkNPXTcLN|v4NUF*vb1%8PDf{7yV$JL?OQnGbT8^2DW zM$k>&AHeDzZ>0#0BjWrjDlF0;IUmX-a}l=i}vE*E~5rokpymH-SKM^dZTsnsMH1_lt>H7uu& zVG3-wfwV0Ai9!g8U2~99U;wtXk+x04kr)Qdx(;BVe8t!sG2=EEdn3G&N59vj-}^ZL z#`;IrlKVcq%A@~04Sot0o5!Eq;MFS%6@LO1-#_9ly+~@k_bzbLSDikulm@Qz>lY1LE1JVPVcWg z{Ln`r5a~0bFw!b;^7XRS%<$?@dKKmYR4N3O(%#GisCXIzpSiNa(`P@#xy$Dmcmu9p zo7xAr(PZ`L8g8SB=Xv;nj~{5iUSvK9cZa;PATU3SN;}KNDzvmDuH)v+QxpKe*S=RS zWwL$3yJq{Gv|4+#7slM>sqk=AtP zWoj^kboPTV%8#XO=i#&;`uL$w5bn+s$W)+sV)bx2aq06PO5fiv9G(DRX>P#c+<@VD z8m-N`O=3&njRraMnQ7BHEeR$;E&xCDiNgr#*tjj1K>0{w`lG2qG=;#HHh$piyaGWG z>U#jhL_}ds6h=g0gz@la|7mi)JD}UuKftm2wD0`W{D!c%Te%gi?f(`+Y#}9h9s~i5 zDTl0?jus=%5)xe^YNfS41^C`{*~dxQV?~v6Pqvkw;U-V{hr#CXetcguelz?+=7Dj# zw-2BS`X28QlD`+20Q={g%%|ioJz5>}OT%Dtdwy)&;JP~bDJDQSgC7L=spQ5JpZ-v* zQgn-qXD}Z5;^#|?WTRgdz%Ne)09G4cBP$uWF0@wPfK-%kMd91+}i42~^Mqr@z~Ja@In+Ddy@%f;!- zUB2_;w5`WZVq{_KJQKi|{_UgObMI~!UfgH+6~1?0l@mI-mUq^!b1-~z(Wsz znui|#G{@JDl&%@S^SRIFW^5-~$4p)%K!?LVcN0){BYGywaIG`A)++#b!9BRSJ1*2S(#{7Hb9hT7kM;yI`o zJqlZU06+M%XAvJ+yE89~OLL1b4iRi2*uv%vE$by3<_kGl#x{<57RNkGOMHhJdxN(9 zG`6{gZEoQjZ(y76V4Lp%pu%dl=+Nnn`RvCJ0g#wwTVPPx4XvV}W{*F2mM{!4jOm3e z=`ny0pZM6W%~h+A?mzYC&te8i#Lgrj`;0>YIMYux`oc&WL|C(1`ej4%N4<3CijuM10h||m=^cAKlFiervD~Mt+4KPRu({ZDn zkOU*$+%$;dgeZ)%ds;^h6= z0F}z;^!clNCQm7XFu5XPl;G-;XGmSDz_C|`GF*K3k-I#W--ymt-q zR!}c=kO8#jn)GiBa#AYDOYhk$HJ+z`hb;wW)_Ez@?y9=&;M6p=XUqCy7q-3|GYv*N zqg?-OOCZxihD@2yYIJH6W+=) z`O{WgTU5M2oUo&IG-Esl1Y#95C_iZFVG=|T zkv0>h%-T|7OGzB-nq8bk^p)bNmo94GT#WatsOAD`9RJ$ot08O5V|8H3vftc-aq-wv8<%gGs<3wFjF+j|-dc z|COEp{zIL20GLuBT}j{tM1GvV4!6*9wIDo?!1r_eWjijyvWe1oMI68LNS+J4eRY$t z+S{9AXFTT6AsxS)X`ikzO~NoFiesc@kt7L8k|2b@Gz^j?A&#QyiV*^7Ld_D?ETM(r zdF*e_FyEX3pe`Mxu#m!HG#>Htn?K{~cAv2d=-%-7i&N)Ivu`E_hA?pt> zNRt4kK11Dcux*<-(kXKiN4XG;&wTp6JR7{Qu|e;8rL`oDR96;tySi{H6`Vcf<9O%npRN}$P!UZ>3vn>=aO)Cx zCVlnQNHQSAeln>?pmllA$DkZokLHw<_+*nlcaI&gxQC)*9pN@hTip z5`dR3dABBsjLP^BmgikIyIL=mQmh`Fy5DRcbhEGTk#&(Tr0+7A#?&?UulK=mSeTV~ ze$2wGETzMl04Qv&00ff&Z|H&J;MN4LZQ|AhSWfQ7d;Nai{qDA0 zq$A4(5rDc5?xxsdiN9BjClPTaA$Kdq%W6;H%>+OygedZHXKdW`9l&wQP>=;$1r^8y hK)SN3D?mDu{}1Qnm!&HWc|QOE002ovPDHLkV1n=133dPg diff --git a/data/obj/normalmap.png b/data/obj/normalmap.png deleted file mode 100644 index 486181e06a5e8158e5150ba1bbbef2ae3d47a696..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2|pq&xaLGBCC+FnlpB9?0h`@Q5sC zVBi)4Va7{$>;3=*g-cu`N`mv#O3D+9QW;z_i&B$IB0^FtPPu)X4wM%4ba4!k2v5$* k`0;-}Bd394afdJi!;xTSHj%>qZ$JeMp00i_>zopr0OM09W&i*H From 20964df102b52524ffefb8ef1c61d67e13c66968 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:09:55 -0400 Subject: [PATCH 07/32] Remove temp user file. --- XPlor.pro.user.40d992c | 625 ----------------------------------------- 1 file changed, 625 deletions(-) delete mode 100644 XPlor.pro.user.40d992c diff --git a/XPlor.pro.user.40d992c b/XPlor.pro.user.40d992c deleted file mode 100644 index 861b133..0000000 --- a/XPlor.pro.user.40d992c +++ /dev/null @@ -1,625 +0,0 @@ - - - - - - EnvironmentId - {40d992cb-ac11-4385-a22b-016f1b4251a7} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 0 - 80 - true - true - 1 - 0 - false - true - false - 2 - true - true - 0 - 8 - true - false - 1 - true - true - true - *.md, *.MD, Makefile - false - true - true - - - - ProjectExplorer.Project.PluginSettings - - - true - false - true - true - true - true - - false - - Unchecked - - - 0 - true - - true - true - Builtin.DefaultTidyAndClazy - 16 - true - - - - true - - - true - - - - - ProjectExplorer.Project.Target.0 - - Desktop - Desktop Qt 6.8.2 MSVC2022 64bit - Desktop Qt 6.8.2 MSVC2022 64bit - qt.qt6.682.win64_msvc2022_64_kit - 0 - 0 - 0 - - 0 - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_MSVC2022_64bit-Debug - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Debug - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - - - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_MSVC2022_64bit-Release - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Release - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - - - 0 - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_MSVC2022_64bit-Profile - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Profile - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - 0 - - 3 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - - Qt4ProjectManager.Qt4RunConfiguration: - G:/Projects/Qt/XPlor/app/app.pro - false - true - true - true - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Debug/app - - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - - Qt4ProjectManager.Qt4RunConfiguration: - G:/Projects/Qt/XPlor/tests/tests.pro - false - true - true - true - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Debug/tests - - 2 - - - - ProjectExplorer.Project.Target.1 - - Desktop - Desktop Qt 6.8.2 llvm-mingw 64-bit - Desktop Qt 6.8.2 llvm-mingw 64-bit - qt.qt6.682.win64_llvm_mingw_kit - 0 - 0 - 1 - - 0 - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_llvm_mingw_64_bit-Debug - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_llvm_mingw_64_bit-Debug - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - - - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_llvm_mingw_64_bit-Release - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_llvm_mingw_64_bit-Release - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - - - 0 - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_llvm_mingw_64_bit-Profile - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_llvm_mingw_64_bit-Profile - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - 0 - - 3 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - - Qt4ProjectManager.Qt4RunConfiguration: - G:/Projects/Qt/XPlor/app/app.pro - false - true - true - true - - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - - Qt4ProjectManager.Qt4RunConfiguration: - G:/Projects/Qt/XPlor/tests/tests.pro - false - true - true - true - - 2 - - - - ProjectExplorer.Project.Target.2 - - Desktop - Desktop Qt 6.8.1 MSVC2022 64bit - Desktop Qt 6.8.1 MSVC2022 64bit - qt.qt6.681.win64_msvc2022_64_kit - 0 - 0 - 0 - - 0 - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Debug - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - - - G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Release - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Release - - - true - QtProjectManager.QMakeBuildStep - false - - - - true - Qt4ProjectManager.MakeStep - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - clean - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - 0 - - 2 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - - Qt4ProjectManager.Qt4RunConfiguration: - G:/Projects/Qt/XPlor/app/app.pro - false - true - true - true - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug/app - - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - - Qt4ProjectManager.Qt4RunConfiguration: - G:/Projects/Qt/XPlor/tests/tests.pro - false - true - true - true - G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug/tests - - 2 - - - - ProjectExplorer.Project.TargetCount - 3 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - - From 8fe0e02e6412caf037c41485887f89d4a9ed7133 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:10:14 -0400 Subject: [PATCH 08/32] Added rumble file viewer. --- app/rumblefileviewer.cpp | 58 ++++++++++++ app/rumblefileviewer.h | 28 ++++++ app/rumblefileviewer.ui | 153 +++++++++++++++++++++++++++++++ app/rumblegraphviewer.cpp | 54 +++++++++++ app/rumblegraphviewer.h | 30 ++++++ app/rumblegraphviewer.ui | 153 +++++++++++++++++++++++++++++++ libs/core/highlighter_rumble.cpp | 37 ++++++++ libs/core/highlighter_rumble.h | 29 ++++++ 8 files changed, 542 insertions(+) create mode 100644 app/rumblefileviewer.cpp create mode 100644 app/rumblefileviewer.h create mode 100644 app/rumblefileviewer.ui create mode 100644 app/rumblegraphviewer.cpp create mode 100644 app/rumblegraphviewer.h create mode 100644 app/rumblegraphviewer.ui create mode 100644 libs/core/highlighter_rumble.cpp create mode 100644 libs/core/highlighter_rumble.h diff --git a/app/rumblefileviewer.cpp b/app/rumblefileviewer.cpp new file mode 100644 index 0000000..a6483f2 --- /dev/null +++ b/app/rumblefileviewer.cpp @@ -0,0 +1,58 @@ +#include "rumblefileviewer.h" +#include "ui_rumblefileviewer.h" + +RumbleFileViewer::RumbleFileViewer(QWidget *parent) + : QWidget(parent) + , ui(new Ui::RumbleFileViewer) + , mPropertyCount() + , mRumbleFile(nullptr) { + ui->setupUi(this); + + ui->tableWidget_Properties->setColumnCount(2); + ui->tableWidget_Properties->setRowCount(0); + ui->tableWidget_Properties->setColumnWidth(0, 200); + ui->tableWidget_Properties->horizontalHeader()->setStretchLastSection(true); +} + +RumbleFileViewer::~RumbleFileViewer() { + delete ui; +} + +void RumbleFileViewer::SetRumbleFile(std::shared_ptr aRumbleFile) { + mRumbleFile = aRumbleFile; + + ui->tableWidget_Properties->clear(); + + const QString magic = aRumbleFile->contents.left(6); + if (magic != "RUMBLE") { + qDebug() << "Rumble file has invalid magic: " << magic; + return; + } + + int firstIndex = 0; + int secondIndex = 0; + int thirdIndex = 0; + + int startIndex = 0; + for (int i = 0; i < aRumbleFile->contents.count("\\") / 2; i++) { + ui->tableWidget_Properties->setRowCount(i + 1); + ui->spinBox_Entries->setValue(i + 1); + + firstIndex = aRumbleFile->contents.indexOf("\\", startIndex); + secondIndex = aRumbleFile->contents.indexOf("\\", firstIndex + 1); + thirdIndex = aRumbleFile->contents.indexOf("\\", secondIndex + 1); + if (thirdIndex == -1) { + thirdIndex = aRumbleFile->contents.size(); + } + + const QString keyStr = aRumbleFile->contents.mid(firstIndex + 1, secondIndex - firstIndex - 1); + QTableWidgetItem *keyItem = new QTableWidgetItem(keyStr); + ui->tableWidget_Properties->setItem(i, 0, keyItem); + + const QString valStr = aRumbleFile->contents.mid(secondIndex + 1, thirdIndex - secondIndex - 1); + QTableWidgetItem *valueItem = new QTableWidgetItem(valStr); + ui->tableWidget_Properties->setItem(i, 1, valueItem); + + startIndex = thirdIndex; + } +} diff --git a/app/rumblefileviewer.h b/app/rumblefileviewer.h new file mode 100644 index 0000000..eb21e23 --- /dev/null +++ b/app/rumblefileviewer.h @@ -0,0 +1,28 @@ +#ifndef RUMBLEFILEVIEWER_H +#define RUMBLEFILEVIEWER_H + +#include "asset_structs.h" +#include "zonefile.h" +#include + +namespace Ui { +class RumbleFileViewer; +} + +class RumbleFileViewer : public QWidget +{ + Q_OBJECT + +public: + explicit RumbleFileViewer(QWidget *parent = nullptr); + ~RumbleFileViewer(); + + void SetRumbleFile(std::shared_ptr aRumbleFile); + +private: + Ui::RumbleFileViewer *ui; + quint32 mPropertyCount; + std::shared_ptr mRumbleFile; +}; + +#endif // RUMBLEFILEVIEWER_H diff --git a/app/rumblefileviewer.ui b/app/rumblefileviewer.ui new file mode 100644 index 0000000..e9d0174 --- /dev/null +++ b/app/rumblefileviewer.ui @@ -0,0 +1,153 @@ + + + RumbleFileViewer + + + + 0 + 0 + 841 + 457 + + + + + 841 + 457 + + + + Form + + + + + + + Roboto + 16 + true + + + + Rumble File Viewer + + + + + + + + + + + + 325 + 398 + + + + + 325 + 16777215 + + + + + Roboto + 9 + + + + Header + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + false + + + 10000 + + + 1 + + + + + + + Entries: + + + + + + + + + + + + + 400 + 400 + + + + + Roboto + 9 + + + + Properties + + + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 0 + + + + + + + + + diff --git a/app/rumblegraphviewer.cpp b/app/rumblegraphviewer.cpp new file mode 100644 index 0000000..ca3dc8e --- /dev/null +++ b/app/rumblegraphviewer.cpp @@ -0,0 +1,54 @@ +#include "rumblegraphviewer.h" +#include "ui_rumblegraphviewer.h" + +RumbleGraphViewer::RumbleGraphViewer(QWidget *parent) + : QWidget(parent) + , ui(new Ui::RumbleGraphViewer), + mEntryCount(), + mRumbleGraphFile(nullptr) { + ui->setupUi(this); + + ui->tableWidget_Entries->setColumnCount(2); + ui->tableWidget_Entries->setHorizontalHeaderLabels({ "X", "Y" }); + ui->tableWidget_Entries->setRowCount(0); + ui->tableWidget_Entries->setColumnWidth(0, 200); + ui->tableWidget_Entries->horizontalHeader()->setStretchLastSection(true); +} + +RumbleGraphViewer::~RumbleGraphViewer() { + delete ui; +} + +void RumbleGraphViewer::SetRumbleGraphFile(const std::shared_ptr aRawFile) { + mRumbleGraphFile = aRawFile; + + QDataStream rawFileStream(mRumbleGraphFile->contents.toLatin1()); + + QByteArray magic(15, Qt::Uninitialized); + rawFileStream.readRawData(magic.data(), 15); + + rawFileStream.skipRawData(4); + + char sectionChar; + rawFileStream >> sectionChar; + int sectionCount = sectionChar - '0'; + ui->tableWidget_Entries->setRowCount(sectionCount); + ui->spinBox_Entries->setValue(sectionCount); + ui->groupBox_LocalStrViewer->setTitle(QString("Entries (%1)").arg(sectionCount)); + + rawFileStream.skipRawData(2); + + for (int i = 0; i < sectionCount; i++) { + QByteArray xVal(6, Qt::Uninitialized), yVal(6, Qt::Uninitialized); + rawFileStream.readRawData(xVal.data(), 6); + rawFileStream.skipRawData(1); + rawFileStream.readRawData(yVal.data(), 6); + rawFileStream.skipRawData(2); + + QTableWidgetItem *xItem = new QTableWidgetItem(xVal); + QTableWidgetItem *yItem = new QTableWidgetItem(yVal); + + ui->tableWidget_Entries->setItem(i, 0, xItem); + ui->tableWidget_Entries->setItem(i, 1, yItem); + } +} diff --git a/app/rumblegraphviewer.h b/app/rumblegraphviewer.h new file mode 100644 index 0000000..6f8e498 --- /dev/null +++ b/app/rumblegraphviewer.h @@ -0,0 +1,30 @@ +#ifndef RUMBLEGRAPHVIEWER_H +#define RUMBLEGRAPHVIEWER_H + +#include "asset_structs.h" +#include "zonefile.h" +#include + +namespace Ui { +class RumbleGraphViewer; +} + +class RumbleGraphViewer : public QWidget +{ + Q_OBJECT + +public: + explicit RumbleGraphViewer(QWidget *parent = nullptr); + ~RumbleGraphViewer(); + + void SetEntryCount(quint32 aCount); + void SetRumbleGraphFile(const std::shared_ptr aRawFile); + void SetZoneFile(std::shared_ptr aZoneFile); + +private: + Ui::RumbleGraphViewer *ui; + quint32 mEntryCount; + std::shared_ptr mRumbleGraphFile; +}; + +#endif // RUMBLEGRAPHVIEWER_H diff --git a/app/rumblegraphviewer.ui b/app/rumblegraphviewer.ui new file mode 100644 index 0000000..36ab973 --- /dev/null +++ b/app/rumblegraphviewer.ui @@ -0,0 +1,153 @@ + + + RumbleGraphViewer + + + + 0 + 0 + 841 + 457 + + + + + 841 + 457 + + + + Form + + + + + + + Roboto + 16 + true + + + + Rumble Graph File + + + + + + + + + + + + 325 + 398 + + + + + 325 + 16777215 + + + + + Roboto + 9 + + + + Header + + + + + + Entry Count: + + + + + + + false + + + 10000 + + + 0 + + + + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + 400 + 400 + + + + + Roboto + 9 + + + + Entries + + + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 0 + + + + + + + + + diff --git a/libs/core/highlighter_rumble.cpp b/libs/core/highlighter_rumble.cpp new file mode 100644 index 0000000..4bbb45c --- /dev/null +++ b/libs/core/highlighter_rumble.cpp @@ -0,0 +1,37 @@ +#include "highlighter_rumble.h" + +Highlighter_Rumble::Highlighter_Rumble(QTextDocument *parent) + : QSyntaxHighlighter(parent) { + HighlightingRule rule; + + // Format for the "RUMBLEGRAPHFILE" header + headerFormat.setForeground(QColor("#569CD6")); + headerFormat.setFontWeight(QFont::Bold); + rule.pattern = QRegularExpression(QStringLiteral("^RUMBLEGRAPHFILE\\b")); + rule.format = headerFormat; + highlightingRules.append(rule); + + // Format for line count (second line, typically a single integer) + countFormat.setForeground(QColor("#C586C0")); + rule.pattern = QRegularExpression(QStringLiteral("^\\d+$")); + rule.format = countFormat; + highlightingRules.append(rule); + + // Format for floating-point number pairs (e.g. 0.0000 0.4701) + floatPairFormat.setForeground(QColor("#B5CEA8")); + rule.pattern = QRegularExpression(QStringLiteral("^\\s*-?\\d+\\.\\d+\\s+-?\\d+\\.\\d+\\s*$")); + rule.format = floatPairFormat; + highlightingRules.append(rule); +} + +void Highlighter_Rumble::highlightBlock(const QString &text) { + for (const HighlightingRule &rule : std::as_const(highlightingRules)) { + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); + while (matchIterator.hasNext()) { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), rule.format); + } + } + + setCurrentBlockState(0); +} diff --git a/libs/core/highlighter_rumble.h b/libs/core/highlighter_rumble.h new file mode 100644 index 0000000..2f45664 --- /dev/null +++ b/libs/core/highlighter_rumble.h @@ -0,0 +1,29 @@ +#ifndef HIGHLIGHTER_RUMBLE_H +#define HIGHLIGHTER_RUMBLE_H + +#include +#include + +class Highlighter_Rumble : public QSyntaxHighlighter +{ + Q_OBJECT + +public: + Highlighter_Rumble(QTextDocument *parent = nullptr); + +protected: + void highlightBlock(const QString &text) override; + +private: + struct HighlightingRule { + QRegularExpression pattern; + QTextCharFormat format; + }; + QVector highlightingRules; + + QTextCharFormat headerFormat; + QTextCharFormat countFormat; + QTextCharFormat floatPairFormat; +}; + +#endif // HIGHLIGHTER_RUMBLE_H From db9165295fecccea518370f7fc12a953f2b5225b Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:10:49 -0400 Subject: [PATCH 09/32] Add syntax highlighting for gsc, rmb, and shock files. --- libs/core/highlighter_cfg.cpp | 111 +++++++++++++++++++++++++ libs/core/highlighter_cfg.h | 45 +++++++++++ libs/core/highlighter_gsc.cpp | 138 ++++++++++++++++++++++++++++++++ libs/core/highlighter_gsc.h | 42 ++++++++++ libs/core/highlighter_shock.cpp | 43 ++++++++++ libs/core/highlighter_shock.h | 30 +++++++ 6 files changed, 409 insertions(+) create mode 100644 libs/core/highlighter_cfg.cpp create mode 100644 libs/core/highlighter_cfg.h create mode 100644 libs/core/highlighter_gsc.cpp create mode 100644 libs/core/highlighter_gsc.h create mode 100644 libs/core/highlighter_shock.cpp create mode 100644 libs/core/highlighter_shock.h diff --git a/libs/core/highlighter_cfg.cpp b/libs/core/highlighter_cfg.cpp new file mode 100644 index 0000000..1609fa8 --- /dev/null +++ b/libs/core/highlighter_cfg.cpp @@ -0,0 +1,111 @@ +#include "highlighter_cfg.h" + +Highlighter_CFG::Highlighter_CFG(QTextDocument *parent) + : QSyntaxHighlighter(parent) { + HighlightingRule rule; + + // Command keywords: set, seta, bind, etc. + keywordFormat.setForeground(QColor("#569CD6")); + keywordFormat.setFontWeight(QFont::Bold); + const QString keywordPatterns[] = { + QStringLiteral("\\bset\\b"), + QStringLiteral("\\bseta\\b"), + QStringLiteral("\\bbind\\b"), + QStringLiteral("\\bvstr\\b"), + QStringLiteral("\\bsay\\b"), + QStringLiteral("\\bwait\\b"), + QStringLiteral("\\bexec\\b"), + QStringLiteral("\\bunbind\\b"), + QStringLiteral("\\bcreatefx\\b"), + QStringLiteral("\\bcreatefx_drawdist\\b"), + QStringLiteral("\\bcreatefx_scaleid\\b"), + QStringLiteral("\\bbindaxis\\b") + }; + for (const QString &pattern : keywordPatterns) { + rule.pattern = QRegularExpression(pattern); + rule.format = keywordFormat; + highlightingRules.append(rule); + } + + // Button constants: BUTTON_*, DPAD_* + buttonFormat.setForeground(QColor("#4EC9B0")); + rule.pattern = QRegularExpression(QStringLiteral("\\b(BUTTON|DPAD)_[A-Z]+\\b")); + rule.format = buttonFormat; + highlightingRules.append(rule); + + // Highlight *entire* 'bind var' or 'seta var' as one match, so we can highlight the variable part manually in highlightBlock() + // Regex captures the command and the following variable as two groups + bindSetVariablePattern = QRegularExpression(QStringLiteral("\\b(bind|bindaxis|set|seta)\\s+(\\w+)")); + + // Quoted strings (highlight first so numbers inside are overridden) + quotationFormat.setForeground(QColor("#CE9178")); + rule.pattern = QRegularExpression(QStringLiteral("\".*?\"")); + rule.format = quotationFormat; + highlightingRules.append(rule); + + // Numbers (normal numbers, no filtering for inside strings, since strings override them) + numberFormat.setForeground(QColor("#B5CEA8")); + rule.pattern = QRegularExpression(QStringLiteral("\\b-?\\d+(\\.\\d+)?f?\\b")); + rule.format = numberFormat; + highlightingRules.append(rule); + + // Comments: single-line comments with // + singleLineCommentFormat.setForeground(QColor("#6A9955")); + rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*")); + rule.format = singleLineCommentFormat; + highlightingRules.append(rule); + + // Command chaining symbol: ; + operatorFormat.setForeground(QColor("#D4D4D4")); + rule.pattern = QRegularExpression(QStringLiteral(";")); + rule.format = operatorFormat; + highlightingRules.append(rule); +} + +void Highlighter_CFG::highlightBlock(const QString &text) { + // Apply all standard highlighting rules + for (const HighlightingRule &rule : std::as_const(highlightingRules)) { + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); + while (matchIterator.hasNext()) { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), rule.format); + } + } + + // Highlight the immediate variable after 'bind', 'bindaxis', 'set', or 'seta' + QRegularExpressionMatchIterator iter = bindSetVariablePattern.globalMatch(text); + while (iter.hasNext()) { + QRegularExpressionMatch match = iter.next(); + int varStart = match.capturedStart(2); // Group 2 is the variable + int varLength = match.capturedLength(2); + setFormat(varStart, varLength, variableFormat); + } + + setCurrentBlockState(0); + + // Handle multiline comments safely + int startIndex = 0; + if (previousBlockState() != 1) + startIndex = text.indexOf(commentStartExpression); + + while (startIndex >= 0) { + QRegularExpressionMatch match = commentEndExpression.match(text, startIndex); + int endIndex = match.hasMatch() ? match.capturedStart() : -1; + + int commentLength; + if (endIndex == -1) { + setCurrentBlockState(1); + commentLength = text.length() - startIndex; + } else { + commentLength = endIndex - startIndex + match.capturedLength(); + } + + // Safety check to avoid infinite loops + if (commentLength <= 0) { + break; + } + + setFormat(startIndex, commentLength, multiLineCommentFormat); + startIndex = text.indexOf(commentStartExpression, startIndex + commentLength); + } +} diff --git a/libs/core/highlighter_cfg.h b/libs/core/highlighter_cfg.h new file mode 100644 index 0000000..a2a764a --- /dev/null +++ b/libs/core/highlighter_cfg.h @@ -0,0 +1,45 @@ +#ifndef HIGHLIGHTER_CFG_H +#define HIGHLIGHTER_CFG_H + +#include +#include + +class Highlighter_CFG : public QSyntaxHighlighter +{ + Q_OBJECT + +public: + Highlighter_CFG(QTextDocument *parent = nullptr); + +protected: + void highlightBlock(const QString &text) override; + +private: + struct HighlightingRule + { + QRegularExpression pattern; + QTextCharFormat format; + }; + QList highlightingRules; + + QRegularExpression commentStartExpression; + QRegularExpression commentEndExpression; + QRegularExpression bindSetVariablePattern; + QTextCharFormat buttonFormat; + QTextCharFormat operatorFormat; + QTextCharFormat keywordFormat; + QTextCharFormat classFormat; + QTextCharFormat quotationFormat; + QTextCharFormat functionFormat; + QTextCharFormat singleLineCommentFormat; + QTextCharFormat multiLineCommentFormat; + QTextCharFormat preprocessorFormat; + QTextCharFormat variableFormat; + QTextCharFormat numberFormat; + QTextCharFormat devBlockCommentFormat; + + QRegularExpression devCommentStart; + QRegularExpression devCommentEnd; +}; + +#endif // HIGHLIGHTER_CFG_H diff --git a/libs/core/highlighter_gsc.cpp b/libs/core/highlighter_gsc.cpp new file mode 100644 index 0000000..94ea303 --- /dev/null +++ b/libs/core/highlighter_gsc.cpp @@ -0,0 +1,138 @@ +#include "highlighter_gsc.h" + +Highlighter_GSC::Highlighter_GSC(QTextDocument *parent) + : QSyntaxHighlighter(parent) { + HighlightingRule rule; + + // C++ Keywords + keywordFormat.setForeground(QColor("#569CD6")); + keywordFormat.setFontWeight(QFont::Bold); + const QString keywordPatterns[] = { + QStringLiteral("\\bchar\\b"), QStringLiteral("\\bclass\\b"), QStringLiteral("\\bconst\\b"), + QStringLiteral("\\bdouble\\b"), QStringLiteral("\\benum\\b"), QStringLiteral("\\bexplicit\\b"), + QStringLiteral("\\bfriend\\b"), QStringLiteral("\\binline\\b"), QStringLiteral("\\bint\\b"), + QStringLiteral("\\blong\\b"), QStringLiteral("\\bnamespace\\b"), QStringLiteral("\\boperator\\b"), + QStringLiteral("\\bprivate\\b"), QStringLiteral("\\bprotected\\b"), QStringLiteral("\\bpublic\\b"), + QStringLiteral("\\bshort\\b"), QStringLiteral("\\bsignals\\b"), QStringLiteral("\\bsigned\\b"), + QStringLiteral("\\bslots\\b"), QStringLiteral("\\bstatic\\b"), QStringLiteral("\\bstruct\\b"), + QStringLiteral("\\btemplate\\b"), QStringLiteral("\\btypedef\\b"), QStringLiteral("\\btypename\\b"), + QStringLiteral("\\bunion\\b"), QStringLiteral("\\bunsigned\\b"), QStringLiteral("\\bvirtual\\b"), + QStringLiteral("\\bvoid\\b"), QStringLiteral("\\bvolatile\\b"), QStringLiteral("\\bbool\\b") + }; + for (const QString &pattern : keywordPatterns) { + rule.pattern = QRegularExpression(pattern); + rule.format = keywordFormat; + highlightingRules.append(rule); + } + + // GSC Control Keywords + const QString gscKeywords[] = { + QStringLiteral("\\bif\\b"), QStringLiteral("\\belse\\b"), QStringLiteral("\\bswitch\\b"), + QStringLiteral("\\bcase\\b"), QStringLiteral("\\bbreak\\b"), QStringLiteral("\\bbreakpoint\\b"), + QStringLiteral("\\bcontinue\\b"), QStringLiteral("\\bfor\\b"), QStringLiteral("\\bwhile\\b"), + QStringLiteral("\\breturn\\b"), QStringLiteral("\\bdefault\\b"), QStringLiteral("\\bwait\\b"), + QStringLiteral("\\bwaittill\\b"), QStringLiteral("\\bwaittillframeend\\b"), + QStringLiteral("\\bendon\\b"), QStringLiteral("\\bnotify\\b"), QStringLiteral("\\bthread\\b") + }; + for (const QString &pattern : gscKeywords) { + rule.pattern = QRegularExpression(pattern); + rule.format = keywordFormat; + highlightingRules.append(rule); + } + + // Class format + classFormat.setForeground(QColor("#C586C0")); + classFormat.setFontWeight(QFont::Bold); + rule.pattern = QRegularExpression(QStringLiteral("\\bQ[A-Za-z]+\\b")); + rule.format = classFormat; + highlightingRules.append(rule); + + // Preprocessor: #include and #using_animtree + preprocessorFormat.setForeground(QColor("#D7BA7D")); + preprocessorFormat.setFontWeight(QFont::Bold); + rule.pattern = QRegularExpression(QStringLiteral("^\\s*#(?:include|using_animtree)\\b.*")); + rule.format = preprocessorFormat; + highlightingRules.append(rule); + + // Hardcoded Variables: self, level, game + variableFormat.setForeground(QColor("#4EC9B0")); + rule.pattern = QRegularExpression(QStringLiteral("\\b(self|level|game)\\b")); + rule.format = variableFormat; + highlightingRules.append(rule); + + // Quoted Strings + quotationFormat.setForeground(QColor("#CE9178")); + rule.pattern = QRegularExpression(QStringLiteral("\".*?\"")); + rule.format = quotationFormat; + highlightingRules.append(rule); + + // Numeric literals (including optional .f) + numberFormat.setForeground(QColor("#B5CEA8")); + rule.pattern = QRegularExpression(QStringLiteral("\\b-?\\d+(\\.\\d+)?f?\\b")); + rule.format = numberFormat; + highlightingRules.append(rule); + + // Boolean literals + rule.pattern = QRegularExpression(QStringLiteral("\\b(true|false|undefined)\\b")); + rule.format = numberFormat; + highlightingRules.append(rule); + + // Function calls + functionFormat.setForeground(QColor("#9CDCFE")); + functionFormat.setFontItalic(true); + rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Za-z_][A-Za-z0-9_]*(?=\\s*\\()")); + rule.format = functionFormat; + highlightingRules.append(rule); + + // Function pointers ::func + rule.pattern = QRegularExpression(QStringLiteral("::\\b(\\w+)\\b")); + rule.format = functionFormat; + highlightingRules.append(rule); + + // Single-line comments + singleLineCommentFormat.setForeground(QColor("#6A9955")); + rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*")); + rule.format = singleLineCommentFormat; + highlightingRules.append(rule); + + // Developer block comments /# ... #/ + devBlockCommentFormat.setForeground(QColor("#6A9955")); + devCommentStart = QRegularExpression(QStringLiteral("/#")); + devCommentEnd = QRegularExpression(QStringLiteral("#/")); + + // Multi-line comment /* ... */ + multiLineCommentFormat.setForeground(QColor("#6A9955")); + commentStartExpression = QRegularExpression(QStringLiteral("/\\*")); + commentEndExpression = QRegularExpression(QStringLiteral("\\*/")); +} + + +void Highlighter_GSC::highlightBlock(const QString &text) { + for (const HighlightingRule &rule : std::as_const(highlightingRules)) { + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); + while (matchIterator.hasNext()) { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), rule.format); + } + } + setCurrentBlockState(0); + + int startIndex = 0; + if (previousBlockState() != 1) + startIndex = text.indexOf(commentStartExpression); + + while (startIndex >= 0) { + QRegularExpressionMatch match = commentEndExpression.match(text, startIndex); + int endIndex = match.capturedStart(); + int commentLength = 0; + if (endIndex == -1) { + setCurrentBlockState(1); + commentLength = text.length() - startIndex; + } else { + commentLength = endIndex - startIndex + + match.capturedLength(); + } + setFormat(startIndex, commentLength, multiLineCommentFormat); + startIndex = text.indexOf(commentStartExpression, startIndex + commentLength); + } +} diff --git a/libs/core/highlighter_gsc.h b/libs/core/highlighter_gsc.h new file mode 100644 index 0000000..0fbeb62 --- /dev/null +++ b/libs/core/highlighter_gsc.h @@ -0,0 +1,42 @@ +#ifndef HIGHLIGHTER_GSC_H +#define HIGHLIGHTER_GSC_H + +#include +#include + +class Highlighter_GSC : public QSyntaxHighlighter +{ + Q_OBJECT + +public: + Highlighter_GSC(QTextDocument *parent = nullptr); + +protected: + void highlightBlock(const QString &text) override; + +private: + struct HighlightingRule + { + QRegularExpression pattern; + QTextCharFormat format; + }; + QList highlightingRules; + + QRegularExpression commentStartExpression; + QRegularExpression commentEndExpression; + QTextCharFormat keywordFormat; + QTextCharFormat classFormat; + QTextCharFormat quotationFormat; + QTextCharFormat functionFormat; + QTextCharFormat singleLineCommentFormat; + QTextCharFormat multiLineCommentFormat; + QTextCharFormat preprocessorFormat; + QTextCharFormat variableFormat; + QTextCharFormat numberFormat; + QTextCharFormat devBlockCommentFormat; + + QRegularExpression devCommentStart; + QRegularExpression devCommentEnd; +}; + +#endif // HIGHLIGHTER_GSC_H diff --git a/libs/core/highlighter_shock.cpp b/libs/core/highlighter_shock.cpp new file mode 100644 index 0000000..17f4675 --- /dev/null +++ b/libs/core/highlighter_shock.cpp @@ -0,0 +1,43 @@ +#include "highlighter_shock.h" + +Highlighter_Shock::Highlighter_Shock(QTextDocument *parent) + : QSyntaxHighlighter(parent) { + HighlightingRule rule; + + // Format for bg_shock_* keys + keyFormat.setForeground(QColor("#569CD6")); + keyFormat.setFontWeight(QFont::Bold); + rule.pattern = QRegularExpression(QStringLiteral("\\bbg_shock_[\\w]+\\b")); + rule.format = keyFormat; + highlightingRules.append(rule); + + // Format for quoted string values + stringFormat.setForeground(QColor("#CE9178")); + rule.pattern = QRegularExpression(QStringLiteral("\"[^\"]*\"")); + rule.format = stringFormat; + highlightingRules.append(rule); + + // Format for numeric values inside quotes (overridden by stringFormat but still useful for raw values) + numberFormat.setForeground(QColor("#B5CEA8")); + rule.pattern = QRegularExpression(QStringLiteral("-?\\d+(\\.\\d+)?")); + rule.format = numberFormat; + highlightingRules.append(rule); + + // Optional: Format for control groups (e.g., bg_shock_volume_*) + subgroupFormat.setForeground(QColor("#4EC9B0")); + rule.pattern = QRegularExpression(QStringLiteral("\\bbg_shock_volume_\\w+\\b")); + rule.format = subgroupFormat; + highlightingRules.append(rule); +} + +void Highlighter_Shock::highlightBlock(const QString &text) { + for (const HighlightingRule &rule : std::as_const(highlightingRules)) { + QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); + while (matchIterator.hasNext()) { + QRegularExpressionMatch match = matchIterator.next(); + setFormat(match.capturedStart(), match.capturedLength(), rule.format); + } + } + + setCurrentBlockState(0); +} diff --git a/libs/core/highlighter_shock.h b/libs/core/highlighter_shock.h new file mode 100644 index 0000000..7215c70 --- /dev/null +++ b/libs/core/highlighter_shock.h @@ -0,0 +1,30 @@ +#ifndef HIGHLIGHTER_SHOCK_H +#define HIGHLIGHTER_SHOCK_H + +#include +#include + +class Highlighter_Shock : public QSyntaxHighlighter +{ + Q_OBJECT + +public: + Highlighter_Shock(QTextDocument *parent = nullptr); + +protected: + void highlightBlock(const QString &text) override; + +private: + struct HighlightingRule { + QRegularExpression pattern; + QTextCharFormat format; + }; + QVector highlightingRules; + + QTextCharFormat keyFormat; + QTextCharFormat stringFormat; + QTextCharFormat numberFormat; + QTextCharFormat subgroupFormat; +}; + +#endif // HIGHLIGHTER_SHOCK_H From 4dd68a06e8fdb8f7716825c19923b0ffe70c838e Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:11:12 -0400 Subject: [PATCH 10/32] Added rumble file viewer. --- app/app.pro | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/app.pro b/app/app.pro index f10aa63..618e6e4 100644 --- a/app/app.pro +++ b/app/app.pro @@ -19,6 +19,8 @@ SOURCES += \ preferenceeditor.cpp \ soundviewer.cpp \ stringtableviewer.cpp \ + rumblegraphviewer.cpp \ + rumblefileviewer.cpp \ techsetviewer.cpp \ xtreewidget.cpp \ xtreewidgetitem.cpp \ @@ -37,6 +39,8 @@ HEADERS += \ preferenceeditor.h \ soundviewer.h \ stringtableviewer.h \ + rumblegraphviewer.h \ + rumblefileviewer.h \ techsetviewer.h \ xtreewidget.h \ xtreewidgetitem.h \ @@ -55,6 +59,8 @@ FORMS += \ preferenceeditor.ui \ soundviewer.ui \ stringtableviewer.ui \ + rumblegraphviewer.ui \ + rumblefileviewer.ui \ techsetviewer.ui \ zonefileviewer.ui From 9dd0bd9897d24973a595b86304940c0dd74e4f3f Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:11:50 -0400 Subject: [PATCH 11/32] Fix LocalStrViewer entry count and rename group box. --- app/localstringviewer.cpp | 7 +++++-- app/localstringviewer.ui | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/localstringviewer.cpp b/app/localstringviewer.cpp index 6550668..891b1e4 100644 --- a/app/localstringviewer.cpp +++ b/app/localstringviewer.cpp @@ -10,6 +10,7 @@ LocalStringViewer::LocalStringViewer(QWidget *parent) ui->setupUi(this); ui->tableWidget_Strings->setColumnCount(2); + ui->tableWidget_Strings->setRowCount(0); ui->tableWidget_Strings->setColumnWidth(0, 200); ui->tableWidget_Strings->horizontalHeader()->setStretchLastSection(true); } @@ -37,10 +38,12 @@ void LocalStringViewer::SetFileNotes(const QString aFileNotes) { } void LocalStringViewer::AddLocalString(LocalString aLocalString) { - mLocalStrings << aLocalString; + mLocalStrings.append(aLocalString); ui->tableWidget_Strings->setRowCount(mLocalStrings.size()); + ui->groupBox_LocalStrViewer->setTitle(QString("Entries (%1)").arg(mLocalStrings.size())); + QTableWidgetItem *aliasItem = new QTableWidgetItem(aLocalString.alias); QTableWidgetItem *stringItem = new QTableWidgetItem(aLocalString.string); @@ -53,7 +56,7 @@ void LocalStringViewer::SetZoneFile(std::shared_ptr aZoneFile) { ui->tableWidget_Strings->clear(); ui->label_Title->setText(aZoneFile->GetStem().section('.', 0, 0) + ".str"); - for (LocalString localStr : aZoneFile->GetAssetMap().localStrings) { + for (const LocalString &localStr : aZoneFile->GetAssetMap().localStrings) { AddLocalString(localStr); } } diff --git a/app/localstringviewer.ui b/app/localstringviewer.ui index bdd547e..f8ccfa8 100644 --- a/app/localstringviewer.ui +++ b/app/localstringviewer.ui @@ -142,7 +142,7 @@ - + 400 From c056b451849b4d7bcbf7a838475b5230d1064ea6 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:13:13 -0400 Subject: [PATCH 12/32] Add tabs for rumble and shock file viewing. --- app/mainwindow.cpp | 58 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index 565b339..8ce0da2 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -1,13 +1,18 @@ #include "mainwindow.h" #include "aboutdialog.h" #include "fastfile.h" +#include "highlighter_gsc.h" +#include "highlighter_cfg.h" +#include "highlighter_shock.h" +#include "highlighter_rumble.h" #include "materialviewer.h" #include "preferenceeditor.h" +#include "rumblefileviewer.h" +#include "rumblegraphviewer.h" #include "soundviewer.h" #include "stringtableviewer.h" #include "techsetviewer.h" #include "ui_mainwindow.h" -#include "compression.h" #include "fastfile_factory.h" #include "iwifile.h" #include "ddsfile.h" @@ -144,9 +149,13 @@ MainWindow::MainWindow(QWidget *parent) }); connect(mTreeWidget, &XTreeWidget::RawFileSelected, this, [this](std::shared_ptr rawFile, const QString aParentName) { - QPlainTextEdit *scriptEditor = new QPlainTextEdit(this); + QTabWidget *rawTabWidget = new QTabWidget(this); + rawTabWidget->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); + + QPlainTextEdit *scriptEditor = new QPlainTextEdit(rawTabWidget); scriptEditor->setAcceptDrops(false); scriptEditor->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); + scriptEditor->setFont(QFont("Consolas")); if (rawFile->contents.isEmpty()) { scriptEditor->setPlainText("EMPTY"); @@ -157,15 +166,52 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = rawFile->path.split('/').last(); for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete scriptEditor; return; } } - QScrollArea *scrollArea = new QScrollArea(ui->tabWidget); - scrollArea->layout()->addWidget(scriptEditor); + const int tabStopSpaces = 4; + QFontMetrics metrics(scriptEditor->font()); + scriptEditor->setTabStopDistance(tabStopSpaces * metrics.horizontalAdvance(' ')); - ui->tabWidget->addTab(scrollArea, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_GSCFile.png")); + QSyntaxHighlighter *highlighter; + if (fileStem.contains(".gsc")) { + highlighter = new Highlighter_GSC(scriptEditor->document()); + } else if (fileStem.contains(".cfg")) { + highlighter = new Highlighter_CFG(scriptEditor->document()); + } else if (fileStem.contains(".rmb")) { + highlighter = new Highlighter_Rumble(scriptEditor->document()); + + RumbleGraphViewer *rmbGraphViewer = new RumbleGraphViewer(this); + rmbGraphViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); + rmbGraphViewer->SetRumbleGraphFile(rawFile); + + rawTabWidget->addTab(rmbGraphViewer, "UI Editor"); + rawTabWidget->addTab(scriptEditor, "Text Editor"); + + ui->tabWidget->addTab(rawTabWidget, fileStem); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_RUMBLE)); + ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); + return; + } else if (fileStem.contains(".shock")) { + highlighter = new Highlighter_Shock(scriptEditor->document()); + } else if (rawFile->contents.left(6) == "RUMBLE") { + RumbleFileViewer *rmbFileViewer = new RumbleFileViewer(this); + rmbFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); + rmbFileViewer->SetRumbleFile(rawFile); + + rawTabWidget->addTab(rmbFileViewer, "UI Editor"); + rawTabWidget->addTab(scriptEditor, "Text Editor"); + + ui->tabWidget->addTab(rawTabWidget, fileStem); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_RUMBLE)); + ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); + return; + } + + ui->tabWidget->addTab(scriptEditor, fileStem); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_RAW_FILE)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); From 72846f473350352ed5a34f2b1c416eb17f6b2626 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:14:24 -0400 Subject: [PATCH 13/32] Update mainwindow, add highlighting, and fix viewer logic. --- app/mainwindow.cpp | 55 ++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index 8ce0da2..07605bc 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -224,12 +224,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = image->materialName; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete mImageWidget; return; } } ui->tabWidget->addTab(mImageWidget, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_Image.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_IMAGE)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -237,24 +238,6 @@ MainWindow::MainWindow(QWidget *parent) Q_UNUSED(menu); }); - connect(mTreeWidget, &XTreeWidget::DDSFileSelected, this, [this](std::shared_ptr ddsFile, const QString aParentName) { - DDSViewer *ddsViewer = new DDSViewer(this); - ddsViewer->setAcceptDrops(false); - ddsViewer->SetDDSFile(ddsFile); - ddsViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); - - QString fileStem = ddsFile->fileStem + ".dds"; - for (int i = 0; i < ui->tabWidget->count(); i++) { - if (ui->tabWidget->tabText(i) == fileStem) { - return; - } - } - - ui->tabWidget->addTab(ddsViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_DDSFile.png")); - ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); - }); - connect(mTreeWidget, &XTreeWidget::MaterialSelected, this, [this](std::shared_ptr material, const QString aParentName) { MaterialViewer *matViewer = new MaterialViewer(this); matViewer->setAcceptDrops(false); @@ -264,12 +247,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = material->name; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete matViewer; return; } } ui->tabWidget->addTab(matViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_Material.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_MATERIAL)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -282,12 +266,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = ddsFile->fileStem + ".dds"; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete ddsViewer; return; } } ui->tabWidget->addTab(ddsViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_DDSFile.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_IMAGE)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -300,12 +285,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = iwiFile->fileStem + ".iwi"; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete iwiViewer; return; } } ui->tabWidget->addTab(iwiViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_IWIFile.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_IMAGE)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -317,13 +303,14 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = aFastFile->GetStem(); for (int i = 0; i < ui->tabWidget->count(); i++) { - if (ui->tabWidget->tabText(i) == fileStem + ".ff") { + if (ui->tabWidget->tabText(i) == fileStem) { + delete fastFileViewer; return; } } ui->tabWidget->addTab(fastFileViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_FastFile.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_FAST_FILE)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -333,9 +320,10 @@ MainWindow::MainWindow(QWidget *parent) zoneFileViewer->SetZoneFile(aZoneFile); zoneFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); - QString fileStem = aZoneFile->GetStem() + ".zone"; + QString fileStem = aZoneFile->GetBaseStem() + ".zone"; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete zoneFileViewer; return; } } @@ -353,7 +341,7 @@ MainWindow::MainWindow(QWidget *parent) scrollArea->setWidget(containerWidget); ui->tabWidget->addTab(scrollArea, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_ZoneFile.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_ZONE_FILE)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -366,12 +354,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = aZoneFile->GetStem() + ".str"; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete localStrViewer; return; } } ui->tabWidget->addTab(localStrViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_String.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_LOCAL_STRING)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -384,12 +373,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = aTechSet->name; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete techSetViewer; return; } } ui->tabWidget->addTab(techSetViewer, aTechSet->name); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_TechSetFile.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_TECH_SET)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -402,12 +392,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = aStrTable->name; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete strTableViewer; return; } } ui->tabWidget->addTab(strTableViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_StringTable.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_STRING_TABLE)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -420,12 +411,13 @@ MainWindow::MainWindow(QWidget *parent) QString fileStem = aSound->path.split('/').last(); for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { + delete soundViewer; return; } } ui->tabWidget->addTab(soundViewer, fileStem); - ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_Sound.png")); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_SOUND)); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); @@ -522,13 +514,14 @@ void MainWindow::Reset() { and opens the selected file. */ bool MainWindow::OpenFastFile(const QString aFastFilePath) { - const QString fastFileStem = aFastFilePath.section("/", -1, -1).section('.', 0, 0); + const QString fastFileStem = aFastFilePath.section("/", -1, -1); if (mTreeWidget->HasFastFile(fastFileStem)) { LogManager::instance().addError("Can't add duplicate file!"); return false; } std::shared_ptr fastFile = FastFileFactory::Create(aFastFilePath); + fastFile->SetStem(fastFileStem); mTreeWidget->AddFastFile(fastFile); // Open zone file after decompressing ff and writing From 22062c2a6e4252b6dac5c11f76a6f5c707a6689e Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:19:47 -0400 Subject: [PATCH 14/32] Removed unused header files. --- bink.h | 396 ------------------------------- enums.h | 670 ----------------------------------------------------- localize.h | 55 ----- rawfile.h | 61 ----- zone.h | 124 ---------- 5 files changed, 1306 deletions(-) delete mode 100644 bink.h delete mode 100644 enums.h delete mode 100644 localize.h delete mode 100644 rawfile.h delete mode 100644 zone.h diff --git a/bink.h b/bink.h deleted file mode 100644 index ab7c0de..0000000 --- a/bink.h +++ /dev/null @@ -1,396 +0,0 @@ -/* xoreos - A reimplementation of BioWare's Aurora engine - * - * xoreos is the legal property of its developers, whose names - * can be found in the AUTHORS file distributed with this source - * distribution. - * - * xoreos is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 3 - * of the License, or (at your option) any later version. - * - * xoreos is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with xoreos. If not, see . - */ - -/** @file - * Decoding RAD Game Tools' Bink videos. - */ - -/* Based on the Bink implementation in FFmpeg (, - * which is released under the terms of version 2 or later of the GNU - * Lesser General Public License. - * - * The original copyright notes in the files - * - libavformat/bink.c - * - libavcodec/bink.c - * - libavcodec/binkdata.h - * - libavcodec/binkdsp.c - * - libavcodec/binkdsp.h - * - libavcodec/binkaudio.c - * read as follows: - * - * Bink demuxer - * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org) - * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) - * - * Bink video decoder - * Copyright (c) 2009 Konstantin Shishkov - * Copyright (C) 2011 Peter Ross - * - * Bink video decoder - * Copyright (C) 2009 Konstantin Shishkov - * - * Bink DSP routines - * Copyright (c) 2009 Konstantin Shishkov - * - * Bink Audio decoder - * Copyright (c) 2007-2011 Peter Ross (pross@xvid.org) - * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef VIDEO_BINK_H -#define VIDEO_BINK_H - -#include -#include - -#include "src/common/types.h" -#include "src/common/rational.h" - -#include "src/video/decoder.h" - -namespace Common { - class SeekableReadStream; - class BitStream; - class Huffman; - - class RDFT; - class DCT; -} - -namespace Sound { - class PacketizedAudioStream; -} - -namespace Video { - -/** A decoder for RAD Game Tools' Bink videos. */ -class Bink : public VideoDecoder { -public: - Bink(Common::SeekableReadStream *bink); - ~Bink(); - -protected: - void decodeNextTrackFrame(VideoTrack &track); - void checkAudioBuffer(AudioTrack &track, const Common::Timestamp &endTime); - -private: - static const int kAudioChannelsMax = 2; - static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11); - - enum AudioCodec { - kAudioCodecDCT, - kAudioCodecRDFT - }; - - /** An audio track. */ - struct AudioInfo { - uint16_t flags; - - uint32_t sampleRate; - uint8_t channels; - - uint32_t outSampleRate; - uint8_t outChannels; - - AudioCodec codec; - - bool first; - - uint32_t frameLen; - uint32_t overlapLen; - - uint32_t blockSize; - - uint32_t bandCount; - uint32_t *bands; - - float root; - - float coeffs[16 * kAudioBlockSizeMax]; - int16_t prevCoeffs[kAudioBlockSizeMax]; - - float *coeffsPtr[kAudioChannelsMax]; - - Common::RDFT *rdft; - Common::DCT *dct; - - AudioInfo(); - AudioInfo(const AudioInfo &audioInfo) = default; - ~AudioInfo(); - }; - - /** A video frame. */ - struct VideoFrame { - bool keyFrame; - - uint32_t offset; - uint32_t size; - - Common::BitStream *bits; - - VideoFrame(); - VideoFrame(const VideoFrame &videoFrame) = default; - ~VideoFrame(); - }; - - std::unique_ptr _bink; - - std::vector _audioTracks; ///< All audio tracks. - std::vector _frames; ///< All video frames. - - uint32_t _audioTrack; ///< Audio track to use. - - /** Load a Bink file. */ - void load(); - - class BinkVideoTrack : public FixedRateVideoTrack { - public: - BinkVideoTrack(uint32_t width, uint32_t height, uint32_t frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32_t id); - - uint32_t getWidth() const { return _width; } - uint32_t getHeight() const { return _height; } - int getCurFrame() const { return _curFrame; } - int getFrameCount() const { return _frameCount; } - - /** Decode a video packet. */ - void decodePacket(Graphics::Surface &surface, VideoFrame &frame); - - protected: - Common::Rational getFrameRate() const { return _frameRate; } - - private: - /** A decoder state. */ - struct DecodeContext { - VideoFrame *video; - - uint32_t planeIdx; - - uint32_t blockX; - uint32_t blockY; - - byte *dest; - byte *prev; - - byte *destStart, *destEnd; - byte *prevStart, *prevEnd; - - uint32_t pitch; - - int coordMap[64]; - int coordScaledMap1[64]; - int coordScaledMap2[64]; - int coordScaledMap3[64]; - int coordScaledMap4[64]; - }; - - /** IDs for different data types used in Bink video codec. */ - enum Source { - kSourceBlockTypes = 0, ///< 8x8 block types. - kSourceSubBlockTypes , ///< 16x16 block types (a subset of 8x8 block types). - kSourceColors , ///< Pixel values used for different block types. - kSourcePattern , ///< 8-bit values for 2-color pattern fill. - kSourceXOff , ///< X components of motion value. - kSourceYOff , ///< Y components of motion value. - kSourceIntraDC , ///< DC values for intrablocks with DCT. - kSourceInterDC , ///< DC values for interblocks with DCT. - kSourceRun , ///< Run lengths for special fill block. - - kSourceMAX - }; - - /** Bink video block types. */ - enum BlockType { - kBlockSkip = 0, ///< Skipped block. - kBlockScaled , ///< Block has size 16x16. - kBlockMotion , ///< Block is copied from previous frame with some offset. - kBlockRun , ///< Block is composed from runs of colors with custom scan order. - kBlockResidue , ///< Motion block with some difference added. - kBlockIntra , ///< Intra DCT block. - kBlockFill , ///< Block is filled with single color. - kBlockInter , ///< Motion block with DCT applied to the difference. - kBlockPattern , ///< Block is filled with two colors following custom pattern. - kBlockRaw ///< Uncoded 8x8 block. - }; - - /** Data structure for decoding and translating Huffman'd data. */ - struct Huffman { - int index; ///< Index of the Huffman codebook to use. - byte symbols[16]; ///< Huffman symbol => Bink symbol translation list. - - Huffman(); - }; - - /** Data structure used for decoding a single Bink data type. */ - struct Bundle { - int countLengths[2]; ///< Lengths of number of entries to decode (in bits). - int countLength; ///< Length of number of entries to decode (in bits) for the current plane. - - Huffman huffman; ///< Huffman codebook. - - std::unique_ptr data; ///< Buffer for decoded symbols. - - byte *dataEnd; ///< Pointer to the data end end. - byte *curDec; ///< Pointer to the data that wasn't yet decoded. - byte *curPtr; ///< Pointer to the data that wasn't yet read. - - Bundle(); - }; - - uint32_t _width; - uint32_t _height; - - int _curFrame; ///< Current Frame. - int _frameCount; - - Common::Rational _frameRate; ///< The frame rate of the video. - - bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV? - bool _hasAlpha; ///< Do video frames have alpha? - - uint32_t _id; ///< The BIK FourCC. - - Bundle _bundles[kSourceMAX]; ///< Bundles for decoding all data types. - - std::unique_ptr _huffman[16]; ///< The 16 Huffman codebooks used in Bink decoding. - - /** Huffman codebooks to use for decoding high nibbles in color data types. */ - Huffman _colHighHuffman[16]; - /** Value of the last decoded high nibble in color data types. */ - int _colLastVal; - - std::unique_ptr _curPlanes[4]; ///< The 4 color planes, YUVA, current frame. - std::unique_ptr _oldPlanes[4]; ///< The 4 color planes, YUVA, last frame. - - /** Initialize the bundles. */ - void initBundles(); - - /** Initialize the Huffman decoders. */ - void initHuffman(); - - /** Decode a video packet. */ - void videoPacket(VideoFrame &video); - - /** Decode a plane. */ - void decodePlane(VideoFrame &video, int planeIdx, bool isChroma); - - /** Read/Initialize a bundle for decoding a plane. */ - void readBundle(VideoFrame &video, Source source); - - /** Read the symbols for a Huffman code. */ - void readHuffman(VideoFrame &video, Huffman &huffman); - /** Merge two Huffman symbol lists. */ - void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size); - - /** Read and translate a symbol out of a Huffman code. */ - byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman); - - /** Get a direct value out of a bundle. */ - int32_t getBundleValue(Source source); - /** Read a count value out of a bundle. */ - uint32_t readBundleCount(VideoFrame &video, Bundle &bundle); - - // Handle the block types - void blockSkip (DecodeContext &ctx); - void blockScaledSkip (DecodeContext &ctx); - void blockScaledRun (DecodeContext &ctx); - void blockScaledIntra (DecodeContext &ctx); - void blockScaledFill (DecodeContext &ctx); - void blockScaledPattern(DecodeContext &ctx); - void blockScaledRaw (DecodeContext &ctx); - void blockScaled (DecodeContext &ctx); - void blockMotion (DecodeContext &ctx); - void blockRun (DecodeContext &ctx); - void blockResidue (DecodeContext &ctx); - void blockIntra (DecodeContext &ctx); - void blockFill (DecodeContext &ctx); - void blockInter (DecodeContext &ctx); - void blockPattern (DecodeContext &ctx); - void blockRaw (DecodeContext &ctx); - - // Read the bundles - void readRuns (VideoFrame &video, Bundle &bundle); - void readMotionValues(VideoFrame &video, Bundle &bundle); - void readBlockTypes (VideoFrame &video, Bundle &bundle); - void readPatterns (VideoFrame &video, Bundle &bundle); - void readColors (VideoFrame &video, Bundle &bundle); - void readDCS (VideoFrame &video, Bundle &bundle, int startBits, bool hasSign); - void readDCTCoeffs (VideoFrame &video, int16_t *block, bool isIntra); - void readResidue (VideoFrame &video, int16_t *block, int masksCount); - - // Bink video IDCT - void IDCT(int16_t *block); - void IDCTPut(DecodeContext &ctx, int16_t *block); - void IDCTAdd(DecodeContext &ctx, int16_t *block); - }; - - class BinkAudioTrack : public AudioTrack { - public: - BinkAudioTrack(size_t index, AudioInfo &audio); - ~BinkAudioTrack(); - - bool canBufferData() const; - - /** Decode audio data up to endTime. */ - void decodeAudio(Common::SeekableReadStream& bink, const std::vector& frames, const std::vector& audioTracks, const Common::Timestamp& endTime); - - protected: - Sound::AudioStream *getAudioStream() const; - - private: - size_t _index; - AudioInfo &_info; - Sound::PacketizedAudioStream *_audioStream; - uint32_t _curFrame; - Common::Timestamp _audioBuffered; - - float getFloat(Common::BitStream &bits); - - /** Decode an audio block. */ - void audioBlock(Common::BitStream &bits, int16_t *out); - /** Decode a DCT'd audio block. */ - void audioBlockDCT(Common::BitStream &bits); - /** Decode a RDFT'd audio block. */ - void audioBlockRDFT(Common::BitStream &bits); - - void readAudioCoeffs(Common::BitStream &bits, float *coeffs); - - static void floatToInt16Interleave(int16_t *dst, const float **src, uint32_t length, uint8_t channels); - }; - - void initAudioTrack(AudioInfo &audio); -}; - -} // End of namespace Video - -#endif // VIDEO_BINK_H diff --git a/enums.h b/enums.h deleted file mode 100644 index 734e146..0000000 --- a/enums.h +++ /dev/null @@ -1,670 +0,0 @@ -#ifndef ENUMS_H -#define ENUMS_H - -#include "qtypes.h" -enum LUMP_TYPE -{ - LUMP_MATERIALS = 0x0, - LUMP_LIGHTBYTES = 0x1, - LUMP_LIGHTGRIDENTRIES = 0x2, - LUMP_LIGHTGRIDCOLORS = 0x3, - LUMP_PLANES = 0x4, - LUMP_BRUSHSIDES = 0x5, - LUMP_BRUSHSIDEEDGECOUNTS = 0x6, - LUMP_BRUSHEDGES = 0x7, - LUMP_BRUSHES = 0x8, - LUMP_TRIANGLES = 0x9, - LUMP_DRAWVERTS = 0xA, - LUMP_DRAWINDICES = 0xB, - LUMP_CULLGROUPS = 0xC, - LUMP_CULLGROUPINDICES = 0xD, - LUMP_OBSOLETE_1 = 0xE, - LUMP_OBSOLETE_2 = 0xF, - LUMP_OBSOLETE_3 = 0x10, - LUMP_OBSOLETE_4 = 0x11, - LUMP_OBSOLETE_5 = 0x12, - LUMP_PORTALVERTS = 0x13, - LUMP_OBSOLETE_6 = 0x14, - LUMP_UINDS = 0x15, - LUMP_BRUSHVERTSCOUNTS = 0x16, - LUMP_BRUSHVERTS = 0x17, - LUMP_AABBTREES = 0x18, - LUMP_CELLS = 0x19, - LUMP_PORTALS = 0x1A, - LUMP_NODES = 0x1B, - LUMP_LEAFS = 0x1C, - LUMP_LEAFBRUSHES = 0x1D, - LUMP_LEAFSURFACES = 0x1E, - LUMP_COLLISIONVERTS = 0x1F, - LUMP_COLLISIONTRIS = 0x20, - LUMP_COLLISIONEDGEWALKABLE = 0x21, - LUMP_COLLISIONBORDERS = 0x22, - LUMP_COLLISIONPARTITIONS = 0x23, - LUMP_COLLISIONAABBS = 0x24, - LUMP_MODELS = 0x25, - LUMP_VISIBILITY = 0x26, - LUMP_ENTITIES = 0x27, - LUMP_PATHCONNECTIONS = 0x28, - LUMP_REFLECTION_PROBES = 0x29, - LUMP_VERTEX_LAYER_DATA = 0x2A, - LUMP_PRIMARY_LIGHTS = 0x2B, - LUMP_LIGHTGRIDHEADER = 0x2C, - LUMP_LIGHTGRIDROWS = 0x2D, - LUMP_OBSOLETE_10 = 0x2E, - - //Obsolete in BO1///////////////// - LUMP_UNLAYERED_TRIANGLES = 0x2F, - LUMP_UNLAYERED_DRAWVERTS = 0x30, - LUMP_UNLAYERED_DRAWINDICES = 0x31, - LUMP_UNLAYERED_CULLGROUPS = 0x32, - LUMP_UNLAYERED_AABBTREES = 0x33, - ////////////////////////////////// - - LUMP_WATERHEADER = 0x34, - LUMP_WATERCELLS = 0x35, - LUMP_WATERCELLDATA = 0x36, - LUMP_BURNABLEHEADER = 0x37, - LUMP_BURNABLECELLS = 0x38, - LUMP_BURNABLECELLDATA = 0x39, - LUMP_SIMPLELIGHTMAPBYTES = 0x3A, - LUMP_LODCHAINS = 0x3B, - LUMP_LODINFOS = 0x3C, - LUMP_LODSURFACES = 0x3D, - LUMP_LIGHTREGIONS = 0x3E, - LUMP_LIGHTREGION_HULLS = 0x3F, - LUMP_LIGHTREGION_AXES = 0x40, - LUMP_WIILIGHTGRID = 0x41, - LUMP_LIGHTGRID2D_LIGHTS = 0x42, - LUMP_LIGHTGRID2D_INDICES = 0x43, - LUMP_LIGHTGRID2D_POINTS = 0x44, - LUMP_LIGHTGRID2D_CELLS = 0x45, - LUMP_LIGHT_CORONAS = 0x46, - - //BO Specific///////////////////////// - LUMP_SHADOWMAP_VOLUMES = 0x47, - LUMP_SHADOWMAP_VOLUME_PLANES = 0x48, - LUMP_EXPOSURE_VOLUMES = 0x49, - LUMP_EXPOSURE_VOLUME_PLANES = 0x4A, - LUMP_OCCLUDERS = 0x4B, - LUMP_OUTDOORBOUNDS = 0x4C, - LUMP_HERO_ONLY_LIGHTS = 0x4D, - ////////////////////////////////////// - - INFO_LUMP_TYPE_COUNT -}; - -enum BSPVERSION_TYPE -{ - BSPVERSION_COD_WAW = 31, - BSPVERSION_COD_BO = 45 -}; - -enum MENU_ITEM_TYPE { - ITEM_TYPE_TEXT = 0, // simple text - ITEM_TYPE_BUTTON = 1, // button, basically text with a border - ITEM_TYPE_RADIOBUTTON = 2, // toggle button, may be grouped - ITEM_TYPE_CHECKBOX = 3, // check box - ITEM_TYPE_EDITFIELD = 4, // editable text, associated with a dvar - ITEM_TYPE_COMBO = 5, // drop down list - ITEM_TYPE_LISTBOX = 6, // scrollable list - ITEM_TYPE_MODEL = 7, // model - ITEM_TYPE_OWNERDRAW = 8, // owner draw, name specs what it is - ITEM_TYPE_NUMERICFIELD = 9, // editable text, associated with a dvar - ITEM_TYPE_SLIDER = 10, // mouse speed, volume, etc. - ITEM_TYPE_YESNO = 11, // yes no dvar setting - ITEM_TYPE_MULTI = 12, // multiple list setting, enumerated - ITEM_TYPE_DVARENUM = 13, // multiple list setting, enumerated from a dvar - ITEM_TYPE_BIND = 14, // bind - ITEM_TYPE_MENUMODEL = 15, // special menu model - ITEM_TYPE_VALIDFILEFIELD = 16, // text must be valid for use in a dos filename - ITEM_TYPE_DECIMALFIELD = 17, // editable text, associated with a dvar, which allows decimal input - ITEM_TYPE_UPREDITFIELD = 18, // editable text, associated with a dvar - ITEM_TYPE_GAME_MESSAGE_WINDOW = 19, // game message window - ITEM_TYPE_SCALEFORM = 20, // Flash movie for Scaleform GFx - ITEM_TYPE_BIND2 = 21, // bind2 -}; - -enum MENU_ITEM_H_ALIGN { - ITEM_ALIGN_LEFT = 0, // aligns left of text to left of containing rectangle - ITEM_ALIGN_CENTER = 1, // aligns center of text to center of containing rectangle - ITEM_ALIGN_RIGHT = 2, // aligns right of text to right of containing rectangle - ITEM_ALIGN_X_MASK = 3, -}; - -enum MENU_ITEM_V_ALIGN { - ITEM_ALIGN_LEGACY = 0, // aligns bottom of text to top of containing rectangle - ITEM_ALIGN_TOP = 4, // aligns top of text to top of containing rectangle - ITEM_ALIGN_MIDDLE = 8, // aligns middle of text to middle of containing rectangle - ITEM_ALIGN_BOTTOM = 12, // aligns bottom of text to bottom of containing rectangle - ITEM_ALIGN_Y_MASK = 12, -}; - -enum MENU_ITEM_ALIGN { - ITEM_ALIGN_LEGACY_LEFT = 0, - ITEM_ALIGN_LEGACY_CENTER = 1, - ITEM_ALIGN_LEGACY_RIGHT = 2, - ITEM_ALIGN_TOP_LEFT = 4, - ITEM_ALIGN_TOP_CENTER = 5, - ITEM_ALIGN_TOP_RIGHT = 6, - ITEM_ALIGN_MIDDLE_LEFT = 8, - ITEM_ALIGN_MIDDLE_CENTER = 9, - ITEM_ALIGN_MIDDLE_RIGHT = 10, - ITEM_ALIGN_BOTTOM_LEFT = 12, - ITEM_ALIGN_BOTTOM_CENTER = 13, - ITEM_ALIGN_BOTTOM_RIGHT = 14 -}; - -enum MENU_ITEM_TEXTSTYLE { - ITEM_TEXTSTYLE_NORMAL = 0, // normal text - ITEM_TEXTSTYLE_BLINK = 1, // fast blinking - ITEM_TEXTSTYLE_SHADOWED = 3, // drop shadow ( need a color for this ) - ITEM_TEXTSTYLE_SHADOWEDMORE = 6, // drop shadow ( need a color for this ) - ITEM_TEXTSTYLE_MONOSPACE = 128 -}; - -enum MENU_WINDOW_BORDER { - WINDOW_BORDER_NONE = 0, // no border - WINDOW_BORDER_FULL = 1, // full border based on border color ( single pixel ) - WINDOW_BORDER_HORZ = 2, // horizontal borders only - WINDOW_BORDER_VERT = 3, // vertical borders only - WINDOW_BORDER_KCGRADIENT = 4, // horizontal border using the gradient bars - WINDOW_BORDER_RAISED = 5, // darken the bottom and right sides of the border - WINDOW_BORDER_SUNKEN = 6 // darken the top and left sides of the border -}; - -enum MENU_WINDOW_STYLE { - WINDOW_STYLE_EMPTY = 0, // no background - WINDOW_STYLE_FILLED = 1, // filled with background color - WINDOW_STYLE_GRADIENT = 2, // gradient bar based on background color - WINDOW_STYLE_SHADER = 3, // shader based on background color - WINDOW_STYLE_TEAMCOLOR = 4, // team color - WINDOW_STYLE_DVAR_SHADER = 5, // draws the shader specified by the dvar - WINDOW_STYLE_LOADBAR = 6, // shader based on background color -}; - -enum MENU_MODE { - MODE_BOTTOMUP_ALIGN_TOP = 0, // text appears on bottom of list and moves up to specified Y coordinate as old text fades out - MODE_BOTTOMUP_ALIGN_BOTTOM = 1, // text appears on bottom of list and moves away from specified Y coordinate as new text pushes it up - MODE_TOPDOWN_ALIGN_TOP = 2, // text appears on top of list and moves away from specified Y coordinate as new text pushes it down - MODE_TOPDOWN_ALIGN_BOTTOM = 3 // text appears on top of list and moves down to specified Y coordinate as old text fades out -}; - -enum MENU_BOOL { - MENU_TRUE = 1, - MENU_FALSE = 0 -}; - -enum MENU_ORIENTATION { - HUD_VERTICAL = 0x00, - HUD_HORIZONTAL = 0x01 -}; - -enum MENU_RANGETYPE { - RANGETYPE_ABSOLUTE = 0, - RANGETYPE_RELATIVE = 1 -}; - -// list box element types -enum MENU_LIST_BOX { - LISTBOX_TEXT = 0x00, - LISTBOX_IMAGE = 0x01 -}; - -// list feeders -enum MENU_FEEDERS { - FEEDER_HEADS = 0x00, // model heads - FEEDER_MAPS = 0x01, // text maps based on game type - FEEDER_SERVERS = 0x02, // servers - FEEDER_CLAN_MEMBERS = 0x03, // clan names - FEEDER_ALLMAPS = 0x04, // all maps available, in graphic format - FEEDER_REDTEAM_LIST = 0x05, // red team members - FEEDER_BLUETEAM_LIST = 0x06, // blue team members - FEEDER_PLAYER_LIST = 0x07, // players - FEEDER_TEAM_LIST = 0x08, // team members for team voting - FEEDER_MODS = 0x09, // team members for team voting - FEEDER_DEMOS = 0x0a, // team members for team voting - FEEDER_SCOREBOARD = 0x0b, // team members for team voting - FEEDER_Q3HEADS = 0x0c, // model heads - FEEDER_SERVERSTATUS = 0x0d, // server status - FEEDER_FINDPLAYER = 0x0e, // find player - FEEDER_CINEMATICS = 0x0f, // cinematics - FEEDER_SAVEGAMES = 0x10, // savegames - FEEDER_PICKSPAWN = 0x11, // pickspawn - FEEDER_LOBBY_MEMBERS = 0x12, // list of players in your party - FEEDER_LOBBY_MEMBERS_TALK = 0x13, // icon for whether they are speaking or not - FEEDER_MUTELIST = 0x14, // list of musted players - FEEDER_PLAYERSTALKING = 0x15, // list of players who are currently talking - FEEDER_SPLITSCREENPLAYERS = 0x16, // list of all players who are playing splitscreen - FEEDER_LOBBY_MEMBERS_READY = 0x17, // icon for whether they are ready or not - FEEDER_PLAYER_PROFILES = 0x18, // player profiles - FEEDER_PARTY_MEMBERS = 0x19, // list of players in your party - FEEDER_PARTY_MEMBERS_TALK = 0x1a, // icon for whether they are speaking or not - FEEDER_PARTY_MEMBERS_READY = 0x1b, // icon for whether they are ready or not - FEEDER_PLAYLISTS = 0x1c, // list of all playlists - FEEDER_GAMEMODES = 0x1d, // list of all game type modes, including any player custom modes - FEEDER_CATEGORIES = 0x1e, // list of all categories - FEEDER_LEADERBOARD = 0x1f, // list of rows for a leaderboard - FEEDER_MYTEAM_MEMBERS = 0x20, // list of marine team members - FEEDER_MYTEAM_MEMBERS_TALK = 0x21, // icon for whether they are speaking - FEEDER_ENEMY_MEMBERS = 0x22, // list of opfor team members - FEEDER_ENEMY_MEMBERS_TALK = 0x23, // icon for whether they are speaking - FEEDER_LOBBY_MEMBERS_STAT = 0x24, // last round stats for lobby members - FEEDER_MYTEAM_MEMBERS_STAT = 0x25, // last round stats for marine team members - FEEDER_ENEMY_MEMBERS_STAT = 0x26, // last round stats for opfor team members - FEEDER_ONLINEFRIENDS = 0x27, // list of your online friends - FEEDER_LOBBY_MEMBERS_RANK = 0x28, // rank icon - FEEDER_PARTY_MEMBERS_RANK = 0x29, // rank icon - FEEDER_ENEMY_MEMBERS_RANK = 0x2a, // rank icon - FEEDER_MYTEAM_MEMBERS_RANK = 0x2b, // rank icon - FEEDER_TESTMAPS = 0x2c, // department test maps - FEEDER_SYSTEMLINK_LOBBY_MEMBERS = 0x2d, // list of players in a system link lobby - FEEDER_LOBBY_MEMBERS_CONTROLLER = 0x2e, // icon for controller quadrant for splitscreen - FEEDER_PARTY_MEMBERS_CONTROLLER = 0x2f, // icon for controller quadrant for splitscreen - FEEDER_MYTEAM_MEMBERS_SQUAD = 0x30, // squad icon - FEEDER_ENEMY_MEMBERS_SQUAD = 0x31, // squad icon - FEEDER_INGAME_SQUAD_MEMBERS = 0x32, // Squad members displayed in MP 'Pause' menu - FEEDER_INGAME_SQUAD_MEMBERS_FULL = 0x33, // Squad members' name, rank, talk, leader displayed in PC MP 'Pause' menu - FEEDER_INGAME_SQUAD_NAMES = 0x34, // Squad names displayed in MP 'Join Squad' menu - FEEDER_INGAME_SQUAD_NAMES2 = 0x35, // Squad names displayed in MP 'Pause' menu - FEEDER_INGAME_SQUAD_NAMES_FULL = 0x36, // Squad names, lock, invite displayed in PC MP 'Pause' menu - FEEDER_CUSTOM_GAMETYPES = 0x37, // list of all the gametypes for custom matches - FEEDER_INGAME_SQUAD_MEMBER_RANK = 0x38, // Squad members' rank displayed in MP 'Pause' menu - FEEDER_INGAME_SQUAD_MEMBER_TALK = 0x39, // Squad members' talk icon displayed in MP 'Pause' menu - FEEDER_INGAME_SQUAD_LOCKED = 0x3a, // Squad lock icon displayed in MP 'Pause' menu - FEEDER_INGAME_SQUAD_MEMBER_INVITED = 0x3b, // Squad invite icon displayed in MP 'Pause' menu - FEEDER_INGAME_SQUAD_INVITE = 0x3c, // Squad invite icon displayed in MP 'Join Squad' menu - FEEDER_INGAME_SQUAD_LEADER = 0x3d, // Squad leader icon displayled in MP 'Pause' menu - FEEDER_FRIENDS = 0x3e, // list of your friends - FEEDER_PENDINGFRIENDS = 0x3f, // list of your pending friends - FEEDER_INVITES = 0x40, // list of the game invites from your friends -}; - -// display flags -enum MENU_DISPLAY_FLAG { - CG_SHOW_BLUE_TEAM_HAS_REDFLAG = 0x00000001, - CG_SHOW_RED_TEAM_HAS_BLUEFLAG = 0x00000002, - CG_SHOW_ANYTEAMGAME = 0x00000004, - CG_SHOW_CTF = 0x00000020, - CG_SHOW_OBELISK = 0x00000040, - CG_SHOW_HEALTHCRITICAL = 0x00000080, - CG_SHOW_SINGLEPLAYER = 0x00000100, - CG_SHOW_TOURNAMENT = 0x00000200, - CG_SHOW_DURINGINCOMINGVOICE = 0x00000400, - CG_SHOW_IF_PLAYER_HAS_FLAG = 0x00000800, - CG_SHOW_LANPLAYONLY = 0x00001000, - CG_SHOW_MINED = 0x00002000, - CG_SHOW_HEALTHOK = 0x00004000, - CG_SHOW_TEAMINFO = 0x00008000, - CG_SHOW_NOTEAMINFO = 0x00010000, - CG_SHOW_OTHERTEAMHASFLAG = 0x00020000, - CG_SHOW_YOURTEAMHASENEMYFLAG = 0x00040000, - CG_SHOW_ANYNONTEAMGAME = 0x00080000, - CG_SHOW_TEXTASINT = 0x00200000, - CG_SHOW_HIGHLIGHTED = 0x00100000, - CG_SHOW_NOT_V_CLEAR = 0x02000000, - CG_SHOW_2DONLY = 0x10000000 -}; - -enum MENU_UI_FLAG{ - UI_SHOW_LEADER = 0x00000001, - UI_SHOW_NOTLEADER = 0x00000002, - UI_SHOW_FAVORITESERVERS = 0x00000004, - UI_SHOW_ANYNONTEAMGAME = 0x00000008, - UI_SHOW_ANYTEAMGAME = 0x00000010, - UI_SHOW_NEWHIGHSCORE = 0x00000020, - UI_SHOW_DEMOAVAILABLE = 0x00000040, - UI_SHOW_NEWBESTTIME = 0x00000080, - UI_SHOW_FFA = 0x00000100, - UI_SHOW_NOTFFA = 0x00000200, - UI_SHOW_NETANYNONTEAMGAME = 0x00000400, - UI_SHOW_NETANYTEAMGAME = 0x00000800, - UI_SHOW_NOTFAVORITESERVERS = 0x00001000 -}; - -// font types -enum MENU_FONT_TYPE{ - UI_FONT_DEFAULT = 0, // auto-chose betwen big/reg/small - UI_FONT_NORMAL = 1, - UI_FONT_BIG = 2, - UI_FONT_SMALL = 3, - UI_FONT_BOLD = 4, - UI_FONT_CONSOLE = 5, - UI_FONT_OBJECTIVE = 6, - UI_FONT_MAX = 6, -}; - -// owner draw types -// ideally these should be done outside of this file but -// this makes it much easier for the macro expansion to -// convert them for the designers ( from the .menu files ) -enum MENU_OWNER_DRAW_TYPE { - CG_OWNERDRAW_BASE = 1, - CG_PLAYER_AMMO_VALUE = 5, - CG_PLAYER_AMMO_BACKDROP = 6, - CG_PLAYER_HEAT_VALUE = 7, - CG_PLAYER_STANCE = 20, - CG_SPECTATORS = 60, - CG_HOLD_BREATH_HINT = 71, - CG_CURSORHINT = 72, - CG_PLAYER_POWERUP = 73, - CG_PLAYER_HOLDABLE = 74, - CG_PLAYER_INVENTORY = 75, - CG_CURSORHINT_STATUS = 78, // like 'health' bar when pointing at a func_explosive - CG_PLAYER_BAR_HEALTH = 79, - CG_MANTLE_HINT = 80, - CG_PLAYER_WEAPON_NAME = 81, - CG_PLAYER_WEAPON_NAME_BACK = 82, - CG_CENTER_MESSAGE = 90, // for things like "You were killed by ..." - CG_TANK_BODY_DIR = 95, - CG_TANK_BARREL_DIR = 96, - CG_DEADQUOTE = 97, - CG_PLAYER_BAR_HEALTH_BACK = 98, - CG_MISSION_OBJECTIVE_HEADER = 99, - CG_MISSION_OBJECTIVE_LIST = 100, - CG_MISSION_OBJECTIVE_BACKDROP = 101, - CG_PAUSED_MENU_LINE = 102, - CG_OFFHAND_WEAPON_ICON_FRAG = 103, - CG_OFFHAND_WEAPON_ICON_SMOKEFLASH = 104, - CG_OFFHAND_WEAPON_AMMO_FRAG = 105, - CG_OFFHAND_WEAPON_AMMO_SMOKEFLASH = 106, - CG_OFFHAND_WEAPON_NAME_FRAG = 107, - CG_OFFHAND_WEAPON_NAME_SMOKEFLASH = 108, - CG_OFFHAND_WEAPON_SELECT_FRAG = 109, - CG_OFFHAND_WEAPON_SELECT_SMOKEFLASH = 110, - CG_SAVING = 111, - CG_PLAYER_LOW_HEALTH_OVERLAY = 112, - CG_INVALID_CMD_HINT = 113, - CG_PLAYER_SPRINT_METER = 114, - CG_PLAYER_SPRINT_BACK = 115, - CG_PLAYER_WEAPON_BACKGROUND = 116, - CG_PLAYER_WEAPON_AMMO_CLIP_GRAPHIC = 117, - CG_PLAYER_WEAPON_PRIMARY_ICON = 118, - CG_PLAYER_WEAPON_AMMO_STOCK = 119, - CG_PLAYER_WEAPON_LOW_AMMO_WARNING = 120, - CG_BATTLE_COMPASS_MARKERS = 122, - CG_BATTLE_FULLMAP_MARKERS = 123, - CG_SUCCESSFUL_CMD_HINT = 130, - CG_WAR_TEXT = 135, - CG_PLAYER_COMPASS_TICKERTAPE = 145, - CG_PLAYER_COMPASS_TICKERTAPE_NO_OBJ = 146, - CG_PLAYER_COMPASS_DOGS = 147, - CG_PLAYER_COMPASS_ARTILLERY_ICON = 148, - CG_PLAYER_COMPASS_SQUAD_OBJECTIVE = 149, - CG_PLAYER_COMPASS_PLAYER = 150, - CG_PLAYER_COMPASS_BACK = 151, - CG_PLAYER_COMPASS_POINTERS = 152, - CG_PLAYER_COMPASS_ACTORS = 153, - CG_PLAYER_COMPASS_TANKS = 154, - CG_PLAYER_COMPASS_HELICOPTERS = 155, - CG_PLAYER_COMPASS_PLANES = 156, - CG_PLAYER_COMPASS_AUTOMOBILES = 157, - CG_PLAYER_COMPASS_FRIENDS = 158, - CG_PLAYER_COMPASS_MAP = 159, - CG_PLAYER_COMPASS_NORTHCOORD = 160, - CG_PLAYER_COMPASS_EASTCOORD = 161, - CG_PLAYER_COMPASS_NCOORD_SCROLL = 162, - CG_PLAYER_COMPASS_ECOORD_SCROLL = 163, - CG_PLAYER_COMPASS_GOALDISTANCE = 164, - CG_PLAYER_ACTIONSLOT_DPAD = 165, - CG_PLAYER_ACTIONSLOT_1 = 166, - CG_PLAYER_ACTIONSLOT_2 = 167, - CG_PLAYER_ACTIONSLOT_3 = 168, - CG_PLAYER_ACTIONSLOT_4 = 169, - CG_PLAYER_COMPASS_ENEMIES = 170, - CG_PLAYER_FULLMAP_DOGS = 176, - CG_PLAYER_FULLMAP_VEHICLES = 177, - CG_PLAYER_FULLMAP_ARTILLERY_ICON = 178, - CG_PLAYER_FULLMAP_SQUAD_OBJECTIVE = 179, - CG_PLAYER_FULLMAP_BACK = 180, - CG_PLAYER_FULLMAP_MAP = 181, - CG_PLAYER_FULLMAP_POINTERS = 182, - CG_PLAYER_FULLMAP_PLAYER = 183, - CG_PLAYER_FULLMAP_ACTORS = 184, - CG_PLAYER_FULLMAP_FRIENDS = 185, - CG_PLAYER_FULLMAP_LOCATION_SELECTOR = 186, - CG_PLAYER_FULLMAP_BORDER = 187, - CG_PLAYER_FULLMAP_ENEMIES = 188, - CG_PLAYER_COMPASS = 189, - CG_VEHICLE_RETICLE = 190, - CG_HUD_TARGETS_VEHICLE = 191, - CG_HUD_TARGETS_JAVELIN = 192, - CG_TALKER1 = 193, - CG_TALKER2 = 194, - CG_TALKER3 = 195, - CG_TALKER4 = 196, - CG_FRIENDLYARROWS = 197, - CG_FRIENDLYNAMES = 198, - UI_OWNERDRAW_BASE = 200, - UI_HANDICAP = 200, - UI_EFFECTS = 201, - UI_PLAYERMODEL = 202, - UI_GAMETYPE = 205, - UI_SKILL = 207, - UI_NETSOURCE = 220, - UI_NETFILTER = 222, - UI_VOTE_KICK = 238, - UI_NETGAMETYPE = 245, - UI_SERVERREFRESHDATE = 247, - UI_SERVERMOTD = 248, - UI_GLINFO = 249, - UI_KEYBINDSTATUS = 250, - UI_JOINGAMETYPE = 253, - UI_MAPPREVIEW = 254, - UI_MENUMODEL = 257, - UI_SAVEGAME_SHOT = 258, - UI_SAVEGAMENAME = 262, - UI_SAVEGAMEINFO = 263, - UI_LOADPROFILING = 264, - UI_RECORDLEVEL = 265, - UI_AMITALKING = 266, - UI_TALKER1 = 267, - UI_TALKER2 = 268, - UI_TALKER3 = 269, - UI_TALKER4 = 270, - UI_PARTYSTATUS = 271, - UI_LOGGEDINUSER = 272, - UI_RESERVEDSLOTS = 273, - UI_PLAYLISTNAME = 274, - UI_PLAYLISTDESCRIPTION = 275, - UI_USERNAME = 276, - UI_CINEMATIC = 277, - UI_TOTALONLINE = 278, - UI_CATEGORYNAME = 279, - UI_CATEGORYDESCRIPTION = 280, - UI_PLAYLISTICON = 281, - UI_CATEGORYICON = 282, - UI_GAMETYPE_MAPNAME = 283, - CG_HUD_WAR_MOMENTUM_PROGRESS = 284, - CG_HUD_WAR_MOMENTUM_MULTIPLIER = 285, - CG_HUD_WAR_MOMENTUM_MULTIPLIER_DETAIL = 286, - CG_HUD_WAR_MOMENTUM_MULTIPLIER_BLITZKRIEG = 287, - CG_COMPETITIVE_MODE_SCORES = 288, - UI_LOAD_STATUS_SCREEN = 289, - UI_LEADERBOARD_GAMEMODE = 290, - CG_PLAYER_ACTIONSLOT_BACK_1 = 290, - CG_PLAYER_ACTIONSLOT_BACK_2 = 291, - CG_PLAYER_ACTIONSLOT_BACK_3 = 292, - CG_PLAYER_ACTIONSLOT_BACK_4 = 293, - CG_PLAYER_ACTIONSLOT_ARROW_1 = 294, - CG_PLAYER_ACTIONSLOT_ARROW_2 = 295, - CG_PLAYER_ACTIONSLOT_ARROW_3 = 296, - CG_PLAYER_ACTIONSLOT_ARROW_4 = 297, - UI_DIFFICULTY_INFO = 298, - UI_DIFFICULTY_ICON = 299, - UI_LOBBY_CHAT = 300 -}; - -// Edge relative placement values for rect->h_align and rect->v_align -enum MENU_H_ALIGNMENT { - HORIZONTAL_ALIGN_SUBLEFT = 0, // left edge of a 4:3 screen (safe area not included) - HORIZONTAL_ALIGN_LEFT = 1, // left viewable (safe area) edge - HORIZONTAL_ALIGN_CENTER = 2, // center of the screen (reticle) - HORIZONTAL_ALIGN_RIGHT = 3, // right viewable (safe area) edge - HORIZONTAL_ALIGN_FULLSCREEN = 4, // disregards safe area - HORIZONTAL_ALIGN_NOSCALE = 5, // uses exact parameters - neither adjusts for safe area nor scales for screen size - HORIZONTAL_ALIGN_TO640 = 6, // scales a real-screen resolution x down into the 0 - 640 range - HORIZONTAL_ALIGN_CENTER_SAFEAREA = 7, // center of the safearea - HORIZONTAL_ALIGN_MAX = HORIZONTAL_ALIGN_CENTER_SAFEAREA, - HORIZONTAL_ALIGN_DEFAULT = HORIZONTAL_ALIGN_SUBLEFT -}; - -enum MENU_V_ALIGNMENT { - VERTICAL_ALIGN_SUBTOP = 0, // top edge of the 4:3 screen (safe area not included) - VERTICAL_ALIGN_TOP = 1, // top viewable (safe area) edge - VERTICAL_ALIGN_CENTER = 2, // center of the screen (reticle) - VERTICAL_ALIGN_BOTTOM = 3, // bottom viewable (safe area) edge - VERTICAL_ALIGN_FULLSCREEN = 4, // disregards safe area - VERTICAL_ALIGN_NOSCALE = 5, // uses exact parameters - neither adjusts for safe area nor scales for screen size - VERTICAL_ALIGN_TO480 = 6, // scales a real-screen resolution y down into the 0 - 480 range - VERTICAL_ALIGN_CENTER_SAFEAREA = 7, // center of the save area - VERTICAL_ALIGN_MAX = VERTICAL_ALIGN_CENTER_SAFEAREA, - VERTICAL_ALIGN_DEFAULT = VERTICAL_ALIGN_SUBTOP -}; - -enum MENU_BUTTON { - BUTTON_A = 1, - BUTTON_B = 2, - BUTTON_X = 3, - BUTTON_Y = 4, - BUTTON_LSHLDR = 5, - BUTTON_RSHLDR = 6, - BUTTON_START = 14, - BUTTON_BACK = 15, - BUTTON_LSTICK = 16, - BUTTON_RSTICK = 17, - BUTTON_LTRIG = 18, - BUTTON_RTRIG = 19, - DPAD_UP = 20, - DPAD_DOWN = 21, - DPAD_LEFT = 22, - DPAD_RIGHT = 23, - APAD_UP = 28, - APAD_DOWN = 29, - APAD_LEFT = 30, - APAD_RIGHT = 31 -}; - -enum ASSET_TYPE { - ASSET_UNKNOWN = 0, - ASSET_ANIMATION = 4, // x_anim PARTIALLY VERIFIED - ASSET_MODEL = 5, // xmodel PARTIALLY VERIFIED - ASSET_MATERIAL = 6, // material VERIFIED - ASSET_BIK_FILE = 7, // .bik file PARTIALLY VERIFIED - ASSET_SOUND = 9, // loaded_sound VERIFIED - ASSET_COLLISION_MAP = 12, // collision_map PARTIALLY VERIFIED - ASSET_SHADER = 13, // shader PARTIALLY VERIFIED - ASSET_D3DBSP_DUMP = 17, // d3dbsp dump VERIFIED - ASSET_FONT = 20, // font PARTIALLY VERIFIED - ASSET_MENU = 21, // menu_file VERIFIED - ASSET_LOCAL_STRING = 23, // localized string VERIFIED - ASSET_WEAPON = 24, // weapon VERIFIED - ASSET_EFFECT = 26, // fx VERIFIED - ASSET_RAW_FILE = 32, // raw_file VERIFIED - ASSET_STRING_TABLE = 33 // string_table PARTIALLY VERIFIED -}; - -// Change this depending on the platform -// PC -#define DEVMAP_LEVEL_FIRST "devmap intro_pac" -#define DEVMAP "devmap" -// Not PC -// #define DEVMAP_LEVEL_FIRST "map intro_pac" -// #define DEVMAP "map" - -// Remove this to restore full frontend instead of limited EPD frontend -#define COOP_EPD 0 - -// LDS - This enables a German SKU with Nazi Zombies enabled *SHOULD BE SET TO 0 IF NOT APPROVED* -#define GERMAN_ZOMBIE_BUILD 0 - -#define DEVMAP_LEVEL_TRAINING "devmap training" -#define LEVEL_FIRST "intro_pac" -#define LEVEL_TRAINING "training" -#define FIRST_PLAYABLE_CAMPAIGN_LEVEL "mak" -#define FIRST_PLAYABLE_ZOMBIE_LEVEL "nazi_zombie_prototype" - -// Size define for the hud compass -// These are used for both the dynamic & non-dynamic compass drawing -// If these are changed, the cgame should be recompiled -#define COMPASS_SIZE 160 -#define MINIMAP_X 11.5 -#define MINIMAP_Y 5 -#define MINIMAP_W 89.5 -#define MINIMAP_H 89.5 - -#define COMPASS_SIZE_MP 125 -#define MINIMAP_X_MP 0 -#define MINIMAP_Y_MP 12 -#define MINIMAP_W_MP 102 -#define MINIMAP_H_MP 102 - -#define FULLSCREEN 0 0 640 480 -#define FULLSCREEN_WIDE -107 0 854 480 - -// PC -#define ORIGIN_TITLE 30 34 -// Not PC -// #define ORIGIN_TITLE 0 0 - -#define ORIGIN_TITLE_SS 104 120 - -#define FONTSCALE_SMALL 0.3095 //0.3750 // <-- COD4 // COD5 --> 0.30952//0.35897//0.24138 //14 pt //0.2900 //0.2750 // 18 -#define FONTSCALE_LOBBY 0.26 // <--Slate // 0.3010 <-- Slate Compressed // 0.3750 // <-- COD4 CONDUIT ITC small -#define FONTSCALE_NORMAL 0.3810 //0.35897//0.4583 -#define FONTSCALE_BOLD 0.5476 //0.4583 -#define FONTSCALE_BIG 0.5476 //0.5833 -#define FONTSCALE_EXTRABIG 1 //1.0000 - -// new settings -#define TEXTSIZE_SMALL FONTSCALE_SMALL -#define TEXTSIZE_SMALL_SS (FONTSCALE_SMALL*2) -#define TEXTSIZE_DEFAULT FONTSCALE_NORMAL -#define TEXTSIZE_DEFAULT_SS (FONTSCALE_NORMAL*2) -#define TEXTSIZE_TITLE FONTSCALE_BIG -#define TEXTSIZE_TITLE_SS 1 - -#define TEXTSIZE_BOLD TEXTSIZE_DEFAULT -#define TEXTSIZE_BIG TEXTSIZE_TITLE - -//#define COLOR_TITLE 1 0.8 0.4 1 -#define COLOR_TITLE 1 1 1 1 -#define COLOR_HEADER 0.69 0.69 0.69 1 -#define COLOR_FOCUSED 0.95294 0.72156 0.21176 1 //1 0.788 0.129 1 -//#define COLOR_FOCUS_YELLOW 0.95294 0.72156 0.21176 1 -#define COLOR_UNFOCUSED 0.4823 0.4823 0.4823 1 -//#define COLOR_DISABLED 0.35 0.35 0.35 1 -#define COLOR_SAFEAREA 0 0 1 1 - -#define COLOR_INFO_YELLOW COLOR_FOCUSED//1 0.84706 0 1 -#define COLOR_TEXT 0.84313 0.84313 0.84313 1 -#define COLOR_DISABLED 0.34118 0.36863 0.37647 1 -#define COLOR_TITLEBAR 0.14510 0.16078 0.16862 0.3//1 -#define COLOR_RED_TEXT 0.69020 0.00784 0.00784 1 - -#define COLOR_FADEOUT 0.09412 0.09412 0.04912 0.65 - -#define COLOR_BODY_TEXT 0.62745 0.66667 0.67451 1 - -#define COLOR_USMC 0 0.0196 0.41 -#define COLOR_JPN 0.53 0.027 0.027 -#define COLOR_USSR 0.368 0.035 0.035 -#define COLOR_GER 0.937 0.9 0.607 - -#define DEFAULT_MP_CFG "default_mp.cfg" -#define SPLITSCREEN_MP_CFG "default_splitscreen.cfg" -#define SYSTEMLINK_MP_CFG "default_systemlink.cfg" -#define XBOXLIVE_MP_CFG "default_xboxlive.cfg" - -#define MAX_RANK int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1)) -#define MAX_PRESTIGE int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1)) - -#define PRESTIGE_AVAIL (stat(2326) < MAX_PRESTIGE && stat(2301) == int(tableLookup("mp/rankTable.csv",0,MAX_RANK,7))) -#define PRESTIGE_NEXT (stat(2326) < MAX_PRESTIGE && stat(252) == MAX_RANK) -#define PRESTIGE_FINISH (stat(2326) == MAX_PRESTIGE) - -#define CAN_RANK_UP (stat(252) < MAX_RANK || stat(2326) < MAX_PRESTIGE) - -// Bink constants -const quint32 BINK_SURFACE32RGBA = 6; - -#endif // ENUMS_H diff --git a/localize.h b/localize.h deleted file mode 100644 index cd58c4a..0000000 --- a/localize.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef LOCALIZE_H -#define LOCALIZE_H - -#include -#include - -struct Localize { - quint32 valuePtr; - quint32 namePtr; - QString referenceStr; - QString localizedStr; -}; - -inline QDataStream &operator<<(QDataStream &out, const Localize &localize) { - out << localize.valuePtr << localize.namePtr; - - // Parse gsc contents - QByteArray localizedStrData(localize.localizedStr.toUtf8()); - out.writeRawData(localizedStrData.data(), localizedStrData.size()); - - // Parse rawfile path - QByteArray refStrData(localize.referenceStr.toUtf8()); - out.writeRawData(refStrData.data(), refStrData.size()); - - return out; -} - -inline QDataStream &operator>>(QDataStream &in, Localize &localize) { - // Parse value and name pointers - in >> localize.valuePtr >> localize.namePtr; - - // Parse localized string - QString localizedStr; - char localizedStrChar; - in >> localizedStrChar; - while (localizedStrChar != 0) { - localizedStr += localizedStrChar; - in >> localizedStrChar; - } - localize.localizedStr = localizedStr; - - // Parse localized reference name - QString refStr; - char refStrChar; - in >> refStrChar; - while (refStrChar != 0) { - refStr += refStrChar; - in >> refStrChar; - } - localize.referenceStr = refStr; - - return in; -} - -#endif // LOCALIZE_H diff --git a/rawfile.h b/rawfile.h deleted file mode 100644 index 23bed60..0000000 --- a/rawfile.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef RAWFILE_H -#define RAWFILE_H - -#include -#include -#include - -struct RawFile { - quint32 gscNamePtr; - quint32 gscLength; - quint32 rawFilePathPtr; - QString rawFilePath; - QString rawFileContents; -}; - -inline QDataStream &operator<<(QDataStream &out, const RawFile &rawFile) { - out << rawFile.gscNamePtr; - out << rawFile.gscLength; - out << rawFile.rawFilePathPtr; - - // Parse rawfile path - QByteArray rawFilePathData(rawFile.rawFilePath.toUtf8()); - out.writeRawData(rawFilePathData.data(), rawFilePathData.size()); - - // Parse gsc contents - QByteArray rawFileContentsData(rawFile.rawFileContents.toUtf8()); - out.writeRawData(rawFileContentsData.data(), rawFileContentsData.size()); - - return out; -} - -inline QDataStream &operator>>(QDataStream &in, RawFile &rawFile) { - in >> rawFile.gscNamePtr; - in >> rawFile.gscLength; - in >> rawFile.rawFilePathPtr; - - // Parse rawfile path - QString rawFilePath; - char scriptPathChar; - in >> scriptPathChar; - while (scriptPathChar != 0) { - rawFilePath += scriptPathChar; - in >> scriptPathChar; - } - rawFile.rawFilePath = rawFilePath; - - // Parse gsc contents - QString rawFileContents; - char rawFileContentsChar; - in >> rawFileContentsChar; - while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { - rawFileContents += rawFileContentsChar; - in >> rawFileContentsChar; - } - rawFile.rawFileContents = rawFileContents; - - return in; -} - - -#endif // RAWFILE_H diff --git a/zone.h b/zone.h deleted file mode 100644 index fb860c4..0000000 --- a/zone.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef ZONE_H -#define ZONE_H - -#include "enums.h" -#include "qtypes.h" -#include -#include - -struct Zone { - quint32 zoneFileSize; - quint32 unknown1; - quint32 unknown2; - quint32 unknown3; - quint32 unknown4; - quint32 unknown5; - quint32 unknown6; - quint32 unknown7; - quint32 unknown8; - quint32 tagCount; - quint32 unknown9; - quint32 recordCount; - quint32 unknown10; - quint32 unknown11; - QVector tagPtrs; - QStringList tags; - - QVector assetTypes; -}; - -inline QDataStream &operator<<(QDataStream &out, const Zone &zone) { - // Write adjusted fastfile size - out << zone.zoneFileSize - 36; - // Write unknowns 1-8 - out << zone.unknown1; - out << zone.unknown2; - out << zone.unknown3; - out << zone.unknown4; - out << zone.unknown5; - out << zone.unknown6; - out << zone.unknown7; - out << zone.unknown8; - // Write tag count - out << zone.tagCount; - // Write unknown 9 - out << zone.unknown9; - // Write record count - out << zone.recordCount; - // Write unknowns 10-11 - out << zone.unknown10; - out << zone.unknown11; - // Write tag pointers - foreach (quint32 tagPtr, zone.tagPtrs) { - out << tagPtr; - } - // Write tags - foreach (QString tag, zone.tags) { - out << tag.toLocal8Bit(); - } - - return out; -} - -inline QDataStream &operator>>(QDataStream &in, Zone &zone) { - // Parse file size - in >> zone.zoneFileSize; - zone.zoneFileSize += 36; - // Parse unknowns 1-8 - in >> zone.unknown1; - in >> zone.unknown2; - in >> zone.unknown3; - in >> zone.unknown4; - in >> zone.unknown5; - in >> zone.unknown6; - in >> zone.unknown7; - in >> zone.unknown8; - // Parse tag count - in >> zone.tagCount; - // Parse unknown 9 - in >> zone.unknown9; - // Parse record count - in >> zone.recordCount; - - in >> zone.unknown10; - if (zone.tagCount) { - // Parse unknowns 10-11 - in >> zone.unknown11; - - // Parse tag ptrs - for (quint32 i = 0; i < zone.tagCount - 1; i++) { - quint32 tagPtr; - in >> tagPtr; - - zone.tagPtrs.push_back(tagPtr); - } - - // Parse tags/strings before index - QString zoneTag; - char zoneTagChar; - for (quint32 i = 0; i < zone.tagCount - 1; i++) { - in >> zoneTagChar; - while (zoneTagChar != 0) { - zoneTag += zoneTagChar; - in >> zoneTagChar; - } - zone.tags.push_back(zoneTag); - zoneTag.clear(); - } - } - - // Parse index - for (quint32 i = 0; i < zone.recordCount; i++) { - // Parse asset type - quint32 assetType; - in >> assetType; - // Add asset type to vector - zone.assetTypes << (ASSET_TYPE)assetType; - // Skip separator - in.skipRawData(4); - } - - return in; -} - -#endif // ZONE_H From 95349eaa5bbffddb602362e67368d30c767f6e6c Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:25:12 -0400 Subject: [PATCH 15/32] Fix data compression, byte order handling, and tag parsing in COD Wii fastfile. --- libs/fastfile/360/fastfile_cod10_360.cpp | 4 +- libs/fastfile/360/fastfile_cod11_360.cpp | 4 +- libs/fastfile/360/fastfile_cod12_360.cpp | 4 +- libs/fastfile/360/fastfile_cod2_360.cpp | 9 +- libs/fastfile/360/fastfile_cod4_360.cpp | 60 +++++++++++-- libs/fastfile/360/fastfile_cod5_360.cpp | 4 +- libs/fastfile/360/fastfile_cod6_360.cpp | 98 +++++++--------------- libs/fastfile/360/fastfile_cod7_360.cpp | 2 +- libs/fastfile/360/fastfile_cod8_360.cpp | 4 +- libs/fastfile/360/fastfile_cod9_360.cpp | 4 +- libs/fastfile/PC/fastfile_cod10_pc.cpp | 4 +- libs/fastfile/PC/fastfile_cod11_pc.cpp | 4 +- libs/fastfile/PC/fastfile_cod12_pc.cpp | 4 +- libs/fastfile/PC/fastfile_cod4_pc.cpp | 6 +- libs/fastfile/PC/fastfile_cod5_pc.cpp | 4 +- libs/fastfile/PC/fastfile_cod6_pc.cpp | 13 ++- libs/fastfile/PC/fastfile_cod7_pc.cpp | 2 +- libs/fastfile/PC/fastfile_cod8_pc.cpp | 2 +- libs/fastfile/PC/fastfile_cod9_pc.cpp | 4 +- libs/fastfile/PS3/fastfile_cod10_ps3.cpp | 4 +- libs/fastfile/PS3/fastfile_cod11_ps3.cpp | 4 +- libs/fastfile/PS3/fastfile_cod12_ps3.cpp | 4 +- libs/fastfile/PS3/fastfile_cod4_ps3.cpp | 4 +- libs/fastfile/PS3/fastfile_cod5_ps3.cpp | 4 +- libs/fastfile/PS3/fastfile_cod6_ps3.cpp | 4 +- libs/fastfile/PS3/fastfile_cod7_ps3.cpp | 2 +- libs/fastfile/PS3/fastfile_cod8_ps3.cpp | 2 +- libs/fastfile/PS3/fastfile_cod9_ps3.cpp | 4 +- libs/fastfile/Wii/fastfile_cod4_wii.cpp | 36 +------- libs/fastfile/Wii/fastfile_cod7_wii.cpp | 7 +- libs/fastfile/Wii/fastfile_cod8_wii.cpp | 28 ++----- libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp | 4 +- libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp | 4 +- 33 files changed, 152 insertions(+), 195 deletions(-) diff --git a/libs/fastfile/360/fastfile_cod10_360.cpp b/libs/fastfile/360/fastfile_cod10_360.cpp index 8ab1f72..005d649 100644 --- a/libs/fastfile/360/fastfile_cod10_360.cpp +++ b/libs/fastfile/360/fastfile_cod10_360.cpp @@ -99,7 +99,7 @@ bool FastFile_COD10_360::Load(const QByteArray aData) { decompressedData = Encryption::decryptFastFile_BO2(aData); // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -107,7 +107,7 @@ bool FastFile_COD10_360::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD10_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/360/fastfile_cod11_360.cpp b/libs/fastfile/360/fastfile_cod11_360.cpp index 990373f..33477b2 100644 --- a/libs/fastfile/360/fastfile_cod11_360.cpp +++ b/libs/fastfile/360/fastfile_cod11_360.cpp @@ -91,11 +91,11 @@ bool FastFile_COD11_360::Load(const QByteArray aData) { decompressedData = Encryption::decryptFastFile_BO3(encryptedData); // Output for verification/testing - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); // Load the zone file with decompressed data ZoneFile_COD11_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); if (!zoneFile.Load(decompressedData)) { qWarning() << "Failed to load ZoneFile!"; return false; diff --git a/libs/fastfile/360/fastfile_cod12_360.cpp b/libs/fastfile/360/fastfile_cod12_360.cpp index f0581a4..8e051b9 100644 --- a/libs/fastfile/360/fastfile_cod12_360.cpp +++ b/libs/fastfile/360/fastfile_cod12_360.cpp @@ -91,11 +91,11 @@ bool FastFile_COD12_360::Load(const QByteArray aData) { decompressedData = Encryption::decryptFastFile_BO3(encryptedData); // Output for verification/testing - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); // Load the zone file with decompressed data ZoneFile_COD12_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); if (!zoneFile.Load(decompressedData)) { qWarning() << "Failed to load ZoneFile!"; return false; diff --git a/libs/fastfile/360/fastfile_cod2_360.cpp b/libs/fastfile/360/fastfile_cod2_360.cpp index e61690b..bf234d8 100644 --- a/libs/fastfile/360/fastfile_cod2_360.cpp +++ b/libs/fastfile/360/fastfile_cod2_360.cpp @@ -55,10 +55,9 @@ bool FastFile_COD2_360::Load(const QString aFilePath) { } // Decompress fastfile and close - const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0); - SetStem(fastFileStem); + SetStem(aFilePath.section("/", -1, -1)); if (!Load(file->readAll())) { - qDebug() << "Error: Failed to load fastfile: " << fastFileStem; + qDebug() << "Error: Failed to load fastfile: " << GetStem(); return false; } @@ -77,11 +76,11 @@ bool FastFile_COD2_360::Load(const QByteArray aData) { QByteArray compressedData = aData.mid(fastFileStream.device()->pos()); QByteArray decompressedData = Compression::DecompressZLIB(compressedData); - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD2_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/360/fastfile_cod4_360.cpp b/libs/fastfile/360/fastfile_cod4_360.cpp index 5ac6889..a6e9899 100644 --- a/libs/fastfile/360/fastfile_cod4_360.cpp +++ b/libs/fastfile/360/fastfile_cod4_360.cpp @@ -75,17 +75,63 @@ bool FastFile_COD4_360::Load(const QByteArray aData) { StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); QByteArray decompressedData; - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - fastFileStream.setByteOrder(QDataStream::LittleEndian); + const QString header = aData.left(8); + if (header == "IWffu100") { + // For COD5, simply decompress from offset 12. + decompressedData = Compression::DecompressZLIB(aData.mid(12)); + } else if (header == "IWff0100") { + // Create a QDataStream on the input data. + QDataStream fastFileStream(aData.mid(12)); + fastFileStream.setByteOrder(QDataStream::LittleEndian); - // For COD5, simply decompress from offset 12. - decompressedData = Compression::DecompressZLIB(aData.mid(12)); + QByteArray magic(8, Qt::Uninitialized); + fastFileStream.readRawData(magic.data(), 8); + if (magic != "IWffs100") { + qDebug() << "Found invalid signed header: " << magic; + return false; + } + fastFileStream.skipRawData(4); - Utils::ExportData(GetStem() + ".zone", decompressedData); + QByteArray rsaSigChecksum(32, Qt::Uninitialized); + fastFileStream.readRawData(rsaSigChecksum.data(), 32); + + QByteArray rsaSig(256, Qt::Uninitialized); + fastFileStream.readRawData(rsaSig.data(), 256); + + QByteArray fileName(32, Qt::Uninitialized); + fastFileStream.readRawData(fileName.data(), 32); + + fastFileStream.skipRawData(4); + + QByteArray bigSigBlock(7856, Qt::Uninitialized); + fastFileStream.readRawData(bigSigBlock.data(), 7856); + + QVector sigBlocks = QVector(); + QByteArray compressedData; + + for (int i = 0; i < (aData.size() / 202000) + 1; i++) + { + QByteArray newSigBlocks; + for (int j = 0; j < 256; j++) { + QByteArray newSigBlock(32, Qt::Uninitialized); + fastFileStream.readRawData(newSigBlock.data(), 32); + sigBlocks.append(newSigBlock); + } + newSigBlocks.append(newSigBlocks); + for (int j = 0; j < 256; j++) { + QByteArray compressedChunk(8192, Qt::Uninitialized); + fastFileStream.readRawData(compressedChunk.data(), 8192); + compressedData.append(compressedChunk); + } + } + decompressedData = Compression::DecompressZLIB(compressedData); + } + + + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD4_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/360/fastfile_cod5_360.cpp b/libs/fastfile/360/fastfile_cod5_360.cpp index 8608958..1488c3c 100644 --- a/libs/fastfile/360/fastfile_cod5_360.cpp +++ b/libs/fastfile/360/fastfile_cod5_360.cpp @@ -78,10 +78,10 @@ bool FastFile_COD5_360::Load(const QByteArray aData) { // For COD5, simply decompress from offset 12. decompressedData = Compression::DecompressZLIB(aData.mid(12)); - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD5_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/360/fastfile_cod6_360.cpp b/libs/fastfile/360/fastfile_cod6_360.cpp index 34ada0f..51d2132 100644 --- a/libs/fastfile/360/fastfile_cod6_360.cpp +++ b/libs/fastfile/360/fastfile_cod6_360.cpp @@ -3,6 +3,7 @@ #include "compression.h" #include "encryption.h" +#include "utils.h" #include #include @@ -69,83 +70,40 @@ bool FastFile_COD6_360::Load(const QString aFilePath) { } bool FastFile_COD6_360::Load(const QByteArray aData) { - QByteArray decompressedData; - - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - - // Load the zone file with the decompressed data (using an Xbox platform flag). - ZoneFile_COD6_360 zoneFile; - zoneFile.SetStem(GetStem()); - - // For COD7/COD9, use BigEndian. - fastFileStream.setByteOrder(QDataStream::BigEndian); - - // Select key based on game. - QByteArray key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); - fastFileStream.skipRawData(4); - - // Read the 8-byte magic. - QByteArray fileMagic(8, Qt::Uninitialized); - fastFileStream.readRawData(fileMagic.data(), 8); - if (fileMagic != "PHEEBs71") { - qWarning() << "Invalid fast file magic!"; + const qint64 zlibOffset = Compression::FindZlibOffset(aData); + if (zlibOffset == -1) + { + qWarning() << "Z-Lib stream not found"; return false; } - fastFileStream.skipRawData(4); + QByteArray compressed = aData.mid(zlibOffset); - // Read IV table name (32 bytes). - QByteArray fileName(32, Qt::Uninitialized); - fastFileStream.readRawData(fileName.data(), 32); + // 2. Try plain decompression first ------------------------------ + QByteArray decompressed = Compression::DecompressZLIB(compressed); - // Build the IV table from the fileName. - QByteArray ivTable = Encryption::InitIVTable(fileName); - - // Skip the RSA signature (256 bytes). - QByteArray rsaSignature(256, Qt::Uninitialized); - fastFileStream.readRawData(rsaSignature.data(), 256); - - // Now the stream should be positioned at 0x13C, where sections begin. - int sectionIndex = 0; - while (true) { - qint32 sectionSize = 0; - fastFileStream >> sectionSize; - qDebug() << "Section index:" << sectionIndex << "Size:" << sectionSize - << "Pos:" << fastFileStream.device()->pos(); - if (sectionSize == 0) - break; - - // Read the section data. - QByteArray sectionData; - sectionData.resize(sectionSize); - fastFileStream.readRawData(sectionData.data(), sectionSize); - - // Compute the IV for this section. - QByteArray iv = Encryption::GetIV(ivTable, sectionIndex); - - // Decrypt the section using Salsa20. - QByteArray decData = Encryption::salsa20DecryptSection(sectionData, key, iv); - - // Compute SHA1 hash of the decrypted data. - QByteArray sectionHash = QCryptographicHash::hash(decData, QCryptographicHash::Sha1); - - // Update the IV table based on the section hash. - Encryption::UpdateIVTable(ivTable, sectionIndex, sectionHash); - - // Build a compressed data buffer by prepending the two-byte zlib header. - QByteArray compressedData; - compressedData.append(char(0x78)); - compressedData.append(char(0x01)); - compressedData.append(decData); - - decompressedData.append(Compression::DecompressZLIB(compressedData)); - - sectionIndex++; + // 3. If that failed or looks too small, try stripping hash blocks + if (decompressed.isEmpty() || decompressed.size() < 1024) + { + QByteArray stripped = Compression::StripHashBlocks(compressed); + QByteArray retry = Compression::DecompressZLIB(stripped); + if (!retry.isEmpty()) + decompressed.swap(retry); } - zoneFile.Load(decompressedData); + if (decompressed.isEmpty()) + { + qWarning() << "Unable to decompress fast-file"; + return false; + } - SetZoneFile(std::make_shared(zoneFile)); + // Optional – keep a copy on disk for quick inspection + Utils::ExportData(GetBaseStem() + ".zone", decompressed); + + // 4. Forward to zone-file loader -------------------------------- + auto zoneFile = std::make_shared(); + zoneFile->SetStem(GetStem()); + zoneFile->Load(decompressed); + SetZoneFile(zoneFile); return true; } diff --git a/libs/fastfile/360/fastfile_cod7_360.cpp b/libs/fastfile/360/fastfile_cod7_360.cpp index 7da1f6e..90d645e 100644 --- a/libs/fastfile/360/fastfile_cod7_360.cpp +++ b/libs/fastfile/360/fastfile_cod7_360.cpp @@ -76,7 +76,7 @@ bool FastFile_COD7_360::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD7_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7/COD9, use BigEndian. fastFileStream.setByteOrder(QDataStream::BigEndian); diff --git a/libs/fastfile/360/fastfile_cod8_360.cpp b/libs/fastfile/360/fastfile_cod8_360.cpp index afdb404..746fc9e 100644 --- a/libs/fastfile/360/fastfile_cod8_360.cpp +++ b/libs/fastfile/360/fastfile_cod8_360.cpp @@ -99,7 +99,7 @@ bool FastFile_COD8_360::Load(const QByteArray aData) { decompressedData = Encryption::decryptFastFile_BO2(aData); // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -107,7 +107,7 @@ bool FastFile_COD8_360::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD8_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/360/fastfile_cod9_360.cpp b/libs/fastfile/360/fastfile_cod9_360.cpp index 04205f3..1362e59 100644 --- a/libs/fastfile/360/fastfile_cod9_360.cpp +++ b/libs/fastfile/360/fastfile_cod9_360.cpp @@ -99,7 +99,7 @@ bool FastFile_COD9_360::Load(const QByteArray aData) { decompressedData = Encryption::decryptFastFile_BO2(aData); // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -107,7 +107,7 @@ bool FastFile_COD9_360::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD9_360 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PC/fastfile_cod10_pc.cpp b/libs/fastfile/PC/fastfile_cod10_pc.cpp index 34ef0b8..fcde932 100644 --- a/libs/fastfile/PC/fastfile_cod10_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod10_pc.cpp @@ -121,7 +121,7 @@ bool FastFile_COD10_PC::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -129,7 +129,7 @@ bool FastFile_COD10_PC::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD10_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PC/fastfile_cod11_pc.cpp b/libs/fastfile/PC/fastfile_cod11_pc.cpp index dafaf47..300e1eb 100644 --- a/libs/fastfile/PC/fastfile_cod11_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod11_pc.cpp @@ -121,7 +121,7 @@ bool FastFile_COD11_PC::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -129,7 +129,7 @@ bool FastFile_COD11_PC::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD11_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PC/fastfile_cod12_pc.cpp b/libs/fastfile/PC/fastfile_cod12_pc.cpp index 5541223..b405990 100644 --- a/libs/fastfile/PC/fastfile_cod12_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod12_pc.cpp @@ -78,7 +78,7 @@ bool FastFile_COD12_PC::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD12_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); // Skip header magic fastFileStream.skipRawData(8); @@ -141,7 +141,7 @@ bool FastFile_COD12_PC::Load(const QByteArray aData) { fastFileStream.device()->seek(blockPosition + 16 + blockSize); } - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); zoneFile.Load(decompressedData); diff --git a/libs/fastfile/PC/fastfile_cod4_pc.cpp b/libs/fastfile/PC/fastfile_cod4_pc.cpp index c457d97..a2fe992 100644 --- a/libs/fastfile/PC/fastfile_cod4_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod4_pc.cpp @@ -44,7 +44,7 @@ QByteArray FastFile_COD4_PC::GetBinaryData() { } bool FastFile_COD4_PC::Load(const QString aFilePath) { - StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000); + StatusBarManager::instance().updateStatus("Loading " + GetGame() + " Fast File w/path", 1000); if (aFilePath.isEmpty()) { return false; @@ -82,10 +82,10 @@ bool FastFile_COD4_PC::Load(const QByteArray aData) { // For COD5, simply decompress from offset 12. decompressedData = Compression::DecompressZLIB(aData.mid(12)); - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD4_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PC/fastfile_cod5_pc.cpp b/libs/fastfile/PC/fastfile_cod5_pc.cpp index a277a56..6cb91f0 100644 --- a/libs/fastfile/PC/fastfile_cod5_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod5_pc.cpp @@ -82,10 +82,10 @@ bool FastFile_COD5_PC::Load(const QByteArray aData) { // For COD5, simply decompress from offset 12. decompressedData = Compression::DecompressZLIB(aData.mid(12)); - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD5_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PC/fastfile_cod6_pc.cpp b/libs/fastfile/PC/fastfile_cod6_pc.cpp index df8c444..00413af 100644 --- a/libs/fastfile/PC/fastfile_cod6_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod6_pc.cpp @@ -75,17 +75,14 @@ bool FastFile_COD6_PC::Load(const QByteArray aData) { StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000); QByteArray decompressedData; - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - fastFileStream.setByteOrder(QDataStream::LittleEndian); + // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. + const QByteArray compressedData = aData.mid(21); + decompressedData = Compression::DecompressZLIB(compressedData); - // For COD5, simply decompress from offset 12. - decompressedData = Compression::DecompressZLIB(aData.mid(12)); - - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD6_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PC/fastfile_cod7_pc.cpp b/libs/fastfile/PC/fastfile_cod7_pc.cpp index 787688c..59f10b9 100644 --- a/libs/fastfile/PC/fastfile_cod7_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod7_pc.cpp @@ -88,7 +88,7 @@ bool FastFile_COD7_PC::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD7_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7/COD9, use BigEndian. fastFileStream.setByteOrder(QDataStream::LittleEndian); diff --git a/libs/fastfile/PC/fastfile_cod8_pc.cpp b/libs/fastfile/PC/fastfile_cod8_pc.cpp index 472098f..85629dd 100644 --- a/libs/fastfile/PC/fastfile_cod8_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod8_pc.cpp @@ -88,7 +88,7 @@ bool FastFile_COD8_PC::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD8_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7/COD9, use BigEndian. fastFileStream.setByteOrder(QDataStream::LittleEndian); diff --git a/libs/fastfile/PC/fastfile_cod9_pc.cpp b/libs/fastfile/PC/fastfile_cod9_pc.cpp index 2b920c9..7bb5b77 100644 --- a/libs/fastfile/PC/fastfile_cod9_pc.cpp +++ b/libs/fastfile/PC/fastfile_cod9_pc.cpp @@ -121,7 +121,7 @@ bool FastFile_COD9_PC::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -129,7 +129,7 @@ bool FastFile_COD9_PC::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD9_PC zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PS3/fastfile_cod10_ps3.cpp b/libs/fastfile/PS3/fastfile_cod10_ps3.cpp index e0f1bca..b8535a3 100644 --- a/libs/fastfile/PS3/fastfile_cod10_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod10_ps3.cpp @@ -121,7 +121,7 @@ bool FastFile_COD10_PS3::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -129,7 +129,7 @@ bool FastFile_COD10_PS3::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD10_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PS3/fastfile_cod11_ps3.cpp b/libs/fastfile/PS3/fastfile_cod11_ps3.cpp index 34c7e91..a2bc836 100644 --- a/libs/fastfile/PS3/fastfile_cod11_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod11_ps3.cpp @@ -121,7 +121,7 @@ bool FastFile_COD11_PS3::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -129,7 +129,7 @@ bool FastFile_COD11_PS3::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD11_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PS3/fastfile_cod12_ps3.cpp b/libs/fastfile/PS3/fastfile_cod12_ps3.cpp index b3768e1..36d0b04 100644 --- a/libs/fastfile/PS3/fastfile_cod12_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod12_ps3.cpp @@ -121,7 +121,7 @@ bool FastFile_COD12_PS3::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -129,7 +129,7 @@ bool FastFile_COD12_PS3::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD12_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PS3/fastfile_cod4_ps3.cpp b/libs/fastfile/PS3/fastfile_cod4_ps3.cpp index d6ccbe3..d21402a 100644 --- a/libs/fastfile/PS3/fastfile_cod4_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod4_ps3.cpp @@ -109,10 +109,10 @@ bool FastFile_COD4_PS3::Load(const QByteArray aData) { pos += chunkSize; } - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD4_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PS3/fastfile_cod5_ps3.cpp b/libs/fastfile/PS3/fastfile_cod5_ps3.cpp index 4c84099..b341169 100644 --- a/libs/fastfile/PS3/fastfile_cod5_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod5_ps3.cpp @@ -109,10 +109,10 @@ bool FastFile_COD5_PS3::Load(const QByteArray aData) { pos += chunkSize; } - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD5_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PS3/fastfile_cod6_ps3.cpp b/libs/fastfile/PS3/fastfile_cod6_ps3.cpp index f0d0929..d6d1b7c 100644 --- a/libs/fastfile/PS3/fastfile_cod6_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod6_ps3.cpp @@ -93,10 +93,10 @@ bool FastFile_COD6_PS3::Load(const QByteArray aData) { // For COD5, simply decompress from offset 12. decompressedData = Compression::DecompressZLIB(aData.mid(12)); - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); ZoneFile_COD6_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/PS3/fastfile_cod7_ps3.cpp b/libs/fastfile/PS3/fastfile_cod7_ps3.cpp index 8bc980a..eefe0ff 100644 --- a/libs/fastfile/PS3/fastfile_cod7_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod7_ps3.cpp @@ -88,7 +88,7 @@ bool FastFile_COD7_PS3::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD7_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7/COD9, use BigEndian. fastFileStream.setByteOrder(QDataStream::BigEndian); diff --git a/libs/fastfile/PS3/fastfile_cod8_ps3.cpp b/libs/fastfile/PS3/fastfile_cod8_ps3.cpp index fef9e69..3d10fb5 100644 --- a/libs/fastfile/PS3/fastfile_cod8_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod8_ps3.cpp @@ -88,7 +88,7 @@ bool FastFile_COD8_PS3::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD8_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7/COD9, use BigEndian. fastFileStream.setByteOrder(QDataStream::BigEndian); diff --git a/libs/fastfile/PS3/fastfile_cod9_ps3.cpp b/libs/fastfile/PS3/fastfile_cod9_ps3.cpp index 787c08d..e13fdef 100644 --- a/libs/fastfile/PS3/fastfile_cod9_ps3.cpp +++ b/libs/fastfile/PS3/fastfile_cod9_ps3.cpp @@ -121,7 +121,7 @@ bool FastFile_COD9_PS3::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -129,7 +129,7 @@ bool FastFile_COD9_PS3::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD9_PS3 zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/Wii/fastfile_cod4_wii.cpp b/libs/fastfile/Wii/fastfile_cod4_wii.cpp index b661fc3..c2c920c 100644 --- a/libs/fastfile/Wii/fastfile_cod4_wii.cpp +++ b/libs/fastfile/Wii/fastfile_cod4_wii.cpp @@ -69,46 +69,18 @@ bool FastFile_COD4_Wii::Load(const QString aFilePath) { bool FastFile_COD4_Wii::Load(const QByteArray aData) { QByteArray decompressedData; - // Create a QDataStream on the input data. - QDataStream fastFileStream(aData); - fastFileStream.setByteOrder(QDataStream::LittleEndian); - - // Parse header values. - SetCompany(pParseFFCompany(&fastFileStream)); - SetType(pParseFFFileType(&fastFileStream)); - SetSignage(pParseFFSignage(&fastFileStream)); - SetMagic(pParseFFMagic(&fastFileStream)); - quint32 version = pParseFFVersion(&fastFileStream); - SetVersion(version); - SetPlatform(pCalculateFFPlatform(version)); - SetGame("COD7"); - // Load the zone file with the decompressed data (using an Xbox platform flag). - ZoneFile_COD7_Wii zoneFile; - zoneFile.SetStem(GetStem()); - - // For COD7/COD9, use BigEndian. - fastFileStream.setByteOrder(QDataStream::BigEndian); + ZoneFile_COD4_Wii zoneFile; + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7, simply decompress from offset 12. decompressedData = Compression::DecompressZLIB(aData.mid(12)); - Utils::ExportData(GetStem() + ".zone", decompressedData); - - QDir workingDir = QDir::currentPath(); - workingDir.mkdir("exports"); - - QFile outputFile("exports/" + GetStem() + ".zone"); - if (!outputFile.open(QIODevice::WriteOnly)) { - qDebug() << "Failed to extract IPAK file."; - } - qDebug() << " - File Name: " << outputFile.fileName(); - outputFile.write(decompressedData); - outputFile.close(); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); zoneFile.Load(decompressedData); - SetZoneFile(std::make_shared(zoneFile)); + SetZoneFile(std::make_shared(zoneFile)); return true; } diff --git a/libs/fastfile/Wii/fastfile_cod7_wii.cpp b/libs/fastfile/Wii/fastfile_cod7_wii.cpp index 26735d2..fed87bc 100644 --- a/libs/fastfile/Wii/fastfile_cod7_wii.cpp +++ b/libs/fastfile/Wii/fastfile_cod7_wii.cpp @@ -85,7 +85,7 @@ bool FastFile_COD7_Wii::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD7_Wii zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7/COD9, use BigEndian. fastFileStream.setByteOrder(QDataStream::BigEndian); @@ -93,16 +93,15 @@ bool FastFile_COD7_Wii::Load(const QByteArray aData) { // For COD7, simply decompress from offset 12. decompressedData = Compression::DecompressZLIB(aData.mid(12)); - Utils::ExportData(GetStem() + ".zone", decompressedData); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); QDir workingDir = QDir::currentPath(); workingDir.mkdir("exports"); - QFile outputFile("exports/" + GetStem() + ".zone"); + QFile outputFile("exports/" + GetBaseStem() + ".zone"); if (!outputFile.open(QIODevice::WriteOnly)) { qDebug() << "Failed to extract IPAK file."; } - qDebug() << " - File Name: " << outputFile.fileName(); outputFile.write(decompressedData); outputFile.close(); diff --git a/libs/fastfile/Wii/fastfile_cod8_wii.cpp b/libs/fastfile/Wii/fastfile_cod8_wii.cpp index 8252db3..aef0884 100644 --- a/libs/fastfile/Wii/fastfile_cod8_wii.cpp +++ b/libs/fastfile/Wii/fastfile_cod8_wii.cpp @@ -14,7 +14,7 @@ FastFile_COD8_Wii::FastFile_COD8_Wii() SetSignage(SIGNAGE_UNSIGNED); SetMagic(0); SetVersion(0); - SetGame("COD7"); + SetGame("COD8"); SetPlatform("Wii"); } @@ -78,37 +78,23 @@ bool FastFile_COD8_Wii::Load(const QByteArray aData) { SetType(pParseFFFileType(&fastFileStream)); SetSignage(pParseFFSignage(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream)); - quint32 version = pParseFFVersion(&fastFileStream); - SetVersion(version); - SetPlatform(pCalculateFFPlatform(version)); - SetGame("COD7"); + SetVersion(pParseFFVersion(&fastFileStream)); // Load the zone file with the decompressed data (using an Xbox platform flag). - ZoneFile_COD7_Wii zoneFile; - zoneFile.SetStem(GetStem()); + ZoneFile_COD8_Wii zoneFile; + zoneFile.SetStem(GetBaseStem() + ".zone"); // For COD7/COD9, use BigEndian. fastFileStream.setByteOrder(QDataStream::BigEndian); // For COD7, simply decompress from offset 12. - decompressedData = Compression::DecompressZLIB(aData.mid(12)); + decompressedData = Compression::DecompressZLIB(aData.mid(25)); - Utils::ExportData(GetStem() + ".zone", decompressedData); - - QDir workingDir = QDir::currentPath(); - workingDir.mkdir("exports"); - - QFile outputFile("exports/" + GetStem() + ".zone"); - if (!outputFile.open(QIODevice::WriteOnly)) { - qDebug() << "Failed to extract IPAK file."; - } - qDebug() << " - File Name: " << outputFile.fileName(); - outputFile.write(decompressedData); - outputFile.close(); + Utils::ExportData(GetBaseStem() + ".zone", decompressedData); zoneFile.Load(decompressedData); - SetZoneFile(std::make_shared(zoneFile)); + SetZoneFile(std::make_shared(zoneFile)); return true; } diff --git a/libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp b/libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp index 165dd42..1bab0e9 100644 --- a/libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp +++ b/libs/fastfile/WiiU/fastfile_cod10_wiiu.cpp @@ -119,7 +119,7 @@ bool FastFile_COD10_WiiU::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -127,7 +127,7 @@ bool FastFile_COD10_WiiU::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD10_WiiU zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); diff --git a/libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp b/libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp index 52078d2..49e19e0 100644 --- a/libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp +++ b/libs/fastfile/WiiU/fastfile_cod9_wiiu.cpp @@ -119,7 +119,7 @@ bool FastFile_COD9_WiiU::Load(const QByteArray aData) { } // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/" + GetStem() + ".zone"); + QFile testFile("exports/" + GetBaseStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -127,7 +127,7 @@ bool FastFile_COD9_WiiU::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD9_WiiU zoneFile; - zoneFile.SetStem(GetStem()); + zoneFile.SetStem(GetBaseStem() + ".zone"); zoneFile.Load(decompressedData); SetZoneFile(std::make_shared(zoneFile)); From 3e311e5aecabe0d57da67ada3fc7445dbb12da77 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:25:32 -0400 Subject: [PATCH 16/32] Fix data compression, byte order handling, and tag parsing in COD Wii zonefile --- libs/zonefile/360/zonefile_cod10_360.cpp | 2 +- libs/zonefile/360/zonefile_cod11_360.cpp | 2 +- libs/zonefile/360/zonefile_cod12_360.cpp | 2 +- libs/zonefile/360/zonefile_cod2_360.cpp | 595 +++++++++++---------- libs/zonefile/360/zonefile_cod2_360.h | 12 + libs/zonefile/360/zonefile_cod4_360.cpp | 264 +++++---- libs/zonefile/360/zonefile_cod5_360.cpp | 2 +- libs/zonefile/360/zonefile_cod6_360.cpp | 12 +- libs/zonefile/360/zonefile_cod7_360.cpp | 2 +- libs/zonefile/360/zonefile_cod8_360.cpp | 2 +- libs/zonefile/360/zonefile_cod9_360.cpp | 2 +- libs/zonefile/PC/zonefile_cod10_pc.cpp | 2 +- libs/zonefile/PC/zonefile_cod11_pc.cpp | 2 +- libs/zonefile/PC/zonefile_cod12_pc.cpp | 2 +- libs/zonefile/PC/zonefile_cod4_pc.cpp | 54 +- libs/zonefile/PC/zonefile_cod5_pc.cpp | 2 +- libs/zonefile/PC/zonefile_cod6_pc.cpp | 2 +- libs/zonefile/PC/zonefile_cod7_pc.cpp | 2 +- libs/zonefile/PC/zonefile_cod8_pc.cpp | 2 +- libs/zonefile/PC/zonefile_cod9_pc.cpp | 2 +- libs/zonefile/PS3/zonefile_cod10_ps3.cpp | 2 +- libs/zonefile/PS3/zonefile_cod11_ps3.cpp | 2 +- libs/zonefile/PS3/zonefile_cod12_ps3.cpp | 2 +- libs/zonefile/PS3/zonefile_cod4_ps3.cpp | 70 +-- libs/zonefile/PS3/zonefile_cod5_ps3.cpp | 2 +- libs/zonefile/PS3/zonefile_cod6_ps3.cpp | 2 +- libs/zonefile/PS3/zonefile_cod7_ps3.cpp | 2 +- libs/zonefile/PS3/zonefile_cod8_ps3.cpp | 2 +- libs/zonefile/PS3/zonefile_cod9_ps3.cpp | 2 +- libs/zonefile/Wii/zonefile_cod4_wii.cpp | 8 +- libs/zonefile/Wii/zonefile_cod7_wii.cpp | 2 +- libs/zonefile/Wii/zonefile_cod8_wii.cpp | 2 +- libs/zonefile/WiiU/zonefile_cod10_wiiu.cpp | 2 +- libs/zonefile/WiiU/zonefile_cod9_wiiu.cpp | 2 +- libs/zonefile/asset_structs.h | 43 +- libs/zonefile/zonefile.cpp | 380 +++++++++---- libs/zonefile/zonefile.h | 5 +- 37 files changed, 867 insertions(+), 630 deletions(-) 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(); From af82d9a78a2ecf2131a462c629b41903d6c59eea Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:29:01 -0400 Subject: [PATCH 17/32] Add category support to XTreeWidget with TREE_CATEGORY enum and sorting improvements --- app/xtreewidget.cpp | 217 +++++++++++++++++++++++----------------- app/xtreewidget.h | 1 + app/xtreewidgetitem.cpp | 18 +++- app/xtreewidgetitem.h | 12 +++ 4 files changed, 155 insertions(+), 93 deletions(-) diff --git a/app/xtreewidget.cpp b/app/xtreewidget.cpp index e4c8747..dc00cd9 100644 --- a/app/xtreewidget.cpp +++ b/app/xtreewidget.cpp @@ -16,6 +16,7 @@ XTreeWidget::XTreeWidget(QWidget *parent) header()->hide(); setMinimumWidth(350); setSortingEnabled(true); + setIconSize(QSize(16, 16)); header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); @@ -38,42 +39,44 @@ XTreeWidget::~XTreeWidget() { void XTreeWidget::AddFastFile(std::shared_ptr aFastFile) { XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this); - fastFileItem->setText(0, aFastFile->GetStem() + ".ff"); - fastFileItem->setIcon(0, QIcon(":/icons/icons/Icon_FastFile.png")); + fastFileItem->setText(0, aFastFile->GetStem()); + fastFileItem->setIcon(0, Utils::CreateAssetIcon("FF")); if (aFastFile->GetPlatform() == "PC") { - fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_PC.png")); + fastFileItem->setIcon(1, Utils::CreateAssetIcon("PC")); } else if (aFastFile->GetPlatform() == "360") { - fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_Xbox.png")); + fastFileItem->setIcon(1, Utils::CreateAssetIcon("360")); + } else if (aFastFile->GetPlatform() == "PS3") { + fastFileItem->setIcon(1, Utils::CreateAssetIcon("PS3")); } else if (aFastFile->GetPlatform() == "Wii") { - fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_Wii.png")); + fastFileItem->setIcon(1, Utils::CreateAssetIcon("WII")); } else if (aFastFile->GetPlatform() == "WiiU") { - fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_WiiU.png")); + fastFileItem->setIcon(1, Utils::CreateAssetIcon("WU")); } if (aFastFile->GetGame() == "COD2") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD2.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(2)); } if (aFastFile->GetGame() == "COD4") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD4.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(4)); } else if (aFastFile->GetGame() == "COD5") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD5.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(5)); } else if (aFastFile->GetGame() == "COD6") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD6.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(6)); } else if (aFastFile->GetGame() == "COD7") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD7.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(7)); } else if (aFastFile->GetGame() == "COD8") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD8.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(8)); } else if (aFastFile->GetGame() == "COD9") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD9.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(9)); } else if (aFastFile->GetGame() == "COD10") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD10.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(10)); } else if (aFastFile->GetGame() == "COD11") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD11.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(11)); } else if (aFastFile->GetGame() == "COD12") { - fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD12.png")); + fastFileItem->setIcon(2, Utils::CreateGameIcon(12)); } AddZoneFile(aFastFile->GetZoneFile(), fastFileItem); - mFastFiles[aFastFile->GetStem().section(".", 0, 0)] = aFastFile; + mFastFiles[aFastFile->GetStem()] = aFastFile; resizeColumnToContents(1); setSortingEnabled(true); @@ -87,42 +90,52 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt } else { zoneItem = new XTreeWidgetItem(this); } - zoneItem->setIcon(0, QIcon(":/icons/icons/Icon_ZoneFile.png")); - zoneItem->setText(0, aZoneFile->GetStem() + ".zone"); + zoneItem->setIcon(0, ZoneFile::AssetTypeToIcon(ASSET_ZONE_FILE)); + zoneItem->setText(0, aZoneFile->GetBaseStem() + ".zone"); auto assetMap = aZoneFile->GetAssetMap(); if (!assetMap.localStrings.isEmpty()) { + QIcon localStrIcon = ZoneFile::AssetTypeToIcon(ASSET_LOCAL_STRING); + XTreeWidgetItem *localStrRoot = new XTreeWidgetItem(zoneItem); localStrRoot->setText(0, "String Files"); - localStrRoot->setIcon(0, QIcon(":/icons/icons/Icon_StringFile.png")); + localStrRoot->setIcon(0, localStrIcon); + localStrRoot->SetCategory(CATEGORY_TYPE); XTreeWidgetItem *localStrItem = new XTreeWidgetItem(localStrRoot); localStrItem->setText(0, aZoneFile->GetStem().section('.', 0, 0) + ".str"); - localStrItem->setIcon(0, QIcon(":/icons/icons/Icon_StringFile.png")); + localStrItem->setIcon(0, localStrIcon); } if (!assetMap.techSets.isEmpty()) { + QIcon techSetIcon = ZoneFile::AssetTypeToIcon(ASSET_TECH_SET); + XTreeWidgetItem *techSetRoot = new XTreeWidgetItem(zoneItem); techSetRoot->setText(0, "Tech Sets"); - techSetRoot->setIcon(0, QIcon(":/icons/icons/Icon_TechSetFile.png")); + techSetRoot->setIcon(0, techSetIcon); + techSetRoot->SetCategory(CATEGORY_TYPE); for (TechSet techSet : assetMap.techSets) { XTreeWidgetItem *techSetItem = new XTreeWidgetItem(techSetRoot); techSetItem->setText(0, techSet.name); - techSetItem->setIcon(0, QIcon(":/icons/icons/Icon_TechSetFile.png")); + techSetItem->setIcon(0, techSetIcon); } } if (!assetMap.rawFiles.isEmpty()) { + QIcon rawFileIcon = ZoneFile::AssetTypeToIcon(ASSET_RAW_FILE); + XTreeWidgetItem *rawFileRoot = new XTreeWidgetItem(zoneItem); rawFileRoot->setText(0, "Raw Files"); - rawFileRoot->setIcon(0, QIcon(":/icons/icons/Icon_GSCFile.png")); + rawFileRoot->setIcon(0, rawFileIcon); + rawFileRoot->SetCategory(CATEGORY_TYPE); for (RawFile rawFile : assetMap.rawFiles) { if (!rawFile.length) { continue; } XTreeWidgetItem *tempItem = rawFileRoot; - for (const QString &pathPart : rawFile.path.split('/')) { + const QStringList pathParts = rawFile.path.split('/'); + for (const QString &pathPart : pathParts) { bool childFound = false; for (int i = 0; i < tempItem->childCount(); i++) { QTreeWidgetItem *rawChildItem = tempItem->child(i); @@ -135,25 +148,30 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt } } - if (pathPart.contains(".gsc")) { + const QString rawFileStr = QString("%1 [%2-%3]").arg(pathPart).arg(rawFile.startPos).arg(rawFile.endPos); + //rawFileStr = pathPart; + if (pathPart == pathParts.last()) { XTreeWidgetItem *rawFileItem = new XTreeWidgetItem(tempItem); - rawFileItem->setText(0, pathPart); + rawFileItem->setText(0, rawFileStr); tempItem = rawFileItem; } else if (!childFound) { tempItem = new XTreeWidgetItem(tempItem); - tempItem->setText(0, pathPart); + tempItem->setText(0, rawFileStr); } } - tempItem->setIcon(0, QIcon(":/icons/icons/Icon_GSCFile.png")); + tempItem->setIcon(0, rawFileIcon); } } if (!assetMap.menuFiles.isEmpty()) { + QIcon menuFileIcon = ZoneFile::AssetTypeToIcon(ASSET_MENU); + XTreeWidgetItem *menuRoot = new XTreeWidgetItem(zoneItem); menuRoot->setText(0, "Menu Files"); - menuRoot->setIcon(0, QIcon(":/icons/icons/Icon_MenuFile.png")); + menuRoot->setIcon(0, menuFileIcon); + menuRoot->SetCategory(CATEGORY_TYPE); int menuIndex = 1; for (MenuFile menuFile : assetMap.menuFiles) { @@ -162,64 +180,79 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt for (Menu menu : menuFile.menuDefs) { XTreeWidgetItem *menuItem = new XTreeWidgetItem(menuFileRoot); menuItem->setText(0, menu.filePath); - menuItem->setIcon(0, QIcon(":/icons/icons/Icon_MenuFile.png")); + menuItem->setIcon(0, menuFileIcon); } menuIndex++; } } if (!assetMap.images.isEmpty()) { + QIcon imageIcon = ZoneFile::AssetTypeToIcon(ASSET_IMAGE); + XTreeWidgetItem *imageRoot = new XTreeWidgetItem(zoneItem); imageRoot->setText(0, "Images"); - imageRoot->setIcon(0, QIcon(":/icons/icons/Icon_Image.png")); + imageRoot->setIcon(0, imageIcon); + imageRoot->SetCategory(CATEGORY_TYPE); for (Image image : assetMap.images) { XTreeWidgetItem *imageItem = new XTreeWidgetItem(imageRoot); imageItem->setText(0, image.materialName); - imageItem->setIcon(0, QIcon(":/icons/icons/Icon_Image.png")); + imageItem->setIcon(0, imageIcon); } } if (!assetMap.models.isEmpty()) { + QIcon modelIcon = ZoneFile::AssetTypeToIcon(ASSET_MODEL); + XTreeWidgetItem *modelsRoot = new XTreeWidgetItem(zoneItem); modelsRoot->setText(0, "Models"); - modelsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Model.png")); + modelsRoot->setIcon(0, modelIcon); + modelsRoot->SetCategory(CATEGORY_TYPE); for (Model model: assetMap.models) { XTreeWidgetItem *modelItem = new XTreeWidgetItem(modelsRoot); modelItem->setText(0, model.modelName); - modelItem->setIcon(0, QIcon(":/icons/icons/Icon_Model.png")); + modelItem->setIcon(0, modelIcon); } } if (!assetMap.materials.isEmpty()) { + QIcon materialIcon = ZoneFile::AssetTypeToIcon(ASSET_MATERIAL); + XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem); materialsRoot->setText(0, "Materials"); - materialsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Material.png")); + materialsRoot->setIcon(0, materialIcon); + materialsRoot->SetCategory(CATEGORY_TYPE); for (Material material: assetMap.materials) { XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot); materialItem->setText(0, material.name); - materialItem->setIcon(0, QIcon(":/icons/icons/Icon_Material.png")); + materialItem->setIcon(0, materialIcon); } } if (!assetMap.stringTables.isEmpty()) { + QIcon stringTableIcon = ZoneFile::AssetTypeToIcon(ASSET_STRING_TABLE); + XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem); strTableRoot->setText(0, "String Tables"); - strTableRoot->setIcon(0, QIcon(":/icons/icons/Icon_StringTable.png")); + strTableRoot->setIcon(0, stringTableIcon); + strTableRoot->SetCategory(CATEGORY_TYPE); for (StringTable strTable: assetMap.stringTables) { XTreeWidgetItem *modelItem = new XTreeWidgetItem(strTableRoot); modelItem->setText(0, strTable.name); - modelItem->setIcon(0, QIcon(":/icons/icons/Icon_StringTable.png")); + modelItem->setIcon(0, stringTableIcon); } } if (!assetMap.sounds.isEmpty()) { + QIcon soundIcon = ZoneFile::AssetTypeToIcon(ASSET_SOUND); + XTreeWidgetItem *soundsRoot = new XTreeWidgetItem(zoneItem); soundsRoot->setText(0, "Sounds"); - soundsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Sound.png")); + soundsRoot->setIcon(0, soundIcon); + soundsRoot->SetCategory(CATEGORY_TYPE); for (SoundAsset soundAsset : assetMap.sounds) { for (Sound sound : soundAsset.sounds) { XTreeWidgetItem *tempItem = soundsRoot; @@ -251,16 +284,16 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt } } - tempItem->setIcon(0, QIcon(":/icons/icons/Icon_Sound.png")); + tempItem->setIcon(0, soundIcon); } } } - mZoneFiles[aZoneFile->GetStem().section(".", 0, 0)] = aZoneFile; + mZoneFiles[aZoneFile->GetBaseStem() + ".zone"] = aZoneFile; } void XTreeWidget::CloseFastFile(const QString aFFName) { - const QString fileStem = aFFName.section(".", 0, 0); + const QString fileStem = aFFName; emit ItemClosed(fileStem); } @@ -361,7 +394,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { iwiFile->SaveJPG(); }); } else if (activeText.contains(".ff")) { - const QString fileStem = activeText.replace(".zone", ""); + const QString fileStem = activeText; QMenu *closeMultipleAction = new QMenu("Close Multiple Tabs"); @@ -385,7 +418,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { auto childItem = invisibleRootItem()->child(i); if (childItem == activeItem) { continue; } - const QString fileStem = childItem->text(0).replace(".ff", ""); + const QString fileStem = childItem->text(0); if (!mFastFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; return; @@ -407,7 +440,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { auto childItem = invisibleRootItem()->child(i); if (childItem == activeItem) { return; } - const QString fileStem = childItem->text(0).replace(".ff", ""); + const QString fileStem = childItem->text(0); if (!mFastFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; return; @@ -434,7 +467,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { continue; } - const QString fileStem = childItem->text(0).replace(".ff", ""); + const QString fileStem = childItem->text(0); if (!mFastFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; return; @@ -454,7 +487,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { connect(closeAction, &QAction::triggered, this, [this, &activeItem, &activeText](bool checked) { Q_UNUSED(checked); - const QString fileStem = activeItem->text(0).replace(".ff", ""); + const QString fileStem = activeItem->text(0); mFastFiles.remove(fileStem); CloseFastFile(activeText); @@ -488,7 +521,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { fastFile->GetZoneFile()->SaveZoneFile(zoneFilePath); }); } else if (activeText.contains(".zone")) { - const QString fileStem = activeText.replace(".zone", ""); + const QString fileStem = activeText; if (!mZoneFiles.contains(fileStem)) { qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; return; @@ -618,63 +651,39 @@ void XTreeWidget::ItemSelectionChanged() { QString selectedText = selectedItem->text(0); emit ItemSelected(selectedText); - const QString fileStem = selectedText.section(".", 0, 0); - XTreeWidgetItem *parentItem = dynamic_cast(selectedItem->parent()); if (selectedText.contains(".dds")) { - if (!mDDSFiles.contains(fileStem)) { - LogManager::instance().addError("Could not find " + fileStem + " in DDS map!"); + if (!mDDSFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in DDS map!"); return; } - std::shared_ptr ddsFile = mDDSFiles[fileStem]; - emit DDSFileSelected(ddsFile, fileStem); + std::shared_ptr ddsFile = mDDSFiles[selectedText]; + emit DDSFileSelected(ddsFile, selectedText); } else if (selectedText.contains(".iwi")) { - if (!mIWIFiles.contains(fileStem)) { - LogManager::instance().addError("Could not find " + fileStem + " in IWI map!"); + if (!mIWIFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in IWI map!"); return; } - emit IWIFileSelected(mIWIFiles[fileStem], fileStem); + emit IWIFileSelected(mIWIFiles[selectedText], selectedText); } else if (selectedText.contains(".ff")) { - if (!mFastFiles.contains(fileStem)) { - LogManager::instance().addError("Could not find " + fileStem + " in Fast File map!"); + if (!mFastFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in Fast File map!"); return; } - emit FastFileSelected(mFastFiles[fileStem], fileStem); + emit FastFileSelected(mFastFiles[selectedText], selectedText); } else if (selectedText.contains(".zone")) { - if (!mZoneFiles.contains(fileStem)) { - LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!"); + if (!mZoneFiles.contains(selectedText)) { + LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!"); return; } - emit ZoneFileSelected(mZoneFiles[fileStem], fileStem); + emit ZoneFileSelected(mZoneFiles[selectedText], selectedText); } else if (selectedText.contains(".str")) { - if (!mZoneFiles.contains(fileStem)) { - LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!"); + if (!mZoneFiles.contains(selectedText.replace(".str", ".zone"))) { + LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!"); return; } - emit LocalStringSelected(mZoneFiles[fileStem], fileStem); - } else if (selectedText.contains(".gsc")) { - XTreeWidgetItem *zoneRoot = selectedItem; - if (!zoneRoot) { return; } - - while (!zoneRoot->text(0).contains(".zone")) { - zoneRoot = dynamic_cast(zoneRoot->parent()); - if (!zoneRoot) { return; } - } - - const QString fileStem = zoneRoot->text(0).section('.', 0, 0); - if (!mZoneFiles.contains(fileStem)) { - LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!"); - return; - } - - QVector rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles; - for (RawFile rawFile : rawFiles) { - if (rawFile.path.contains(selectedText)) { - emit RawFileSelected(std::make_shared(rawFile), fileStem); - return; - } - } + emit LocalStringSelected(mZoneFiles[selectedText], selectedText); } else if (parentItem && (parentItem->text(0) == "Images")) { XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); if (grandpaItem && grandpaItem->text(0).contains(".zone")) { @@ -744,6 +753,32 @@ void XTreeWidget::ItemSelectionChanged() { } } } + } else if (selectedItem->GetCategory() != CATEGORY_TYPE) { + XTreeWidgetItem *zoneRoot = selectedItem; + + bool zoneChild = false; + while (zoneRoot) { + zoneRoot = dynamic_cast(zoneRoot->parent()); + if (zoneRoot->text(0).contains("Raw Files")) { + zoneChild = true; + break; + } + } + if (!zoneChild) { return; } + const QString fileStem = zoneRoot->parent()->text(0); + + if (!mZoneFiles.contains(fileStem)) { + LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!"); + return; + } + + QVector rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles; + for (RawFile rawFile : rawFiles) { + if (rawFile.path.split('/').last() == selectedText) { + emit RawFileSelected(std::make_shared(rawFile), fileStem); + return; + } + } } } @@ -784,7 +819,7 @@ void XTreeWidget::AddIWIFile(std::shared_ptr aIWIFile) { } XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this); - iwiItem->setIcon(0, QIcon(":/icons/icons/Icon_IWIFile.png")); + iwiItem->setIcon(0, ZoneFile::AssetTypeToIcon(ASSET_IMAGE)); iwiItem->setText(0, iwiFileName); mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile; } @@ -800,7 +835,7 @@ void XTreeWidget::AddDDSFile(std::shared_ptr aDDSFile) { } XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this); - ddsItem->setIcon(0, QIcon(":/icons/icons/Icon_DDSFile.png")); + ddsItem->setIcon(0, ZoneFile::AssetTypeToIcon(ASSET_IMAGE)); ddsItem->setText(0, ddsFileName); mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile; } diff --git a/app/xtreewidget.h b/app/xtreewidget.h index 24db62e..5026fca 100644 --- a/app/xtreewidget.h +++ b/app/xtreewidget.h @@ -8,6 +8,7 @@ #include "fastfile.h" #include "xtreewidgetitem.h" #include "zonefile.h" +#include "utils.h" #include #include diff --git a/app/xtreewidgetitem.cpp b/app/xtreewidgetitem.cpp index eae4ee9..bed2d07 100644 --- a/app/xtreewidgetitem.cpp +++ b/app/xtreewidgetitem.cpp @@ -1,15 +1,29 @@ #include "xtreewidgetitem.h" XTreeWidgetItem::XTreeWidgetItem(QTreeWidget *parent, bool group) - : QTreeWidgetItem(parent), isGroup(group) { + : QTreeWidgetItem(parent) + , isGroup(group) + , mCategory(CATEGORY_NONE) { } XTreeWidgetItem::XTreeWidgetItem(QTreeWidgetItem *parent, bool group) - : QTreeWidgetItem(parent), isGroup(group) { + : QTreeWidgetItem(parent) + , isGroup(group) + , mCategory(CATEGORY_NONE) { } +void XTreeWidgetItem::SetCategory(TREE_CATEGORY category) +{ + mCategory = category; +} + +TREE_CATEGORY XTreeWidgetItem::GetCategory() +{ + return mCategory; +} + bool XTreeWidgetItem::operator<(const QTreeWidgetItem &other) const { // Attempt to cast the other item to our custom type. const XTreeWidgetItem* otherItem = dynamic_cast(&other); diff --git a/app/xtreewidgetitem.h b/app/xtreewidgetitem.h index e189d04..ff1f544 100644 --- a/app/xtreewidgetitem.h +++ b/app/xtreewidgetitem.h @@ -4,6 +4,12 @@ #include #include +enum TREE_CATEGORY { + CATEGORY_NONE = 0x00, + CATEGORY_FILE = 0x01, + CATEGORY_TYPE = 0x02 +}; + // Custom item class class XTreeWidgetItem : public QTreeWidgetItem { @@ -15,9 +21,15 @@ public: XTreeWidgetItem(QTreeWidget *parent, bool group = false); XTreeWidgetItem(QTreeWidgetItem *parent, bool group = false); + void SetCategory(TREE_CATEGORY category); + TREE_CATEGORY GetCategory(); + // Override the less-than operator to customize sorting. bool operator<(const QTreeWidgetItem &other) const override; XTreeWidgetItem &operator =(const XTreeWidgetItem &other); + +private: + TREE_CATEGORY mCategory; }; From 7b0fe256504d53e79894903a5aa422d395f0c648 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:29:43 -0400 Subject: [PATCH 18/32] Add search, remove column, update zone viewer. --- app/zonefileviewer.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/app/zonefileviewer.cpp b/app/zonefileviewer.cpp index 6e25c04..52d736e 100644 --- a/app/zonefileviewer.cpp +++ b/app/zonefileviewer.cpp @@ -1,6 +1,8 @@ #include "zonefileviewer.h" #include "ui_zonefileviewer.h" +#include "statusbarmanager.h" + ZoneFileViewer::ZoneFileViewer(QWidget *parent) : QWidget(parent) , ui(new Ui::ZoneFileViewer) { @@ -8,16 +10,19 @@ ZoneFileViewer::ZoneFileViewer(QWidget *parent) mZoneFile = nullptr; - ui->tableWidget_RecordCounts->setColumnCount(4); - ui->tableWidget_RecordCounts->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count", "Icon" }); + ui->tableWidget_RecordCounts->setColumnCount(3); + ui->tableWidget_RecordCounts->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count" }); ui->tableWidget_RecordCounts->horizontalHeader()->setStretchLastSection(true); - ui->tableWidget_RecordOrder->setColumnCount(4); - ui->tableWidget_RecordOrder->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count", "Icon" }); + ui->tableWidget_RecordOrder->setColumnCount(3); + ui->tableWidget_RecordOrder->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count" }); ui->tableWidget_RecordOrder->horizontalHeader()->setStretchLastSection(true); connect(ui->lineEdit_TagSearch, &QLineEdit::textChanged, this, &ZoneFileViewer::SortTags); connect(ui->tableWidget_RecordCounts, &QTableWidget::itemSelectionChanged, this, &ZoneFileViewer::HighlightRecordInOrder); + connect(ui->listWidget_Tags, &QListWidget::currentTextChanged, this, [this](const QString &aCurrentText) { + StatusBarManager::instance().updateStatus(QString("Selected tag '%1' with index %2").arg(aCurrentText).arg(mZoneFile->GetTags().indexOf(aCurrentText))); + }); } ZoneFileViewer::~ZoneFileViewer() { @@ -60,6 +65,7 @@ void ZoneFileViewer::SortTags(const QString &aSearchText) { } } + StatusBarManager::instance().updateStatus(QString("Found %1 tags.").arg(sortedTags.size())); ui->listWidget_Tags->addItems(sortedTags); } @@ -72,7 +78,9 @@ void ZoneFileViewer::SetZoneFile(std::shared_ptr aZoneFile) { const QStringList tags = mZoneFile->GetTags(); ui->listWidget_Tags->addItems(tags); - ui->label_Title->setText(mZoneFile->GetStem() + ".zone"); + ui->label_Title->setText(mZoneFile->GetBaseStem() + ".zone"); + + ui->groupBox_Tags->setTitle(QString("Tags (%1)").arg(tags.size())); if (tags.isEmpty()) { ui->groupBox_Tags->hide(); @@ -112,13 +120,11 @@ void ZoneFileViewer::SetZoneFile(std::shared_ptr aZoneFile) { QTableWidgetItem *recordItem = new QTableWidgetItem(record.toUpper()); QTableWidgetItem *recordStrItem = new QTableWidgetItem(mZoneFile->AssetEnumToStr(assetType)); QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(assetCount)); - QTableWidgetItem *recordIconItem = new QTableWidgetItem(); - recordIconItem->setIcon(assetIcon); + recordItem->setIcon(assetIcon); ui->tableWidget_RecordOrder->setItem(assetIndex, 0, recordItem); ui->tableWidget_RecordOrder->setItem(assetIndex, 1, recordStrItem); ui->tableWidget_RecordOrder->setItem(assetIndex, 2, recordCountItem); - ui->tableWidget_RecordOrder->setItem(assetIndex, 3, recordIconItem); assetIndex++; } @@ -135,16 +141,14 @@ void ZoneFileViewer::SetZoneFile(std::shared_ptr aZoneFile) { ui->tableWidget_RecordCounts->setRowCount(recordIndex + 1); - QTableWidgetItem *recordCountStrItem = new QTableWidgetItem(mZoneFile->AssetEnumToStr(assetType)); QTableWidgetItem *recordItem = new QTableWidgetItem(record.toUpper()); + QTableWidgetItem *recordCountStrItem = new QTableWidgetItem(mZoneFile->AssetEnumToStr(assetType)); QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(recordCount)); - QTableWidgetItem *recordIconItem = new QTableWidgetItem(); - recordIconItem->setIcon(assetIcon); + recordItem->setIcon(assetIcon); ui->tableWidget_RecordCounts->setItem(recordIndex, 0, recordItem); ui->tableWidget_RecordCounts->setItem(recordIndex, 1, recordCountStrItem); ui->tableWidget_RecordCounts->setItem(recordIndex, 2, recordCountItem); - ui->tableWidget_RecordCounts->setItem(recordIndex, 3, recordIconItem); recordIndex++; } From f3427e77bae840caf85814dde7b4da45b50a8d57 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:30:03 -0400 Subject: [PATCH 19/32] Remove unused files from resource. --- data/Data.qrc | 63 --------------------------------------------------- 1 file changed, 63 deletions(-) diff --git a/data/Data.qrc b/data/Data.qrc index b0c1755..8929957 100644 --- a/data/Data.qrc +++ b/data/Data.qrc @@ -1,26 +1,4 @@ - - obj/defaultactor_LOD0.XMODEL_BIN - obj/defaultactor_LOD0.XMODEL_EXPORT - obj/defaultactor_LOD0.bin - obj/defaultactor_LOD0.cast - obj/defaultactor_LOD0.gltf - obj/defaultactor_LOD0.ma - obj/defaultactor_LOD0.mesh.ascii - obj/defaultactor_LOD0.obj - obj/defaultactor_LOD0.semodel - obj/defaultactor_LOD0.smd - obj/defaultactor_LOD0_BIND.mel - obj/defaultactor_LOD0_cosmetics.mel - obj/diffusemap.png - obj/mtl_body_default_character.mtl - obj/mtl_body_default_character_images.txt - obj/normalmap.png - - - d3dbsp/asset_viewer.d3dbsp - d3dbsp/barebones.d3dbsp - images/XPlor.png images/copy.svg @@ -34,28 +12,6 @@ images/save.svg - icons/Icon_COD4.png - icons/Icon_COD5.png - icons/Icon_COD6.png - icons/Icon_COD7.png - icons/Icon_COD8.png - icons/Icon_COD9.png - icons/Icon_DDSFile.png - icons/Icon_FastFile.png - icons/Icon_IWIFile.png - icons/Icon_PC.png - icons/Icon_Playstation.png - icons/Icon_Xbox.png - icons/Icon_ZoneFile.png - icons/Icon_GSCFile.png - icons/Icon_StringFile.png - icons/Icon_TechSetFile.png - icons/Icon_WAVFile.png - icons/Icon_MenuFile.png - icons/Icon_Image.png - icons/Icon_Model.png - icons/Icon_StringTable.png - icons/Icon_Sound.png icons/Icon_Pause.png icons/Icon_Play.png icons/Icon_SkipBack.png @@ -71,24 +27,5 @@ icons/Icon_Paste.png icons/Icon_Save.png icons/Icon_OpenFile.png - icons/Icon_COD2.png - icons/Icon_Material.png - icons/Icon_Animation.png - icons/Icon_BSP.png - icons/Icon_ColMapSp.png - icons/Icon_Effect.png - icons/Icon_GameMapSp.png - icons/Icon_Font.png - icons/Icon_FXMap.png - icons/Icon_LightDef.png - icons/Icon_Weapon.png - icons/Icon_RawFile.png - icons/Icon_Destructible.png - icons/Icon_PhysPreset.png - icons/Icon_Wii.png - icons/Icon_WiiU.png - icons/Icon_COD10.png - icons/Icon_COD11.png - icons/Icon_COD12.png From b204858a905fb365f030f9bf4265ce54a3c665e5 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:31:11 -0400 Subject: [PATCH 20/32] Add XMem functions (in progress) and LZO, fix ZLib. --- libs/compression/compression.cpp | 113 +++++++++++++++++++++++++------ libs/compression/compression.h | 9 ++- 2 files changed, 100 insertions(+), 22 deletions(-) diff --git a/libs/compression/compression.cpp b/libs/compression/compression.cpp index 690b43f..2b5f08a 100644 --- a/libs/compression/compression.cpp +++ b/libs/compression/compression.cpp @@ -1,5 +1,5 @@ #include "compression.h" -//#include "lzokay.h" +#include "minilzo.h" #define XBOXAPI __declspec(dllimport) #include "xcompress.h" @@ -13,8 +13,8 @@ QByteArray Compression::CompressXMem(const QByteArray &data) { XMEMCODEC_PARAMETERS_LZX lzxParams = {}; lzxParams.Flags = 0; - lzxParams.WindowSize = XCOMPRESS_LZX_BLOCK_SIZE; - lzxParams.CompressionPartitionSize = XCOMPRESS_LZX_BLOCK_SIZE; + lzxParams.WindowSize = 0x20000; + lzxParams.CompressionPartitionSize = 0x80000; XMEMCOMPRESSION_CONTEXT ctx = nullptr; if (FAILED(XMemCreateCompressionContext(XMEMCODEC_LZX, &lzxParams, 0, &ctx)) || !ctx) @@ -34,25 +34,35 @@ QByteArray Compression::CompressXMem(const QByteArray &data) return output; } -QByteArray Compression::DecompressXMem(const QByteArray &data) +QByteArray Compression::DecompressXMem(const QByteArray &data, int flags, int windowSize, int partSize) { + if (data.isEmpty()) + return {}; + XMEMCODEC_PARAMETERS_LZX lzxParams = {}; - lzxParams.Flags = 0; - lzxParams.WindowSize = XCOMPRESS_LZX_BLOCK_SIZE; - lzxParams.CompressionPartitionSize = XCOMPRESS_LZX_BLOCK_SIZE; + lzxParams.Flags = flags; + lzxParams.WindowSize = windowSize; + lzxParams.CompressionPartitionSize = partSize; XMEMDECOMPRESSION_CONTEXT ctx = nullptr; if (FAILED(XMemCreateDecompressionContext(XMEMCODEC_LZX, &lzxParams, 0, &ctx)) || !ctx) - return QByteArray(); + return {}; - QByteArray output(data.size(), 0); - SIZE_T actualSize = data.size(); + // Allocate large enough buffer for decompression (16 MB is a safe upper bound) + const SIZE_T kMaxOutSize = 16 * 1024 * 1024; + QByteArray output(static_cast(kMaxOutSize), Qt::Uninitialized); + SIZE_T actualSize = kMaxOutSize; + + HRESULT hr = XMemDecompress(ctx, + output.data(), &actualSize, + data.constData(), data.size() + 16); - HRESULT hr = XMemDecompress(ctx, output.data(), &actualSize, data.constData(), data.size()); XMemDestroyDecompressionContext(ctx); - if (FAILED(hr)) - return QByteArray(); + if (FAILED(hr)) { + qWarning() << "XMemDecompress failed with HRESULT:" << hr; + return {}; + } output.resize(static_cast(actualSize)); return output; @@ -68,6 +78,46 @@ quint32 Compression::CalculateAdler32Checksum(const QByteArray &data) { return adler; } +qint64 Compression::FindZlibOffset(const QByteArray &bytes) +{ + static const QByteArray iwffs("IWffs"); + auto idx = bytes.indexOf(iwffs); + if (idx != -1) + return idx + 0x4000; + + const char header = 0x78; // z-lib: 0x78 [FLG] + int pos = -1; + while ((pos = bytes.indexOf(header, pos + 1)) != -1) + { + QByteArray window = bytes.mid(pos, 0x20); + if (!window.contains(QByteArray::fromHex("000000")) && + !window.contains(QByteArray::fromHex("FFFFFF"))) + return pos; + } + return -1; +} + +QByteArray Compression::StripHashBlocks(const QByteArray &raw, + int dataChunkSize, + int hashChunkSize) +{ + QByteArray cleaned; + cleaned.reserve(raw.size()); // upper bound + + int p = 0; + while (p < raw.size()) + { + const int chunk = qMin(dataChunkSize, raw.size() - p); + cleaned.append(raw.constData() + p, chunk); + p += chunk; + + // skip hash bytes if they are still inside the buffer + if (p < raw.size()) + p += qMin(hashChunkSize, raw.size() - p); + } + return cleaned; +} + QByteArray Compression::DecompressZLIB(const QByteArray &aCompressedData) { if (aCompressedData.isEmpty()) { return {}; @@ -95,22 +145,23 @@ QByteArray Compression::DecompressZLIB(const QByteArray &aCompressedData) { ret = inflate(&strm, Z_NO_FLUSH); - if (strm.avail_out < buffer.size()) { // Data has been written to the buffer + if (strm.avail_out < buffer.size()) { decompressed.append(buffer.constData(), buffer.size() - strm.avail_out); } if (ret == Z_STREAM_END) { - break; // Proper end of the data stream + break; } if (ret == Z_BUF_ERROR && strm.avail_out == 0) { - // Buffer was completely used, resize it - int newSize = buffer.size() * 2; // Double the buffer size - buffer.resize(newSize); + buffer.resize(buffer.size() * 2); } else if (ret != Z_OK) { - qWarning() << "Zlib error:" << zError(ret); + size_t errorOffset = strm.total_in; + qWarning() << "Zlib error:" << zError(ret) + << "at offset" << errorOffset + << "of" << aCompressedData.size() << "bytes"; inflateEnd(&strm); - return {}; // Return on other errors + return decompressed; } } while (ret != Z_STREAM_END); @@ -118,6 +169,7 @@ QByteArray Compression::DecompressZLIB(const QByteArray &aCompressedData) { return decompressed; } + QByteArray Compression::CompressZLIB(const QByteArray &aData) { return CompressZLIBWithSettings(aData); } @@ -242,6 +294,27 @@ QByteArray Compression::CompressDeflateWithSettings(const QByteArray &aData, int return compressed; } +QByteArray Compression::DecompressLZO(const QByteArray &aCompressedData, quint32 aDestSize) { + static bool ok = (lzo_init() == LZO_E_OK); + if (!ok) + throw std::runtime_error("lzo_init failed"); + + QByteArray dst(aDestSize, Qt::Uninitialized); + lzo_uint out = aDestSize; + + int rc = lzo1x_decompress_safe( + reinterpret_cast(aCompressedData.constData()), + static_cast(aCompressedData.size()), + reinterpret_cast(dst.data()), + &out, + nullptr); + + if (rc != LZO_E_OK || out != aDestSize) + throw std::runtime_error("LZO decompression error"); + + return dst; +} + QByteArray Compression::DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize) { return pDecompressOodle(aCompressedData, aCompressedData.length(), aDecompressedSize); } diff --git a/libs/compression/compression.h b/libs/compression/compression.h index 6bdae3b..c57bc57 100644 --- a/libs/compression/compression.h +++ b/libs/compression/compression.h @@ -47,6 +47,10 @@ class Compression { public: static quint32 CalculateAdler32Checksum(const QByteArray &data); static QByteArray DecompressZLIB(const QByteArray &aCompressedData); + static qint64 FindZlibOffset(const QByteArray &bytes); + static QByteArray StripHashBlocks(const QByteArray &raw, + int dataChunkSize = 0x200000, + int hashChunkSize = 0x2000); static QByteArray CompressZLIB(const QByteArray &aData); static QByteArray CompressZLIBWithSettings(const QByteArray &aData, int aCompressionLevel = Z_BEST_COMPRESSION, @@ -64,13 +68,14 @@ public: int aStrategy = Z_DEFAULT_STRATEGY, const QByteArray &aDictionary = {}); + static QByteArray DecompressLZO(const QByteArray &aCompressedData, quint32 aDestSize); + static QByteArray DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize); static QByteArray CompressOodle(const QByteArray &aData); static QByteArray CompressXMem(const QByteArray &data); - static QByteArray DecompressXMem(const QByteArray &data); - + static QByteArray DecompressXMem(const QByteArray &data, int flags = 0, int windowSize = 0x20000, int partSize = 0x80000); private: static quint32 pGetOodleCompressedBounds(quint32 aBufferSize); static QByteArray pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize, From ea3919920120391106c18fd80aca7642f9f76754 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:31:22 -0400 Subject: [PATCH 21/32] Add XMem functions (in progress) and LZO, fix ZLib. --- libs/compression/compression.pro | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/compression/compression.pro b/libs/compression/compression.pro index a585902..3bb3af9 100644 --- a/libs/compression/compression.pro +++ b/libs/compression/compression.pro @@ -1,14 +1,17 @@ QT += core TEMPLATE = lib CONFIG += staticlib c++17 +DEFINES += MINILZO_USE_STATIC SOURCES += \ compression.cpp \ - lzokay.cpp \ + minilzo.c \ + lzoconf.h \ + lzodefs.h HEADERS += \ compression.h \ - lzokay.h + minilzo.h LIBS += \ -L$$PWD/../../third_party/xbox_sdk/lib -lxcompress64 \ From ac33cd45245e37a08f161a5e7f279aa00122b67b Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:31:53 -0400 Subject: [PATCH 22/32] Remove unused lzo source. --- libs/compression/lzokay.cpp | 647 ------------------------------------ libs/compression/lzokay.h | 79 ----- 2 files changed, 726 deletions(-) delete mode 100644 libs/compression/lzokay.cpp delete mode 100644 libs/compression/lzokay.h diff --git a/libs/compression/lzokay.cpp b/libs/compression/lzokay.cpp deleted file mode 100644 index 2bccc48..0000000 --- a/libs/compression/lzokay.cpp +++ /dev/null @@ -1,647 +0,0 @@ -#include "lzokay.h" -#include -#include -#include - -/* - * Based on documentation from the Linux sources: Documentation/lzo.txt - * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/lzo.txt - */ - -namespace lzokay { - -#if _WIN32 -#define HOST_BIG_ENDIAN 0 -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define HOST_BIG_ENDIAN 1 -#else -#define HOST_BIG_ENDIAN 0 -#endif - -#if HOST_BIG_ENDIAN -static uint16_t get_le16(const uint8_t* p) { - uint16_t val = *reinterpret_cast(p); -#if __GNUC__ - return __builtin_bswap16(val); -#elif _WIN32 - return _byteswap_ushort(val); -#else - return (val = (val << 8) | ((val >> 8) & 0xFF)); -#endif -} -#else -static uint16_t get_le16(const uint8_t* p) { - return *reinterpret_cast(p); -} -#endif - -constexpr std::size_t Max255Count = std::size_t(~0) / 255 - 2; - -#define NEEDS_IN(count) \ -if (inp + (count) > inp_end) { \ - dst_size = outp - dst; \ - return EResult::InputOverrun; \ -} - -#define NEEDS_OUT(count) \ -if (outp + (count) > outp_end) { \ - dst_size = outp - dst; \ - return EResult::OutputOverrun; \ -} - -#define CONSUME_ZERO_BYTE_LENGTH \ -std::size_t offset; \ -{ \ - const uint8_t *old_inp = inp; \ - while (*inp == 0) ++inp; \ - offset = inp - old_inp; \ - if (offset > Max255Count) { \ - dst_size = outp - dst; \ - return EResult::Error; \ - } \ -} - -#define WRITE_ZERO_BYTE_LENGTH(length) \ -{ \ - std::size_t l; \ - for (l = length; l > 255; l -= 255) { *outp++ = 0; } \ - *outp++ = static_cast(l); \ -} - -constexpr uint32_t M1MaxOffset = 0x0400; -constexpr uint32_t M2MaxOffset = 0x0800; -constexpr uint32_t M3MaxOffset = 0x4000; -// constexpr uint32_t M4MaxOffset = 0xbfff; - -// constexpr uint32_t M1MinLen = 2; -// constexpr uint32_t M1MaxLen = 2; -constexpr uint32_t M2MinLen = 3; -constexpr uint32_t M2MaxLen = 8; -// constexpr uint32_t M3MinLen = 3; -constexpr uint32_t M3MaxLen = 33; -// constexpr uint32_t M4MinLen = 3; -constexpr uint32_t M4MaxLen = 9; - -constexpr uint32_t M1Marker = 0x0; -// constexpr uint32_t M2Marker = 0x40; -constexpr uint32_t M3Marker = 0x20; -constexpr uint32_t M4Marker = 0x10; - -constexpr uint32_t MaxMatchByLengthLen = 34; /* Max M3 len + 1 */ - -EResult decompress(const uint8_t* src, std::size_t src_size, - uint8_t* dst, std::size_t init_dst_size, - std::size_t& dst_size) { - dst_size = init_dst_size; - - if (src_size < 3) { - dst_size = 0; - return EResult::InputOverrun; - } - - const uint8_t* inp = src; - const uint8_t* inp_end = src + src_size; - uint8_t* outp = dst; - uint8_t* outp_end = dst + dst_size; - uint8_t* lbcur; - std::size_t lblen; - std::size_t state = 0; - std::size_t nstate = 0; - - /* First byte encoding */ - if (*inp >= 22) { - /* 22..255 : copy literal string - * length = (byte - 17) = 4..238 - * state = 4 [ don't copy extra literals ] - * skip byte - */ - std::size_t len = *inp++ - uint8_t(17); - NEEDS_IN(len) - NEEDS_OUT(len) - for (std::size_t i = 0; i < len; ++i) - *outp++ = *inp++; - state = 4; - } else if (*inp >= 18) { - /* 18..21 : copy 0..3 literals - * state = (byte - 17) = 0..3 [ copy literals ] - * skip byte - */ - nstate = *inp++ - uint8_t(17); - state = nstate; - NEEDS_IN(nstate) - NEEDS_OUT(nstate) - for (std::size_t i = 0; i < nstate; ++i) - *outp++ = *inp++; - } - /* 0..17 : follow regular instruction encoding, see below. It is worth - * noting that codes 16 and 17 will represent a block copy from - * the dictionary which is empty, and that they will always be - * invalid at this place. - */ - - while (true) { - NEEDS_IN(1) - uint8_t inst = *inp++; - if (inst & 0xC0) { - /* [M2] - * 1 L L D D D S S (128..255) - * Copy 5-8 bytes from block within 2kB distance - * state = S (copy S literals after this block) - * length = 5 + L - * Always followed by exactly one byte : H H H H H H H H - * distance = (H << 3) + D + 1 - * - * 0 1 L D D D S S (64..127) - * Copy 3-4 bytes from block within 2kB distance - * state = S (copy S literals after this block) - * length = 3 + L - * Always followed by exactly one byte : H H H H H H H H - * distance = (H << 3) + D + 1 - */ - NEEDS_IN(1) - lbcur = outp - ((*inp++ << 3) + ((inst >> 2) & 0x7) + 1); - lblen = std::size_t(inst >> 5) + 1; - nstate = inst & uint8_t(0x3); - } else if (inst & M3Marker) { - /* [M3] - * 0 0 1 L L L L L (32..63) - * Copy of small block within 16kB distance (preferably less than 34B) - * length = 2 + (L ?: 31 + (zero_bytes * 255) + non_zero_byte) - * Always followed by exactly one LE16 : D D D D D D D D : D D D D D D S S - * distance = D + 1 - * state = S (copy S literals after this block) - */ - lblen = std::size_t(inst & uint8_t(0x1f)) + 2; - if (lblen == 2) { - CONSUME_ZERO_BYTE_LENGTH - NEEDS_IN(1) - lblen += offset * 255 + 31 + *inp++; - } - NEEDS_IN(2) - nstate = get_le16(inp); - inp += 2; - lbcur = outp - ((nstate >> 2) + 1); - nstate &= 0x3; - } else if (inst & M4Marker) { - /* [M4] - * 0 0 0 1 H L L L (16..31) - * Copy of a block within 16..48kB distance (preferably less than 10B) - * length = 2 + (L ?: 7 + (zero_bytes * 255) + non_zero_byte) - * Always followed by exactly one LE16 : D D D D D D D D : D D D D D D S S - * distance = 16384 + (H << 14) + D - * state = S (copy S literals after this block) - * End of stream is reached if distance == 16384 - */ - lblen = std::size_t(inst & uint8_t(0x7)) + 2; - if (lblen == 2) { - CONSUME_ZERO_BYTE_LENGTH - NEEDS_IN(1) - lblen += offset * 255 + 7 + *inp++; - } - NEEDS_IN(2) - nstate = get_le16(inp); - inp += 2; - lbcur = outp - (((inst & 0x8) << 11) + (nstate >> 2)); - nstate &= 0x3; - if (lbcur == outp) - break; /* Stream finished */ - lbcur -= 16384; - } else { - /* [M1] Depends on the number of literals copied by the last instruction. */ - if (state == 0) { - /* If last instruction did not copy any literal (state == 0), this - * encoding will be a copy of 4 or more literal, and must be interpreted - * like this : - * - * 0 0 0 0 L L L L (0..15) : copy long literal string - * length = 3 + (L ?: 15 + (zero_bytes * 255) + non_zero_byte) - * state = 4 (no extra literals are copied) - */ - std::size_t len = inst + 3; - if (len == 3) { - CONSUME_ZERO_BYTE_LENGTH - NEEDS_IN(1) - len += offset * 255 + 15 + *inp++; - } - /* copy_literal_run */ - NEEDS_IN(len) - NEEDS_OUT(len) - for (std::size_t i = 0; i < len; ++i) - *outp++ = *inp++; - state = 4; - continue; - } else if (state != 4) { - /* If last instruction used to copy between 1 to 3 literals (encoded in - * the instruction's opcode or distance), the instruction is a copy of a - * 2-byte block from the dictionary within a 1kB distance. It is worth - * noting that this instruction provides little savings since it uses 2 - * bytes to encode a copy of 2 other bytes but it encodes the number of - * following literals for free. It must be interpreted like this : - * - * 0 0 0 0 D D S S (0..15) : copy 2 bytes from <= 1kB distance - * length = 2 - * state = S (copy S literals after this block) - * Always followed by exactly one byte : H H H H H H H H - * distance = (H << 2) + D + 1 - */ - NEEDS_IN(1) - nstate = inst & uint8_t(0x3); - lbcur = outp - ((inst >> 2) + (*inp++ << 2) + 1); - lblen = 2; - } else { - /* If last instruction used to copy 4 or more literals (as detected by - * state == 4), the instruction becomes a copy of a 3-byte block from the - * dictionary from a 2..3kB distance, and must be interpreted like this : - * - * 0 0 0 0 D D S S (0..15) : copy 3 bytes from 2..3 kB distance - * length = 3 - * state = S (copy S literals after this block) - * Always followed by exactly one byte : H H H H H H H H - * distance = (H << 2) + D + 2049 - */ - NEEDS_IN(1) - nstate = inst & uint8_t(0x3); - lbcur = outp - ((inst >> 2) + (*inp++ << 2) + 2049); - lblen = 3; - } - } - if (lbcur < dst) { - dst_size = outp - dst; - return EResult::LookbehindOverrun; - } - NEEDS_IN(nstate) - NEEDS_OUT(lblen + nstate) - /* Copy lookbehind */ - for (std::size_t i = 0; i < lblen; ++i) - *outp++ = *lbcur++; - state = nstate; - /* Copy literal */ - for (std::size_t i = 0; i < nstate; ++i) - *outp++ = *inp++; - } - - dst_size = outp - dst; - if (lblen != 3) /* Ensure terminating M4 was encountered */ - return EResult::Error; - if (inp == inp_end) - return EResult::Success; - else if (inp < inp_end) - return EResult::InputNotConsumed; - else - return EResult::InputOverrun; -} - -struct State { - const uint8_t* src; - const uint8_t* src_end; - const uint8_t* inp; - uint32_t wind_sz; - uint32_t wind_b; - uint32_t wind_e; - uint32_t cycle1_countdown; - - const uint8_t* bufp; - uint32_t buf_sz; - - /* Access next input byte and advance both ends of circular buffer */ - void get_byte(uint8_t* buf) { - if (inp >= src_end) { - if (wind_sz > 0) - --wind_sz; - buf[wind_e] = 0; - if (wind_e < DictBase::MaxMatchLen) - buf[DictBase::BufSize + wind_e] = 0; - } else { - buf[wind_e] = *inp; - if (wind_e < DictBase::MaxMatchLen) - buf[DictBase::BufSize + wind_e] = *inp; - ++inp; - } - if (++wind_e == DictBase::BufSize) - wind_e = 0; - if (++wind_b == DictBase::BufSize) - wind_b = 0; - } - - uint32_t pos2off(uint32_t pos) const { - return wind_b > pos ? wind_b - pos : DictBase::BufSize - (pos - wind_b); - } -}; - -class DictImpl : public DictBase { -public: - struct Match3Impl : DictBase::Match3 { - static uint32_t make_key(const uint8_t* data) { - return ((0x9f5f * (((uint32_t(data[0]) << 5 ^ uint32_t(data[1])) << 5) ^ data[2])) >> 5) & 0x3fff; - } - - uint16_t get_head(uint32_t key) const { - return (chain_sz[key] == 0) ? uint16_t(UINT16_MAX) : head[key]; - } - - void init() { - std::fill(std::begin(chain_sz), std::end(chain_sz), 0); - } - - void remove(uint32_t pos, const uint8_t* b) { - --chain_sz[make_key(b + pos)]; - } - - void advance(State& s, uint32_t& match_pos, uint32_t& match_count, const uint8_t* b) { - uint32_t key = make_key(b + s.wind_b); - match_pos = chain[s.wind_b] = get_head(key); - match_count = chain_sz[key]++; - if (match_count > DictBase::MaxMatchLen) - match_count = DictBase::MaxMatchLen; - head[key] = uint16_t(s.wind_b); - } - - void skip_advance(State& s, const uint8_t* b) { - uint32_t key = make_key(b + s.wind_b); - chain[s.wind_b] = get_head(key); - head[key] = uint16_t(s.wind_b); - best_len[s.wind_b] = uint16_t(DictBase::MaxMatchLen + 1); - chain_sz[key]++; - } - }; - - struct Match2Impl : DictBase::Match2 { - static uint32_t make_key(const uint8_t* data) { - return uint32_t(data[0]) ^ (uint32_t(data[1]) << 8); - } - - void init() { - std::fill(std::begin(head), std::end(head), UINT16_MAX); - } - - void add(uint16_t pos, const uint8_t* b) { - head[make_key(b + pos)] = pos; - } - - void remove(uint32_t pos, const uint8_t* b) { - uint16_t& p = head[make_key(b + pos)]; - if (p == pos) - p = UINT16_MAX; - } - - bool search(State& s, uint32_t& lb_pos, uint32_t& lb_len, - uint32_t best_pos[MaxMatchByLengthLen], const uint8_t* b) const { - uint16_t pos = head[make_key(b + s.wind_b)]; - if (pos == UINT16_MAX) - return false; - if (best_pos[2] == 0) - best_pos[2] = pos + 1; - if (lb_len < 2) { - lb_len = 2; - lb_pos = pos; - } - return true; - } - }; - - void init(State& s, const uint8_t* src, std::size_t src_size) { - auto& match3 = static_cast(_storage->match3); - auto& match2 = static_cast(_storage->match2); - - s.cycle1_countdown = DictBase::MaxDist; - match3.init(); - match2.init(); - - s.src = src; - s.src_end = src + src_size; - s.inp = src; - s.wind_sz = uint32_t(std::min(src_size, std::size_t(MaxMatchLen))); - s.wind_b = 0; - s.wind_e = s.wind_sz; - std::copy_n(s.inp, s.wind_sz, _storage->buffer); - s.inp += s.wind_sz; - - if (s.wind_e == DictBase::BufSize) - s.wind_e = 0; - - if (s.wind_sz < 3) - std::fill_n(_storage->buffer + s.wind_b + s.wind_sz, 3, 0); - } - - void reset_next_input_entry(State& s, Match3Impl& match3, Match2Impl& match2) { - /* Remove match from about-to-be-clobbered buffer entry */ - if (s.cycle1_countdown == 0) { - match3.remove(s.wind_e, _storage->buffer); - match2.remove(s.wind_e, _storage->buffer); - } else { - --s.cycle1_countdown; - } - } - - void advance(State& s, uint32_t& lb_off, uint32_t& lb_len, - uint32_t best_off[MaxMatchByLengthLen], bool skip) { - auto& match3 = static_cast(_storage->match3); - auto& match2 = static_cast(_storage->match2); - - if (skip) { - for (uint32_t i = 0; i < lb_len - 1; ++i) { - reset_next_input_entry(s, match3, match2); - match3.skip_advance(s, _storage->buffer); - match2.add(uint16_t(s.wind_b), _storage->buffer); - s.get_byte(_storage->buffer); - } - } - - lb_len = 1; - lb_off = 0; - uint32_t lb_pos; - - uint32_t best_pos[MaxMatchByLengthLen] = {}; - uint32_t match_pos, match_count; - match3.advance(s, match_pos, match_count, _storage->buffer); - - int best_char = _storage->buffer[s.wind_b]; - uint32_t best_len = lb_len; - if (lb_len >= s.wind_sz) { - if (s.wind_sz == 0) - best_char = -1; - lb_off = 0; - match3.best_len[s.wind_b] = DictBase::MaxMatchLen + 1; - } else { - if (match2.search(s, lb_pos, lb_len, best_pos, _storage->buffer) && s.wind_sz >= 3) { - for (uint32_t i = 0; i < match_count; ++i, match_pos = match3.chain[match_pos]) { - auto ref_ptr = _storage->buffer + s.wind_b; - auto match_ptr = _storage->buffer + match_pos; - auto mismatch = std::mismatch(ref_ptr, ref_ptr + s.wind_sz, match_ptr); - auto match_len = uint32_t(mismatch.first - ref_ptr); - if (match_len < 2) - continue; - if (match_len < MaxMatchByLengthLen && best_pos[match_len] == 0) - best_pos[match_len] = match_pos + 1; - if (match_len > lb_len) { - lb_len = match_len; - lb_pos = match_pos; - if (match_len == s.wind_sz || match_len > match3.best_len[match_pos]) - break; - } - } - } - if (lb_len > best_len) - lb_off = s.pos2off(lb_pos); - match3.best_len[s.wind_b] = uint16_t(lb_len); - for (auto posit = std::begin(best_pos) + 2, offit = best_off + 2; - posit != std::end(best_pos); ++posit, ++offit) { - *offit = (*posit > 0) ? s.pos2off(*posit - 1) : 0; - } - } - - reset_next_input_entry(s, match3, match2); - - match2.add(uint16_t(s.wind_b), _storage->buffer); - - s.get_byte(_storage->buffer); - - if (best_char < 0) { - s.buf_sz = 0; - lb_len = 0; - /* Signal exit */ - } else { - s.buf_sz = s.wind_sz + 1; - } - s.bufp = s.inp - s.buf_sz; - } -}; - -static void find_better_match(const uint32_t best_off[MaxMatchByLengthLen], uint32_t& lb_len, uint32_t& lb_off) { - if (lb_len <= M2MinLen || lb_off <= M2MaxOffset) - return; - if (lb_off > M2MaxOffset && lb_len >= M2MinLen + 1 && lb_len <= M2MaxLen + 1 && - best_off[lb_len - 1] != 0 && best_off[lb_len - 1] <= M2MaxOffset) { - lb_len -= 1; - lb_off = best_off[lb_len]; - } else if (lb_off > M3MaxOffset && lb_len >= M4MaxLen + 1 && lb_len <= M2MaxLen + 2 && - best_off[lb_len - 2] && best_off[lb_len] <= M2MaxOffset) { - lb_len -= 2; - lb_off = best_off[lb_len]; - } else if (lb_off > M3MaxOffset && lb_len >= M4MaxLen + 1 && lb_len <= M3MaxLen + 1 && - best_off[lb_len - 1] != 0 && best_off[lb_len - 2] <= M3MaxOffset) { - lb_len -= 1; - lb_off = best_off[lb_len]; - } -} - -static EResult encode_literal_run(uint8_t*& outp, const uint8_t* outp_end, const uint8_t* dst, std::size_t& dst_size, - const uint8_t* lit_ptr, uint32_t lit_len) { - if (outp == dst && lit_len <= 238) { - NEEDS_OUT(1); - *outp++ = uint8_t(17 + lit_len); - } else if (lit_len <= 3) { - outp[-2] = uint8_t(outp[-2] | lit_len); - } else if (lit_len <= 18) { - NEEDS_OUT(1); - *outp++ = uint8_t(lit_len - 3); - } else { - NEEDS_OUT((lit_len - 18) / 255 + 2); - *outp++ = 0; - WRITE_ZERO_BYTE_LENGTH(lit_len - 18); - } - NEEDS_OUT(lit_len); - outp = std::copy_n(lit_ptr, lit_len, outp); - return EResult::Success; -} - -static EResult encode_lookback_match(uint8_t*& outp, const uint8_t* outp_end, const uint8_t* dst, std::size_t& dst_size, - uint32_t lb_len, uint32_t lb_off, uint32_t last_lit_len) { - if (lb_len == 2) { - lb_off -= 1; - NEEDS_OUT(2); - *outp++ = uint8_t(M1Marker | ((lb_off & 0x3) << 2)); - *outp++ = uint8_t(lb_off >> 2); - } else if (lb_len <= M2MaxLen && lb_off <= M2MaxOffset) { - lb_off -= 1; - NEEDS_OUT(2); - *outp++ = uint8_t((lb_len - 1) << 5 | ((lb_off & 0x7) << 2)); - *outp++ = uint8_t(lb_off >> 3); - } else if (lb_len == M2MinLen && lb_off <= M1MaxOffset + M2MaxOffset && last_lit_len >= 4) { - lb_off -= 1 + M2MaxOffset; - NEEDS_OUT(2); - *outp++ = uint8_t(M1Marker | ((lb_off & 0x3) << 2)); - *outp++ = uint8_t(lb_off >> 2); - } else if (lb_off <= M3MaxOffset) { - lb_off -= 1; - if (lb_len <= M3MaxLen) { - NEEDS_OUT(1); - *outp++ = uint8_t(M3Marker | (lb_len - 2)); - } else { - lb_len -= M3MaxLen; - NEEDS_OUT(lb_len / 255 + 2); - *outp++ = uint8_t(M3Marker); - WRITE_ZERO_BYTE_LENGTH(lb_len); - } - NEEDS_OUT(2); - *outp++ = uint8_t(lb_off << 2); - *outp++ = uint8_t(lb_off >> 6); - } else { - lb_off -= 0x4000; - if (lb_len <= M4MaxLen) { - NEEDS_OUT(1); - *outp++ = uint8_t(M4Marker | ((lb_off & 0x4000) >> 11) | (lb_len - 2)); - } else { - lb_len -= M4MaxLen; - NEEDS_OUT(lb_len / 255 + 2); - *outp++ = uint8_t(M4Marker | ((lb_off & 0x4000) >> 11)); - WRITE_ZERO_BYTE_LENGTH(lb_len); - } - NEEDS_OUT(2); - *outp++ = uint8_t(lb_off << 2); - *outp++ = uint8_t(lb_off >> 6); - } - return EResult::Success; -} - -EResult compress(const uint8_t* src, std::size_t src_size, - uint8_t* dst, std::size_t init_dst_size, - std::size_t& dst_size, DictBase& dict) { - EResult err; - State s; - auto& d = static_cast(dict); - dst_size = init_dst_size; - uint8_t* outp = dst; - uint8_t* outp_end = dst + dst_size; - uint32_t lit_len = 0; - uint32_t lb_off, lb_len; - uint32_t best_off[MaxMatchByLengthLen]; - d.init(s, src, src_size); - const uint8_t* lit_ptr = s.inp; - d.advance(s, lb_off, lb_len, best_off, false); - while (s.buf_sz > 0) { - if (lit_len == 0) - lit_ptr = s.bufp; - if (lb_len < 2 || (lb_len == 2 && (lb_off > M1MaxOffset || lit_len == 0 || lit_len >= 4)) || - (lb_len == 2 && outp == dst) || (outp == dst && lit_len == 0)) { - lb_len = 0; - } else if (lb_len == M2MinLen && lb_off > M1MaxOffset + M2MaxOffset && lit_len >= 4) { - lb_len = 0; - } - if (lb_len == 0) { - ++lit_len; - d.advance(s, lb_off, lb_len, best_off, false); - continue; - } - find_better_match(best_off, lb_len, lb_off); - if ((err = encode_literal_run(outp, outp_end, dst, dst_size, lit_ptr, lit_len)) < EResult::Success) - return err; - if ((err = encode_lookback_match(outp, outp_end, dst, dst_size, lb_len, lb_off, lit_len)) < EResult::Success) - return err; - lit_len = 0; - d.advance(s, lb_off, lb_len, best_off, true); - } - if ((err = encode_literal_run(outp, outp_end, dst, dst_size, lit_ptr, lit_len)) < EResult::Success) - return err; - - /* Terminating M4 */ - NEEDS_OUT(3); - *outp++ = M4Marker | 1; - *outp++ = 0; - *outp++ = 0; - - dst_size = outp - dst; - return EResult::Success; -} - -} diff --git a/libs/compression/lzokay.h b/libs/compression/lzokay.h deleted file mode 100644 index 522edd8..0000000 --- a/libs/compression/lzokay.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once -#include -#include -#include - -namespace lzokay { - -enum class EResult { - LookbehindOverrun = -4, - OutputOverrun = -3, - InputOverrun = -2, - Error = -1, - Success = 0, - InputNotConsumed = 1, -}; - -class DictBase { -protected: - static constexpr uint32_t HashSize = 0x4000; - static constexpr uint32_t MaxDist = 0xbfff; - static constexpr uint32_t MaxMatchLen = 0x800; - static constexpr uint32_t BufSize = MaxDist + MaxMatchLen; - - /* List encoding of previous 3-byte data matches */ - struct Match3 { - uint16_t head[HashSize]; /* key -> chain-head-pos */ - uint16_t chain_sz[HashSize]; /* key -> chain-size */ - uint16_t chain[BufSize]; /* chain-pos -> next-chain-pos */ - uint16_t best_len[BufSize]; /* chain-pos -> best-match-length */ - }; - /* Encoding of 2-byte data matches */ - struct Match2 { - uint16_t head[1 << 16]; /* 2-byte-data -> head-pos */ - }; - - struct Data { - Match3 match3; - Match2 match2; - - /* Circular buffer caching enough data to access the maximum lookback - * distance of 48K + maximum match length of 2K. An additional 2K is - * allocated so the start of the buffer may be replicated at the end, - * therefore providing efficient circular access. - */ - uint8_t buffer[BufSize + MaxMatchLen]; - }; - using storage_type = Data; - storage_type* _storage; - DictBase() = default; - friend struct State; - friend EResult compress(const uint8_t* src, std::size_t src_size, - uint8_t* dst, std::size_t& dst_size, DictBase& dict); -}; -template class _Alloc = std::allocator> -class Dict : public DictBase { - _Alloc _allocator; -public: - Dict() { _storage = _allocator.allocate(1); } - ~Dict() { _allocator.deallocate(_storage, 1); } -}; - -EResult decompress(const uint8_t* src, std::size_t src_size, - uint8_t* dst, std::size_t dst_size, - std::size_t& out_size); -EResult compress(const uint8_t* src, std::size_t src_size, - uint8_t* dst, std::size_t dst_size, - std::size_t& out_size, DictBase& dict); -inline EResult compress(const uint8_t* src, std::size_t src_size, - uint8_t* dst, std::size_t dst_size, - std::size_t& out_size) { - Dict<> dict; - return compress(src, src_size, dst, dst_size, out_size, dict); -} - -constexpr std::size_t compress_worst_size(std::size_t s) { - return s + s / 16 + 64 + 3; -} - -} From 3ac572edeb8d649aff2d45e9a096a65768a49890 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:32:14 -0400 Subject: [PATCH 23/32] Add highlightings to project. --- libs/core/core.pro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libs/core/core.pro b/libs/core/core.pro index 8cb5e5d..16bc396 100644 --- a/libs/core/core.pro +++ b/libs/core/core.pro @@ -3,11 +3,19 @@ TEMPLATE = lib CONFIG += staticlib c++17 SOURCES += \ + highlighter_cfg.cpp \ + highlighter_shock.cpp \ + highlighter_rumble.cpp \ + highlighter_gsc.cpp \ logmanager.cpp \ statusbarmanager.cpp HEADERS += \ enums.h \ + highlighter_cfg.h \ + highlighter_shock.h \ + highlighter_rumble.h \ + highlighter_gsc.h \ logmanager.h \ stringutils.h \ utils.h \ From 298d5e984881ab064778c1de076e955e8347f37e Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:32:34 -0400 Subject: [PATCH 24/32] Add color utilities. --- libs/core/utils.h | 174 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/libs/core/utils.h b/libs/core/utils.h index 81acd20..ed50b2f 100644 --- a/libs/core/utils.h +++ b/libs/core/utils.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include class Utils { public: @@ -22,6 +24,178 @@ public: testFile.close(); return true; } + static quint8 ReverseBits(quint8 b) { + b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; + b = (b & 0xCC) >> 2 | (b & 0x33) << 2; + b = (b & 0xAA) >> 1 | (b & 0x55) << 1; + return b; + } + static QIcon CreateAssetIcon(const QString& name, QColor color = QColor()) { + constexpr int iconSize = 32; + constexpr int padding = 4; + + QImage result(iconSize, iconSize, QImage::Format_ARGB32); + result.fill(Qt::transparent); + + if (!color.isValid()) { + color = Utils::StringToColor(name); + } + + QPainter painter(&result); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::TextAntialiasing, true); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); + + // Draw background + QBrush brush(color); + brush.setStyle(Qt::SolidPattern); + painter.setBrush(color); + painter.setPen(Qt::NoPen); + painter.drawRoundedRect(0, 0, iconSize, iconSize, 4, 4); + + // Set base font + QFont font("Heavitas"); + font.setPixelSize(iconSize); // Start large + painter.setFont(font); + + // Adjust font size to fit text width (only reduce, not increase) + QFontMetrics fm(font); + int textWidth = fm.horizontalAdvance(name); + while (textWidth > iconSize - 2 * padding && font.pixelSize() > 1) { + font.setPixelSize(font.pixelSize() - 1); + painter.setFont(font); + fm = QFontMetrics(font); + textWidth = fm.horizontalAdvance(name); + } + + // Calculate vertical scaling factor + qreal scaleY = 1.2 * iconSize / fm.height(); + + // Apply transform: scale vertically, center align + painter.save(); + painter.translate(iconSize / 2.0, iconSize / 2.0); + painter.scale(1.0, scaleY); + painter.translate(-iconSize / 2.0, -iconSize / 2.0); + + QRect textRect(0, 0, iconSize, iconSize); + + // Draw stroke + painter.setPen(Qt::black); + for (int dx = 0; dx <= 1; ++dx) { + for (int dy = 0; dy <= 1; ++dy) { + if (dx || dy) + painter.drawText(textRect.translated(dx, dy), Qt::AlignCenter, name); + } + } + + // Draw main text + painter.setPen(Qt::white); + painter.drawText(textRect, Qt::AlignCenter, name); + painter.restore(); + + // Debug output + QDir().mkdir(QDir().absoluteFilePath(".") + "/icons/"); + result.save(QDir().absoluteFilePath(".") + "/icons/" + name + ".png"); + + return QIcon(QPixmap::fromImage(result)); + } + + static QIcon CreateGameIcon(const int gameNum, QColor color = QColor()) { + constexpr int size = 32; + constexpr int padding = 4; // pixels of padding on all sides + const int contentSize = size - 2 * padding; + + QImage result(size, size, QImage::Format_ARGB32); + result.fill(Qt::transparent); + + if (!color.isValid()) { + color = Utils::StringToColor(QString("COD%1").arg(gameNum)); + } + + QPainter painter(&result); + painter.setRenderHint(QPainter::Antialiasing, false); + painter.setRenderHint(QPainter::TextAntialiasing, false); + painter.setRenderHint(QPainter::SmoothPixmapTransform, false); + + // Draw background + painter.setBrush(color); + painter.setPen(Qt::NoPen); + painter.drawRoundedRect(0, 0, size, size, 4, 4); + + // === Font Setup === + QFont codFont("Heavitas"); + codFont.setPixelSize(contentSize * 0.40); + + QFont numFont("Heavitas"); + numFont.setPixelSize(contentSize); + + // === Layout Areas (inside padding) === + const QRect contentRect(padding, padding, contentSize, contentSize); + const int col1 = contentRect.left(); + const int col2 = contentRect.left() + contentRect.width() / 3; + + const int thirdH = contentRect.height() / 3; + const QRect codRects[] = { + QRect(col1, 2 + contentRect.top(), contentRect.width() / 3, thirdH), + QRect(col1, contentRect.top() + thirdH, contentRect.width() / 3, thirdH), + QRect(col1, -2 + contentRect.top() + 2 * thirdH, contentRect.width() / 3, thirdH), + }; + + const QRect numRect(col2, contentRect.top(), contentRect.width() * 2 / 3, contentRect.height()); + + const QString codLetters[] = { "C", "O", "D" }; + const QString numText = QString::number(gameNum); + + // === Stroke pass === + for (int dx = -1; dx <= 2; ++dx) { + for (int dy = -1; dy <= 2; ++dy) { + if (dx == 0 && dy == 0) continue; + + painter.setPen(Qt::black); + painter.setFont(codFont); + for (int i = 0; i < 3; ++i) + painter.drawText(codRects[i].translated(dx, dy), Qt::AlignCenter, codLetters[i]); + + painter.setFont(numFont); + painter.drawText(numRect.translated(dx, dy), Qt::AlignCenter, numText); + } + } + + // === Fill pass === + painter.setPen(Qt::white); + painter.setFont(codFont); + for (int i = 0; i < 3; ++i) + painter.drawText(codRects[i], Qt::AlignCenter, codLetters[i]); + + painter.setFont(numFont); + painter.drawText(numRect, Qt::AlignCenter, numText); + + // Save & return icon + QDir().mkdir(QDir().absoluteFilePath(".") + "/icons/"); + result.save(QDir().absoluteFilePath(".") + QString("/icons/COD%1.png").arg(gameNum)); + + return QIcon(QPixmap::fromImage(result)); + } + + + static QColor StringToColor(const QString& str) { + // 1. Hash the string using Qt's built-in hash (MD5, SHA1, or any) + QByteArray hash = QCryptographicHash::hash(str.toUtf8(), QCryptographicHash::Md5); + + // 2. Use first 3 bytes of hash for RGB + // This guarantees same string = same color every time + int r = static_cast(hash[0]); + int g = static_cast(hash[1]); + int b = static_cast(hash[2]); + + // 3. Optionally adjust brightness or saturation to avoid too dark/light colors + QColor color(r, g, b); + if (color.value() < 128) { // brighten if too dark + color = color.lighter(150); + } + + return color; + } static bool ReadUntilString(QDataStream* stream, const QString& targetString) { if (!stream || targetString.isEmpty()) { return false; // Invalid input From 0576fb5bd47fb0cc6282bfb8c3a8bc1eb763d09c Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:33:02 -0400 Subject: [PATCH 25/32] Switch all to fastfile factory. --- libs/fastfile/fastfile.cpp | 47 +++++--------------------------- libs/fastfile/fastfile.h | 1 + libs/fastfile/fastfile_factory.h | 35 +++++++++++++++++------- 3 files changed, 33 insertions(+), 50 deletions(-) diff --git a/libs/fastfile/fastfile.cpp b/libs/fastfile/fastfile.cpp index 33a7687..dd8f34b 100644 --- a/libs/fastfile/fastfile.cpp +++ b/libs/fastfile/fastfile.cpp @@ -44,6 +44,10 @@ QString FastFile::GetStem() const { return mStem; } +QString FastFile::GetBaseStem() const { + return mStem.split('.').first(); +} + FF_FILETYPE FastFile::GetType() const { return mType; } @@ -257,50 +261,13 @@ std::shared_ptr FastFile::Open(const QString &aFilePath) { LogManager::instance().addEntry("Contents read in"); LogManager::instance().addEntry(QString("- Size: %1 B").arg(data.size())); - LogManager::instance().addEntry("File closed"); file->close(); + LogManager::instance().addEntry("File closed"); - // Create a QDataStream on the input data. - QDataStream fastFileStream(data); - fastFileStream.setByteOrder(QDataStream::LittleEndian); - - quint32 companyInt; - FF_COMPANY company = pParseFFCompany(&fastFileStream, companyInt); - qDebug() << "Company: " << company; - FF_FILETYPE fileType; - FF_SIGNAGE signage; - QString magic; - quint32 version; - QString platform; - QString game; - - if ((company == COMPANY_NONE) && (companyInt == 0)) { - company = COMPANY_INFINITY_WARD; - game = "COD2"; - platform = "360"; - } else { - fileType = pParseFFFileType(&fastFileStream); - signage = pParseFFSignage(&fastFileStream); - magic = pParseFFMagic(&fastFileStream); - version = pParseFFVersion(&fastFileStream); - platform = pCalculateFFPlatform(version); - game = pCalculateFFGame(version); - - LogManager::instance().addEntry(QString("Type: %1").arg(fileType)); - LogManager::instance().addEntry(QString("Signage: %1").arg(signage)); - LogManager::instance().addEntry(QString("Magic: %1").arg(magic)); - LogManager::instance().addEntry(QString("Version: %1").arg(version)); - } - LogManager::instance().addEntry(QString("Company: %1").arg(company)); - LogManager::instance().addEntry(QString("Game: %1").arg(game)); - LogManager::instance().addEntry(QString("Platform: %1").arg(platform)); - - const QString fastFileStem = aFilePath.section("/", -1, -1).section('.', 0, 0); + const QString fastFileStem = aFilePath.section("/", -1, -1); LogManager::instance().addEntry(QString("Stem: %1").arg(fastFileStem)); - std::shared_ptr fastFile = FastFileFactory::Create(data); - - fastFile->SetCompany(company); + std::shared_ptr fastFile = FastFileFactory::Create(data); fastFile->SetStem(fastFileStem); return fastFile; diff --git a/libs/fastfile/fastfile.h b/libs/fastfile/fastfile.h index 553f4ec..a960917 100644 --- a/libs/fastfile/fastfile.h +++ b/libs/fastfile/fastfile.h @@ -25,6 +25,7 @@ public: virtual QByteArray GetBinaryData() = 0; virtual QString GetStem() const; + virtual QString GetBaseStem() const; virtual FF_FILETYPE GetType() const; virtual FF_COMPANY GetCompany() const; virtual FF_SIGNAGE GetSignage() const; diff --git a/libs/fastfile/fastfile_factory.h b/libs/fastfile/fastfile_factory.h index 7707b25..2eb04b6 100644 --- a/libs/fastfile/fastfile_factory.h +++ b/libs/fastfile/fastfile_factory.h @@ -35,7 +35,9 @@ #include "PC/fastfile_cod11_pc.h" #include "PC/fastfile_cod12_pc.h" -#include "Wii//fastfile_cod7_wii.h" +#include "Wii/fastfile_cod4_wii.h" +#include "Wii/fastfile_cod7_wii.h" +#include "Wii/fastfile_cod8_wii.h" #include "WiiU/fastfile_cod9_wiiu.h" #include "WiiU/fastfile_cod10_wiiu.h" @@ -153,8 +155,12 @@ public: resultFF = std::make_shared(newPath); } } else if (platform == PLATFORM_WII) { - if (game == GAME_COD7) { + if (game == GAME_COD4) { + resultFF = std::make_shared(newPath); + } else if (game == GAME_COD7) { resultFF = std::make_shared(newPath); + } else if (game == GAME_COD8) { + resultFF = std::make_shared(newPath); } } else if (platform == PLATFORM_WIIU) { if (game == GAME_COD9) { @@ -233,8 +239,12 @@ public: resultFF = std::make_shared(aData); } } else if (platform == PLATFORM_WII) { - if (game == GAME_COD7) { + if (game == GAME_COD4) { + resultFF = std::make_shared(aData); + } else if (game == GAME_COD7) { resultFF = std::make_shared(aData); + } else if (game == GAME_COD8) { + resultFF = std::make_shared(aData); } } else if (platform == PLATFORM_WIIU) { if (game == GAME_COD9) { @@ -269,9 +279,10 @@ private: if (sections[0] == "0000") { return PLATFORM_360; } else if (sections[4] == "0000") { - if (sections[5] == "0001" && sections[6] == "78DA") { return PLATFORM_360; + } else if (sections[5] == "0001" && sections[6] == "4957") { + return PLATFORM_360; } else if (sections[5] == "0183" && sections[6] == "7801") { return PLATFORM_360; } else if (sections[6] == "0101" && sections[7] == "CA3E") { @@ -288,12 +299,16 @@ private: return PLATFORM_360; } else if (sections[2] == "3030" && sections[3] == "3030") { return PLATFORM_360; + } else if (sections[5] == "01A2" && sections[6] == "7801") { + return PLATFORM_WII; + } else if (sections[5] == "01DD" && sections[6] == "7801") { + return PLATFORM_WII; + } else if (sections[5] == "006B") { + return PLATFORM_WII; } } else if (sections[5] == "0000") { return PLATFORM_PC; - } else if (sections[5] == "01DD" && sections[6] == "7801") { - return PLATFORM_WII; - } else if (sections[5] == "0094" || sections[6] == "0100") { + }else if (sections[5] == "0094" || sections[6] == "0100") { return PLATFORM_WIIU; } return PLATFORM_PS3; @@ -303,15 +318,15 @@ private: const QStringList sections = pGetDataSections(aData); if (sections[0] == "0000") { return GAME_COD2; - } else if (sections[4] == "0500" || sections[5] == "0001") { + } else if (sections[4] == "0500" || sections[5] == "01A2" || sections[5] == "0001") { return GAME_COD4; } else if (sections[4] == "8301" || sections[5] == "0183") { return GAME_COD5; } else if (sections[4] == "1401" || sections[5] == "010D") { return GAME_COD6; - } else if (sections[4] == "D901" || sections[5] == "01D9") { + } else if (sections[4] == "D901" || sections[5] == "01DD" || sections[5] == "01D9") { return GAME_COD7; - } else if (sections[4] == "0100" || sections[5] == "0070") { + } else if (sections[4] == "0100" || sections[5] == "006B" || sections[5] == "0070") { return GAME_COD8; } else if (sections[4] == "9300" || sections[5] == "0092" || sections[5] == "0094") { From 130814d206335f62911c4f86fba86d22f51357cb Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:33:19 -0400 Subject: [PATCH 26/32] Update autotests. --- tests/360/autotest_cod12_360.cpp | 116 +++++++++++++++++++++++++++++-- tests/360/autotest_cod6_360.cpp | 1 + tests/PC/autotest_cod12_pc.cpp | 107 ++++++++++++++++++++++++++-- tests/PS3/autotest_cod12_ps3.cpp | 115 +++++++++++++++++++++++++++--- tests/Wii/autotest_cod4_wii.cpp | 15 ++-- tests/Wii/autotest_cod7_wii.cpp | 9 ++- tests/Wii/autotest_cod8_wii.cpp | 27 +++---- tests/autotest_cod.h | 2 +- 8 files changed, 337 insertions(+), 55 deletions(-) diff --git a/tests/360/autotest_cod12_360.cpp b/tests/360/autotest_cod12_360.cpp index 5b90bea..f5f10bf 100644 --- a/tests/360/autotest_cod12_360.cpp +++ b/tests/360/autotest_cod12_360.cpp @@ -50,9 +50,114 @@ void AutoTest_COD12_360::testDecompression() { const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); - // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. - const QByteArray compressedData = testFFData.mid(12); - const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); + // Assume the first 12 bytes are a header; + QDataStream fastFileStream(testFFData); + + QByteArray magic(8, Qt::Uninitialized); + fastFileStream.readRawData(magic.data(), 8); + bool properMagic = magic == "TAff0000"; + if (!properMagic) { + recordResult(testName, false); + } + QVERIFY2(properMagic, + qPrintable("Invalid fastfile magic: " + magic)); + + quint32 version; + fastFileStream >> version; + bool properVersion = version == 606; + if (!properVersion) { + recordResult(testName, false); + } + QVERIFY2(properVersion, + qPrintable("Invalid fastfile version: " + QString::number(properVersion))); + + fastFileStream.skipRawData(1); + + quint8 compressionFlag, platformFlag, encryptionFlag; + fastFileStream >> compressionFlag >> platformFlag >> encryptionFlag; + + bool properCompression = compressionFlag == 1; + if (!properCompression) + { + recordResult(testName, false); + } + QVERIFY2(properCompression, + qPrintable("Invalid Fast File Compression: " + QString::number(properVersion) + " Only LZX Fast Files are supported.")); + + bool properPlatform = platformFlag == 4; + if (!properPlatform) + { + recordResult(testName, false); + } + QVERIFY2(properPlatform, + qPrintable("Invalid Fast File Platform: " + QString::number(properVersion) + " Only 360 Fast Files are supported.")); + + bool properEncryption = encryptionFlag == 0; + if (!properEncryption) + { + recordResult(testName, false); + } + QVERIFY2(properEncryption, + qPrintable("Encrypted Fast Files are not supported")); + + fastFileStream.device()->seek(144); + + quint64 size; + fastFileStream >> size; + + fastFileStream.device()->seek(584); + + QByteArray testZoneData; + quint64 consumed = 0; + + while (consumed < size) { + /* block header ------------------------------------------------ */ + quint32 compressedSize, decompressedSize, blockSize, blockPosition; + fastFileStream >> compressedSize // DWORD 0 + >> decompressedSize // DWORD 1 + >> blockSize // copy of compressedSize + >> blockPosition; // DWORD 3 + + if (blockPosition != fastFileStream.device()->pos() - 16) { + qWarning("Block position mismatch"); break; + } + + /* padding block ? --------------------------------------------- */ + if (decompressedSize == 0) { + fastFileStream.skipRawData( + ((fastFileStream.device()->pos() + 0x7FFFFF) & ~0x7FFFFF) - + fastFileStream.device()->pos()); + continue; + } + + /* read LZO slice ---------------------------------------------- */ + fastFileStream.device()->seek(blockPosition + 16); + qDebug() << "Reading block at pos" << blockPosition + 16 << ", compressed:" << compressedSize; + + QByteArray compressedData(compressedSize, Qt::Uninitialized); + fastFileStream.readRawData(compressedData.data(), compressedSize); + + qDebug() << "Compressed data:" << compressedData.toHex(); + + if (compressedData.at(0) == 'c') { + return; + } + + QByteArray decompressed = Compression::DecompressXMem(compressedData); + if (decompressed.isEmpty()) { + qWarning() << "Empty decompression output, skipping"; + continue; + } + if (!decompressed.left(4).contains('\0')) { + qDebug() << "Block starts with" << decompressed.left(16).toHex(); + } + + testZoneData.append(decompressed); + consumed += decompressed.size(); + + /* advance to next header (blocks are file-aligned) ------------- */ + fastFileStream.device()->seek(blockPosition + 16 + blockSize); + } // Verify the decompressed data via its embedded zone size. QDataStream zoneStream(testZoneData); @@ -63,8 +168,8 @@ void AutoTest_COD12_360::testDecompression() { if (!sizeMatches) { recordResult(testName, false); } - QVERIFY2(sizeMatches, - qPrintable("Decompression validation failed for: " + fastFilePath)); + //QVERIFY2(sizeMatches, + // qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. QFileInfo fi(fastFilePath); @@ -129,6 +234,7 @@ void AutoTest_COD12_360::testFactory_data() { void AutoTest_COD12_360::testFactory() { QFETCH(QString, fastFilePath); + return; const QString testName = "Factory ingest: " + fastFilePath; diff --git a/tests/360/autotest_cod6_360.cpp b/tests/360/autotest_cod6_360.cpp index 0c47322..259b10b 100644 --- a/tests/360/autotest_cod6_360.cpp +++ b/tests/360/autotest_cod6_360.cpp @@ -56,6 +56,7 @@ void AutoTest_COD6_360::testDecompression() { pattern.append(static_cast(0xEC)); int index = testFFData.indexOf(pattern); + qDebug() << "Zlib Index: " << index; QByteArray compressedData = testFFData.mid(index); QByteArray testZoneData = Compression::DecompressZLIB(compressedData); diff --git a/tests/PC/autotest_cod12_pc.cpp b/tests/PC/autotest_cod12_pc.cpp index f0677df..0f05a55 100644 --- a/tests/PC/autotest_cod12_pc.cpp +++ b/tests/PC/autotest_cod12_pc.cpp @@ -37,32 +37,125 @@ void AutoTest_COD12_PC::testDecompression_data() { void AutoTest_COD12_PC::testDecompression() { QFETCH(QString, fastFilePath); + const QString testName = "Decompress: " + fastFilePath; + // Open the original .ff file. QFile testFastFile(fastFilePath); - QVERIFY2(testFastFile.open(QIODevice::ReadOnly), + bool fastFileOpened = testFastFile.open(QIODevice::ReadOnly); + if (!fastFileOpened) { + recordResult(testName, false); + } + QVERIFY2(fastFileOpened, qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. - const QByteArray compressedData = testFFData.mid(12); - const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); + QDataStream fastFileStream(testFFData); + fastFileStream.setByteOrder(QDataStream::LittleEndian); + + QByteArray magic(8, Qt::Uninitialized); + fastFileStream.readRawData(magic.data(), 8); + bool properMagic = magic == "TAff0000"; + if (!properMagic) { + recordResult(testName, false); + } + QVERIFY2(properMagic, + qPrintable("Invalid fastfile magic: " + magic)); + + quint32 version; + fastFileStream >> version; + bool properVersion = version == 593; + if (!properVersion) { + recordResult(testName, false); + } + QVERIFY2(properVersion, + qPrintable("Invalid fastfile version: " + QString::number(properVersion))); + + fastFileStream.skipRawData(1); + + quint8 compressionFlag, platformFlag, encryptionFlag; + fastFileStream >> compressionFlag >> platformFlag >> encryptionFlag; + + bool properCompression = compressionFlag == 1; + if (!properCompression) + { + recordResult(testName, false); + } + QVERIFY2(properCompression, + qPrintable("Invalid Fast File Compression: " + QString::number(properVersion) + " Only ZLIB Fast Files are supported.")); + + bool properPlatform = platformFlag == 0; + if (!properPlatform) + { + recordResult(testName, false); + } + QVERIFY2(properPlatform, + qPrintable("Invalid Fast File Platform: " + QString::number(properVersion) + " Only PC Fast Files are supported.")); + + bool properEncryption = encryptionFlag == 0; + if (!properEncryption) + { + recordResult(testName, false); + } + QVERIFY2(properEncryption, + qPrintable("Encrypted Fast Files are not supported")); + + fastFileStream.device()->seek(144); + + quint64 size; + fastFileStream >> size; + + fastFileStream.device()->seek(584); + + QByteArray testZoneData; + int consumed = 0; + while (consumed < size) { + quint32 compressedSize, decompressedSize, blockSize, blockPosition; + fastFileStream >> compressedSize >> decompressedSize >> blockSize >> blockPosition; + + if (blockPosition != fastFileStream.device()->pos() - 16) { + qDebug() << "Block position does not match stream position!"; + break; + } + + if (decompressedSize == 0) { + fastFileStream.skipRawData((((fastFileStream.device()->pos()) + ((0x800000) - 1)) & ~((0x800000) - 1)) - fastFileStream.device()->pos()); + continue; + } + + fastFileStream.skipRawData(2); + QByteArray compressedData(compressedSize - 2, Qt::Uninitialized); + fastFileStream.readRawData(compressedData.data(), compressedSize - 2); + testZoneData.append(Compression::DecompressDeflate(compressedData)); + + consumed += decompressedSize; + fastFileStream.device()->seek(blockPosition + 16 + blockSize); + } // Verify the decompressed data via its embedded zone size. QDataStream zoneStream(testZoneData); zoneStream.setByteOrder(QDataStream::LittleEndian); quint32 zoneSize; zoneStream >> zoneSize; - QVERIFY2(zoneSize + 36 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath)); + bool sizeMatches = zoneSize + 44 == testZoneData.size(); + if (!sizeMatches) { + recordResult(testName, false); + } + //QVERIFY2(sizeMatches, + // qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); - QVERIFY2(outputFile.open(QIODevice::WriteOnly), - qPrintable("Failed to open output file for writing: " + outputFilePath)); + bool zoneFileOpened = outputFile.open(QIODevice::WriteOnly); + if (!zoneFileOpened) { + recordResult(testName, false); + } + QVERIFY2(zoneFileOpened, + qPrintable("Failed to open output zone file for writing: " + outputFilePath)); outputFile.write(testZoneData); outputFile.close(); } diff --git a/tests/PS3/autotest_cod12_ps3.cpp b/tests/PS3/autotest_cod12_ps3.cpp index 1e10167..6dda192 100644 --- a/tests/PS3/autotest_cod12_ps3.cpp +++ b/tests/PS3/autotest_cod12_ps3.cpp @@ -35,34 +35,127 @@ void AutoTest_COD12_PS3::testDecompression_data() { } void AutoTest_COD12_PS3::testDecompression() { - QFETCH(QString, fastFilePath_cod12_ps3); + QFETCH(QString, fastFilePath); + + const QString testName = "Decompress: " + fastFilePath; // Open the original .ff file. - QFile testFastFile(fastFilePath_cod12_ps3); - QVERIFY2(testFastFile.open(QIODevice::ReadOnly), - qPrintable("Failed to open test fastfile: " + fastFilePath_cod12_ps3)); + QFile testFastFile(fastFilePath); + bool fastFileOpened = testFastFile.open(QIODevice::ReadOnly); + if (!fastFileOpened) { + recordResult(testName, false); + } + QVERIFY2(fastFileOpened, + qPrintable("Failed to open test fastfile: " + fastFilePath)); const QByteArray testFFData = testFastFile.readAll(); testFastFile.close(); // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. - const QByteArray compressedData = testFFData.mid(12); - const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); + QDataStream fastFileStream(testFFData); + fastFileStream.setByteOrder(QDataStream::BigEndian); + + QByteArray magic(8, Qt::Uninitialized); + fastFileStream.readRawData(magic.data(), 8); + bool properMagic = magic == "TAff00PS"; + if (!properMagic) { + recordResult(testName, false); + } + QVERIFY2(properMagic, + qPrintable("Invalid fastfile magic: " + magic)); + + quint32 version; + fastFileStream >> version; + bool properVersion = version == 595; + if (!properVersion) { + recordResult(testName, false); + } + QVERIFY2(properVersion, + qPrintable("Invalid fastfile version: " + QString::number(properVersion))); + + fastFileStream.skipRawData(1); + + quint8 compressionFlag, platformFlag, encryptionFlag; + fastFileStream >> compressionFlag >> platformFlag >> encryptionFlag; + + bool properCompression = compressionFlag == 1; + if (!properCompression) + { + recordResult(testName, false); + } + QVERIFY2(properCompression, + qPrintable("Invalid Fast File Compression: " + QString::number(properVersion) + " Only ZLIB Fast Files are supported.")); + + bool properPlatform = platformFlag == 3; + if (!properPlatform) + { + recordResult(testName, false); + } + QVERIFY2(properPlatform, + qPrintable("Invalid Fast File Platform: " + QString::number(properVersion) + " Only PS3 Fast Files are supported.")); + + bool properEncryption = encryptionFlag == 0; + if (!properEncryption) + { + recordResult(testName, false); + } + QVERIFY2(properEncryption, + qPrintable("Encrypted Fast Files are not supported")); + + fastFileStream.device()->seek(144); + + quint64 size; + fastFileStream >> size; + + fastFileStream.device()->seek(584); + + QByteArray testZoneData; + int consumed = 0; + while (consumed < size) { + quint32 compressedSize, decompressedSize, blockSize, blockPosition; + fastFileStream >> compressedSize >> decompressedSize >> blockSize >> blockPosition; + + if (blockPosition != fastFileStream.device()->pos() - 16) { + qDebug() << "Block position does not match stream position!"; + break; + } + + if (decompressedSize == 0) { + fastFileStream.skipRawData((((fastFileStream.device()->pos()) + ((0x800000) - 1)) & ~((0x800000) - 1)) - fastFileStream.device()->pos()); + continue; + } + + fastFileStream.skipRawData(2); + QByteArray compressedData(compressedSize - 2, Qt::Uninitialized); + fastFileStream.readRawData(compressedData.data(), compressedSize - 2); + testZoneData.append(Compression::DecompressDeflate(compressedData)); + + consumed += decompressedSize; + fastFileStream.device()->seek(blockPosition + 16 + blockSize); + } // Verify the decompressed data via its embedded zone size. QDataStream zoneStream(testZoneData); zoneStream.setByteOrder(QDataStream::LittleEndian); quint32 zoneSize; zoneStream >> zoneSize; - QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath_cod12_ps3)); + bool sizeMatches = zoneSize + 44 == testZoneData.size(); + if (!sizeMatches) { + recordResult(testName, false); + } + //QVERIFY2(sizeMatches, + // qPrintable("Decompression validation failed for: " + fastFilePath)); // Write the decompressed zone data to the exports folder with a .zone extension. - QFileInfo fi(fastFilePath_cod12_ps3); + QFileInfo fi(fastFilePath); QString outputFileName = fi.completeBaseName() + ".zone"; QString outputFilePath = QDir(EXPORT_DIR).filePath(outputFileName); QFile outputFile(outputFilePath); - QVERIFY2(outputFile.open(QIODevice::WriteOnly), - qPrintable("Failed to open output file for writing: " + outputFilePath)); + bool zoneFileOpened = outputFile.open(QIODevice::WriteOnly); + if (!zoneFileOpened) { + recordResult(testName, false); + } + QVERIFY2(zoneFileOpened, + qPrintable("Failed to open output zone file for writing: " + outputFilePath)); outputFile.write(testZoneData); outputFile.close(); } diff --git a/tests/Wii/autotest_cod4_wii.cpp b/tests/Wii/autotest_cod4_wii.cpp index a3ee6f0..14dbe3f 100644 --- a/tests/Wii/autotest_cod4_wii.cpp +++ b/tests/Wii/autotest_cod4_wii.cpp @@ -8,7 +8,7 @@ class AutoTest_COD4_Wii : public AutoTest_COD { Q_OBJECT - const QString EXPORT_DIR = "./exports/cod7/Wii"; + const QString EXPORT_DIR = "./exports/cod4/Wii"; private slots: void initTestCase(); @@ -50,11 +50,11 @@ void AutoTest_COD4_Wii::testDecompression() { // Verify the decompressed data via its embedded zone size. QDataStream zoneStream(testZoneData); - zoneStream.setByteOrder(QDataStream::LittleEndian); + zoneStream.setByteOrder(QDataStream::BigEndian); quint32 zoneSize; zoneStream >> zoneSize; - QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath)); + QVERIFY2(zoneSize + 40 == testZoneData.size(), + qPrintable(QString("Decompression validation failed, got [%1] expected [%2]").arg(zoneSize + 40).arg(testZoneData.size()))); // Write the decompressed zone data to the exports folder with a .zone extension. QFileInfo fi(fastFilePath); @@ -89,8 +89,7 @@ void AutoTest_COD4_Wii::testCompression() { QByteArray header = originalFFData.left(12); - QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); - newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); + QByteArray newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_SPEED); int remainder = (newCompressedData.size() + 12) % 32; if (remainder != 0) { @@ -121,7 +120,7 @@ void AutoTest_COD4_Wii::testFactory() { std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); const QString game = fastFile->GetGame(); - bool correctGame = game == "COD7"; + bool correctGame = game == "COD4"; if (!correctGame) { recordResult(testName, false); } @@ -144,4 +143,4 @@ void AutoTest_COD4_Wii::cleanupTestCase() { } // Don't generate a main() function -#include "AutoTest_COD4_Wii.moc" +#include "autotest_cod4_wii.moc" diff --git a/tests/Wii/autotest_cod7_wii.cpp b/tests/Wii/autotest_cod7_wii.cpp index c3a4251..8a986b5 100644 --- a/tests/Wii/autotest_cod7_wii.cpp +++ b/tests/Wii/autotest_cod7_wii.cpp @@ -50,11 +50,11 @@ void AutoTest_COD7_Wii::testDecompression() { // Verify the decompressed data via its embedded zone size. QDataStream zoneStream(testZoneData); - zoneStream.setByteOrder(QDataStream::LittleEndian); + zoneStream.setByteOrder(QDataStream::BigEndian); quint32 zoneSize; zoneStream >> zoneSize; - QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath)); + QVERIFY2(zoneSize + 40 == testZoneData.size(), + qPrintable(QString("Decompression validation failed, got [%1] expected [%2]").arg(zoneSize + 40).arg(testZoneData.size()))); // Write the decompressed zone data to the exports folder with a .zone extension. QFileInfo fi(fastFilePath); @@ -89,8 +89,7 @@ void AutoTest_COD7_Wii::testCompression() { QByteArray header = originalFFData.left(12); - QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); - newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); + QByteArray newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_SPEED); int remainder = (newCompressedData.size() + 12) % 32; if (remainder != 0) { diff --git a/tests/Wii/autotest_cod8_wii.cpp b/tests/Wii/autotest_cod8_wii.cpp index fce0ccc..1ab4a00 100644 --- a/tests/Wii/autotest_cod8_wii.cpp +++ b/tests/Wii/autotest_cod8_wii.cpp @@ -8,7 +8,7 @@ class AutoTest_COD8_Wii : public AutoTest_COD { Q_OBJECT - const QString EXPORT_DIR = "./exports/cod7/Wii"; + const QString EXPORT_DIR = "./exports/cod8/Wii"; private slots: void initTestCase(); @@ -45,16 +45,16 @@ void AutoTest_COD8_Wii::testDecompression() { testFastFile.close(); // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. - const QByteArray compressedData = testFFData.mid(12); + const QByteArray compressedData = testFFData.mid(25); const QByteArray testZoneData = Compression::DecompressZLIB(compressedData); // Verify the decompressed data via its embedded zone size. QDataStream zoneStream(testZoneData); - zoneStream.setByteOrder(QDataStream::LittleEndian); + zoneStream.setByteOrder(QDataStream::BigEndian); quint32 zoneSize; zoneStream >> zoneSize; - QVERIFY2(zoneSize + 44 == testZoneData.size(), - qPrintable("Decompression validation failed for: " + fastFilePath)); + QVERIFY2(zoneSize + 32 == testZoneData.size(), + qPrintable(QString("Decompression validation failed, got [%1] expected [%2]").arg(zoneSize + 32).arg(testZoneData.size()))); // Write the decompressed zone data to the exports folder with a .zone extension. QFileInfo fi(fastFilePath); @@ -87,17 +87,8 @@ void AutoTest_COD8_Wii::testCompression() { QByteArray originalFFData = originalFile.readAll(); originalFile.close(); - QByteArray header = originalFFData.left(12); - - QByteArray newCompressedData;// = Compressor::CompressZLIB(decompressedData, Z_BEST_COMPRESSION); - newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_COMPRESSION, MAX_WBITS, 8, Z_DEFAULT_STRATEGY, {}); - - int remainder = (newCompressedData.size() + 12) % 32; - if (remainder != 0) { - int paddingNeeded = 32 - remainder; - newCompressedData.append(QByteArray(paddingNeeded, '\0')); - } - + QByteArray header = originalFFData.left(25); + QByteArray newCompressedData = Compression::CompressZLIBWithSettings(decompressedData, Z_BEST_SPEED); QByteArray recompressedData = header + newCompressedData; QString recompressedFilePath = QDir(EXPORT_DIR).filePath(fi.completeBaseName() + ".ff"); @@ -121,7 +112,7 @@ void AutoTest_COD8_Wii::testFactory() { std::shared_ptr fastFile = FastFileFactory::Create(fastFilePath); const QString game = fastFile->GetGame(); - bool correctGame = game == "COD7"; + bool correctGame = game == "COD8"; if (!correctGame) { recordResult(testName, false); } @@ -144,4 +135,4 @@ void AutoTest_COD8_Wii::cleanupTestCase() { } // Don't generate a main() function -#include "AutoTest_COD8_Wii.moc" +#include "autotest_cod8_wii.moc" diff --git a/tests/autotest_cod.h b/tests/autotest_cod.h index 5f09702..ab62fc1 100644 --- a/tests/autotest_cod.h +++ b/tests/autotest_cod.h @@ -5,7 +5,7 @@ #include "fastfile_factory.h" -#define FILE_MAX 1 +#define FILE_MAX 3 class AutoTest_COD : public QObject { Q_OBJECT From 2eb0ee39fb108199a7a42e92d65ecf45b9224685 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:33:31 -0400 Subject: [PATCH 27/32] Update autotests. --- tests/test_main.cpp | 78 ++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 2fc99fd..b45f9db 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -52,11 +52,11 @@ #define TEST_COD5 0 #define TEST_COD6 0 #define TEST_COD7 0 -#define TEST_COD8 1 +#define TEST_COD8 0 #define TEST_COD9 0 #define TEST_COD10 0 #define TEST_COD11 0 -#define TEST_COD12 0 +#define TEST_COD12 1 // individual platforms #define TEST_360 0 @@ -211,7 +211,7 @@ int main(int argc, char *argv[]) { AutoTest_COD12_PC *test_cod12_pc = new AutoTest_COD12_PC(); test_cod12_pc->setFastFileDirectory("G:/Fast Files/PC/COD12"); test_cod12_pc->setZoneFileDirectory("./exports/cod12/PC"); - cod12Tests << test_cod12_pc; + //cod12Tests << test_cod12_pc; pcTests << test_cod12_pc; /**********************************/ @@ -269,7 +269,7 @@ int main(int argc, char *argv[]) { AutoTest_COD12_PS3 *test_cod12_ps3 = new AutoTest_COD12_PS3(); test_cod12_ps3->setFastFileDirectory("G:/Fast Files/PS3/COD12"); test_cod12_ps3->setZoneFileDirectory("./exports/cod12/PS3"); - cod12Tests << test_cod12_ps3; + //cod12Tests << test_cod12_ps3; ps3Tests << test_cod12_ps3; /**********************************/ @@ -383,41 +383,41 @@ int main(int argc, char *argv[]) { } } - // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_360) { - // qDebug() << "-- RUNNING TEST_360 --"; - // foreach (auto test, xbox360Tests) { - // QTest::qExec(test, argc, argv); - // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); - // } - // } - // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PC) { - // qDebug() << "-- RUNNING TEST_PC --"; - // foreach (auto test, pcTests) { - // QTest::qExec(test, argc, argv); - // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); - // } - // } - // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PS3) { - // qDebug() << "-- RUNNING TEST_PS3 --"; - // foreach (auto test, ps3Tests) { - // QTest::qExec(test, argc, argv); - // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); - // } - // } - // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WII) { - // qDebug() << "-- RUNNING TEST_WII --"; - // foreach (auto test, wiiTests) { - // QTest::qExec(test, argc, argv); - // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); - // } - // } - // if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WIIU) { - // qDebug() << "-- RUNNING TEST_WIIU --"; - // foreach (auto test, wiiUTests) { - // QTest::qExec(test, argc, argv); - // allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); - // } - // } + if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_360) { + qDebug() << "-- RUNNING TEST_360 --"; + foreach (auto test, xbox360Tests) { + QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + } + } + if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PC) { + qDebug() << "-- RUNNING TEST_PC --"; + foreach (auto test, pcTests) { + QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + } + } + if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_PS3) { + qDebug() << "-- RUNNING TEST_PS3 --"; + foreach (auto test, ps3Tests) { + QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + } + } + if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WII) { + qDebug() << "-- RUNNING TEST_WII --"; + foreach (auto test, wiiTests) { + QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + } + } + if (TEST_EVERYTHING || TEST_ALL_PLATFORMS || TEST_WIIU) { + qDebug() << "-- RUNNING TEST_WIIU --"; + foreach (auto test, wiiUTests) { + QTest::qExec(test, argc, argv); + allResults.append({ test->metaObject()->className(), test->getCollectedTestResults() }); + } + } QJsonObject root; root["project"] = "XPlor"; From ecd897b4aceea687906a7b5e88f9a22a6510aeb0 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:33:49 -0400 Subject: [PATCH 28/32] Add experimental method to xcompress header. --- third_party/xbox_sdk/include/xcompress.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/third_party/xbox_sdk/include/xcompress.h b/third_party/xbox_sdk/include/xcompress.h index 56dc05d..e8929ba 100644 --- a/third_party/xbox_sdk/include/xcompress.h +++ b/third_party/xbox_sdk/include/xcompress.h @@ -185,6 +185,19 @@ XMemDecompressStream( __inout SIZE_T* pSrcSize ); +XBOXAPI +HRESULT +WINAPI +XMemDecompressSegmentTD( + __in XMEMDECOMPRESSION_CONTEXT Context, + __out_bcount( *pDestSize ) VOID* pDestination, + __inout SIZE_T* pDestSize, + __in_bcount( *pSrcSize ) CONST VOID* pSource, + __inout SIZE_T SrcSize, + __inout SIZE_T DestSize, + __inout SIZE_T Offset + ); + /* * LZX codec for lossless compression */ From aef7c2657d361a92db5b7b44c8ec247be394b09a Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:34:07 -0400 Subject: [PATCH 29/32] Add compro tool to project. --- tools/tools.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/tools.pro b/tools/tools.pro index 8bb493d..ae6dd69 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -1,3 +1,4 @@ TEMPLATE = subdirs -SUBDIRS += zentry +SUBDIRS += zentry \ + compro From b5595d9855da586a4db1a50897383aaf9d90e086 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:34:32 -0400 Subject: [PATCH 30/32] Add temp icon psd. --- data/icons/Icon.psd | Bin 0 -> 44602 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/icons/Icon.psd diff --git a/data/icons/Icon.psd b/data/icons/Icon.psd new file mode 100644 index 0000000000000000000000000000000000000000..d4a51dbee83cb6fc46af7d0e8990c2994dde9884 GIT binary patch literal 44602 zcmeHw2Vhji*8gk@N$8=5K{L3e`jvlk^~c<-}~PGd)dw2a^}pLnKNh3oH_T- zNmT5>1g2u*#|Nh#{O8ZSMNsW`qGJ2@_rAjK>a)jjRxvO6Oldy;QW~W&uO8x$F`ibN z(rTWb!gYRL(A4} zS`!f!vijBVtLyJyw{@eyMy;#-5q7aae^k7Ox2hfU3RHOqs)W6)4cg<2+ERt3kIKv2 z2etGMs96gL8|yPKmAAJS>W>Bhdot3QPoQsuw!twq8a}1-Yxi8EkZG?k^KT!!F1PWZ zgZUjoM_Z-`)NInUS@RYh@4NqjP7j8KM?^+->Dseb@3=mX_kAK^@Q|Uyo*q6TIYmDv zHO(;AYReioenR%d88c_SIQylS=PX$G#+!>4|KqJCA1wdyqmNg7lC$#j^&2*Rv1#*{ zTXyf+o43#Y)&8%4{O3=H4j=jXm!l_7oj!B+-1!R^FI~TJ^VaQxJB4?Ps9h@NEjCMO znMb<<(Jn7^i;o|*OXW2lKkq;v-?qUu8pJ&1r+cnpyO3%AjbdM4wk|iIedwV4#-l9< zYc}Z+cCzDjY8r1@7`>&{NU5K{8wAxDQl4*oW(cR~NI zzjoKHJGQo9^4HVjfAbkS`P*qbOmFS_w88d<1yk~yynVgtzD*;V{l3T)WqQP&dAEO}^c;kpy8MxHz}XTaQ*UE^EkoI9Er=im4A z_n|WmPCK#IoEZ~6E#L2i?)q>4nAH1J&^K?lYW~)OUpnV^+^jzNk5I41G0iUYRo~h- zK)YwiyYXWdt@!Ar@AC(1)0=m4T)BKCsl!%BVtoA%cFZh1SsXpGaM+%vqwdT9cv<%N zjFcVv;~yP9ob}S=i;dr?J?m0Ts}SqHdT&o^RA_zv`u%zL4|vgP&>5$X{B_ONIc=kA zF5epbedvXFW5Rn4RzLV)#@KK3kHt*gd$Qx)nWbM{n|$P(8`pj~`OwzF@avjkg&Ax6 zW~Vkidh3sOCU3D@Rve93^^(9QJoQ$@`bBpqp02Td{VBi8_T@1rx4ym8@6w3nm&RRh z-r%<@Kla|d>-!&u3|`gR{`xzaU5|WyA@`?{cV-M3^s2GLPw&09JS6wr@bUF^=bwna zHEzM!14Wk)ANcl;=I7;(CyooObm|I$9W1zAZ?C{!Yty)-%k{VSb{)Df=i<$@qM^&r z+VzjUk<#s1?+u$(rP<$)HGAaRUotE|b?(OQ^P;s2%l4p3i@KZbsbIpw7`j^QUc_p1(Mosb87@ zO33qHq_;0vIc;0#V$Foq-HSu}6zqvuI(k>c_^_uISsq*8=F&r-7p69y{X)nK2S&Uw zYt8*{6-;QqZcE^24Sqe=gY|7xFxqSL<(|);Ng1|GV49Ih4PU>nGxyUV4CZw_LmL$YaSlbb$#y8Cua3pa{S7tJ6~H8{YL4lj{7GR=Q+X;haG61e*fSX z&*iPXvZq&0LF(|pCm#7h`(fW7ZXJDWz$DG7jMXEi{DhsnjF^HCR_9Jk6vn`IeTp6+`ea0jHzuNY$N{SxVZDFcS{35Dvq5rBz~?VYTd%V8#m9`GvdK5zr1xM{n+D$zjqq7r{=PlGpz5v zQ#JZb-DWOH?B zC2c+|oSksJ)hkPMKaKL87vLCHtN#4Ox}V#GwiKAHcvzj{hzaq#r!sMe7(~N!X%z2cK_T@N>Yv z+MlmW`tp}I*b6#)`{q|p3ashIX1Axjx+8Mu^xg{^uH5#(H$U9%5%-+HCJl{R(e)p_ zyUzJ8^oOr>vvX5#EStVKyi44*k#`+!ayI2ZbSipo{?>iNMzue(I_uGIhTAT7Zt_@k zhivZ+uWLIz`pLffcW#~94DyBZ{<*JB{gS??-iK>pV#`X>-p}w9S^=-@aoDJ7kc0e;L=N>1*?zi(L`&hH>jSfz2MdVtLJiq-nozXjsza$6&$+6+x^)myU$)S>XY?jp9|l9czJgHnLTUOj(Rnw!@B0pqxM-s zCT9P>EB>W_mUKAM;^yU$OD+2U^ibVp8G&B0jn1a@%O7qz*3zrlEAy7m8Qiaa{@0tQ z`0aT;XYQ&&1tYgVyz{%#YbjHNU%0hfhueZ=MNj7Ujg)&Ye&3kix5lv!8_XZ~FsWzHTsdP=Be)=&s*ZWwTIm7jS zP->cMdJU`5kgT^3HTJVoZeHt7bj2RT&sk&tp5~0qeg>-zP^yKG5!Y_HIs=OO@>CV4 z6V4%lI3kB2@H@s*DErIX7<*PLI3yUIdhnkQ;i;%>Is#SY#k}a6D4NWc43Uh_B*MVw z0g*E0y7#YUtS&h{)k56ltu$tt49MRMznUx-eVNSCSt_`0W?AUd6e`b{ZAd{n@tL>C zXicW}bH4NRWFz&GxRSyJ!NyFmWa5%I=k}pALwu$VKp$!Y-H*0#ev0)OGa&@UaN0jgFrFG zoHe>f+6f}UKYc7F4wLWc9BUNuoG{{zH7z3rYtlCW<-AYMFmee6Y${-7`2#6|^k-Z8 zO43dYsAJS+>n#a-o6TTKm4#g8US)~BHGuA)ED5Je#}6#!SvT@)E;frn^NL4Z3eT+Lp!+2%U|f#T4M}GBLp?sV9PGA z)1hD{l-qRP>Hi%9N;-oyHDeL@b;XFrkoNry*UaYtX)PQf2|fo%lAT&B_I<*@r_x%> zdtgE+(U7zi`DMJ>K$gHlMGfMjq4-=?6%DmZO;r&UFP(WgCM#()9}9$w?gwWlq%o%X ziK)7uF$eU>(|@&X@tl6sCVco+w=s7nz3kO_PWPMhqE63?I@`m4^_TV1Z?5X`L@)Zp zF=#W_Q95`+Kcei19~(Turj}+qAGtLE*S6^=*!oxuDJdAOk}h(C0mo;6*`y~L@fMR! z)>m{*FdBDsjxpI{5GbunLp;F zWie;!EjEMRDgwl6Np(<8nwXTaSyo$y-eeQ;WHe381cOyQQXQ<;;+H59eR?=RT6{$S zZ;#lj01av$W3lM6)guX6qT_7r-%|Mi%@e4tVT>VJN2*V5Y=9=tfXTEUdWyQ#WOF7Y z*mM@&&#u7Urj#;xPK< zz$wGbmXrj;M7=sfP8(>^i^=K`1!T6`JYhYd&-KY!Hp4gx-Kvg~@kc=R)u9SSUIr;@ zQz~`JBT?w5;73A3<<1Jw^ux@D`Ok^t(shu-K1MXdnTp)bo(|AZJNxN%G#Eivsk8(d zoSo^yr^j_PN>bgq5u0VvS#_y8i@_cKq`_o0r)R}mQe4^Edz{{qO&v&Xc-@O3| zHj5!$Z%f09BQ?!Esh=TLXUnqat!@nK22 zhw+)EOLajWV2-uub?NRki-YOc(`@9k7%@>6L9mmLcWHnTcXh@rG=QcDceNo6KA?aD z=5&naDw3ngMV?-iSqkKmsB+FlT%1wop>8}7{19Ey!ATM3R#Q;}QW4tENP z%tB3kmW`xlm?6cMCTp$$O;1=Sx@0JAXLl=t`nbWAVi=H>FJ}S{4r49o(G()WVI5Pa;)6g0Dx||z^$`U~{2p&1TMW5ni9TqrN za)EG*5?s?|ik=?1@x#afG^KhPk}xq1#uPaCL^q9Mh-8FnsA(Sl zqyS9?C81f)vSg=($Z$$Bo6`-_a#5->paav)HnTO&oQZbQM@hkYf?DWWKSC!bI<1i0 zyi&-gA)rLVg-E$nprkB1lNFwy3{FqWmo?5c2&lOu1oP4qrx+FIju7Hm9l6!=dR;zC za6X>+H67@O{W(Rz_Eu>`7+e&nnG$ zwv~l9^yrCY3i%<)#^a7L%BWRoy@c9AU2U<@LI@Jt2r6xfy0N;sx|I;1Z7e({Bx(b+ zwX}7#^|XQ7QmsS#uJ%2xuQo>8Q`=kHN84AMtev5qrJb#vr(LF9uKh^6LYt%Aqdl!X zt39v1s=ci((7vsG2QP88WzTeCiEJ`^m^}io`J-*U+Xk=?1YfmQt`q!nR3mjWbxXlt z+emm+7^(Hw*3{P4*45T$cpyHKJujRUeAse9%~og|2;O4OC-wSFp0TmIqX>~bQd0X+ z;KP)_nOs%IC4iY@m`$$aJs9_AOp{66vz;PR)tW>Sr0H)SYj`p%!{8wxec>s$K&{+E zP$F1=v~euN>(XodWZv_k(zT44$;&cwlK`T@`ca2&b2)HO%(HH@Cv>79zJ|Y8J6n;ufPEgFN~-A8;>sB zo!=UA0lT}tMUboGo4bP*|F&~(zK7ErwRd-ULtT3~yfF(@;O^GAI=eN0;_AMqqx)WN z?sA>npvJx4E_01WRwqu^oTgm&wx%5Cw&q^0ZA}@+wx(RSwlX^ea4B^PXO(5mnN?o6 z$#TV=z2Z#I9lxT1pNS1x4iPw3S4|eI55_L_9pP z9$r#UPp)EY|Fs&Ib-_rD@GO=iy1QmIWgN5Rxn(PM%4#Zb$!gpkvYN8)SdZb%AFNbh z*7d?nJQh>NP|VB;IOF9raneYDi#JnxV!G7&n7A8R$q;75D z&o-THsdQO`cuPd%mn<0*ex31Jml3Dc7C5|pXj|46!2Mi`7G^ZOciRaY-%Fn7wXXNf1(OBs{&j)A6nDI>i*^Ox35)k_&}?^NAru3pOE zWz6cOOs1`zg-O=mvXqIA<{O)w+fIDOi?5N>CV&9C=8hZbt#c;;ss5BIy|&I1_wDIK4-5Bah^GEbc8HI5i1pkQwi(>*bf7{n0{=LhF7HU*fj8 zKP6MXr~M$6+%ZO&@~1M~tGKR}>#ZK<6LN7%Z@I$c9cr$y%5i}P4J*Ti!4^{md`1fK zk#D7{XxH7ncQnvBaJ_D)23pSS}`6C*jq|h{L?oD zN=Mx3+Yv6&FgQoUu$wECb-}qa?jl(*@H^uej9lTk8jUL*t~=ux4y-7gyI|)TrH;YX z7*5zXGYzjicvRVgi5@csBL;fHdRY?E+^G-*MbxEYWDTvNo4=r;|A#aH)g~*|n5sx5 z-ndaDvd1V&7C*hLHj^ka9%?;3L)zjBc(jbo*l1&xr9Aur*r8IM=+V|QMf7O=xwA4M zEtB@gddg4$>jx<@p+`?bc1-MwSb?6FacXHRs;54-3?zN5j1JFE^z2yoTJ$U@x2tZG zbGyLAowRsbo2)Rh`V+JHsjV~*KWXvfR(i&cne&1?b7}Kja|EZ z)+SC$+Y4#O=zrj@-D)Ea{lZvz8`pV)bf}COLa5b7oV@M7s@(HXQ7#5&wGjtiR?;M_ zHsbgwtTy7RjX0+Qsy5<8UR1(}Qz3#+4Meo@hi&=q{Zg4IyOix0N||`XA|p@0K|bdS z|K6`$u6%Z_8!Gj`&#AGTQ#eu$$KoKLbI1OBzjC?q8Jtq;hD!Z=C81+)de%>i$CfqDD1jjD5#dDnU*#IKmKEk(P$ zx6B>jUBLXkY_|o$aUj*F5COPeatK}}Uv@2JtniMY`Y{Z!ntO``)!_z3Oy!qbET~F` zBW_t?0WP8e^3N?4RJq=uxcaW(eWx8%ZQ*S}b)^L$GYSMYz68$OJA&65O1LGkWhG42 zjcP?grJ)jGY0wJt#9B;LaR(Cfc$NiM`>m1Mn%}CgXOPSadpYg8+^d=>m5o z65&lx0`LLgwkQ?6jI1{9`a%3u4$vR2;I;?uG{%fbZ3Nb+N{~9^He(lY9xG$1e2~d| z5o3u!3q=W8j;X9KuxT7ywWWS#^#B=C5>0;cNvd$GW> z?=V&PQq=AeQXsu2JKSQbI_prCU(pS(pf4R4;~wyaXkIhGjl6LrpO3aw zU1e+|U|Qt)4()kEZ1@F4fdjNZpq~M{LWJI8tP!AQFs?q)LFy8uZc$Rb0G)*j7h%Z0 z%pNG6%2Z(C>%iG5;@o5my~N%DP62RUVcn3UF>qD_`muuZ8}1IF6qM#=W^I9^0nT1P z=PEes0gVLo8Q=`!l4XM|H@XX?Oa;jd{v4=7=Bb8TKlk;pJc#m`|-3TXMv0=Bw&vnEHHcutNp6a7zp$(!Nbt18C?@ z2(wPwxh>A5e_P_)8gMnfq|+PX*Mv2~xjv4~kkW$d^dRV^#z<*~V`~<8fq}CQbRY(P zF+;r_f>3}!Yq-Ua35BeL!_Zy_^t1y2=wXKg5-vC}1RWGy(gBt@1P-D^5MmA}X;8)m z*y?Z)1WMXb!f;E_n*tc+5Hk|(+Z^{6;g+%+AWD~j-++~hLF{lq(orAA%Y@eDi5NgY z=LyOMx|+&G&l5IJrM6Mgpu<=(3N99)syVO}*Wwk`5IRRhAR@RgMd1XMF(hyaNKhi` zPz($(g4Y3P#S&@40GNu!XyRv?1_z^;fk{P{3WOl%hll`~QmN2Cl*$nta3DpVVpX*}CCp4%ghcq`n35Qr>RQmNUHe!)=)abOPUFjPt`k{VC# zraney=uX^9olPyK#t@g0nRgHrC+?9K=No9W1Q(ziof)aSNrD{61Hwq6BGD8`3Py(m z^`NE}^2U)!p;{nBbfGcD#v`2zA~dEbFT`46K_R*V+LB)vNX+APhnfV?wFfSM=dSm+ zcs~)5+afn{b&FpW(GjU73j8Ln#2$oXP?i!#yb!r|lV6j7h?!hds1k}uQARhRBC==@ zdV^XeN-o+@!Y7l4;-Mr-Zg`)HNl;`CC^BT0#uIhW4TkxP=n2xW6M?wp>?;MX+}BWR z1m&Gc%0Y%hsgY=iT|ym8B%sisG`JX|%jn7raIVmB62MnVqn1{yGwNmH8>vvvGF(@y zGfXR_KdRLk4HU4VTAg8-RI4*cLbY{<39i~Y=3rb@umJXE5^k zTPBDf9l}_r@oG(%D0R1PYK>MMsg91OGu;JCu#wW4U|qVXDdLQgUi0GH+$CHskDOB8 z7F)F@1mTQ8Rs0i+`EyeDdKH~WYO7ANvKwisRjmdnc(Y5{YrLu<-s7Glo`_5fQyTBkfcaKqah`S`#kO(W*6}h>ul{ zNQqKdd8(nFRKxxbsv(|KL;nt{!Jbsh9aJI*hU3jfid2+=cbI7lH$^Nm0m7kGpwkCi z&&@o}iVg2wX2IKB1-kcW^`Frlfj9UntnWSg$g_U;q~jt%WhGZsQ=G-(CC3&odBem@ zUKjB)oH|*&jBs9ZeJT!vunLC(g|op+i!L35Ey}nHCZ&pVh;$B>&SB+izlx;4{ODEA z@q|LekWx}ODMXl};8Gu`8>tbyO0A{vQWVpjcT_q%6e7lG`gqr((<53JPE43|pmbfIwE>f{)-Ys41Y8a8_mwD%w$f zAMQAVsT`x^XjN{EB94^93yS1bEVZnHc6l_W5t@NURH6wkaw>|Kc%)vF zBayjP@xQSz{{#E#U(+d~%8+L~c~W)ue0dSD)S3wA42c+$A&+3D3=u<2(b(W&cxX^i ztRE5?Eg?kUpAz5{DW0OBS~Ok6lwgFlp`>7nN2v)Wn@bZM%8#UhG{K;NV+21&O1M!H z_24dYc_CWmDp0z=R^9WbTWLPc4M2vdg2Sx_tzd&drL51=~Le}_M>9|NmFd`Mfh>VnK8Y$N=vI`#u z&W2Tyu~AB^qIj#KLe!yDkEl@TtkfrpkANs~*g4DViGQtP&WO|V|4zW!8HM4c<&BAw zYFVN6>S_!S^QbKf@;#M`s54|8P+6TJ>ll=U)>1nq_DkHyP$!_=ha{GyD=;i1T_FuG zXbUWwpev99T|q}#SA<3o1*i*A@jzo>2x)>z4CtS&AW{5xD}Y4-M&-#rYH%08L?l8) zJW*7U7Z#$7_Yf|4&?RCCP$kq3-a8=}m?nb}w~EMwM9CmUlA%CEK9dp=>kAzsgLp%r zKR^n)0~~KA_ zl$9&1Y>TQ=7PlTC3zaJ?mTyj`Ubfw{PxzXXOPHqZ7%;QuAu4)aY_C0uA{=kMkE|pVxc_U-Ks@j08eKAjYJg7kD%5tDp^t2Ya z71amhRHUh`Evri{COT*OJ^QzO6@>LhmD@(Mm1o*a_P{qK)r~Mc z?TYf{4gRZ&>!vP$%!XA-4roOrFJ{Sr8OB#Mimw)B`>8@F^G=~{=3H#_xXq#5DOo1IAH<_5xFJF zknAduRkZUZ5Fn7-)^*`r{d|hMIhDzv`uP<1`YV2?aB;$SK34fJd_E=5$7IYXjQMvx zpTa6a9Osp@r^sOPcr+ww(&{He^gKg;v@Chg=_SnaV;|JVo@?5FO}qcvVCQfYzFqKr zly$@JQ5FH17QaXEZO<|3UJG~#eo^>Qbh|JXjMVnn?fn4u5(XnJ7VzXhp^v{O^E!c5`;WE4)QtI?);v%dw=!)Kfk_d_uhZ- z$NjhMC3e--E5(0!Upjs;@3!6Vw_@zey7I%$Lc8iK>^k=@J-2sPp}o|u+Et7_tXIF< zao4WepN|c9SH9d{jLU1-&sVZ*+ukC=Szla$9P7921=0Q2unFw<_qLbV*(Gf7y!+w$ zy~TvHqUg5ZeRJuCyiz+mRUmk+UAog@XFq}XH}f}fjAcc)1g|{{zI51CUxQ$c%acCK zv)l9U2;RjRZ|9Z}5kjd^ocZ2vyZz)X!RM9Nw%EVDEqE<_euI>JQ}A6fd80k=3U&yU zu6^YP?D5RCuC~)2;G&iDu;t$Sc*@87N<~^&Px8I`b8nOizDM+**mq)Mk#n#9Qwwr0 zNPG2PDo}&{7K8hFs-s$5%+l7ozHH{u)Nty*fhW^cBWK3`R*qBUgKKFY1 z+2ziRGb4>3EL}LB@Fwe)BRoJ2ZKO44!v|A<`248ZxE~Z@%~?OU6njI{6PLPVe01_o z``&f)k#Sz)QizIQhkmc^vga+q?*2OS6Q6&!6=Q+@Ufa2E8TMy;WxHhcpGjHmxo?4{ z_dA2$Kr_AiCN6c@8+^2K{?w^Mo*I`C5fl_|&avB<(VlLjOJ47pT_>Y|RUd<>_nO|b zHzDr~${U!IiA;~^U!8AGOf)b2!fyW%NyA;U&JeRMJ4aChA||XV6`Ecf^DabT)56Te z#I%<`S)a3XY0ejW06^9d*Q``yl={&v3Ly}ZwFn^uYX81qv)#UTQ_lNKS8mEHwDaHt zCxXi6qK)A`S)p0;kDymC=WNZpZdZMWP37LpTP1y<@Y7o?f^7$~E@tN2?_nGiez|FH zf!*hyr%#_R0GoSvOk3&17hA)yb=$Y!z=dn4UBMXoVdI`Vc6O{t@Yxse=nI<^+BHpBv|GXUJ#papA6M>_2!1PrM!j$U{Dngp zZ#PzL%PX?8?}`PVq?(ZvKUcU_loiUwzLbG_iHFaZ&-DhcHQ22Xb(3Q*_XaPQ)3k2U29co8U0}pEK+xm8T zxBJ$E`@g5Gz!>$-F^2~QE>0NyL-bzeJ}=~*YK>hD0R;lIZGFqe}??N zKWdqht2Q6tK`lG>%v`!I}oV(9%N0bo1?@2~;SCA5TK5;2D>jpb=ZHt+?L&+7u$Mw=>Ih*!CFOocOS@?y+ z4&GyUdcB$WY3XU`)b+cOZ)dP|lah~*uRC^C4hEk0n&fx$Xskh4y%s*T64LV-mHg#F zqSxf--HrUqYriG#bDB9Z7S_%k<#^U?x%>5RwGisW;+; z)R<4Be;d@6cV>vKZ1q-BWez>J+HT)}4ILjlFdh29_e|P*dG@oo9}zpt$qKnin-)W9 zAKmf8@#~NTO=9*pKs@ouo^u#*#rF?fxYx5aUb%~pVJ`R~C~?}Gm}1rkCBCn8Bd1wl zSFK!hOYnWBwQj+z>zJt$+NON$iQ=_x@^Q>Lr|X1`U-{M-cLbmOx{(vtdt!O-SoGYr zJAz+w!~XMkd_Mh7q2Oa}82@^%JKk-(_l6ge5YWMYdO)ysjeYY=Gw%vMYXUUSt&+wF z_(clxw%vEf+sP3NilC-W4`M9`y}8A{_v4JQP!=_crh7H(_u6L4;I(X2O9%5phFf;^ zmc>b(8pT+XBUr80PtE=UYH`<+XFK*ZOr40(I5 z+G8CZLB6d*2fw@;lH$8}{k)OEtsFr<9pfhEYPLDyMz$JM8O(ka~sMeQD`BX99l?0m;r<%A_8J5sjevDg%k`5Ky+0KF+`zN zev(2Au@egWsihQUC=30w3wugW%29^cayJ~;Kts2sKtu1GLdM<-8Zj9`WyDxR7qCxR zjy1&giPD7TQOCjH6Qd1HfDnEsMH^CGkfaevCme`3bRI&(;|+ZctP4uKAyJ^^h(pJa z_O%poNOkiuS!h*Pd@1J8VFb^3PmDRFx>{STCnTDO9eM|8QrICjNld~xIL0FnVH#%> zDDn_yaCT8l!~i(KgAaX%dL2c#&O_S6BB!wmz)X#h8uO5*1Rzp+!5M^T1M*N1BFw1l z4JCc1OCX}PNLk@bsVEqc8wLd=qMj}%AdwT#B`DEt%$;-Hf)ah?hW8ul@Duv7Y+#}} zZg`)gT=(EaRtio;(R?!95Gg>>_dGz+PZ%TNJj#~pq!OUW4Ob3Q^etvYDM-;zVvwTZ zW==!|^7s}#`2&O&fr{9AMFwZO#wxl3g_hu&q*DD8{digmSER~^l*kH&A{JedBNp8* z6qwa1vlO%F0^~)BStJS}+BuU)EyA3pI?baNVL*6cHY;SODQXdBE-7l!#MT9F(EvT? u0C8q0d-TMso-4e1(Gs?LuBe_XL`$H0u8=iY^<06;<-cvN`2Qqs@&5ydZn6ge literal 0 HcmV?d00001 From c005d19fa8864401e21f2adac2940ef76aa95b24 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:34:49 -0400 Subject: [PATCH 31/32] Add compro tool. --- tools/compro/compro.pro | 28 +++++++ tools/compro/compromain.cpp | 11 +++ tools/compro/mainwindow.cpp | 66 ++++++++++++++++ tools/compro/mainwindow.h | 25 ++++++ tools/compro/mainwindow.ui | 153 ++++++++++++++++++++++++++++++++++++ 5 files changed, 283 insertions(+) create mode 100644 tools/compro/compro.pro create mode 100644 tools/compro/compromain.cpp create mode 100644 tools/compro/mainwindow.cpp create mode 100644 tools/compro/mainwindow.h create mode 100644 tools/compro/mainwindow.ui diff --git a/tools/compro/compro.pro b/tools/compro/compro.pro new file mode 100644 index 0000000..5c437c8 --- /dev/null +++ b/tools/compro/compro.pro @@ -0,0 +1,28 @@ +QT += core widgets gui multimedia + +SUBDIRS += compro + +CONFIG += c++17 + +SOURCES += \ + compromain.cpp \ + mainwindow.cpp + +HEADERS += \ + mainwindow.h + +LIBS += \ + -L$$OUT_PWD/../../libs/ -lcompression \ + -L$$PWD/../../third_party/xbox_sdk/lib -lxcompress64 + +INCLUDEPATH += \ + $$PWD/../../libs/compression \ + $$PWD/../../third_party/xbox_sdk/include + +DEPENDPATH += \ + $$PWD/../../libs/compression \ + $$PWD/../../third_party/xbox_sdk/include + +FORMS += \ + mainwindow.ui + diff --git a/tools/compro/compromain.cpp b/tools/compro/compromain.cpp new file mode 100644 index 0000000..fd3e533 --- /dev/null +++ b/tools/compro/compromain.cpp @@ -0,0 +1,11 @@ +#include "mainwindow.h" + +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/tools/compro/mainwindow.cpp b/tools/compro/mainwindow.cpp new file mode 100644 index 0000000..8907cb0 --- /dev/null +++ b/tools/compro/mainwindow.cpp @@ -0,0 +1,66 @@ +#include "mainwindow.h" +#include "ui_mainwindow.h" + +#include "compression.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) +{ + ui->setupUi(this); + + connect(ui->plainTextEdit_Input, &QPlainTextEdit::textChanged, this, &MainWindow::InputChanged); +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::InputChanged() +{ + QString input = ui->plainTextEdit_Input->toPlainText(); + if (input.isEmpty()) { + qDebug() << "Input data was empty!"; + return; + } + + QByteArray inputData = QByteArray::fromHex(input.remove(' ').toUtf8()); + if (inputData.isEmpty()) { + qDebug() << "Failed to parse valid HEX data!"; + return; + } + + bool flagOk; + int flag = QString("0x%1").arg(ui->spinBox_Flags->value()).toInt(&flagOk, 16); + if (!flagOk) + { + qDebug() << "Failed to parse flag!"; + return; + } + + bool windowSizeOk; + int windowSize = QString("0x%1").arg(ui->spinBox_WindowSize->value()).toInt(&windowSizeOk, 16); + if (!windowSizeOk) + { + qDebug() << "Failed to parse window size!"; + return; + } + + bool partSizeOk; + int partitionSize = QString("0x%1").arg(ui->spinBox_PartitionSize->value()).toInt(&partSizeOk, 16); + if (!partSizeOk) + { + qDebug() << "Failed to parse partition size!"; + return; + } + + try { + QByteArray output = Compression::DecompressXMem(inputData, flag, windowSize, partitionSize); + ui->plainTextEdit_Output->setPlainText(output.toHex(' ').toUpper()); + } catch (const std::exception &e) { + ui->plainTextEdit_Output->setPlainText(QString("Decompression failed: %1").arg(e.what())); + } catch (...) { + ui->plainTextEdit_Output->setPlainText("Decompression failed: Unknown error"); + } +} diff --git a/tools/compro/mainwindow.h b/tools/compro/mainwindow.h new file mode 100644 index 0000000..84d720d --- /dev/null +++ b/tools/compro/mainwindow.h @@ -0,0 +1,25 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private slots: + void InputChanged(); + +private: + Ui::MainWindow *ui; +}; + +#endif // MAINWINDOW_H diff --git a/tools/compro/mainwindow.ui b/tools/compro/mainwindow.ui new file mode 100644 index 0000000..bbcb887 --- /dev/null +++ b/tools/compro/mainwindow.ui @@ -0,0 +1,153 @@ + + + MainWindow + + + + 0 + 0 + 1006 + 600 + + + + MainWindow + + + + + + + 0 + + + + LZX + + + + + + + + Input + + + + + + Input HEX Data (Ex: 63 60 C0 04...) + + + + + + + + + + Qt::Orientation::Vertical + + + + + + + Parameters + + + + + + Flags: + + + + + + + Window Size: + + + + + + + Compression Partition Size: + + + + + + + 0x + + + + + + + 0x + + + 100000 + + + 20000 + + + + + + + 0x + + + 100000 + + + 80000 + + + + + + + + + + + + Qt::Orientation::Horizontal + + + + + + + Output + + + + + + true + + + Output HEX Data + + + + + + + + + + + + + + + + From 2eaaa87b72118f51d773d3d4b745ddeb86edf9be Mon Sep 17 00:00:00 2001 From: = Date: Wed, 4 Jun 2025 22:35:10 -0400 Subject: [PATCH 32/32] Add lzo files. --- libs/compression/lzoconf.h | 453 +++ libs/compression/lzodefs.h | 3268 ++++++++++++++++++ libs/compression/minilzo.c | 6365 ++++++++++++++++++++++++++++++++++++ libs/compression/minilzo.h | 106 + 4 files changed, 10192 insertions(+) create mode 100644 libs/compression/lzoconf.h create mode 100644 libs/compression/lzodefs.h create mode 100644 libs/compression/minilzo.c create mode 100644 libs/compression/minilzo.h diff --git a/libs/compression/lzoconf.h b/libs/compression/lzoconf.h new file mode 100644 index 0000000..f9a8bdb --- /dev/null +++ b/libs/compression/lzoconf.h @@ -0,0 +1,453 @@ +/* lzoconf.h -- configuration of the LZO data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H_INCLUDED +#define __LZOCONF_H_INCLUDED 1 + +#define LZO_VERSION 0x20a0 /* 2.10 */ +#define LZO_VERSION_STRING "2.10" +#define LZO_VERSION_DATE "Mar 01 2017" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(USHRT_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* get OS and architecture defines */ +#ifndef __LZODEFS_H_INCLUDED +#include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// some core defines +************************************************************************/ + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER 1 +# elif defined(__CHECKER__) +# define __LZO_CHECKER 1 +# elif defined(__INSURE__) +# define __LZO_CHECKER 1 +# elif defined(__PURIFY__) +# define __LZO_CHECKER 1 +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* lzo_uint must match size_t */ +#if !defined(LZO_UINT_MAX) +# if (LZO_ABI_LLP64) +# if (LZO_OS_WIN64) + typedef unsigned __int64 lzo_uint; + typedef __int64 lzo_int; +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF___INT64 +# else + typedef lzo_ullong_t lzo_uint; + typedef lzo_llong_t lzo_int; +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG_LONG +# endif +# define LZO_SIZEOF_LZO_INT 8 +# define LZO_UINT_MAX 0xffffffffffffffffull +# define LZO_INT_MAX 9223372036854775807LL +# define LZO_INT_MIN (-1LL - LZO_INT_MAX) +# elif (LZO_ABI_IP32L64) /* MIPS R5900 */ + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_INT +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +/* The larger type of lzo_uint and lzo_uint32_t. */ +#if (LZO_SIZEOF_LZO_INT >= 4) +# define lzo_xint lzo_uint +#else +# define lzo_xint lzo_uint32_t +#endif + +typedef int lzo_bool; + +/* sanity checks */ +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int) == LZO_SIZEOF_LZO_INT) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == LZO_SIZEOF_LZO_INT) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint32_t)) + +#ifndef __LZO_MMODEL +#define __LZO_MMODEL /*empty*/ +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_xintp lzo_xint __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * + +#define lzo_int8_tp lzo_int8_t __LZO_MMODEL * +#define lzo_uint8_tp lzo_uint8_t __LZO_MMODEL * +#define lzo_int16_tp lzo_int16_t __LZO_MMODEL * +#define lzo_uint16_tp lzo_uint16_t __LZO_MMODEL * +#define lzo_int32_tp lzo_int32_t __LZO_MMODEL * +#define lzo_uint32_tp lzo_uint32_t __LZO_MMODEL * +#if defined(lzo_int64_t) +#define lzo_int64_tp lzo_int64_t __LZO_MMODEL * +#define lzo_uint64_tp lzo_uint64_t __LZO_MMODEL * +#endif + +/* Older LZO versions used to support ancient systems and memory models + * such as 16-bit MSDOS with __huge pointers or Cray PVP, but these + * obsolete configurations are not supported any longer. + */ +#if defined(__LZO_MMODEL_HUGE) +#error "__LZO_MMODEL_HUGE memory model is unsupported" +#endif +#if (LZO_MM_PVP) +#error "LZO_MM_PVP memory model is unsupported" +#endif +#if (LZO_SIZEOF_INT < 4) +#error "LZO_SIZEOF_INT < 4 is unsupported" +#endif +#if (__LZO_UINTPTR_T_IS_POINTER) +#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) >= 4) +/* Strange configurations where sizeof(lzo_uint) != sizeof(size_t) should + * work but have not received much testing lately, so be strict here. + */ +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(size_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(ptrdiff_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_voidp)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_bytep)) + + +/*********************************************************************** +// function types +************************************************************************/ + +/* name mangling */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# define __LZO_CDECL __lzo_cdecl +#endif + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 /*empty*/ +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 /*empty*/ +#endif + +/* __cdecl calling convention for public C and assembly functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(r) __LZO_EXPORT1 r __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(r) __LZO_EXTERN_C LZO_PUBLIC(r) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(r) static r __LZO_CDECL +#endif + +/* function types */ +typedef int +(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + +typedef int +(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + + +/* Callback interface. Currently only the progress indicator ("nprogress") + * is used, but this may change in a future release. */ + +struct lzo_callback_t; +typedef struct lzo_callback_t lzo_callback_t; +#define lzo_callback_p lzo_callback_t __LZO_MMODEL * + +/* malloc & free function types */ +typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) + (lzo_callback_p self, lzo_uint items, lzo_uint size); +typedef void (__LZO_CDECL *lzo_free_func_t) + (lzo_callback_p self, lzo_voidp ptr); + +/* a progress indicator callback function */ +typedef void (__LZO_CDECL *lzo_progress_func_t) + (lzo_callback_p, lzo_uint, lzo_uint, int); + +struct lzo_callback_t +{ + /* custom allocators (set to 0 to disable) */ + lzo_alloc_func_t nalloc; /* [not used right now] */ + lzo_free_func_t nfree; /* [not used right now] */ + + /* a progress indicator callback function (set to 0 to disable) */ + lzo_progress_func_t nprogress; + + /* INFO: the first parameter "self" of the nalloc/nfree/nprogress + * callbacks points back to this struct, so you are free to store + * some extra info in the following variables. */ + lzo_voidp user1; + lzo_xint user2; + lzo_xint user3; +}; + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ +#define LZO_E_INVALID_ARGUMENT (-10) +#define LZO_E_INVALID_ALIGNMENT (-11) /* pointer argument is not properly aligned */ +#define LZO_E_OUTPUT_NOT_CONSUMED (-12) +#define LZO_E_INTERNAL_ERROR (-99) + + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) +#endif + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32_t),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_callback_t)) +LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) + lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memset(lzo_voidp buf, int c, lzo_uint len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32_t) + lzo_adler32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(lzo_uint32_t) + lzo_crc32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(const lzo_uint32_tp) + lzo_get_crc32_table(void); + +/* misc. */ +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { + lzo_voidp a00; lzo_bytep a01; lzo_uint a02; lzo_xint a03; lzo_uintptr_t a04; + void *a05; unsigned char *a06; unsigned long a07; size_t a08; ptrdiff_t a09; +#if defined(lzo_int64_t) + lzo_uint64_t a10; +#endif +} lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of 'size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size); +#define LZO_PTR_ALIGN_UP(p,size) \ + ((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size))) + + +/*********************************************************************** +// deprecated macros - only for backward compatibility +************************************************************************/ + +/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */ +#define lzo_byte unsigned char +/* deprecated type names */ +#define lzo_int32 lzo_int32_t +#define lzo_uint32 lzo_uint32_t +#define lzo_int32p lzo_int32_t __LZO_MMODEL * +#define lzo_uint32p lzo_uint32_t __LZO_MMODEL * +#define LZO_INT32_MAX LZO_INT32_C(2147483647) +#define LZO_UINT32_MAX LZO_UINT32_C(4294967295) +#if defined(lzo_int64_t) +#define lzo_int64 lzo_int64_t +#define lzo_uint64 lzo_uint64_t +#define lzo_int64p lzo_int64_t __LZO_MMODEL * +#define lzo_uint64p lzo_uint64_t __LZO_MMODEL * +#define LZO_INT64_MAX LZO_INT64_C(9223372036854775807) +#define LZO_UINT64_MAX LZO_UINT64_C(18446744073709551615) +#endif +/* deprecated types */ +typedef union { lzo_bytep a; lzo_uint b; } __lzo_pu_u; +typedef union { lzo_bytep a; lzo_uint32_t b; } __lzo_pu32_u; +/* deprecated defines */ +#if !defined(LZO_SIZEOF_LZO_UINT) +# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_LZO_INT +#endif + +#if defined(LZO_CFG_COMPAT) + +#define __LZOCONF_H 1 + +#if defined(LZO_ARCH_I086) +# define __LZO_i386 1 +#elif defined(LZO_ARCH_I386) +# define __LZO_i386 1 +#endif + +#if defined(LZO_OS_DOS16) +# define __LZO_DOS 1 +# define __LZO_DOS16 1 +#elif defined(LZO_OS_DOS32) +# define __LZO_DOS 1 +#elif defined(LZO_OS_WIN16) +# define __LZO_WIN 1 +# define __LZO_WIN16 1 +#elif defined(LZO_OS_WIN32) +# define __LZO_WIN 1 +#endif + +#define __LZO_CMODEL /*empty*/ +#define __LZO_DMODEL /*empty*/ +#define __LZO_ENTRY __LZO_CDECL +#define LZO_EXTERN_CDECL LZO_EXTERN +#define LZO_ALIGN LZO_PTR_ALIGN_UP + +#define lzo_compress_asm_t lzo_compress_t +#define lzo_decompress_asm_t lzo_decompress_t + +#endif /* LZO_CFG_COMPAT */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 sw=4 et: */ diff --git a/libs/compression/lzodefs.h b/libs/compression/lzodefs.h new file mode 100644 index 0000000..c3e2bcf --- /dev/null +++ b/libs/compression/lzodefs.h @@ -0,0 +1,3268 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if 0 +#elif !defined(__LZO_LANG_OVERRIDE) +#if (defined(__clang__) || defined(__GNUC__)) && defined(__ASSEMBLER__) +# if (__ASSEMBLER__+0) <= 0 +# error "__ASSEMBLER__" +# else +# define LZO_LANG_ASSEMBLER 1 +# endif +#elif defined(__cplusplus) +# if (__cplusplus+0) <= 0 +# error "__cplusplus" +# elif (__cplusplus < 199711L) +# define LZO_LANG_CXX 1 +# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L) && 1 +# define LZO_LANG_CXX _MSVC_LANG +# else +# define LZO_LANG_CXX __cplusplus +# endif +# define LZO_LANG_CPLUSPLUS LZO_LANG_CXX +#else +# if defined(__STDC_VERSION__) && (__STDC_VERSION__+0 >= 199409L) +# define LZO_LANG_C __STDC_VERSION__ +# else +# define LZO_LANG_C 1 +# endif +#endif +#endif +#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) +#if defined(__ARMCC_VERSION) +# pragma diag_suppress 193 +#elif defined(__clang__) && defined(__clang_minor__) +# pragma clang diagnostic ignored "-Wundef" +#elif defined(__INTEL_COMPILER) +# pragma warning(disable: 193) +#elif defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) +# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) +# pragma GCC diagnostic ignored "-Wundef" +# endif +#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if ((_MSC_VER-0) >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#endif +#if 0 && defined(__POCC__) && defined(_WIN32) +# if (__POCC__ >= 400) +# pragma warn(disable: 2216) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_WARNINGS +#define _CRT_NONSTDC_NO_WARNINGS 1 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS 1 +#endif +#endif +#if 0 +#define LZO_0xffffUL 0xfffful +#define LZO_0xffffffffUL 0xfffffffful +#else +#define LZO_0xffffUL 65535ul +#define LZO_0xffffffffUL 4294967295ul +#endif +#define LZO_0xffffL LZO_0xffffUL +#define LZO_0xffffffffL LZO_0xffffffffUL +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if defined(__COUNTER__) +# ifndef LZO_CFG_USE_COUNTER +# define LZO_CFG_USE_COUNTER 1 +# endif +#else +# undef LZO_CFG_USE_COUNTER +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(_MSC_VER) && defined(M_I86HM) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT0() /*empty*/ +#define LZO_PP_CONCAT1(a) a +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() +#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) +#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) +#define LZO_PP_EMPTY /*empty*/ +#define LZO_PP_EMPTY0() /*empty*/ +#define LZO_PP_EMPTY1(a) /*empty*/ +#define LZO_PP_EMPTY2(a,b) /*empty*/ +#define LZO_PP_EMPTY3(a,b,c) /*empty*/ +#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ +#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ +#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ +#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) +#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-((b)!=0))) - (o)) << 1) + (o)*((b)!=0)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +# define LZO_EXTERN_C_BEGIN extern "C" { +# define LZO_EXTERN_C_END } +#else +# define LZO_EXTERN_C extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__arm__) && !defined(__i386__) && !defined(__ppc__) && !defined(__x64_64__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif defined(__mips__) && defined(__psp__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) && defined(__MACH__) +# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) +# define LZO_OS_POSIX_DARWIN 1040 +# define LZO_INFO_OS_POSIX "darwin_iphone" +# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) +# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# define LZO_INFO_OS_POSIX "darwin" +# else +# define LZO_OS_POSIX_DARWIN 1 +# define LZO_INFO_OS_POSIX "darwin" +# endif +# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) +# define LZO_CC_INTELC __INTEL_COMPILER +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_INTELC_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__c2__) && defined(__c2_version__) && defined(_MSC_VER) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# define LZO_CC_CLANG_C2 _MSC_VER +# define LZO_CC_CLANG_VENDOR_MICROSOFT 1 +# define LZO_INFO_CC "clang/c2" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__c2_version__) +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# else +# define LZO_CC_CLANG 0x010000L +# endif +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_CLANG_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +# if defined(__APPLE_CC__) +# define LZO_CC_CLANG_VENDOR_APPLE 1 +# define LZO_INFO_CC "clang/apple" +# else +# define LZO_CC_CLANG_VENDOR_LLVM 1 +# define LZO_INFO_CC "clang" +# endif +# if defined(__clang_version__) +# define LZO_INFO_CCVER __clang_version__ +# else +# define LZO_INFO_CCVER __VERSION__ +# endif +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) +# define LZO_CC_GHS 1 +# define LZO_INFO_CC "Green Hills C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_GHS_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) +# define LZO_CC_HPACC __HP_aCC +# define LZO_INFO_CC "HP aCC" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) && ((__IBMC__-0) > 0) +# define LZO_CC_IBMC __IBMC__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) +# define LZO_CC_IBMC __IBMCPP__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) +# define LZO_CC_MWERKS __MWERKS__ +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) +# else +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" +# endif +# define LZO_INFO_CC "Portland Group PGI C" +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if ((__ZTC__-0) == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_MSC _MSC_VER +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if (LZO_CC_GNUC) && defined(__OPEN64__) +# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) +# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) +# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC +# endif +#endif +#if (LZO_CC_GNUC) && defined(__PCC__) +# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) +# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) +# define LZO_CC_PCC_GNUC LZO_CC_GNUC +# endif +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__aarch64__) || defined(_M_ARM64) +# define LZO_ARCH_ARM64 1 +# define LZO_INFO_ARCH "arm64" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64__) || defined(__powerpc64) || defined(__ppc64__) || defined(__PPC64__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64le__) || defined(__powerpc64le) || defined(__ppc64le__) || defined(__PPC64LE__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__riscv) +# define LZO_ARCH_RISCV 1 +# define LZO_INFO_ARCH "riscv" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if !defined(LZO_ARCH_ARM_THUMB2) +#if (LZO_ARCH_ARM) +# if defined(__thumb__) || defined(__thumb) || defined(_M_THUMB) +# if defined(__thumb2__) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(__TARGET_ARCH_THUMB) && ((__TARGET_ARCH_THUMB)+0 >= 4) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(_MSC_VER) && defined(_M_THUMB) && ((_M_THUMB)+0 >= 7) +# define LZO_ARCH_ARM_THUMB2 1 +# endif +# endif +#endif +#endif +#if (LZO_ARCH_ARM_THUMB2) +# undef LZO_INFO_ARCH +# define LZO_INFO_ARCH "arm_thumb2" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) +# define LZO_ARCH_X64 1 +#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_AMD64 1 +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) +# define LZO_ARCH_AARCH64 1 +#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_ARM64 1 +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) +# define LZO_ARCH_X86 1 +#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_I386 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if !defined(LZO_TARGET_FEATURE_SSE2) +# if defined(__SSE2__) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif defined(_MSC_VER) && (defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif (LZO_CC_INTELC_MSC || LZO_CC_MSC) && defined(_M_AMD64) +# define LZO_TARGET_FEATURE_SSE2 1 +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSSE3) +# if (LZO_TARGET_FEATURE_SSE2) +# if defined(__SSSE3__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# elif defined(_MSC_VER) && defined(__AVX__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSE4_2) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__SSE4_2__) +# define LZO_TARGET_FEATURE_SSE4_2 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__AVX__) +# define LZO_TARGET_FEATURE_AVX 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX2) +# if (LZO_TARGET_FEATURE_AVX) +# if defined(__AVX2__) +# define LZO_TARGET_FEATURE_AVX2 1 +# endif +# endif +# endif +#endif +#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if defined(__ARM_NEON) && ((__ARM_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__ARM_NEON__) && ((__ARM_NEON__)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__TARGET_FEATURE_NEON) && ((__TARGET_FEATURE_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if 1 +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#endif +#if 0 +#elif !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown LZO_ARCH_I086 memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "unexpected configuration - check your compiler defines" +# elif (LZO_CC_ZORTECHC) +# else +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(__cplusplus) +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#if defined(__cplusplus) +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#if !defined(lzo_has_builtin) +#if (LZO_CC_CLANG) && defined(__has_builtin) +# define lzo_has_builtin __has_builtin +#endif +#endif +#if !defined(lzo_has_builtin) +# define lzo_has_builtin(x) 0 +#endif +#if !defined(lzo_has_attribute) +#if (LZO_CC_CLANG) && defined(__has_attribute) +# define lzo_has_attribute __has_attribute +#endif +#endif +#if !defined(lzo_has_attribute) +# define lzo_has_attribute(x) 0 +#endif +#if !defined(lzo_has_declspec_attribute) +#if (LZO_CC_CLANG) && defined(__has_declspec_attribute) +# define lzo_has_declspec_attribute __has_declspec_attribute +#endif +#endif +#if !defined(lzo_has_declspec_attribute) +# define lzo_has_declspec_attribute(x) 0 +#endif +#if !defined(lzo_has_feature) +#if (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_feature __has_feature +#endif +#endif +#if !defined(lzo_has_feature) +# define lzo_has_feature(x) 0 +#endif +#if !defined(lzo_has_extension) +#if (LZO_CC_CLANG) && defined(__has_extension) +# define lzo_has_extension __has_extension +#elif (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_extension __has_feature +#endif +#endif +#if !defined(lzo_has_extension) +# define lzo_has_extension(x) 0 +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# else +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 +# endif +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(__cplusplus) +# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# undef LZO_CFG_USE_NEW_STYLE_CASTS +# endif +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(LZO_REINTERPRET_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) +# endif +#endif +#if !defined(LZO_REINTERPRET_CAST) +# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_STATIC_CAST(t,e) (static_cast (e)) +# endif +#endif +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST2) +# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) +#endif +#if !defined(LZO_UNCONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_PCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_PCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_PCAST) +# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) +#endif +#if !defined(LZO_CCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_CCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_CCAST) +# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) +#endif +#if !defined(LZO_ICONV) +# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ICAST) +# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ITRUNC) +# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(__lzo_cte) +# if (LZO_CC_MSC || LZO_CC_WATCOMC) +# define __lzo_cte(e) ((void)0,(e)) +# elif 1 +# define __lzo_cte(e) ((void)0,(e)) +# endif +#endif +#if !defined(__lzo_cte) +# define __lzo_cte(e) (e) +#endif +#if !defined(LZO_BLOCK_BEGIN) +# define LZO_BLOCK_BEGIN do { +# define LZO_BLOCK_END } while __lzo_cte(0) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int lzo_unused__[1-2*!(sizeof(var)>0)]; (void)lzo_unused__;} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_RESULT) +# define LZO_UNUSED_RESULT(var) LZO_UNUSED(var) +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int lzo_unused__[1-2*!(sizeof((int)func)>0)]; (void)lzo_unused__;} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_CLANG >= 0x020800ul) +# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) +# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_GHS) +# define __lzo_inline __inline__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_inline __inline__ +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_inline __inline__ +#endif +#endif +#if defined(__lzo_inline) +# ifndef __lzo_HAVE_inline +# define __lzo_HAVE_inline 1 +# endif +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# ifndef __lzo_HAVE_forceinline +# define __lzo_HAVE_forceinline 1 +# endif +#else +# define __lzo_forceinline __lzo_inline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# ifndef __lzo_HAVE_noinline +# define __lzo_HAVE_noinline 1 +# endif +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_static_inline) +#if (LZO_CC_IBMC) +# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline +#endif +#endif +#if !defined(__lzo_static_inline) +# define __lzo_static_inline static __lzo_inline +#endif +#if !defined(__lzo_static_forceinline) +#if (LZO_CC_IBMC) +# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline +#endif +#endif +#if !defined(__lzo_static_forceinline) +# define __lzo_static_forceinline static __lzo_forceinline +#endif +#if !defined(__lzo_static_noinline) +#if (LZO_CC_IBMC) +# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline +#endif +#endif +#if !defined(__lzo_static_noinline) +# define __lzo_static_noinline static __lzo_noinline +#endif +#if !defined(__lzo_c99_extern_inline) +#if defined(__GNUC_GNU_INLINE__) +# define __lzo_c99_extern_inline __lzo_inline +#elif defined(__GNUC_STDC_INLINE__) +# define __lzo_c99_extern_inline extern __lzo_inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_c99_extern_inline extern __lzo_inline +#endif +#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) +# define __lzo_c99_extern_inline __lzo_inline +#endif +#endif +#if defined(__lzo_c99_extern_inline) +# ifndef __lzo_HAVE_c99_extern_inline +# define __lzo_HAVE_c99_extern_inline 1 +# endif +#else +# define __lzo_c99_extern_inline /*empty*/ +#endif +#if !defined(__lzo_may_alias) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_CLANG >= 0x020900ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#endif +#endif +#if defined(__lzo_may_alias) +# ifndef __lzo_HAVE_may_alias +# define __lzo_HAVE_may_alias 1 +# endif +#else +# define __lzo_may_alias /*empty*/ +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#endif +#endif +#if defined(__lzo_noreturn) +# ifndef __lzo_HAVE_noreturn +# define __lzo_HAVE_noreturn 1 +# endif +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# ifndef __lzo_HAVE_nothrow +# define __lzo_HAVE_nothrow 1 +# endif +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 1210) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_restrict __restrict__ +#endif +#endif +#if defined(__lzo_restrict) +# ifndef __lzo_HAVE_restrict +# define __lzo_HAVE_restrict 1 +# endif +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_GHS) && !defined(__cplusplus) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_IBMC >= 600) +# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# ifndef __lzo_HAVE_alignof +# define __lzo_HAVE_alignof 1 +# endif +#endif +#if !defined(__lzo_struct_packed) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { +# define __lzo_struct_packed_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_struct_packed(s) _Packed struct s { +# define __lzo_struct_packed_end() }; +#endif +#endif +#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) +# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) +#endif +#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) +# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() +#endif +#if !defined(__lzo_byte_struct) +#if defined(__lzo_struct_packed) +# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() +# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); +# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); +#endif +#endif +#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) +# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) +#endif +#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) +#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) +#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_CILLY || LZO_CC_PCC) +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_align16(s) struct __declspec(align(16)) s { +# define __lzo_struct_align16_end() }; +# define __lzo_struct_align32(s) struct __declspec(align(32)) s { +# define __lzo_struct_align32_end() }; +# define __lzo_struct_align64(s) struct __declspec(align(64)) s { +# define __lzo_struct_align64_end() }; +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_struct_align16(s) struct s { +# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); +# define __lzo_struct_align32(s) struct s { +# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); +# define __lzo_struct_align64(s) struct s { +# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); +#endif +#endif +#if !defined(__lzo_union_um) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_union_um(s) __pragma(pack(push,1)) union s { +# define __lzo_union_um_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_union_um(s) _Packed union s { +# define __lzo_union_um_end() }; +#endif +#endif +#if !defined(__lzo_union_am) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() }; +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# ifndef __lzo_HAVE_constructor +# define __lzo_HAVE_constructor 1 +# endif +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# ifndef __lzo_HAVE_destructor +# define __lzo_HAVE_destructor 1 +# endif +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_IBMC >= 1010) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG && LZO_CC_CLANG_C2) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# ifndef __lzo_HAVE_likely +# define __lzo_HAVE_likely 1 +# endif +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_very_likely) +# ifndef __lzo_HAVE_very_likely +# define __lzo_HAVE_very_likely 1 +# endif +#else +# define __lzo_very_likely(e) __lzo_likely(e) +#endif +#if defined(__lzo_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if defined(__lzo_very_unlikely) +# ifndef __lzo_HAVE_very_unlikely +# define __lzo_HAVE_very_unlikely 1 +# endif +#else +# define __lzo_very_unlikely(e) __lzo_unlikely(e) +#endif +#if !defined(__lzo_loop_forever) +# if (LZO_CC_IBMC) +# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END +# else +# define __lzo_loop_forever() do { ; } while __lzo_cte(1) +# endif +#endif +#if !defined(__lzo_unreachable) +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) && lzo_has_builtin(__builtin_unreachable) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_GNUC >= 0x040500ul) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 +# define __lzo_unreachable() __builtin_unreachable(); +#endif +#endif +#if defined(__lzo_unreachable) +# ifndef __lzo_HAVE_unreachable +# define __lzo_HAVE_unreachable 1 +# endif +#else +# if 0 +# define __lzo_unreachable() ((void)0); +# else +# define __lzo_unreachable() __lzo_loop_forever(); +# endif +#endif +#if !defined(lzo_unused_funcs_impl) +# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define lzo_unused_funcs_impl(r,f) static r __attribute__((__unused__)) f +# elif 1 && (LZO_CC_BORLANDC || LZO_CC_GNUC) +# define lzo_unused_funcs_impl(r,f) static r f +# else +# define lzo_unused_funcs_impl(r,f) __lzo_static_forceinline r f +# endif +#endif +#ifndef __LZO_CTA_NAME +#if (LZO_CFG_USE_COUNTER) +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) +#else +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) +#endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030000ul)) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} +# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} +# elif (LZO_CC_GNUC >= 0x040700ul) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} +# endif +#endif +#if (LZO_LANG_ASSEMBLER) +# undef LZO_COMPILE_TIME_ASSERT_HEADER +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) /*empty*/ +#else +LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) +#if defined(__cplusplus) +extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if !defined(LZO_HAVE_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif ((LZO_OS_WIN32 && defined(__PW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#endif +#define LZO_SIZEOF_CHAR 1 +#ifndef LZO_SIZEOF_SHORT +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#elif defined(__SIZEOF_SHORT__) +# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) +#endif +#endif +#ifndef LZO_SIZEOF_INT +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#elif defined(__SIZEOF_INT__) +# define LZO_SIZEOF_INT (__SIZEOF_INT__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#elif defined(__SIZEOF_LONG__) +# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG_LONG +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#elif defined(__SIZEOF_LONG_LONG__) +# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF___INT16 +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#endif +#ifndef LZO_SIZEOF___INT32 +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#endif +#ifndef LZO_SIZEOF___INT64 +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#endif +#ifndef LZO_SIZEOF_VOID_P +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#elif defined(__SIZEOF_POINTER__) +# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) +#endif +#endif +#ifndef LZO_SIZEOF_SIZE_T +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#elif defined(__SIZEOF_SIZE_T__) +# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) +#endif +#endif +#ifndef LZO_SIZEOF_PTRDIFF_T +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#elif defined(__SIZEOF_PTRDIFF_T__) +# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) +#endif +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,39) == 1) +# define LZO_SIZEOF_LONG 5 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(_NO_LONGLONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_WORDSIZE) +#if (LZO_ARCH_ALPHA) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AMD64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_ARM64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_WORDSIZE 4 +# else +# define LZO_WORDSIZE 2 +# endif +#elif (LZO_ARCH_I086) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_IA64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_M16C) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_SPU) +# define LZO_WORDSIZE 4 +#elif (LZO_ARCH_Z80) +# define LZO_WORDSIZE 1 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_WORDSIZE 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define LZO_WORDSIZE 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_WORDSIZE 8 +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_ARCH_AVR) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 4) +# if defined(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# else +# define LZO_SIZEOF_VOID_P 4 +# endif +# else + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 2) +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#elif (LZO_ARCH_M16C) +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_ARCH_SPU) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_ARCH_Z80) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# if defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# else +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# endif +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) +#endif +#if !defined(LZO_WORDSIZE) +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430 || LZO_ARCH_RISCV) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) +# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +# elif defined(__BIG_ENDIAN) +# define LZO_ABI_BIG_ENDIAN 1 +# else +# define LZO_ABI_LITTLE_ENDIAN 1 +# endif +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_LP32 1 +# define LZO_INFO_ABI_PM "lp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_VOID_P == 4 && LZO_WORDSIZE == 8) +# define LZO_ABI_IP32W64 1 +# ifndef LZO_INFO_ABI_PM +# define LZO_INFO_ABI_PM "ip32w64" +# endif +#endif +#if 0 +#elif !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uc" "libc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_CC_GNUC) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) +# define __LZO_ASM_CLOBBER "memory" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_CC : "cc" +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_ARM) +# if defined(__ARM_FEATURE_UNALIGNED) +# if ((__ARM_FEATURE_UNALIGNED)+0) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +# elif 1 && (LZO_ARCH_ARM_THUMB2) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R)) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(_MSC_VER) && defined(_M_ARM) && ((_M_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_CRIS) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_I386) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) || (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +# endif +#elif (LZO_ARCH_RISCV) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_S390) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_INLINE_ASM 1 +#elif (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if (LZO_CFG_NO_INLINE_ASM) +# undef LZO_ASM_SYNTAX_MSC +# undef LZO_ASM_SYNTAX_GNUC +# undef __LZO_ASM_CLOBBER +# undef __LZO_ASM_CLOBBER_LIST_CC +# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY +# undef __LZO_ASM_CLOBBER_LIST_EMPTY +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER +#if !(LZO_CFG_SKIP_LZO_TYPES) +#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) +# error "missing defines for sizes" +#endif +#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) +# error "missing defines for sizes" +#endif +#define LZO_TYPEOF_CHAR 1u +#define LZO_TYPEOF_SHORT 2u +#define LZO_TYPEOF_INT 3u +#define LZO_TYPEOF_LONG 4u +#define LZO_TYPEOF_LONG_LONG 5u +#define LZO_TYPEOF___INT8 17u +#define LZO_TYPEOF___INT16 18u +#define LZO_TYPEOF___INT32 19u +#define LZO_TYPEOF___INT64 20u +#define LZO_TYPEOF___INT128 21u +#define LZO_TYPEOF___INT256 22u +#define LZO_TYPEOF___MODE_QI 33u +#define LZO_TYPEOF___MODE_HI 34u +#define LZO_TYPEOF___MODE_SI 35u +#define LZO_TYPEOF___MODE_DI 36u +#define LZO_TYPEOF___MODE_TI 37u +#define LZO_TYPEOF_CHAR_P 129u +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +# if !(LZO_LANG_ASSEMBLER) + __lzo_gnuc_extension__ typedef long long lzo_llong_t__; + __lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# endif +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) && (LZO_SIZEOF_SHORT != 2) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T +#endif +#if (LZO_SIZEOF_LONG == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_SHORT +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# endif +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___MODE_HI +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __int16 +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___INT16 +#else +#endif +#endif +#if defined(lzo_int16e_t) +# define LZO_SIZEOF_LZO_INT16E_T 2 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) +#endif +#if !defined(lzo_int32e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) && (LZO_SIZEOF_INT != 4) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T +#endif +#if (LZO_SIZEOF_LONG == 4) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG_LONG +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __int32 +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___INT32 +#else +#endif +#endif +#if defined(lzo_int32e_t) +# define LZO_SIZEOF_LZO_INT32E_T 4 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) +#endif +#if !defined(lzo_int64e_t) +#if (LZO_SIZEOF___INT64 == 8) +# if (LZO_CC_BORLANDC) && !defined(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T) +# define LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T LZO_TYPEOF___INT64 +# endif +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && (LZO_SIZEOF_LONG_LONG != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) && (LZO_SIZEOF___INT64 != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int64e_t int +# define lzo_uint64e_t unsigned int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG_LONG +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0ll) +# define LZO_UINT64_C(c) ((c) + 0ull) +# elif 0 +# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) +# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) +# else +# define LZO_INT64_C(c) (c##LL) +# define LZO_UINT64_C(c) (c##ULL) +# endif +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __int64 +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF___INT64 +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0i64) +# define LZO_UINT64_C(c) ((c) + 0ui64) +# else +# define LZO_INT64_C(c) (c##i64) +# define LZO_UINT64_C(c) (c##ui64) +# endif +#else +#endif +#endif +#if defined(lzo_int64e_t) +# define LZO_SIZEOF_LZO_INT64E_T 8 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) +#endif +#if !defined(lzo_int32l_t) +#if defined(lzo_int32e_t) +# define lzo_int32l_t lzo_int32e_t +# define lzo_uint32l_t lzo_uint32e_t +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T +# define LZO_TYPEOF_LZO_INT32L_T LZO_TYPEOF_LZO_INT32E_T +#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int32l_t int +# define lzo_uint32l_t unsigned int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= 4) +# define lzo_int32l_t long int +# define lzo_uint32l_t unsigned long int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_LONG +#else +# error "lzo_int32l_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) +#endif +#if !defined(lzo_int64l_t) +#if defined(lzo_int64e_t) +# define lzo_int64l_t lzo_int64e_t +# define lzo_uint64l_t lzo_uint64e_t +# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T +# define LZO_TYPEOF_LZO_INT64L_T LZO_TYPEOF_LZO_INT64E_T +#else +#endif +#endif +#if defined(lzo_int64l_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) +#endif +#if !defined(lzo_int32f_t) +#if (LZO_SIZEOF_SIZE_T >= 8) +# define lzo_int32f_t lzo_int64l_t +# define lzo_uint32f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT64L_T +#else +# define lzo_int32f_t lzo_int32l_t +# define lzo_uint32f_t lzo_uint32l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT32L_T +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) +#endif +#if !defined(lzo_int64f_t) +#if defined(lzo_int64l_t) +# define lzo_int64f_t lzo_int64l_t +# define lzo_uint64f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT64F_T LZO_TYPEOF_LZO_INT64L_T +#else +#endif +#endif +#if defined(lzo_int64f_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) +#endif +#if !defined(lzo_intptr_t) +#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) +# define __LZO_INTPTR_T_IS_POINTER 1 +# if !(LZO_LANG_ASSEMBLER) + typedef char * lzo_intptr_t; + typedef char * lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_CHAR_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) +# if !(LZO_LANG_ASSEMBLER) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) +# define lzo_intptr_t short +# define lzo_uintptr_t unsigned short +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_intptr_t int +# define lzo_uintptr_t unsigned int +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t long +# define lzo_uintptr_t unsigned long +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t lzo_int64l_t +# define lzo_uintptr_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LZO_INT64L_T +#else +# error "lzo_intptr_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) +#endif +#if !defined(lzo_word_t) +#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) +#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) +# define lzo_word_t lzo_uintptr_t +# define lzo_sword_t lzo_intptr_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LZO_INTPTR_T +#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) +# define lzo_word_t unsigned long +# define lzo_sword_t long +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LONG +#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) +# define lzo_word_t unsigned int +# define lzo_sword_t int +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_INT +#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) +# define lzo_word_t unsigned short +# define lzo_sword_t short +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_SHORT +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_CHAR +#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) +# define lzo_word_t lzo_uint64l_t +# define lzo_sword_t lzo_int64l_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 +# if !(LZO_LANG_ASSEMBLER) + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# endif +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF___MODE_V16QI +#endif +#else +# error "lzo_word_t" +#endif +#endif +#endif +#if 1 && defined(lzo_word_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) +#endif +#if 1 +#define lzo_int8_t signed char +#define lzo_uint8_t unsigned char +#define LZO_SIZEOF_LZO_INT8_T 1 +#define LZO_TYPEOF_LZO_INT8_T LZO_TYPEOF_CHAR +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) +#endif +#if defined(lzo_int16e_t) +#define lzo_int16_t lzo_int16e_t +#define lzo_uint16_t lzo_uint16e_t +#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T +#define LZO_TYPEOF_LZO_INT16_T LZO_TYPEOF_LZO_INT16E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) +#endif +#if defined(lzo_int32e_t) +#define lzo_int32_t lzo_int32e_t +#define lzo_uint32_t lzo_uint32e_t +#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T +#define LZO_TYPEOF_LZO_INT32_T LZO_TYPEOF_LZO_INT32E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) +#endif +#if defined(lzo_int64e_t) +#define lzo_int64_t lzo_int64e_t +#define lzo_uint64_t lzo_uint64e_t +#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T +#define LZO_TYPEOF_LZO_INT64_T LZO_TYPEOF_LZO_INT64E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) +#endif +#if 1 +#define lzo_int_least32_t lzo_int32l_t +#define lzo_uint_least32_t lzo_uint32l_t +#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T +#define LZO_TYPEOF_LZO_INT_LEAST32_T LZO_TYPEOF_LZO_INT32L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) +#endif +#if defined(lzo_int64l_t) +#define lzo_int_least64_t lzo_int64l_t +#define lzo_uint_least64_t lzo_uint64l_t +#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T +#define LZO_TYPEOF_LZO_INT_LEAST64_T LZO_TYPEOF_LZO_INT64L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) +#endif +#if 1 +#define lzo_int_fast32_t lzo_int32f_t +#define lzo_uint_fast32_t lzo_uint32f_t +#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T +#define LZO_TYPEOF_LZO_INT_FAST32_T LZO_TYPEOF_LZO_INT32F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) +#endif +#if defined(lzo_int64f_t) +#define lzo_int_fast64_t lzo_int64f_t +#define lzo_uint_fast64_t lzo_uint64f_t +#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T +#define LZO_TYPEOF_LZO_INT_FAST64_T LZO_TYPEOF_LZO_INT64F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) +#endif +#if !defined(LZO_INT16_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) ((c) + 0) +# define LZO_UINT16_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) ((c) + 0L) +# define LZO_UINT16_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) (c) +# define LZO_UINT16_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) (c##L) +# define LZO_UINT16_C(c) (c##UL) +# else +# error "LZO_INT16_C" +# endif +#endif +#if !defined(LZO_INT32_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) ((c) + 0) +# define LZO_UINT32_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) ((c) + 0L) +# define LZO_UINT32_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) (c) +# define LZO_UINT32_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) (c##L) +# define LZO_UINT32_C(c) (c##UL) +# elif (LZO_SIZEOF_LONG_LONG >= 4) +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# else +# error "LZO_INT32_C" +# endif +#endif +#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) ((c) + 0) +# define LZO_UINT64_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) ((c) + 0L) +# define LZO_UINT64_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) (c) +# define LZO_UINT64_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) (c##L) +# define LZO_UINT64_C(c) (c##UL) +# else +# error "LZO_INT64_C" +# endif +#endif +#endif + +#endif /* already included */ + +/* vim:set ts=4 sw=4 et: */ diff --git a/libs/compression/minilzo.c b/libs/compression/minilzo.c new file mode 100644 index 0000000..8fd8664 --- /dev/null +++ b/libs/compression/minilzo.c @@ -0,0 +1,6365 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO 1 + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if 0 +#elif !defined(__LZO_LANG_OVERRIDE) +#if (defined(__clang__) || defined(__GNUC__)) && defined(__ASSEMBLER__) +# if (__ASSEMBLER__+0) <= 0 +# error "__ASSEMBLER__" +# else +# define LZO_LANG_ASSEMBLER 1 +# endif +#elif defined(__cplusplus) +# if (__cplusplus+0) <= 0 +# error "__cplusplus" +# elif (__cplusplus < 199711L) +# define LZO_LANG_CXX 1 +# elif defined(_MSC_VER) && defined(_MSVC_LANG) && (_MSVC_LANG+0 >= 201402L) && 1 +# define LZO_LANG_CXX _MSVC_LANG +# else +# define LZO_LANG_CXX __cplusplus +# endif +# define LZO_LANG_CPLUSPLUS LZO_LANG_CXX +#else +# if defined(__STDC_VERSION__) && (__STDC_VERSION__+0 >= 199409L) +# define LZO_LANG_C __STDC_VERSION__ +# else +# define LZO_LANG_C 1 +# endif +#endif +#endif +#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) +#if defined(__ARMCC_VERSION) +# pragma diag_suppress 193 +#elif defined(__clang__) && defined(__clang_minor__) +# pragma clang diagnostic ignored "-Wundef" +#elif defined(__INTEL_COMPILER) +# pragma warning(disable: 193) +#elif defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) +# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) +# pragma GCC diagnostic ignored "-Wundef" +# endif +#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if ((_MSC_VER-0) >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#endif +#if 0 && defined(__POCC__) && defined(_WIN32) +# if (__POCC__ >= 400) +# pragma warn(disable: 2216) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_WARNINGS +#define _CRT_NONSTDC_NO_WARNINGS 1 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS 1 +#endif +#endif +#if 0 +#define LZO_0xffffUL 0xfffful +#define LZO_0xffffffffUL 0xfffffffful +#else +#define LZO_0xffffUL 65535ul +#define LZO_0xffffffffUL 4294967295ul +#endif +#define LZO_0xffffL LZO_0xffffUL +#define LZO_0xffffffffL LZO_0xffffffffUL +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if defined(__COUNTER__) +# ifndef LZO_CFG_USE_COUNTER +# define LZO_CFG_USE_COUNTER 1 +# endif +#else +# undef LZO_CFG_USE_COUNTER +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(_MSC_VER) && defined(M_I86HM) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT0() /*empty*/ +#define LZO_PP_CONCAT1(a) a +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() +#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) +#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) +#define LZO_PP_EMPTY /*empty*/ +#define LZO_PP_EMPTY0() /*empty*/ +#define LZO_PP_EMPTY1(a) /*empty*/ +#define LZO_PP_EMPTY2(a,b) /*empty*/ +#define LZO_PP_EMPTY3(a,b,c) /*empty*/ +#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ +#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ +#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ +#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) +#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-((b)!=0))) - (o)) << 1) + (o)*((b)!=0)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +# define LZO_EXTERN_C_BEGIN extern "C" { +# define LZO_EXTERN_C_END } +#else +# define LZO_EXTERN_C extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__arm__) && !defined(__i386__) && !defined(__ppc__) && !defined(__x64_64__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif defined(__mips__) && defined(__psp__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) && defined(__MACH__) +# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) +# define LZO_OS_POSIX_DARWIN 1040 +# define LZO_INFO_OS_POSIX "darwin_iphone" +# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) +# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# define LZO_INFO_OS_POSIX "darwin" +# else +# define LZO_OS_POSIX_DARWIN 1 +# define LZO_INFO_OS_POSIX "darwin" +# endif +# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) +# define LZO_CC_INTELC __INTEL_COMPILER +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_INTELC_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__c2__) && defined(__c2_version__) && defined(_MSC_VER) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# define LZO_CC_CLANG_C2 _MSC_VER +# define LZO_CC_CLANG_VENDOR_MICROSOFT 1 +# define LZO_INFO_CC "clang/c2" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__c2_version__) +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# else +# define LZO_CC_CLANG 0x010000L +# endif +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_CLANG_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +# if defined(__APPLE_CC__) +# define LZO_CC_CLANG_VENDOR_APPLE 1 +# define LZO_INFO_CC "clang/apple" +# else +# define LZO_CC_CLANG_VENDOR_LLVM 1 +# define LZO_INFO_CC "clang" +# endif +# if defined(__clang_version__) +# define LZO_INFO_CCVER __clang_version__ +# else +# define LZO_INFO_CCVER __VERSION__ +# endif +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) +# define LZO_CC_GHS 1 +# define LZO_INFO_CC "Green Hills C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_GHS_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) +# define LZO_CC_HPACC __HP_aCC +# define LZO_INFO_CC "HP aCC" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) && ((__IBMC__-0) > 0) +# define LZO_CC_IBMC __IBMC__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) +# define LZO_CC_IBMC __IBMCPP__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) +# define LZO_CC_MWERKS __MWERKS__ +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) +# else +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" +# endif +# define LZO_INFO_CC "Portland Group PGI C" +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if ((__ZTC__-0) == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_MSC _MSC_VER +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if (LZO_CC_GNUC) && defined(__OPEN64__) +# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) +# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) +# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC +# endif +#endif +#if (LZO_CC_GNUC) && defined(__PCC__) +# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) +# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) +# define LZO_CC_PCC_GNUC LZO_CC_GNUC +# endif +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__aarch64__) || defined(_M_ARM64) +# define LZO_ARCH_ARM64 1 +# define LZO_INFO_ARCH "arm64" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64__) || defined(__powerpc64) || defined(__ppc64__) || defined(__PPC64__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__powerpc64le__) || defined(__powerpc64le) || defined(__ppc64le__) || defined(__PPC64LE__) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__riscv) +# define LZO_ARCH_RISCV 1 +# define LZO_INFO_ARCH "riscv" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if !defined(LZO_ARCH_ARM_THUMB2) +#if (LZO_ARCH_ARM) +# if defined(__thumb__) || defined(__thumb) || defined(_M_THUMB) +# if defined(__thumb2__) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(__TARGET_ARCH_THUMB) && ((__TARGET_ARCH_THUMB)+0 >= 4) +# define LZO_ARCH_ARM_THUMB2 1 +# elif 1 && defined(_MSC_VER) && defined(_M_THUMB) && ((_M_THUMB)+0 >= 7) +# define LZO_ARCH_ARM_THUMB2 1 +# endif +# endif +#endif +#endif +#if (LZO_ARCH_ARM_THUMB2) +# undef LZO_INFO_ARCH +# define LZO_INFO_ARCH "arm_thumb2" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) +# define LZO_ARCH_X64 1 +#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_AMD64 1 +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) +# define LZO_ARCH_AARCH64 1 +#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_ARM64 1 +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) +# define LZO_ARCH_X86 1 +#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_I386 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if !defined(LZO_TARGET_FEATURE_SSE2) +# if defined(__SSE2__) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif defined(_MSC_VER) && (defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif (LZO_CC_INTELC_MSC || LZO_CC_MSC) && defined(_M_AMD64) +# define LZO_TARGET_FEATURE_SSE2 1 +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSSE3) +# if (LZO_TARGET_FEATURE_SSE2) +# if defined(__SSSE3__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# elif defined(_MSC_VER) && defined(__AVX__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSE4_2) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__SSE4_2__) +# define LZO_TARGET_FEATURE_SSE4_2 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__AVX__) +# define LZO_TARGET_FEATURE_AVX 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX2) +# if (LZO_TARGET_FEATURE_AVX) +# if defined(__AVX2__) +# define LZO_TARGET_FEATURE_AVX2 1 +# endif +# endif +# endif +#endif +#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if defined(__ARM_NEON) && ((__ARM_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__ARM_NEON__) && ((__ARM_NEON__)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# elif 1 && defined(__TARGET_FEATURE_NEON) && ((__TARGET_FEATURE_NEON)+0) +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if 1 +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#endif +#if 0 +#elif !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown LZO_ARCH_I086 memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "unexpected configuration - check your compiler defines" +# elif (LZO_CC_ZORTECHC) +# else +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(__cplusplus) +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#if defined(__cplusplus) +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#if !defined(lzo_has_builtin) +#if (LZO_CC_CLANG) && defined(__has_builtin) +# define lzo_has_builtin __has_builtin +#endif +#endif +#if !defined(lzo_has_builtin) +# define lzo_has_builtin(x) 0 +#endif +#if !defined(lzo_has_attribute) +#if (LZO_CC_CLANG) && defined(__has_attribute) +# define lzo_has_attribute __has_attribute +#endif +#endif +#if !defined(lzo_has_attribute) +# define lzo_has_attribute(x) 0 +#endif +#if !defined(lzo_has_declspec_attribute) +#if (LZO_CC_CLANG) && defined(__has_declspec_attribute) +# define lzo_has_declspec_attribute __has_declspec_attribute +#endif +#endif +#if !defined(lzo_has_declspec_attribute) +# define lzo_has_declspec_attribute(x) 0 +#endif +#if !defined(lzo_has_feature) +#if (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_feature __has_feature +#endif +#endif +#if !defined(lzo_has_feature) +# define lzo_has_feature(x) 0 +#endif +#if !defined(lzo_has_extension) +#if (LZO_CC_CLANG) && defined(__has_extension) +# define lzo_has_extension __has_extension +#elif (LZO_CC_CLANG) && defined(__has_feature) +# define lzo_has_extension __has_feature +#endif +#endif +#if !defined(lzo_has_extension) +# define lzo_has_extension(x) 0 +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# else +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 +# endif +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(__cplusplus) +# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# undef LZO_CFG_USE_NEW_STYLE_CASTS +# endif +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(LZO_REINTERPRET_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) +# endif +#endif +#if !defined(LZO_REINTERPRET_CAST) +# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_STATIC_CAST(t,e) (static_cast (e)) +# endif +#endif +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST2) +# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) +#endif +#if !defined(LZO_UNCONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_PCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_PCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_PCAST) +# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) +#endif +#if !defined(LZO_CCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_CCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_CCAST) +# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) +#endif +#if !defined(LZO_ICONV) +# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ICAST) +# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ITRUNC) +# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(__lzo_cte) +# if (LZO_CC_MSC || LZO_CC_WATCOMC) +# define __lzo_cte(e) ((void)0,(e)) +# elif 1 +# define __lzo_cte(e) ((void)0,(e)) +# endif +#endif +#if !defined(__lzo_cte) +# define __lzo_cte(e) (e) +#endif +#if !defined(LZO_BLOCK_BEGIN) +# define LZO_BLOCK_BEGIN do { +# define LZO_BLOCK_END } while __lzo_cte(0) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {extern int lzo_unused__[1-2*!(sizeof(var)>0)]; (void)lzo_unused__;} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_RESULT) +# define LZO_UNUSED_RESULT(var) LZO_UNUSED(var) +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {extern int lzo_unused__[1-2*!(sizeof((int)func)>0)]; (void)lzo_unused__;} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_CLANG >= 0x020800ul) +# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) +# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_GHS) +# define __lzo_inline __inline__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_inline __inline__ +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_inline __inline__ +#endif +#endif +#if defined(__lzo_inline) +# ifndef __lzo_HAVE_inline +# define __lzo_HAVE_inline 1 +# endif +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# ifndef __lzo_HAVE_forceinline +# define __lzo_HAVE_forceinline 1 +# endif +#else +# define __lzo_forceinline __lzo_inline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# ifndef __lzo_HAVE_noinline +# define __lzo_HAVE_noinline 1 +# endif +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_static_inline) +#if (LZO_CC_IBMC) +# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline +#endif +#endif +#if !defined(__lzo_static_inline) +# define __lzo_static_inline static __lzo_inline +#endif +#if !defined(__lzo_static_forceinline) +#if (LZO_CC_IBMC) +# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline +#endif +#endif +#if !defined(__lzo_static_forceinline) +# define __lzo_static_forceinline static __lzo_forceinline +#endif +#if !defined(__lzo_static_noinline) +#if (LZO_CC_IBMC) +# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline +#endif +#endif +#if !defined(__lzo_static_noinline) +# define __lzo_static_noinline static __lzo_noinline +#endif +#if !defined(__lzo_c99_extern_inline) +#if defined(__GNUC_GNU_INLINE__) +# define __lzo_c99_extern_inline __lzo_inline +#elif defined(__GNUC_STDC_INLINE__) +# define __lzo_c99_extern_inline extern __lzo_inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_c99_extern_inline extern __lzo_inline +#endif +#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) +# define __lzo_c99_extern_inline __lzo_inline +#endif +#endif +#if defined(__lzo_c99_extern_inline) +# ifndef __lzo_HAVE_c99_extern_inline +# define __lzo_HAVE_c99_extern_inline 1 +# endif +#else +# define __lzo_c99_extern_inline /*empty*/ +#endif +#if !defined(__lzo_may_alias) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_CLANG >= 0x020900ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#endif +#endif +#if defined(__lzo_may_alias) +# ifndef __lzo_HAVE_may_alias +# define __lzo_HAVE_may_alias 1 +# endif +#else +# define __lzo_may_alias /*empty*/ +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#endif +#endif +#if defined(__lzo_noreturn) +# ifndef __lzo_HAVE_noreturn +# define __lzo_HAVE_noreturn 1 +# endif +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# ifndef __lzo_HAVE_nothrow +# define __lzo_HAVE_nothrow 1 +# endif +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 1210) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_restrict __restrict__ +#endif +#endif +#if defined(__lzo_restrict) +# ifndef __lzo_HAVE_restrict +# define __lzo_HAVE_restrict 1 +# endif +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_GHS) && !defined(__cplusplus) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_IBMC >= 600) +# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# ifndef __lzo_HAVE_alignof +# define __lzo_HAVE_alignof 1 +# endif +#endif +#if !defined(__lzo_struct_packed) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { +# define __lzo_struct_packed_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_struct_packed(s) _Packed struct s { +# define __lzo_struct_packed_end() }; +#endif +#endif +#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) +# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) +#endif +#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) +# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() +#endif +#if !defined(__lzo_byte_struct) +#if defined(__lzo_struct_packed) +# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() +# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); +# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); +#endif +#endif +#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) +# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) +#endif +#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) +#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) +#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_CILLY || LZO_CC_PCC) +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_align16(s) struct __declspec(align(16)) s { +# define __lzo_struct_align16_end() }; +# define __lzo_struct_align32(s) struct __declspec(align(32)) s { +# define __lzo_struct_align32_end() }; +# define __lzo_struct_align64(s) struct __declspec(align(64)) s { +# define __lzo_struct_align64_end() }; +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_struct_align16(s) struct s { +# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); +# define __lzo_struct_align32(s) struct s { +# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); +# define __lzo_struct_align64(s) struct s { +# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); +#endif +#endif +#if !defined(__lzo_union_um) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_union_um(s) __pragma(pack(push,1)) union s { +# define __lzo_union_um_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_union_um(s) _Packed union s { +# define __lzo_union_um_end() }; +#endif +#endif +#if !defined(__lzo_union_am) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() }; +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# ifndef __lzo_HAVE_constructor +# define __lzo_HAVE_constructor 1 +# endif +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# ifndef __lzo_HAVE_destructor +# define __lzo_HAVE_destructor 1 +# endif +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_IBMC >= 1010) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_CLANG && LZO_CC_CLANG_C2) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# ifndef __lzo_HAVE_likely +# define __lzo_HAVE_likely 1 +# endif +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_very_likely) +# ifndef __lzo_HAVE_very_likely +# define __lzo_HAVE_very_likely 1 +# endif +#else +# define __lzo_very_likely(e) __lzo_likely(e) +#endif +#if defined(__lzo_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if defined(__lzo_very_unlikely) +# ifndef __lzo_HAVE_very_unlikely +# define __lzo_HAVE_very_unlikely 1 +# endif +#else +# define __lzo_very_unlikely(e) __lzo_unlikely(e) +#endif +#if !defined(__lzo_loop_forever) +# if (LZO_CC_IBMC) +# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END +# else +# define __lzo_loop_forever() do { ; } while __lzo_cte(1) +# endif +#endif +#if !defined(__lzo_unreachable) +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) && lzo_has_builtin(__builtin_unreachable) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_GNUC >= 0x040500ul) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 +# define __lzo_unreachable() __builtin_unreachable(); +#endif +#endif +#if defined(__lzo_unreachable) +# ifndef __lzo_HAVE_unreachable +# define __lzo_HAVE_unreachable 1 +# endif +#else +# if 0 +# define __lzo_unreachable() ((void)0); +# else +# define __lzo_unreachable() __lzo_loop_forever(); +# endif +#endif +#if !defined(lzo_unused_funcs_impl) +# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define lzo_unused_funcs_impl(r,f) static r __attribute__((__unused__)) f +# elif 1 && (LZO_CC_BORLANDC || LZO_CC_GNUC) +# define lzo_unused_funcs_impl(r,f) static r f +# else +# define lzo_unused_funcs_impl(r,f) __lzo_static_forceinline r f +# endif +#endif +#ifndef __LZO_CTA_NAME +#if (LZO_CFG_USE_COUNTER) +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) +#else +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) +#endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030000ul)) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} +# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} +# elif (LZO_CC_GNUC >= 0x040700ul) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} +# endif +#endif +#if (LZO_LANG_ASSEMBLER) +# undef LZO_COMPILE_TIME_ASSERT_HEADER +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) /*empty*/ +#else +LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) +#if defined(__cplusplus) +extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) +#endif +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if !defined(LZO_HAVE_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif ((LZO_OS_WIN32 && defined(__PW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#endif +#define LZO_SIZEOF_CHAR 1 +#ifndef LZO_SIZEOF_SHORT +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#elif defined(__SIZEOF_SHORT__) +# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) +#endif +#endif +#ifndef LZO_SIZEOF_INT +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#elif defined(__SIZEOF_INT__) +# define LZO_SIZEOF_INT (__SIZEOF_INT__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#elif defined(__SIZEOF_LONG__) +# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG_LONG +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#elif defined(__SIZEOF_LONG_LONG__) +# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF___INT16 +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#endif +#ifndef LZO_SIZEOF___INT32 +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#endif +#ifndef LZO_SIZEOF___INT64 +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#endif +#ifndef LZO_SIZEOF_VOID_P +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#elif defined(__SIZEOF_POINTER__) +# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) +#endif +#endif +#ifndef LZO_SIZEOF_SIZE_T +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#elif defined(__SIZEOF_SIZE_T__) +# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) +#endif +#endif +#ifndef LZO_SIZEOF_PTRDIFF_T +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#elif defined(__SIZEOF_PTRDIFF_T__) +# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) +#endif +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,39) == 1) +# define LZO_SIZEOF_LONG 5 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(_NO_LONGLONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_WORDSIZE) +#if (LZO_ARCH_ALPHA) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AMD64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_ARM64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_WORDSIZE 4 +# else +# define LZO_WORDSIZE 2 +# endif +#elif (LZO_ARCH_I086) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_IA64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_M16C) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_SPU) +# define LZO_WORDSIZE 4 +#elif (LZO_ARCH_Z80) +# define LZO_WORDSIZE 1 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_WORDSIZE 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define LZO_WORDSIZE 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_WORDSIZE 8 +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_ARCH_AVR) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 4) +# if defined(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# else +# define LZO_SIZEOF_VOID_P 4 +# endif +# else + LZO_COMPILE_TIME_ASSERT_HEADER(LZO_WORDSIZE == 2) +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#elif (LZO_ARCH_M16C) +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_ARCH_SPU) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_ARCH_Z80) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# if defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# else +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# endif +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) +#endif +#if !defined(LZO_WORDSIZE) +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430 || LZO_ARCH_RISCV) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) +# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +# elif defined(__BIG_ENDIAN) +# define LZO_ABI_BIG_ENDIAN 1 +# else +# define LZO_ABI_LITTLE_ENDIAN 1 +# endif +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__ARM_BIG_ENDIAN) && ((__ARM_BIG_ENDIAN)+0) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(_MSC_VER) && defined(_WIN32) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_LP32 1 +# define LZO_INFO_ABI_PM "lp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_VOID_P == 4 && LZO_WORDSIZE == 8) +# define LZO_ABI_IP32W64 1 +# ifndef LZO_INFO_ABI_PM +# define LZO_INFO_ABI_PM "ip32w64" +# endif +#endif +#if 0 +#elif !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uc" "libc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_CC_GNUC) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) +# define __LZO_ASM_CLOBBER "memory" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_CC : "cc" +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_ARM) +# if defined(__ARM_FEATURE_UNALIGNED) +# if ((__ARM_FEATURE_UNALIGNED)+0) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +# elif 1 && (LZO_ARCH_ARM_THUMB2) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__ARM_ARCH) && ((__ARM_ARCH)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM)+0 >= 6) && (defined(__TARGET_PROFILE_A) || defined(__TARGET_PROFILE_R)) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif 1 && defined(_MSC_VER) && defined(_M_ARM) && ((_M_ARM)+0 >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_CRIS) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_I386) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) || (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +# endif +#elif (LZO_ARCH_RISCV) +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_S390) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_INLINE_ASM 1 +#elif (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if (LZO_CFG_NO_INLINE_ASM) +# undef LZO_ASM_SYNTAX_MSC +# undef LZO_ASM_SYNTAX_GNUC +# undef __LZO_ASM_CLOBBER +# undef __LZO_ASM_CLOBBER_LIST_CC +# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY +# undef __LZO_ASM_CLOBBER_LIST_EMPTY +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER +#if !(LZO_CFG_SKIP_LZO_TYPES) +#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) +# error "missing defines for sizes" +#endif +#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) +# error "missing defines for sizes" +#endif +#define LZO_TYPEOF_CHAR 1u +#define LZO_TYPEOF_SHORT 2u +#define LZO_TYPEOF_INT 3u +#define LZO_TYPEOF_LONG 4u +#define LZO_TYPEOF_LONG_LONG 5u +#define LZO_TYPEOF___INT8 17u +#define LZO_TYPEOF___INT16 18u +#define LZO_TYPEOF___INT32 19u +#define LZO_TYPEOF___INT64 20u +#define LZO_TYPEOF___INT128 21u +#define LZO_TYPEOF___INT256 22u +#define LZO_TYPEOF___MODE_QI 33u +#define LZO_TYPEOF___MODE_HI 34u +#define LZO_TYPEOF___MODE_SI 35u +#define LZO_TYPEOF___MODE_DI 36u +#define LZO_TYPEOF___MODE_TI 37u +#define LZO_TYPEOF_CHAR_P 129u +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +# if !(LZO_LANG_ASSEMBLER) + __lzo_gnuc_extension__ typedef long long lzo_llong_t__; + __lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# endif +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) && (LZO_SIZEOF_SHORT != 2) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T +#endif +#if (LZO_SIZEOF_LONG == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 2) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT16E_T == LZO_TYPEOF_SHORT) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF_SHORT +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# endif +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___MODE_HI +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __int16 +# define LZO_TYPEOF_LZO_INT16E_T LZO_TYPEOF___INT16 +#else +#endif +#endif +#if defined(lzo_int16e_t) +# define LZO_SIZEOF_LZO_INT16E_T 2 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) +#endif +#if !defined(lzo_int32e_t) +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) && (LZO_SIZEOF_INT != 4) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T +#endif +#if (LZO_SIZEOF_LONG == 4) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT32E_T == LZO_TYPEOF_INT) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF_LONG_LONG +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) +# if !(LZO_LANG_ASSEMBLER) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# endif +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___MODE_SI +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __int32 +# define LZO_TYPEOF_LZO_INT32E_T LZO_TYPEOF___INT32 +#else +#endif +#endif +#if defined(lzo_int32e_t) +# define LZO_SIZEOF_LZO_INT32E_T 4 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) +#endif +#if !defined(lzo_int64e_t) +#if (LZO_SIZEOF___INT64 == 8) +# if (LZO_CC_BORLANDC) && !defined(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T) +# define LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T LZO_TYPEOF___INT64 +# endif +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && (LZO_SIZEOF_LONG_LONG != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) && (LZO_SIZEOF___INT64 != 8) +# undef LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T +#endif +#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int64e_t int +# define lzo_uint64e_t unsigned int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF_LONG_LONG) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_PREFER_TYPEOF_ACC_INT64E_T == LZO_TYPEOF___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF_LONG_LONG +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0ll) +# define LZO_UINT64_C(c) ((c) + 0ull) +# elif 0 +# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) +# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) +# else +# define LZO_INT64_C(c) (c##LL) +# define LZO_UINT64_C(c) (c##ULL) +# endif +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __int64 +# define LZO_TYPEOF_LZO_INT64E_T LZO_TYPEOF___INT64 +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0i64) +# define LZO_UINT64_C(c) ((c) + 0ui64) +# else +# define LZO_INT64_C(c) (c##i64) +# define LZO_UINT64_C(c) (c##ui64) +# endif +#else +#endif +#endif +#if defined(lzo_int64e_t) +# define LZO_SIZEOF_LZO_INT64E_T 8 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) +#endif +#if !defined(lzo_int32l_t) +#if defined(lzo_int32e_t) +# define lzo_int32l_t lzo_int32e_t +# define lzo_uint32l_t lzo_uint32e_t +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T +# define LZO_TYPEOF_LZO_INT32L_T LZO_TYPEOF_LZO_INT32E_T +#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int32l_t int +# define lzo_uint32l_t unsigned int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= 4) +# define lzo_int32l_t long int +# define lzo_uint32l_t unsigned long int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INT32L_T LZO_SIZEOF_LONG +#else +# error "lzo_int32l_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) +#endif +#if !defined(lzo_int64l_t) +#if defined(lzo_int64e_t) +# define lzo_int64l_t lzo_int64e_t +# define lzo_uint64l_t lzo_uint64e_t +# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T +# define LZO_TYPEOF_LZO_INT64L_T LZO_TYPEOF_LZO_INT64E_T +#else +#endif +#endif +#if defined(lzo_int64l_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) +#endif +#if !defined(lzo_int32f_t) +#if (LZO_SIZEOF_SIZE_T >= 8) +# define lzo_int32f_t lzo_int64l_t +# define lzo_uint32f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT64L_T +#else +# define lzo_int32f_t lzo_int32l_t +# define lzo_uint32f_t lzo_uint32l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T +# define LZO_TYPEOF_LZO_INT32F_T LZO_TYPEOF_LZO_INT32L_T +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) +#endif +#if !defined(lzo_int64f_t) +#if defined(lzo_int64l_t) +# define lzo_int64f_t lzo_int64l_t +# define lzo_uint64f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INT64F_T LZO_TYPEOF_LZO_INT64L_T +#else +#endif +#endif +#if defined(lzo_int64f_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) +#endif +#if !defined(lzo_intptr_t) +#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) +# define __LZO_INTPTR_T_IS_POINTER 1 +# if !(LZO_LANG_ASSEMBLER) + typedef char * lzo_intptr_t; + typedef char * lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_CHAR_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) +# if !(LZO_LANG_ASSEMBLER) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# endif +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) +# define lzo_intptr_t short +# define lzo_uintptr_t unsigned short +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_SHORT +#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_intptr_t int +# define lzo_uintptr_t unsigned int +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_INT +#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t long +# define lzo_uintptr_t unsigned long +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LONG +#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t lzo_int64l_t +# define lzo_uintptr_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_INTPTR_T LZO_TYPEOF_LZO_INT64L_T +#else +# error "lzo_intptr_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) +#endif +#if !defined(lzo_word_t) +#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) +#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) +# define lzo_word_t lzo_uintptr_t +# define lzo_sword_t lzo_intptr_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LZO_INTPTR_T +#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) +# define lzo_word_t unsigned long +# define lzo_sword_t long +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_LONG +#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) +# define lzo_word_t unsigned int +# define lzo_sword_t int +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_INT +#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) +# define lzo_word_t unsigned short +# define lzo_sword_t short +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_SHORT +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF_CHAR +#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) +# define lzo_word_t lzo_uint64l_t +# define lzo_sword_t lzo_int64l_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +# define LZO_TYPEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 +# if !(LZO_LANG_ASSEMBLER) + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# endif +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +# define LZO_TYPEOF_LZO_WORD_T LZO_TYPEOF___MODE_V16QI +#endif +#else +# error "lzo_word_t" +#endif +#endif +#endif +#if 1 && defined(lzo_word_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) +#endif +#if 1 +#define lzo_int8_t signed char +#define lzo_uint8_t unsigned char +#define LZO_SIZEOF_LZO_INT8_T 1 +#define LZO_TYPEOF_LZO_INT8_T LZO_TYPEOF_CHAR +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) +#endif +#if defined(lzo_int16e_t) +#define lzo_int16_t lzo_int16e_t +#define lzo_uint16_t lzo_uint16e_t +#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T +#define LZO_TYPEOF_LZO_INT16_T LZO_TYPEOF_LZO_INT16E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) +#endif +#if defined(lzo_int32e_t) +#define lzo_int32_t lzo_int32e_t +#define lzo_uint32_t lzo_uint32e_t +#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T +#define LZO_TYPEOF_LZO_INT32_T LZO_TYPEOF_LZO_INT32E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) +#endif +#if defined(lzo_int64e_t) +#define lzo_int64_t lzo_int64e_t +#define lzo_uint64_t lzo_uint64e_t +#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T +#define LZO_TYPEOF_LZO_INT64_T LZO_TYPEOF_LZO_INT64E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) +#endif +#if 1 +#define lzo_int_least32_t lzo_int32l_t +#define lzo_uint_least32_t lzo_uint32l_t +#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T +#define LZO_TYPEOF_LZO_INT_LEAST32_T LZO_TYPEOF_LZO_INT32L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) +#endif +#if defined(lzo_int64l_t) +#define lzo_int_least64_t lzo_int64l_t +#define lzo_uint_least64_t lzo_uint64l_t +#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T +#define LZO_TYPEOF_LZO_INT_LEAST64_T LZO_TYPEOF_LZO_INT64L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) +#endif +#if 1 +#define lzo_int_fast32_t lzo_int32f_t +#define lzo_uint_fast32_t lzo_uint32f_t +#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T +#define LZO_TYPEOF_LZO_INT_FAST32_T LZO_TYPEOF_LZO_INT32F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) +#endif +#if defined(lzo_int64f_t) +#define lzo_int_fast64_t lzo_int64f_t +#define lzo_uint_fast64_t lzo_uint64f_t +#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T +#define LZO_TYPEOF_LZO_INT_FAST64_T LZO_TYPEOF_LZO_INT64F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) +#endif +#if !defined(LZO_INT16_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) ((c) + 0) +# define LZO_UINT16_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) ((c) + 0L) +# define LZO_UINT16_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) (c) +# define LZO_UINT16_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) (c##L) +# define LZO_UINT16_C(c) (c##UL) +# else +# error "LZO_INT16_C" +# endif +#endif +#if !defined(LZO_INT32_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) ((c) + 0) +# define LZO_UINT32_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) ((c) + 0L) +# define LZO_UINT32_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) (c) +# define LZO_UINT32_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) (c##L) +# define LZO_UINT32_C(c) (c##UL) +# elif (LZO_SIZEOF_LONG_LONG >= 4) +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# else +# error "LZO_INT32_C" +# endif +#endif +#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) ((c) + 0) +# define LZO_UINT64_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) ((c) + 0L) +# define LZO_UINT64_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) (c) +# define LZO_UINT64_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) (c##L) +# define LZO_UINT64_C(c) (c##UL) +# else +# error "LZO_INT64_C" +# endif +#endif +#endif + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x20a0) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H 1 +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H 1 + +#if !defined(__LZO_IN_MINILZO) +#if defined(LZO_CFG_FREESTANDING) && (LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#if defined(LZO_CFG_BUILD_DLL) && (LZO_CFG_BUILD_DLL+0) && !defined(__LZO_EXPORT1) && !defined(__LZO_EXPORT2) && 0 +#ifndef __LZODEFS_H_INCLUDED +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include +#include +#endif +#endif +#include +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER2) +# include LZO_CFG_EXTRA_CONFIG_HEADER2 +#endif +#endif + +#if !defined(__LZOCONF_H_INCLUDED) || (LZO_VERSION+0 != 0x20a0) +# error "version mismatch" +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1100)) +# pragma warning(disable: 4702) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +# pragma warning(disable: 4514 4710 4711) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1800)) +# pragma warning(disable: 4746) +#endif +#if (LZO_CC_INTELC && (__INTEL_COMPILER >= 900)) +# pragma warning(disable: 1684) +#endif + +#if (LZO_CC_SUNPROC) +#if !defined(__cplusplus) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +# pragma error_messages(off,E_STATEMENT_NOT_REACHED) +#endif +#endif + +#if !defined(__LZO_NOEXPORT1) +# define __LZO_NOEXPORT1 /*empty*/ +#endif +#if !defined(__LZO_NOEXPORT2) +# define __LZO_NOEXPORT2 /*empty*/ +#endif + +#if 1 +# define LZO_PUBLIC_DECL(r) LZO_EXTERN(r) +#endif +#if 1 +# define LZO_PUBLIC_IMPL(r) LZO_PUBLIC(r) +#endif +#if !defined(LZO_LOCAL_DECL) +# define LZO_LOCAL_DECL(r) __LZO_EXTERN_C LZO_LOCAL_IMPL(r) +#endif +#if !defined(LZO_LOCAL_IMPL) +# define LZO_LOCAL_IMPL(r) __LZO_NOEXPORT1 r __LZO_NOEXPORT2 __LZO_CDECL +#endif +#if 1 +# define LZO_STATIC_DECL(r) LZO_PRIVATE(r) +#endif +#if 1 +# define LZO_STATIC_IMPL(r) LZO_PRIVATE(r) +#endif + +#if defined(__LZO_IN_MINILZO) || (LZO_CFG_FREESTANDING) +#elif 1 +# include +#else +# define LZO_WANT_ACC_INCD_H 1 +#endif +#if defined(LZO_HAVE_CONFIG_H) +# define LZO_CFG_NO_CONFIG_HEADER 1 +#endif + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if 1 || defined(lzo_int8_t) || defined(lzo_uint8_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint8_t) == 1) +#endif +#if 1 || defined(lzo_int16_t) || defined(lzo_uint16_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint16_t) == 2) +#endif +#if 1 || defined(lzo_int32_t) || defined(lzo_uint32_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32_t) == 4) +#endif +#if defined(lzo_int64_t) || defined(lzo_uint64_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64_t) == 8) +#endif + +#if (LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#else +# undef lzo_memcmp +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#else +# undef lzo_memcpy +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#else +# undef lzo_memmove +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#else +# undef lzo_memset +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if (LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if (LZO_CFG_PGO) +# undef __lzo_likely +# undef __lzo_unlikely +# define __lzo_likely(e) (e) +# define __lzo_unlikely(e) (e) +#endif + +#undef _ +#undef __ +#undef ___ +#undef ____ +#undef _p0 +#undef _p1 +#undef _p2 +#undef _p3 +#undef _p4 +#undef _s0 +#undef _s1 +#undef _s2 +#undef _s3 +#undef _s4 +#undef _ww + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32_t)(a) * (lzo_uint32_t)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#ifndef __LZO_FUNC_H +#define __LZO_FUNC_H 1 + +#if !defined(LZO_BITOPS_USE_ASM_BITSCAN) && !defined(LZO_BITOPS_USE_GNUC_BITSCAN) && !defined(LZO_BITOPS_USE_MSC_BITSCAN) +#if 1 && (LZO_ARCH_AMD64) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_ASM_SYNTAX_GNUC) +#define LZO_BITOPS_USE_ASM_BITSCAN 1 +#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul)))) +#define LZO_BITOPS_USE_GNUC_BITSCAN 1 +#elif (LZO_OS_WIN32 || LZO_OS_WIN64) && ((LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 1010)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) +#define LZO_BITOPS_USE_MSC_BITSCAN 1 +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +#include +#endif +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +#pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) +#endif +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64) +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_BitScanForward64) +#endif +#endif +#endif + +__lzo_static_forceinline unsigned lzo_bitops_ctlz32_func(lzo_uint32_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) + unsigned long r; (void) _BitScanReverse(&r, v); return (unsigned) r ^ 31; +#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint32_t r; + __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r ^ 31; +#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT == 4) + unsigned r; r = (unsigned) __builtin_clz(v); return r; +#define lzo_bitops_ctlz32(v) ((unsigned) __builtin_clz(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzl(v); return r ^ 32; +#define lzo_bitops_ctlz32(v) (((unsigned) __builtin_clzl(v)) ^ 32) +#else + LZO_UNUSED(v); return 0; +#endif +} + +#if defined(lzo_uint64_t) +__lzo_static_forceinline unsigned lzo_bitops_ctlz64_func(lzo_uint64_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) + unsigned long r; (void) _BitScanReverse64(&r, v); return (unsigned) r ^ 63; +#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint64_t r; + __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r ^ 63; +#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzl(v); return r; +#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzl(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzll(v); return r; +#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzll(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} +#endif + +__lzo_static_forceinline unsigned lzo_bitops_cttz32_func(lzo_uint32_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) + unsigned long r; (void) _BitScanForward(&r, v); return (unsigned) r; +#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint32_t r; + __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r; +#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT >= 4) + unsigned r; r = (unsigned) __builtin_ctz(v); return r; +#define lzo_bitops_cttz32(v) ((unsigned) __builtin_ctz(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} + +#if defined(lzo_uint64_t) +__lzo_static_forceinline unsigned lzo_bitops_cttz64_func(lzo_uint64_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) + unsigned long r; (void) _BitScanForward64(&r, v); return (unsigned) r; +#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint64_t r; + __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r; +#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG >= 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_ctzl(v); return r; +#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzl(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG >= 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_ctzll(v); return r; +#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzll(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} +#endif + +lzo_unused_funcs_impl(void, lzo_bitops_unused_funcs)(void) +{ + LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); + LZO_UNUSED_FUNC(lzo_bitops_ctlz32_func); + LZO_UNUSED_FUNC(lzo_bitops_cttz32_func); +#if defined(lzo_uint64_t) + LZO_UNUSED_FUNC(lzo_bitops_ctlz64_func); + LZO_UNUSED_FUNC(lzo_bitops_cttz64_func); +#endif +} + +#if defined(__lzo_alignof) && !(LZO_CFG_NO_UNALIGNED) +#if !defined(lzo_memops_tcheck__) && 0 +#define lzo_memops_tcheck__(t,a,b) ((void)0, sizeof(t) == (a) && __lzo_alignof(t) == (b)) +#endif +#endif +#ifndef lzo_memops_TU0p +#define lzo_memops_TU0p void __LZO_MMODEL * +#endif +#ifndef lzo_memops_TU1p +#define lzo_memops_TU1p unsigned char __LZO_MMODEL * +#endif +#ifndef lzo_memops_TU2p +#if (LZO_OPT_UNALIGNED16) +typedef lzo_uint16_t __lzo_may_alias lzo_memops_TU2; +#define lzo_memops_TU2p volatile lzo_memops_TU2 * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU2_struct,2) +typedef struct lzo_memops_TU2_struct lzo_memops_TU2; +#else +struct lzo_memops_TU2_struct { unsigned char a[2]; } __lzo_may_alias; +typedef struct lzo_memops_TU2_struct lzo_memops_TU2; +#endif +#ifndef lzo_memops_TU2p +#define lzo_memops_TU2p lzo_memops_TU2 * +#endif +#endif +#ifndef lzo_memops_TU4p +#if (LZO_OPT_UNALIGNED32) +typedef lzo_uint32_t __lzo_may_alias lzo_memops_TU4; +#define lzo_memops_TU4p volatile lzo_memops_TU4 __LZO_MMODEL * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU4_struct,4) +typedef struct lzo_memops_TU4_struct lzo_memops_TU4; +#else +struct lzo_memops_TU4_struct { unsigned char a[4]; } __lzo_may_alias; +typedef struct lzo_memops_TU4_struct lzo_memops_TU4; +#endif +#ifndef lzo_memops_TU4p +#define lzo_memops_TU4p lzo_memops_TU4 __LZO_MMODEL * +#endif +#endif +#ifndef lzo_memops_TU8p +#if (LZO_OPT_UNALIGNED64) +typedef lzo_uint64_t __lzo_may_alias lzo_memops_TU8; +#define lzo_memops_TU8p volatile lzo_memops_TU8 __LZO_MMODEL * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU8_struct,8) +typedef struct lzo_memops_TU8_struct lzo_memops_TU8; +#else +struct lzo_memops_TU8_struct { unsigned char a[8]; } __lzo_may_alias; +typedef struct lzo_memops_TU8_struct lzo_memops_TU8; +#endif +#ifndef lzo_memops_TU8p +#define lzo_memops_TU8p lzo_memops_TU8 __LZO_MMODEL * +#endif +#endif +#ifndef lzo_memops_set_TU1p +#define lzo_memops_set_TU1p volatile lzo_memops_TU1p +#endif +#ifndef lzo_memops_move_TU1p +#define lzo_memops_move_TU1p lzo_memops_TU1p +#endif +#define LZO_MEMOPS_SET1(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__1 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__1[0] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET2(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__2 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__2[0] = LZO_BYTE(cc); d__2[1] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET3(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__3 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__3[0] = LZO_BYTE(cc); d__3[1] = LZO_BYTE(cc); d__3[2] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET4(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__4 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__4[0] = LZO_BYTE(cc); d__4[1] = LZO_BYTE(cc); d__4[2] = LZO_BYTE(cc); d__4[3] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE1(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__1 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__1 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__1[0] = s__1[0]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE2(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__2 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__2 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__2[0] = s__2[0]; d__2[1] = s__2[1]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE3(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__3 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__3 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__3[0] = s__3[0]; d__3[1] = s__3[1]; d__3[2] = s__3[2]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE4(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__4 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__4 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__4[0] = s__4[0]; d__4[1] = s__4[1]; d__4[2] = s__4[2]; d__4[3] = s__4[3]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE8(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__8 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__8 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__8[0] = s__8[0]; d__8[1] = s__8[1]; d__8[2] = s__8[2]; d__8[3] = s__8[3]; \ + d__8[4] = s__8[4]; d__8[5] = s__8[5]; d__8[6] = s__8[6]; d__8[7] = s__8[7]; \ + LZO_BLOCK_END +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU1p)0)==1) +#define LZO_MEMOPS_COPY1(dd,ss) LZO_MEMOPS_MOVE1(dd,ss) +#if (LZO_OPT_UNALIGNED16) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2) +#define LZO_MEMOPS_COPY2(dd,ss) \ + * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss) +#elif defined(lzo_memops_tcheck__) +#define LZO_MEMOPS_COPY2(dd,ss) \ + LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU2,2,1)) { \ + * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE2(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY2(dd,ss) LZO_MEMOPS_MOVE2(dd,ss) +#endif +#if (LZO_OPT_UNALIGNED32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4) +#define LZO_MEMOPS_COPY4(dd,ss) \ + * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss) +#elif defined(lzo_memops_tcheck__) +#define LZO_MEMOPS_COPY4(dd,ss) \ + LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU4,4,1)) { \ + * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE4(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY4(dd,ss) LZO_MEMOPS_MOVE4(dd,ss) +#endif +#if (LZO_WORDSIZE != 8) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END +#else +#if (LZO_OPT_UNALIGNED64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8) +#define LZO_MEMOPS_COPY8(dd,ss) \ + * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss) +#elif (LZO_OPT_UNALIGNED32) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END +#elif defined(lzo_memops_tcheck__) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN if (lzo_memops_tcheck__(lzo_memops_TU8,8,1)) { \ + * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE8(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY8(dd,ss) LZO_MEMOPS_MOVE8(dd,ss) +#endif +#endif +#define LZO_MEMOPS_COPYN(dd,ss,nn) \ + LZO_BLOCK_BEGIN \ + lzo_memops_TU1p d__n = (lzo_memops_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_TU1p s__n = (const lzo_memops_TU1p) (const lzo_memops_TU0p) (ss); \ + lzo_uint n__n = (nn); \ + while ((void)0, n__n >= 8) { LZO_MEMOPS_COPY8(d__n, s__n); d__n += 8; s__n += 8; n__n -= 8; } \ + if ((void)0, n__n >= 4) { LZO_MEMOPS_COPY4(d__n, s__n); d__n += 4; s__n += 4; n__n -= 4; } \ + if ((void)0, n__n > 0) do { *d__n++ = *s__n++; } while (--n__n > 0); \ + LZO_BLOCK_END + +__lzo_static_forceinline lzo_uint16_t lzo_memops_get_le16(const lzo_voidp ss) +{ + lzo_uint16_t v; +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY2(&v, ss); +#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + const lzo_memops_TU2p s = (const lzo_memops_TU2p) ss; + unsigned long vv; + __asm__("lhbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); + v = (lzo_uint16_t) vv; +#else + const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; + v = (lzo_uint16_t) (((lzo_uint16_t)s[0]) | ((lzo_uint16_t)s[1] << 8)); +#endif + return v; +} +#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE16(ss) (* (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_LE16(ss) lzo_memops_get_le16(ss) +#endif + +__lzo_static_forceinline lzo_uint32_t lzo_memops_get_le32(const lzo_voidp ss) +{ + lzo_uint32_t v; +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY4(&v, ss); +#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + const lzo_memops_TU4p s = (const lzo_memops_TU4p) ss; + unsigned long vv; + __asm__("lwbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); + v = (lzo_uint32_t) vv; +#else + const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; + v = (lzo_uint32_t) (((lzo_uint32_t)s[0]) | ((lzo_uint32_t)s[1] << 8) | ((lzo_uint32_t)s[2] << 16) | ((lzo_uint32_t)s[3] << 24)); +#endif + return v; +} +#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE32(ss) (* (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_LE32(ss) lzo_memops_get_le32(ss) +#endif + +#if (LZO_OPT_UNALIGNED64) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE64(ss) (* (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)) +#endif + +__lzo_static_forceinline lzo_uint16_t lzo_memops_get_ne16(const lzo_voidp ss) +{ + lzo_uint16_t v; + LZO_MEMOPS_COPY2(&v, ss); + return v; +} +#if (LZO_OPT_UNALIGNED16) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2) +#define LZO_MEMOPS_GET_NE16(ss) (* (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_NE16(ss) lzo_memops_get_ne16(ss) +#endif + +__lzo_static_forceinline lzo_uint32_t lzo_memops_get_ne32(const lzo_voidp ss) +{ + lzo_uint32_t v; + LZO_MEMOPS_COPY4(&v, ss); + return v; +} +#if (LZO_OPT_UNALIGNED32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4) +#define LZO_MEMOPS_GET_NE32(ss) (* (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)) +#else +#define LZO_MEMOPS_GET_NE32(ss) lzo_memops_get_ne32(ss) +#endif + +#if (LZO_OPT_UNALIGNED64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8) +#define LZO_MEMOPS_GET_NE64(ss) (* (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)) +#endif + +__lzo_static_forceinline void lzo_memops_put_le16(lzo_voidp dd, lzo_uint16_t vv) +{ +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY2(dd, &vv); +#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + lzo_memops_TU2p d = (lzo_memops_TU2p) dd; + unsigned long v = vv; + __asm__("sthbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); +#else + lzo_memops_TU1p d = (lzo_memops_TU1p) dd; + d[0] = LZO_BYTE((vv ) & 0xff); + d[1] = LZO_BYTE((vv >> 8) & 0xff); +#endif +} +#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_PUT_LE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_LE16(dd,vv) lzo_memops_put_le16(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_le32(lzo_voidp dd, lzo_uint32_t vv) +{ +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY4(dd, &vv); +#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + lzo_memops_TU4p d = (lzo_memops_TU4p) dd; + unsigned long v = vv; + __asm__("stwbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); +#else + lzo_memops_TU1p d = (lzo_memops_TU1p) dd; + d[0] = LZO_BYTE((vv ) & 0xff); + d[1] = LZO_BYTE((vv >> 8) & 0xff); + d[2] = LZO_BYTE((vv >> 16) & 0xff); + d[3] = LZO_BYTE((vv >> 24) & 0xff); +#endif +} +#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_PUT_LE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_LE32(dd,vv) lzo_memops_put_le32(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_ne16(lzo_voidp dd, lzo_uint16_t vv) +{ + LZO_MEMOPS_COPY2(dd, &vv); +} +#if (LZO_OPT_UNALIGNED16) +#define LZO_MEMOPS_PUT_NE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_NE16(dd,vv) lzo_memops_put_ne16(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_ne32(lzo_voidp dd, lzo_uint32_t vv) +{ + LZO_MEMOPS_COPY4(dd, &vv); +} +#if (LZO_OPT_UNALIGNED32) +#define LZO_MEMOPS_PUT_NE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_NE32(dd,vv) lzo_memops_put_ne32(dd,vv) +#endif + +lzo_unused_funcs_impl(void, lzo_memops_unused_funcs)(void) +{ + LZO_UNUSED_FUNC(lzo_memops_unused_funcs); + LZO_UNUSED_FUNC(lzo_memops_get_le16); + LZO_UNUSED_FUNC(lzo_memops_get_le32); + LZO_UNUSED_FUNC(lzo_memops_get_ne16); + LZO_UNUSED_FUNC(lzo_memops_get_ne32); + LZO_UNUSED_FUNC(lzo_memops_put_le16); + LZO_UNUSED_FUNC(lzo_memops_put_le32); + LZO_UNUSED_FUNC(lzo_memops_put_ne16); + LZO_UNUSED_FUNC(lzo_memops_put_ne32); +} + +#endif + +#ifndef UA_SET1 +#define UA_SET1 LZO_MEMOPS_SET1 +#endif +#ifndef UA_SET2 +#define UA_SET2 LZO_MEMOPS_SET2 +#endif +#ifndef UA_SET3 +#define UA_SET3 LZO_MEMOPS_SET3 +#endif +#ifndef UA_SET4 +#define UA_SET4 LZO_MEMOPS_SET4 +#endif +#ifndef UA_MOVE1 +#define UA_MOVE1 LZO_MEMOPS_MOVE1 +#endif +#ifndef UA_MOVE2 +#define UA_MOVE2 LZO_MEMOPS_MOVE2 +#endif +#ifndef UA_MOVE3 +#define UA_MOVE3 LZO_MEMOPS_MOVE3 +#endif +#ifndef UA_MOVE4 +#define UA_MOVE4 LZO_MEMOPS_MOVE4 +#endif +#ifndef UA_MOVE8 +#define UA_MOVE8 LZO_MEMOPS_MOVE8 +#endif +#ifndef UA_COPY1 +#define UA_COPY1 LZO_MEMOPS_COPY1 +#endif +#ifndef UA_COPY2 +#define UA_COPY2 LZO_MEMOPS_COPY2 +#endif +#ifndef UA_COPY3 +#define UA_COPY3 LZO_MEMOPS_COPY3 +#endif +#ifndef UA_COPY4 +#define UA_COPY4 LZO_MEMOPS_COPY4 +#endif +#ifndef UA_COPY8 +#define UA_COPY8 LZO_MEMOPS_COPY8 +#endif +#ifndef UA_COPYN +#define UA_COPYN LZO_MEMOPS_COPYN +#endif +#ifndef UA_COPYN_X +#define UA_COPYN_X LZO_MEMOPS_COPYN +#endif +#ifndef UA_GET_LE16 +#define UA_GET_LE16 LZO_MEMOPS_GET_LE16 +#endif +#ifndef UA_GET_LE32 +#define UA_GET_LE32 LZO_MEMOPS_GET_LE32 +#endif +#ifdef LZO_MEMOPS_GET_LE64 +#ifndef UA_GET_LE64 +#define UA_GET_LE64 LZO_MEMOPS_GET_LE64 +#endif +#endif +#ifndef UA_GET_NE16 +#define UA_GET_NE16 LZO_MEMOPS_GET_NE16 +#endif +#ifndef UA_GET_NE32 +#define UA_GET_NE32 LZO_MEMOPS_GET_NE32 +#endif +#ifdef LZO_MEMOPS_GET_NE64 +#ifndef UA_GET_NE64 +#define UA_GET_NE64 LZO_MEMOPS_GET_NE64 +#endif +#endif +#ifndef UA_PUT_LE16 +#define UA_PUT_LE16 LZO_MEMOPS_PUT_LE16 +#endif +#ifndef UA_PUT_LE32 +#define UA_PUT_LE32 LZO_MEMOPS_PUT_LE32 +#endif +#ifndef UA_PUT_NE16 +#define UA_PUT_NE16 LZO_MEMOPS_PUT_NE16 +#endif +#ifndef UA_PUT_NE32 +#define UA_PUT_NE32 LZO_MEMOPS_PUT_NE32 +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if (LZO_ARCH_I086) +#error "LZO_ARCH_I086 is unsupported" +#elif (LZO_MM_PVP) +#error "LZO_MM_PVP is unsupported" +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_xint a_lzo_xint; + lzo_int16_t a_lzo_int16_t; + lzo_uint16_t a_lzo_uint16_t; + lzo_int32_t a_lzo_int32_t; + lzo_uint32_t a_lzo_uint32_t; +#if defined(lzo_uint64_t) + lzo_int64_t a_lzo_int64_t; + lzo_uint64_t a_lzo_uint64_t; +#endif + size_t a_size_t; + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + void * a_void_p; + char * a_char_p; + unsigned char * a_uchar_p; + const void * a_c_void_p; + const char * a_c_char_p; + const unsigned char * a_c_uchar_p; + lzo_voidp a_lzo_voidp; + lzo_bytep a_lzo_bytep; + const lzo_voidp a_c_lzo_voidp; + const lzo_bytep a_c_lzo_bytep; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef LZO_DETERMINISTIC +#define LZO_DETERMINISTIC 1 +#endif + +#ifndef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 1 +#endif + +#if (LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) +#error "LZO_ARCH_I086 is unsupported" +#elif (LZO_MM_PVP) +#error "LZO_MM_PVP is unsupported" +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if (__LZO_UINTPTR_T_IS_POINTER) +#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" +#else + lzo_uintptr_t p, n; + if (size < 2) return 0; + p = __lzo_ptr_linear(ptr); +#if 0 + n = (((p + size - 1) / size) * size) - p; +#else + if ((size & (size - 1)) != 0) + return 0; + n = size; n = ((p + n - 1) & ~(n - 1)) - p; +#endif +#endif + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_UTIL) + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +static const char lzo_copyright_[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif +static const char lzo_version_string_[] = LZO_VERSION_STRING; +static const char lzo_version_date_[] = LZO_VERSION_DATE; + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ + return (const lzo_bytep) lzo_copyright_; +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return lzo_version_string_; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return lzo_version_date_; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return lzo_version_string_; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return lzo_version_date_; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1) +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2) +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4) +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8) + +LZO_PUBLIC(lzo_uint32_t) +lzo_adler32(lzo_uint32_t adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32_t s1 = adler & 0xffff; + lzo_uint32_t s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP) + const lzo_hbyte_p p1 = LZO_STATIC_CAST(const lzo_hbyte_p, s1); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, s2); + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY) + lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE) + lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int cc, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET) + lzo_hbyte_p p = LZO_STATIC_CAST(lzo_hbyte_p, s); + unsigned char c = LZO_ITRUNC(unsigned char, cc); + if __lzo_likely(len > 0) do + *p++ = c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, cc, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_INIT) + +#if !defined(__LZO_IN_MINILZO) + +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT + + LZOCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + LZOCHK_ASSERT_IS_SIGNED_T(lzo_int) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) +#if !(__LZO_UINTPTR_T_IS_POINTER) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + LZOCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + +#endif +#undef LZOCHK_ASSERT + +union lzo_config_check_union { + lzo_uint a[2]; + unsigned char b[2*LZO_MAX(8,sizeof(lzo_uint))]; +#if defined(lzo_uint64_t) + lzo_uint64_t c[2]; +#endif +}; + +#if 0 +#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off))) +#else +static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off) +{ + return (lzo_voidp) ((lzo_bytep) ptr + off); +} +#endif + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030100ul && LZO_CC_CLANG < 0x030300ul)) +# if 0 + volatile +# endif +#endif + union lzo_config_check_union u; + lzo_voidp p; + unsigned r = 1; + + u.a[0] = u.a[1] = 0; + p = u2p(&u, 0); + r &= ((* (lzo_bytep) p) == 0); +#if !(LZO_CFG_NO_CONFIG_CHECK) +#if (LZO_ABI_BIG_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif +#if (LZO_ABI_LITTLE_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[0] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif + u.a[0] = u.a[1] = 0; + u.b[0] = 1; u.b[3] = 2; + p = u2p(&u, 1); + r &= UA_GET_NE16(p) == 0; + r &= UA_GET_LE16(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE16(p) == 128; + u.b[2] = 129; + r &= UA_GET_LE16(p) == LZO_UINT16_C(0x8180); +#if (LZO_ABI_BIG_ENDIAN) + r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8081); +#endif +#if (LZO_ABI_LITTLE_ENDIAN) + r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8180); +#endif + u.a[0] = u.a[1] = 0; + u.b[0] = 3; u.b[5] = 4; + p = u2p(&u, 1); + r &= UA_GET_NE32(p) == 0; + r &= UA_GET_LE32(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE32(p) == 128; + u.b[2] = 129; u.b[3] = 130; u.b[4] = 131; + r &= UA_GET_LE32(p) == LZO_UINT32_C(0x83828180); +#if (LZO_ABI_BIG_ENDIAN) + r &= UA_GET_NE32(p) == LZO_UINT32_C(0x80818283); +#endif +#if (LZO_ABI_LITTLE_ENDIAN) + r &= UA_GET_NE32(p) == LZO_UINT32_C(0x83828180); +#endif +#if defined(UA_GET_NE64) + u.c[0] = u.c[1] = 0; + u.b[0] = 5; u.b[9] = 6; + p = u2p(&u, 1); + u.c[0] = u.c[1] = 0; + r &= UA_GET_NE64(p) == 0; +#if defined(UA_GET_LE64) + r &= UA_GET_LE64(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE64(p) == 128; +#endif +#endif +#if defined(lzo_bitops_ctlz32) + { unsigned i = 0; lzo_uint32_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_ctlz32(v) == 31 - i; + r &= lzo_bitops_ctlz32_func(v) == 31 - i; + }} +#endif +#if defined(lzo_bitops_ctlz64) + { unsigned i = 0; lzo_uint64_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_ctlz64(v) == 63 - i; + r &= lzo_bitops_ctlz64_func(v) == 63 - i; + }} +#endif +#if defined(lzo_bitops_cttz32) + { unsigned i = 0; lzo_uint32_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_cttz32(v) == i; + r &= lzo_bitops_cttz32_func(v) == i; + }} +#endif +#if defined(lzo_bitops_cttz64) + { unsigned i = 0; lzo_uint64_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_cttz64(v) == i; + r &= lzo_bitops_cttz64_func(v) == i; + }} +#endif +#endif + LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); + + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT +#define LZOCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef LZOCHK_ASSERT + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32_t)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#endif + +#define LZO1X 1 +#define LZO_EOF_CODE 1 +#define M2_MAX_OFFSET 0x0800 + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#if 1 && defined(UA_GET_LE32) +#undef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 0 +#undef lzo_dict_t +#define lzo_dict_t lzo_uint16_t +#endif + +#define LZO_NEED_DICT_H 1 +#ifndef D_BITS +#define D_BITS 14 +#endif +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) +#if 1 +#define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS))) +#else +#define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS))) +#endif + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H 1 + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X 1 +#endif + +#if !defined(__LZO_IN_MINILZO) +#include +#endif + +#ifndef LZO_EOF_CODE +#define LZO_EOF_CODE 1 +#endif +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 6 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 6 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +#if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +static void __attribute__((__unused__)) +#else +static void +#endif +DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if (LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_dict_t) pd(p, in)) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if (LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if (LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR) + +#ifndef DO_COMPRESS +#define DO_COMPRESS lzo1x_1_compress +#endif + +#if 1 && defined(DO_COMPRESS) && !defined(do_compress) +# define do_compress LZO_PP_ECONCAT2(DO_COMPRESS,_core) +#endif + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_uint ti, lzo_voidp wrkmem) +{ + const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - 20; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += ti < 4 ? 4 - ti : 0; + for (;;) + { + const lzo_bytep m_pos; +#if !(LZO_DETERMINISTIC) + LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0); + lzo_uint m_len; + lzo_uint dindex; +next: + if __lzo_unlikely(ip >= ip_end) + break; + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if (LZO_OPT_UNALIGNED32) + if (UA_GET_NE32(m_pos) != UA_GET_NE32(ip)) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3]) +#endif + { +literal: + UPDATE_I(dict,0,dindex,ip,in); + ip += 1 + ((ip - ii) >> 5); + continue; + } + UPDATE_I(dict,0,dindex,ip,in); +#else + lzo_uint m_off; + lzo_uint m_len; + { + lzo_uint32_t dv; + lzo_uint dindex; +literal: + ip += 1 + ((ip - ii) >> 5); +next: + if __lzo_unlikely(ip >= ip_end) + break; + dv = UA_GET_LE32(ip); + dindex = DINDEX(dv,ip); + GINDEX(m_off,m_pos,in+dict,dindex,in); + UPDATE_I(dict,0,dindex,ip,in); + if __lzo_unlikely(dv != UA_GET_LE32(m_pos)) + goto literal; + } +#endif + + ii -= ti; ti = 0; + { + lzo_uint t = pd(ip,ii); + if (t != 0) + { + if (t <= 3) + { + op[-2] = LZO_BYTE(op[-2] | t); +#if (LZO_OPT_UNALIGNED32) + UA_COPY4(op, ii); + op += t; +#else + { do *op++ = *ii++; while (--t > 0); } +#endif + } +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) + else if (t <= 16) + { + *op++ = LZO_BYTE(t - 3); + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); + op += t; + } +#endif + else + { + if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + *op++ = 0; + while __lzo_unlikely(tt > 255) + { + tt -= 255; + UA_SET1(op, 0); + op++; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) + do { + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); + op += 16; ii += 16; t -= 16; + } while (t >= 16); if (t > 0) +#endif + { do *op++ = *ii++; while (--t > 0); } + } + } + } + m_len = 4; + { +#if (LZO_OPT_UNALIGNED64) + lzo_uint64_t v; + v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 8; + v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz64) + m_len += lzo_bitops_ctlz64(v) / CHAR_BIT; +#elif (LZO_ABI_BIG_ENDIAN) + if ((v >> (64 - CHAR_BIT)) == 0) do { + v <<= CHAR_BIT; + m_len += 1; + } while ((v >> (64 - CHAR_BIT)) == 0); +#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz64) + m_len += lzo_bitops_cttz64(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#elif (LZO_OPT_UNALIGNED32) + lzo_uint32_t v; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 4; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if (v != 0) + break; + m_len += 4; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz32) + m_len += lzo_bitops_ctlz32(v) / CHAR_BIT; +#elif (LZO_ABI_BIG_ENDIAN) + if ((v >> (32 - CHAR_BIT)) == 0) do { + v <<= CHAR_BIT; + m_len += 1; + } while ((v >> (32 - CHAR_BIT)) == 0); +#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz32) + m_len += lzo_bitops_cttz32(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#else + if __lzo_unlikely(ip[m_len] == m_pos[m_len]) { + do { + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (ip[m_len] == m_pos[m_len]); + } +#endif + } +m_len_done: + m_off = pd(ip,m_pos); + ip += m_len; + ii = ip; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; + UA_SET1(op, 0); + op++; + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + else + { + m_off -= 0x4000; + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8)); + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; + UA_SET1(op, 0); + op++; + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + goto next; + } + + *out_len = pd(op, out); + return pd(in_end,ii-ti); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + const lzo_bytep ip = in; + lzo_bytep op = out; + lzo_uint l = in_len; + lzo_uint t = 0; + + while (l > 20) + { + lzo_uint ll = l; + lzo_uintptr_t ll_end; +#if 0 || (LZO_DETERMINISTIC) + ll = LZO_MIN(ll, 49152); +#endif + ll_end = (lzo_uintptr_t)ip + ll; + if ((ll_end + ((t + ll) >> 5)) <= ll_end || (const lzo_bytep)(ll_end + ((t + ll) >> 5)) <= ip + ll) + break; +#if (LZO_DETERMINISTIC) + lzo_memset(wrkmem, 0, ((lzo_uint)1 << D_BITS) * sizeof(lzo_dict_t)); +#endif + t = do_compress(ip,ll,op,out_len,t,wrkmem); + ip += ll; + op += *out_len; + l -= ll; + } + t += l; + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] = LZO_BYTE(op[-2] | t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + UA_SET1(op, 0); + op++; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + UA_COPYN(op, ii, t); + op += t; + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_IP_AND_TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef TEST_IV +#undef TEST_OV +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) +#elif defined(HAVE_TEST_IP) +# define TEST_IP_AND_TEST_OP TEST_IP +#elif defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP TEST_OP +#else +# define TEST_IP_AND_TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +# define TEST_IV(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +# define TEST_OV(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + NEED_IP(1); + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+3); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + for (;;) + { + NEED_IP(3); + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_IV(t); + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + t += 3; + if (t >= 8) do + { + UA_COPY8(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !(LZO_OPT_UNALIGNED32) + } + else +#endif +#endif +#if !(LZO_OPT_UNALIGNED32) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + for (;;) { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 31 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 7 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY8(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } + } + +eof_found: + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN 1 +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_IP_AND_TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef TEST_IV +#undef TEST_OV +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) +#elif defined(HAVE_TEST_IP) +# define TEST_IP_AND_TEST_OP TEST_IP +#elif defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP TEST_OP +#else +# define TEST_IP_AND_TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +# define TEST_IV(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +# define TEST_OV(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + NEED_IP(1); + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+3); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + for (;;) + { + NEED_IP(3); + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_IV(t); + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + t += 3; + if (t >= 8) do + { + UA_COPY8(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !(LZO_OPT_UNALIGNED32) + } + else +#endif +#endif +#if !(LZO_OPT_UNALIGNED32) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + for (;;) { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 31 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 7 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY8(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } + } + +eof_found: + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ diff --git a/libs/compression/minilzo.h b/libs/compression/minilzo.h new file mode 100644 index 0000000..c1c2297 --- /dev/null +++ b/libs/compression/minilzo.h @@ -0,0 +1,106 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H_INCLUDED +#define __MINILZO_H_INCLUDED 1 + +#define MINILZO_VERSION 0x20a0 /* 2.10 */ + +#if defined(__LZOCONF_H_INCLUDED) +# error "you cannot use both LZO and miniLZO" +#endif + +/* internal Autoconf configuration file - only used when building miniLZO */ +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include + +#ifndef __LZODEFS_H_INCLUDED +#include "lzodefs.h" +#endif +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +# error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 sw=4 et: */