diff --git a/DevILSDK/lib/x64/unicode/Release/DevIL.dll b/DevILSDK/lib/x64/unicode/Release/DevIL.dll deleted file mode 100644 index f37e16d..0000000 Binary files a/DevILSDK/lib/x64/unicode/Release/DevIL.dll and /dev/null differ diff --git a/DevILSDK/lib/x64/unicode/Release/DevIL.lib b/DevILSDK/lib/x64/unicode/Release/DevIL.lib deleted file mode 100644 index 1402f93..0000000 Binary files a/DevILSDK/lib/x64/unicode/Release/DevIL.lib and /dev/null differ diff --git a/DevILSDK/lib/x64/unicode/Release/ILU.dll b/DevILSDK/lib/x64/unicode/Release/ILU.dll deleted file mode 100644 index 6bc6413..0000000 Binary files a/DevILSDK/lib/x64/unicode/Release/ILU.dll and /dev/null differ diff --git a/DevILSDK/lib/x64/unicode/Release/ILU.lib b/DevILSDK/lib/x64/unicode/Release/ILU.lib deleted file mode 100644 index a44cbd1..0000000 Binary files a/DevILSDK/lib/x64/unicode/Release/ILU.lib and /dev/null differ diff --git a/DevILSDK/lib/x64/unicode/Release/ILUT.dll b/DevILSDK/lib/x64/unicode/Release/ILUT.dll deleted file mode 100644 index e560746..0000000 Binary files a/DevILSDK/lib/x64/unicode/Release/ILUT.dll and /dev/null differ diff --git a/DevILSDK/lib/x64/unicode/Release/ILUT.lib b/DevILSDK/lib/x64/unicode/Release/ILUT.lib deleted file mode 100644 index 49a0775..0000000 Binary files a/DevILSDK/lib/x64/unicode/Release/ILUT.lib and /dev/null differ diff --git a/DevILSDK/lib/x86/Release/DevIL.dll b/DevILSDK/lib/x86/Release/DevIL.dll deleted file mode 100644 index 1bd3822..0000000 Binary files a/DevILSDK/lib/x86/Release/DevIL.dll and /dev/null differ diff --git a/DevILSDK/lib/x86/Release/DevIL.lib b/DevILSDK/lib/x86/Release/DevIL.lib deleted file mode 100644 index cb7de1e..0000000 Binary files a/DevILSDK/lib/x86/Release/DevIL.lib and /dev/null differ diff --git a/DevILSDK/lib/x86/Release/ILU.dll b/DevILSDK/lib/x86/Release/ILU.dll deleted file mode 100644 index 2966069..0000000 Binary files a/DevILSDK/lib/x86/Release/ILU.dll and /dev/null differ diff --git a/DevILSDK/lib/x86/Release/ILU.lib b/DevILSDK/lib/x86/Release/ILU.lib deleted file mode 100644 index 5ea04cb..0000000 Binary files a/DevILSDK/lib/x86/Release/ILU.lib and /dev/null differ diff --git a/DevILSDK/lib/x86/Release/ILUT.dll b/DevILSDK/lib/x86/Release/ILUT.dll deleted file mode 100644 index 0fa9deb..0000000 Binary files a/DevILSDK/lib/x86/Release/ILUT.dll and /dev/null differ diff --git a/DevILSDK/lib/x86/Release/ILUT.lib b/DevILSDK/lib/x86/Release/ILUT.lib deleted file mode 100644 index c78c6a4..0000000 Binary files a/DevILSDK/lib/x86/Release/ILUT.lib and /dev/null differ diff --git a/DevILSDK/lib/x86/unicode/Release/DevIL.dll b/DevILSDK/lib/x86/unicode/Release/DevIL.dll deleted file mode 100644 index 38b2017..0000000 Binary files a/DevILSDK/lib/x86/unicode/Release/DevIL.dll and /dev/null differ diff --git a/DevILSDK/lib/x86/unicode/Release/DevIL.lib b/DevILSDK/lib/x86/unicode/Release/DevIL.lib deleted file mode 100644 index 8669310..0000000 Binary files a/DevILSDK/lib/x86/unicode/Release/DevIL.lib and /dev/null differ diff --git a/DevILSDK/lib/x86/unicode/Release/ILU.dll b/DevILSDK/lib/x86/unicode/Release/ILU.dll deleted file mode 100644 index 7228e66..0000000 Binary files a/DevILSDK/lib/x86/unicode/Release/ILU.dll and /dev/null differ diff --git a/DevILSDK/lib/x86/unicode/Release/ILU.lib b/DevILSDK/lib/x86/unicode/Release/ILU.lib deleted file mode 100644 index ab2231f..0000000 Binary files a/DevILSDK/lib/x86/unicode/Release/ILU.lib and /dev/null differ diff --git a/DevILSDK/lib/x86/unicode/Release/ILUT.dll b/DevILSDK/lib/x86/unicode/Release/ILUT.dll deleted file mode 100644 index c329aaf..0000000 Binary files a/DevILSDK/lib/x86/unicode/Release/ILUT.dll and /dev/null differ diff --git a/DevILSDK/lib/x86/unicode/Release/ILUT.lib b/DevILSDK/lib/x86/unicode/Release/ILUT.lib deleted file mode 100644 index 0219ac0..0000000 Binary files a/DevILSDK/lib/x86/unicode/Release/ILUT.lib and /dev/null differ diff --git a/XPlor.pro b/XPlor.pro index 64a2d3a..c64d696 100644 --- a/XPlor.pro +++ b/XPlor.pro @@ -1,99 +1,12 @@ -QT += core gui multimedia +TEMPLATE = subdirs -RC_ICONS = XPlor.ico - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -CONFIG += c++17 - -SOURCES += \ - aboutdialog.cpp \ - ddsfile.cpp \ - ddsviewer.cpp \ - fastfile.cpp \ - fastfile_cod2.cpp \ - fastfile_cod5.cpp \ - fastfile_cod7.cpp \ - fastfile_cod9.cpp \ - fastfileviewer.cpp \ - imagewidget.cpp \ - iwifile.cpp \ - iwiviewer.cpp \ - localstringviewer.cpp \ - lzokay.cpp \ - main.cpp \ - mainwindow.cpp \ - iwifile.cpp \ - preferenceeditor.cpp \ - soundviewer.cpp \ - statusbarmanager.cpp \ - stringtableviewer.cpp \ - techsetviewer.cpp \ - xtreewidget.cpp \ - xtreewidgetitem.cpp \ - zonefile.cpp \ - zonefile_cod2.cpp \ - zonefile_cod5.cpp \ - zonefile_cod7.cpp \ - zonefile_cod9.cpp \ - zonefileviewer.cpp - -HEADERS += \ - aboutdialog.h \ - asset_structs.h \ - compressor.h \ - d3dbsp_structs.h \ - dds_structs.h \ - ddsfile.h \ - ddsviewer.h \ - enums.h \ - fastfile.h \ - fastfile_cod2.h \ - fastfile_cod5.h \ - fastfile_cod7.h \ - fastfile_cod9.h \ - fastfileviewer.h \ - imagewidget.h \ - ipak_structs.h \ - iwifile.h \ - iwiviewer.h \ - localstringviewer.h \ - lzokay.hpp \ - lzx.h \ - mainwindow.h \ - preferenceeditor.h \ - soundviewer.h \ - statusbarmanager.h \ - stringtableviewer.h \ - techsetviewer.h \ - utils.h \ - xtreewidget.h \ - iwifile.h \ - xtreewidgetitem.h \ - zonefile.h \ - zonefile_cod2.h \ - zonefile_cod5.h \ - zonefile_cod7.h \ - zonefile_cod9.h \ - zonefileviewer.h - -FORMS += \ - aboutdialog.ui \ - ddsviewer.ui \ - fastfileviewer.ui \ - imagewidget.ui \ - iwiviewer.ui \ - localstringviewer.ui \ - mainwindow.ui \ - modelviewer.ui \ - preferenceeditor.ui \ - soundviewer.ui \ - stringtableviewer.ui \ - techsetviewer.ui \ - zonefileviewer.ui - -RESOURCES += data/data.qrc - -LIBS += -L$$PWD/DevILSDK/lib/x64/Unicode/Release -lDevIL -LIBS += -L$$PWD/DevILSDK/lib/x64/Unicode/Release -lILU -LIBS += -L$$PWD/DevILSDK/lib/x64/Unicode/Release -lILUT +SUBDIRS += libs/core \ + libs/compression \ + libs/encryption \ + libs/fastfile \ + libs/zonefile \ + libs/ddsfile \ + libs/iwifile \ + libs/ipakfile \ + app \ + tests diff --git a/LICENSE b/app/LICENSE similarity index 100% rename from LICENSE rename to app/LICENSE diff --git a/aboutdialog.cpp b/app/aboutdialog.cpp similarity index 100% rename from aboutdialog.cpp rename to app/aboutdialog.cpp diff --git a/aboutdialog.h b/app/aboutdialog.h similarity index 100% rename from aboutdialog.h rename to app/aboutdialog.h diff --git a/aboutdialog.ui b/app/aboutdialog.ui similarity index 100% rename from aboutdialog.ui rename to app/aboutdialog.ui diff --git a/XPlor.ico b/app/app.ico similarity index 100% rename from XPlor.ico rename to app/app.ico diff --git a/app/app.pro b/app/app.pro new file mode 100644 index 0000000..b174e95 --- /dev/null +++ b/app/app.pro @@ -0,0 +1,111 @@ +QT += core widgets gui multimedia + +RC_ICONS = app.ico + +SUBDIRS += app + +CONFIG += c++17 + +SOURCES += \ + aboutdialog.cpp \ + ddsviewer.cpp \ + fastfileviewer.cpp \ + imagewidget.cpp \ + iwiviewer.cpp \ + localstringviewer.cpp \ + main.cpp \ + mainwindow.cpp \ + materialviewer.cpp \ + preferenceeditor.cpp \ + soundviewer.cpp \ + stringtableviewer.cpp \ + techsetviewer.cpp \ + xtreewidget.cpp \ + xtreewidgetitem.cpp \ + zonefileviewer.cpp + +HEADERS += \ + aboutdialog.h \ + d3dbsp_structs.h \ + ddsviewer.h \ + fastfileviewer.h \ + imagewidget.h \ + iwiviewer.h \ + localstringviewer.h \ + mainwindow.h \ + materialviewer.h \ + preferenceeditor.h \ + soundviewer.h \ + stringtableviewer.h \ + techsetviewer.h \ + xtreewidget.h \ + xtreewidgetitem.h \ + zonefileviewer.h + +FORMS += \ + aboutdialog.ui \ + ddsviewer.ui \ + fastfileviewer.ui \ + imagewidget.ui \ + iwiviewer.ui \ + localstringviewer.ui \ + mainwindow.ui \ + materialviewer.ui \ + modelviewer.ui \ + preferenceeditor.ui \ + soundviewer.ui \ + stringtableviewer.ui \ + techsetviewer.ui \ + zonefileviewer.ui + +RESOURCES += ../data/data.qrc + +app.depends += \ + libs/core \ + libs/compression \ + libs/encryption \ + libs/fastfile \ + libs/ddsfile \ + libs/ipakfile \ + libs/iwifile \ + libs/zonefile + +LIBS += \ + -L$$PWD/../third_party/devil_sdk/lib/ -lDevIL \ + -L$$PWD/../third_party/devil_sdk/lib/ -lILU \ + -L$$PWD/../third_party/devil_sdk/lib/ -lILUT \ + -L$$PWD/../third_party/zlib/lib/ -lzlib \ + -L$$OUT_PWD/../libs/ -lcore \ + -L$$OUT_PWD/../libs/ -lcompression \ +# -L$$OUT_PWD/../libs/ -lencryption \ + -L$$OUT_PWD/../libs/ -lfastfile \ + -L$$OUT_PWD/../libs/ -lddsfile \ +# -L$$OUT_PWD/../libs/ -lipakfile \ + -L$$OUT_PWD/../libs/ -liwifile \ + -L$$OUT_PWD/../libs/ -lzonefile + +message($$OUT_PWD/../libs/core) + +INCLUDEPATH += \ + $$PWD/../third_party/devil_sdk/include/ \ + $$PWD/../third_party/zlib/include \ + $$PWD/../libs/core \ + $$PWD/../libs/compression \ + $$PWD/../libs/encryption \ + $$PWD/../libs/fastfile \ + $$PWD/../libs/ddsfile \ + $$PWD/../libs/ipakfile \ + $$PWD/../libs/iwifile \ + $$PWD/../libs/zonefile + +DEPENDPATH += \ + $$PWD/../third_party/devil_sdk/include/ \ + $$PWD/../third_party/zlib_lib/include \ + $$PWD/../libs/core \ + $$PWD/../libs/compression \ + $$PWD/../libs/encryption \ + $$PWD/../libs/fastfile \ + $$PWD/../libs/ddsfile \ + $$PWD/../libs/ipakfile \ + $$PWD/../libs/iwifile \ + $$PWD/../libs/zonefile diff --git a/d3dbsp_structs.h b/app/d3dbsp_structs.h similarity index 100% rename from d3dbsp_structs.h rename to app/d3dbsp_structs.h diff --git a/ddsviewer.cpp b/app/ddsviewer.cpp similarity index 100% rename from ddsviewer.cpp rename to app/ddsviewer.cpp diff --git a/ddsviewer.h b/app/ddsviewer.h similarity index 100% rename from ddsviewer.h rename to app/ddsviewer.h diff --git a/ddsviewer.ui b/app/ddsviewer.ui similarity index 100% rename from ddsviewer.ui rename to app/ddsviewer.ui diff --git a/fastfileviewer.cpp b/app/fastfileviewer.cpp similarity index 100% rename from fastfileviewer.cpp rename to app/fastfileviewer.cpp diff --git a/fastfileviewer.h b/app/fastfileviewer.h similarity index 100% rename from fastfileviewer.h rename to app/fastfileviewer.h diff --git a/fastfileviewer.ui b/app/fastfileviewer.ui similarity index 100% rename from fastfileviewer.ui rename to app/fastfileviewer.ui diff --git a/imagewidget.cpp b/app/imagewidget.cpp similarity index 100% rename from imagewidget.cpp rename to app/imagewidget.cpp diff --git a/imagewidget.h b/app/imagewidget.h similarity index 100% rename from imagewidget.h rename to app/imagewidget.h diff --git a/imagewidget.ui b/app/imagewidget.ui similarity index 100% rename from imagewidget.ui rename to app/imagewidget.ui diff --git a/iwiviewer.cpp b/app/iwiviewer.cpp similarity index 100% rename from iwiviewer.cpp rename to app/iwiviewer.cpp diff --git a/iwiviewer.h b/app/iwiviewer.h similarity index 100% rename from iwiviewer.h rename to app/iwiviewer.h diff --git a/iwiviewer.ui b/app/iwiviewer.ui similarity index 100% rename from iwiviewer.ui rename to app/iwiviewer.ui diff --git a/localstringviewer.cpp b/app/localstringviewer.cpp similarity index 100% rename from localstringviewer.cpp rename to app/localstringviewer.cpp diff --git a/localstringviewer.h b/app/localstringviewer.h similarity index 100% rename from localstringviewer.h rename to app/localstringviewer.h diff --git a/localstringviewer.ui b/app/localstringviewer.ui similarity index 100% rename from localstringviewer.ui rename to app/localstringviewer.ui diff --git a/main.cpp b/app/main.cpp similarity index 100% rename from main.cpp rename to app/main.cpp diff --git a/mainwindow.cpp b/app/mainwindow.cpp similarity index 84% rename from mainwindow.cpp rename to app/mainwindow.cpp index 7bb1a6a..1aad8e7 100644 --- a/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -1,22 +1,29 @@ #include "mainwindow.h" #include "aboutdialog.h" #include "fastfile.h" +#include "materialviewer.h" #include "preferenceeditor.h" -#include "qheaderview.h" #include "soundviewer.h" #include "stringtableviewer.h" #include "techsetviewer.h" #include "ui_mainwindow.h" #include "compressor.h" -#include "dds_structs.h" #include "iwifile.h" #include "ddsfile.h" #include "statusbarmanager.h" +#include "ddsviewer.h" +#include "fastfileviewer.h" +#include "ipak_structs.h" +#include "iwiviewer.h" +#include "localstringviewer.h" +#include "imagewidget.h" +#include "xtreewidget.h" +#include "zonefileviewer.h" +#include "techsetviewer.h" +#include "logmanager.h" #include -#include "DevILSDK/include/IL/il.h" - MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); @@ -34,6 +41,7 @@ MainWindow::MainWindow(QWidget *parent) mDiskLumpOrder = QVector(); mLumps = QMap(); mTreeWidget = new XTreeWidget(this); + mLogWidget = new QPlainTextEdit(this); //ModelViewer *mModelViewer = new ModelViewer(container); //mModelViewer->setAcceptDrops(false); @@ -48,6 +56,9 @@ MainWindow::MainWindow(QWidget *parent) connect(&StatusBarManager::instance(), &StatusBarManager::progressUpdated, this, &MainWindow::HandleProgressUpdate); + connect(&LogManager::instance(), &LogManager::entryAdded, + this, &MainWindow::HandleLogEntry); + statusBar()->addPermanentWidget(mProgressBar); connect(ui->actionPreferences, &QAction::triggered, this, [this](bool checked) { @@ -131,9 +142,10 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->clear(); }); - connect(mTreeWidget, &XTreeWidget::RawFileSelected, this, [this](std::shared_ptr rawFile) { + connect(mTreeWidget, &XTreeWidget::RawFileSelected, this, [this](std::shared_ptr rawFile, const QString aParentName) { QPlainTextEdit *scriptEditor = new QPlainTextEdit(this); scriptEditor->setAcceptDrops(false); + scriptEditor->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); if (rawFile->contents.isEmpty()) { scriptEditor->setPlainText("EMPTY"); @@ -153,10 +165,11 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::ImageSelected, this, [this](std::shared_ptr image) { + connect(mTreeWidget, &XTreeWidget::ImageSelected, this, [this](std::shared_ptr image, const QString aParentName) { ImageWidget *mImageWidget = new ImageWidget(this); mImageWidget->setAcceptDrops(false); mImageWidget->SetImage(image); + mImageWidget->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); QString fileStem = image->materialName; for (int i = 0; i < ui->tabWidget->count(); i++) { @@ -170,14 +183,15 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::MenuSelected, this, [this](std::shared_ptr menu) { + connect(mTreeWidget, &XTreeWidget::MenuSelected, this, [](std::shared_ptr menu, const QString aParentName) { Q_UNUSED(menu); }); - connect(mTreeWidget, &XTreeWidget::DDSFileSelected, this, [this](std::shared_ptr ddsFile) { + 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++) { @@ -191,10 +205,47 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::IWIFileSelected, this, [this](std::shared_ptr iwiFile) { + connect(mTreeWidget, &XTreeWidget::MaterialSelected, this, [this](std::shared_ptr material, const QString aParentName) { + MaterialViewer *matViewer = new MaterialViewer(this); + matViewer->setAcceptDrops(false); + matViewer->SetMaterial(material); + matViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); + + QString fileStem = material->name; + for (int i = 0; i < ui->tabWidget->count(); i++) { + if (ui->tabWidget->tabText(i) == fileStem) { + return; + } + } + + ui->tabWidget->addTab(matViewer, fileStem); + ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_Material.png")); + ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); + }); + + 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::IWIFileSelected, this, [this](std::shared_ptr iwiFile, const QString aParentName) { IWIViewer *iwiViewer = new IWIViewer(this); iwiViewer->setAcceptDrops(false); iwiViewer->SetIWIFile(iwiFile); + iwiViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); QString fileStem = iwiFile->fileStem + ".iwi"; for (int i = 0; i < ui->tabWidget->count(); i++) { @@ -208,12 +259,13 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::FastFileSelected, this, [this](std::shared_ptr aFastFile) { + connect(mTreeWidget, &XTreeWidget::FastFileSelected, this, [this](std::shared_ptr aFastFile, const QString aParentName) { FastFileViewer *fastFileViewer = new FastFileViewer(this); fastFileViewer->setAcceptDrops(false); fastFileViewer->SetFastFile(aFastFile); + fastFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); - QString fileStem = aFastFile->GetStem(); + QString fileStem = aFastFile->GetStem() + ".ff"; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { return; @@ -225,12 +277,13 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::ZoneFileSelected, this, [this](std::shared_ptr aZoneFile) { + connect(mTreeWidget, &XTreeWidget::ZoneFileSelected, this, [this](std::shared_ptr aZoneFile, const QString aParentName) { ZoneFileViewer *zoneFileViewer = new ZoneFileViewer(this); zoneFileViewer->setAcceptDrops(false); zoneFileViewer->SetZoneFile(aZoneFile); + zoneFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); - QString fileStem = aZoneFile->GetStem(); + QString fileStem = aZoneFile->GetStem() + ".zone"; for (int i = 0; i < ui->tabWidget->count(); i++) { if (ui->tabWidget->tabText(i) == fileStem) { return; @@ -242,10 +295,11 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::LocalStringSelected, this, [this](std::shared_ptr aZoneFile) { + connect(mTreeWidget, &XTreeWidget::LocalStringSelected, this, [this](std::shared_ptr aZoneFile, const QString aParentName) { LocalStringViewer *localStrViewer = new LocalStringViewer(this); localStrViewer->setAcceptDrops(false); localStrViewer->SetZoneFile(aZoneFile); + localStrViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); QString fileStem = aZoneFile->GetStem() + ".str"; for (int i = 0; i < ui->tabWidget->count(); i++) { @@ -259,11 +313,11 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::TechSetSelected, this, [this](std::shared_ptr aTechSet) { - + connect(mTreeWidget, &XTreeWidget::TechSetSelected, this, [this](std::shared_ptr aTechSet, const QString aParentName) { TechSetViewer *techSetViewer = new TechSetViewer(this); techSetViewer->setAcceptDrops(false); techSetViewer->SetTechSet(aTechSet); + techSetViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); QString fileStem = aTechSet->name; for (int i = 0; i < ui->tabWidget->count(); i++) { @@ -277,11 +331,11 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::StrTableSelected, this, [this](std::shared_ptr aStrTable) { - + connect(mTreeWidget, &XTreeWidget::StrTableSelected, this, [this](std::shared_ptr aStrTable, const QString aParentName) { StringTableViewer *strTableViewer = new StringTableViewer(this); strTableViewer->setAcceptDrops(false); strTableViewer->SetStringTable(aStrTable); + strTableViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); QString fileStem = aStrTable->name; for (int i = 0; i < ui->tabWidget->count(); i++) { @@ -295,11 +349,11 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::SoundSelected, this, [this](std::shared_ptr aSound) { - + connect(mTreeWidget, &XTreeWidget::SoundSelected, this, [this](std::shared_ptr aSound, const QString aParentName) { SoundViewer *soundViewer = new SoundViewer(this); soundViewer->setAcceptDrops(false); soundViewer->SetSound(aSound); + soundViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); QString fileStem = aSound->path.split('/').last(); for (int i = 0; i < ui->tabWidget->count(); i++) { @@ -313,15 +367,25 @@ MainWindow::MainWindow(QWidget *parent) ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); }); - connect(mTreeWidget, &XTreeWidget::TabSelected, this, [this](QString tabName) { + connect(mTreeWidget, &XTreeWidget::ItemSelected, this, [this](const QString itemText) { for (int i = 0; i < ui->tabWidget->count(); i++) { - if (ui->tabWidget->tabText(i) == tabName) { + if (ui->tabWidget->tabText(i) == itemText) { ui->tabWidget->setCurrentIndex(i); break; } } }); + connect(mTreeWidget, &XTreeWidget::ItemClosed, this, [this](const QString itemText) { + for (int i = 0; i < ui->tabWidget->count(); i++) { + const QString parentName = ui->tabWidget->widget(i)->property("PARENT_NAME").toString(); + if (parentName == itemText) { + ui->tabWidget->removeTab(i); + break; + } + } + }); + // Connect Help > About dialog connect(ui->actionAbout, &QAction::triggered, this, [this](bool checked) { Q_UNUSED(checked); @@ -345,8 +409,14 @@ MainWindow::MainWindow(QWidget *parent) QDockWidget *treeDockWidget = new QDockWidget(this); treeDockWidget->setWidget(mTreeWidget); + treeDockWidget->setWindowTitle("Tree Browser"); addDockWidget(Qt::LeftDockWidgetArea, treeDockWidget); + QDockWidget *logDockWidget = new QDockWidget(this); + logDockWidget->setWidget(mLogWidget); + logDockWidget->setWindowTitle("Logs"); + addDockWidget(Qt::RightDockWidgetArea, logDockWidget); + ui->toolBar->addAction(ui->actionNew_Fast_File); ui->toolBar->addAction(ui->actionNew_Zone_File); ui->toolBar->addAction(ui->actionOpen_Fast_File); @@ -390,7 +460,13 @@ void MainWindow::Reset() { and opens the selected file. */ bool MainWindow::OpenFastFile(const QString aFastFilePath) { - std::shared_ptr fastFile = FastFile::Create(aFastFilePath); + const QString fastFileStem = aFastFilePath.section("/", -1, -1).section('.', 0, 0); + if (mTreeWidget->HasFastFile(fastFileStem)) { + LogManager::instance().addError("Can't add duplicate file!"); + return false; + } + + std::shared_ptr fastFile = FastFile::Open(aFastFilePath); mTreeWidget->AddFastFile(fastFile); // Open zone file after decompressing ff and writing @@ -522,6 +598,14 @@ int MainWindow::LoadFile_DDSFiles(const QStringList aFilePaths) { return 0; } +void MainWindow::HandleLogEntry(const QString &entry) { + QString logContents = mLogWidget->toPlainText() + "\n" + entry; + if (mLogWidget->toPlainText().isEmpty()) { + logContents = entry; + } + mLogWidget->setPlainText(logContents); +} + void MainWindow::HandleStatusUpdate(const QString &message, int timeout) { statusBar()->showMessage(message, timeout); mProgressBar->setVisible(false); // Hide progress bar if just a message diff --git a/mainwindow.h b/app/mainwindow.h similarity index 89% rename from mainwindow.h rename to app/mainwindow.h index 136f140..daa90dc 100644 --- a/mainwindow.h +++ b/app/mainwindow.h @@ -3,16 +3,7 @@ #include "d3dbsp_structs.h" #include "asset_structs.h" -#include "ddsviewer.h" -#include "fastfileviewer.h" -#include "ipak_structs.h" -#include "iwiviewer.h" -#include "localstringviewer.h" -#include "modelviewer.h" -#include "imagewidget.h" #include "xtreewidget.h" -#include "zonefileviewer.h" -#include "techsetviewer.h" #include #include @@ -56,6 +47,7 @@ private slots: int LoadFile_DDS(const QString aFilePath); int LoadFile_DDSFiles(const QStringList aFilePaths); + void HandleLogEntry(const QString &entry); void HandleStatusUpdate(const QString &message, int timeout); void HandleProgressUpdate(const QString &message, int progress, int max); @@ -76,6 +68,7 @@ private: QMap mTreeMap; QMap>> mStrTableMap; XTreeWidget *mTreeWidget; + QPlainTextEdit *mLogWidget; QProgressBar *mProgressBar; quint32 mBSPVersion; diff --git a/mainwindow.ui b/app/mainwindow.ui similarity index 99% rename from mainwindow.ui rename to app/mainwindow.ui index 1b257d7..184418c 100644 --- a/mainwindow.ui +++ b/app/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 986 - 692 + 1579 + 857 @@ -46,7 +46,7 @@ 0 0 - 986 + 1579 21 diff --git a/app/materialviewer.cpp b/app/materialviewer.cpp new file mode 100644 index 0000000..1a97977 --- /dev/null +++ b/app/materialviewer.cpp @@ -0,0 +1,42 @@ +#include "materialviewer.h" +#include "ui_materialviewer.h" + +MaterialViewer::MaterialViewer(QWidget *parent) + : QWidget(parent) + , ui(new Ui::MaterialViewer) { + ui->setupUi(this); +} + +MaterialViewer::~MaterialViewer() { + delete ui; +} + +QString ToHexStr(quint32 in) { + return QString("%1").arg(in, 8, 16, QChar('0')).toUpper(); +} + +void MaterialViewer::SetMaterial(std::shared_ptr aMaterial) { + ui->lineEdit_NamePtr->setText(ToHexStr(aMaterial->namePtr)); + 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])); + ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[0])); + ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[1])); + ui->spinBox_TextureCount->setValue(aMaterial->textureCount); + ui->spinBox_ConstCount->setValue(aMaterial->constCount); + ui->lineEdit_TechSetPtr->setText(ToHexStr(aMaterial->techSetPtr)); + ui->lineEdit_TexturePtr->setText(ToHexStr(aMaterial->texturePtr)); + ui->lineEdit_ConstantPtr->setText(ToHexStr(aMaterial->constPtr)); +} diff --git a/app/materialviewer.h b/app/materialviewer.h new file mode 100644 index 0000000..78378bb --- /dev/null +++ b/app/materialviewer.h @@ -0,0 +1,25 @@ +#ifndef MATERIALVIEWER_H +#define MATERIALVIEWER_H + +#include "asset_structs.h" +#include + +namespace Ui { +class MaterialViewer; +} + +class MaterialViewer : public QWidget +{ + Q_OBJECT + +public: + explicit MaterialViewer(QWidget *parent = nullptr); + ~MaterialViewer(); + + void SetMaterial(std::shared_ptr aMaterial); + +private: + Ui::MaterialViewer *ui; +}; + +#endif // MATERIALVIEWER_H diff --git a/app/materialviewer.ui b/app/materialviewer.ui new file mode 100644 index 0000000..f7aa9d8 --- /dev/null +++ b/app/materialviewer.ui @@ -0,0 +1,236 @@ + + + MaterialViewer + + + + 0 + 0 + 1001 + 650 + + + + Form + + + + + + + Roboto + 16 + true + + + + Material 0 + + + + + + + + + + + + 325 + 398 + + + + + 325 + 16777215 + + + + + Roboto + 9 + + + + Header + + + + + + Name Ptr: + + + + + + + + + + Name: + + + + + + + Ref Ptr: + + + + + + + Ref Name: + + + + + + + Unknowns: + + + + + + + State A: + + + + + + + State B: + + + + + + + Texture Count: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Constant Count: + + + + + + + Tech Set Ptr: + + + + + + + Texture Ptr: + + + + + + + Constant Ptr: + + + + + + + + + + + + + + + + + + + 400 + 400 + + + + + Roboto + 9 + + + + Data + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Orientation::Vertical + + + + 20 + 143 + + + + + + + + + diff --git a/modelviewer.cpp b/app/modelviewer.cpp similarity index 100% rename from modelviewer.cpp rename to app/modelviewer.cpp diff --git a/modelviewer.h b/app/modelviewer.h similarity index 100% rename from modelviewer.h rename to app/modelviewer.h diff --git a/modelviewer.ui b/app/modelviewer.ui similarity index 100% rename from modelviewer.ui rename to app/modelviewer.ui diff --git a/preferenceeditor.cpp b/app/preferenceeditor.cpp similarity index 100% rename from preferenceeditor.cpp rename to app/preferenceeditor.cpp diff --git a/preferenceeditor.h b/app/preferenceeditor.h similarity index 100% rename from preferenceeditor.h rename to app/preferenceeditor.h diff --git a/preferenceeditor.ui b/app/preferenceeditor.ui similarity index 100% rename from preferenceeditor.ui rename to app/preferenceeditor.ui diff --git a/soundviewer.cpp b/app/soundviewer.cpp similarity index 100% rename from soundviewer.cpp rename to app/soundviewer.cpp diff --git a/soundviewer.h b/app/soundviewer.h similarity index 100% rename from soundviewer.h rename to app/soundviewer.h diff --git a/soundviewer.ui b/app/soundviewer.ui similarity index 100% rename from soundviewer.ui rename to app/soundviewer.ui diff --git a/stringtableviewer.cpp b/app/stringtableviewer.cpp similarity index 100% rename from stringtableviewer.cpp rename to app/stringtableviewer.cpp diff --git a/stringtableviewer.h b/app/stringtableviewer.h similarity index 100% rename from stringtableviewer.h rename to app/stringtableviewer.h diff --git a/stringtableviewer.ui b/app/stringtableviewer.ui similarity index 100% rename from stringtableviewer.ui rename to app/stringtableviewer.ui diff --git a/techsetviewer.cpp b/app/techsetviewer.cpp similarity index 100% rename from techsetviewer.cpp rename to app/techsetviewer.cpp diff --git a/techsetviewer.h b/app/techsetviewer.h similarity index 100% rename from techsetviewer.h rename to app/techsetviewer.h diff --git a/techsetviewer.ui b/app/techsetviewer.ui similarity index 100% rename from techsetviewer.ui rename to app/techsetviewer.ui diff --git a/xtreewidget.cpp b/app/xtreewidget.cpp similarity index 84% rename from xtreewidget.cpp rename to app/xtreewidget.cpp index 5b9bdbf..22e76fe 100644 --- a/xtreewidget.cpp +++ b/app/xtreewidget.cpp @@ -1,7 +1,7 @@ #include "xtreewidget.h" #include "qheaderview.h" #include "qmenu.h" -#include "utils.h" +#include "logmanager.h" XTreeWidget::XTreeWidget(QWidget *parent) : QTreeWidget(parent) { @@ -28,7 +28,7 @@ XTreeWidget::XTreeWidget(QWidget *parent) //header()->resizeSection(1, 32); //header()->resizeSection(2, 32); - connect(this, &QTreeWidget::itemSelectionChanged, this, &XTreeWidget::ItemSelectionChanged); + connect(this, &XTreeWidget::itemSelectionChanged, this, &XTreeWidget::ItemSelectionChanged); connect(this, &XTreeWidget::customContextMenuRequested, this, &XTreeWidget::PrepareContextMenu); } @@ -45,7 +45,9 @@ void XTreeWidget::AddFastFile(std::shared_ptr aFastFile) { } else if (aFastFile->GetPlatform() == "360") { fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_Xbox.png")); } - if (aFastFile->GetGame() == "COD4") { + if (aFastFile->GetGame() == "COD2") { + fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD2.png")); + } if (aFastFile->GetGame() == "COD4") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD4.png")); } else if (aFastFile->GetGame() == "COD5") { fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD5.png")); @@ -179,6 +181,18 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt } } + if (!assetMap.materials.isEmpty()) { + XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem); + materialsRoot->setText(0, "Materials"); + materialsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Material.png")); + + for (Material material: assetMap.materials) { + XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot); + materialItem->setText(0, material.name); + materialItem->setIcon(0, QIcon(":/icons/icons/Icon_Material.png")); + } + } + if (!assetMap.stringTables.isEmpty()) { XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem); strTableRoot->setText(0, "String Tables"); @@ -197,7 +211,7 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt soundsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Sound.png")); for (SoundAsset soundAsset : assetMap.sounds) { for (Sound sound : soundAsset.sounds) { - XTreeWidgetItem *tempItem = soundsRoot; + XTreeWidgetItem *tempItem = soundsRoot; if (!sound.dataLength) { continue; } @@ -234,6 +248,11 @@ void XTreeWidget::AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetIt mZoneFiles[aZoneFile->GetStem().section(".", 0, 0)] = aZoneFile; } +void XTreeWidget::CloseFastFile(const QString aFFName) { + const QString fileStem = aFFName.section(".", 0, 0); + emit ItemClosed(fileStem); +} + void XTreeWidget::PrepareContextMenu(const QPoint &pos) { auto activeItem = itemAt(pos); if (!activeItem) { return; } @@ -333,11 +352,13 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { } else if (activeText.contains(".ff")) { QMenu *closeMultipleAction = new QMenu("Close Multiple Tabs"); + QAction *closeAllAction = new QAction("Close All"); closeMultipleAction->addAction(closeAllAction); connect(closeAllAction, &QAction::triggered, this, [this](bool checked) { Q_UNUSED(checked); + mFastFiles.clear(); clear(); emit Cleared(); @@ -351,6 +372,15 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { for (int i = 0; i < invisibleRootItem()->childCount(); i++) { auto childItem = invisibleRootItem()->child(i); if (childItem == activeItem) { continue; } + + const QString fileStem = childItem->text(0).replace(".ff", ""); + if (!mFastFiles.contains(fileStem)) { + qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; + return; + } + + mFastFiles.remove(fileStem); + CloseFastFile(fileStem); invisibleRootItem()->removeChild(childItem); i--; } @@ -364,6 +394,15 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { for (int i = 0; i < invisibleRootItem()->childCount(); i++) { auto childItem = invisibleRootItem()->child(i); if (childItem == activeItem) { return; } + + const QString fileStem = childItem->text(0).replace(".ff", ""); + if (!mFastFiles.contains(fileStem)) { + qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; + return; + } + + mFastFiles.remove(fileStem); + CloseFastFile(fileStem); invisibleRootItem()->removeChild(childItem); i--; } @@ -382,38 +421,41 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { ready = true; continue; } + + const QString fileStem = childItem->text(0).replace(".ff", ""); + if (!mFastFiles.contains(fileStem)) { + qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; + return; + } + + mFastFiles.remove(fileStem); + CloseFastFile(fileStem); invisibleRootItem()->removeChild(childItem); i--; } }); contextMenu->addMenu(closeMultipleAction); - const QString fileStem = activeText.replace(".ff", ""); - if (!mFastFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; - return; - } QAction *closeAction = new QAction("Close File"); contextMenu->addAction(closeAction); - connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) { + connect(closeAction, &QAction::triggered, this, [this, &activeItem, &activeText](bool checked) { Q_UNUSED(checked); + const QString fileStem = activeItem->text(0).replace(".ff", ""); + mFastFiles.remove(fileStem); + CloseFastFile(activeText); invisibleRootItem()->removeChild(activeItem); }); QMenu *exportSubmenu = new QMenu("Export...", this); contextMenu->addMenu(exportSubmenu); - std::shared_ptr fastFile = mFastFiles[fileStem]; - QAction *exportDDSAction = new QAction("Export as Zone File"); exportSubmenu->addAction(exportDDSAction); - connect(exportDDSAction, &QAction::triggered, this, [fastFile](bool checked) { + connect(exportDDSAction, &QAction::triggered, this, [](bool checked) { Q_UNUSED(checked); - - //fastFile->SaveZone(); }); } else if (activeText.contains(".zone")) { const QString fileStem = activeText.replace(".zone", ""); @@ -431,8 +473,6 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) { exportSubmenu->addAction(exportDDSAction); connect(exportDDSAction, &QAction::triggered, this, [zoneFile](bool checked) { Q_UNUSED(checked); - - //zoneFile->SaveFastFile(); }); } else if (activeItem && activeText.contains(".wav")) { XTreeWidgetItem *parentItem = dynamic_cast(activeItem->parent()); @@ -541,7 +581,7 @@ void XTreeWidget::ItemSelectionChanged() { if (!selectedItem) { return; } if (selectedItem->text(0).isEmpty()) { return; } QString selectedText = selectedItem->text(0); - emit TabSelected(selectedText); + emit ItemSelected(selectedText); const QString fileStem = selectedText.section(".", 0, 0); @@ -549,35 +589,35 @@ void XTreeWidget::ItemSelectionChanged() { if (selectedText.contains(".dds")) { if (!mDDSFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in DDS map!"; + LogManager::instance().addError("Could not find " + fileStem + " in DDS map!"); return; } std::shared_ptr ddsFile = mDDSFiles[fileStem]; - emit DDSFileSelected(ddsFile); + emit DDSFileSelected(ddsFile, fileStem); } else if (selectedText.contains(".iwi")) { if (!mIWIFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in IWI map!"; + LogManager::instance().addError("Could not find " + fileStem + " in IWI map!"); return; } - emit IWIFileSelected(mIWIFiles[fileStem]); + emit IWIFileSelected(mIWIFiles[fileStem], fileStem); } else if (selectedText.contains(".ff")) { if (!mFastFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Fast File map!"; + LogManager::instance().addError("Could not find " + fileStem + " in Fast File map!"); return; } - emit FastFileSelected(mFastFiles[fileStem]); + emit FastFileSelected(mFastFiles[fileStem], fileStem); } else if (selectedText.contains(".zone")) { if (!mZoneFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; + LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!"); return; } - emit ZoneFileSelected(mZoneFiles[fileStem]); + emit ZoneFileSelected(mZoneFiles[fileStem], fileStem); } else if (selectedText.contains(".str")) { if (!mZoneFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; + LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!"); return; } - emit LocalStringSelected(mZoneFiles[fileStem]); + emit LocalStringSelected(mZoneFiles[fileStem], fileStem); } else if (selectedText.contains(".gsc")) { XTreeWidgetItem *zoneRoot = selectedItem; if (!zoneRoot) { return; } @@ -589,14 +629,14 @@ void XTreeWidget::ItemSelectionChanged() { const QString fileStem = zoneRoot->text(0).section('.', 0, 0); if (!mZoneFiles.contains(fileStem)) { - qDebug() << "Error: Could not find " << fileStem << " in Zone File map!"; + 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)); + emit RawFileSelected(std::make_shared(rawFile), fileStem); return; } } @@ -607,7 +647,7 @@ void XTreeWidget::ItemSelectionChanged() { QVector images = mZoneFiles[fileStem]->GetAssetMap().images; for (Image image : images) { if (image.materialName == selectedText) { - emit ImageSelected(std::make_shared(image)); + emit ImageSelected(std::make_shared(image), fileStem); break; } } @@ -619,19 +659,31 @@ void XTreeWidget::ItemSelectionChanged() { auto techsets = mZoneFiles[fileStem]->GetAssetMap().techSets; for (auto techset : techsets) { if (techset.name == selectedText) { - emit TechSetSelected(std::make_shared(techset)); + emit TechSetSelected(std::make_shared(techset), fileStem); break; } } } - } else if (parentItem && (parentItem->text(0) == "String Tables")) { + } else if (parentItem && (parentItem->text(0) == "Tech Sets")) { XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); if (grandpaItem && grandpaItem->text(0).contains(".zone")) { const QString fileStem = grandpaItem->text(0).section('.', 0, 0); - QVector strTables = mZoneFiles[fileStem]->GetAssetMap().stringTables; - for (StringTable strTable : strTables) { - if (strTable.name == selectedText) { - emit StrTableSelected(std::make_shared(strTable)); + auto techsets = mZoneFiles[fileStem]->GetAssetMap().techSets; + for (auto techset : techsets) { + if (techset.name == selectedText) { + emit TechSetSelected(std::make_shared(techset), fileStem); + break; + } + } + } + } else if (parentItem && (parentItem->text(0) == "Materials")) { + XTreeWidgetItem *grandpaItem = dynamic_cast(parentItem->parent()); + if (grandpaItem && grandpaItem->text(0).contains(".zone")) { + const QString fileStem = grandpaItem->text(0).section('.', 0, 0); + QVector materials = mZoneFiles[fileStem]->GetAssetMap().materials; + for (Material material : materials) { + if (material.name == selectedText) { + emit MaterialSelected(std::make_shared(material), fileStem); break; } } @@ -651,7 +703,7 @@ void XTreeWidget::ItemSelectionChanged() { for (SoundAsset soundAsset : soundAssets) { for (Sound sound : soundAsset.sounds) { if (sound.path.contains(selectedText)) { - emit SoundSelected(std::make_shared(sound)); + emit SoundSelected(std::make_shared(sound), fileStem); break; } } @@ -660,24 +712,32 @@ void XTreeWidget::ItemSelectionChanged() { } } -std::shared_ptr XTreeWidget::pFindZoneFile(const QString aFilePart) { +std::shared_ptr XTreeWidget::FindZoneFile(const QString aStem) { foreach (auto zoneFile, mZoneFiles) { - if (zoneFile->GetStem() == aFilePart) { + if (zoneFile->GetStem() == aStem) { return zoneFile; } } return nullptr; } -std::shared_ptr XTreeWidget::pFindFastFile(const QString aFilePart) { +std::shared_ptr XTreeWidget::FindFastFile(const QString aStem) { foreach (auto fastFile, mFastFiles) { - if (fastFile->GetStem() == aFilePart) { + if (fastFile->GetStem() == aStem) { return fastFile; } } return nullptr; } +bool XTreeWidget::HasZoneFile(const QString aStem) { + return FindZoneFile(aStem) != nullptr; +} + +bool XTreeWidget::HasFastFile(const QString aStem) { + return FindFastFile(aStem) != nullptr; +} + void XTreeWidget::AddIWIFile(std::shared_ptr aIWIFile) { const QString iwiFileName = QString(aIWIFile->fileStem + ".iwi"); diff --git a/app/xtreewidget.h b/app/xtreewidget.h new file mode 100644 index 0000000..37e3761 --- /dev/null +++ b/app/xtreewidget.h @@ -0,0 +1,62 @@ +#ifndef XTREEWIDGET_H +#define XTREEWIDGET_H + +#include "d3dbsp_structs.h" +#include "asset_structs.h" +#include "ddsfile.h" +#include "iwifile.h" +#include "fastfile.h" +#include "xtreewidgetitem.h" +#include "zonefile.h" + +#include + +class XTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + explicit XTreeWidget(QWidget *parent = nullptr); + ~XTreeWidget(); + + void AddFastFile(std::shared_ptr aFastFile); + void AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetItem *aParentItem = nullptr); + void AddIWIFile(std::shared_ptr aIWIFile); + void AddDDSFile(std::shared_ptr aDDSFile); + + std::shared_ptr FindZoneFile(const QString aStem); + std::shared_ptr FindFastFile(const QString aStem); + + bool HasZoneFile(const QString aStem); + bool HasFastFile(const QString aStem); + + void CloseFastFile(const QString aFFName); +signals: + void DDSFileSelected(std::shared_ptr aDDSFile, const QString aParentName); + void IWIFileSelected(std::shared_ptr aIWIFile, const QString aParentName); + void FastFileSelected(std::shared_ptr aFastFile, const QString aParentName); + void ZoneFileSelected(std::shared_ptr aZoneFile, const QString aParentName); + void LocalStringSelected(std::shared_ptr aZoneFile, const QString aParentName); + void RawFileSelected(std::shared_ptr aRawFile, const QString aParentName); + void ImageSelected(std::shared_ptr aImage, const QString aParentName); + void TechSetSelected(std::shared_ptr aZoneFile, const QString aParentName); + void StrTableSelected(std::shared_ptr aStrTable, const QString aParentName); + void MenuSelected(std::shared_ptr aMenu, const QString aParentName); + void SoundSelected(std::shared_ptr aSound, const QString aParentName); + void MaterialSelected(std::shared_ptr aMaterial, const QString aParentName); + void ItemSelected(const QString itemText); + + void ItemClosed(const QString itemText); + void Cleared(); + +protected: + void ItemSelectionChanged(); + void PrepareContextMenu(const QPoint &pos); + +private: + QMap> mFastFiles; + QMap> mZoneFiles; + QMap> mDDSFiles; + QMap> mIWIFiles; +}; + +#endif // XTREEWIDGET_H diff --git a/xtreewidgetitem.cpp b/app/xtreewidgetitem.cpp similarity index 100% rename from xtreewidgetitem.cpp rename to app/xtreewidgetitem.cpp diff --git a/xtreewidgetitem.h b/app/xtreewidgetitem.h similarity index 100% rename from xtreewidgetitem.h rename to app/xtreewidgetitem.h diff --git a/zonefileviewer.cpp b/app/zonefileviewer.cpp similarity index 100% rename from zonefileviewer.cpp rename to app/zonefileviewer.cpp diff --git a/zonefileviewer.h b/app/zonefileviewer.h similarity index 100% rename from zonefileviewer.h rename to app/zonefileviewer.h diff --git a/zonefileviewer.ui b/app/zonefileviewer.ui similarity index 100% rename from zonefileviewer.ui rename to app/zonefileviewer.ui diff --git a/data/Data.qrc b/data/Data.qrc index 6334224..8cb3696 100644 --- a/data/Data.qrc +++ b/data/Data.qrc @@ -71,5 +71,7 @@ icons/Icon_Paste.png icons/Icon_Save.png icons/Icon_OpenFile.png + icons/Icon_COD2.png + icons/Icon_Material.png diff --git a/data/icons/Icon_COD2.png b/data/icons/Icon_COD2.png new file mode 100644 index 0000000..470c389 Binary files /dev/null and b/data/icons/Icon_COD2.png differ diff --git a/data/icons/Icon_Material.png b/data/icons/Icon_Material.png new file mode 100644 index 0000000..2e9d2e8 Binary files /dev/null and b/data/icons/Icon_Material.png differ diff --git a/fastfile_cod9.cpp b/fastfile_cod9.cpp deleted file mode 100644 index 66d7e6e..0000000 --- a/fastfile_cod9.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "fastfile_cod9.h" -#include "zonefile_cod9.h" - -#include "utils.h" -#include "compressor.h" - -#include -#include - -FastFile_COD9::FastFile_COD9() { - -} - -FastFile_COD9::~FastFile_COD9() { - -} - -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); - 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_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 (GetGame() == "COD7") { - fastFileStream.skipRawData(4); - if (GetPlatform() == "360") { - key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); - } else if (GetPlatform() == "PS3") { - key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); - // or - // key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370"); - } - } else if (GetGame() == "COD9") { - 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); - - // Build the IV table from the fileName. - QByteArray ivTable = Compressor::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 = Compressor::GetIV(ivTable, sectionIndex); - - // Decrypt the section using Salsa20. - QByteArray decData = Compressor::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. - Compressor::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); - - if (GetPlatform() == "PC") { - decompressedData.append(Compressor::DecompressZLIB(compressedData)); - } else if (GetPlatform() == "360") { - decompressedData.append(LZX::DecompressLZX(decData, decData.size())); - } - - // Optionally write out test files for COD9. - QFile testFile("exports/" + QString("%1.out").arg(sectionIndex)); - if(testFile.open(QIODevice::WriteOnly)) { - testFile.write(decompressedData); - testFile.close(); - } - - sectionIndex++; - } - - // For COD9, write out the complete decompressed zone for testing. - QFile testFile("exports/test.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.Load(decompressedData, GetStem().section('.', 0, 0) + ".zone", FF_PLATFORM_XBOX); - SetZoneFile(std::make_shared(zoneFile)); - - return true; -} diff --git a/libs/compression/compression.pro b/libs/compression/compression.pro new file mode 100644 index 0000000..92cf04b --- /dev/null +++ b/libs/compression/compression.pro @@ -0,0 +1,27 @@ +QT += core +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += \ + lzokay.cpp \ + salsa20.cpp \ + sha1.cpp + +HEADERS += \ + lzx.h \ + lzokay.hpp \ + sha1.h \ + os_types.h \ + config_win32.h \ + compressor.h + +LIBS += \ + -L$$OUT_PWD/../libs/encryption -lencryption + +INCLUDEPATH += \ + $$PWD/../encryption + +DEPENDPATH += \ + $$PWD/../encryption + +DESTDIR = $$OUT_PWD/../ diff --git a/compressor.h b/libs/compression/compressor.h similarity index 72% rename from compressor.h rename to libs/compression/compressor.h index 11d2a8e..2e9af0c 100644 --- a/compressor.h +++ b/libs/compression/compressor.h @@ -1,11 +1,10 @@ #ifndef COMPRESSOR_H #define COMPRESSOR_H -#include "utils.h" #include "QtZlib/zlib.h" #include "lzokay.hpp" -#include "lzx.h" #include "statusbarmanager.h" +#include "ecrypt-sync.h" #include #include @@ -13,7 +12,8 @@ #include #include #include -#include +#include +#include typedef enum { EResult_LookbehindOverrun = -4, @@ -37,14 +37,11 @@ public: if (compressedData.isEmpty()) return QByteArray(); - // Set up the inflate stream. z_stream strm; memset(&strm, 0, sizeof(strm)); - // The inflate() function needs a non-const pointer; this is safe as we never modify the input. strm.next_in = reinterpret_cast(const_cast(compressedData.data())); strm.avail_in = static_cast(compressedData.size()); - // Use inflateInit(); if you want to support gzip streams, see note below. int ret = inflateInit(&strm); if (ret != Z_OK) { qWarning() << "inflateInit failed:" << zError(ret); @@ -54,17 +51,18 @@ public: QByteArray outArray; char buffer[4096]; - // Decompress until we reach the stream end. + int compressedBytesConsumed = 0; int index = 0; - do { - StatusBarManager::instance().updateProgressStatus("Processing Decompressing ZLib Data", index++, index++); + int totalCompressedSize = compressedData.size(); // n in x/n progress + do { strm.next_out = reinterpret_cast(buffer); strm.avail_out = sizeof(buffer); + int compressedBefore = strm.avail_in; // Track before calling inflate ret = inflate(&strm, Z_NO_FLUSH); - // Handle a special case: if inflate() returns Z_BUF_ERROR without - // having produced any output and with no further input, then we break out. + int compressedAfter = strm.avail_in; // Track after calling inflate + if (ret == Z_BUF_ERROR && strm.avail_in == 0) { break; } @@ -74,17 +72,29 @@ public: return QByteArray(); } - // Calculate number of bytes produced in this iteration. int bytesProduced = sizeof(buffer) - strm.avail_out; - if (bytesProduced > 0) + int bytesConsumed = compressedBefore - compressedAfter; // Track consumed compressed bytes + compressedBytesConsumed += bytesConsumed; + + if (bytesProduced > 0) { outArray.append(buffer, bytesProduced); + index++; + + StatusBarManager::instance().updateProgressStatus( + QString("Processing Decompressing ZLib Data (%1/%2 bytes)").arg(compressedBytesConsumed).arg(totalCompressedSize), + compressedBytesConsumed, totalCompressedSize); + } + } while (ret != Z_STREAM_END); + StatusBarManager::instance().updateStatus("Finished decompression!"); + inflateEnd(&strm); return outArray; } + static QByteArray DecompressLZO(const QByteArray& input) { lzokay::EResult error; @@ -408,6 +418,169 @@ public: return output; } + + static void fillIVTable(QByteArray fastFileData, QByteArray& ivTable, quint32 ivTableLength) + { + QDataStream stream(fastFileData); + stream.skipRawData(24); + + quint32 nameKeyLength = 0; + for (int i = 0; i < 32 && !stream.atEnd(); i++) { + if (!stream.atEnd() && stream.device()->peek(1).toHex() != "00") { + nameKeyLength++; + stream.skipRawData(1); + } else { + break; + } + } + + if (nameKeyLength < 32) { + stream.skipRawData(32 - nameKeyLength); + } + + if (ivTableLength < 16) { + qWarning() << "IV table length too small!"; + return; + } + + for (quint32 i = 0; i < ivTableLength - 16; i++) { + if (stream.atEnd()) { + qWarning() << "Stream ended while filling IV table!"; + return; + } + quint8 ivVal; + stream >> ivVal; + ivTable[i] = ivVal; + } + } + + static void fillIV(int index, QByteArray& ivPtr, const QByteArray& ivTable, const QVector& ivCounter) + { + if (index < 0 || index >= ivCounter.size()) { + qWarning() << "Invalid IV index: " << index; + return; + } + + int ivOffset = ((index + 4 * (ivCounter[index] - 1)) % 800) * 20; + + if (ivOffset + 8 > ivTable.size()) { + qWarning() << "IV offset out of bounds! Offset: " << ivOffset; + return; + } + + ivPtr = ivTable.mid(ivOffset, 8); + } + + + static void generateNewIV(int index, const QByteArray& hash, QByteArray& ivTable, QVector& ivCounter) + { + if (index < 0 || index >= ivCounter.size()) { + qWarning() << "Invalid index: " << index; + return; + } + + quint32 safeCounter = fmin(ivCounter[index], 800u - 1); + int ivOffset = (index + 4 * safeCounter) % 800 * 5; + + for (int i = 0; i < 20; i++) { + if (ivOffset + i >= ivTable.size()) { + qWarning() << "Index out of bounds for IV table!"; + return; + } + ivTable[ivOffset + i] ^= hash[i]; + } + + ivCounter[index]++; + } + + static QByteArray decryptFastFile(const QByteArray& fastFileData) + { + const QByteArray bo2_salsa20_key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); + + QByteArray fileData = fastFileData; + QByteArray finalFastFile; + + QByteArray ivTable(16000, 0); + fillIVTable(fileData, ivTable, 16000 - 1); + + QVector ivCounter(4, 1); + QDataStream stream(fileData); + stream.setByteOrder(QDataStream::LittleEndian); + stream.skipRawData(0x138); + + QByteArray sha1Hash(20, 0); + QByteArray ivPtr(8, 0); + int chunkIndex = 0; + + while (!stream.atEnd()) { + quint32 dataLength; + stream >> dataLength; + + if (dataLength == 0 || dataLength > fileData.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(bo2_salsa20_key.constData()), 256, 0); + ECRYPT_ivsetup(&x, reinterpret_cast(ivPtr.constData())); + + QByteArray encryptedBlock = fileData.mid(stream.device()->pos(), dataLength); + QByteArray decryptedBlock; + decryptedBlock.resize(dataLength); + + ECRYPT_decrypt_bytes(&x, reinterpret_cast(encryptedBlock.constData()), + reinterpret_cast(decryptedBlock.data()), dataLength); + + QCryptographicHash sha1(QCryptographicHash::Sha1); + sha1.addData(decryptedBlock); + sha1Hash = sha1.result(); + + z_stream strm = {}; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = static_cast(decryptedBlock.size()); + strm.next_in = reinterpret_cast(decryptedBlock.data()); + + QByteArray decompressedData; + decompressedData.resize(fmax(dataLength * 2, 4096)); + strm.avail_out = decompressedData.size(); + strm.next_out = reinterpret_cast(decompressedData.data()); + + int zReturn = inflateInit2(&strm, -15); + if (zReturn != Z_OK) { + qWarning() << "inflateInit2 failed with error code" << zReturn; + break; + } + + zReturn = inflate(&strm, Z_FINISH); + inflateEnd(&strm); + + if (zReturn != Z_STREAM_END) { + qDebug() << "Error decompressing at offset: " << stream.device()->pos() << " : " << zReturn; + decompressedData.clear(); + } else { + decompressedData.resize(strm.total_out); + } + + finalFastFile.append(decompressedData); + + generateNewIV(chunkIndex % 4, sha1Hash, ivTable, ivCounter); + + if (stream.device()->pos() + static_cast(dataLength) > fileData.size()) { + qWarning() << "Skipping past file size!"; + break; + } + + stream.skipRawData(dataLength); + chunkIndex++; + } + + return finalFastFile; + } }; diff --git a/libs/compression/config_win32.h b/libs/compression/config_win32.h new file mode 100644 index 0000000..29e4784 --- /dev/null +++ b/libs/compression/config_win32.h @@ -0,0 +1,28 @@ +/* configuration header file for compiling under Microsoft Windows */ + +/* update package version here */ + +#pragma once + +#define PACKAGE "jbig2dec" +#define VERSION "0.2" + +/* define this iff you are linking to/compiling in libpng */ +#define HAVE_LIBPNG + +#ifdef _MSC_VER /* Microsoft Visual C+*/ + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef __int64 int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +/* no uint64_t */ + +# define vsnprintf _vsnprintf +# define snprintf _snprintf + +#endif /* _MSC_VER */ diff --git a/lzokay.cpp b/libs/compression/lzokay.cpp similarity index 100% rename from lzokay.cpp rename to libs/compression/lzokay.cpp diff --git a/lzokay.hpp b/libs/compression/lzokay.hpp similarity index 100% rename from lzokay.hpp rename to libs/compression/lzokay.hpp diff --git a/lzx.h b/libs/compression/lzx.h similarity index 100% rename from lzx.h rename to libs/compression/lzx.h diff --git a/libs/compression/os_types.h b/libs/compression/os_types.h new file mode 100644 index 0000000..2006a21 --- /dev/null +++ b/libs/compression/os_types.h @@ -0,0 +1,30 @@ +/* + jbig2dec + + Copyright (c) 2002 artofcode LLC. + + This program 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. + + $Id: os_types.h,v 1.1 2002/07/20 17:23:15 giles Exp $ +*/ + +/* + indirection layer for build and platform-specific definitions + + in general, this header should insure that the stdint types are + available, and that any optional compile flags are defined if + the build system doesn't pass them directly. +*/ + +#ifdef HAVE_CONFIG_H +#include "config_types.h" +#elif defined(_WIN32) +#include "config_win32.h" +#endif + +#if defined(HAVE_STDINT_H) || defined(__MACOS__) +#include +#endif diff --git a/libs/compression/salsa20.cpp b/libs/compression/salsa20.cpp new file mode 100644 index 0000000..39349f3 --- /dev/null +++ b/libs/compression/salsa20.cpp @@ -0,0 +1,219 @@ +/* +salsa20-merged.c version 20051118 +D. J. Bernstein +Public domain. +*/ + +#include "ecrypt-sync.h" + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +void ECRYPT_init(void) +{ + return; +} + +static const char sigma[17] = "expand 32-byte k"; +static const char tau[17] = "expand 16-byte k"; + +void ECRYPT_keysetup(ECRYPT_ctx *x,const u8 *k,u32 kbits,u32 ivbits) +{ + const char *constants; + + x->input[1] = U8TO32_LITTLE(k + 0); + x->input[2] = U8TO32_LITTLE(k + 4); + x->input[3] = U8TO32_LITTLE(k + 8); + x->input[4] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[11] = U8TO32_LITTLE(k + 0); + x->input[12] = U8TO32_LITTLE(k + 4); + x->input[13] = U8TO32_LITTLE(k + 8); + x->input[14] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[5] = U8TO32_LITTLE(constants + 4); + x->input[10] = U8TO32_LITTLE(constants + 8); + x->input[15] = U8TO32_LITTLE(constants + 12); +} + +void ECRYPT_ivsetup(ECRYPT_ctx *x,const u8 *iv) +{ + x->input[6] = U8TO32_LITTLE(iv + 0); + x->input[7] = U8TO32_LITTLE(iv + 4); + x->input[8] = 0; + x->input[9] = 0; +} + +void ECRYPT_encrypt_bytes(ECRYPT_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget; + u8 tmp[64]; + unsigned int i; + + if (!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20;i > 0;i -= 2) { + x4 = XOR( x4,ROTATE(PLUS( x0,x12), 7)); + x8 = XOR( x8,ROTATE(PLUS( x4, x0), 9)); + x12 = XOR(x12,ROTATE(PLUS( x8, x4),13)); + x0 = XOR( x0,ROTATE(PLUS(x12, x8),18)); + x9 = XOR( x9,ROTATE(PLUS( x5, x1), 7)); + x13 = XOR(x13,ROTATE(PLUS( x9, x5), 9)); + x1 = XOR( x1,ROTATE(PLUS(x13, x9),13)); + x5 = XOR( x5,ROTATE(PLUS( x1,x13),18)); + x14 = XOR(x14,ROTATE(PLUS(x10, x6), 7)); + x2 = XOR( x2,ROTATE(PLUS(x14,x10), 9)); + x6 = XOR( x6,ROTATE(PLUS( x2,x14),13)); + x10 = XOR(x10,ROTATE(PLUS( x6, x2),18)); + x3 = XOR( x3,ROTATE(PLUS(x15,x11), 7)); + x7 = XOR( x7,ROTATE(PLUS( x3,x15), 9)); + x11 = XOR(x11,ROTATE(PLUS( x7, x3),13)); + x15 = XOR(x15,ROTATE(PLUS(x11, x7),18)); + x1 = XOR( x1,ROTATE(PLUS( x0, x3), 7)); + x2 = XOR( x2,ROTATE(PLUS( x1, x0), 9)); + x3 = XOR( x3,ROTATE(PLUS( x2, x1),13)); + x0 = XOR( x0,ROTATE(PLUS( x3, x2),18)); + x6 = XOR( x6,ROTATE(PLUS( x5, x4), 7)); + x7 = XOR( x7,ROTATE(PLUS( x6, x5), 9)); + x4 = XOR( x4,ROTATE(PLUS( x7, x6),13)); + x5 = XOR( x5,ROTATE(PLUS( x4, x7),18)); + x11 = XOR(x11,ROTATE(PLUS(x10, x9), 7)); + x8 = XOR( x8,ROTATE(PLUS(x11,x10), 9)); + x9 = XOR( x9,ROTATE(PLUS( x8,x11),13)); + x10 = XOR(x10,ROTATE(PLUS( x9, x8),18)); + x12 = XOR(x12,ROTATE(PLUS(x15,x14), 7)); + x13 = XOR(x13,ROTATE(PLUS(x12,x15), 9)); + x14 = XOR(x14,ROTATE(PLUS(x13,x12),13)); + x15 = XOR(x15,ROTATE(PLUS(x14,x13),18)); + } + x0 = PLUS(x0,j0); + x1 = PLUS(x1,j1); + x2 = PLUS(x2,j2); + x3 = PLUS(x3,j3); + x4 = PLUS(x4,j4); + x5 = PLUS(x5,j5); + x6 = PLUS(x6,j6); + x7 = PLUS(x7,j7); + x8 = PLUS(x8,j8); + x9 = PLUS(x9,j9); + x10 = PLUS(x10,j10); + x11 = PLUS(x11,j11); + x12 = PLUS(x12,j12); + x13 = PLUS(x13,j13); + x14 = PLUS(x14,j14); + x15 = PLUS(x15,j15); + + x0 = XOR(x0,U8TO32_LITTLE(m + 0)); + x1 = XOR(x1,U8TO32_LITTLE(m + 4)); + x2 = XOR(x2,U8TO32_LITTLE(m + 8)); + x3 = XOR(x3,U8TO32_LITTLE(m + 12)); + x4 = XOR(x4,U8TO32_LITTLE(m + 16)); + x5 = XOR(x5,U8TO32_LITTLE(m + 20)); + x6 = XOR(x6,U8TO32_LITTLE(m + 24)); + x7 = XOR(x7,U8TO32_LITTLE(m + 28)); + x8 = XOR(x8,U8TO32_LITTLE(m + 32)); + x9 = XOR(x9,U8TO32_LITTLE(m + 36)); + x10 = XOR(x10,U8TO32_LITTLE(m + 40)); + x11 = XOR(x11,U8TO32_LITTLE(m + 44)); + x12 = XOR(x12,U8TO32_LITTLE(m + 48)); + x13 = XOR(x13,U8TO32_LITTLE(m + 52)); + x14 = XOR(x14,U8TO32_LITTLE(m + 56)); + x15 = XOR(x15,U8TO32_LITTLE(m + 60)); + + j8 = PLUSONE(j8); + if (!j8) { + j9 = PLUSONE(j9); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x4); + U32TO8_LITTLE(c + 20,x5); + U32TO8_LITTLE(c + 24,x6); + U32TO8_LITTLE(c + 28,x7); + U32TO8_LITTLE(c + 32,x8); + U32TO8_LITTLE(c + 36,x9); + U32TO8_LITTLE(c + 40,x10); + U32TO8_LITTLE(c + 44,x11); + U32TO8_LITTLE(c + 48,x12); + U32TO8_LITTLE(c + 52,x13); + U32TO8_LITTLE(c + 56,x14); + U32TO8_LITTLE(c + 60,x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) ctarget[i] = c[i]; + } + x->input[8] = j8; + x->input[9] = j9; + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} + +void ECRYPT_decrypt_bytes(ECRYPT_ctx *x,const u8 *c,u8 *m,u32 bytes) +{ + ECRYPT_encrypt_bytes(x,c,m,bytes); +} + +void ECRYPT_keystream_bytes(ECRYPT_ctx *x,u8 *stream,u32 bytes) +{ + u32 i; + for (i = 0;i < bytes;++i) stream[i] = 0; + ECRYPT_encrypt_bytes(x,stream,stream,bytes); +} diff --git a/libs/compression/sha1.cpp b/libs/compression/sha1.cpp new file mode 100644 index 0000000..e2f9109 --- /dev/null +++ b/libs/compression/sha1.cpp @@ -0,0 +1,259 @@ +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +----------------- +Modified 7/98 +By James H. Brown +Still 100% Public Domain + +Corrected a problem which generated improper hash values on 16 bit machines +Routine SHA1Update changed from + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int +len) +to + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned +long len) + +The 'len' parameter was declared an int which works fine on 32 bit machines. +However, on 16 bit machines an int is too small for the shifts being done +against +it. This caused the hash function to generate incorrect values if len was +greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). + +Since the file IO in main() reads 16K at a time, any file 8K or larger would +be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million +"a"s). + +I also changed the declaration of variables i & j in SHA1Update to +unsigned long from unsigned int for the same reason. + +These changes should make no difference to any 32 bit implementations since +an +int and a long are the same size in those environments. + +-- +I also corrected a few compiler warnings generated by Borland C. +1. Added #include for exit() prototype +2. Removed unused variable 'j' in SHA1Final +3. Changed exit(0) to return(0) at end of main. + +ALL changes I made can be located by searching for comments containing 'JHB' +----------------- +Modified 8/98 +By Steve Reid +Still 100% public domain + +1- Removed #include and used return() instead of exit() +2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) +3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net + +----------------- +Modified 4/01 +By Saul Kravitz +Still 100% PD +Modified to run on Compaq Alpha hardware. + +----------------- +Modified 07/2002 +By Ralph Giles +Still 100% public domain +modified for use with stdint types, autoconf +code cleanup, removed attribution comments +switched SHA1Final() argument order for consistency +use SHA1_ prefix for public api +move public api to sha1.h +*/ + +/* +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +#define SHA1HANDSOFF + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "os_types.h" +#include "sha1.h" + +void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +/* FIXME: can we do this in an endian-proof way? */ +#ifdef WORDS_BIGENDIAN +#define blk0(i) block->l[i] +#else +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +#ifdef VERBOSE /* SAK */ +void SHAPrintContext(SHA1_CTX *context, char *msg){ + printf("%s (%d,%d) %x %x %x %x %x\n", + msg, + context->count[0], context->count[1], + context->state[0], + context->state[1], + context->state[2], + context->state[3], + context->state[4]); +} +#endif /* VERBOSE */ + +/* Hash a single 512-bit block. This is the core of the algorithm. */ +void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e; + typedef union { + uint8_t c[64]; + uint32_t l[16]; + } CHAR64LONG16; + CHAR64LONG16* block; + +#ifdef SHA1HANDSOFF + static uint8_t workspace[64]; + block = (CHAR64LONG16*)workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16*)buffer; +#endif + + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ +void SHA1_Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ +void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len) +{ + size_t i, j; + +#ifdef VERBOSE + SHAPrintContext(context, "before"); +#endif + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1_Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1_Transform(context->state, data + i); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); + +#ifdef VERBOSE + SHAPrintContext(context, "after "); +#endif +} + + +/* Add padding and return the message digest. */ +void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) +{ + uint32_t i; + uint8_t finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1_Update(context, (uint8_t *)"\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1_Update(context, (uint8_t *)"\0", 1); + } + SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ + for (i = 0; i < SHA1_DIGEST_SIZE; i++) { + digest[i] = (uint8_t) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + + /* Wipe variables */ + i = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(finalcount, 0, 8); /* SWR */ + +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ + SHA1_Transform(context->state, context->buffer); +#endif +} diff --git a/libs/compression/sha1.h b/libs/compression/sha1.h new file mode 100644 index 0000000..055a3db --- /dev/null +++ b/libs/compression/sha1.h @@ -0,0 +1,29 @@ +/* public api for steve reid's public domain SHA-1 implementation */ +/* this file is in the public domain */ + +#include "config_win32.h" + +#ifndef __SHA1_H +#define __SHA1_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint32_t state[5]; + uint32_t count[2]; + uint8_t buffer[64]; +} SHA1_CTX; + +#define SHA1_DIGEST_SIZE 20 + +void SHA1_Init(SHA1_CTX* context); +void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len); +void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]); + +#ifdef __cplusplus +} +#endif + +#endif /* __SHA1_H */ diff --git a/libs/core/core.pro b/libs/core/core.pro new file mode 100644 index 0000000..79669a7 --- /dev/null +++ b/libs/core/core.pro @@ -0,0 +1,16 @@ +QT += core widgets +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += \ + logmanager.cpp \ + statusbarmanager.cpp + +HEADERS += \ + enums.h \ + logmanager.h \ + stringutils.h \ + utils.h \ + statusbarmanager.h + +DESTDIR = $$OUT_PWD/../ diff --git a/enums.h b/libs/core/enums.h similarity index 100% rename from enums.h rename to libs/core/enums.h diff --git a/libs/core/logmanager.cpp b/libs/core/logmanager.cpp new file mode 100644 index 0000000..09b8147 --- /dev/null +++ b/libs/core/logmanager.cpp @@ -0,0 +1,13 @@ +#include "logmanager.h" + +void LogManager::addEntry(const QString &entry) { + emit entryAdded(entry); +} + +void LogManager::addError(const QString &error) { + emit entryAdded(QString("ERROR: " + error)); +} + +void LogManager::addLine() { + emit entryAdded(""); +} diff --git a/libs/core/logmanager.h b/libs/core/logmanager.h new file mode 100644 index 0000000..d3161d5 --- /dev/null +++ b/libs/core/logmanager.h @@ -0,0 +1,31 @@ +#ifndef LOGMANAGER_H +#define LOGMANAGER_H + +#include +#include + +class LogManager : public QObject +{ + Q_OBJECT + +public: + static LogManager &instance() { + static LogManager instance; + return instance; + } + + void addEntry(const QString &entry); + void addError(const QString &error); + void addLine(); + +signals: + void entryAdded(const QString &entry); + +private: + LogManager() {} // Private constructor for singleton + ~LogManager() {} + + Q_DISABLE_COPY(LogManager) +}; + +#endif // LOGMANAGER_H diff --git a/statusbarmanager.cpp b/libs/core/statusbarmanager.cpp similarity index 100% rename from statusbarmanager.cpp rename to libs/core/statusbarmanager.cpp diff --git a/statusbarmanager.h b/libs/core/statusbarmanager.h similarity index 100% rename from statusbarmanager.h rename to libs/core/statusbarmanager.h diff --git a/libs/core/stringutils.h b/libs/core/stringutils.h new file mode 100644 index 0000000..e69de29 diff --git a/utils.h b/libs/core/utils.h similarity index 100% rename from utils.h rename to libs/core/utils.h diff --git a/dds_structs.h b/libs/ddsfile/dds_structs.h similarity index 100% rename from dds_structs.h rename to libs/ddsfile/dds_structs.h diff --git a/ddsfile.cpp b/libs/ddsfile/ddsfile.cpp similarity index 99% rename from ddsfile.cpp rename to libs/ddsfile/ddsfile.cpp index bae7cec..bc99b47 100644 --- a/ddsfile.cpp +++ b/libs/ddsfile/ddsfile.cpp @@ -1,6 +1,6 @@ #include "ddsfile.h" -#include "enums.h" #include "iwifile.h" +#include "qdir.h" DDSPixelFormat DDSFile::CalculatePixelFormat(quint8 aIWIFormat) { DDSPixelFormat ddsPixelFormat = {}; diff --git a/ddsfile.h b/libs/ddsfile/ddsfile.h similarity index 97% rename from ddsfile.h rename to libs/ddsfile/ddsfile.h index 5ccf0c7..a807e62 100644 --- a/ddsfile.h +++ b/libs/ddsfile/ddsfile.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include struct DDSPixelFormat { quint32 size; diff --git a/libs/ddsfile/ddsfile.pro b/libs/ddsfile/ddsfile.pro new file mode 100644 index 0000000..57825e5 --- /dev/null +++ b/libs/ddsfile/ddsfile.pro @@ -0,0 +1,27 @@ +QT += core +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += \ + ddsfile.cpp + +HEADERS += \ + dds_structs.h \ + ddsfile.h \ + enums.h + +LIBS += \ + -L$$PWD/../../third_party/devil_sdk/lib/ -lDevIL \ + -L$$PWD/../../third_party/devil_sdk/lib/ -lILU \ + -L$$PWD/../../third_party/devil_sdk/lib/ -lILUT \ + -L$$OUT_PWD/../libs/iwifile -liwifile + +INCLUDEPATH += \ + $$PWD/../iwifile/ \ + $$PWD/../../third_party/devil_sdk/include/ + +DEPENDPATH += \ + $$PWD/../iwifile/ \ + $$PWD/../../third_party/devil_sdk/include/ + +DESTDIR = $$OUT_PWD/../ diff --git a/libs/ddsfile/enums.h b/libs/ddsfile/enums.h new file mode 100644 index 0000000..b5f8204 --- /dev/null +++ b/libs/ddsfile/enums.h @@ -0,0 +1,876 @@ +#ifndef ENUMS_H +#define ENUMS_H + +#include + +enum FF_PLATFORM { + FF_PLATFORM_NONE = 0x00, // No platform + FF_PLATFORM_XBOX = 0x01, // Xbox 360 + FF_PLATFORM_PS3 = 0x02, // Playstation 3 + FF_PLATFORM_PC = 0x03 // PC +}; + +enum FF_GAME { + FF_GAME_NONE = 0x00, // No game + FF_GAME_COD1 = 0x01, // Call of Duty + FF_GAME_COD2 = 0x02, // Call of Duty 2 + FF_GAME_COD3 = 0x03, // Call of Duty 3 + FF_GAME_COD4 = 0x04, // Modern Warware 1 + FF_GAME_COD5 = 0x05, // World at War + FF_GAME_COD6 = 0x06, // Modern Warfare 2 + FF_GAME_COD7 = 0x07, // Black Ops 1 + FF_GAME_COD8 = 0x08, // Modern Warfare 3 + FF_GAME_COD9 = 0x09, // Black Ops 2 +}; + +enum IWI_VERSION { + IWI_VERSION_COD2 = 0x05, // 05 CoD2 + IWI_VERSION_COD4 = 0x06, // 06 CoD4 + IWI_VERSION_COD5 = 0x06, // 06 CoD5 + IWI_VERSION_CODMW2 = 0x08, // 08 CoDMW2 + IWI_VERSION_CODMW3 = 0x08, // 08 CoDMW3 + IWI_VERSION_CODBO1 = 0x0D, // 13 CoDBO1 + IWI_VERSION_CODBO2 = 0x1B, // 27 CoDBO2 +}; + +enum IWI_FORMAT { + // IWI Format + IWI_FORMAT_ARGB32 = 0x01, // 01 ARGB32 + IWI_FORMAT_RGB24 = 0x02, // 02 RGB24 + IWI_FORMAT_GA16 = 0x03, // 03 GA16 + IWI_FORMAT_A8 = 0x04, // 04 A8 + IWI_FORMAT_DXT1 = 0x0B, // 11 DXT1 + IWI_FORMAT_DXT3 = 0x0C, // 12 DXT3 + IWI_FORMAT_DXT5 = 0x0D // 13 DXT5 +}; + +enum DDS_FLAGS { + DDSD_CAPS = 0x1, + DDSD_HEIGHT = 0x2, + DDSD_WIDTH = 0x4, + DDSD_PITCH = 0x8, + DDSD_PIXELFORMAT = 0x1000, + DDSD_MIPMAPCOUNT = 0x20000, + DDSD_LINEARSIZE = 0x80000, + DDSD_DEPTH = 0x800000 +}; + +enum DDS_PIXELFORMAT_FLAGS { + DDPF_ALPHAPIXELS = 0x1, + DDPF_ALPHA = 0x2, + DDPF_FOURCC = 0x4, + DDPF_RGB = 0x40, + DDPF_YUV = 0x200, + DDPF_LUMINANCE = 0x20000 +}; + +enum DDS_CAPS_FLAGS { + DDSCAPS_COMPLEX = 0x8, + DDSCAPS_MIPMAP = 0x400000, + DDSCAPS_TEXTURE = 0x1000 +}; + +enum DDS_CAPS2_FLAGS { + DDSCAPS2_CUBEMAP = 0x200, // Indicates a cubemap. + DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, + DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, + DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, + DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, + DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, + DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, + DDSCAPS2_VOLUME = 0x200000 // Indicates that the texture is a volume texture. +}; + +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 FF_COMPANY { + COMPANY_NONE = 0x00, + COMPANY_INFINITY_WARD = 0x01, + COMPANY_TREYARCH = 0x02, + COMPANY_SLEDGEHAMMER = 0x03, + COMPANY_NEVERSOFT = 0x04 +}; + +enum FF_FILETYPE { + FILETYPE_NONE = 0x00, + FILETYPE_FAST_FILE = 0x01 +}; + +enum FF_SIGNAGE { + SIGNAGE_NONE = 0x00, + SIGNAGE_SIGNED = 0x01, + SIGNAGE_UNSIGNED = 0x02 +}; + +enum IMAGE_COMPRESSION { + COMPRESSION_NONE = 0x00, + COMPRESSION_DXT1 = 0x01, + COMPRESSION_DXT3 = 0x02, + COMPRESSION_DXT5 = 0x03 +}; +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 +}; + +enum SHADER_TYPE { + SHADER_NONE = 0x00, + SHADER_PIXEL = 0x01, + SHADER_VERTEX = 0x02 +}; + +enum SHADER_OPCODE { + OPCODE_Nop, + OPCODE_Mov, + OPCODE_Add, + OPCODE_Sub, + OPCODE_Mad, + OPCODE_Mul, + OPCODE_Rcp, + OPCODE_Rsq, + OPCODE_Dp3, + OPCODE_Dp4, + OPCODE_Min, + OPCODE_Max, + OPCODE_Slt, + OPCODE_Sge, + OPCODE_Exp, + OPCODE_Log, + OPCODE_Lit, + OPCODE_Dst, + OPCODE_Lrp, + OPCODE_Frc, + OPCODE_M4x4, + OPCODE_M4x3, + OPCODE_M3x4, + OPCODE_M3x3, + OPCODE_M3x2, + OPCODE_Call, + OPCODE_CallNZ, + OPCODE_Loop, + OPCODE_Ret, + OPCODE_EndLoop, + OPCODE_Label, + OPCODE_Dcl, + OPCODE_Pow, + OPCODE_Crs, + OPCODE_Sgn, + OPCODE_Abs, + OPCODE_Nrm, + OPCODE_SinCos, + OPCODE_Rep, + OPCODE_EndRep, + OPCODE_If, + OPCODE_IfC, + OPCODE_Else, + OPCODE_Endif, + OPCODE_Break, + OPCODE_BreakC, + OPCODE_MovA, + OPCODE_DefB, + OPCODE_DefI, + OPCODE_TexCoord = 64, + OPCODE_TexKill, + OPCODE_Tex, + OPCODE_TexBem, + OPCODE_TexBeml, + OPCODE_TexReg2AR, + OPCODE_TexReg2GB, + OPCODE_TeXM3x2Pad, + OPCODE_TexM3x2Tex, + OPCODE_TeXM3x3Pad, + OPCODE_TexM3x3Tex, + OPCODE_TexM3x3Diff, + OPCODE_TexM3x3Spec, + OPCODE_TexM3x3VSpec, + OPCODE_ExpP, + OPCODE_LogP, + OPCODE_Cnd, + OPCODE_Def, + OPCODE_TexReg2RGB, + OPCODE_TexDP3Tex, + OPCODE_TexM3x2Depth, + OPCODE_TexDP3, + OPCODE_TexM3x3, + OPCODE_TexDepth, + OPCODE_Cmp, + OPCODE_Bem, + OPCODE_DP2Add, + OPCODE_DSX, + OPCODE_DSY, + OPCODE_TexLDD, + OPCODE_SetP, + OPCODE_TexLDL, + OPCODE_Breakp, + OPCODE_Phase = 0xFFFD, + OPCODE_Comment = 0xFFFE, + OPCODE_End = 0xFFFF +}; + +#define SECTION_TYPE_INFO 1 +#define SECTION_TYPE_DATA 2 + +#define IPAK_SECTION_ENTRY 1 +#define IPAK_SECTION_DATA 2 +#define IPAK_SECTION_METADATA 3 + +#define FORMAT_DXT1 0 +#define FORMAT_DXT3 1 +#define FORMAT_DXT5 2 +#define FORMAT_A8R8G8B8 3 + +// 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) +#endif // ENUMS_H diff --git a/libs/encryption/ecrypt-config.h b/libs/encryption/ecrypt-config.h new file mode 100644 index 0000000..096358a --- /dev/null +++ b/libs/encryption/ecrypt-config.h @@ -0,0 +1,272 @@ +/* ecrypt-config.h */ + +/* *** Normally, it should not be necessary to edit this file. *** */ + +#ifndef ECRYPT_CONFIG +#define ECRYPT_CONFIG + +/* ------------------------------------------------------------------------- */ + +/* Guess the endianness of the target architecture. */ + +/* + * The LITTLE endian machines: + */ +#if defined(__ultrix) /* Older MIPS */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__alpha) /* Alpha */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(i386) /* x86 (gcc) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__i386) /* x86 (gcc) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(_M_IX86) /* x86 (MSC, Borland) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(_MSC_VER) /* x86 (surely MSC) */ +#define ECRYPT_LITTLE_ENDIAN +#elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */ +#define ECRYPT_LITTLE_ENDIAN + +/* + * The BIG endian machines: + */ +#elif defined(sun) /* Newer Sparc's */ +#define ECRYPT_BIG_ENDIAN +#elif defined(__ppc__) /* PowerPC */ +#define ECRYPT_BIG_ENDIAN + +/* + * Finally machines with UNKNOWN endianness: + */ +#elif defined (_AIX) /* RS6000 */ +#define ECRYPT_UNKNOWN +#elif defined(__hpux) /* HP-PA */ +#define ECRYPT_UNKNOWN +#elif defined(__aux) /* 68K */ +#define ECRYPT_UNKNOWN +#elif defined(__dgux) /* 88K (but P6 in latest boxes) */ +#define ECRYPT_UNKNOWN +#elif defined(__sgi) /* Newer MIPS */ +#define ECRYPT_UNKNOWN +#else /* Any other processor */ +#define ECRYPT_UNKNOWN +#endif + +/* ------------------------------------------------------------------------- */ + +/* + * Find minimal-width types to store 8-bit, 16-bit, 32-bit, and 64-bit + * integers. + * + * Note: to enable 64-bit types on 32-bit compilers, it might be + * necessary to switch from ISO C90 mode to ISO C99 mode (e.g., gcc + * -std=c99). + */ + +#include + +/* --- check char --- */ + +#if (UCHAR_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T char +#define U8C(v) (v##U) + +#if (UCHAR_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (UCHAR_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T char +#define U16C(v) (v##U) +#endif + +#if (UCHAR_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T char +#define U32C(v) (v##U) +#endif + +#if (UCHAR_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T char +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check short --- */ + +#if (USHRT_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T short +#define U8C(v) (v##U) + +#if (USHRT_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (USHRT_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T short +#define U16C(v) (v##U) +#endif + +#if (USHRT_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T short +#define U32C(v) (v##U) +#endif + +#if (USHRT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T short +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check int --- */ + +#if (UINT_MAX / 0xFU > 0xFU) +#ifndef I8T +#define I8T int +#define U8C(v) (v##U) + +#if (ULONG_MAX == 0xFFU) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (UINT_MAX / 0xFFU > 0xFFU) +#ifndef I16T +#define I16T int +#define U16C(v) (v##U) +#endif + +#if (UINT_MAX / 0xFFFFU > 0xFFFFU) +#ifndef I32T +#define I32T int +#define U32C(v) (v##U) +#endif + +#if (UINT_MAX / 0xFFFFFFFFU > 0xFFFFFFFFU) +#ifndef I64T +#define I64T int +#define U64C(v) (v##U) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check long --- */ + +#if (ULONG_MAX / 0xFUL > 0xFUL) +#ifndef I8T +#define I8T long +#define U8C(v) (v##UL) + +#if (ULONG_MAX == 0xFFUL) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (ULONG_MAX / 0xFFUL > 0xFFUL) +#ifndef I16T +#define I16T long +#define U16C(v) (v##UL) +#endif + +#if (ULONG_MAX / 0xFFFFUL > 0xFFFFUL) +#ifndef I32T +#define I32T long +#define U32C(v) (v##UL) +#endif + +#if (ULONG_MAX / 0xFFFFFFFFUL > 0xFFFFFFFFUL) +#ifndef I64T +#define I64T long +#define U64C(v) (v##UL) +#define ECRYPT_NATIVE64 +#endif + +#endif +#endif +#endif +#endif + +/* --- check long long --- */ + +#ifdef ULLONG_MAX + +#if (ULLONG_MAX / 0xFULL > 0xFULL) +#ifndef I8T +#define I8T long long +#define U8C(v) (v##ULL) + +#if (ULLONG_MAX == 0xFFULL) +#define ECRYPT_I8T_IS_BYTE +#endif + +#endif + +#if (ULLONG_MAX / 0xFFULL > 0xFFULL) +#ifndef I16T +#define I16T long long +#define U16C(v) (v##ULL) +#endif + +#if (ULLONG_MAX / 0xFFFFULL > 0xFFFFULL) +#ifndef I32T +#define I32T long long +#define U32C(v) (v##ULL) +#endif + +#if (ULLONG_MAX / 0xFFFFFFFFULL > 0xFFFFFFFFULL) +#ifndef I64T +#define I64T long long +#define U64C(v) (v##ULL) +#endif + +#endif +#endif +#endif +#endif + +#endif + +/* --- check __int64 --- */ + +#ifdef _UI64_MAX + +#if (_UI64_MAX / 0xFFFFFFFFui64 > 0xFFFFFFFFui64) +#ifndef I64T +#define I64T __int64 +#define U64C(v) (v##ui64) +#endif + +#endif + +#endif + +/* ------------------------------------------------------------------------- */ + +#endif diff --git a/libs/encryption/ecrypt-machine.h b/libs/encryption/ecrypt-machine.h new file mode 100644 index 0000000..3e550d0 --- /dev/null +++ b/libs/encryption/ecrypt-machine.h @@ -0,0 +1,46 @@ +/* ecrypt-machine.h */ + +/* + * This file is included by 'ecrypt-portable.h'. It allows to override + * the default macros for specific platforms. Please carefully check + * the machine code generated by your compiler (with optimisations + * turned on) before deciding to edit this file. + */ + +/* ------------------------------------------------------------------------- */ + +#if (defined(ECRYPT_DEFAULT_ROT) && !defined(ECRYPT_MACHINE_ROT)) + +#define ECRYPT_MACHINE_ROT + +#if (defined(WIN32) && defined(_MSC_VER)) + +#undef ROTL32 +#undef ROTR32 +#undef ROTL64 +#undef ROTR64 + +#include + +#define ROTL32(v, n) _lrotl(v, n) +#define ROTR32(v, n) _lrotr(v, n) +#define ROTL64(v, n) _rotl64(v, n) +#define ROTR64(v, n) _rotr64(v, n) + +#endif + +#endif + +/* ------------------------------------------------------------------------- */ + +#if (defined(ECRYPT_DEFAULT_SWAP) && !defined(ECRYPT_MACHINE_SWAP)) + +#define ECRYPT_MACHINE_SWAP + +/* + * If you want to overwrite the default swap macros, put it here. And so on. + */ + +#endif + +/* ------------------------------------------------------------------------- */ diff --git a/libs/encryption/ecrypt-portable.h b/libs/encryption/ecrypt-portable.h new file mode 100644 index 0000000..972e7e9 --- /dev/null +++ b/libs/encryption/ecrypt-portable.h @@ -0,0 +1,303 @@ +/* ecrypt-portable.h */ + +/* + * WARNING: the conversions defined below are implemented as macros, + * and should be used carefully. They should NOT be used with + * parameters which perform some action. E.g., the following two lines + * are not equivalent: + * + * 1) ++x; y = ROTL32(x, n); + * 2) y = ROTL32(++x, n); + */ + +/* + * *** Please do not edit this file. *** + * + * The default macros can be overridden for specific architectures by + * editing 'ecrypt-machine.h'. + */ + +#ifndef ECRYPT_PORTABLE +#define ECRYPT_PORTABLE + +#include "ecrypt-config.h" + +/* ------------------------------------------------------------------------- */ + +/* + * The following types are defined (if available): + * + * u8: unsigned integer type, at least 8 bits + * u16: unsigned integer type, at least 16 bits + * u32: unsigned integer type, at least 32 bits + * u64: unsigned integer type, at least 64 bits + * + * s8, s16, s32, s64 -> signed counterparts of u8, u16, u32, u64 + * + * The selection of minimum-width integer types is taken care of by + * 'ecrypt-config.h'. Note: to enable 64-bit types on 32-bit + * compilers, it might be necessary to switch from ISO C90 mode to ISO + * C99 mode (e.g., gcc -std=c99). + */ + +#ifdef I8T +typedef signed I8T s8; +typedef unsigned I8T u8; +#endif + +#ifdef I16T +typedef signed I16T s16; +typedef unsigned I16T u16; +#endif + +#ifdef I32T +typedef signed I32T s32; +typedef unsigned I32T u32; +#endif + +#ifdef I64T +typedef signed I64T s64; +typedef unsigned I64T u64; +#endif + +/* + * The following macros are used to obtain exact-width results. + */ + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U16V(v) ((u16)(v) & U16C(0xFFFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) +#define U64V(v) ((u64)(v) & U64C(0xFFFFFFFFFFFFFFFF)) + +/* ------------------------------------------------------------------------- */ + +/* + * The following macros return words with their bits rotated over n + * positions to the left/right. + */ + +#define ECRYPT_DEFAULT_ROT + +#define ROTL8(v, n) \ +(U8V((v) << (n)) | ((v) >> (8 - (n)))) + +#define ROTL16(v, n) \ + (U16V((v) << (n)) | ((v) >> (16 - (n)))) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define ROTL64(v, n) \ + (U64V((v) << (n)) | ((v) >> (64 - (n)))) + +#define ROTR8(v, n) ROTL8(v, 8 - (n)) +#define ROTR16(v, n) ROTL16(v, 16 - (n)) +#define ROTR32(v, n) ROTL32(v, 32 - (n)) +#define ROTR64(v, n) ROTL64(v, 64 - (n)) + +#include "ecrypt-machine.h" + +/* ------------------------------------------------------------------------- */ + +/* + * The following macros return a word with bytes in reverse order. + */ + +#define ECRYPT_DEFAULT_SWAP + +#define SWAP16(v) \ + ROTL16(v, 8) + +#define SWAP32(v) \ + ((ROTL32(v, 8) & U32C(0x00FF00FF)) | \ + (ROTL32(v, 24) & U32C(0xFF00FF00))) + +#ifdef ECRYPT_NATIVE64 +#define SWAP64(v) \ + ((ROTL64(v, 8) & U64C(0x000000FF000000FF)) | \ + (ROTL64(v, 24) & U64C(0x0000FF000000FF00)) | \ + (ROTL64(v, 40) & U64C(0x00FF000000FF0000)) | \ + (ROTL64(v, 56) & U64C(0xFF000000FF000000))) +#else +#define SWAP64(v) \ + (((u64)SWAP32(U32V(v)) << 32) | (u64)SWAP32(U32V(v >> 32))) +#endif + +#include "ecrypt-machine.h" + +#define ECRYPT_DEFAULT_WTOW + +#ifdef ECRYPT_LITTLE_ENDIAN +#define U16TO16_LITTLE(v) (v) +#define U32TO32_LITTLE(v) (v) +#define U64TO64_LITTLE(v) (v) + +#define U16TO16_BIG(v) SWAP16(v) +#define U32TO32_BIG(v) SWAP32(v) +#define U64TO64_BIG(v) SWAP64(v) +#endif + +#ifdef ECRYPT_BIG_ENDIAN +#define U16TO16_LITTLE(v) SWAP16(v) +#define U32TO32_LITTLE(v) SWAP32(v) +#define U64TO64_LITTLE(v) SWAP64(v) + +#define U16TO16_BIG(v) (v) +#define U32TO32_BIG(v) (v) +#define U64TO64_BIG(v) (v) +#endif + +#include "ecrypt-machine.h" + +/* + * The following macros load words from an array of bytes with + * different types of endianness, and vice versa. + */ + +#define ECRYPT_DEFAULT_BTOW + +#if (!defined(ECRYPT_UNKNOWN) && defined(ECRYPT_I8T_IS_BYTE)) + +#define U8TO16_LITTLE(p) U16TO16_LITTLE(((u16*)(p))[0]) +#define U8TO32_LITTLE(p) U32TO32_LITTLE(((u32*)(p))[0]) +#define U8TO64_LITTLE(p) U64TO64_LITTLE(((u64*)(p))[0]) + +#define U8TO16_BIG(p) U16TO16_BIG(((u16*)(p))[0]) +#define U8TO32_BIG(p) U32TO32_BIG(((u32*)(p))[0]) +#define U8TO64_BIG(p) U64TO64_BIG(((u64*)(p))[0]) + +#define U16TO8_LITTLE(p, v) (((u16*)(p))[0] = U16TO16_LITTLE(v)) +#define U32TO8_LITTLE(p, v) (((u32*)(p))[0] = U32TO32_LITTLE(v)) +#define U64TO8_LITTLE(p, v) (((u64*)(p))[0] = U64TO64_LITTLE(v)) + +#define U16TO8_BIG(p, v) (((u16*)(p))[0] = U16TO16_BIG(v)) +#define U32TO8_BIG(p, v) (((u32*)(p))[0] = U32TO32_BIG(v)) +#define U64TO8_BIG(p, v) (((u64*)(p))[0] = U64TO64_BIG(v)) + +#else + +#define U8TO16_LITTLE(p) \ +(((u16)((p)[0]) ) | \ + ((u16)((p)[1]) << 8)) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_LITTLE(p) \ + (((u64)((p)[0]) ) | \ + ((u64)((p)[1]) << 8) | \ + ((u64)((p)[2]) << 16) | \ + ((u64)((p)[3]) << 24) | \ + ((u64)((p)[4]) << 32) | \ + ((u64)((p)[5]) << 40) | \ + ((u64)((p)[6]) << 48) | \ + ((u64)((p)[7]) << 56)) +#else +#define U8TO64_LITTLE(p) \ + ((u64)U8TO32_LITTLE(p) | ((u64)U8TO32_LITTLE((p) + 4) << 32)) +#endif + +#define U8TO16_BIG(p) \ + (((u16)((p)[0]) << 8) | \ + ((u16)((p)[1]) )) + +#define U8TO32_BIG(p) \ + (((u32)((p)[0]) << 24) | \ + ((u32)((p)[1]) << 16) | \ + ((u32)((p)[2]) << 8) | \ + ((u32)((p)[3]) )) + +#ifdef ECRYPT_NATIVE64 +#define U8TO64_BIG(p) \ + (((u64)((p)[0]) << 56) | \ + ((u64)((p)[1]) << 48) | \ + ((u64)((p)[2]) << 40) | \ + ((u64)((p)[3]) << 32) | \ + ((u64)((p)[4]) << 24) | \ + ((u64)((p)[5]) << 16) | \ + ((u64)((p)[6]) << 8) | \ + ((u64)((p)[7]) )) +#else +#define U8TO64_BIG(p) \ + (((u64)U8TO32_BIG(p) << 32) | (u64)U8TO32_BIG((p) + 4)) +#endif + +#define U16TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ +} while (0) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + (p)[4] = U8V((v) >> 32); \ + (p)[5] = U8V((v) >> 40); \ + (p)[6] = U8V((v) >> 48); \ + (p)[7] = U8V((v) >> 56); \ + } while (0) +#else +#define U64TO8_LITTLE(p, v) \ + do { \ + U32TO8_LITTLE((p), U32V((v) )); \ + U32TO8_LITTLE((p) + 4, U32V((v) >> 32)); \ + } while (0) +#endif + +#define U16TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + } while (0) + +#define U32TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 24); \ + (p)[1] = U8V((v) >> 16); \ + (p)[2] = U8V((v) >> 8); \ + (p)[3] = U8V((v) ); \ + } while (0) + +#ifdef ECRYPT_NATIVE64 +#define U64TO8_BIG(p, v) \ + do { \ + (p)[0] = U8V((v) >> 56); \ + (p)[1] = U8V((v) >> 48); \ + (p)[2] = U8V((v) >> 40); \ + (p)[3] = U8V((v) >> 32); \ + (p)[4] = U8V((v) >> 24); \ + (p)[5] = U8V((v) >> 16); \ + (p)[6] = U8V((v) >> 8); \ + (p)[7] = U8V((v) ); \ +} while (0) +#else +#define U64TO8_BIG(p, v) \ + do { \ + U32TO8_BIG((p), U32V((v) >> 32)); \ + U32TO8_BIG((p) + 4, U32V((v) )); \ +} while (0) +#endif + +#endif + +#include "ecrypt-machine.h" + +/* ------------------------------------------------------------------------- */ + +#endif diff --git a/libs/encryption/ecrypt-sync.h b/libs/encryption/ecrypt-sync.h new file mode 100644 index 0000000..9027877 --- /dev/null +++ b/libs/encryption/ecrypt-sync.h @@ -0,0 +1,279 @@ +/* ecrypt-sync.h */ + +/* + * Header file for synchronous stream ciphers without authentication + * mechanism. + * + * *** Please only edit parts marked with "[edit]". *** + */ + +#ifndef ECRYPT_SYNC +#define ECRYPT_SYNC + +#include "ecrypt-portable.h" + +/* ------------------------------------------------------------------------- */ + +/* Cipher parameters */ + +/* + * The name of your cipher. + */ +#define ECRYPT_NAME "Salsa20" /* [edit] */ +#define ECRYPT_PROFILE "S!_H." + +/* + * Specify which key and IV sizes are supported by your cipher. A user + * should be able to enumerate the supported sizes by running the + * following code: + * + * for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i) + * { + * keysize = ECRYPT_KEYSIZE(i); + * + * ... + * } + * + * All sizes are in bits. + */ + +#define ECRYPT_MAXKEYSIZE 256 /* [edit] */ +#define ECRYPT_KEYSIZE(i) (128 + (i)*128) /* [edit] */ + +#define ECRYPT_MAXIVSIZE 64 /* [edit] */ +#define ECRYPT_IVSIZE(i) (64 + (i)*64) /* [edit] */ + +/* ------------------------------------------------------------------------- */ + +/* Data structures */ + +/* + * ECRYPT_ctx is the structure containing the representation of the + * internal state of your cipher. + */ + +typedef struct +{ + u32 input[16]; /* could be compressed */ + /* + * [edit] + * + * Put here all state variable needed during the encryption process. + */ +} ECRYPT_ctx; + +/* ------------------------------------------------------------------------- */ + +/* Mandatory functions */ + +/* + * Key and message independent initialization. This function will be + * called once when the program starts (e.g., to build expanded S-box + * tables). + */ +void ECRYPT_init(); + +/* + * Key setup. It is the user's responsibility to select the values of + * keysize and ivsize from the set of supported values specified + * above. + */ +void ECRYPT_keysetup( + ECRYPT_ctx* ctx, + const u8* key, + u32 keysize, /* Key size in bits. */ + u32 ivsize); /* IV size in bits. */ + +/* + * IV setup. After having called ECRYPT_keysetup(), the user is + * allowed to call ECRYPT_ivsetup() different times in order to + * encrypt/decrypt different messages with the same key but different + * IV's. + */ +void ECRYPT_ivsetup( + ECRYPT_ctx* ctx, + const u8* iv); + +/* + * Encryption/decryption of arbitrary length messages. + * + * For efficiency reasons, the API provides two types of + * encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function + * (declared here) encrypts byte strings of arbitrary length, while + * the ECRYPT_encrypt_blocks() function (defined later) only accepts + * lengths which are multiples of ECRYPT_BLOCKLENGTH. + * + * The user is allowed to make multiple calls to + * ECRYPT_encrypt_blocks() to incrementally encrypt a long message, + * but he is NOT allowed to make additional encryption calls once he + * has called ECRYPT_encrypt_bytes() (unless he starts a new message + * of course). For example, this sequence of calls is acceptable: + * + * ECRYPT_keysetup(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_bytes(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_blocks(); + * + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_bytes(); + * + * The following sequence is not: + * + * ECRYPT_keysetup(); + * ECRYPT_ivsetup(); + * ECRYPT_encrypt_blocks(); + * ECRYPT_encrypt_bytes(); + * ECRYPT_encrypt_blocks(); + */ + +void ECRYPT_encrypt_bytes( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 msglen); /* Message length in bytes. */ + +void ECRYPT_decrypt_bytes( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 msglen); /* Message length in bytes. */ + +/* ------------------------------------------------------------------------- */ + +/* Optional features */ + +/* + * For testing purposes it can sometimes be useful to have a function + * which immediately generates keystream without having to provide it + * with a zero plaintext. If your cipher cannot provide this function + * (e.g., because it is not strictly a synchronous cipher), please + * reset the ECRYPT_GENERATES_KEYSTREAM flag. + */ + +#define ECRYPT_GENERATES_KEYSTREAM +#ifdef ECRYPT_GENERATES_KEYSTREAM + +void ECRYPT_keystream_bytes( + ECRYPT_ctx* ctx, + u8* keystream, + u32 length); /* Length of keystream in bytes. */ + +#endif + +/* ------------------------------------------------------------------------- */ + +/* Optional optimizations */ + +/* + * By default, the functions in this section are implemented using + * calls to functions declared above. However, you might want to + * implement them differently for performance reasons. + */ + +/* + * All-in-one encryption/decryption of (short) packets. + * + * The default definitions of these functions can be found in + * "ecrypt-sync.c". If you want to implement them differently, please + * undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag. + */ +#define ECRYPT_USES_DEFAULT_ALL_IN_ONE /* [edit] */ + +void ECRYPT_encrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* plaintext, + u8* ciphertext, + u32 msglen); + +void ECRYPT_decrypt_packet( + ECRYPT_ctx* ctx, + const u8* iv, + const u8* ciphertext, + u8* plaintext, + u32 msglen); + +/* + * Encryption/decryption of blocks. + * + * By default, these functions are defined as macros. If you want to + * provide a different implementation, please undef the + * ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions + * declared below. + */ + +#define ECRYPT_BLOCKLENGTH 64 /* [edit] */ + +#define ECRYPT_USES_DEFAULT_BLOCK_MACROS /* [edit] */ +#ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS + +#define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks) \ +ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks) \ + ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#ifdef ECRYPT_GENERATES_KEYSTREAM + +#define ECRYPT_keystream_blocks(ctx, keystream, blocks) \ + ECRYPT_keystream_bytes(ctx, keystream, \ + (blocks) * ECRYPT_BLOCKLENGTH) + +#endif + +#else + +void ECRYPT_encrypt_blocks( + ECRYPT_ctx* ctx, + const u8* plaintext, + u8* ciphertext, + u32 blocks); /* Message length in blocks. */ + +void ECRYPT_decrypt_blocks( + ECRYPT_ctx* ctx, + const u8* ciphertext, + u8* plaintext, + u32 blocks); /* Message length in blocks. */ + +#ifdef ECRYPT_GENERATES_KEYSTREAM + +void ECRYPT_keystream_blocks( + ECRYPT_ctx* ctx, + const u8* keystream, + u32 blocks); /* Keystream length in blocks. */ + +#endif + +#endif + +/* + * If your cipher can be implemented in different ways, you can use + * the ECRYPT_VARIANT parameter to allow the user to choose between + * them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please + * only use this possibility if you really think it could make a + * significant difference and keep the number of variants + * (ECRYPT_MAXVARIANT) as small as possible (definitely not more than + * 10). Note also that all variants should have exactly the same + * external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.). + */ +#define ECRYPT_MAXVARIANT 1 /* [edit] */ + +#ifndef ECRYPT_VARIANT +#define ECRYPT_VARIANT 1 +#endif + +#if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT) +#error this variant does not exist +#endif + +/* ------------------------------------------------------------------------- */ + +#endif diff --git a/libs/encryption/encryption.pro b/libs/encryption/encryption.pro new file mode 100644 index 0000000..c6daa24 --- /dev/null +++ b/libs/encryption/encryption.pro @@ -0,0 +1,13 @@ +QT += core +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += + +HEADERS += \ + ecrypt-config.h \ + ecrypt-machine.h \ + ecrypt-portable.h \ + ecrypt-sync.h + +DESTDIR = $$OUT_PWD/../ diff --git a/fastfile.cpp b/libs/fastfile/fastfile.cpp similarity index 74% rename from fastfile.cpp rename to libs/fastfile/fastfile.cpp index 907dd7c..999c83f 100644 --- a/fastfile.cpp +++ b/libs/fastfile/fastfile.cpp @@ -5,6 +5,7 @@ #include "fastfile_cod7.h" #include "fastfile_cod9.h" #include "compressor.h" +#include "logmanager.h" #include #include @@ -40,6 +41,7 @@ FastFile::~FastFile() { } FF_COMPANY FastFile::pParseFFCompany(QDataStream *afastFileStream, quint32 &aCompanyInt) { + LogManager::instance().addEntry("Parsing company into reference..."); // Check for null datastream ptr if (!afastFileStream) { return COMPANY_NONE; } // Parse company @@ -48,24 +50,25 @@ FF_COMPANY FastFile::pParseFFCompany(QDataStream *afastFileStream, quint32 &aCom aCompanyInt = companyData.toUInt(); if (companyData == "IW") { - qDebug() << "Company found: 'INFINITY_WARD'"; + LogManager::instance().addEntry("Company found: 'INFINITY_WARD'"); return COMPANY_INFINITY_WARD; } else if (companyData == "TA") { - qDebug() << "Company found: 'TREYARCH'"; + LogManager::instance().addEntry("Company found: 'TREYARCH'"); return COMPANY_TREYARCH; } else if (companyData == "Sl") { - qDebug() << "Company found: 'SLEDGEHAMMER'"; + LogManager::instance().addEntry("Company found: 'SLEDGEHAMMER'"); return COMPANY_SLEDGEHAMMER; } else if (companyData == "NX") { - qDebug() << "Company found: 'NEVERSOFT'"; + LogManager::instance().addEntry("Company found: 'NEVERSOFT'"); return COMPANY_NEVERSOFT; } else { - qDebug() << QString("Failed to find company, found '%1'!").arg(companyData); + LogManager::instance().addEntry(QString("Failed to find company, found '%1'!").arg(companyData)); } return COMPANY_NONE; } FF_COMPANY FastFile::pParseFFCompany(QDataStream *afastFileStream) { + LogManager::instance().addEntry("Parsing company..."); // Check for null datastream ptr if (!afastFileStream) { return COMPANY_NONE; } // Parse company @@ -73,19 +76,19 @@ FF_COMPANY FastFile::pParseFFCompany(QDataStream *afastFileStream) { afastFileStream->readRawData(companyData.data(), 2); if (companyData == "IW") { - qDebug() << "Company found: 'INFINITY_WARD'"; + LogManager::instance().addEntry("Company found: 'INFINITY_WARD'"); return COMPANY_INFINITY_WARD; } else if (companyData == "TA") { - qDebug() << "Company found: 'TREYARCH'"; + LogManager::instance().addEntry("Company found: 'TREYARCH'"); return COMPANY_TREYARCH; } else if (companyData == "Sl") { - qDebug() << "Company found: 'SLEDGEHAMMER'"; + LogManager::instance().addEntry("Company found: 'SLEDGEHAMMER'"); return COMPANY_SLEDGEHAMMER; } else if (companyData == "NX") { - qDebug() << "Company found: 'NEVERSOFT'"; + LogManager::instance().addEntry("Company found: 'NEVERSOFT'"); return COMPANY_NEVERSOFT; } else { - qDebug() << QString("Failed to find company, found '%1'!").arg(companyData); + LogManager::instance().addEntry(QString("Failed to find company, found '%1'!").arg(companyData)); } return COMPANY_NONE; } @@ -181,19 +184,28 @@ QString FastFile::pCalculateFFGame(quint32 aVersion) { return result; } -std::shared_ptr FastFile::Create(const QString &aFilePath) { +std::shared_ptr FastFile::Open(const QString &aFilePath) { + LogManager::instance().addEntry("Processing Fastfile..."); + if (aFilePath.isEmpty()) { + LogManager::instance().addError("Attempted to open file w/no name!"); return nullptr; } + LogManager::instance().addEntry("File Path: " + aFilePath); // 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); + LogManager::instance().addError(QString("File failed to open: %1").arg(file->errorString())); return nullptr; } + LogManager::instance().addEntry("File opened"); const QByteArray data = file->readAll(); + LogManager::instance().addEntry("Contents read in"); + LogManager::instance().addEntry(QString("- Size: %1 B").arg(data.size())); + + LogManager::instance().addEntry("File closed"); file->close(); // Create a QDataStream on the input data. @@ -221,19 +233,20 @@ std::shared_ptr FastFile::Create(const QString &aFilePath) { platform = pCalculateFFPlatform(version); game = pCalculateFFGame(version); - qDebug() << "Type: " << fileType; - qDebug() << "Signage: " << signage; - qDebug() << "Magic: " << magic; - qDebug() << "Version: " << 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)); } - qDebug() << "Company: " << company; - qDebug() << "Game: " << game; - qDebug() << "Platform: " << platform; + 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); - qDebug() << "Stem: " << fastFileStem; + LogManager::instance().addEntry(QString("Stem: %1").arg(fastFileStem)); FastFile *fastFile; + bool validff = true; if (game == "COD2") { fastFile = new FastFile_COD2(); } else if (game == "COD5") { @@ -242,14 +255,20 @@ std::shared_ptr FastFile::Create(const QString &aFilePath) { fastFile = new FastFile_COD7(); } else if (game == "COD9") { fastFile = new FastFile_COD9(); + } else { + validff = false; } - if (fastFile) { + + LogManager::instance().addLine(); + + 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; } diff --git a/fastfile.h b/libs/fastfile/fastfile.h similarity index 97% rename from fastfile.h rename to libs/fastfile/fastfile.h index cc67375..fdcf9c3 100644 --- a/fastfile.h +++ b/libs/fastfile/fastfile.h @@ -46,7 +46,7 @@ public: static QString pCalculateFFPlatform(quint32 aVersion); static QString pCalculateFFGame(quint32 aVersion); - static std::shared_ptr Create(const QString& aFilePath); + static std::shared_ptr Open(const QString& aFilePath); private: QString mStem; diff --git a/libs/fastfile/fastfile.pro b/libs/fastfile/fastfile.pro new file mode 100644 index 0000000..db0e2ab --- /dev/null +++ b/libs/fastfile/fastfile.pro @@ -0,0 +1,37 @@ +QT += core widgets +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += \ + fastfile_cod2.cpp \ + fastfile_cod5.cpp \ + fastfile_cod7.cpp \ + fastfile_cod9.cpp \ + fastfile.cpp + +HEADERS += \ + fastfile.h \ + fastfile_cod2.h \ + fastfile_cod5.h \ + fastfile_cod7.h \ + fastfile_cod9.h + +LIBS += \ + -L$$OUT_PWD/../libs/core -lcore \ + -L$$OUT_PWD/../libs/compression -lcompression \ + -L$$OUT_PWD/../libs/encryption -lencryption \ + -L$$OUT_PWD/../libs/zonefile -lzonefile + +INCLUDEPATH += \ + $$PWD/../core \ + $$PWD/../compression \ + $$PWD/../encryption \ + $$PWD/../zonefile + +DEPENDPATH += \ + $$PWD/../core \ + $$PWD/../compression \ + $$PWD/../encryption \ + $$PWD/../zonefile + +DESTDIR = $$OUT_PWD/../ diff --git a/fastfile_cod2.cpp b/libs/fastfile/fastfile_cod2.cpp similarity index 87% rename from fastfile_cod2.cpp rename to libs/fastfile/fastfile_cod2.cpp index 4ea4f7a..473b7bf 100644 --- a/fastfile_cod2.cpp +++ b/libs/fastfile/fastfile_cod2.cpp @@ -28,7 +28,8 @@ bool FastFile_COD2::Load(const QString aFilePath) { } // Decompress fastfile and close - const QString fastFileStem = aFilePath.section("/", -1, -1); + 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; @@ -62,7 +63,7 @@ bool FastFile_COD2::Load(const QByteArray aData) { QDir exportsDir(QDir::currentPath()); exportsDir.mkdir("exports"); - QFile testFile("exports/" + GetStem().split('.')[0] + ".zone"); + QFile testFile("exports/" + GetStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -70,7 +71,7 @@ bool FastFile_COD2::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD2 zoneFile; - zoneFile.Load(decompressedData, GetStem().section('.', 0, 0) + ".zone", FF_PLATFORM_XBOX); + zoneFile.Load(decompressedData, GetStem() + ".zone", FF_PLATFORM_XBOX); SetZoneFile(std::make_shared(zoneFile)); return true; diff --git a/fastfile_cod2.h b/libs/fastfile/fastfile_cod2.h similarity index 100% rename from fastfile_cod2.h rename to libs/fastfile/fastfile_cod2.h diff --git a/fastfile_cod5.cpp b/libs/fastfile/fastfile_cod5.cpp similarity index 93% rename from fastfile_cod5.cpp rename to libs/fastfile/fastfile_cod5.cpp index 104e8c5..41bc6e0 100644 --- a/fastfile_cod5.cpp +++ b/libs/fastfile/fastfile_cod5.cpp @@ -66,7 +66,7 @@ bool FastFile_COD5::Load(const QByteArray aData) { // For COD5, simply decompress from offset 12. decompressedData = Compressor::DecompressZLIB(aData.mid(12)); - QFile testFile("exports/" + GetStem().section('.', 0, 0) + ".zone"); + QFile testFile("exports/" + GetStem() + ".zone"); if(testFile.open(QIODevice::WriteOnly)) { testFile.write(decompressedData); testFile.close(); @@ -80,7 +80,7 @@ bool FastFile_COD5::Load(const QByteArray aData) { } ZoneFile_COD5 zoneFile; - zoneFile.Load(decompressedData, GetStem().section('.', 0, 0) + ".zone", platform); + zoneFile.Load(decompressedData, GetStem() + ".zone", platform); SetZoneFile(std::make_shared(zoneFile)); return true; diff --git a/fastfile_cod5.h b/libs/fastfile/fastfile_cod5.h similarity index 100% rename from fastfile_cod5.h rename to libs/fastfile/fastfile_cod5.h diff --git a/fastfile_cod7.cpp b/libs/fastfile/fastfile_cod7.cpp similarity index 97% rename from fastfile_cod7.cpp rename to libs/fastfile/fastfile_cod7.cpp index 973b5a5..7e7b0c1 100644 --- a/fastfile_cod7.cpp +++ b/libs/fastfile/fastfile_cod7.cpp @@ -135,7 +135,7 @@ bool FastFile_COD7::Load(const QByteArray aData) { // Load the zone file with the decompressed data (using an Xbox platform flag). ZoneFile_COD7 zoneFile; - zoneFile.Load(decompressedData, GetStem().section('.', 0, 0) + ".zone", FF_PLATFORM_XBOX); + zoneFile.Load(decompressedData, GetStem() + ".zone", FF_PLATFORM_XBOX); SetZoneFile(std::make_shared(zoneFile)); return true; diff --git a/fastfile_cod7.h b/libs/fastfile/fastfile_cod7.h similarity index 100% rename from fastfile_cod7.h rename to libs/fastfile/fastfile_cod7.h diff --git a/libs/fastfile/fastfile_cod9.cpp b/libs/fastfile/fastfile_cod9.cpp new file mode 100644 index 0000000..1ade8bb --- /dev/null +++ b/libs/fastfile/fastfile_cod9.cpp @@ -0,0 +1,111 @@ +#include "fastfile_cod9.h" +#include "zonefile_cod9.h" + +#include "utils.h" +#include "compressor.h" + +#include +#include + +FastFile_COD9::FastFile_COD9() { + +} + +FastFile_COD9::~FastFile_COD9() { + +} + +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 = Compressor::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.Load(decompressedData, GetStem() + ".zone", FF_PLATFORM_PC); + SetZoneFile(std::make_shared(zoneFile)); + + return true; +} diff --git a/fastfile_cod9.h b/libs/fastfile/fastfile_cod9.h similarity index 100% rename from fastfile_cod9.h rename to libs/fastfile/fastfile_cod9.h diff --git a/ipak_structs.h b/libs/ipakfile/ipak_structs.h similarity index 100% rename from ipak_structs.h rename to libs/ipakfile/ipak_structs.h diff --git a/libs/ipakfile/ipakfile.pro b/libs/ipakfile/ipakfile.pro new file mode 100644 index 0000000..0ee1df9 --- /dev/null +++ b/libs/ipakfile/ipakfile.pro @@ -0,0 +1,10 @@ +QT += core +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += + +HEADERS += \ + ipak_structs.h + +DESTDIR = $$OUT_PWD/../ diff --git a/iwifile.cpp b/libs/iwifile/iwifile.cpp similarity index 100% rename from iwifile.cpp rename to libs/iwifile/iwifile.cpp diff --git a/iwifile.h b/libs/iwifile/iwifile.h similarity index 96% rename from iwifile.h rename to libs/iwifile/iwifile.h index c1c4d2d..0af67bd 100644 --- a/iwifile.h +++ b/libs/iwifile/iwifile.h @@ -1,7 +1,6 @@ #ifndef IWIFILE_H #define IWIFILE_H -#include "qimage.h" #include #include #include @@ -9,7 +8,6 @@ #include #include #include -#include // Supported versions static const QVector supportedVersions = { diff --git a/libs/iwifile/iwifile.pro b/libs/iwifile/iwifile.pro new file mode 100644 index 0000000..c0c2aee --- /dev/null +++ b/libs/iwifile/iwifile.pro @@ -0,0 +1,25 @@ +QT += core +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += \ + iwifile.cpp + +HEADERS += \ + iwifile.h + +LIBS += \ + -L$$PWD/../../third_party/devil_sdk/lib/ -lDevIL \ + -L$$PWD/../../third_party/devil_sdk/lib/ -lILU \ + -L$$PWD/../../third_party/devil_sdk/lib/ -lILUT \ + -L$$OUT_PWD/../libs/ddsfile -lddsfile + +INCLUDEPATH += \ + $$PWD/../../third_party/devil_sdk/include/ \ + $$PWD/../ddsfile + +DEPENDPATH += \ + $$PWD/../../third_party/devil_sdk/include/ \ + $$PWD/../ddsfile + +DESTDIR = $$OUT_PWD/../ diff --git a/asset_structs.h b/libs/zonefile/asset_structs.h similarity index 92% rename from asset_structs.h rename to libs/zonefile/asset_structs.h index bc26dd3..1ed6c16 100644 --- a/asset_structs.h +++ b/libs/zonefile/asset_structs.h @@ -178,33 +178,17 @@ struct Image { }; struct Material { + quint32 namePtr; QString name; - QString materialName; - quint32 size1; - quint32 size2; - IMAGE_COMPRESSION compression; - quint32 unknowna; - quint32 unknownb; - quint32 unknownc; - quint32 unknownd; - quint32 unknowne; - quint32 unknownf; - quint32 unknowng; - quint32 unknownh; - quint32 unknowni; - quint32 unknownj; - quint32 unknownk; - quint32 unknownl; - quint32 unknownm; - quint32 unknown1; - quint32 unknown2; - quint32 unknown3; - quint32 unknown4; - quint32 unknown5; - quint32 unknown6; - quint32 unknown7; - quint32 unknown8; - quint32 unknown9; + quint32 refNamePtr; + QString refName; + quint8 unknownA[12]; + quint32 stateBits[2]; + quint16 textureCount; + quint16 constCount; + quint32 techSetPtr; + quint32 texturePtr; + quint32 constPtr; }; struct Menu { @@ -371,7 +355,7 @@ struct AssetMap { QVector rawFiles; //QVector phyPresets; QVector models; - //QVector rawFiles; + QVector materials; //QVector shaders; QVector techSets; QVector images; diff --git a/zonefile.cpp b/libs/zonefile/zonefile.cpp similarity index 100% rename from zonefile.cpp rename to libs/zonefile/zonefile.cpp diff --git a/zonefile.h b/libs/zonefile/zonefile.h similarity index 97% rename from zonefile.h rename to libs/zonefile/zonefile.h index 7e59ac4..79c067a 100644 --- a/zonefile.h +++ b/libs/zonefile/zonefile.h @@ -48,7 +48,7 @@ private slots: virtual RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) = 0; virtual void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) = 0; virtual Model pParseAsset_Model(QDataStream *aZoneFileStream) = 0; - virtual void pParseAsset_Material(QDataStream *aZoneFileStream) = 0; + virtual Material pParseAsset_Material(QDataStream *aZoneFileStream) = 0; virtual Shader pParseAsset_Shader(QDataStream *aZoneFileStream) = 0; virtual TechSet pParseAsset_TechSet(QDataStream *aZoneFileStream) = 0; virtual Image pParseAsset_Image(QDataStream *aZoneFileStream) = 0; diff --git a/libs/zonefile/zonefile.pro b/libs/zonefile/zonefile.pro new file mode 100644 index 0000000..9ce3ac5 --- /dev/null +++ b/libs/zonefile/zonefile.pro @@ -0,0 +1,29 @@ +QT += core widgets +TEMPLATE = lib +CONFIG += staticlib c++17 debug + +SOURCES += \ + zonefile.cpp \ + zonefile_cod2.cpp \ + zonefile_cod5.cpp \ + zonefile_cod7.cpp \ + zonefile_cod9.cpp + +HEADERS += \ + asset_structs.h \ + zonefile.h \ + zonefile_cod2.h \ + zonefile_cod5.h \ + zonefile_cod7.h \ + zonefile_cod9.h + +LIBS += \ + -L$$OUT_PWD/../libs/core -lcore + +INCLUDEPATH += \ + $$PWD/../core + +DEPENDPATH += \ + $$PWD/../core + +DESTDIR = $$OUT_PWD/../ diff --git a/zonefile_cod2.cpp b/libs/zonefile/zonefile_cod2.cpp similarity index 94% rename from zonefile_cod2.cpp rename to libs/zonefile/zonefile_cod2.cpp index 32c3ddb..9e39056 100644 --- a/zonefile_cod2.cpp +++ b/libs/zonefile/zonefile_cod2.cpp @@ -180,12 +180,8 @@ QStringList ZoneFile_COD2::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 // 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++) { + for (quint32 i = 0; i < recordCount; i++) { // Skip record start QByteArray rawAssetType(4, Qt::Uninitialized); aZoneFileStream->readRawData(rawAssetType.data(), 4); @@ -200,7 +196,7 @@ QStringList ZoneFile_COD2::pParseZoneIndex(QDataStream *aZoneFileStream, quint32 AssetMap ZoneFile_COD2::pParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) { AssetMap result; - aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 8); + //aZoneFileStream->device()->seek(aZoneFileStream->device()->pos() - 8); for (int i = 0; i < assetOrder.size(); i++) { const QString typeHex = assetOrder[i]; @@ -218,7 +214,7 @@ AssetMap ZoneFile_COD2::pParseAssets(QDataStream *aZoneFileStream, QStringList a } else if (typeStr == "MODEL") { // xmodel result.models << pParseAsset_Model(aZoneFileStream); } else if (typeStr == "MATERIAL") { // material - pParseAsset_Material(aZoneFileStream); + result.materials << pParseAsset_Material(aZoneFileStream); } else if (typeStr == "SHADER") { // pixelshader pParseAsset_Shader(aZoneFileStream); } else if (typeStr == "TECH SET") { // techset include @@ -394,10 +390,6 @@ Model ZoneFile_COD2::pParseAsset_Model(QDataStream *aZoneFileStream) { return result; } -void ZoneFile_COD2::pParseAsset_Material(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); -} - Shader ZoneFile_COD2::pParseAsset_Shader(QDataStream *aZoneFileStream) { Shader result = Shader(); @@ -536,68 +528,26 @@ Image ZoneFile_COD2::pParseAsset_Image(QDataStream *aZoneFileStream) { Material ZoneFile_COD2::pParseAsset_Material(QDataStream *aZoneFileStream) { Material 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; + *aZoneFileStream >> result.namePtr; + if (result.namePtr != 4294967295 && GetTagCount() > result.namePtr - 1) { + result.name = GetTags()[result.namePtr - 1]; } - 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; + *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; } diff --git a/zonefile_cod2.h b/libs/zonefile/zonefile_cod2.h similarity index 95% rename from zonefile_cod2.h rename to libs/zonefile/zonefile_cod2.h index de24a7c..220bdea 100644 --- a/zonefile_cod2.h +++ b/libs/zonefile/zonefile_cod2.h @@ -27,7 +27,7 @@ protected: RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - void pParseAsset_Material(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; @@ -45,7 +45,6 @@ protected: void pParseAsset_Weapon(QDataStream *aZoneFileStream) override; void pParseAsset_D3DBSP(QDataStream *aZoneFileStream) override; StringTable pParseAsset_StringTable(QDataStream *aZoneFileStream) override; - Material pParseAsset_Material(QDataStream *aZoneFileStream); }; #endif // ZONEFILE_COD2_H diff --git a/zonefile_cod5.cpp b/libs/zonefile/zonefile_cod5.cpp similarity index 99% rename from zonefile_cod5.cpp rename to libs/zonefile/zonefile_cod5.cpp index e91e916..5d190e9 100644 --- a/zonefile_cod5.cpp +++ b/libs/zonefile/zonefile_cod5.cpp @@ -396,8 +396,10 @@ Model ZoneFile_COD5::pParseAsset_Model(QDataStream *aZoneFileStream) { return result; } -void ZoneFile_COD5::pParseAsset_Material(QDataStream *aZoneFileStream) { +Material ZoneFile_COD5::pParseAsset_Material(QDataStream *aZoneFileStream) { Q_UNUSED(aZoneFileStream); + + return Material(); } Shader ZoneFile_COD5::pParseAsset_Shader(QDataStream *aZoneFileStream) { diff --git a/zonefile_cod5.h b/libs/zonefile/zonefile_cod5.h similarity index 97% rename from zonefile_cod5.h rename to libs/zonefile/zonefile_cod5.h index 016c8e4..880025f 100644 --- a/zonefile_cod5.h +++ b/libs/zonefile/zonefile_cod5.h @@ -27,7 +27,7 @@ private: RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - void pParseAsset_Material(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; diff --git a/zonefile_cod7.cpp b/libs/zonefile/zonefile_cod7.cpp similarity index 99% rename from zonefile_cod7.cpp rename to libs/zonefile/zonefile_cod7.cpp index baeedb8..080d1ff 100644 --- a/zonefile_cod7.cpp +++ b/libs/zonefile/zonefile_cod7.cpp @@ -396,8 +396,10 @@ Model ZoneFile_COD7::pParseAsset_Model(QDataStream *aZoneFileStream) { return result; } -void ZoneFile_COD7::pParseAsset_Material(QDataStream *aZoneFileStream) { +Material ZoneFile_COD7::pParseAsset_Material(QDataStream *aZoneFileStream) { Q_UNUSED(aZoneFileStream); + + return Material(); } Shader ZoneFile_COD7::pParseAsset_Shader(QDataStream *aZoneFileStream) { diff --git a/zonefile_cod7.h b/libs/zonefile/zonefile_cod7.h similarity index 97% rename from zonefile_cod7.h rename to libs/zonefile/zonefile_cod7.h index 5ed47b0..87339f5 100644 --- a/zonefile_cod7.h +++ b/libs/zonefile/zonefile_cod7.h @@ -27,7 +27,7 @@ protected: RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - void pParseAsset_Material(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; diff --git a/zonefile_cod9.cpp b/libs/zonefile/zonefile_cod9.cpp similarity index 99% rename from zonefile_cod9.cpp rename to libs/zonefile/zonefile_cod9.cpp index e902499..3784c56 100644 --- a/zonefile_cod9.cpp +++ b/libs/zonefile/zonefile_cod9.cpp @@ -396,8 +396,10 @@ Model ZoneFile_COD9::pParseAsset_Model(QDataStream *aZoneFileStream) { return result; } -void ZoneFile_COD9::pParseAsset_Material(QDataStream *aZoneFileStream) { +Material ZoneFile_COD9::pParseAsset_Material(QDataStream *aZoneFileStream) { Q_UNUSED(aZoneFileStream); + + return Material(); } Shader ZoneFile_COD9::pParseAsset_Shader(QDataStream *aZoneFileStream) { diff --git a/zonefile_cod9.h b/libs/zonefile/zonefile_cod9.h similarity index 97% rename from zonefile_cod9.h rename to libs/zonefile/zonefile_cod9.h index 837ac8d..accdf2b 100644 --- a/zonefile_cod9.h +++ b/libs/zonefile/zonefile_cod9.h @@ -27,7 +27,7 @@ protected: RawFile pParseAsset_RawFile(QDataStream *aZoneFileStream) override; void pParseAsset_PhysPreset(QDataStream *aZoneFileStream) override; Model pParseAsset_Model(QDataStream *aZoneFileStream) override; - void pParseAsset_Material(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; diff --git a/tests/autotest_cod.cpp b/tests/autotest_cod.cpp new file mode 100644 index 0000000..3a8357c --- /dev/null +++ b/tests/autotest_cod.cpp @@ -0,0 +1,12 @@ +#include + +class AutoTest_COD : public QObject { + Q_OBJECT + +private slots: + virtual void testAddition() = 0; + virtual void testString() = 0; +}; + +// Don't generate a main() function +#include "autotest_cod.moc" diff --git a/tests/autotest_cod5.cpp b/tests/autotest_cod5.cpp new file mode 100644 index 0000000..b27a477 --- /dev/null +++ b/tests/autotest_cod5.cpp @@ -0,0 +1,23 @@ +#include + +#include "autotest_cod.cpp" + +class AutoTest_COD5 : public AutoTest_COD { + Q_OBJECT + +private slots: + void testAddition(); + void testString(); +}; + +void AutoTest_COD5::testAddition() { + QCOMPARE(2 + 2, 4); +} + +void AutoTest_COD5::testString() { + QString str = "hello"; + QVERIFY(str.startsWith("h")); +} + +// Don't generate a main() function +#include "autotest_cod5.moc" diff --git a/tests/autotest_xplor.cpp b/tests/autotest_xplor.cpp new file mode 100644 index 0000000..5368821 --- /dev/null +++ b/tests/autotest_xplor.cpp @@ -0,0 +1,20 @@ +#include + +class AutoTest_XPlor : public QObject { + Q_OBJECT + +private slots: + void testAddition(); + void testString(); +}; + +void AutoTest_XPlor::testAddition() { + QCOMPARE(2 + 2, 4); +} + +void AutoTest_XPlor::testString() { + QString str = "hello"; + QVERIFY(str.startsWith("h")); +} + +#include "autotest_xplor.moc" diff --git a/tests/test_main.cpp b/tests/test_main.cpp new file mode 100644 index 0000000..9574a20 --- /dev/null +++ b/tests/test_main.cpp @@ -0,0 +1,41 @@ +#include +#include "autotest_xplor.cpp" +// #include "autotest_cod1.cpp" +// #include "autotest_cod2.cpp" +// #include "autotest_cod3.cpp" +// #include "autotest_cod4.cpp" +#include "autotest_cod5.cpp" + +int main(int argc, char *argv[]) { + AutoTest_XPlor test_xplor; + if (QTest::qExec(&test_xplor, argc, argv)) { + return -1; + } + + // AutoTest_COD1 test_cod1; + // if (QTest::qExec(&test_cod1, argc, argv)) { + // return -10; + // } + + // AutoTest_COD2 test_cod2; + // if (QTest::qExec(&test_cod2, argc, argv)) { + // return -10; + // } + + // AutoTest_COD3 test_cod3; + // if (QTest::qExec(&test_cod3, argc, argv)) { + // return -10; + // } + + // AutoTest_COD4 test_cod4; + // if (QTest::qExec(&test_cod4, argc, argv)) { + // return -10; + // } + + AutoTest_COD5 test_cod5; + if (QTest::qExec(&test_cod5, argc, argv)) { + return -10; + } + + return 0; +} diff --git a/tests/tests.pro b/tests/tests.pro new file mode 100644 index 0000000..0bbe71f --- /dev/null +++ b/tests/tests.pro @@ -0,0 +1,25 @@ +TEMPLATE = app +CONFIG += no_main + +# Enable the testlib module +QT += testlib + +# Define a test-specific flag +DEFINES += QT_TESTS + +TARGET = tests + +# List all test source files +SOURCES += \ + autotest_cod5.cpp \ + test_main.cpp \ + autotest_cod.cpp \ + autotest_xplor.cpp + + +# Prevent tests from being built in release mode (optional) +# CONFIG(debug, debug|release) { +# message("Including test files in Debug mode") +# } else { +# SOURCES -= autotest_cod5.cpp +# } diff --git a/DevILSDK/include/IL/DevIL.i b/third_party/devil_sdk/include/IL/DevIL.i similarity index 100% rename from DevILSDK/include/IL/DevIL.i rename to third_party/devil_sdk/include/IL/DevIL.i diff --git a/DevILSDK/include/IL/build-lua b/third_party/devil_sdk/include/IL/build-lua similarity index 100% rename from DevILSDK/include/IL/build-lua rename to third_party/devil_sdk/include/IL/build-lua diff --git a/DevILSDK/include/IL/build-python b/third_party/devil_sdk/include/IL/build-python similarity index 100% rename from DevILSDK/include/IL/build-python rename to third_party/devil_sdk/include/IL/build-python diff --git a/DevILSDK/include/IL/config.h.win b/third_party/devil_sdk/include/IL/config.h.win similarity index 100% rename from DevILSDK/include/IL/config.h.win rename to third_party/devil_sdk/include/IL/config.h.win diff --git a/DevILSDK/include/IL/devil_cpp_wrapper.hpp b/third_party/devil_sdk/include/IL/devil_cpp_wrapper.hpp similarity index 100% rename from DevILSDK/include/IL/devil_cpp_wrapper.hpp rename to third_party/devil_sdk/include/IL/devil_cpp_wrapper.hpp diff --git a/DevILSDK/include/IL/devil_internal_exports.h b/third_party/devil_sdk/include/IL/devil_internal_exports.h similarity index 100% rename from DevILSDK/include/IL/devil_internal_exports.h rename to third_party/devil_sdk/include/IL/devil_internal_exports.h diff --git a/DevILSDK/include/IL/il.h b/third_party/devil_sdk/include/IL/il.h similarity index 100% rename from DevILSDK/include/IL/il.h rename to third_party/devil_sdk/include/IL/il.h diff --git a/DevILSDK/include/IL/il_wrap.h b/third_party/devil_sdk/include/IL/il_wrap.h similarity index 100% rename from DevILSDK/include/IL/il_wrap.h rename to third_party/devil_sdk/include/IL/il_wrap.h diff --git a/DevILSDK/include/IL/ilu.h b/third_party/devil_sdk/include/IL/ilu.h similarity index 100% rename from DevILSDK/include/IL/ilu.h rename to third_party/devil_sdk/include/IL/ilu.h diff --git a/DevILSDK/include/IL/ilu_region.h b/third_party/devil_sdk/include/IL/ilu_region.h similarity index 100% rename from DevILSDK/include/IL/ilu_region.h rename to third_party/devil_sdk/include/IL/ilu_region.h diff --git a/DevILSDK/include/IL/ilut.h b/third_party/devil_sdk/include/IL/ilut.h similarity index 100% rename from DevILSDK/include/IL/ilut.h rename to third_party/devil_sdk/include/IL/ilut.h diff --git a/DevILSDK/include/IL/ilut_config.h b/third_party/devil_sdk/include/IL/ilut_config.h similarity index 100% rename from DevILSDK/include/IL/ilut_config.h rename to third_party/devil_sdk/include/IL/ilut_config.h diff --git a/DevILSDK/include/IL/luadevil.c b/third_party/devil_sdk/include/IL/luadevil.c similarity index 100% rename from DevILSDK/include/IL/luadevil.c rename to third_party/devil_sdk/include/IL/luadevil.c diff --git a/DevILSDK/include/IL/stamp-h.in b/third_party/devil_sdk/include/IL/stamp-h.in similarity index 100% rename from DevILSDK/include/IL/stamp-h.in rename to third_party/devil_sdk/include/IL/stamp-h.in diff --git a/DevILSDK/lib/x64/Release/DevIL.dll b/third_party/devil_sdk/lib/DevIL.dll similarity index 100% rename from DevILSDK/lib/x64/Release/DevIL.dll rename to third_party/devil_sdk/lib/DevIL.dll diff --git a/DevILSDK/lib/x64/Release/DevIL.lib b/third_party/devil_sdk/lib/DevIL.lib similarity index 100% rename from DevILSDK/lib/x64/Release/DevIL.lib rename to third_party/devil_sdk/lib/DevIL.lib diff --git a/DevILSDK/lib/x64/Release/ILU.dll b/third_party/devil_sdk/lib/ILU.dll similarity index 100% rename from DevILSDK/lib/x64/Release/ILU.dll rename to third_party/devil_sdk/lib/ILU.dll diff --git a/DevILSDK/lib/x64/Release/ILU.lib b/third_party/devil_sdk/lib/ILU.lib similarity index 100% rename from DevILSDK/lib/x64/Release/ILU.lib rename to third_party/devil_sdk/lib/ILU.lib diff --git a/DevILSDK/lib/x64/Release/ILUT.dll b/third_party/devil_sdk/lib/ILUT.dll similarity index 100% rename from DevILSDK/lib/x64/Release/ILUT.dll rename to third_party/devil_sdk/lib/ILUT.dll diff --git a/DevILSDK/lib/x64/Release/ILUT.lib b/third_party/devil_sdk/lib/ILUT.lib similarity index 100% rename from DevILSDK/lib/x64/Release/ILUT.lib rename to third_party/devil_sdk/lib/ILUT.lib diff --git a/third_party/zlib/include/deflate.h b/third_party/zlib/include/deflate.h new file mode 100644 index 0000000..a5d5acc --- /dev/null +++ b/third_party/zlib/include/deflate.h @@ -0,0 +1,331 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2004 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 +#define COMMENT_STATE 91 +#define HCRC_STATE 103 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Byte_zf *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Byte_zf *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte_z method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Byte_zf *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/third_party/zlib/include/zconf.h b/third_party/zlib/include/zconf.h new file mode 100644 index 0000000..b9ad50d --- /dev/null +++ b/third_party/zlib/include/zconf.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte_z z_Byte_z +# define uInt z_uInt +# define uLong z_uLong +# define Byte_zf z_Byte_zf +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte_z; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Byte_zf Byte_z FAR +#else + typedef Byte_z FAR Byte_zf; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte_z const *voidpc; + typedef Byte_z FAR *voidpf; + typedef Byte_z *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/third_party/zlib/include/zlib.h b/third_party/zlib/include/zlib.h new file mode 100644 index 0000000..08759ed --- /dev/null +++ b/third_party/zlib/include/zlib.h @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Byte_zf *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Byte_zf *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Byte_zf *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Byte_zf *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Byte_zf *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Byte_zf *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Byte_zf *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Byte_zf *dest, uLongf *destLen, + const Byte_zf *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Byte_zf *dest, uLongf *destLen, + const Byte_zf *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Byte_zf *dest, uLongf *destLen, + const Byte_zf *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Byte_zf *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Byte_zf *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/third_party/zlib/include/zutil.h b/third_party/zlib/include/zutil.h new file mode 100644 index 0000000..6cc3fc1 --- /dev/null +++ b/third_party/zlib/include/zutil.h @@ -0,0 +1,269 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id$ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# ifndef _WIN32_WCE +# include +# endif +# include +# include +#endif +#ifdef NO_ERRNO_H +# ifdef _WIN32_WCE + /* The Microsoft C Run-Time Library for Windows CE doesn't have + * errno. We define it as a global variable to simplify porting. + * Its value is always 0 and should not be used. We rename it to + * avoid conflict with other libraries that use the same workaround. + */ +# define errno z_errno +# endif + extern int errno; +#else +# ifndef _WIN32_WCE +# include +# endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +# ifdef M_I86 + #include +# endif +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif +#ifdef VMS +# define NO_vsnprintf +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Byte_zf* dest, const Byte_zf* source, uInt len)); + extern int zmemcmp OF((const Byte_zf* s1, const Byte_zf* s2, uInt len)); + extern void zmemzero OF((Byte_zf* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/third_party/zlib/lib/zlib.lib b/third_party/zlib/lib/zlib.lib new file mode 100644 index 0000000..36a53de Binary files /dev/null and b/third_party/zlib/lib/zlib.lib differ diff --git a/xtreewidget.h b/xtreewidget.h deleted file mode 100644 index 1929c68..0000000 --- a/xtreewidget.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef XTREEWIDGET_H -#define XTREEWIDGET_H - -#include "d3dbsp_structs.h" -#include "asset_structs.h" -#include "ddsfile.h" -#include "iwifile.h" -#include "fastfile.h" -#include "xtreewidgetitem.h" -#include "zonefile.h" - -#include - -class XTreeWidget : public QTreeWidget -{ - Q_OBJECT -public: - explicit XTreeWidget(QWidget *parent = nullptr); - ~XTreeWidget(); - - void AddFastFile(std::shared_ptr aFastFile); - void AddZoneFile(std::shared_ptr aZoneFile, XTreeWidgetItem *aParentItem = nullptr); - void AddIWIFile(std::shared_ptr aIWIFile); - void AddDDSFile(std::shared_ptr aDDSFile); - -signals: - void DDSFileSelected(std::shared_ptr aDDSFile); - void IWIFileSelected(std::shared_ptr aIWIFile); - void FastFileSelected(std::shared_ptr aFastFile); - void ZoneFileSelected(std::shared_ptr aZoneFile); - void LocalStringSelected(std::shared_ptr aZoneFile); - void RawFileSelected(std::shared_ptr aRawFile); - void ImageSelected(std::shared_ptr aImage); - void TechSetSelected(std::shared_ptr aZoneFile); - void StrTableSelected(std::shared_ptr aStrTable); - void MenuSelected(std::shared_ptr aMenu); - void SoundSelected(std::shared_ptr aSound); - void TabSelected(const QString aTabName); - void Cleared(); - -protected: - void ItemSelectionChanged(); - void PrepareContextMenu(const QPoint &pos); - -private: - QMap> mFastFiles; - QMap> mZoneFiles; - QMap> mDDSFiles; - QMap> mIWIFiles; - - std::shared_ptr pFindZoneFile(const QString aFilePart); - std::shared_ptr pFindFastFile(const QString aFilePart); -}; - -#endif // XTREEWIDGET_H