This commit is contained in:
Nicholas Johnson 2025-12-20 01:50:52 -05:00
commit f49ca74b17
280 changed files with 4938 additions and 3380 deletions

View File

@ -10,7 +10,9 @@ SOURCES += $$files($$PWD/*.cpp)
HEADERS += $$files($$PWD/*.h) HEADERS += $$files($$PWD/*.h)
FORMS += $$files($$PWD/*.ui) FORMS += $$files($$PWD/*.ui)
RESOURCES += ../data/data.qrc RESOURCES += ../data/data.qrc \
../data/Data.qrc \
data/Data.qrc
LIBS += \ LIBS += \
-L$$PWD/../third_party/devil_sdk/lib/ -lDevIL -lILU -lILUT \ -L$$PWD/../third_party/devil_sdk/lib/ -lDevIL -lILU -lILUT \
@ -21,9 +23,6 @@ LIBS += \
-L$$OUT_PWD/../libs/ -lcompression \ -L$$OUT_PWD/../libs/ -lcompression \
-L$$OUT_PWD/../libs/ -lencryption \ -L$$OUT_PWD/../libs/ -lencryption \
-L$$OUT_PWD/../libs/ -lfastfile \ -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 -L$$OUT_PWD/../libs/ -lzonefile
INCLUDEPATH += \ INCLUDEPATH += \
@ -34,9 +33,6 @@ INCLUDEPATH += \
$$PWD/../libs/compression \ $$PWD/../libs/compression \
$$PWD/../libs/encryption \ $$PWD/../libs/encryption \
$$PWD/../libs/fastfile \ $$PWD/../libs/fastfile \
$$PWD/../libs/ddsfile \
$$PWD/../libs/ipakfile \
$$PWD/../libs/iwifile \
$$PWD/../libs/xassets \ $$PWD/../libs/xassets \
$$PWD/../libs/zonefile $$PWD/../libs/zonefile
@ -48,9 +44,6 @@ DEPENDPATH += \
$$PWD/../libs/compression \ $$PWD/../libs/compression \
$$PWD/../libs/encryption \ $$PWD/../libs/encryption \
$$PWD/../libs/fastfile \ $$PWD/../libs/fastfile \
$$PWD/../libs/ddsfile \
$$PWD/../libs/ipakfile \
$$PWD/../libs/iwifile \
$$PWD/../libs/xassets \ $$PWD/../libs/xassets \
$$PWD/../libs/zonefile $$PWD/../libs/zonefile

View File

@ -7,176 +7,176 @@ DDSViewer::DDSViewer(QWidget *parent)
, ui(new Ui::DDSViewer) , ui(new Ui::DDSViewer)
{ {
ui->setupUi(this); ui->setupUi(this);
mDDSFile = nullptr; //mDDSFile = nullptr;
} }
DDSViewer::~DDSViewer() { DDSViewer::~DDSViewer() {
delete ui; delete ui;
} }
void DDSViewer::SetDDSFile(const DDSFile* aDDSFile) { // void DDSViewer::SetDDSFile(const DDSFile* aDDSFile) {
mDDSFile = aDDSFile; // mDDSFile = aDDSFile;
ui->label_Title->setText(mDDSFile->fileStem + ".dds"); // ui->label_Title->setText(mDDSFile->fileStem + ".dds");
char magicData[5]; // char magicData[5];
magicData[0] = static_cast<char>(mDDSFile->header.magic & 0xFF); // magicData[0] = static_cast<char>(mDDSFile->header.magic & 0xFF);
magicData[1] = static_cast<char>((mDDSFile->header.magic >> 8) & 0xFF); // magicData[1] = static_cast<char>((mDDSFile->header.magic >> 8) & 0xFF);
magicData[2] = static_cast<char>((mDDSFile->header.magic >> 16) & 0xFF); // magicData[2] = static_cast<char>((mDDSFile->header.magic >> 16) & 0xFF);
magicData[3] = static_cast<char>((mDDSFile->header.magic >> 24) & 0xFF); // magicData[3] = static_cast<char>((mDDSFile->header.magic >> 24) & 0xFF);
magicData[4] = '\0'; // magicData[4] = '\0';
// If youre using Qt and want a QString: // // If youre using Qt and want a QString:
QString magicStr = QString::fromLatin1(magicData); // QString magicStr = QString::fromLatin1(magicData);
ui->lineEdit_Magic->setText(magicStr); // ui->lineEdit_Magic->setText(magicStr);
ui->spinBox_Size->setValue(mDDSFile->header.size); // ui->spinBox_Size->setValue(mDDSFile->header.size);
ui->checkBox_CapsValid->setChecked((mDDSFile->header.flags & DDSD_CAPS) != 0); // ui->checkBox_CapsValid->setChecked((mDDSFile->header.flags & DDSD_CAPS) != 0);
ui->checkBox_HeightValid->setChecked((mDDSFile->header.flags & DDSD_HEIGHT) != 0); // ui->checkBox_HeightValid->setChecked((mDDSFile->header.flags & DDSD_HEIGHT) != 0);
ui->checkBox_WidthValid->setChecked((mDDSFile->header.flags & DDSD_WIDTH) != 0); // ui->checkBox_WidthValid->setChecked((mDDSFile->header.flags & DDSD_WIDTH) != 0);
ui->checkBox_PitchValid->setChecked((mDDSFile->header.flags & DDSD_PITCH) != 0); // ui->checkBox_PitchValid->setChecked((mDDSFile->header.flags & DDSD_PITCH) != 0);
ui->checkBox_PFValid->setChecked((mDDSFile->header.flags & DDSD_PIXELFORMAT) != 0); // ui->checkBox_PFValid->setChecked((mDDSFile->header.flags & DDSD_PIXELFORMAT) != 0);
ui->checkBox_MipmapCountValid->setChecked((mDDSFile->header.flags & DDSD_MIPMAPCOUNT) != 0); // ui->checkBox_MipmapCountValid->setChecked((mDDSFile->header.flags & DDSD_MIPMAPCOUNT) != 0);
ui->checkBox_LinearSizeValid->setChecked((mDDSFile->header.flags & DDSD_LINEARSIZE) != 0); // ui->checkBox_LinearSizeValid->setChecked((mDDSFile->header.flags & DDSD_LINEARSIZE) != 0);
ui->checkBox_DepthValid->setChecked((mDDSFile->header.flags & DDSD_DEPTH) != 0); // ui->checkBox_DepthValid->setChecked((mDDSFile->header.flags & DDSD_DEPTH) != 0);
ui->spinBox_PLSize->setValue(mDDSFile->header.pitchOrLinearSize); // ui->spinBox_PLSize->setValue(mDDSFile->header.pitchOrLinearSize);
ui->spinBox_Depth->setValue(mDDSFile->header.depth); // ui->spinBox_Depth->setValue(mDDSFile->header.depth);
ui->spinBox_Width->setValue(mDDSFile->header.width); // ui->spinBox_Width->setValue(mDDSFile->header.width);
ui->spinBox_Height->setValue(mDDSFile->header.height); // ui->spinBox_Height->setValue(mDDSFile->header.height);
ui->spinBox_MipmapCount->setValue(mDDSFile->header.mipMapCount); // ui->spinBox_MipmapCount->setValue(mDDSFile->header.mipMapCount);
ui->spinBox_Res1->setValue(mDDSFile->header.reserved1[0]); // ui->spinBox_Res1->setValue(mDDSFile->header.reserved1[0]);
ui->spinBox_Res2->setValue(mDDSFile->header.reserved1[1]); // ui->spinBox_Res2->setValue(mDDSFile->header.reserved1[1]);
ui->spinBox_Res3->setValue(mDDSFile->header.reserved1[2]); // ui->spinBox_Res3->setValue(mDDSFile->header.reserved1[2]);
ui->spinBox_Res4->setValue(mDDSFile->header.reserved1[3]); // ui->spinBox_Res4->setValue(mDDSFile->header.reserved1[3]);
ui->spinBox_Res5->setValue(mDDSFile->header.reserved1[4]); // ui->spinBox_Res5->setValue(mDDSFile->header.reserved1[4]);
ui->spinBox_Res6->setValue(mDDSFile->header.reserved1[5]); // ui->spinBox_Res6->setValue(mDDSFile->header.reserved1[5]);
ui->spinBox_Res7->setValue(mDDSFile->header.reserved1[6]); // ui->spinBox_Res7->setValue(mDDSFile->header.reserved1[6]);
ui->spinBox_Res8->setValue(mDDSFile->header.reserved1[7]); // ui->spinBox_Res8->setValue(mDDSFile->header.reserved1[7]);
ui->spinBox_Res9->setValue(mDDSFile->header.reserved1[8]); // ui->spinBox_Res9->setValue(mDDSFile->header.reserved1[8]);
ui->spinBox_Res10->setValue(mDDSFile->header.reserved1[9]); // ui->spinBox_Res10->setValue(mDDSFile->header.reserved1[9]);
ui->spinBox_Res11->setValue(mDDSFile->header.reserved1[10]); // ui->spinBox_Res11->setValue(mDDSFile->header.reserved1[10]);
ui->spinBox_Res12->setValue(mDDSFile->header.reserved2); // ui->spinBox_Res12->setValue(mDDSFile->header.reserved2);
ui->spinBox_PF_Size->setValue(mDDSFile->header.pixelFormat.size); // ui->spinBox_PF_Size->setValue(mDDSFile->header.pixelFormat.size);
ui->checkBox_PF_AlphaPxValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_ALPHAPIXELS) != 0); // ui->checkBox_PF_AlphaPxValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_ALPHAPIXELS) != 0);
ui->checkBox_PF_AlphaOnlyValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_ALPHA) != 0); // ui->checkBox_PF_AlphaOnlyValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_ALPHA) != 0);
ui->checkBox_PF_FormatValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_FOURCC) != 0); // ui->checkBox_PF_FormatValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_FOURCC) != 0);
ui->checkBox_PF_RGBValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_RGB) != 0); // ui->checkBox_PF_RGBValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_RGB) != 0);
ui->checkBox_PF_YUVValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_YUV) != 0); // ui->checkBox_PF_YUVValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_YUV) != 0);
ui->checkBox_PF_LuminanceValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_LUMINANCE) != 0); // ui->checkBox_PF_LuminanceValid->setChecked((mDDSFile->header.pixelFormat.flags & DDPF_LUMINANCE) != 0);
QString formatStr = QString::number(mDDSFile->header.pixelFormat.format); // QString formatStr = QString::number(mDDSFile->header.pixelFormat.format);
switch (mDDSFile->header.pixelFormat.format) { // switch (mDDSFile->header.pixelFormat.format) {
case IWI_FORMAT_ARGB32: // case IWI_FORMAT_ARGB32:
formatStr = "ARGB32"; // formatStr = "ARGB32";
break; // break;
case IWI_FORMAT_RGB24: // case IWI_FORMAT_RGB24:
formatStr = "RGB24"; // formatStr = "RGB24";
break; // break;
case IWI_FORMAT_GA16: // case IWI_FORMAT_GA16:
formatStr = "GA16"; // formatStr = "GA16";
break; // break;
case IWI_FORMAT_A8: // case IWI_FORMAT_A8:
formatStr = "A8"; // formatStr = "A8";
break; // break;
case IWI_FORMAT_DXT1: // case IWI_FORMAT_DXT1:
formatStr = "DXT1"; // formatStr = "DXT1";
break; // break;
case IWI_FORMAT_DXT3: // case IWI_FORMAT_DXT3:
formatStr = "DXT3"; // formatStr = "DXT3";
break; // break;
case IWI_FORMAT_DXT5: // case IWI_FORMAT_DXT5:
formatStr = "DXT5"; // formatStr = "DXT5";
break; // break;
} // }
ui->lineEdit_PF_Format->setText(formatStr); // ui->lineEdit_PF_Format->setText(formatStr);
ui->spinBox_PF_RGBBitCount->setValue(mDDSFile->header.pixelFormat.rgbBitCount); // ui->spinBox_PF_RGBBitCount->setValue(mDDSFile->header.pixelFormat.rgbBitCount);
ui->spinBox_RedBitCount->setValue(mDDSFile->header.pixelFormat.rBitMask); // ui->spinBox_RedBitCount->setValue(mDDSFile->header.pixelFormat.rBitMask);
ui->spinBox_GreenBitCount->setValue(mDDSFile->header.pixelFormat.gBitMask); // ui->spinBox_GreenBitCount->setValue(mDDSFile->header.pixelFormat.gBitMask);
ui->spinBox_BlueBitCount->setValue(mDDSFile->header.pixelFormat.bBitMask); // ui->spinBox_BlueBitCount->setValue(mDDSFile->header.pixelFormat.bBitMask);
ui->spinBox_AlphaBitMask->setValue(mDDSFile->header.pixelFormat.aBitMask); // ui->spinBox_AlphaBitMask->setValue(mDDSFile->header.pixelFormat.aBitMask);
ui->checkBox_Caps1_TextureValid->setChecked((mDDSFile->header.caps.caps1 & DDSCAPS_TEXTURE) != 0); // ui->checkBox_Caps1_TextureValid->setChecked((mDDSFile->header.caps.caps1 & DDSCAPS_TEXTURE) != 0);
ui->checkBox_Caps1_ComplexValid->setChecked((mDDSFile->header.caps.caps1 & DDSCAPS_COMPLEX) != 0); // ui->checkBox_Caps1_ComplexValid->setChecked((mDDSFile->header.caps.caps1 & DDSCAPS_COMPLEX) != 0);
ui->checkBox_Caps1_MipmapValid->setChecked((mDDSFile->header.caps.caps1 & DDSCAPS_MIPMAP) != 0); // ui->checkBox_Caps1_MipmapValid->setChecked((mDDSFile->header.caps.caps1 & DDSCAPS_MIPMAP) != 0);
ui->checkBox_Caps2_CubemapValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0); // ui->checkBox_Caps2_CubemapValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0);
ui->checkBox_Caps2_CMPXValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) != 0); // ui->checkBox_Caps2_CMPXValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEX) != 0);
ui->checkBox_Caps2_CMNXValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) != 0); // ui->checkBox_Caps2_CMNXValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) != 0);
ui->checkBox_Caps2_CMPYValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) != 0); // ui->checkBox_Caps2_CMPYValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEY) != 0);
ui->checkBox_Caps2_CMNYValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) != 0); // ui->checkBox_Caps2_CMNYValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) != 0);
ui->checkBox_Caps2_CMPZValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) != 0); // ui->checkBox_Caps2_CMPZValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) != 0);
ui->checkBox_Caps2_CMNZValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) != 0); // ui->checkBox_Caps2_CMNZValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) != 0);
ui->checkBox_Caps2_VolumeValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_VOLUME) != 0); // ui->checkBox_Caps2_VolumeValid->setChecked((mDDSFile->header.caps.caps2 & DDSCAPS2_VOLUME) != 0);
ui->spinBox_Caps_DDSX->setValue(mDDSFile->header.caps.dDSX); // ui->spinBox_Caps_DDSX->setValue(mDDSFile->header.caps.dDSX);
ui->spinBox_Caps_Res->setValue(mDDSFile->header.caps.reserved); // ui->spinBox_Caps_Res->setValue(mDDSFile->header.caps.reserved);
ui->comboBox_Mipmap->clear(); // ui->comboBox_Mipmap->clear();
for (auto mipmap : mDDSFile->mipmaps) { // for (auto mipmap : mDDSFile->mipmaps) {
ui->comboBox_Mipmap->addItem(QString("%1x%2").arg(mipmap.width).arg(mipmap.height)); // ui->comboBox_Mipmap->addItem(QString("%1x%2").arg(mipmap.width).arg(mipmap.height));
} // }
connect(ui->comboBox_Mipmap, &QComboBox::currentIndexChanged, this, &DDSViewer::MipmapIndexChanged); // connect(ui->comboBox_Mipmap, &QComboBox::currentIndexChanged, this, &DDSViewer::MipmapIndexChanged);
if (!mDDSFile->mipmaps.empty()) { // if (!mDDSFile->mipmaps.empty()) {
MipmapIndexChanged(0); // MipmapIndexChanged(0);
} // }
} // }
void DDSViewer::MipmapIndexChanged(int aMipmapIndex) { // void DDSViewer::MipmapIndexChanged(int aMipmapIndex) {
if (aMipmapIndex == -1) { return; } // if (aMipmapIndex == -1) { return; }
auto mipmaps = mDDSFile->mipmaps; // auto mipmaps = mDDSFile->mipmaps;
auto mipmap = mipmaps[aMipmapIndex]; // auto mipmap = mipmaps[aMipmapIndex];
ui->spinBox_MipmapSize->setValue(mipmap.size); // ui->spinBox_MipmapSize->setValue(mipmap.size);
ui->spinBox_MipmapWidth->setValue(mipmap.width); // ui->spinBox_MipmapWidth->setValue(mipmap.width);
ui->spinBox_MipmapHeight->setValue(mipmap.height); // ui->spinBox_MipmapHeight->setValue(mipmap.height);
// Validate Data // // Validate Data
if (mipmap.size <= 0) { // if (mipmap.size <= 0) {
qDebug() << "Error: Mipmap data is empty!"; // qDebug() << "Error: Mipmap data is empty!";
return; // return;
} // }
if (mipmap.width <= 0 || mipmap.height <= 0) { // if (mipmap.width <= 0 || mipmap.height <= 0) {
qDebug() << "Error: Invalid mipmap dimensions!"; // qDebug() << "Error: Invalid mipmap dimensions!";
return; // return;
} // }
// Ensure data size matches expected size // // Ensure data size matches expected size
int bytesPerPixel = 4; // RGBA8888 // int bytesPerPixel = 4; // RGBA8888
quint32 expectedSize = mipmap.width * mipmap.height * bytesPerPixel; // quint32 expectedSize = mipmap.width * mipmap.height * bytesPerPixel;
if (mipmap.size < expectedSize) { // if (mipmap.size < expectedSize) {
qDebug() << "Error: Mipmap data size mismatch! Expected:" << expectedSize << ", Got:" << mipmap.size; // qDebug() << "Error: Mipmap data size mismatch! Expected:" << expectedSize << ", Got:" << mipmap.size;
return; // return;
} // }
// Create QImage // // Create QImage
const unsigned char* imageData = reinterpret_cast<const unsigned char*>(mipmap.data.constData()); // const unsigned char* imageData = reinterpret_cast<const unsigned char*>(mipmap.data.constData());
QImage image(reinterpret_cast<const uchar*>(imageData), // QImage image(reinterpret_cast<const uchar*>(imageData),
mipmap.width, mipmap.height, // mipmap.width, mipmap.height,
mipmap.width * bytesPerPixel, // Stride // mipmap.width * bytesPerPixel, // Stride
QImage::Format_RGBA8888); // QImage::Format_RGBA8888);
if (image.isNull()) { // if (image.isNull()) {
qDebug() << "Error: QImage creation failed!"; // qDebug() << "Error: QImage creation failed!";
return; // return;
} // }
// Convert to QPixmap // // Convert to QPixmap
QPixmap pixmap = QPixmap::fromImage(image); // QPixmap pixmap = QPixmap::fromImage(image);
if (pixmap.isNull()) { // if (pixmap.isNull()) {
qDebug() << "Error: QPixmap conversion failed!"; // qDebug() << "Error: QPixmap conversion failed!";
return; // return;
} // }
// Scale and display // // Scale and display
pixmap = pixmap.scaled(ui->label_Image->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); // pixmap = pixmap.scaled(ui->label_Image->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
ui->label_Image->setPixmap(pixmap); // ui->label_Image->setPixmap(pixmap);
} // }

View File

@ -1,7 +1,6 @@
#ifndef DDSVIEWER_H #ifndef DDSVIEWER_H
#define DDSVIEWER_H #define DDSVIEWER_H
#include "ddsfile.h"
#include <QWidget> #include <QWidget>
namespace Ui { namespace Ui {
@ -16,14 +15,14 @@ public:
explicit DDSViewer(QWidget *parent = nullptr); explicit DDSViewer(QWidget *parent = nullptr);
~DDSViewer(); ~DDSViewer();
void SetDDSFile(const DDSFile *aDDSFile); //void SetDDSFile(const DDSFile *aDDSFile);
private slots: private slots:
void MipmapIndexChanged(int aMipmapIndex); //void MipmapIndexChanged(int aMipmapIndex);
private: private:
Ui::DDSViewer *ui; Ui::DDSViewer *ui;
const DDSFile* mDDSFile; //const DDSFile* mDDSFile;
}; };
#endif // DDSVIEWER_H #endif // DDSVIEWER_H

View File

@ -2,9 +2,9 @@
#define IMAGEWIDGET_H #define IMAGEWIDGET_H
#include "enums.h" #include "enums.h"
#include "dds_structs.h" //#include "dds_structs.h"
#include "d3dbsp_structs.h" #include "d3dbsp_structs.h"
#include "ipak_structs.h" //#include "ipak_structs.h"
#include <QWidget> #include <QWidget>

View File

@ -14,85 +14,85 @@ IWIViewer::~IWIViewer()
delete ui; delete ui;
} }
void IWIViewer::SetIWIFile(const IWIFile* aIWIFile) { // void IWIViewer::SetIWIFile(const IWIFile* aIWIFile) {
mIWIFile = aIWIFile; // mIWIFile = aIWIFile;
ui->label_Title->setText(mIWIFile->fileStem + ".iwi"); // ui->label_Title->setText(mIWIFile->fileStem + ".iwi");
// If youre using Qt and want a QString: // // If youre using Qt and want a QString:
QString magicStr = QString::fromLatin1(mIWIFile->header.Magic, 3); // QString magicStr = QString::fromLatin1(mIWIFile->header.Magic, 3);
ui->lineEdit_Magic->setText(magicStr); // ui->lineEdit_Magic->setText(magicStr);
ui->spinBox_Version->setValue(mIWIFile->header.Version); // ui->spinBox_Version->setValue(mIWIFile->header.Version);
ui->spinBox_Depth->setValue(mIWIFile->info.Depth); // ui->spinBox_Depth->setValue(mIWIFile->info.Depth);
QString formatStr = ""; // QString formatStr = "";
switch (mIWIFile->info.Format) { // switch (mIWIFile->info.Format) {
case IWI_FORMAT_ARGB32: // case IWI_FORMAT_ARGB32:
formatStr = "ARGB32"; // formatStr = "ARGB32";
break; // break;
case IWI_FORMAT_RGB24: // case IWI_FORMAT_RGB24:
formatStr = "RGB24"; // formatStr = "RGB24";
break; // break;
case IWI_FORMAT_GA16: // case IWI_FORMAT_GA16:
formatStr = "GA16"; // formatStr = "GA16";
break; // break;
case IWI_FORMAT_A8: // case IWI_FORMAT_A8:
formatStr = "A8"; // formatStr = "A8";
break; // break;
case IWI_FORMAT_DXT1: // case IWI_FORMAT_DXT1:
formatStr = "DXT1"; // formatStr = "DXT1";
break; // break;
case IWI_FORMAT_DXT3: // case IWI_FORMAT_DXT3:
formatStr = "DXT3"; // formatStr = "DXT3";
break; // break;
case IWI_FORMAT_DXT5: // case IWI_FORMAT_DXT5:
formatStr = "DXT5"; // formatStr = "DXT5";
break; // break;
} // }
ui->lineEdit_Format->setText(formatStr); // ui->lineEdit_Format->setText(formatStr);
ui->spinBox_Height->setValue(mIWIFile->info.Height); // ui->spinBox_Height->setValue(mIWIFile->info.Height);
ui->spinBox_Width->setValue(mIWIFile->info.Width); // ui->spinBox_Width->setValue(mIWIFile->info.Width);
ui->spinBox_Usage->setValue(mIWIFile->info.Usage); // ui->spinBox_Usage->setValue(mIWIFile->info.Usage);
ui->comboBox_Mipmap->clear(); // ui->comboBox_Mipmap->clear();
for (auto mipmap : mIWIFile->mipmaps) { // for (auto mipmap : mIWIFile->mipmaps) {
ui->comboBox_Mipmap->addItem(QString::number(mipmap.offset)); // ui->comboBox_Mipmap->addItem(QString::number(mipmap.offset));
} // }
connect(ui->comboBox_Mipmap, &QComboBox::currentIndexChanged, this, &IWIViewer::MipmapIndexChanged); // connect(ui->comboBox_Mipmap, &QComboBox::currentIndexChanged, this, &IWIViewer::MipmapIndexChanged);
if (!mIWIFile->mipmaps.empty()) { // if (!mIWIFile->mipmaps.empty()) {
MipmapIndexChanged(0); // MipmapIndexChanged(0);
} // }
} // }
void IWIViewer::MipmapIndexChanged(int aMipmapIndex) { // void IWIViewer::MipmapIndexChanged(int aMipmapIndex) {
auto mipmaps = mIWIFile->mipmaps; // auto mipmaps = mIWIFile->mipmaps;
if (aMipmapIndex == -1) { return; } // if (aMipmapIndex == -1) { return; }
auto mipmap = mipmaps[aMipmapIndex]; // auto mipmap = mipmaps[aMipmapIndex];
ui->spinBox_MipmapSize->setValue(mipmap.size); // ui->spinBox_MipmapSize->setValue(mipmap.size);
ui->spinBox_MipmapOffset->setValue(mipmap.offset); // ui->spinBox_MipmapOffset->setValue(mipmap.offset);
const unsigned char* imageData = reinterpret_cast<const unsigned char*>(mipmap.data.constData()); // const unsigned char* imageData = reinterpret_cast<const unsigned char*>(mipmap.data.constData());
QImage image(reinterpret_cast<const uchar*>(imageData), // QImage image(reinterpret_cast<const uchar*>(imageData),
mIWIFile->info.Width, mIWIFile->info.Height, // mIWIFile->info.Width, mIWIFile->info.Height,
QImage::Format_RGBA8888); // QImage::Format_RGBA8888);
if (image.isNull()) { // if (image.isNull()) {
qDebug() << "Error: QImage creation failed!"; // qDebug() << "Error: QImage creation failed!";
return; // return;
} // }
// Convert to QPixmap // // Convert to QPixmap
QPixmap pixmap = QPixmap::fromImage(image); // QPixmap pixmap = QPixmap::fromImage(image);
if (pixmap.isNull()) { // if (pixmap.isNull()) {
qDebug() << "Error: QPixmap conversion failed!"; // qDebug() << "Error: QPixmap conversion failed!";
return; // return;
} // }
// Scale and display // // Scale and display
pixmap = pixmap.scaled(ui->label_Image->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); // pixmap = pixmap.scaled(ui->label_Image->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
ui->label_Image->setPixmap(pixmap); // ui->label_Image->setPixmap(pixmap);
} // }

View File

@ -1,7 +1,7 @@
#ifndef IWIVIEWER_H #ifndef IWIVIEWER_H
#define IWIVIEWER_H #define IWIVIEWER_H
#include "iwifile.h" //#include "iwifile.h"
#include <QWidget> #include <QWidget>
namespace Ui { namespace Ui {
@ -18,10 +18,10 @@ public:
void MipmapIndexChanged(int aMipmapIndex); void MipmapIndexChanged(int aMipmapIndex);
void SetIWIFile(const IWIFile *aIWIFile); //void SetIWIFile(const IWIFile *aIWIFile);
private: private:
Ui::IWIViewer *ui; Ui::IWIViewer *ui;
const IWIFile* mIWIFile; //const IWIFile* mIWIFile;
}; };
#endif // IWIVIEWER_H #endif // IWIVIEWER_H

View File

@ -42,7 +42,7 @@ void LocalStringViewer::AddLocalString(XLocalizeEntry aLocalString) {
ui->tableWidget_Strings->setRowCount(mLocalStrings.size()); ui->tableWidget_Strings->setRowCount(mLocalStrings.size());
ui->groupBox_LocalStrViewer->setTitle(QString("Entries (%1)").arg(mLocalStrings.size())); ui->groupBox_LocalStrViewer->setTitle(QString("Entries (%1)").arg(mLocalStrings.size()));
QTableWidgetItem *aliasItem = new QTableWidgetItem(aLocalString.GetValue()->GetString()); QTableWidgetItem *aliasItem = new QTableWidgetItem(aLocalString.GetValue()->GetString());
QTableWidgetItem *stringItem = new QTableWidgetItem(aLocalString.GetName()->GetString()); QTableWidgetItem *stringItem = new QTableWidgetItem(aLocalString.LocalizeEntryName()->GetString());
ui->tableWidget_Strings->setItem(mLocalStrings.size() - 1, 0, aliasItem); ui->tableWidget_Strings->setItem(mLocalStrings.size() - 1, 0, aliasItem);
ui->tableWidget_Strings->setItem(mLocalStrings.size() - 1, 1, stringItem); ui->tableWidget_Strings->setItem(mLocalStrings.size() - 1, 1, stringItem);
} }

View File

@ -15,12 +15,8 @@
#include "stringtableviewer.h" #include "stringtableviewer.h"
#include "techsetviewer.h" #include "techsetviewer.h"
#include "fastfile_factory.h" #include "fastfile_factory.h"
#include "iwifile.h"
#include "ddsfile.h"
#include "statusbarmanager.h" #include "statusbarmanager.h"
#include "ddsviewer.h"
#include "fastfileviewer.h" #include "fastfileviewer.h"
#include "ipak_structs.h"
#include "iwiviewer.h" #include "iwiviewer.h"
#include "localstringviewer.h" #include "localstringviewer.h"
#include "zonefileviewer.h" #include "zonefileviewer.h"
@ -33,9 +29,9 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) { : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this); ui->setupUi(this);
setAcceptDrops(true); XAsset::SetDebug(false);
XAsset::SetDebug(true); setAcceptDrops(true);
mTypeMap = QMap<QString, int>(); mTypeMap = QMap<QString, int>();
mTypeOrder = QStringList(); mTypeOrder = QStringList();
@ -82,6 +78,11 @@ MainWindow::MainWindow(QWidget *parent)
Q_UNUSED(checked); Q_UNUSED(checked);
PreferenceEditor *prefEditor = new PreferenceEditor(this); PreferenceEditor *prefEditor = new PreferenceEditor(this);
connect(prefEditor, &PreferenceEditor::DebugModeChanged, this, [](bool aEnable) {
XAsset::SetDebug(aEnable);
});
prefEditor->exec(); prefEditor->exec();
}); });
@ -168,13 +169,13 @@ MainWindow::MainWindow(QWidget *parent)
scriptEditor->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); scriptEditor->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
scriptEditor->setFont(QFont("Consolas")); scriptEditor->setFont(QFont("Consolas"));
// if (rawFile->contents.isEmpty()) { if (rawFile->Buffer().isEmpty()) {
// scriptEditor->setPlainText("EMPTY"); scriptEditor->setPlainText("EMPTY");
// } else { } else {
// scriptEditor->setPlainText(rawFile->contents); scriptEditor->setPlainText(QString::fromUtf8(rawFile->Buffer()));
// } }
QString fileStem;// = rawFile->path.split('/').last(); QString fileStem = rawFile->DisplayName().split('/').last();
for (int i = 0; i < ui->tabWidget->count(); i++) { for (int i = 0; i < ui->tabWidget->count(); i++) {
if (ui->tabWidget->tabText(i) == fileStem) { if (ui->tabWidget->tabText(i) == fileStem) {
delete scriptEditor; delete scriptEditor;
@ -265,48 +266,48 @@ MainWindow::MainWindow(QWidget *parent)
// } // }
// } // }
//ui->tabWidget->addTab(matViewer, fileStem); ui->tabWidget->addTab(matViewer, aParentName);
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_MATERIAL)); ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_MATERIAL));
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
}); });
connect(mTreeWidget, &XTreeWidget::DDSFileSelected, this, [this](const DDSFile* ddsFile, const QString aParentName) { //connect(mTreeWidget, &XTreeWidget::DDSFileSelected, this, [this](const DDSFile* ddsFile, const QString aParentName) {
DDSViewer *ddsViewer = new DDSViewer(this); // DDSViewer *ddsViewer = new DDSViewer(this);
ddsViewer->setAcceptDrops(false); // ddsViewer->setAcceptDrops(false);
ddsViewer->SetDDSFile(ddsFile); // ddsViewer->SetDDSFile(ddsFile);
ddsViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); // ddsViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
QString fileStem = ddsFile->fileStem + ".dds"; // QString fileStem = ddsFile->fileStem + ".dds";
for (int i = 0; i < ui->tabWidget->count(); i++) { // for (int i = 0; i < ui->tabWidget->count(); i++) {
if (ui->tabWidget->tabText(i) == fileStem) { // if (ui->tabWidget->tabText(i) == fileStem) {
delete ddsViewer; // delete ddsViewer;
return; // return;
} // }
} // }
ui->tabWidget->addTab(ddsViewer, fileStem); // ui->tabWidget->addTab(ddsViewer, fileStem);
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE)); // ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE));
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); // ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
}); //});
connect(mTreeWidget, &XTreeWidget::IWIFileSelected, this, [this](const IWIFile* iwiFile, const QString aParentName) { // connect(mTreeWidget, &XTreeWidget::IWIFileSelected, this, [this](const IWIFile* iwiFile, const QString aParentName) {
IWIViewer *iwiViewer = new IWIViewer(this); // IWIViewer *iwiViewer = new IWIViewer(this);
iwiViewer->setAcceptDrops(false); // iwiViewer->setAcceptDrops(false);
iwiViewer->SetIWIFile(iwiFile); // iwiViewer->SetIWIFile(iwiFile);
iwiViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); // iwiViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
QString fileStem = iwiFile->fileStem + ".iwi"; // QString fileStem = iwiFile->fileStem + ".iwi";
for (int i = 0; i < ui->tabWidget->count(); i++) { // for (int i = 0; i < ui->tabWidget->count(); i++) {
if (ui->tabWidget->tabText(i) == fileStem) { // if (ui->tabWidget->tabText(i) == fileStem) {
delete iwiViewer; // delete iwiViewer;
return; // return;
} // }
} // }
ui->tabWidget->addTab(iwiViewer, fileStem); // ui->tabWidget->addTab(iwiViewer, fileStem);
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE)); // ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE));
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); // ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
}); // });
connect(mTreeWidget, &XTreeWidget::FastFileSelected, this, [this](const FastFile* aFastFile, const QString aParentName) { connect(mTreeWidget, &XTreeWidget::FastFileSelected, this, [this](const FastFile* aFastFile, const QString aParentName) {
FastFileViewer *fastFileViewer = new FastFileViewer(this); FastFileViewer *fastFileViewer = new FastFileViewer(this);
@ -383,7 +384,7 @@ MainWindow::MainWindow(QWidget *parent)
techSetViewer->SetTechSet(aTechSet); techSetViewer->SetTechSet(aTechSet);
techSetViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); techSetViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
QString fileStem = aTechSet->GetName(); QString fileStem = aTechSet->TechniqueSetName().GetString();
for (int i = 0; i < ui->tabWidget->count(); i++) { for (int i = 0; i < ui->tabWidget->count(); i++) {
if (ui->tabWidget->tabText(i) == fileStem) { if (ui->tabWidget->tabText(i) == fileStem) {
delete techSetViewer; delete techSetViewer;
@ -391,7 +392,7 @@ MainWindow::MainWindow(QWidget *parent)
} }
} }
ui->tabWidget->addTab(techSetViewer, aTechSet->GetName()); ui->tabWidget->addTab(techSetViewer, aTechSet->TechniqueSetName().GetString());
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_TECHNIQUE_SET)); ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, Utils::CreateAssetIcon(ASSET_TYPE_TECHNIQUE_SET));
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1); ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
}); });
@ -402,7 +403,7 @@ MainWindow::MainWindow(QWidget *parent)
strTableViewer->SetStringTable(aStrTable); strTableViewer->SetStringTable(aStrTable);
strTableViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName)); strTableViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
QString fileStem = aStrTable->GetName()->GetString(); QString fileStem = aStrTable->StringTableName()->GetString();
for (int i = 0; i < ui->tabWidget->count(); i++) { for (int i = 0; i < ui->tabWidget->count(); i++) {
if (ui->tabWidget->tabText(i) == fileStem) { if (ui->tabWidget->tabText(i) == fileStem) {
delete strTableViewer; delete strTableViewer;
@ -482,7 +483,7 @@ MainWindow::MainWindow(QWidget *parent)
QDockWidget *logDockWidget = new QDockWidget(this); QDockWidget *logDockWidget = new QDockWidget(this);
logDockWidget->setWidget(mLogWidget); logDockWidget->setWidget(mLogWidget);
logDockWidget->setWindowTitle("Logs"); logDockWidget->setWindowTitle("Logs");
addDockWidget(Qt::RightDockWidgetArea, logDockWidget); addDockWidget(Qt::BottomDockWidgetArea, logDockWidget);
ui->toolBar->addAction(ui->actionNew_Fast_File); ui->toolBar->addAction(ui->actionNew_Fast_File);
ui->toolBar->addAction(ui->actionNew_Zone_File); ui->toolBar->addAction(ui->actionNew_Zone_File);
@ -673,21 +674,21 @@ quint32 DXT3 = 0x33545844; // 'DXT3'
quint32 DXT5 = 0x35545844; // 'DXT5' quint32 DXT5 = 0x35545844; // 'DXT5'
int MainWindow::LoadFile_IWI(const QString aFilePath) { int MainWindow::LoadFile_IWI(const QString aFilePath) {
mTreeWidget->AddIWIFile(new IWIFile(aFilePath)); //mTreeWidget->AddIWIFile(new IWIFile(aFilePath));
return 0; return 0;
} }
int MainWindow::LoadFile_DDSFiles(const QStringList aFilePaths) { // int MainWindow::LoadFile_DDSFiles(const QStringList aFilePaths) {
for (const QString &filePath : aFilePaths) { // for (const QString &filePath : aFilePaths) {
if (!filePath.endsWith(".dds", Qt::CaseInsensitive)) { // if (!filePath.endsWith(".dds", Qt::CaseInsensitive)) {
qDebug() << "Error: Invalid filename " << filePath; // qDebug() << "Error: Invalid filename " << filePath;
return -1; // return -1;
} // }
mTreeWidget->AddDDSFile(new DDSFile(filePath)); // mTreeWidget->AddDDSFile(new DDSFile(filePath));
} // }
return 0; // return 0;
} // }
void MainWindow::HandleLogEntry(const QString &entry) { void MainWindow::HandleLogEntry(const QString &entry) {
QString logContents = mLogWidget->toPlainText() + "\n" + entry; QString logContents = mLogWidget->toPlainText() + "\n" + entry;
@ -711,14 +712,14 @@ void MainWindow::HandleProgressUpdate(const QString &message, int progress, int
statusBar()->showMessage(progressText); statusBar()->showMessage(progressText);
} }
int MainWindow::LoadFile_DDS(const QString aFilePath) { // int MainWindow::LoadFile_DDS(const QString aFilePath) {
if (!aFilePath.endsWith(".dds", Qt::CaseInsensitive)) { // if (!aFilePath.endsWith(".dds", Qt::CaseInsensitive)) {
qDebug() << "Error: Invalid filename " << aFilePath; // qDebug() << "Error: Invalid filename " << aFilePath;
return -1; // return -1;
} // }
mTreeWidget->AddDDSFile(new DDSFile(aFilePath)); // mTreeWidget->AddDDSFile(new DDSFile(aFilePath));
return 0; // return 0;
} // }
int MainWindow::LoadFile_XSUB(const QString aFilePath) { int MainWindow::LoadFile_XSUB(const QString aFilePath) {
QFile file(aFilePath); QFile file(aFilePath);
@ -757,130 +758,130 @@ int MainWindow::LoadFile_IPAK(const QString aFilePath) {
QDataStream stream(&file); QDataStream stream(&file);
stream.setByteOrder(QDataStream::BigEndian); stream.setByteOrder(QDataStream::BigEndian);
IPAKHeader header; // IPAKHeader header;
stream >> header; // stream >> header;
if (header.version == "50000") { // if (header.version == "50000") {
if (header.magic == "KAPI") { // if (header.magic == "KAPI") {
stream.setByteOrder(QDataStream::LittleEndian); // stream.setByteOrder(QDataStream::LittleEndian);
} else if (header.magic == "IPAK") { // } else if (header.magic == "IPAK") {
stream.setByteOrder(QDataStream::BigEndian); // stream.setByteOrder(QDataStream::BigEndian);
} else { // } else {
qDebug() << "Invalid IPAK file!"; // qDebug() << "Invalid IPAK file!";
return -1; // return -1;
} // }
} else { // } else {
qDebug() << "Invalid IPAK file version!"; // qDebug() << "Invalid IPAK file version!";
return -1; // return -1;
} // }
qDebug() << "IPAK File " << "\n" // qDebug() << "IPAK File " << "\n"
<< "- Platform: " << header.platform << "\n" // << "- Platform: " << header.platform << "\n"
<< "- Magic: " << header.magic << "\n" // << "- Magic: " << header.magic << "\n"
<< "- Size: " << header.size << "\n" // << "- Size: " << header.size << "\n"
<< "- Version: " << header.version << "\n" // << "- Version: " << header.version << "\n"
<< "- Sections: " << header.sectionCount; // << "- Sections: " << header.sectionCount;
QDir outputFolder = QDir(QDir::currentPath() + "/output"); // QDir outputFolder = QDir(QDir::currentPath() + "/output");
outputFolder.remove(QDir::currentPath() + "/output"); // outputFolder.remove(QDir::currentPath() + "/output");
outputFolder.mkdir(QDir::currentPath() + "/output"); // outputFolder.mkdir(QDir::currentPath() + "/output");
QVector<IPAKDataChunkMetaData> metas = QVector<IPAKDataChunkMetaData>(); // QVector<IPAKDataChunkMetaData> metas = QVector<IPAKDataChunkMetaData>();
QVector<IPAKIndexEntry> entries = QVector<IPAKIndexEntry>(); // QVector<IPAKIndexEntry> entries = QVector<IPAKIndexEntry>();
QVector<IPAKSection> sections = QVector<IPAKSection>(header.sectionCount); // QVector<IPAKSection> sections = QVector<IPAKSection>(header.sectionCount);
for (quint32 i = 0; i < header.sectionCount; i++) { // for (quint32 i = 0; i < header.sectionCount; i++) {
IPAKSection currentSection; // IPAKSection currentSection;
stream >> currentSection; // stream >> currentSection;
sections << currentSection; // sections << currentSection;
qDebug() << " - IPAK Section " << i + 1 << "\n" // qDebug() << " - IPAK Section " << i + 1 << "\n"
<< " - Type: " << currentSection.type << " -> " << currentSection.typeInt << "\n" // << " - Type: " << currentSection.type << " -> " << currentSection.typeInt << "\n"
<< " - Offset: " << currentSection.offset << "\n" // << " - Offset: " << currentSection.offset << "\n"
<< " - Item (IWI) Count: " << currentSection.itemCount << "\n" // << " - Item (IWI) Count: " << currentSection.itemCount << "\n"
<< " - Size: " << currentSection.size; // << " - Size: " << currentSection.size;
qint64 sectionPos = stream.device()->pos(); // qint64 sectionPos = stream.device()->pos();
stream.device()->seek(currentSection.offset); // stream.device()->seek(currentSection.offset);
QString sectionType = currentSection.type; // QString sectionType = currentSection.type;
if (sectionType == "Data") { // if (sectionType == "Data") {
IPAKDataChunkHeader chunkHeader; // IPAKDataChunkHeader chunkHeader;
stream >> chunkHeader; // stream >> chunkHeader;
qDebug() << " - Chunk Header\n" // qDebug() << " - Chunk Header\n"
<< " - Count: " << chunkHeader.count << "\n" // << " - Count: " << chunkHeader.count << "\n"
<< " - Offset: " << chunkHeader.offset; // << " - Offset: " << chunkHeader.offset;
for (quint32 j = 0; j < 31; j++) { // for (quint32 j = 0; j < 31; j++) {
IPAKDataChunkCommand command; // IPAKDataChunkCommand command;
stream >> command; // stream >> command;
if (!command.size) { continue; } // if (!command.size) { continue; }
chunkHeader.commands << command; // chunkHeader.commands << command;
qDebug() << " - Command\n" // qDebug() << " - Command\n"
<< " - Size: " << command.size << "\n" // << " - Size: " << command.size << "\n"
<< " - Compressed: " << command.compressed; // << " - Compressed: " << command.compressed;
} // }
for (quint32 j = 0; j < chunkHeader.count; j++) { // for (quint32 j = 0; j < chunkHeader.count; j++) {
auto command = chunkHeader.commands[j]; // auto command = chunkHeader.commands[j];
qDebug() << "Reading from " << stream.device()->pos(); // qDebug() << "Reading from " << stream.device()->pos();
QByteArray data = stream.device()->read(command.size); // QByteArray data = stream.device()->read(command.size);
qDebug() << " to " << stream.device()->pos(); // qDebug() << " to " << stream.device()->pos();
QString outputFilePath = outputFolder.filePath(QString("%1.iwi").arg(j)); // QString outputFilePath = outputFolder.filePath(QString("%1.iwi").arg(j));
if (command.compressed) { // if (command.compressed) {
//data = Compression::DecompressLZO(data); // //data = Compression::DecompressLZO(data);
} // }
QFile outputFile(outputFilePath); // QFile outputFile(outputFilePath);
if (!outputFile.open(QIODevice::WriteOnly)) { // if (!outputFile.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to extract IPAK file."; // qDebug() << "Failed to extract IPAK file.";
} // }
qDebug() << " - File Name: " << outputFile.fileName(); // qDebug() << " - File Name: " << outputFile.fileName();
outputFile.write(data); // outputFile.write(data);
outputFile.close(); // outputFile.close();
} // }
qDebug() << stream.device()->pos(); // qDebug() << stream.device()->pos();
stream.skipRawData(sizeof(quint32) * (31 - chunkHeader.count)); // stream.skipRawData(sizeof(quint32) * (31 - chunkHeader.count));
qDebug() << stream.device()->pos(); // qDebug() << stream.device()->pos();
} else if (sectionType == "Index") { // } else if (sectionType == "Index") {
for (quint32 j = 0; j < currentSection.itemCount; j++) { // for (quint32 j = 0; j < currentSection.itemCount; j++) {
IPAKIndexEntry entry; // IPAKIndexEntry entry;
stream >> entry; // stream >> entry;
if (entry.size == 0) { continue; } // if (entry.size == 0) { continue; }
entries << entry; // entries << entry;
quint64 entryPos = stream.device()->pos(); // quint64 entryPos = stream.device()->pos();
qDebug() << " - Index Entry " << j + 1 << "\n" // qDebug() << " - Index Entry " << j + 1 << "\n"
<< " - Name Hash: " << entry.nameHash << "\n" // << " - Name Hash: " << entry.nameHash << "\n"
<< " - Data Hash: " << entry.dataHash << "\n" // << " - Data Hash: " << entry.dataHash << "\n"
<< " - Offset: " << entry.offset << "\n" // << " - Offset: " << entry.offset << "\n"
<< " - Size: " << entry.size; // << " - Size: " << entry.size;
stream.device()->seek(entry.offset); // stream.device()->seek(entry.offset);
QByteArray sectionData(entry.size, Qt::Uninitialized); // QByteArray sectionData(entry.size, Qt::Uninitialized);
stream.readRawData(sectionData.data(), entry.size); // stream.readRawData(sectionData.data(), entry.size);
const QString entryKey = QString::number(entry.nameHash); // const QString entryKey = QString::number(entry.nameHash);
QFile outputFile(outputFolder.filePath(QString("%1.dds").arg(entryKey))); // QFile outputFile(outputFolder.filePath(QString("%1.dds").arg(entryKey)));
if (!outputFile.open(QIODevice::WriteOnly)) { // if (!outputFile.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to extract IPAK file."; // qDebug() << "Failed to extract IPAK file.";
} // }
qDebug() << " - File Name: " << outputFile.fileName(); // qDebug() << " - File Name: " << outputFile.fileName();
outputFile.write(sectionData); // outputFile.write(sectionData);
outputFile.close(); // outputFile.close();
stream.device()->seek(entryPos); // stream.device()->seek(entryPos);
} // }
} // }
stream.device()->seek(sectionPos); // stream.device()->seek(sectionPos);
qDebug() << stream.device()->pos(); // qDebug() << stream.device()->pos();
} // }
return 0; // Success return 0; // Success
} }
@ -891,6 +892,7 @@ void MainWindow::dragEnterEvent(QDragEnterEvent *event) {
if (mimeData->hasUrls()) { if (mimeData->hasUrls()) {
foreach (const QUrl url, mimeData->urls()) { foreach (const QUrl url, mimeData->urls()) {
if (!url.toString().contains(".ff") && if (!url.toString().contains(".ff") &&
!url.toString().contains(".fp") &&
!url.toString().contains(".zone") && !url.toString().contains(".zone") &&
!url.toString().contains(".ipak") && !url.toString().contains(".ipak") &&
!url.toString().contains(".d3dbsp") && !url.toString().contains(".d3dbsp") &&
@ -925,7 +927,7 @@ void MainWindow::dropEvent(QDropEvent *event) {
const QString urlStr = url.toLocalFile(); const QString urlStr = url.toLocalFile();
if (urlStr.contains(".zone")) { if (urlStr.contains(".zone")) {
qDebug() << "OpenZoneFile Returned: " << OpenZoneFile(urlStr); qDebug() << "OpenZoneFile Returned: " << OpenZoneFile(urlStr);
} else if (urlStr.contains(".ff")) { } else if (urlStr.contains(".ff") || urlStr.contains(".fp")) {
qDebug() << "OpenFastFile Returned: " << OpenFastFile(urlStr); qDebug() << "OpenFastFile Returned: " << OpenFastFile(urlStr);
} else if (urlStr.contains(".ipak")) { } else if (urlStr.contains(".ipak")) {
qDebug() << "LoadFile_IPAK Returned: " << LoadFile_IPAK(urlStr); qDebug() << "LoadFile_IPAK Returned: " << LoadFile_IPAK(urlStr);
@ -935,7 +937,7 @@ void MainWindow::dropEvent(QDropEvent *event) {
qDebug() << "LoadFile_IWI Returned: " << LoadFile_IWI(urlStr); qDebug() << "LoadFile_IWI Returned: " << LoadFile_IWI(urlStr);
} else if (urlStr.contains(".dds")) { } else if (urlStr.contains(".dds")) {
if (mimeData->urls().size() == 1) { if (mimeData->urls().size() == 1) {
qDebug() << "LoadFile_DDS Returned: " << LoadFile_DDS(urlStr); //qDebug() << "LoadFile_DDS Returned: " << LoadFile_DDS(urlStr);
} else { } else {
ddsPaths << urlStr; ddsPaths << urlStr;
} }
@ -969,7 +971,7 @@ void MainWindow::dropEvent(QDropEvent *event) {
} }
} }
if (ddsPaths.size() > 1) { if (ddsPaths.size() > 1) {
qDebug() << "LoadFile_DDSFiles Returned: " << LoadFile_DDSFiles(ddsPaths); //qDebug() << "LoadFile_DDSFiles Returned: " << LoadFile_DDSFiles(ddsPaths);
} }
} else { } else {
ui->statusBar->showMessage("Can't display dropped data!"); ui->statusBar->showMessage("Can't display dropped data!");

View File

@ -43,8 +43,6 @@ private slots:
int LoadFile_IPAK(const QString aFilePath); int LoadFile_IPAK(const QString aFilePath);
int LoadFile_XSUB(const QString aFilePath); int LoadFile_XSUB(const QString aFilePath);
int LoadFile_IWI(const QString aFilePath); int LoadFile_IWI(const QString aFilePath);
int LoadFile_DDS(const QString aFilePath);
int LoadFile_DDSFiles(const QStringList aFilePaths);
void HandleLogEntry(const QString &entry); void HandleLogEntry(const QString &entry);
void HandleStatusUpdate(const QString &message, int timeout); void HandleStatusUpdate(const QString &message, int timeout);

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1001</width> <width>780</width>
<height>897</height> <height>644</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -15,10 +15,22 @@
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="QToolBox" name="toolBox">
<property name="title"> <property name="currentIndex">
<string>Properties</string> <number>0</number>
</property> </property>
<widget class="QWidget" name="page_data">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>762</width>
<height>566</height>
</rect>
</property>
<attribute name="label">
<string>Model Data</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
@ -251,196 +263,207 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="0"> </layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_25"> <widget class="QLabel" name="label_25">
<property name="text"> <property name="text">
<string>Contents:</string> <string>Contents:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="1"> <item row="0" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_4"> <widget class="QSpinBox" name="spinBox_ClassPtr_4">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="17" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_26"> <widget class="QLabel" name="label_26">
<property name="text"> <property name="text">
<string>Bone Info Pointer:</string> <string>Bone Info Pointer:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="17" column="1"> <item row="1" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_5"> <widget class="QSpinBox" name="spinBox_ClassPtr_5">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="18" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_28"> <widget class="QLabel" name="label_28">
<property name="text"> <property name="text">
<string>Radius:</string> <string>Radius:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="18" column="1"> <item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_2"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_2"/>
</item> </item>
<item row="19" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_29"> <widget class="QLabel" name="label_29">
<property name="text"> <property name="text">
<string>Min X: </string> <string>Min X: </string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="19" column="1"> <item row="3" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_3"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_3"/>
</item> </item>
<item row="20" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_30"> <widget class="QLabel" name="label_30">
<property name="text"> <property name="text">
<string>Min Y: </string> <string>Min Y: </string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="20" column="1"> <item row="4" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_4"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_4"/>
</item> </item>
<item row="21" column="0"> <item row="5" column="0">
<widget class="QLabel" name="label_31"> <widget class="QLabel" name="label_31">
<property name="text"> <property name="text">
<string>Min Z: </string> <string>Min Z: </string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="21" column="1"> <item row="5" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_5"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_5"/>
</item> </item>
<item row="22" column="0"> <item row="6" column="0">
<widget class="QLabel" name="label_32"> <widget class="QLabel" name="label_32">
<property name="text"> <property name="text">
<string>Max X: </string> <string>Max X: </string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="22" column="1"> <item row="6" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_6"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_6"/>
</item> </item>
<item row="23" column="0"> <item row="7" column="0">
<widget class="QLabel" name="label_33"> <widget class="QLabel" name="label_33">
<property name="text"> <property name="text">
<string>Max Y: </string> <string>Max Y: </string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="23" column="1"> <item row="7" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_7"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_7"/>
</item> </item>
<item row="24" column="0"> <item row="8" column="0">
<widget class="QLabel" name="label_34"> <widget class="QLabel" name="label_34">
<property name="text"> <property name="text">
<string>Max Z: </string> <string>Max Z: </string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="24" column="1"> <item row="8" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_8"/> <widget class="QDoubleSpinBox" name="doubleSpinBox_8"/>
</item> </item>
<item row="25" column="0"> <item row="9" column="0">
<widget class="QLabel" name="label_35"> <widget class="QLabel" name="label_35">
<property name="text"> <property name="text">
<string>Lod Count:</string> <string>Lod Count:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="25" column="1"> <item row="9" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_7"> <widget class="QSpinBox" name="spinBox_ClassPtr_7">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="26" column="0"> <item row="10" column="0">
<widget class="QLabel" name="label_36"> <widget class="QLabel" name="label_36">
<property name="text"> <property name="text">
<string>Coll Lod:</string> <string>Coll Lod:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="26" column="1"> <item row="10" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_8"> <widget class="QSpinBox" name="spinBox_ClassPtr_8">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="27" column="0"> <item row="11" column="0">
<widget class="QLabel" name="label_37"> <widget class="QLabel" name="label_37">
<property name="text"> <property name="text">
<string>Stream Info Pointer:</string> <string>Stream Info Pointer:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="27" column="1"> <item row="11" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_9"> <widget class="QSpinBox" name="spinBox_ClassPtr_9">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="28" column="0"> <item row="12" column="0">
<widget class="QLabel" name="label_38"> <widget class="QLabel" name="label_38">
<property name="text"> <property name="text">
<string>Memory Usage:</string> <string>Memory Usage:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="28" column="1"> <item row="12" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_10"> <widget class="QSpinBox" name="spinBox_ClassPtr_10">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="29" column="0"> <item row="13" column="0">
<widget class="QLabel" name="label_39"> <widget class="QLabel" name="label_39">
<property name="text"> <property name="text">
<string>Flags:</string> <string>Flags:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="29" column="1"> <item row="13" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_11"> <widget class="QSpinBox" name="spinBox_ClassPtr_11">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="30" column="0"> <item row="14" column="0">
<widget class="QLabel" name="label_40"> <widget class="QLabel" name="label_40">
<property name="text"> <property name="text">
<string>Phys Preset Pointer:</string> <string>Phys Preset Pointer:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="30" column="1"> <item row="14" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_12"> <widget class="QSpinBox" name="spinBox_ClassPtr_12">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="31" column="0"> <item row="15" column="0">
<widget class="QLabel" name="label_41"> <widget class="QLabel" name="label_41">
<property name="text"> <property name="text">
<string>Phys Geometry Pointer:</string> <string>Phys Geometry Pointer:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="31" column="1"> <item row="15" column="1">
<widget class="QSpinBox" name="spinBox_ClassPtr_13"> <widget class="QSpinBox" name="spinBox_ClassPtr_13">
<property name="maximum"> <property name="maximum">
<number>1000000000</number> <number>1000000000</number>
@ -449,6 +472,13 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
</widget>
</item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
@ -602,19 +632,19 @@
</item> </item>
</layout> </layout>
</widget> </widget>
</item> <widget class="QWidget" name="page_3d">
<item> <property name="geometry">
<widget class="Line" name="line"> <rect>
<property name="orientation"> <x>0</x>
<enum>Qt::Orientation::Vertical</enum> <y>0</y>
<width>762</width>
<height>566</height>
</rect>
</property> </property>
<attribute name="label">
<string>3D View</string>
</attribute>
</widget> </widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3DWindow">
<property name="title">
<string>3D Window</string>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -27,6 +27,8 @@ PreferenceEditor::PreferenceEditor(QWidget *parent)
ui->frame_FileEditors->show(); ui->frame_FileEditors->show();
} }
}); });
connect(ui->checkBox_DebugMode, &QCheckBox::clicked, this, &PreferenceEditor::DebugModeChanged);
} }
PreferenceEditor::~PreferenceEditor() PreferenceEditor::~PreferenceEditor()

View File

@ -15,6 +15,9 @@ public:
explicit PreferenceEditor(QWidget *parent = nullptr); explicit PreferenceEditor(QWidget *parent = nullptr);
~PreferenceEditor(); ~PreferenceEditor();
signals:
void DebugModeChanged(bool aEnable);
private: private:
Ui::PreferenceEditor *ui; Ui::PreferenceEditor *ui;
}; };

View File

@ -73,14 +73,14 @@
</font> </font>
</property> </property>
<property name="currentRow"> <property name="currentRow">
<number>0</number> <number>-1</number>
</property> </property>
<item> <item>
<property name="text"> <property name="text">
<string>View</string> <string>View</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="data/Data.qrc"> <iconset resource="../data/data.qrc">
<normaloff>:/icons/icons/Icon_Views.png</normaloff>:/icons/icons/Icon_Views.png</iconset> <normaloff>:/icons/icons/Icon_Views.png</normaloff>:/icons/icons/Icon_Views.png</iconset>
</property> </property>
</item> </item>
@ -89,7 +89,7 @@
<string>Tree Widget</string> <string>Tree Widget</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="data/Data.qrc"> <iconset resource="../data/data.qrc">
<normaloff>:/icons/icons/Icon_Tree.png</normaloff>:/icons/icons/Icon_Tree.png</iconset> <normaloff>:/icons/icons/Icon_Tree.png</normaloff>:/icons/icons/Icon_Tree.png</iconset>
</property> </property>
</item> </item>
@ -98,12 +98,19 @@
<string>File Editors</string> <string>File Editors</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="data/Data.qrc"> <iconset resource="../data/data.qrc">
<normaloff>:/icons/icons/Icon_Editor.png</normaloff>:/icons/icons/Icon_Editor.png</iconset> <normaloff>:/icons/icons/Icon_Editor.png</normaloff>:/icons/icons/Icon_Editor.png</iconset>
</property> </property>
</item> </item>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="checkBox_DebugMode">
<property name="text">
<string>Enable Debug Mode</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -135,7 +142,7 @@
<string/> <string/>
</property> </property>
<property name="pixmap"> <property name="pixmap">
<pixmap resource="data/Data.qrc">:/icons/icons/Icon_Views.png</pixmap> <pixmap resource="../data/data.qrc">:/icons/icons/Icon_Views.png</pixmap>
</property> </property>
<property name="scaledContents"> <property name="scaledContents">
<bool>true</bool> <bool>true</bool>
@ -292,7 +299,7 @@
<string/> <string/>
</property> </property>
<property name="pixmap"> <property name="pixmap">
<pixmap resource="data/Data.qrc">:/icons/icons/Icon_Tree.png</pixmap> <pixmap resource="../data/data.qrc">:/icons/icons/Icon_Tree.png</pixmap>
</property> </property>
<property name="scaledContents"> <property name="scaledContents">
<bool>true</bool> <bool>true</bool>
@ -370,7 +377,7 @@
<string/> <string/>
</property> </property>
<property name="pixmap"> <property name="pixmap">
<pixmap resource="data/Data.qrc">:/icons/icons/Icon_Editor.png</pixmap> <pixmap resource="../data/data.qrc">:/icons/icons/Icon_Editor.png</pixmap>
</property> </property>
<property name="scaledContents"> <property name="scaledContents">
<bool>true</bool> <bool>true</bool>
@ -489,7 +496,7 @@
</layout> </layout>
</widget> </widget>
<resources> <resources>
<include location="data/Data.qrc"/> <include location="../data/data.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

View File

@ -16,10 +16,18 @@ TechSetViewer::~TechSetViewer()
void TechSetViewer::SetTechSet(const XMaterialTechniqueSet* aTechSet) { void TechSetViewer::SetTechSet(const XMaterialTechniqueSet* aTechSet) {
//ui->listWidget_Ptrs->clear(); //ui->listWidget_Ptrs->clear();
ui->label_Title->setText(aTechSet->GetName()); ui->label_Title->setText(aTechSet->GetName());
ui->lineEdit_TechniqueName->setText(aTechSet->DisplayName());
ui->spinBox_WorldVertFormat->setValue(aTechSet->WorldVertFormat());
// int ptrIndex = 1; for (const XMaterialTechnique &technique : aTechSet->Techniques())
//for (auto ptr : aTechSet->pointers) { {
// ui->listWidget_Ptrs->addItem(QString("Pointer %1: %2").arg(ptrIndex).arg(ptr)); ui->listWidget_Techniques->addItem(technique.DisplayName());
// ptrIndex++; }
//}
connect(ui->listWidget_Techniques, &QListWidget::currentRowChanged, this, [&](int aRow) {
const XMaterialTechnique &technique = aTechSet->Techniques()[aRow];
ui->lineEdit_TechniqueName->setText(technique.DisplayName());
ui->spinBox_Flags->setValue(technique.Flags());
ui->spinBox_PassCount->setValue(technique.PassCount());
});
} }

View File

@ -81,9 +81,9 @@
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>Name:</string> <string>Name:</string>
</property> </property>
@ -92,7 +92,7 @@
<item> <item>
<widget class="QLineEdit" name="lineEdit_TechniqueName"> <widget class="QLineEdit" name="lineEdit_TechniqueName">
<property name="placeholderText"> <property name="placeholderText">
<string>Technique set name</string> <string>Technique name</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -7,8 +7,9 @@ XTreeWidget::XTreeWidget(QWidget *parent)
: QTreeWidget(parent) { : QTreeWidget(parent) {
mFastFiles = QMap<QString, const FastFile*>(); mFastFiles = QMap<QString, const FastFile*>();
mZoneFiles = QMap<QString, const ZoneFile*>(); mZoneFiles = QMap<QString, const ZoneFile*>();
mDDSFiles = QMap<QString, const DDSFile*>(); //mDDSFiles = QMap<QString, const DDSFile*>();
mIWIFiles = QMap<QString, const IWIFile*>(); //mIWIFiles = QMap<QString, const IWIFile*>();
mRootItemMap = QMap<XAssetType, QMap<QString, XTreeWidgetItem*>>();
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
setSelectionMode(QTreeWidget::SingleSelection); setSelectionMode(QTreeWidget::SingleSelection);
@ -41,36 +42,36 @@ void XTreeWidget::AddFastFile(FastFile* aFastFile) {
XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this); XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this);
fastFileItem->setText(0, aFastFile->GetStem()); fastFileItem->setText(0, aFastFile->GetStem());
fastFileItem->setIcon(0, Utils::CreateAssetIcon("FF")); fastFileItem->setIcon(0, Utils::CreateAssetIcon("FF"));
if (aFastFile->GetPlatform() == "PC") { if (aFastFile->GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("PC")); fastFileItem->setIcon(1, Utils::CreateAssetIcon("PC"));
} else if (aFastFile->GetPlatform() == "360") { } else if (aFastFile->GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("360")); fastFileItem->setIcon(1, Utils::CreateAssetIcon("360"));
} else if (aFastFile->GetPlatform() == "PS3") { } else if (aFastFile->GetCommonInfo().GetPlatform() == PLATFORM_PS3) {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("PS3")); fastFileItem->setIcon(1, Utils::CreateAssetIcon("PS3"));
} else if (aFastFile->GetPlatform() == "Wii") { } else if (aFastFile->GetCommonInfo().GetPlatform() == PLATFORM_WII) {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("WII")); fastFileItem->setIcon(1, Utils::CreateAssetIcon("WII"));
} else if (aFastFile->GetPlatform() == "WiiU") { } else if (aFastFile->GetCommonInfo().GetPlatform() == PLATFORM_WIIU) {
fastFileItem->setIcon(1, Utils::CreateAssetIcon("WU")); fastFileItem->setIcon(1, Utils::CreateAssetIcon("WU"));
} }
if (aFastFile->GetGame() == "COD2") { if (aFastFile->GetCommonInfo().GetGame() == GAME_COD2) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(2)); fastFileItem->setIcon(2, Utils::CreateGameIcon(2));
} if (aFastFile->GetGame() == "COD4") { } if (aFastFile->GetCommonInfo().GetGame() == GAME_COD4) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(4)); fastFileItem->setIcon(2, Utils::CreateGameIcon(4));
} else if (aFastFile->GetGame() == "COD5") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD5) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(5)); fastFileItem->setIcon(2, Utils::CreateGameIcon(5));
} else if (aFastFile->GetGame() == "COD6") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD6) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(6)); fastFileItem->setIcon(2, Utils::CreateGameIcon(6));
} else if (aFastFile->GetGame() == "COD7") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD7) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(7)); fastFileItem->setIcon(2, Utils::CreateGameIcon(7));
} else if (aFastFile->GetGame() == "COD8") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD8) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(8)); fastFileItem->setIcon(2, Utils::CreateGameIcon(8));
} else if (aFastFile->GetGame() == "COD9") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD9) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(9)); fastFileItem->setIcon(2, Utils::CreateGameIcon(9));
} else if (aFastFile->GetGame() == "COD10") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD10) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(10)); fastFileItem->setIcon(2, Utils::CreateGameIcon(10));
} else if (aFastFile->GetGame() == "COD11") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD11) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(11)); fastFileItem->setIcon(2, Utils::CreateGameIcon(11));
} else if (aFastFile->GetGame() == "COD12") { } else if (aFastFile->GetCommonInfo().GetGame() == GAME_COD12) {
fastFileItem->setIcon(2, Utils::CreateGameIcon(12)); fastFileItem->setIcon(2, Utils::CreateGameIcon(12));
} }
@ -83,6 +84,47 @@ void XTreeWidget::AddFastFile(FastFile* aFastFile) {
sortByColumn(0, Qt::AscendingOrder); sortByColumn(0, Qt::AscendingOrder);
} }
void XTreeWidget::AddAsset(XAsset* aAsset, const QString& aZoneFileName, XTreeWidgetItem* aRootItem)
{
const XAssetType assetType = aAsset->GetType();
QIcon assetIcon = Utils::CreateAssetIcon(assetType);
QTreeWidgetItem *groupItem = nullptr;
for (int i = 0; i < aRootItem->childCount(); i++)
{
QTreeWidgetItem *testItem = aRootItem->child(i);
if (testItem && (testItem->text(0) == aAsset->GetName() || (testItem->text(0) + "s") == aAsset->GetName()))
{
groupItem = testItem;
break;
}
}
if (!groupItem)
{
QString newName = aAsset->GetName();
if (*(newName.end() - 1) != 's')
{
newName += 's';
}
groupItem = new XTreeWidgetItem(aRootItem);
groupItem->setText(0, newName);
groupItem->setIcon(0, assetIcon);
}
XTreeWidgetItem *newItem = new XTreeWidgetItem(groupItem);
newItem->SetAssetType(assetType);
newItem->SetAssetPtr(aAsset);
newItem->setText(0, aAsset->DisplayName());
newItem->setIcon(0, assetIcon);
for (XAsset *subAsset : aAsset->SubAssets())
{
AddAsset(subAsset, aZoneFileName, newItem);
}
update();
}
void XTreeWidget::AddZoneFile(const ZoneFile* aZoneFile, XTreeWidgetItem *aParentItem) { void XTreeWidget::AddZoneFile(const ZoneFile* aZoneFile, XTreeWidgetItem *aParentItem) {
XTreeWidgetItem *zoneItem; XTreeWidgetItem *zoneItem;
if (aParentItem != nullptr) { if (aParentItem != nullptr) {
@ -90,182 +132,15 @@ void XTreeWidget::AddZoneFile(const ZoneFile* aZoneFile, XTreeWidgetItem *aParen
} else { } else {
zoneItem = new XTreeWidgetItem(this); zoneItem = new XTreeWidgetItem(this);
} }
const QString zoneFileName = aZoneFile->GetBaseStem() + ".zone";
zoneItem->setText(0, zoneFileName);
zoneItem->setIcon(0, Utils::CreateAssetIcon("ZF")); zoneItem->setIcon(0, Utils::CreateAssetIcon("ZF"));
zoneItem->setText(0, aZoneFile->GetBaseStem() + ".zone");
XAssetList assetList = aZoneFile->GetAssetList(); XAssetList assetList = aZoneFile->GetAssetList();
QVector<XAsset*> localizeEntries;
for (int i = 0; i < assetList.Size(); i++) for (int i = 0; i < assetList.Size(); i++)
{ {
XAsset *currentAsset = assetList.GetAsset(i); AddAsset(assetList.GetAsset(i), zoneFileName, zoneItem);
if (currentAsset->GetType() == ASSET_TYPE_LOCALIZE_ENTRY)
{
localizeEntries.append(currentAsset);
} else if (currentAsset->GetType() == ASSET_TYPE_LOCALIZE_ENTRY)
{
localizeEntries.append(currentAsset);
} }
}
// if (!assetMap.localizeEntries.isEmpty()) {
// QIcon localStrIcon = Utils::CreateAssetIcon(ASSET_TYPE_LOCALIZE_ENTRY);
// XTreeWidgetItem *localStrRoot = new XTreeWidgetItem(zoneItem);
// localStrRoot->setText(0, "String Files");
// localStrRoot->setIcon(0, localStrIcon);
// localStrRoot->SetCategory(CATEGORY_TYPE);
// XTreeWidgetItem *localStrItem = new XTreeWidgetItem(localStrRoot);
// localStrItem->setText(0, aZoneFile->GetStem().section('.', 0, 0) + ".str");
// localStrItem->setIcon(0, localStrIcon);
// }
// if (!assetMap.techSets.isEmpty()) {
// QIcon techSetIcon = Utils::CreateAssetIcon(ASSET_TYPE_TECHNIQUE_SET);
// XTreeWidgetItem *techSetRoot = new XTreeWidgetItem(zoneItem);
// techSetRoot->setText(0, "Tech Sets");
// techSetRoot->setIcon(0, techSetIcon);
// techSetRoot->SetCategory(CATEGORY_TYPE);
// for (auto techSet : assetMap.techSets) {
// XTreeWidgetItem *techSetItem = new XTreeWidgetItem(techSetRoot);
// techSetItem->setText(0, techSet.name);
// techSetItem->setIcon(0, techSetIcon);
// }
// }
// if (!assetMap.rawFiles.isEmpty()) {
// QIcon rawFileIcon = Utils::CreateAssetIcon(ASSET_TYPE_RAWFILE);
// XTreeWidgetItem *rawFileRoot = new XTreeWidgetItem(zoneItem);
// rawFileRoot->setText(0, "Raw Files");
// rawFileRoot->setIcon(0, rawFileIcon);
// rawFileRoot->SetCategory(CATEGORY_TYPE);
// for (auto rawFile : assetMap.rawFiles) {
// if (!rawFile.length) { continue; }
// XTreeWidgetItem *tempItem = rawFileRoot;
// // const QStringList pathParts = rawFile->path.split('/');
// // for (const QString &pathPart : pathParts) {
// // bool childFound = false;
// // for (int i = 0; i < tempItem->childCount(); i++) {
// // QTreeWidgetItem *rawChildItem = tempItem->child(i);
// // XTreeWidgetItem *childItem = dynamic_cast<XTreeWidgetItem*>(rawChildItem);
// // if (childItem->text(0) == pathPart) {
// // tempItem = childItem;
// // childFound = true;
// // break;
// // }
// // }
// // const QString rawFileStr = pathPart;// = QString("%1 [%2-%3]").arg(pathPart).arg(rawFile.startPos).arg(rawFile.endPos);
// // if (pathPart == pathParts.last()) {
// // XTreeWidgetItem *rawFileItem = new XTreeWidgetItem(tempItem);
// // rawFileItem->setText(0, rawFileStr);
// // tempItem = rawFileItem;
// // } else if (!childFound) {
// // tempItem = new XTreeWidgetItem(tempItem);
// // tempItem->setText(0, rawFileStr);
// // }
// // }
// tempItem->setIcon(0, rawFileIcon);
// }
// }
// if (!assetMap.menuDefinitions.isEmpty()) {
// // QIcon MenuDefIcon = Utils::CreateAssetIcon(ASSET_TYPE_MENU);
// // XTreeWidgetItem *menuRoot = new XTreeWidgetItem(zoneItem);
// // menuRoot->setText(0, "Menu Files");
// // menuRoot->setIcon(0, MenuDefIcon);
// // menuRoot->SetCategory(CATEGORY_TYPE);
// // int menuIndex = 1;
// // for (MenuDef menuDef : assetMap.menuDefinitions) {
// // XTreeWidgetItem *MenuDefRoot = new XTreeWidgetItem(menuRoot);
// // MenuDefRoot->setText(0, QString("Menu %1").arg(menuIndex));
// // for (Menu menu : menuDef.men) {
// // XTreeWidgetItem *menuItem = new XTreeWidgetItem(MenuDefRoot);
// // menuItem->setText(0, menu.filePath);
// // menuItem->setIcon(0, MenuDefIcon);
// // }
// // menuIndex++;
// // }
// }
// if (!assetMap.images.isEmpty()) {
// // QIcon imageIcon = Utils::CreateAssetIcon(ASSET_TYPE_IMAGE);
// // XTreeWidgetItem *imageRoot = new XTreeWidgetItem(zoneItem);
// // imageRoot->setText(0, "Images");
// // imageRoot->setIcon(0, imageIcon);
// // imageRoot->SetCategory(CATEGORY_TYPE);
// // for (Image image : assetMap.images) {
// // XTreeWidgetItem *imageItem = new XTreeWidgetItem(imageRoot);
// // imageItem->setText(0, image.materialName);
// // imageItem->setIcon(0, imageIcon);
// // }
// }
// if (!assetMap.models.isEmpty()) {
// QIcon modelIcon = Utils::CreateAssetIcon(ASSET_TYPE_XMODEL);
// XTreeWidgetItem *modelsRoot = new XTreeWidgetItem(zoneItem);
// modelsRoot->setText(0, "Models");
// modelsRoot->setIcon(0, modelIcon);
// modelsRoot->SetCategory(CATEGORY_TYPE);
// for (auto model: assetMap.models) {
// XTreeWidgetItem *modelItem = new XTreeWidgetItem(modelsRoot);
// modelItem->setText(0, model.name);
// modelItem->setIcon(0, modelIcon);
// }
// }
// if (!assetMap.materials.isEmpty()) {
// QIcon materialIcon = Utils::CreateAssetIcon(ASSET_TYPE_MATERIAL);
// XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem);
// materialsRoot->setText(0, "Materials");
// materialsRoot->setIcon(0, materialIcon);
// materialsRoot->SetCategory(CATEGORY_TYPE);
// for (auto material: assetMap.materials) {
// XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot);
// //materialItem->setText(0, material.name);
// materialItem->setIcon(0, materialIcon);
// }
// }
// if (!assetMap.stringTables.isEmpty()) {
// QIcon stringTableIcon = Utils::CreateAssetIcon(ASSET_TYPE_STRINGTABLE);
// XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem);
// strTableRoot->setText(0, "String Tables");
// strTableRoot->setIcon(0, stringTableIcon);
// strTableRoot->SetCategory(CATEGORY_TYPE);
// for (auto strTable: assetMap.stringTables) {
// XTreeWidgetItem *modelItem = new XTreeWidgetItem(strTableRoot);
// modelItem->setText(0, strTable.name);
// modelItem->setIcon(0, stringTableIcon);
// }
// }
// if (!assetMap.sounds.isEmpty()) {
// QIcon soundIcon = Utils::CreateAssetIcon(ASSET_TYPE_SOUND);
// XTreeWidgetItem *soundsRoot = new XTreeWidgetItem(zoneItem);
// soundsRoot->setText(0, "Sounds");
// soundsRoot->setIcon(0, soundIcon);
// soundsRoot->SetCategory(CATEGORY_TYPE);
// }
mZoneFiles[aZoneFile->GetBaseStem() + ".zone"] = aZoneFile; mZoneFiles[aZoneFile->GetBaseStem() + ".zone"] = aZoneFile;
} }
@ -284,93 +159,93 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
QMenu *contextMenu = new QMenu(this); QMenu *contextMenu = new QMenu(this);
if (activeText.contains(".dds")) { if (activeText.contains(".dds")) {
const QString fileStem = activeText.replace(".dds", ""); // const QString fileStem = activeText.replace(".dds", "");
if (!mDDSFiles.contains(fileStem)) { // if (!mDDSFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in DDS map!"; // qDebug() << "Error: Could not find " << fileStem << " in DDS map!";
return; // return;
} // }
QAction *closeAction = new QAction("Close File"); // QAction *closeAction = new QAction("Close File");
contextMenu->addAction(closeAction); // contextMenu->addAction(closeAction);
connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) { // connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
mDDSFiles.remove(fileStem); // mDDSFiles.remove(fileStem);
invisibleRootItem()->removeChild(activeItem); // invisibleRootItem()->removeChild(activeItem);
}); // });
QMenu *exportSubmenu = new QMenu("Export...", this); // QMenu *exportSubmenu = new QMenu("Export...", this);
contextMenu->addMenu(exportSubmenu); // contextMenu->addMenu(exportSubmenu);
const DDSFile* ddsFile = mDDSFiles[fileStem]; // const DDSFile* ddsFile = mDDSFiles[fileStem];
QAction *exportIWIAction = new QAction("Export as IWI"); // QAction *exportIWIAction = new QAction("Export as IWI");
exportSubmenu->addAction(exportIWIAction); // exportSubmenu->addAction(exportIWIAction);
connect(exportIWIAction, &QAction::triggered, this, [ddsFile](bool checked) { // connect(exportIWIAction, &QAction::triggered, this, [ddsFile](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
ddsFile->SaveIWI(); // ddsFile->SaveIWI();
}); // });
QAction *exportPNGAction = new QAction("Export as PNG"); // QAction *exportPNGAction = new QAction("Export as PNG");
exportSubmenu->addAction(exportPNGAction); // exportSubmenu->addAction(exportPNGAction);
connect(exportPNGAction, &QAction::triggered, this, [ddsFile](bool checked) { // connect(exportPNGAction, &QAction::triggered, this, [ddsFile](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
ddsFile->SavePNG(); // ddsFile->SavePNG();
}); // });
QAction *exportJPGAction = new QAction("Export as JPG"); // QAction *exportJPGAction = new QAction("Export as JPG");
exportSubmenu->addAction(exportJPGAction); // exportSubmenu->addAction(exportJPGAction);
connect(exportJPGAction, &QAction::triggered, this, [ddsFile](bool checked) { // connect(exportJPGAction, &QAction::triggered, this, [ddsFile](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
ddsFile->SaveJPG(); // ddsFile->SaveJPG();
}); // });
} else if (activeText.contains(".iwi")) { } else if (activeText.contains(".iwi")) {
const QString fileStem = activeText.replace(".iwi", ""); // const QString fileStem = activeText.replace(".iwi", "");
if (!mIWIFiles.contains(fileStem)) { // if (!mIWIFiles.contains(fileStem)) {
qDebug() << "Error: Could not find " << fileStem << " in IWI map!"; // qDebug() << "Error: Could not find " << fileStem << " in IWI map!";
return; // return;
} // }
QAction *closeAction = new QAction("Close File"); // QAction *closeAction = new QAction("Close File");
contextMenu->addAction(closeAction); // contextMenu->addAction(closeAction);
connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) { // connect(closeAction, &QAction::triggered, this, [this, &fileStem, &activeItem](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
mIWIFiles.remove(fileStem); // mIWIFiles.remove(fileStem);
invisibleRootItem()->removeChild(activeItem); // invisibleRootItem()->removeChild(activeItem);
}); // });
QMenu *exportSubmenu = new QMenu("Export...", this); // QMenu *exportSubmenu = new QMenu("Export...", this);
contextMenu->addMenu(exportSubmenu); // contextMenu->addMenu(exportSubmenu);
const IWIFile* iwiFile = mIWIFiles[fileStem]; // const IWIFile* iwiFile = mIWIFiles[fileStem];
QAction *exportDDSAction = new QAction("Export as DDS"); // QAction *exportDDSAction = new QAction("Export as DDS");
exportSubmenu->addAction(exportDDSAction); // exportSubmenu->addAction(exportDDSAction);
connect(exportDDSAction, &QAction::triggered, this, [iwiFile](bool checked) { // connect(exportDDSAction, &QAction::triggered, this, [iwiFile](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
iwiFile->SaveDDS(); // iwiFile->SaveDDS();
}); // });
QAction *exportPNGAction = new QAction("Export as PNG"); // QAction *exportPNGAction = new QAction("Export as PNG");
exportSubmenu->addAction(exportPNGAction); // exportSubmenu->addAction(exportPNGAction);
connect(exportPNGAction, &QAction::triggered, this, [iwiFile](bool checked) { // connect(exportPNGAction, &QAction::triggered, this, [iwiFile](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
iwiFile->SavePNG(); // iwiFile->SavePNG();
}); // });
QAction *exportJPGAction = new QAction("Export as JPG"); // QAction *exportJPGAction = new QAction("Export as JPG");
exportSubmenu->addAction(exportJPGAction); // exportSubmenu->addAction(exportJPGAction);
connect(exportJPGAction, &QAction::triggered, this, [iwiFile](bool checked) { // connect(exportJPGAction, &QAction::triggered, this, [iwiFile](bool checked) {
Q_UNUSED(checked); // Q_UNUSED(checked);
iwiFile->SaveJPG(); // iwiFile->SaveJPG();
}); // });
} else if (activeText.contains(".ff")) { } else if (activeText.contains(".ff")) {
const QString fileStem = activeText; const QString fileStem = activeText;
@ -629,21 +504,10 @@ void XTreeWidget::ItemSelectionChanged() {
QString selectedText = selectedItem->text(0); QString selectedText = selectedItem->text(0);
emit ItemSelected(selectedText); emit ItemSelected(selectedText);
XTreeWidgetItem *parentItem = dynamic_cast<XTreeWidgetItem*>(selectedItem->parent()); switch (selectedItem->AssetType())
{
/*if (selectedText.contains(".dds")) { case ASSET_TYPE_NONE:
if (!mDDSFiles.contains(selectedText)) { if (selectedText.contains(".ff")) {
LogManager::instance().addError("Could not find " + selectedText + " in DDS map!");
return;
}
emit DDSFileSelected(mDDSFiles[selectedText], selectedText);
} else if (selectedText.contains(".iwi")) {
if (!mIWIFiles.contains(selectedText)) {
LogManager::instance().addError("Could not find " + selectedText + " in IWI map!");
return;
}
emit IWIFileSelected(mIWIFiles[selectedText], selectedText);
} else */if (selectedText.contains(".ff")) {
if (!mFastFiles.contains(selectedText)) { if (!mFastFiles.contains(selectedText)) {
LogManager::instance().addError("Could not find " + selectedText + " in Fast File map!"); LogManager::instance().addError("Could not find " + selectedText + " in Fast File map!");
return; return;
@ -655,96 +519,20 @@ void XTreeWidget::ItemSelectionChanged() {
return; return;
} }
emit ZoneFileSelected(mZoneFiles[selectedText], selectedText); emit ZoneFileSelected(mZoneFiles[selectedText], selectedText);
} else if (selectedText.contains(".str")) {
if (!mZoneFiles.contains(selectedText.replace(".str", ".zone"))) {
LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!");
return;
} }
emit LocalStringSelected(mZoneFiles[selectedText], selectedText);
} else if (parentItem && (parentItem->text(0) == "Images")) {
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
// QVector<Image> images = mZoneFiles[fileStem]->GetAssetMap().images;
// for (Image image : images) {
// if (image.materialName == selectedText) {
// emit ImageSelected(std::make_shared<Image>(image), fileStem);
// break;
// }
// }
}
} /*else if (parentItem && (parentItem->text(0) == "Tech Sets")) {
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
auto techsets = mZoneFiles[fileStem]->GetAssetList().techSets;
for (auto techset : techsets) {
if (techset.name == selectedText) {
emit TechSetSelected(new MaterialTechSet(techset), fileStem);
break; break;
} case ASSET_TYPE_TECHNIQUE_SET:
} emit TechSetSelected(dynamic_cast<const XMaterialTechniqueSet*>(selectedItem->AssetPtr()), selectedText);
}
} else if (parentItem && (parentItem->text(0) == "Materials")) {
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
auto materials = mZoneFiles[fileStem]->GetAssetMap().materials;
for (auto material : materials) {
// if (material.name == selectedText) {
// emit MaterialSelected(std::make_shared<Material>(material), fileStem);
// break;
// }
}
}
} else if (parentItem && selectedText.contains(".wav")) {
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
while (grandpaItem && !grandpaItem->text(0).contains(".zone")) {
grandpaItem = dynamic_cast<XTreeWidgetItem*>(grandpaItem->parent());
if (grandpaItem == invisibleRootItem()) {
break; break;
} case ASSET_TYPE_MATERIAL:
} emit MaterialSelected(dynamic_cast<const XMaterial*>(selectedItem->AssetPtr()), selectedText);
if (grandpaItem && grandpaItem != invisibleRootItem() && grandpaItem->text(0).contains(".zone")) {
const QString fileStem = grandpaItem->text(0).section('.', 0, 0);
// QVector<LoadedSound> LoadedSounds = mZoneFiles[fileStem]->GetAssetMap().sounds;
// for (LoadedSound LoadedSound : LoadedSounds) {
// for (Sound sound : LoadedSound.sounds) {
// if (sound.path.contains(selectedText)) {
// emit SoundSelected(std::make_shared<Sound>(sound), fileStem);
// break;
// }
// }
// }
}
} else if (selectedItem->GetCategory() != CATEGORY_TYPE) {
XTreeWidgetItem *zoneRoot = selectedItem;
bool zoneChild = false;
while (zoneRoot) {
zoneRoot = dynamic_cast<XTreeWidgetItem*>(zoneRoot->parent());
if (zoneRoot->text(0).contains("Raw Files")) {
zoneChild = true;
break; break;
} case ASSET_TYPE_RAWFILE:
} emit RawFileSelected(dynamic_cast<const XRawFile*>(selectedItem->AssetPtr()), selectedText);
if (!zoneChild) { return; } break;
const QString fileStem = zoneRoot->parent()->text(0); default:
break;
if (!mZoneFiles.contains(fileStem)) { };
LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!");
return;
}
auto rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles;
for (auto rawFile : rawFiles) {
//if (rawFile->path.split('/').last() == selectedText) {
// emit RawFileSelected(std::make_shared<RawFile>(rawFile), fileStem);
// return;
//}
}
}*/
} }
const ZoneFile* XTreeWidget::FindZoneFile(const QString aStem) { const ZoneFile* XTreeWidget::FindZoneFile(const QString aStem) {
@ -773,34 +561,34 @@ bool XTreeWidget::HasFastFile(const QString aStem) {
return FindFastFile(aStem) != nullptr; return FindFastFile(aStem) != nullptr;
} }
void XTreeWidget::AddIWIFile(IWIFile* aIWIFile) { // void XTreeWidget::AddIWIFile(IWIFile* aIWIFile) {
const QString iwiFileName = QString(aIWIFile->fileStem + ".iwi"); // const QString iwiFileName = QString(aIWIFile->fileStem + ".iwi");
for (int i = 0; i < invisibleRootItem()->childCount(); i++) { // for (int i = 0; i < invisibleRootItem()->childCount(); i++) {
auto iwiFileItem = invisibleRootItem()->child(i); // auto iwiFileItem = invisibleRootItem()->child(i);
if (iwiFileItem->text(0) == iwiFileName) { // if (iwiFileItem->text(0) == iwiFileName) {
delete iwiFileItem; // delete iwiFileItem;
} // }
} // }
XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this); // XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this);
iwiItem->setIcon(0, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE)); // iwiItem->setIcon(0, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE));
iwiItem->setText(0, iwiFileName); // iwiItem->setText(0, iwiFileName);
mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile; // mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile;
} // }
void XTreeWidget::AddDDSFile(DDSFile* aDDSFile) { // void XTreeWidget::AddDDSFile(DDSFile* aDDSFile) {
const QString ddsFileName = QString(aDDSFile->fileStem + ".dds"); // const QString ddsFileName = QString(aDDSFile->fileStem + ".dds");
for (int i = 0; i < invisibleRootItem()->childCount(); i++) { // for (int i = 0; i < invisibleRootItem()->childCount(); i++) {
auto ddsFileItem = invisibleRootItem()->child(i); // auto ddsFileItem = invisibleRootItem()->child(i);
if (ddsFileItem->text(0) == ddsFileName) { // if (ddsFileItem->text(0) == ddsFileName) {
delete ddsFileItem; // delete ddsFileItem;
} // }
} // }
XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this); // XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this);
ddsItem->setIcon(0, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE)); // ddsItem->setIcon(0, Utils::CreateAssetIcon(ASSET_TYPE_IMAGE));
ddsItem->setText(0, ddsFileName); // ddsItem->setText(0, ddsFileName);
mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile; // mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile;
} // }

View File

@ -2,8 +2,8 @@
#define XTREEWIDGET_H #define XTREEWIDGET_H
#include "d3dbsp_structs.h" #include "d3dbsp_structs.h"
#include "ddsfile.h" //#include "iwifile.h"
#include "iwifile.h" //#include "ddsfile.h"
#include "fastfile.h" #include "fastfile.h"
#include "xloadedsound.h" #include "xloadedsound.h"
#include "xtreewidgetitem.h" #include "xtreewidgetitem.h"
@ -25,8 +25,8 @@ public:
void AddFastFile(FastFile* aFastFile); void AddFastFile(FastFile* aFastFile);
void AddZoneFile(const ZoneFile *aZoneFile, XTreeWidgetItem *aParentItem = nullptr); void AddZoneFile(const ZoneFile *aZoneFile, XTreeWidgetItem *aParentItem = nullptr);
void AddIWIFile(IWIFile* aIWIFile); //void AddIWIFile(IWIFile* aIWIFile);
void AddDDSFile(DDSFile* aDDSFile); //void AddDDSFile(IWIFile* aDDSFile);
const ZoneFile *FindZoneFile(const QString aStem); const ZoneFile *FindZoneFile(const QString aStem);
const FastFile* FindFastFile(const QString aStem); const FastFile* FindFastFile(const QString aStem);
@ -35,9 +35,9 @@ public:
bool HasFastFile(const QString aStem); bool HasFastFile(const QString aStem);
void CloseFastFile(const QString aFFName); void CloseFastFile(const QString aFFName);
void AddAsset(XAsset *aAsset, const QString &aZoneFileName, XTreeWidgetItem *aRootItem);
signals: signals:
void DDSFileSelected(const DDSFile* aDDSFile, const QString aParentName); //void IWIFileSelected(const IWIFile* aIWIFile, const QString aParentName);
void IWIFileSelected(const IWIFile* aIWIFile, const QString aParentName);
void FastFileSelected(const FastFile* aFastFile, const QString aParentName); void FastFileSelected(const FastFile* aFastFile, const QString aParentName);
void ZoneFileSelected(const ZoneFile* aZoneFile, const QString aParentName); void ZoneFileSelected(const ZoneFile* aZoneFile, const QString aParentName);
void LocalStringSelected(const ZoneFile* aZoneFile, const QString aParentName); void LocalStringSelected(const ZoneFile* aZoneFile, const QString aParentName);
@ -60,8 +60,10 @@ protected:
private: private:
QMap<QString, const FastFile*> mFastFiles; QMap<QString, const FastFile*> mFastFiles;
QMap<QString, const ZoneFile*> mZoneFiles; QMap<QString, const ZoneFile*> mZoneFiles;
QMap<QString, const DDSFile*> mDDSFiles; //QMap<QString, const DDSFile*> mDDSFiles;
QMap<QString, const IWIFile*> mIWIFiles; //QMap<QString, const IWIFile*> mIWIFiles;
QMap<XAssetType, QMap<QString, XTreeWidgetItem*>> mRootItemMap;
}; };
#endif // XTREEWIDGET_H #endif // XTREEWIDGET_H

View File

@ -3,27 +3,19 @@
XTreeWidgetItem::XTreeWidgetItem(QTreeWidget *parent, bool group) XTreeWidgetItem::XTreeWidgetItem(QTreeWidget *parent, bool group)
: QTreeWidgetItem(parent) : QTreeWidgetItem(parent)
, isGroup(group) , isGroup(group)
, mCategory(CATEGORY_NONE) { , mAssetType(ASSET_TYPE_NONE)
, mAssetPtr(nullptr) {
} }
XTreeWidgetItem::XTreeWidgetItem(QTreeWidgetItem *parent, bool group) XTreeWidgetItem::XTreeWidgetItem(QTreeWidgetItem *parent, bool group)
: QTreeWidgetItem(parent) : QTreeWidgetItem(parent)
, isGroup(group) , isGroup(group)
, mCategory(CATEGORY_NONE) { , mAssetType(ASSET_TYPE_NONE)
, mAssetPtr(nullptr) {
} }
void XTreeWidgetItem::SetCategory(TREE_CATEGORY category)
{
mCategory = category;
}
TREE_CATEGORY XTreeWidgetItem::GetCategory()
{
return mCategory;
}
bool XTreeWidgetItem::operator<(const QTreeWidgetItem &other) const { bool XTreeWidgetItem::operator<(const QTreeWidgetItem &other) const {
// Attempt to cast the other item to our custom type. // Attempt to cast the other item to our custom type.
const XTreeWidgetItem* otherItem = dynamic_cast<const XTreeWidgetItem*>(&other); const XTreeWidgetItem* otherItem = dynamic_cast<const XTreeWidgetItem*>(&other);
@ -54,3 +46,33 @@ XTreeWidgetItem& XTreeWidgetItem::operator=(const XTreeWidgetItem &other)
} }
return *this; return *this;
} }
XAssetType XTreeWidgetItem::AssetType() const
{
return mAssetType;
}
void XTreeWidgetItem::SetAssetType(XAssetType aAssetType)
{
mAssetType = aAssetType;
}
bool XTreeWidgetItem::GetIsGroup() const
{
return isGroup;
}
void XTreeWidgetItem::SetIsGroup(bool aIsGroup)
{
isGroup = aIsGroup;
}
XAsset *XTreeWidgetItem::AssetPtr() const
{
return mAssetPtr;
}
void XTreeWidgetItem::SetAssetPtr(XAsset *aAssetPtr)
{
mAssetPtr = aAssetPtr;
}

View File

@ -1,35 +1,36 @@
#ifndef XTREEWIDGETITEM_H #ifndef XTREEWIDGETITEM_H
#define XTREEWIDGETITEM_H #define XTREEWIDGETITEM_H
#include "xassettype.h"
#include <QTreeWidget> #include <QTreeWidget>
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
enum TREE_CATEGORY { class XAsset;
CATEGORY_NONE = 0x00,
CATEGORY_FILE = 0x01,
CATEGORY_TYPE = 0x02
};
// Custom item class // Custom item class
class XTreeWidgetItem : public QTreeWidgetItem class XTreeWidgetItem : public QTreeWidgetItem
{ {
public: public:
// Flag to indicate if the item is a collapsible group/header.
bool isGroup;
// Constructors: default to non-group unless specified.
XTreeWidgetItem(QTreeWidget *parent, bool group = false); XTreeWidgetItem(QTreeWidget *parent, bool group = false);
XTreeWidgetItem(QTreeWidgetItem *parent, bool group = false); XTreeWidgetItem(QTreeWidgetItem *parent, bool group = false);
~XTreeWidgetItem() = default;
void SetCategory(TREE_CATEGORY category);
TREE_CATEGORY GetCategory();
// Override the less-than operator to customize sorting. // Override the less-than operator to customize sorting.
bool operator<(const QTreeWidgetItem &other) const override; bool operator<(const QTreeWidgetItem &other) const override;
XTreeWidgetItem &operator =(const XTreeWidgetItem &other); XTreeWidgetItem &operator =(const XTreeWidgetItem &other);
XAssetType AssetType() const;
void SetAssetType(XAssetType aAssetType);
bool GetIsGroup() const;
void SetIsGroup(bool aIsGroup);
XAsset *AssetPtr() const;
void SetAssetPtr(XAsset *aAssetPtr);
private: private:
TREE_CATEGORY mCategory; bool isGroup;
XAssetType mAssetType;
XAsset* mAssetPtr;
}; };

View File

@ -52,14 +52,13 @@ void ZoneFileViewer::HighlightRecordInOrder() {
void ZoneFileViewer::SortTags(const QString &aSearchText) { void ZoneFileViewer::SortTags(const QString &aSearchText) {
ui->listWidget_Tags->clear(); ui->listWidget_Tags->clear();
const QStringList tags = mZoneFile->GetTags();
if (aSearchText.isEmpty()) { if (aSearchText.isEmpty()) {
ui->listWidget_Tags->addItems(tags); ui->listWidget_Tags->addItems(mTags);
return; return;
} }
QStringList sortedTags; QStringList sortedTags;
foreach (const QString tag, tags) { foreach (const QString tag, mTags) {
if (tag.contains(aSearchText)) { if (tag.contains(aSearchText)) {
sortedTags << tag; sortedTags << tag;
} }
@ -72,17 +71,22 @@ void ZoneFileViewer::SortTags(const QString &aSearchText) {
void ZoneFileViewer::SetZoneFile(const ZoneFile* aZoneFile) { void ZoneFileViewer::SetZoneFile(const ZoneFile* aZoneFile) {
mZoneFile = aZoneFile; mZoneFile = aZoneFile;
auto rawTags = aZoneFile->GetAssetList().GetStringList().ScriptStrings();
for (int i = 0; i < rawTags.size(); i++)
{
mTags.push_back(rawTags[i].GetString());
}
ui->tableWidget_RecordCounts->clearContents(); ui->tableWidget_RecordCounts->clearContents();
ui->tableWidget_RecordOrder->clearContents(); ui->tableWidget_RecordOrder->clearContents();
ui->listWidget_Tags->clear(); ui->listWidget_Tags->clear();
const QStringList tags = mZoneFile->GetTags(); ui->listWidget_Tags->addItems(mTags);
ui->listWidget_Tags->addItems(tags);
ui->label_Title->setText(mZoneFile->GetBaseStem() + ".zone"); ui->label_Title->setText(mZoneFile->GetBaseStem() + ".zone");
ui->groupBox_Tags->setTitle(QString("Tags (%1)").arg(tags.size())); ui->groupBox_Tags->setTitle(QString("Tags (%1)").arg(mTags.size()));
if (tags.isEmpty()) { if (mTags.isEmpty()) {
ui->groupBox_Tags->hide(); ui->groupBox_Tags->hide();
} else { } else {
ui->groupBox_Tags->show(); ui->groupBox_Tags->show();

View File

@ -28,6 +28,7 @@ public slots:
private: private:
Ui::ZoneFileViewer *ui; Ui::ZoneFileViewer *ui;
const ZoneFile* mZoneFile; const ZoneFile* mZoneFile;
QStringList mTags;
}; };
#endif // ZONEFILEVIEWER_H #endif // ZONEFILEVIEWER_H

View File

@ -336,7 +336,7 @@ QByteArray Compression::DecompressLZO(const QByteArray &aCompressedData, quint32
} }
QByteArray Compression::DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize) { QByteArray Compression::DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize) {
return pDecompressOodle(aCompressedData, aCompressedData.length(), aDecompressedSize); return pDecompressOodle(aCompressedData, aCompressedData.size(), aDecompressedSize);
} }
QByteArray Compression::CompressOodle(const QByteArray &aData) { QByteArray Compression::CompressOodle(const QByteArray &aData) {
@ -352,18 +352,16 @@ quint32 Compression::pGetOodleCompressedBounds(quint32 aBufferSize) {
} }
QByteArray Compression::pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize, OodleFormat aformat, OodleCompressionLevel alevel) { QByteArray Compression::pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize, OodleFormat aformat, OodleCompressionLevel alevel) {
QLibrary oodleLib("oo2core_8_win64"); QLibrary lib("../../../third_party/oodle_lib/dll/oo2core_8_win64.dll"); // adjust path if needed
if (!lib.load()) {
if (!oodleLib.load()) { qDebug() << "Failed to load:" << lib.errorString();
qDebug() << "Failed to load DLL:" << oodleLib.errorString();
return QByteArray(); return QByteArray();
} }
OodleLZ_CompressFunc OodleLZ_Compress = OodleLZ_CompressFunc OodleLZ_Compress = (OodleLZ_CompressFunc)lib.resolve("OodleLZ_Compress");
(OodleLZ_CompressFunc)oodleLib.resolve("OodleLZ_Compress");
if (!OodleLZ_Compress) { if (!OodleLZ_Compress) {
qDebug() << "Failed to resolve function:" << oodleLib.errorString(); qDebug() << "Failed to resolve OodleLZ_Compress:" << lib.errorString();
return QByteArray(); return QByteArray();
} }
@ -375,26 +373,58 @@ QByteArray Compression::pCompressOodle(QByteArray aBuffer, quint32 aBufferSize,
return QByteArray(reinterpret_cast<const char*>(outputBuffer), aOutputBufferSize); return QByteArray(reinterpret_cast<const char*>(outputBuffer), aOutputBufferSize);
} }
QByteArray Compression::pDecompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize) { QByteArray Compression::pDecompressOodle(const QByteArray &aBuffer,
QLibrary oodleLib("oo2core_8_win64"); quint32 aBufferSize,
quint32 aOutputBufferSize)
if (!oodleLib.load()) { {
qDebug() << "Failed to load DLL:" << oodleLib.errorString(); QLibrary lib("../../../third_party/oodle_lib/dll/oo2core_8_win64.dll");
return QByteArray(); if (!lib.load()) {
qWarning() << "Failed to load Oodle DLL:" << lib.errorString();
return {};
} }
OodleLZ_DecompressFunc OodleLZ_Decompress = OodleLZ_DecompressFunc OodleLZ_Decompress =
(OodleLZ_DecompressFunc)oodleLib.resolve("OodleLZ_Decompress"); reinterpret_cast<OodleLZ_DecompressFunc>(lib.resolve("OodleLZ_Decompress"));
if (!OodleLZ_Decompress) { if (!OodleLZ_Decompress) {
qDebug() << "Failed to resolve function:" << oodleLib.errorString(); qWarning() << "Failed to resolve OodleLZ_Decompress:" << lib.errorString();
return QByteArray(); return {};
} }
std::byte *outputBuffer = new std::byte[aOutputBufferSize]; QByteArray out(aOutputBufferSize + 1, Qt::Uninitialized);
if (aBuffer.length() > 0 && aBufferSize > 0 && aOutputBufferSize > 0) if (aBuffer.isEmpty() || aBufferSize == 0 || aOutputBufferSize == 0) {
OodleLZ_Decompress(reinterpret_cast<std::byte*>(aBuffer.data()), aBufferSize, outputBuffer, aOutputBufferSize, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); qWarning() << "Invalid Oodle parameters (empty input or size 0)";
return {};
return QByteArray(reinterpret_cast<const char*>(outputBuffer), aOutputBufferSize); }
int result = OodleLZ_Decompress(
aBuffer.constData(),
static_cast<int64_t>(aBufferSize),
out.data(),
static_cast<int64_t>(aOutputBufferSize),
1,
0,
0,
0,
0,
0,
0,
0,
0,
3);
if (result < 0) {
qWarning() << "OodleLZ_Decompress failed with code" << result;
return {};
}
if (result > out.size()) {
qWarning() << "Oodle returned more than expected:" << result
<< "expected" << aOutputBufferSize;
return out;
}
out.resize(result);
return out;
} }

View File

@ -41,7 +41,22 @@ enum OodleCompressionLevel {
}; };
typedef int (*OodleLZ_CompressFunc)(OodleFormat Format, std::byte *Buffer, long BufferSize, std::byte *OutputBuffer, OodleCompressionLevel Level, uint a, uint b, uint c); typedef int (*OodleLZ_CompressFunc)(OodleFormat Format, std::byte *Buffer, long BufferSize, std::byte *OutputBuffer, OodleCompressionLevel Level, uint a, uint b, uint c);
typedef int (*OodleLZ_DecompressFunc)(std::byte* Buffer, long BufferSize, std::byte* OutputBuffer, long OutputBufferSize, uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h, uint i, int ThreadModule); typedef int (__stdcall *OodleLZ_DecompressFunc)(
const void *compBuf,
int64_t compBufSize,
void *rawBuf,
int64_t rawLen,
uint32_t fuzzSafe,
uint32_t checkCRC,
uint32_t verbosity,
void *decBufBase,
size_t decBufSize,
void *fpCallback,
void *callbackUserData,
void *decoderMemory,
size_t decoderMemorySize,
int threadPhase
);
class Compression { class Compression {
public: public:
@ -80,7 +95,7 @@ private:
static quint32 pGetOodleCompressedBounds(quint32 aBufferSize); static quint32 pGetOodleCompressedBounds(quint32 aBufferSize);
static QByteArray pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize, static QByteArray pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize,
OodleFormat aformat, OodleCompressionLevel alevel); OodleFormat aformat, OodleCompressionLevel alevel);
static QByteArray pDecompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize); static QByteArray pDecompressOodle(const QByteArray &aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize);
}; };

View File

@ -12,8 +12,6 @@ FastFile_COD10_360::FastFile_COD10_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD10");
} }
FastFile_COD10_360::FastFile_COD10_360(const QByteArray& aData) FastFile_COD10_360::FastFile_COD10_360(const QByteArray& aData)
@ -103,6 +101,7 @@ bool FastFile_COD10_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_360* zoneFile = new ZoneFile_COD10_360(); ZoneFile_COD10_360* zoneFile = new ZoneFile_COD10_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD11_360::FastFile_COD11_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD11");
SetPlatform("PC");
} }
FastFile_COD11_360::FastFile_COD11_360(const QByteArray& aData) FastFile_COD11_360::FastFile_COD11_360(const QByteArray& aData)
@ -141,6 +139,7 @@ bool FastFile_COD11_360::Load(const QByteArray aData) {
// Load the zone file with decompressed data // Load the zone file with decompressed data
ZoneFile_COD11_360* zoneFile = new ZoneFile_COD11_360(); ZoneFile_COD11_360* zoneFile = new ZoneFile_COD11_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD12_360::FastFile_COD12_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD12");
SetPlatform("PC");
} }
FastFile_COD12_360::FastFile_COD12_360(const QByteArray& aData) FastFile_COD12_360::FastFile_COD12_360(const QByteArray& aData)
@ -141,6 +139,7 @@ bool FastFile_COD12_360::Load(const QByteArray aData) {
// Load the zone file with decompressed data // Load the zone file with decompressed data
ZoneFile_COD12_360* zoneFile = new ZoneFile_COD12_360(); ZoneFile_COD12_360* zoneFile = new ZoneFile_COD12_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -14,8 +14,6 @@ FastFile_COD2_360::FastFile_COD2_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD2");
} }
FastFile_COD2_360::FastFile_COD2_360(const QByteArray& aData) FastFile_COD2_360::FastFile_COD2_360(const QByteArray& aData)
@ -81,6 +79,7 @@ bool FastFile_COD2_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD2_360* zoneFile = new ZoneFile_COD2_360(); ZoneFile_COD2_360* zoneFile = new ZoneFile_COD2_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD4_360::FastFile_COD4_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD4");
} }
FastFile_COD4_360::FastFile_COD4_360(const QByteArray& aData) FastFile_COD4_360::FastFile_COD4_360(const QByteArray& aData)
@ -130,6 +128,7 @@ bool FastFile_COD4_360::Load(const QByteArray aData) {
ZoneFile_COD4_360* zoneFile = new ZoneFile_COD4_360(); ZoneFile_COD4_360* zoneFile = new ZoneFile_COD4_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD5_360::FastFile_COD5_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD5");
} }
FastFile_COD5_360::FastFile_COD5_360(const QByteArray& aData) FastFile_COD5_360::FastFile_COD5_360(const QByteArray& aData)
@ -82,6 +80,7 @@ bool FastFile_COD5_360::Load(const QByteArray aData) {
ZoneFile_COD5_360* zoneFile = new ZoneFile_COD5_360(); ZoneFile_COD5_360* zoneFile = new ZoneFile_COD5_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD6_360::FastFile_COD6_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD6");
} }
FastFile_COD6_360::FastFile_COD6_360(const QByteArray& aData) FastFile_COD6_360::FastFile_COD6_360(const QByteArray& aData)
@ -115,6 +113,7 @@ bool FastFile_COD6_360::Load(const QByteArray aData) {
ZoneFile_COD6_360* zoneFile = new ZoneFile_COD6_360(); ZoneFile_COD6_360* zoneFile = new ZoneFile_COD6_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -14,8 +14,6 @@ FastFile_COD7_360::FastFile_COD7_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD7");
} }
FastFile_COD7_360::FastFile_COD7_360(const QByteArray& aData) FastFile_COD7_360::FastFile_COD7_360(const QByteArray& aData)
@ -140,6 +138,7 @@ bool FastFile_COD7_360::Load(const QByteArray aData) {
ZoneFile_COD7_360* zoneFile = new ZoneFile_COD7_360(); ZoneFile_COD7_360* zoneFile = new ZoneFile_COD7_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -14,8 +14,6 @@ FastFile_COD7_5_360::FastFile_COD7_5_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD7.5");
} }
FastFile_COD7_5_360::FastFile_COD7_5_360(const QByteArray& aData) FastFile_COD7_5_360::FastFile_COD7_5_360(const QByteArray& aData)
@ -138,6 +136,7 @@ bool FastFile_COD7_5_360::Load(const QByteArray aData) {
ZoneFile_COD7_360* zoneFile = new ZoneFile_COD7_360(); ZoneFile_COD7_360* zoneFile = new ZoneFile_COD7_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD8_360::FastFile_COD8_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD8");
} }
FastFile_COD8_360::FastFile_COD8_360(const QByteArray& aData) FastFile_COD8_360::FastFile_COD8_360(const QByteArray& aData)
@ -101,6 +99,7 @@ bool FastFile_COD8_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD8_360* zoneFile = new ZoneFile_COD8_360(); ZoneFile_COD8_360* zoneFile = new ZoneFile_COD8_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD9_360::FastFile_COD9_360()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("360");
SetGame("COD9");
} }
FastFile_COD9_360::FastFile_COD9_360(const QByteArray& aData) FastFile_COD9_360::FastFile_COD9_360(const QByteArray& aData)
@ -105,6 +103,7 @@ bool FastFile_COD9_360::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD9_360* zoneFile = new ZoneFile_COD9_360(); ZoneFile_COD9_360* zoneFile = new ZoneFile_COD9_360();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD10_PC::FastFile_COD10_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD10");
SetPlatform("PC");
} }
FastFile_COD10_PC::FastFile_COD10_PC(const QByteArray& aData) FastFile_COD10_PC::FastFile_COD10_PC(const QByteArray& aData)
@ -80,12 +78,10 @@ bool FastFile_COD10_PC::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD9");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
if (GetPlatform() == "PC") { if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileStream.setByteOrder(XDataStream::LittleEndian); fastFileStream.setByteOrder(XDataStream::LittleEndian);
} }
@ -122,6 +118,7 @@ bool FastFile_COD10_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_PC* zoneFile = new ZoneFile_COD10_PC(); ZoneFile_COD10_PC* zoneFile = new ZoneFile_COD10_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD11_PC::FastFile_COD11_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD11");
SetPlatform("PC");
} }
FastFile_COD11_PC::FastFile_COD11_PC(const QByteArray& aData) FastFile_COD11_PC::FastFile_COD11_PC(const QByteArray& aData)
@ -116,6 +114,7 @@ bool FastFile_COD11_PC::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD11_PC* zoneFile = new ZoneFile_COD11_PC(); ZoneFile_COD11_PC* zoneFile = new ZoneFile_COD11_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD12_PC::FastFile_COD12_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD12");
SetPlatform("PC");
} }
FastFile_COD12_PC::FastFile_COD12_PC(const QByteArray& aData) FastFile_COD12_PC::FastFile_COD12_PC(const QByteArray& aData)

View File

@ -0,0 +1,209 @@
#include "fastfile_cod21_pc.h"
#include "zonefile_cod21_pc.h"
#include "utils.h"
#include "compression.h"
#include "encryption.h"
#include <QFile>
#include <QDebug>
FastFile_COD21_PC::FastFile_COD21_PC()
: FastFile() {
SetCompany(COMPANY_INFINITY_WARD);
SetType(FILETYPE_FAST_FILE);
SetSignage(SIGNAGE_SIGNED);
SetMagic(0);
SetVersion(0);
}
FastFile_COD21_PC::FastFile_COD21_PC(const QByteArray& aData)
: FastFile_COD21_PC() {
if (!aData.isEmpty()) {
Load(aData);
}
}
FastFile_COD21_PC::FastFile_COD21_PC(const QString aFilePath)
: FastFile_COD21_PC() {
if (!aFilePath.isEmpty()) {
Load(aFilePath);
}
}
FastFile_COD21_PC::~FastFile_COD21_PC() {
}
QByteArray FastFile_COD21_PC::GetBinaryData() const {
return QByteArray();
}
bool FastFile_COD21_PC::Load(const QString aFilePath) {
if (aFilePath.isEmpty()) {
return false;
}
// Check fastfile can be read
QFile *file = new QFile(aFilePath);
if (!file->open(QIODevice::ReadOnly)) {
qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath);
return false;
}
// Decompress fastfile and close
const QString fastFileStem = aFilePath.section("/", -1, -1).split('.').first();
SetStem(fastFileStem);
if (!Load(file->readAll())) {
qDebug() << "Error: Failed to load fastfile: " << fastFileStem;
return false;
}
file->close();
// Open zone file after decompressing ff and writing
return true;
}
bool FastFile_COD21_PC::Load(const QByteArray aData) {
QByteArray decompressedData;
// Create a XDataStream on the input data.
XDataStream fastFileStream(aData);
fastFileStream.setByteOrder(XDataStream::LittleEndian);
auto dev = fastFileStream.device();
if (dev->bytesAvailable() < 12) {
qWarning() << "Not enough data for block header";
return false;
}
// Skip to start of fastfile
quint64 startIndex = aData.indexOf("IWCIWffs100");
if (startIndex == -1)
{
qDebug() << "Failed to find data start!";
return true;
}
fastFileStream.skipRawData(startIndex + 11);
qDebug() << "Start index: " << startIndex + 11;
// Skip RSA hashes
fastFileStream.skipRawData(32760);
qint32 decompressedDataLen = fastFileStream.ParseInt32();
qDebug() << "Decompressed Data Len: " << decompressedDataLen;
fastFileStream.skipRawData(3);
qint8 compressionType = fastFileStream.ParseInt8();
qDebug() << "Compression Type: " << compressionType;
long decompressedDataCount = 0;
int loopCount = 1;
while (decompressedDataCount < decompressedDataLen)
{
qDebug() << QString("Block Offset: {0:%1}, total: {1:%2}").arg(fastFileStream.device()->pos()).arg(decompressedDataCount);
if (loopCount == 512)
{
// Skip an RSA block
fastFileStream.skipRawData(0x4000);
loopCount = 0;
}
qint32 compLenRaw = fastFileStream.ParseInt32();
qDebug() << "Test: " << fastFileStream.device()->pos();
qint32 compressedLen = (compLenRaw + 3) & ~3;
qint32 decompressedLen = fastFileStream.ParseInt32();
if (dev->bytesAvailable() < compressedLen) {
qDebug() << "Too Much at: " << fastFileStream.device()->pos();
qWarning() << "Not enough data for compressed block. Want"
<< compressedLen << "have" << dev->bytesAvailable();
break;
}
fastFileStream.skipRawData(4); // padding
QByteArray compressedAligned(compressedLen, Qt::Uninitialized);
// Read the full aligned block
if (fastFileStream.readRawData(compressedAligned.data(), compressedLen) != compressedLen) {
qWarning() << "Unexpected EOF while reading aligned compressed block";
//return false;
}
// Only first compLenRaw bytes are real data
QByteArray compressedChunk = compressedAligned.left(compLenRaw);
QByteArray decompressedChunk;
switch (compressionType)
{
// Decompress None
case 1:
decompressedChunk = compressedChunk;
break;
// unknown
case 4:
case 5:
qDebug() << "unimplemented compression type!";
return false;
// Decompress Oodle
case 6:
case 7:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
qDebug() << "Calling Oodle with compLenRaw=" << compLenRaw
<< "aligned=" << compressedLen
<< "decompressedLen=" << decompressedLen;
decompressedChunk = Compression::DecompressOodle(compressedChunk, decompressedLen);
break;
default:
qDebug() << "Unknown type of compression!";
return false;
}
if (decompressedChunk.isNull())
{
qDebug() << "Decompressor returned null!";
continue;
}
if (decompressedDataCount + decompressedLen > decompressedDataLen) {
qWarning() << "Decompressed overrun:" << decompressedDataCount + decompressedLen
<< ">" << decompressedDataLen;
decompressedLen = decompressedDataLen - decompressedDataCount;
decompressedChunk.truncate(decompressedLen);
}
decompressedData.append(decompressedChunk);
decompressedDataCount += decompressedLen;
loopCount++;
}
Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
// // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD21_PC* zoneFile = new ZoneFile_COD21_PC();
zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!";
return false;
}
SetZoneFile(zoneFile);
return true;
}

View File

@ -0,0 +1,20 @@
#ifndef FASTFILE_COD21_PC_H
#define FASTFILE_COD21_PC_H
#include "fastfile.h"
class FastFile_COD21_PC : public FastFile
{
public:
FastFile_COD21_PC();
FastFile_COD21_PC(const QByteArray &aData);
FastFile_COD21_PC(const QString aFilePath);
~FastFile_COD21_PC();
QByteArray GetBinaryData() const override;
bool Load(const QString aFilePath) override;
bool Load(const QByteArray aData) override;
};
#endif // FASTFILE_COD21_PC_H

View File

@ -15,8 +15,6 @@ FastFile_COD4_PC::FastFile_COD4_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("PC");
SetGame("COD4");
} }
FastFile_COD4_PC::FastFile_COD4_PC(const QByteArray& aData) FastFile_COD4_PC::FastFile_COD4_PC(const QByteArray& aData)
@ -44,7 +42,7 @@ QByteArray FastFile_COD4_PC::GetBinaryData() const {
} }
bool FastFile_COD4_PC::Load(const QString aFilePath) { bool FastFile_COD4_PC::Load(const QString aFilePath) {
StatusBarManager::instance().updateStatus("Loading " + GetGame() + " Fast File w/path", 1000); StatusBarManager::instance().updateStatus("Loading COD" + GetCommonInfo().GetGameString() + " Fast File w/path", 1000);
if (aFilePath.isEmpty()) { if (aFilePath.isEmpty()) {
return false; return false;
@ -86,6 +84,7 @@ bool FastFile_COD4_PC::Load(const QByteArray aData) {
ZoneFile_COD4_PC* zoneFile = new ZoneFile_COD4_PC(); ZoneFile_COD4_PC* zoneFile = new ZoneFile_COD4_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD5_PC::FastFile_COD5_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("PC");
SetGame("COD5");
} }
FastFile_COD5_PC::FastFile_COD5_PC(const QByteArray& aData) FastFile_COD5_PC::FastFile_COD5_PC(const QByteArray& aData)
@ -86,6 +84,7 @@ bool FastFile_COD5_PC::Load(const QByteArray aData) {
ZoneFile_COD5_PC* zoneFile = new ZoneFile_COD5_PC(); ZoneFile_COD5_PC* zoneFile = new ZoneFile_COD5_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD6_PC::FastFile_COD6_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetPlatform("PC");
SetGame("COD6");
} }
FastFile_COD6_PC::FastFile_COD6_PC(const QByteArray& aData) FastFile_COD6_PC::FastFile_COD6_PC(const QByteArray& aData)
@ -101,6 +99,7 @@ bool FastFile_COD6_PC::Load(const QByteArray aData) {
ZoneFile_COD6_PC* zoneFile = new ZoneFile_COD6_PC(); ZoneFile_COD6_PC* zoneFile = new ZoneFile_COD6_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -1,9 +1,8 @@
#include "fastfile_cod7_pc.h" #include "fastfile_cod7_pc.h"
#include "zonefile_cod7_pc.h" //#include "zonefile_cod7_pc.h"
#include "utils.h" #include "utils.h"
#include "compression.h" #include "compression.h"
#include "encryption.h"
#include <QFile> #include <QFile>
#include <QDebug> #include <QDebug>
@ -15,8 +14,6 @@ FastFile_COD7_PC::FastFile_COD7_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD7");
SetPlatform("PC");
} }
FastFile_COD7_PC::FastFile_COD7_PC(const QByteArray& aData) FastFile_COD7_PC::FastFile_COD7_PC(const QByteArray& aData)
@ -83,8 +80,6 @@ bool FastFile_COD7_PC::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform("360");
SetGame("COD7");
// Assume the first 12 bytes are a header; the rest is zlib-compressed zone data. // Assume the first 12 bytes are a header; the rest is zlib-compressed zone data.
const QByteArray compressedData = aData.mid(12); const QByteArray compressedData = aData.mid(12);
@ -92,13 +87,14 @@ bool FastFile_COD7_PC::Load(const QByteArray aData) {
Utils::ExportData(GetBaseStem() + ".zone", decompressedData); Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
ZoneFile_COD7_PC* zoneFile = new ZoneFile_COD7_PC(); // ZoneFile_COD7_PC* zoneFile = new ZoneFile_COD7_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); // zoneFile->SetStem(GetBaseStem() + ".zone");
if (!zoneFile->Load(decompressedData)) { // zoneFile->SetCommonInfo(&mCommonInfo);
qWarning() << "Failed to load ZoneFile!"; // if (!zoneFile->Load(decompressedData)) {
return false; // qWarning() << "Failed to load ZoneFile!";
} // return false;
SetZoneFile(zoneFile); // }
// SetZoneFile(zoneFile);
return true; return true;
} }

View File

@ -15,8 +15,6 @@ FastFile_COD8_PC::FastFile_COD8_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD8");
SetPlatform("PC");
} }
FastFile_COD8_PC::FastFile_COD8_PC(const QByteArray& aData) FastFile_COD8_PC::FastFile_COD8_PC(const QByteArray& aData)
@ -88,6 +86,7 @@ bool FastFile_COD8_PC::Load(const QByteArray aData) {
ZoneFile_COD8_PC* zoneFile = new ZoneFile_COD8_PC(); ZoneFile_COD8_PC* zoneFile = new ZoneFile_COD8_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD9_PC::FastFile_COD9_PC()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD9");
SetPlatform("PC");
} }
FastFile_COD9_PC::FastFile_COD9_PC(const QByteArray& aData) FastFile_COD9_PC::FastFile_COD9_PC(const QByteArray& aData)
@ -174,6 +172,7 @@ bool FastFile_COD9_PC::Load(const QByteArray aData) {
// Load zone file // Load zone file
ZoneFile_COD9_PC* zoneFile = new ZoneFile_COD9_PC(); ZoneFile_COD9_PC* zoneFile = new ZoneFile_COD9_PC();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(finalZone)) { if (!zoneFile->Load(finalZone)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD10_PS3::FastFile_COD10_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD10");
SetPlatform("PS3");
} }
FastFile_COD10_PS3::FastFile_COD10_PS3(const QByteArray& aData) FastFile_COD10_PS3::FastFile_COD10_PS3(const QByteArray& aData)
@ -80,20 +78,18 @@ bool FastFile_COD10_PS3::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD9");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
if (GetPlatform() == "PC") { if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileStream.setByteOrder(XDataStream::LittleEndian); fastFileStream.setByteOrder(XDataStream::LittleEndian);
} }
// Select key based on game. // Select key based on game.
QByteArray key; QByteArray key;
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3");
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE");
} }
@ -122,6 +118,7 @@ bool FastFile_COD10_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_PS3* zoneFile = new ZoneFile_COD10_PS3(); ZoneFile_COD10_PS3* zoneFile = new ZoneFile_COD10_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -13,8 +13,6 @@ FastFile_COD11_PS3::FastFile_COD11_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD11");
SetPlatform("PS3");
} }
FastFile_COD11_PS3::FastFile_COD11_PS3(const QByteArray& aData) FastFile_COD11_PS3::FastFile_COD11_PS3(const QByteArray& aData)
@ -140,6 +138,7 @@ bool FastFile_COD11_PS3::Load(const QByteArray aData) {
// Load the zone file with decompressed data // Load the zone file with decompressed data
ZoneFile_COD11_PS3* zoneFile = new ZoneFile_COD11_PS3(); ZoneFile_COD11_PS3* zoneFile = new ZoneFile_COD11_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD12_PS3::FastFile_COD12_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD12");
SetPlatform("PS3");
} }
FastFile_COD12_PS3::FastFile_COD12_PS3(const QByteArray& aData) FastFile_COD12_PS3::FastFile_COD12_PS3(const QByteArray& aData)
@ -80,20 +78,18 @@ bool FastFile_COD12_PS3::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD9");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
if (GetPlatform() == "PC") { if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileStream.setByteOrder(XDataStream::LittleEndian); fastFileStream.setByteOrder(XDataStream::LittleEndian);
} }
// Select key based on game. // Select key based on game.
QByteArray key; QByteArray key;
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3");
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE");
} }
@ -122,6 +118,7 @@ bool FastFile_COD12_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD12_PS3* zoneFile = new ZoneFile_COD12_PS3(); ZoneFile_COD12_PS3* zoneFile = new ZoneFile_COD12_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD4_PS3::FastFile_COD4_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD4");
SetPlatform("PS3");
} }
FastFile_COD4_PS3::FastFile_COD4_PS3(const QByteArray& aData) FastFile_COD4_PS3::FastFile_COD4_PS3(const QByteArray& aData)
@ -108,6 +106,7 @@ bool FastFile_COD4_PS3::Load(const QByteArray aData) {
ZoneFile_COD4_PS3* zoneFile = new ZoneFile_COD4_PS3(); ZoneFile_COD4_PS3* zoneFile = new ZoneFile_COD4_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD5_PS3::FastFile_COD5_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD5");
SetPlatform("PS3");
} }
FastFile_COD5_PS3::FastFile_COD5_PS3(const QByteArray& aData) FastFile_COD5_PS3::FastFile_COD5_PS3(const QByteArray& aData)
@ -108,6 +106,7 @@ bool FastFile_COD5_PS3::Load(const QByteArray aData) {
ZoneFile_COD5_PS3* zoneFile = new ZoneFile_COD5_PS3(); ZoneFile_COD5_PS3* zoneFile = new ZoneFile_COD5_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD6_PS3::FastFile_COD6_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD6");
SetPlatform("PS3");
} }
FastFile_COD6_PS3::FastFile_COD6_PS3(const QByteArray& aData) FastFile_COD6_PS3::FastFile_COD6_PS3(const QByteArray& aData)
@ -101,6 +99,7 @@ bool FastFile_COD6_PS3::Load(const QByteArray aData) {
ZoneFile_COD6_PS3* zoneFile = new ZoneFile_COD6_PS3(); ZoneFile_COD6_PS3* zoneFile = new ZoneFile_COD6_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -15,8 +15,6 @@ FastFile_COD7_PS3::FastFile_COD7_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD7");
SetPlatform("PS3");
} }
FastFile_COD7_PS3::FastFile_COD7_PS3(const QByteArray& aData) FastFile_COD7_PS3::FastFile_COD7_PS3(const QByteArray& aData)
@ -84,6 +82,7 @@ bool FastFile_COD7_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD7_PS3* zoneFile = new ZoneFile_COD7_PS3(); ZoneFile_COD7_PS3* zoneFile = new ZoneFile_COD7_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);

View File

@ -15,8 +15,6 @@ FastFile_COD8_PS3::FastFile_COD8_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD8");
SetPlatform("PS3");
} }
FastFile_COD8_PS3::FastFile_COD8_PS3(const QByteArray& aData) FastFile_COD8_PS3::FastFile_COD8_PS3(const QByteArray& aData)
@ -83,23 +81,22 @@ bool FastFile_COD8_PS3::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD7");
ZoneFile_COD8_PS3* zoneFile = new ZoneFile_COD8_PS3(); ZoneFile_COD8_PS3* zoneFile = new ZoneFile_COD8_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
if (GetPlatform() == "PC") { if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileStream.setByteOrder(XDataStream::LittleEndian); fastFileStream.setByteOrder(XDataStream::LittleEndian);
// Select key based on game. // Select key based on game.
QByteArray key; QByteArray key;
fastFileStream.skipRawData(4); fastFileStream.skipRawData(4);
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d"); key = QByteArray::fromHex("1ac1d12d527c59b40eca619120ff8217ccff09cd16896f81b829c7f52793405d");
} else if (GetPlatform() == "PS3") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PS3) {
key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A"); key = QByteArray::fromHex("46D3F997F29C9ACE175B0DAE3AB8C0C1B8E423E2E3BF7E3C311EA35245BF193A");
// or // or
// key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370"); // key = QByteArray::fromHex("0C99B3DDB8D6D0845D1147E470F28A8BF2AE69A8A9F534767B54E9180FF55370");

View File

@ -12,8 +12,6 @@ FastFile_COD9_PS3::FastFile_COD9_PS3()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD9");
SetPlatform("PS3");
} }
FastFile_COD9_PS3::FastFile_COD9_PS3(const QByteArray& aData) FastFile_COD9_PS3::FastFile_COD9_PS3(const QByteArray& aData)
@ -80,20 +78,18 @@ bool FastFile_COD9_PS3::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD9");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
if (GetPlatform() == "PC") { if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileStream.setByteOrder(XDataStream::LittleEndian); fastFileStream.setByteOrder(XDataStream::LittleEndian);
} }
// Select key based on game. // Select key based on game.
QByteArray key; QByteArray key;
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3");
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE");
} }
@ -114,9 +110,9 @@ bool FastFile_COD9_PS3::Load(const QByteArray aData) {
QByteArray rsaSignature(256, Qt::Uninitialized); QByteArray rsaSignature(256, Qt::Uninitialized);
fastFileStream.readRawData(rsaSignature.data(), 256); fastFileStream.readRawData(rsaSignature.data(), 256);
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
//decompressedData = Compressor::cod9_decryptFastFile(aData); //decompressedData = Compressor::cod9_decryptFastFile(aData);
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
//decompressedData = Encryption::decryptFastFile_BO2(aData); //decompressedData = Encryption::decryptFastFile_BO2(aData);
} }
@ -130,6 +126,7 @@ bool FastFile_COD9_PS3::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD9_PS3* zoneFile = new ZoneFile_COD9_PS3(); ZoneFile_COD9_PS3* zoneFile = new ZoneFile_COD9_PS3();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -14,8 +14,6 @@ FastFile_COD4_Wii::FastFile_COD4_Wii()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD4");
SetPlatform("Wii");
} }
FastFile_COD4_Wii::FastFile_COD4_Wii(const QByteArray& aData) FastFile_COD4_Wii::FastFile_COD4_Wii(const QByteArray& aData)
@ -75,6 +73,7 @@ bool FastFile_COD4_Wii::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD4_Wii* zoneFile = new ZoneFile_COD4_Wii(); ZoneFile_COD4_Wii* zoneFile = new ZoneFile_COD4_Wii();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -14,8 +14,6 @@ FastFile_COD7_Wii::FastFile_COD7_Wii()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD7");
SetPlatform("Wii");
} }
FastFile_COD7_Wii::FastFile_COD7_Wii(const QByteArray& aData) FastFile_COD7_Wii::FastFile_COD7_Wii(const QByteArray& aData)
@ -80,8 +78,6 @@ bool FastFile_COD7_Wii::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD7");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
@ -103,6 +99,7 @@ bool FastFile_COD7_Wii::Load(const QByteArray aData) {
ZoneFile_COD7_Wii* zoneFile = new ZoneFile_COD7_Wii(); ZoneFile_COD7_Wii* zoneFile = new ZoneFile_COD7_Wii();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -14,8 +14,6 @@ FastFile_COD8_Wii::FastFile_COD8_Wii()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD8");
SetPlatform("Wii");
} }
FastFile_COD8_Wii::FastFile_COD8_Wii(const QByteArray& aData) FastFile_COD8_Wii::FastFile_COD8_Wii(const QByteArray& aData)
@ -90,6 +88,7 @@ bool FastFile_COD8_Wii::Load(const QByteArray aData) {
ZoneFile_COD8_Wii* zoneFile = new ZoneFile_COD8_Wii(); ZoneFile_COD8_Wii* zoneFile = new ZoneFile_COD8_Wii();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD10_WiiU::FastFile_COD10_WiiU()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD10");
SetPlatform("WiiU");
} }
FastFile_COD10_WiiU::FastFile_COD10_WiiU(const QByteArray& aData) FastFile_COD10_WiiU::FastFile_COD10_WiiU(const QByteArray& aData)
@ -78,20 +76,18 @@ bool FastFile_COD10_WiiU::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD9");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
if (GetPlatform() == "PC") { if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileStream.setByteOrder(XDataStream::LittleEndian); fastFileStream.setByteOrder(XDataStream::LittleEndian);
} }
// Select key based on game. // Select key based on game.
QByteArray key; QByteArray key;
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3");
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE");
} }
@ -112,9 +108,9 @@ bool FastFile_COD10_WiiU::Load(const QByteArray aData) {
QByteArray rsaSignature(256, Qt::Uninitialized); QByteArray rsaSignature(256, Qt::Uninitialized);
fastFileStream.readRawData(rsaSignature.data(), 256); fastFileStream.readRawData(rsaSignature.data(), 256);
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
//decompressedData = Compressor::cod9_decryptFastFile(aData); //decompressedData = Compressor::cod9_decryptFastFile(aData);
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
//decompressedData = Encryption::decryptFastFile_BO2(aData); //decompressedData = Encryption::decryptFastFile_BO2(aData);
} }
@ -128,6 +124,7 @@ bool FastFile_COD10_WiiU::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD10_WiiU *zoneFile = new ZoneFile_COD10_WiiU(); ZoneFile_COD10_WiiU *zoneFile = new ZoneFile_COD10_WiiU();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -12,8 +12,6 @@ FastFile_COD9_WiiU::FastFile_COD9_WiiU()
SetSignage(SIGNAGE_UNSIGNED); SetSignage(SIGNAGE_UNSIGNED);
SetMagic(0); SetMagic(0);
SetVersion(0); SetVersion(0);
SetGame("COD9");
SetPlatform("WiiU");
} }
FastFile_COD9_WiiU::FastFile_COD9_WiiU(const QByteArray& aData) FastFile_COD9_WiiU::FastFile_COD9_WiiU(const QByteArray& aData)
@ -78,20 +76,18 @@ bool FastFile_COD9_WiiU::Load(const QByteArray aData) {
SetMagic(pParseFFMagic(&fastFileStream)); SetMagic(pParseFFMagic(&fastFileStream));
quint32 version = pParseFFVersion(&fastFileStream); quint32 version = pParseFFVersion(&fastFileStream);
SetVersion(version); SetVersion(version);
SetPlatform(pCalculateFFPlatform(version));
SetGame("COD9");
// For COD7/COD9, use BigEndian. // For COD7/COD9, use BigEndian.
fastFileStream.setByteOrder(XDataStream::BigEndian); fastFileStream.setByteOrder(XDataStream::BigEndian);
if (GetPlatform() == "PC") { if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
fastFileStream.setByteOrder(XDataStream::LittleEndian); fastFileStream.setByteOrder(XDataStream::LittleEndian);
} }
// Select key based on game. // Select key based on game.
QByteArray key; QByteArray key;
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3"); key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3");
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE"); key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE");
} }
@ -112,9 +108,9 @@ bool FastFile_COD9_WiiU::Load(const QByteArray aData) {
QByteArray rsaSignature(256, Qt::Uninitialized); QByteArray rsaSignature(256, Qt::Uninitialized);
fastFileStream.readRawData(rsaSignature.data(), 256); fastFileStream.readRawData(rsaSignature.data(), 256);
if (GetPlatform() == "360") { if (GetCommonInfo().GetPlatform() == PLATFORM_XBOX) {
//decompressedData = Compressor::cod9_decryptFastFile(aData); //decompressedData = Compressor::cod9_decryptFastFile(aData);
} else if (GetPlatform() == "PC") { } else if (GetCommonInfo().GetPlatform() == PLATFORM_PC) {
//decompressedData = Encryption::decryptFastFile_BO2(aData); //decompressedData = Encryption::decryptFastFile_BO2(aData);
} }
@ -128,6 +124,7 @@ bool FastFile_COD9_WiiU::Load(const QByteArray aData) {
// Load the zone file with the decompressed data (using an Xbox platform flag). // Load the zone file with the decompressed data (using an Xbox platform flag).
ZoneFile_COD9_WiiU* zoneFile = new ZoneFile_COD9_WiiU(); ZoneFile_COD9_WiiU* zoneFile = new ZoneFile_COD9_WiiU();
zoneFile->SetStem(GetBaseStem() + ".zone"); zoneFile->SetStem(GetBaseStem() + ".zone");
zoneFile->SetCommonInfo(&mCommonInfo);
if (!zoneFile->Load(decompressedData)) { if (!zoneFile->Load(decompressedData)) {
qWarning() << "Failed to load ZoneFile!"; qWarning() << "Failed to load ZoneFile!";
return false; return false;

View File

@ -7,15 +7,15 @@
#include <QDebug> #include <QDebug>
FastFile::FastFile() FastFile::FastFile()
: mStem(""), : mCommonInfo(),
mStem(""),
mType(FILETYPE_NONE), mType(FILETYPE_NONE),
mCompany(COMPANY_NONE), mCompany(COMPANY_NONE),
mSignage(SIGNAGE_NONE), mSignage(SIGNAGE_NONE),
mMagic(""), mMagic(""),
mVersion(0), mVersion(0),
mZoneFile(nullptr), mZoneFile(nullptr)
mGame(""), {
mPlatform("") {
} }
@ -24,15 +24,15 @@ FastFile::FastFile(const QByteArray &aData) {
} }
FastFile::FastFile(FastFile &fastFile) FastFile::FastFile(FastFile &fastFile)
: mStem(fastFile.GetStem()), : mCommonInfo(fastFile.GetCommonInfo()),
mStem(fastFile.GetStem()),
mType(fastFile.GetType()), mType(fastFile.GetType()),
mCompany(fastFile.GetCompany()), mCompany(fastFile.GetCompany()),
mSignage(fastFile.GetSignage()), mSignage(fastFile.GetSignage()),
mMagic(fastFile.GetMagic()), mMagic(fastFile.GetMagic()),
mVersion(fastFile.GetVersion()), mVersion(fastFile.GetVersion()),
mZoneFile(fastFile.GetZoneFile()), mZoneFile(fastFile.GetZoneFile())
mGame(fastFile.GetGame()), {
mPlatform(fastFile.GetPlatform()) {
} }
@ -72,14 +72,6 @@ const ZoneFile* FastFile::GetZoneFile() const {
return mZoneFile; return mZoneFile;
} }
QString FastFile::GetGame() const {
return mGame;
}
QString FastFile::GetPlatform() const {
return mPlatform;
}
void FastFile::SetStem(const QString aStem) { void FastFile::SetStem(const QString aStem) {
mStem = aStem; mStem = aStem;
} }
@ -108,13 +100,6 @@ void FastFile::SetZoneFile(const ZoneFile* aZoneFile) {
mZoneFile = aZoneFile; mZoneFile = aZoneFile;
} }
void FastFile::SetGame(const QString aGame) { mGame = aGame;
}
void FastFile::SetPlatform(const QString aPlatform) {
mPlatform = aPlatform;
}
FF_COMPANY FastFile::pParseFFCompany(XDataStream *afastFileStream, quint32 &aCompanyInt) { FF_COMPANY FastFile::pParseFFCompany(XDataStream *afastFileStream, quint32 &aCompanyInt) {
LogManager::instance().addEntry("Parsing company into reference..."); LogManager::instance().addEntry("Parsing company into reference...");
// Check for null datastream ptr // Check for null datastream ptr
@ -272,6 +257,27 @@ FastFile* FastFile::Open(const QString &aFilePath) {
return fastFile; return fastFile;
} }
XCommonInfo FastFile::GetCommonInfo() const
{
return mCommonInfo;
}
void FastFile::SetCommonInfo(const XCommonInfo &newCommonInfo)
{
mCommonInfo = newCommonInfo;
}
bool FastFile::Debug() const
{
return mDebug;
}
void FastFile::SetDebug(bool aDebug)
{
mDebug = aDebug;
}
bool FastFile::ExportFastFile(const QString aFastFilePath) const { bool FastFile::ExportFastFile(const QString aFastFilePath) const {
QFile fastFile(aFastFilePath); QFile fastFile(aFastFilePath);
if (!fastFile.open(QIODevice::WriteOnly)) { if (!fastFile.open(QIODevice::WriteOnly)) {

View File

@ -2,8 +2,9 @@
#define FASTFILE_H #define FASTFILE_H
#include "enums.h" #include "enums.h"
#include "utils.h"
#include "zonefile.h" #include "zonefile.h"
#include "xcommoninfo.h"
#include "utils.h"
#include <QString> #include <QString>
#include <QCryptographicHash> #include <QCryptographicHash>
@ -33,8 +34,6 @@ public:
virtual QString GetMagic() const; virtual QString GetMagic() const;
virtual quint32 GetVersion() const; virtual quint32 GetVersion() const;
virtual const ZoneFile *GetZoneFile() const; virtual const ZoneFile *GetZoneFile() const;
virtual QString GetGame() const;
virtual QString GetPlatform() const;
virtual void SetStem(const QString aStem); virtual void SetStem(const QString aStem);
virtual void SetType(const FF_FILETYPE aType); virtual void SetType(const FF_FILETYPE aType);
@ -43,8 +42,6 @@ public:
virtual void SetMagic(const QString aMagic); virtual void SetMagic(const QString aMagic);
virtual void SetVersion(const quint32 aVersion); virtual void SetVersion(const quint32 aVersion);
virtual void SetZoneFile(const ZoneFile* aZoneFile); virtual void SetZoneFile(const ZoneFile* aZoneFile);
virtual void SetGame(const QString aGame);
virtual void SetPlatform(const QString aPlatform);
static FF_COMPANY pParseFFCompany(XDataStream *afastFileStream, quint32 &aCompanyInt); static FF_COMPANY pParseFFCompany(XDataStream *afastFileStream, quint32 &aCompanyInt);
static FF_COMPANY pParseFFCompany(XDataStream *afastFileStream); static FF_COMPANY pParseFFCompany(XDataStream *afastFileStream);
@ -57,6 +54,15 @@ public:
static FastFile* Open(const QString& aFilePath); static FastFile* Open(const QString& aFilePath);
XCommonInfo GetCommonInfo() const;
void SetCommonInfo(const XCommonInfo &newCommonInfo);
bool Debug() const;
void SetDebug(bool aDebug);
protected:
XCommonInfo mCommonInfo;
private: private:
QString mStem; QString mStem;
FF_FILETYPE mType; FF_FILETYPE mType;
@ -65,8 +71,8 @@ private:
QString mMagic; QString mMagic;
quint32 mVersion; quint32 mVersion;
const ZoneFile* mZoneFile; const ZoneFile* mZoneFile;
QString mGame;
QString mPlatform; bool mDebug;
}; };
#endif // FASTFILE_H #endif // FASTFILE_H

View File

@ -15,6 +15,7 @@
#include "360/fastfile_cod12_360.h" #include "360/fastfile_cod12_360.h"
//#include "PS3/fastfile_cod3_ps3.h" //#include "PS3/fastfile_cod3_ps3.h"
#include "PC/fastfile_cod21_pc.h"
#include "PS3/fastfile_cod4_ps3.h" #include "PS3/fastfile_cod4_ps3.h"
#include "PS3/fastfile_cod5_ps3.h" #include "PS3/fastfile_cod5_ps3.h"
#include "PS3/fastfile_cod6_ps3.h" #include "PS3/fastfile_cod6_ps3.h"
@ -45,39 +46,14 @@
#include <QByteArray> #include <QByteArray>
#include <QString> #include <QString>
#include <memory>
#include <QFile> #include <QFile>
#include <QDebug> #include <QDebug>
class FastFile; class FastFile;
enum FastFile_Platform {
PLATFORM_NONE = 0x00,
PLATFORM_PC = 0x01,
PLATFORM_360 = 0x02,
PLATFORM_PS3 = 0x03,
PLATFORM_WII = 0x04,
PLATFORM_WIIU = 0x05
};
enum FastFile_Game {
GAME_NONE = 0x00,
GAME_COD2 = 0x01,
GAME_COD4 = 0x02,
GAME_COD5 = 0x03,
GAME_COD6 = 0x04,
GAME_COD7 = 0x05,
GAME_COD7_5 = 0x06,
GAME_COD8 = 0x07,
GAME_COD9 = 0x08,
GAME_COD10 = 0x09,
GAME_COD11 = 0x10,
GAME_COD12 = 0x11
};
class FastFileFactory { class FastFileFactory {
public: public:
static FastFile* Create(const QString& aFilePath, FastFile_Platform aPlatform = PLATFORM_NONE, FastFile_Game aGame = GAME_NONE) { static FastFile* Create(const QString& aFilePath, XPlatform aPlatform = PLATFORM_NONE, XGame aGame = GAME_NONE) {
QFile fastFile(aFilePath); QFile fastFile(aFilePath);
if (!fastFile.open(QIODevice::ReadOnly)) { if (!fastFile.open(QIODevice::ReadOnly)) {
qDebug() << "Factory failed to open fast file: " << aFilePath; qDebug() << "Factory failed to open fast file: " << aFilePath;
@ -96,7 +72,7 @@ public:
aGame = pGetGame(data); aGame = pGetGame(data);
} }
if (aPlatform == PLATFORM_360) { if (aPlatform == PLATFORM_XBOX) {
if (aGame == GAME_COD2) { if (aGame == GAME_COD2) {
resultFF = new FastFile_COD2_360(aFilePath); resultFF = new FastFile_COD2_360(aFilePath);
} else if (aGame == GAME_COD4) { } else if (aGame == GAME_COD4) {
@ -173,9 +149,15 @@ public:
resultFF = new FastFile_COD10_WiiU(aFilePath); resultFF = new FastFile_COD10_WiiU(aFilePath);
} }
} }
if (resultFF)
{
resultFF->SetCommonInfo(XCommonInfo(aGame, aPlatform));
}
return resultFF; return resultFF;
} }
static FastFile* Create(const QByteArray& aData, const QString aStem = "no_name", FastFile_Platform aPlatform = PLATFORM_NONE, FastFile_Game aGame = GAME_NONE) { static FastFile* Create(const QByteArray& aData, const QString aStem = "no_name", XPlatform aPlatform = PLATFORM_NONE, XGame aGame = GAME_NONE) {
FastFile* resultFF = nullptr; FastFile* resultFF = nullptr;
if (aPlatform == PLATFORM_NONE) { if (aPlatform == PLATFORM_NONE) {
@ -185,7 +167,7 @@ public:
aGame = pGetGame(aData); aGame = pGetGame(aData);
} }
if (aPlatform == PLATFORM_360) { if (aPlatform == PLATFORM_XBOX) {
if (aGame == GAME_COD2) { if (aGame == GAME_COD2) {
resultFF = new FastFile_COD2_360(); resultFF = new FastFile_COD2_360();
} else if (aGame == GAME_COD4) { } else if (aGame == GAME_COD4) {
@ -228,6 +210,8 @@ public:
resultFF = new FastFile_COD11_PC(); resultFF = new FastFile_COD11_PC();
} else if (aGame == GAME_COD12) { } else if (aGame == GAME_COD12) {
resultFF = new FastFile_COD12_PC(); resultFF = new FastFile_COD12_PC();
} else if (aGame == GAME_COD21) {
resultFF = new FastFile_COD21_PC();
} }
} else if (aPlatform == PLATFORM_PS3) { } else if (aPlatform == PLATFORM_PS3) {
if (aGame == GAME_COD4) { if (aGame == GAME_COD4) {
@ -266,8 +250,10 @@ public:
} }
if (resultFF) { if (resultFF) {
resultFF->SetStem(aStem); resultFF->SetStem(aStem);
resultFF->SetCommonInfo(XCommonInfo(aGame, aPlatform));
resultFF->Load(aData); resultFF->Load(aData);
} }
return resultFF; return resultFF;
} }
private: private:
@ -286,33 +272,38 @@ private:
return sections; return sections;
} }
static FastFile_Platform pGetPlatform(const QByteArray& aData) { static XPlatform pGetPlatform(const QByteArray& aData) {
const QStringList sections = pGetDataSections(aData); const QStringList sections = pGetDataSections(aData);
if (sections[0] == "0000" || sections[0] == "4E58") { if (pGetGame(aData) == GAME_COD21)
return PLATFORM_360; {
} else if (sections[4] == "0000") { return PLATFORM_PC;
}
else if (sections[0] == "0000" || sections[0] == "4E58") {
return PLATFORM_XBOX;
}
else if (sections[4] == "0000") {
if (sections[5] == "0001" && sections[6] == "78DA") { if (sections[5] == "0001" && sections[6] == "78DA") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[5] == "0001" && sections[6] == "4957") { } else if (sections[5] == "0001" && sections[6] == "4957") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[5] == "0183" && sections[6] == "7801") { } else if (sections[5] == "0183" && sections[6] == "7801") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[5] == "01D9" && sections[6] == "0000") { } else if (sections[5] == "01D9" && sections[6] == "0000") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[6] == "0101" && sections[7] == "CA3E") { } else if (sections[6] == "0101" && sections[7] == "CA3E") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[6] == "0000" && sections[7] == "0001") { } else if (sections[6] == "0000" && sections[7] == "0001") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[6] == "0101" && sections[7] == "CC76") { } else if (sections[6] == "0101" && sections[7] == "CC76") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[6] == "0101" && sections[7] == "0101") { } else if (sections[6] == "0101" && sections[7] == "0101") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[2] == "7831") { } else if (sections[2] == "7831") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[0] == "5331" && sections[2] == "7531") { } else if (sections[0] == "5331" && sections[2] == "7531") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[2] == "3030" && sections[3] == "3030") { } else if (sections[2] == "3030" && sections[3] == "3030") {
return PLATFORM_360; return PLATFORM_XBOX;
} else if (sections[5] == "01A2" && sections[6] == "7801") { } else if (sections[5] == "01A2" && sections[6] == "7801") {
return PLATFORM_WII; return PLATFORM_WII;
} else if (sections[5] == "01DD" && sections[6] == "7801") { } else if (sections[5] == "01DD" && sections[6] == "7801") {
@ -328,7 +319,7 @@ private:
return PLATFORM_PS3; return PLATFORM_PS3;
} }
static FastFile_Game pGetGame(const QByteArray& aData) { static XGame pGetGame(const QByteArray& aData) {
const QStringList sections = pGetDataSections(aData); const QStringList sections = pGetDataSections(aData);
if (sections[0] == "0000") { if (sections[0] == "0000") {
return GAME_COD2; return GAME_COD2;
@ -353,6 +344,8 @@ private:
return GAME_COD11; return GAME_COD11;
} else if (sections[2] == "3030") { } else if (sections[2] == "3030") {
return GAME_COD12; return GAME_COD12;
} else if (sections[2] == "6131" || sections[2] == "6431") {
return GAME_COD21;
} }
return GAME_NONE; return GAME_NONE;
} }

View File

@ -1,5 +1,4 @@
#include "iwifile.h" #include "iwifile.h"
#include "ddsfile.h"
IWIFile::IWIFile() : IWIFile::IWIFile() :
fileStem(), fileStem(),
@ -81,39 +80,39 @@ IWIFile::IWIFile(const QString &aFilePath) :
file.close(); file.close();
} }
IWIFile::IWIFile(const DDSFile &aDDSFile) { // IWIFile::IWIFile(const DDSFile &aDDSFile) {
// Ensure the DDS file has mipmaps // // Ensure the DDS file has mipmaps
if (aDDSFile.mipmaps.isEmpty()) { // if (aDDSFile.mipmaps.isEmpty()) {
qDebug() << "Error: No mipmaps found in DDS file!"; // qDebug() << "Error: No mipmaps found in DDS file!";
return; // return;
} // }
// Create IWIFile object // // Create IWIFile object
fileStem = aDDSFile.fileStem; // fileStem = aDDSFile.fileStem;
// Set header (Magic & Version) // // Set header (Magic & Version)
memcpy(header.Magic, "IWi", 3); // memcpy(header.Magic, "IWi", 3);
header.Version = 0x06; // Default to CoD4/CoD5 version // header.Version = 0x06; // Default to CoD4/CoD5 version
// Set IWI Texture Info // // Set IWI Texture Info
info.Format = static_cast<quint8>(aDDSFile.header.pixelFormat.format); // info.Format = static_cast<quint8>(aDDSFile.header.pixelFormat.format);
info.Width = aDDSFile.header.width; // info.Width = aDDSFile.header.width;
info.Height = aDDSFile.header.height; // info.Height = aDDSFile.header.height;
info.Depth = 1; // Default depth for 2D textures // info.Depth = 1; // Default depth for 2D textures
info.Usage = 0; // No specific usage // info.Usage = 0; // No specific usage
// Convert DDS mipmaps to IWI mipmaps // // Convert DDS mipmaps to IWI mipmaps
int offset = 28; // Standard offset start // int offset = 28; // Standard offset start
for (const auto& ddsMipmap : aDDSFile.mipmaps) { // for (const auto& ddsMipmap : aDDSFile.mipmaps) {
IWIMipmap iwiMipmap; // IWIMipmap iwiMipmap;
iwiMipmap.offset = offset; // iwiMipmap.offset = offset;
iwiMipmap.size = ddsMipmap.data.size(); // iwiMipmap.size = ddsMipmap.data.size();
iwiMipmap.data = ddsMipmap.data; // iwiMipmap.data = ddsMipmap.data;
offset += iwiMipmap.size; // offset += iwiMipmap.size;
mipmaps.append(iwiMipmap); // mipmaps.append(iwiMipmap);
} // }
} // }
IWIFile::IWIFile(const IWIFile &iwiFile) { IWIFile::IWIFile(const IWIFile &iwiFile) {
fileStem = iwiFile.fileStem; fileStem = iwiFile.fileStem;
@ -210,80 +209,82 @@ bool IWIFile::SaveIWI() const {
return true; return true;
} }
bool IWIFile::SaveDDS() const { // bool IWIFile::SaveDDS() const {
SetupExportDirs(); // SetupExportDirs();
QFile file("exports/dds/" + fileStem + ".dds"); // QFile file("exports/dds/" + fileStem + ".dds");
if (!file.open(QIODevice::WriteOnly)) { // if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Error: Unable to write DDS file " << fileStem + ".dds"; // qDebug() << "Error: Unable to write DDS file " << fileStem + ".dds";
return false; // return false;
} // }
DDSHeader ddsHeader = {}; // DDSHeader ddsHeader = {};
ddsHeader.magic = 0x20534444; // 'DDS ' // ddsHeader.magic = 0x20534444; // 'DDS '
ddsHeader.size = 124; // ddsHeader.size = 124;
ddsHeader.flags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_LINEARSIZE; // ddsHeader.flags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_LINEARSIZE;
ddsHeader.height = info.Height; // ddsHeader.height = info.Height;
ddsHeader.width = info.Width; // ddsHeader.width = info.Width;
ddsHeader.depth = 0; // ddsHeader.depth = 0;
ddsHeader.mipMapCount = mipmaps.size(); // ddsHeader.mipMapCount = mipmaps.size();
DDSPixelFormat ddsPixelFormat = DDSFile::CalculatePixelFormat(info.Format); // DDSPixelFormat ddsPixelFormat = DDSFile::CalculatePixelFormat(info.Format);
if (ddsPixelFormat.flags & DDPF_FOURCC) { // if (ddsPixelFormat.flags & DDPF_FOURCC) {
ddsHeader.flags |= DDSD_LINEARSIZE; // ddsHeader.flags |= DDSD_LINEARSIZE;
} else { // } else {
ddsHeader.flags |= DDSD_PITCH; // ddsHeader.flags |= DDSD_PITCH;
} // }
ddsHeader.pixelFormat = ddsPixelFormat; // ddsHeader.pixelFormat = ddsPixelFormat;
// Calculate pitch/linear size // // Calculate pitch/linear size
if (ddsPixelFormat.flags & DDPF_FOURCC) { // if (ddsPixelFormat.flags & DDPF_FOURCC) {
int blockSize = (ddsPixelFormat.format == 0x31545844) ? 8 : 16; // int blockSize = (ddsPixelFormat.format == 0x31545844) ? 8 : 16;
ddsHeader.pitchOrLinearSize = fmax(1, (ddsHeader.width + 3) / 4) * blockSize * (ddsHeader.height / 4); // ddsHeader.pitchOrLinearSize = fmax(1, (ddsHeader.width + 3) / 4) * blockSize * (ddsHeader.height / 4);
} else { // } else {
ddsHeader.pitchOrLinearSize = ddsHeader.width * (ddsPixelFormat.rgbBitCount / 8); // ddsHeader.pitchOrLinearSize = ddsHeader.width * (ddsPixelFormat.rgbBitCount / 8);
} // }
DDSCaps ddsCaps = {}; // DDSCaps ddsCaps = {};
ddsCaps.caps1 = DDSCAPS_TEXTURE; // ddsCaps.caps1 = DDSCAPS_TEXTURE;
ddsCaps.caps2 = 0; // ddsCaps.caps2 = 0;
ddsCaps.dDSX = 0; // ddsCaps.dDSX = 0;
ddsCaps.reserved = 0; // ddsCaps.reserved = 0;
ddsHeader.caps = ddsCaps; // ddsHeader.caps = ddsCaps;
QDataStream out(&file); // QDataStream out(&file);
out.setByteOrder(QDataStream::LittleEndian); // out.setByteOrder(QDataStream::LittleEndian);
// Write DDS header // // Write DDS header
out.writeRawData(reinterpret_cast<const char*>(&ddsHeader), sizeof(DDSHeader)); // out.writeRawData(reinterpret_cast<const char*>(&ddsHeader), sizeof(DDSHeader));
for (auto mipmap : mipmaps) { // for (auto mipmap : mipmaps) {
if (!mipmap.data.size()) { continue; } // if (!mipmap.data.size()) { continue; }
// Write mipmap data // // Write mipmap data
out.writeRawData(reinterpret_cast<const char*>(mipmap.data.constData()), mipmap.data.size()); // out.writeRawData(reinterpret_cast<const char*>(mipmap.data.constData()), mipmap.data.size());
} // }
file.close(); // file.close();
return true; // return true;
} // }
bool IWIFile::SavePNG() const { bool IWIFile::SavePNG() const {
DDSFile ddsFile(*this); // DDSFile ddsFile(*this);
if (!ddsFile.SavePNG()) { // if (!ddsFile.SavePNG()) {
qDebug() << "Error: Failed to save PNG file: " << fileStem + ".png"; // qDebug() << "Error: Failed to save PNG file: " << fileStem + ".png";
// return false;
// }
// return true;
return false; return false;
} }
return true;
}
bool IWIFile::SaveJPG() const { bool IWIFile::SaveJPG() const {
DDSFile ddsFile(*this); // DDSFile ddsFile(*this);
if (!ddsFile.SavePNG()) { // if (!ddsFile.SavePNG()) {
qDebug() << "Error: Failed to save JPG file: " << fileStem + ".jpg"; // qDebug() << "Error: Failed to save JPG file: " << fileStem + ".jpg";
// return false;
// }
// return true;
return false; return false;
} }
return true;
}
// Check if the IWI version is supported // Check if the IWI version is supported
bool IWIHeader::isSupported() const { bool IWIHeader::isSupported() const {

View File

@ -9,8 +9,6 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include "ddsfile.h"
// Supported versions // Supported versions
static const QVector<quint8> supportedVersions = { static const QVector<quint8> supportedVersions = {
0x05, // CoD2 0x05, // CoD2
@ -50,7 +48,6 @@ public:
IWIFile(); IWIFile();
IWIFile(const QString &aFilePath); IWIFile(const QString &aFilePath);
IWIFile(const DDSFile &aDDSFile);
IWIFile(const IWIFile &iwiFile); IWIFile(const IWIFile &iwiFile);
IWIFile& operator=(const IWIFile& other); IWIFile& operator=(const IWIFile& other);
~IWIFile(); ~IWIFile();

View File

@ -9,11 +9,9 @@ XAnimDeltaPart::XAnimDeltaPart()
} }
void XAnimDeltaPart::ParseData(XDataStream *aStream) { void XAnimDeltaPart::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
mTrans.ParsePtr(aStream); mTrans.ParsePtr(aStream);
mQuat.ParsePtr(aStream); mQuat.ParsePtr(aStream);
} }
}
void XAnimDeltaPart::Clear() void XAnimDeltaPart::Clear()
{ {

View File

@ -7,13 +7,11 @@ XAnimDeltaPartQuat::XAnimDeltaPartQuat()
} }
void XAnimDeltaPartQuat::ParseData(XDataStream *aStream) { void XAnimDeltaPartQuat::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
mSize = aStream->ParseUInt32(QString("%1 size").arg(GetName())); mSize = aStream->ParseUInt32(QString("%1 size").arg(GetName()));
// Parse data // Parse data
mData.ParseData(aStream); mData.ParseData(aStream);
} }
}
quint32 XAnimDeltaPartQuat::GetSize() const { quint32 XAnimDeltaPartQuat::GetSize() const {
return mSize; return mSize;

View File

@ -7,11 +7,9 @@ XAnimDeltaPartQuatData::XAnimDeltaPartQuatData()
} }
void XAnimDeltaPartQuatData::ParseData(XDataStream *aStream) { void XAnimDeltaPartQuatData::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
// Parse frames // Parse frames
mFrames.ParseData(aStream); mFrames.ParseData(aStream);
} }
}
const XAnimDeltaPartQuatDataFrames& XAnimDeltaPartQuatData::GetFrames() const { const XAnimDeltaPartQuatDataFrames& XAnimDeltaPartQuatData::GetFrames() const {
return mFrames; return mFrames;

View File

@ -37,7 +37,6 @@ void XAnimDeltaPartQuatDataFrames::SetIndices(const XAnimDynamicIndices& indices
} }
void XAnimDeltaPartQuatDataFrames::ParseData(XDataStream *aStream) { void XAnimDeltaPartQuatDataFrames::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
mFramesPtr = aStream->ParseInt32(QString("%1 frames ptr").arg(GetName())); mFramesPtr = aStream->ParseInt32(QString("%1 frames ptr").arg(GetName()));
mFrames[0] = aStream->ParseInt16(QString("%1 frame %2").arg(GetName()).arg(0)); mFrames[0] = aStream->ParseInt16(QString("%1 frame %2").arg(GetName()).arg(0));
@ -46,7 +45,6 @@ void XAnimDeltaPartQuatDataFrames::ParseData(XDataStream *aStream) {
// Parse indices // Parse indices
mIndices.ParseData(aStream); mIndices.ParseData(aStream);
} }
}
void XAnimDeltaPartQuatDataFrames::Clear() void XAnimDeltaPartQuatDataFrames::Clear()
{ {

View File

@ -8,16 +8,10 @@ XAnimDynamicFrames::XAnimDynamicFrames()
} }
void XAnimDynamicFrames::ParseData(XDataStream *aStream) { void XAnimDynamicFrames::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
qint32 framePtr = aStream->ParseInt32(QString("%1 frames ptr").arg(GetName()));
if (framePtr == -1)
{
mFrames[0] = aStream->ParseUInt8(QString("%1 frame %2").arg(GetName()).arg(0)); mFrames[0] = aStream->ParseUInt8(QString("%1 frame %2").arg(GetName()).arg(0));
mFrames[1] = aStream->ParseUInt8(QString("%1 frame %2").arg(GetName()).arg(1)); mFrames[1] = aStream->ParseUInt8(QString("%1 frame %2").arg(GetName()).arg(1));
mFrames[2] = aStream->ParseUInt8(QString("%1 frame %2").arg(GetName()).arg(2)); mFrames[2] = aStream->ParseUInt8(QString("%1 frame %2").arg(GetName()).arg(2));
} }
}
}
void XAnimDynamicFrames::Clear() void XAnimDynamicFrames::Clear()
{ {

View File

@ -8,10 +8,8 @@ XAnimDynamicIndices::XAnimDynamicIndices()
} }
void XAnimDynamicIndices::ParseData(XDataStream *aStream) { void XAnimDynamicIndices::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
mIndices[0] = aStream->ParseUInt8(QString("%1 index").arg(GetName())); mIndices[0] = aStream->ParseUInt8(QString("%1 index").arg(GetName()));
} }
}
void XAnimDynamicIndices::Clear() void XAnimDynamicIndices::Clear()
{ {

View File

@ -7,15 +7,10 @@ XAnimIndices::XAnimIndices()
SetName("Animation Indices"); SetName("Animation Indices");
} }
void XAnimIndices::ParseData(XDataStream *aStream) { void XAnimIndices::ParseData(XDataStream *aStream)
if (GetPtr() == -1) {
qint32 indexPtr = aStream->ParseInt32(QString("%1 index ptr").arg(GetName()));
if (indexPtr == -1)
{ {
mIndex = aStream->ParseUInt32(QString("%1 index").arg(GetName())); mIndex = aStream->ParseUInt32(QString("%1 index").arg(GetName()));
} }
}
}
void XAnimIndices::Clear() void XAnimIndices::Clear()
{ {

View File

@ -8,13 +8,11 @@ XAnimNotifyInfo::XAnimNotifyInfo()
SetName("Animation Notify Info"); SetName("Animation Notify Info");
} }
void XAnimNotifyInfo::ParseData(XDataStream *aStream) { void XAnimNotifyInfo::ParseData(XDataStream *aStream)
if (GetPtr() == -1) { {
mName = aStream->ParseUInt32(QString("%1 name").arg(GetName())); mName = aStream->ParseUInt32(QString("%1 name").arg(GetName()));
mTime = aStream->ParseSingle(QString("%1 time").arg(GetName())); mTime = aStream->ParseSingle(QString("%1 time").arg(GetName()));
} }
}
void XAnimNotifyInfo::Clear() void XAnimNotifyInfo::Clear()
{ {

View File

@ -14,7 +14,7 @@ XAnimParts::XAnimParts()
, mBoneCount(12) , mBoneCount(12)
, mNotifyCount(0) , mNotifyCount(0)
, mAssetType(0) , mAssetType(0)
, mPad(false) , mIsDefault(false)
, mRandomDataShortCount(0) , mRandomDataShortCount(0)
, mIndexCount(0) , mIndexCount(0)
, mFramerate(0.0f) , mFramerate(0.0f)
@ -34,31 +34,32 @@ XAnimParts::XAnimParts()
SetName("Animation Parts"); SetName("Animation Parts");
} }
void XAnimParts::ParseData(XDataStream *aStream) { void XAnimParts::ParseData(XDataStream *aStream)
if (GetPtr() == -1) { {
mName.ParsePtr(aStream, false); mName.ParsePtr(aStream, false);
// Parse all fields // Parse all fields
mDataByteCount = aStream->ParseUInt32(QString("%1 data byte count").arg(GetName())); mDataByteCount = aStream->ParseUInt16(QString("%1 data byte count").arg(GetName()));
mDataShortCount = aStream->ParseUInt32(QString("%1 data short count").arg(GetName())); mDataShortCount = aStream->ParseUInt16(QString("%1 data short count").arg(GetName()));
mDataIntCount = aStream->ParseUInt32(QString("%1 data int count").arg(GetName())); mDataIntCount = aStream->ParseUInt16(QString("%1 data int count").arg(GetName()));
mRandomDataByteCount = aStream->ParseUInt32(QString("%1 random date byte count").arg(GetName())); mRandomDataByteCount = aStream->ParseUInt16(QString("%1 random date byte count").arg(GetName()));
mRandomDataIntCount = aStream->ParseUInt32(QString("%1 random data int count").arg(GetName())); mRandomDataIntCount = aStream->ParseUInt16(QString("%1 random data int count").arg(GetName()));
mNumFrames = aStream->ParseUInt32(QString("%1 # frames").arg(GetName())); mNumFrames = aStream->ParseUInt16(QString("%1 # frames").arg(GetName()));
quint8 loopDelta = aStream->ParseUInt8(QString("%1 loop delta").arg(GetName())); mIsLoop = aStream->ParseUInt8(QString("%1 loop").arg(GetName()));
mIsLoop = (loopDelta & 0x1) != 0; mIsDelta = aStream->ParseUInt8(QString("%1 delta").arg(GetName()));
mIsDelta = (loopDelta & 0x2) != 0; aStream->skipRawData(2);
for (int i = 0; i < 12; i++) for (int i = 0; i < 10; i++)
{ {
mBoneCount[i] = aStream->ParseUInt8(QString("%1 bone count %2").arg(GetName()).arg(i)); mBoneCount[i] = aStream->ParseUInt8(QString("%1 bone count %2").arg(GetName()).arg(i));
} }
aStream->skipRawData(2);
mNotifyCount = aStream->ParseUInt8(QString("%1 notify count").arg(GetName())); mNotifyCount = aStream->ParseUInt8(QString("%1 notify count").arg(GetName()));
mAssetType = aStream->ParseUInt8(QString("%1 asset type").arg(GetName())); mAssetType = aStream->ParseUInt8(QString("%1 asset type").arg(GetName()));
mPad = aStream->ParseUInt32(QString("%1 pad").arg(GetName())) != 0; mIsDefault = aStream->ParseUInt8(QString("%1 pad").arg(GetName()));
aStream->skipRawData(1);
qint32 namesPtr, dataBytePtr, dataShortPtr, dataIntPtr, qint32 namesPtr, dataBytePtr, dataShortPtr, dataIntPtr,
randomDataShortPtr, randomDataBytePtr, randomDataIntPtr; randomDataShortPtr, randomDataBytePtr, randomDataIntPtr;
@ -76,17 +77,18 @@ void XAnimParts::ParseData(XDataStream *aStream) {
randomDataIntPtr = aStream->ParseInt32(QString("%1 random data int ptr").arg(GetName())); randomDataIntPtr = aStream->ParseInt32(QString("%1 random data int ptr").arg(GetName()));
// Parse indices // Parse indices
mIndices.ParseData(aStream); mIndices.ParsePtr(aStream, false);
mNotify.ParsePtr(aStream, false); mNotify.ParsePtr(aStream, false);
mDeltaPart.ParsePtr(aStream, false); mDeltaPart.ParsePtr(aStream, false);
mName.ParseData(aStream); mName.ParseDataSafe(aStream);
SetDisplayName(mName.GetString());
if (namesPtr) if (namesPtr)
{ {
mNames = aStream->ParseInt32(QString("%1 names").arg(GetName())); mNames = aStream->ParseInt32(QString("%1 names").arg(GetName()));
} }
mNotify.ParseData(aStream); mNotify.ParseDataSafe(aStream);
mDeltaPart.ParseData(aStream); mDeltaPart.ParseDataSafe(aStream);
if (dataBytePtr) if (dataBytePtr)
{ {
mDataByte = aStream->ParseUInt8(QString("%1 data byte").arg(GetName())); mDataByte = aStream->ParseUInt8(QString("%1 data byte").arg(GetName()));
@ -111,8 +113,7 @@ void XAnimParts::ParseData(XDataStream *aStream) {
{ {
mRandomDataInt = aStream->ParseInt32(QString("%1 random data int").arg(GetName())); mRandomDataInt = aStream->ParseInt32(QString("%1 random data int").arg(GetName()));
} }
mIndices.ParseData(aStream); mIndices.ParseDataSafe(aStream);
}
} }
void XAnimParts::Clear() void XAnimParts::Clear()

View File

@ -35,7 +35,7 @@ private:
quint8 mNotifyCount = 0; quint8 mNotifyCount = 0;
quint8 mAssetType = 0; quint8 mAssetType = 0;
bool mPad = false; bool mIsDefault = false;
quint32 mRandomDataShortCount = 0; quint32 mRandomDataShortCount = 0;
quint32 mIndexCount = 0; quint32 mIndexCount = 0;

View File

@ -19,14 +19,12 @@ XAnimPartTrans::XAnimPartTrans(const XAnimPartTrans &aSrc)
} }
void XAnimPartTrans::ParseData(XDataStream *aStream) { void XAnimPartTrans::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
mSize = aStream->ParseUInt32(QString("%1 size").arg(GetName())); mSize = aStream->ParseUInt32(QString("%1 size").arg(GetName()));
mIsSmallTrans = aStream->ParseUInt8(QString("%1 is small trans").arg(GetName())) != 0; mIsSmallTrans = aStream->ParseUInt8(QString("%1 is small trans").arg(GetName())) != 0;
// Parse data // Parse data
mData.ParseData(aStream); mData.ParseData(aStream);
} }
}
void XAnimPartTrans::Clear() void XAnimPartTrans::Clear()
{ {

View File

@ -17,12 +17,10 @@ XAnimPartTransData::XAnimPartTransData(const XAnimPartTransData &aSrc)
} }
void XAnimPartTransData::ParseData(XDataStream *aStream) { void XAnimPartTransData::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
// We need to determine which part of the union to parse // We need to determine which part of the union to parse
// For simplicity, we'll assume it's always frames for now // For simplicity, we'll assume it's always frames for now
mFrames.ParseData(aStream); mFrames.ParseData(aStream);
} }
}
void XAnimPartTransData::Clear() void XAnimPartTransData::Clear()
{ {

View File

@ -11,7 +11,6 @@ XAnimPartTransFrames::XAnimPartTransFrames()
} }
void XAnimPartTransFrames::ParseData(XDataStream *aStream) { void XAnimPartTransFrames::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) {
mMins[0] = aStream->ParseSingle(QString("%1 min %2").arg(GetName()).arg(0)); mMins[0] = aStream->ParseSingle(QString("%1 min %2").arg(GetName()).arg(0));
mMins[1] = aStream->ParseSingle(QString("%1 min %2").arg(GetName()).arg(1)); mMins[1] = aStream->ParseSingle(QString("%1 min %2").arg(GetName()).arg(1));
mMins[2] = aStream->ParseSingle(QString("%1 min %2").arg(GetName()).arg(2)); mMins[2] = aStream->ParseSingle(QString("%1 min %2").arg(GetName()).arg(2));
@ -20,12 +19,11 @@ void XAnimPartTransFrames::ParseData(XDataStream *aStream) {
mMaxs[2] = aStream->ParseSingle(QString("%1 max %2").arg(GetName()).arg(2)); mMaxs[2] = aStream->ParseSingle(QString("%1 max %2").arg(GetName()).arg(2));
// Parse frames // Parse frames
mFrames.ParseData(aStream); mFrames.ParsePtr(aStream);
// Parse indices // Parse indices
mIndices.ParseData(aStream); mIndices.ParseData(aStream);
} }
}
void XAnimPartTransFrames::Clear() void XAnimPartTransFrames::Clear()
{ {

View File

@ -23,6 +23,9 @@ XAsset::XAsset()
: mPtr(0) : mPtr(0)
, mType(ASSET_TYPE_NONE) , mType(ASSET_TYPE_NONE)
, mName("Unknown Asset") , mName("Unknown Asset")
, mDisplayName("Unknown")
, mCommonInfo(nullptr)
, mSubAssets()
{ {
} }
@ -79,7 +82,15 @@ void XAsset::Clear()
void XAsset::ParsePtr(XDataStream *aStream, bool aDataFlag) { void XAsset::ParsePtr(XDataStream *aStream, bool aDataFlag) {
mPtr = aStream->ParseInt32(QString("%1 ptr").arg(GetName())); mPtr = aStream->ParseInt32(QString("%1 ptr").arg(GetName()));
if (aDataFlag && mPtr == -1) if (aDataFlag)
{
ParseDataSafe(aStream);
}
}
void XAsset::ParseDataSafe(XDataStream *aStream)
{
if (GetPtr() == -1)
{ {
ParseData(aStream); ParseData(aStream);
} }
@ -146,6 +157,8 @@ XAsset* XAsset::Create(XAssetType aAssetType)
return new XModelPieces(); return new XModelPieces();
case ASSET_TYPE_PHYSPRESET: case ASSET_TYPE_PHYSPRESET:
return new XPhysPreset(); return new XPhysPreset();
case ASSET_TYPE_SCRIPT_PARSE_TREE:
return new XRawFile();
// case ASSET_TYPE_UI_MAP: // case ASSET_TYPE_UI_MAP:
// case ASSET_TYPE_AITYPE: // case ASSET_TYPE_AITYPE:
// case ASSET_TYPE_MPTYPE: // case ASSET_TYPE_MPTYPE:
@ -237,7 +250,7 @@ QString XAsset::XAssetTypeToString(XAssetType type) {
return "String"; return "String";
case ASSET_TYPE_ASSETLIST: case ASSET_TYPE_ASSETLIST:
return "AssetList"; return "AssetList";
case ASSET_TYPE_COLLISION_MAP: case ASSET_TYPE_COL_MAP_MP:
return "CollisionMap"; return "CollisionMap";
case ASSET_TYPE_GFX_MAP: case ASSET_TYPE_GFX_MAP:
return "GfxMap"; return "GfxMap";
@ -430,4 +443,39 @@ QString XAsset::XAssetTypeToString(XAssetType type) {
} }
} }
const XCommonInfo *XAsset::GetCommonInfo() const
{
return mCommonInfo;
}
void XAsset::SetCommonInfo(const XCommonInfo *newCommonInfo)
{
mCommonInfo = newCommonInfo;
}
QString XAsset::DisplayName() const
{
return mDisplayName;
}
void XAsset::SetDisplayName(const QString &aDisplayName)
{
mDisplayName = aDisplayName;
}
QVector<XAsset *> XAsset::SubAssets() const
{
return mSubAssets;
}
void XAsset::SetSubAssets(const QVector<XAsset *> &aSubAssets)
{
mSubAssets = aSubAssets;
}
void XAsset::AddSubAsset(XAsset* aSubAsset)
{
mSubAssets.push_back(aSubAsset);
}
bool XAsset::mDebug = true; bool XAsset::mDebug = true;

View File

@ -2,16 +2,19 @@
#define XASSET_H #define XASSET_H
#include "xassettype.h" #include "xassettype.h"
#include "xdatastream.h" #include "xdatastream.h"
#include "xcommoninfo.h"
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
#include <QIODevice> #include <QIODevice>
class ZoneFile;
class XAsset class XAsset
{ {
public: public:
XAsset(); explicit XAsset();
virtual ~XAsset() = default; virtual ~XAsset() = default;
void SetPtr(qint32 aPtr); void SetPtr(qint32 aPtr);
@ -29,16 +32,32 @@ public:
virtual void Clear(); virtual void Clear();
virtual void ParsePtr(XDataStream *aStream, bool aDataFlag = true); virtual void ParsePtr(XDataStream *aStream, bool aDataFlag = true);
virtual void ParseData(XDataStream *aStream) = 0; virtual void ParseData(XDataStream *aStream) = 0;
virtual void ParseDataSafe(XDataStream *aStream);
static XAsset* Create(XAssetType aAssetType); static XAsset* Create(XAssetType aAssetType);
static QString XAssetTypeToString(XAssetType type); static QString XAssetTypeToString(XAssetType type);
static bool mDebug; static bool mDebug;
const XCommonInfo *GetCommonInfo() const;
void SetCommonInfo(const XCommonInfo *newCommonInfo);
QString DisplayName() const;
void SetDisplayName(const QString &aDisplayName);
QVector<XAsset *> SubAssets() const;
void SetSubAssets(const QVector<XAsset *> &aSubAssets);
void AddSubAsset(XAsset *aSubAsset);
private: private:
qint32 mPtr; qint32 mPtr;
XAssetType mType; XAssetType mType;
QString mName; QString mName;
QString mDisplayName;
const XCommonInfo* mCommonInfo;
QVector<XAsset*> mSubAssets;
}; };
#endif // XASSET_H #endif // XASSET_H

View File

@ -57,16 +57,13 @@ void XAssetList::ParseData(XDataStream *aStream) {
for (int i = 0; i < mAssetHeaders.size(); i++) for (int i = 0; i < mAssetHeaders.size(); i++)
{ {
if (aStream->device()->pos() > 98000)
{
qDebug() << "test";
}
XAssetHeader assetHeader = mAssetHeaders[i]; XAssetHeader assetHeader = mAssetHeaders[i];
XAsset* asset = XAsset::Create(assetHeader.GetAssetType()); XAsset* asset = XAsset::Create(assetHeader.GetAssetType());
if (asset) if (asset)
{ {
asset->SetPtr(assetHeader.GetAssetPtr()); asset->SetPtr(assetHeader.GetAssetPtr());
asset->ParseData(aStream); asset->SetCommonInfo(GetCommonInfo());
asset->ParseDataSafe(aStream);
mAssets.append(asset); mAssets.append(asset);
} }

View File

@ -1,8 +1,6 @@
#ifndef XASSETTYPE_H #ifndef XASSETTYPE_H
#define XASSETTYPE_H #define XASSETTYPE_H
#include <QString>
enum XAssetType enum XAssetType
{ {
ASSET_TYPE_XMODELPIECES, ASSET_TYPE_XMODELPIECES,
@ -11,6 +9,7 @@ enum XAssetType
ASSET_TYPE_XMODEL, ASSET_TYPE_XMODEL,
ASSET_TYPE_MATERIAL, ASSET_TYPE_MATERIAL,
ASSET_TYPE_PIXELSHADER, ASSET_TYPE_PIXELSHADER,
ASSET_TYPE_VERTEXSHADER,
ASSET_TYPE_TECHNIQUE_SET, ASSET_TYPE_TECHNIQUE_SET,
ASSET_TYPE_IMAGE, ASSET_TYPE_IMAGE,
ASSET_TYPE_SOUND, ASSET_TYPE_SOUND,
@ -26,7 +25,7 @@ enum XAssetType
ASSET_TYPE_LIGHT_DEF, ASSET_TYPE_LIGHT_DEF,
ASSET_TYPE_UI_MAP, ASSET_TYPE_UI_MAP,
ASSET_TYPE_FONT, ASSET_TYPE_FONT,
ASSET_TYPE_MENULIST, ASSET_TYPE_MENULIST, // Sometimes referred to as MENUFILE
ASSET_TYPE_MENU, ASSET_TYPE_MENU,
ASSET_TYPE_LOCALIZE_ENTRY, ASSET_TYPE_LOCALIZE_ENTRY,
ASSET_TYPE_WEAPON, ASSET_TYPE_WEAPON,
@ -43,11 +42,13 @@ enum XAssetType
ASSET_TYPE_STRING, ASSET_TYPE_STRING,
ASSET_TYPE_ASSETLIST, ASSET_TYPE_ASSETLIST,
ASSET_TYPE_COLLISION_MAP, ASSET_TYPE_COL_MAP_MP,
ASSET_TYPE_GFX_MAP, ASSET_TYPE_GFX_MAP,
ASSET_TYPE_D3DBSP, ASSET_TYPE_D3DBSP,
ASSET_TYPE_GAME_MAP_SP, ASSET_TYPE_GAME_MAP_SP,
ASSET_TYPE_GAME_MAP_MP,
ASSET_TYPE_COL_MAP_SP, ASSET_TYPE_COL_MAP_SP,
ASSET_TYPE_COM_MAP,
ASSET_TYPE_DESTRUCTIBLE, ASSET_TYPE_DESTRUCTIBLE,
ASSET_TYPE_SHOCK_FILE, ASSET_TYPE_SHOCK_FILE,
ASSET_TYPE_PHYSCOLLMAP, ASSET_TYPE_PHYSCOLLMAP,

View File

@ -2,7 +2,7 @@
XCardMemory::XCardMemory() XCardMemory::XCardMemory()
: XAsset() : XAsset()
, mPlatform(0) , mPlatform(2)
{ {
SetName("Card Memory"); SetName("Card Memory");
} }
@ -12,17 +12,18 @@ XCardMemory::~XCardMemory()
} }
qint32 XCardMemory::GetPlatform() const QVector<qint32> XCardMemory::GetPlatform() const
{ {
return mPlatform; return mPlatform;
} }
void XCardMemory::ParseData(XDataStream *aStream) void XCardMemory::ParseData(XDataStream *aStream)
{ {
mPlatform = aStream->ParseInt32(QString("%1 platform").arg(GetName())); mPlatform[0] = aStream->ParseInt32(QString("%1 platform 1").arg(GetName()));
mPlatform[1] = aStream->ParseInt32(QString("%1 platform 2").arg(GetName()));
} }
void XCardMemory::Clear() void XCardMemory::Clear()
{ {
mPlatform = 0; mPlatform.clear();
} }

View File

@ -9,13 +9,13 @@ public:
explicit XCardMemory(); explicit XCardMemory();
~XCardMemory(); ~XCardMemory();
qint32 GetPlatform() const; QVector<qint32> GetPlatform() const;
virtual void ParseData(XDataStream* aStream) override; virtual void ParseData(XDataStream* aStream) override;
virtual void Clear() override; virtual void Clear() override;
private: private:
qint32 mPlatform; QVector<qint32> mPlatform;
}; };
#endif // XCARDMEMORY_H #endif // XCARDMEMORY_H

View File

@ -17,17 +17,15 @@ XCollisionPartition::~XCollisionPartition()
void XCollisionPartition::ParseData(XDataStream *aStream) { void XCollisionPartition::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) { if (GetPtr() == -1) {
*aStream mTriCount = aStream->ParseUInt8(QString("%1 tri count").arg(GetName()));
>> mTriCount mBorderCount = aStream->ParseUInt8(QString("%1 border count").arg(GetName()));
>> mBorderCount;
aStream->skipRawData(2); aStream->skipRawData(2);
qint32 bordersPtr; mFirstTri = aStream->ParseUInt32(QString("%1 first tri").arg(GetName()));
*aStream
>> mFirstTri
>> bordersPtr;
qint32 bordersPtr;
bordersPtr = aStream->ParseUInt32(QString("%1 first tri").arg(GetName()));
if (bordersPtr == -1) if (bordersPtr == -1)
{ {
for (int i = 0; i < mBorderCount; i++) for (int i = 0; i < mBorderCount; i++)

View File

@ -18,7 +18,7 @@ public:
private: private:
quint8 mTriCount; quint8 mTriCount;
quint8 mBorderCount; quint8 mBorderCount;
int mFirstTri; qint32 mFirstTri;
QVector<XCollisionBorder> mBorders; QVector<XCollisionBorder> mBorders;
}; };

View File

@ -0,0 +1,44 @@
#include "xcommoninfo.h"
XCommonInfo::XCommonInfo() {}
XCommonInfo::XCommonInfo(const XGame &aGame, const XPlatform &aPlatform)
: mGame(aGame)
, mPlatform(aPlatform) {}
XGame XCommonInfo::GetGame() const
{
return mGame;
}
QString XCommonInfo::GetGameString() const
{
if (mGame == GAME_NONE) return "UNKNOWN";
else if (mGame == GAME_COD7_5) return "COD7.5";
return QString("COD%1").arg(mGame);
}
void XCommonInfo::SetGame(XGame newGame)
{
mGame = newGame;
}
XPlatform XCommonInfo::GetPlatform() const
{
return mPlatform;
}
QString XCommonInfo::GetPlatformString() const
{
if (mPlatform == PLATFORM_XBOX) return "Xbox";
else if (mPlatform == PLATFORM_PS3) return "PS3";
else if (mPlatform == PLATFORM_PC) return "PC";
else if (mPlatform == PLATFORM_WII) return "Wii";
else if (mPlatform == PLATFORM_WIIU) return "Wii U";
return "UNKNOWN";
}
void XCommonInfo::SetPlatform(XPlatform newPlatform)
{
mPlatform = newPlatform;
}

View File

@ -0,0 +1,26 @@
#ifndef XCOMMONINFO_H
#define XCOMMONINFO_H
#include "xgame.h"
#include "xplatform.h"
class XCommonInfo
{
public:
XCommonInfo();
XCommonInfo(const XGame& aGame, const XPlatform& aPlatform);
XGame GetGame() const;
QString GetGameString() const;
void SetGame(XGame newGame);
XPlatform GetPlatform() const;
QString GetPlatformString() const;
void SetPlatform(XPlatform newPlatform);
private:
XGame mGame;
XPlatform mPlatform;
};
#endif // XCOMMONINFO_H

View File

@ -31,15 +31,17 @@ void XComWorld::ParseData(XDataStream *aStream)
{ {
mName->ParsePtr(aStream, false); mName->ParsePtr(aStream, false);
quint32 primaryLightPtr; mInUse = aStream->ParseUInt8(QString("%1 in use").arg(GetName()));
*aStream aStream->skipRawData(3);
>> mInUse
>> mPrimaryLightCount mPrimaryLightCount = aStream->ParseUInt32(QString("%1 primary light count").arg(GetName()));
>> primaryLightPtr;
quint32 primaryLightsPtr;
primaryLightsPtr = aStream->ParseUInt32(QString("%1 primary lights ptr").arg(GetName()));
mName->ParseData(aStream); mName->ParseData(aStream);
if (primaryLightPtr) if (primaryLightsPtr)
{ {
if (mPrimaryLights != nullptr) if (mPrimaryLights != nullptr)
{ {

View File

@ -7,15 +7,8 @@ XCStaticModelWritable::XCStaticModelWritable()
SetName("C Static Model Writable"); SetName("C Static Model Writable");
} }
XCStaticModelWritable::~XCStaticModelWritable()
{
}
void XCStaticModelWritable::ParseData(XDataStream *aStream) { void XCStaticModelWritable::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) { mNextModelInWorldSector = aStream->ParseUInt32(QString("%1 next model in world sector").arg(GetName()));
*aStream >> mNextModelInWorldSector;
}
} }
quint32 XCStaticModelWritable::GetNextModelInWorldSector() const { quint32 XCStaticModelWritable::GetNextModelInWorldSector() const {

View File

@ -7,7 +7,6 @@ class XCStaticModelWritable : public XAsset
{ {
public: public:
explicit XCStaticModelWritable(); explicit XCStaticModelWritable();
~XCStaticModelWritable();
void ParseData(XDataStream *aStream) override; void ParseData(XDataStream *aStream) override;

View File

@ -12,18 +12,8 @@ void XD3DIndexBuffer::ParseData(XDataStream *aStream)
{ {
XD3DResource::ParseData(aStream); XD3DResource::ParseData(aStream);
*aStream >> mAddress; mAddress = aStream->ParseUInt32(QString("%1 address").arg(GetName()));
if (IsDebug()) mSize = aStream->ParseUInt32(QString("%1 size").arg(GetName()));
{
qDebug() << QString("[%1] mAddress = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mAddress);
}
*aStream >> mSize;
if (IsDebug())
{
qDebug() << QString("[%1] mSize = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mSize);
}
} }
void XD3DIndexBuffer::Clear() void XD3DIndexBuffer::Clear()

View File

@ -19,41 +19,12 @@ XD3DResource::~XD3DResource()
void XD3DResource::ParseData(XDataStream *aStream) void XD3DResource::ParseData(XDataStream *aStream)
{ {
*aStream >> mCommon; mCommon = aStream->ParseUInt32(QString("%1 common").arg(GetName()));
if (IsDebug()) mReferenceCount = aStream->ParseUInt32(QString("%1 reference count").arg(GetName()));
{ mFence = aStream->ParseUInt32(QString("%1 fence").arg(GetName()));
qDebug() << QString("[%1] mCommon = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mCommon); mReadFence = aStream->ParseUInt32(QString("%1 read fence").arg(GetName()));
} mIdentifier = aStream->ParseUInt32(QString("%1 identifier").arg(GetName()));
mBaseFlush = aStream->ParseUInt32(QString("%1 base flush").arg(GetName()));
*aStream >> mReferenceCount;
if (IsDebug())
{
qDebug() << QString("[%1] mReferenceCount = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mReferenceCount);
}
*aStream >> mFence;
if (IsDebug())
{
qDebug() << QString("[%1] mFence = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mFence);
}
*aStream >> mReadFence;
if (IsDebug())
{
qDebug() << QString("[%1] mReadFence = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mReadFence);
}
*aStream >> mIdentifier;
if (IsDebug())
{
qDebug() << QString("[%1] mIdentifier = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mIdentifier);
}
*aStream >> mBaseFlush;
if (IsDebug())
{
qDebug() << QString("[%1] mBaseFlush = %2").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(mBaseFlush);
}
} }
void XD3DResource::Clear() void XD3DResource::Clear()

View File

@ -16,9 +16,8 @@ void XDMaterial::ParseData(XDataStream *aStream) {
if (GetPtr() == -1) { if (GetPtr() == -1) {
mMaterial = XString::ParseCustom(aStream); mMaterial = XString::ParseCustom(aStream);
*aStream mSurfaceFlags = aStream->ParseInt32(QString("%1 surface flags").arg(GetName()));
>> mSurfaceFlags mContentFlags = aStream->ParseInt32(QString("%1 content flags").arg(GetName()));
>> mContentFlags;
} }
} }

View File

@ -23,8 +23,8 @@ public:
private: private:
QString mMaterial = ""; QString mMaterial = "";
int mSurfaceFlags = 0; qint32 mSurfaceFlags = 0;
int mContentFlags = 0; qint32 mContentFlags = 0;
}; };
#endif // XDMATERIAL_H #endif // XDMATERIAL_H

View File

@ -20,21 +20,15 @@ void XDObjAnimMat::ParseData(XDataStream *aStream)
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
quint32 rawQuat; mQuat.push_back(aStream->ParseSingle(QString("%1 quat %2").arg(GetName()).arg(i)));
*aStream >> rawQuat;
memcpy(&mQuat[i], &rawQuat, sizeof(mQuat[i]));
} }
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
quint32 rawTrans; mTrans.push_back(aStream->ParseSingle(QString("%1 trans %2").arg(GetName()).arg(i)));
*aStream >> rawTrans;
memcpy(&mTrans[i], &rawTrans, sizeof(mTrans[i]));
} }
quint32 rawTransWeight; mTransWeight = aStream->ParseSingle(QString("%1 trans weight").arg(GetName()));
*aStream >> rawTransWeight;
memcpy(&mTransWeight, &rawTransWeight, sizeof(mTransWeight));
} }
} }

View File

@ -19,11 +19,10 @@ void XDynEntityClient::ParseData(XDataStream *aStream)
{ {
if (GetPtr()) if (GetPtr())
{ {
*aStream mPhysObjId = aStream->ParseInt32(QString("%1 phys obj id").arg(GetName()));
>> mPhysObjId mFlags = aStream->ParseUInt32(QString("%1 flags").arg(GetName()));
>> mFlags mLightingHandle = aStream->ParseUInt32(QString("%1 lighting handle").arg(GetName()));
>> mLightingHandle mHealth = aStream->ParseInt32(QString("%1 health").arg(GetName()));
>> mHealth;
} }
} }

View File

@ -13,10 +13,10 @@ public:
void Clear() override; void Clear() override;
private: private:
int mPhysObjId; qint32 mPhysObjId;
quint32 mFlags; quint32 mFlags;
quint32 mLightingHandle; quint32 mLightingHandle;
int mHealth; qint32 mHealth;
}; };
#endif // XDYNENTITYCLIENT_H #endif // XDYNENTITYCLIENT_H

View File

@ -17,16 +17,14 @@ XDynEntityColl::~XDynEntityColl()
void XDynEntityColl::ParseData(XDataStream *aStream) void XDynEntityColl::ParseData(XDataStream *aStream)
{ {
if (GetPtr()) if (GetPtr())
{ {
*aStream mSector = aStream->ParseUInt32(QString("%1 sector").arg(GetName()));
>> mSector mNextEntInSector = aStream->ParseUInt32(QString("%1 next ent in sector").arg(GetName()));
>> mNextEntInSector mLinkMins[0] = aStream->ParseSingle(QString("%1 link min 1").arg(GetName()));
>> mLinkMins[0] mLinkMins[1] = aStream->ParseSingle(QString("%1 link min 2").arg(GetName()));
>> mLinkMins[1] mLinkMaxs[0] = aStream->ParseSingle(QString("%1 link max 1").arg(GetName()));
>> mLinkMaxs[0] mLinkMaxs[1] = aStream->ParseSingle(QString("%1 link max 2").arg(GetName()));
>> mLinkMaxs[1];
} }
} }

View File

@ -31,19 +31,18 @@ void XDynEntityDef::ParseData(XDataStream *aStream)
mPose.ParseData(aStream); mPose.ParseData(aStream);
mModel.ParsePtr(aStream, false); mModel.ParsePtr(aStream, false);
*aStream mBrushModel = aStream->ParseUInt32(QString("%1 brush model").arg(GetName()));
>> mBrushModel mPhysicsBrushModel = aStream->ParseUInt32(QString("%1 physics brush model").arg(GetName()));
>> mPhysicsBrushModel;
mDestroyFx.ParsePtr(aStream, false); mDestroyFx.ParsePtr(aStream, false);
mDestroyPieces.ParsePtr(aStream, false); mDestroyPieces.ParsePtr(aStream, false);
mPhysPreset.ParsePtr(aStream, false); mPhysPreset.ParsePtr(aStream, false);
*aStream >> mHealth; mHealth = aStream->ParseUInt32(QString("%1 health").arg(GetName()));
mMass.ParseData(aStream); mMass.ParseData(aStream);
*aStream >> mContents; mContents = aStream->ParseUInt32(QString("%1 contents").arg(GetName()));
mModel.ParseData(aStream); mModel.ParseData(aStream);
mDestroyFx.ParseData(aStream); mDestroyFx.ParseData(aStream);

View File

@ -33,9 +33,9 @@ private:
XFxEffectDef mDestroyFx; XFxEffectDef mDestroyFx;
XModelPieces mDestroyPieces; XModelPieces mDestroyPieces;
XPhysPreset mPhysPreset; XPhysPreset mPhysPreset;
int mHealth; qint32 mHealth;
XPhysMass mMass; XPhysMass mMass;
int mContents; qint32 mContents;
}; };
#endif // XDYNENTITYDEF_H #endif // XDYNENTITYDEF_H

Some files were not shown because too many files have changed in this diff Show More