Refactor: Updated compression functions for LZX format.
This commit is contained in:
parent
622323117a
commit
8d5e5812ec
@ -31,7 +31,8 @@ QByteArray Compression::CompressXMem(const QByteArray &data)
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray Compression::DecompressXMem(const QByteArray &data, int flags, int windowSize, int partSize)
|
QByteArray Compression::DecompressXMem(const QByteArray &data,
|
||||||
|
int flags, int windowSize, int partSize)
|
||||||
{
|
{
|
||||||
if (data.isEmpty())
|
if (data.isEmpty())
|
||||||
return {};
|
return {};
|
||||||
@ -41,27 +42,49 @@ QByteArray Compression::DecompressXMem(const QByteArray &data, int flags, int wi
|
|||||||
lzxParams.WindowSize = windowSize;
|
lzxParams.WindowSize = windowSize;
|
||||||
lzxParams.CompressionPartitionSize = partSize;
|
lzxParams.CompressionPartitionSize = partSize;
|
||||||
|
|
||||||
XMEMDECOMPRESSION_CONTEXT ctx = nullptr;
|
QByteArray internalState(0x94933, Qt::Uninitialized);
|
||||||
if (FAILED(XMemCreateDecompressionContext(XMEMCODEC_LZX, &lzxParams, 0, &ctx)) || !ctx)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
// Allocate large enough buffer for decompression (16 MB is a safe upper bound)
|
XMEMDECOMPRESSION_CONTEXT ctx = XMemInitializeDecompressionContext(
|
||||||
const SIZE_T kMaxOutSize = 16 * 1024 * 1024;
|
XMEMCODEC_LZX, &lzxParams, 1,
|
||||||
QByteArray output(static_cast<int>(kMaxOutSize), Qt::Uninitialized);
|
internalState.data(), internalState.size());
|
||||||
SIZE_T actualSize = kMaxOutSize;
|
|
||||||
|
|
||||||
HRESULT hr = XMemDecompress(ctx,
|
if (!ctx || XMemResetDecompressionContext(ctx)) {
|
||||||
output.data(), &actualSize,
|
qWarning() << "Failed to init LZX context";
|
||||||
data.constData(), data.size() + 16);
|
|
||||||
|
|
||||||
XMemDestroyDecompressionContext(ctx);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
qWarning() << "XMemDecompress failed with HRESULT:" << hr;
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
output.resize(static_cast<int>(actualSize));
|
QByteArray output;
|
||||||
|
output.reserve(16 * 1024 * 1024); // rough guess
|
||||||
|
|
||||||
|
const quint8 *nextIn = reinterpret_cast<const quint8*>(data.constData());
|
||||||
|
SIZE_T availIn = data.size();
|
||||||
|
|
||||||
|
QByteArray scratch(0x10000, Qt::Uninitialized); // 64 KB chunks
|
||||||
|
|
||||||
|
while (availIn > 0) {
|
||||||
|
SIZE_T inSize = availIn; // let XMem tell us how much it will consume
|
||||||
|
SIZE_T outSize = scratch.size(); // max 64 KB per call
|
||||||
|
|
||||||
|
HRESULT hr = XMemDecompressStream(ctx,
|
||||||
|
scratch.data(), &outSize,
|
||||||
|
nextIn, &inSize);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
qWarning() << "XMemDecompressStream failed, hr=" << hr;
|
||||||
|
XMemDestroyDecompressionContext(ctx);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inSize == 0 && outSize == 0)
|
||||||
|
break; // no progress
|
||||||
|
|
||||||
|
output.append(scratch.constData(), static_cast<int>(outSize));
|
||||||
|
|
||||||
|
nextIn += inSize;
|
||||||
|
availIn -= inSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMemDestroyDecompressionContext(ctx);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,19 +100,18 @@ quint32 Compression::CalculateAdler32Checksum(const QByteArray &data) {
|
|||||||
|
|
||||||
qint64 Compression::FindZlibOffset(const QByteArray &bytes)
|
qint64 Compression::FindZlibOffset(const QByteArray &bytes)
|
||||||
{
|
{
|
||||||
static const QByteArray iwffs("IWffs");
|
QDataStream stream(bytes);
|
||||||
auto idx = bytes.indexOf(iwffs);
|
|
||||||
if (idx != -1)
|
|
||||||
return idx + 0x4000;
|
|
||||||
|
|
||||||
const char header = 0x78; // z-lib: 0x78 [FLG]
|
while (!stream.atEnd())
|
||||||
int pos = -1;
|
|
||||||
while ((pos = bytes.indexOf(header, pos + 1)) != -1)
|
|
||||||
{
|
{
|
||||||
QByteArray window = bytes.mid(pos, 0x20);
|
QByteArray testSegment = stream.device()->peek(2).toHex().toUpper();
|
||||||
if (!window.contains(QByteArray::fromHex("000000")) &&
|
if (testSegment == "7801" ||
|
||||||
!window.contains(QByteArray::fromHex("FFFFFF")))
|
testSegment == "785E" ||
|
||||||
return pos;
|
testSegment == "789C" ||
|
||||||
|
testSegment == "78DA") {
|
||||||
|
return stream.device()->pos();
|
||||||
|
}
|
||||||
|
stream.skipRawData(1);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,12 +25,6 @@
|
|||||||
http://www.oberhumer.com/opensource/lzo/
|
http://www.oberhumer.com/opensource/lzo/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE:
|
|
||||||
* the full LZO package can be found at
|
|
||||||
* http://www.oberhumer.com/opensource/lzo/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __LZO_IN_MINILZO 1
|
#define __LZO_IN_MINILZO 1
|
||||||
|
|
||||||
#if defined(LZO_CFG_FREESTANDING)
|
#if defined(LZO_CFG_FREESTANDING)
|
||||||
|
|||||||
@ -223,3 +223,21 @@ double XDataStream::ParseDouble(const QString& aDebugString)
|
|||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool XDataStream::ParseBool(const QString &aDebugString)
|
||||||
|
{
|
||||||
|
qint64 start = this->device()->pos();
|
||||||
|
|
||||||
|
char val;
|
||||||
|
*this >> val;
|
||||||
|
|
||||||
|
if (mDebug)
|
||||||
|
{
|
||||||
|
qDebug() << QString("[%1-%2] Parsed %3: %4")
|
||||||
|
.arg(start, 10, 10, QChar('0'))
|
||||||
|
.arg(this->device()->pos(), 10, 10, QChar('0'))
|
||||||
|
.arg(aDebugString)
|
||||||
|
.arg(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ public:
|
|||||||
quint64 ParseUInt64(const QString& aDebugString = "");
|
quint64 ParseUInt64(const QString& aDebugString = "");
|
||||||
float ParseSingle(const QString& aDebugString = "");
|
float ParseSingle(const QString& aDebugString = "");
|
||||||
double ParseDouble(const QString& aDebugString = "");
|
double ParseDouble(const QString& aDebugString = "");
|
||||||
|
bool ParseBool(const QString& aDebugString = "");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mDebug;
|
bool mDebug;
|
||||||
|
|||||||
@ -6,6 +6,6 @@ SUBDIRS += core \
|
|||||||
fastfile \
|
fastfile \
|
||||||
xassets \
|
xassets \
|
||||||
zonefile \
|
zonefile \
|
||||||
ddsfile \
|
#ddsfile \
|
||||||
iwifile \
|
#iwifile \
|
||||||
ipakfile
|
#ipakfile
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
#ifndef XD3DENUMS_H
|
#ifndef XD3DENUMS_H
|
||||||
#define XD3DENUMS_H
|
#define XD3DENUMS_H
|
||||||
|
|
||||||
enum XD3DResourceType
|
#include <QtTypes>
|
||||||
|
|
||||||
|
enum XD3DResourceType : qint32
|
||||||
{
|
{
|
||||||
D3DRTYPE_NONE = 0x0,
|
D3DRTYPE_NONE = 0x0,
|
||||||
D3DRTYPE_VERTEXBUFFER = 0x1,
|
D3DRTYPE_VERTEXBUFFER = 0x1,
|
||||||
@ -21,7 +23,7 @@ enum XD3DResourceType
|
|||||||
D3DRTYPE_FORCE_DWORD = 0x7FFFFFFF,
|
D3DRTYPE_FORCE_DWORD = 0x7FFFFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum XD3DFormat
|
enum XD3DFormat : qint32
|
||||||
{
|
{
|
||||||
D3DFMT_DXT1 = 0x1A200152,
|
D3DFMT_DXT1 = 0x1A200152,
|
||||||
D3DFMT_LIN_DXT1 = 0x1A200052,
|
D3DFMT_LIN_DXT1 = 0x1A200052,
|
||||||
@ -177,7 +179,7 @@ enum XD3DFormat
|
|||||||
D3DFMT_FORCE_DWORD = 0x7FFFFFFF,
|
D3DFMT_FORCE_DWORD = 0x7FFFFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum XD3DMultiSampleType
|
enum XD3DMultiSampleType : qint32
|
||||||
{
|
{
|
||||||
D3DMULTISAMPLE_NONE = 0x0,
|
D3DMULTISAMPLE_NONE = 0x0,
|
||||||
D3DMULTISAMPLE_2_SAMPLES = 0x1,
|
D3DMULTISAMPLE_2_SAMPLES = 0x1,
|
||||||
|
|||||||
@ -16,9 +16,7 @@ XOperandInternalDataUnion::~XOperandInternalDataUnion()
|
|||||||
|
|
||||||
void XOperandInternalDataUnion::ParseData(XDataStream *aStream)
|
void XOperandInternalDataUnion::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
aStream->ParseSingle(QString("%1 center of mass x").arg(GetName()));
|
||||||
|
|
||||||
// TODO: Fill in XOperandInternalDataUnion::ParseData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XOperandInternalDataUnion::Clear()
|
void XOperandInternalDataUnion::Clear()
|
||||||
|
|||||||
@ -9,16 +9,19 @@ XPhysMass::XPhysMass()
|
|||||||
SetName("Phys Mass");
|
SetName("Phys Mass");
|
||||||
}
|
}
|
||||||
|
|
||||||
XPhysMass::~XPhysMass()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XPhysMass::ParseData(XDataStream *aStream)
|
void XPhysMass::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mCenterOfMass.setX(aStream->ParseSingle(QString("%1 center of mass x").arg(GetName())));
|
||||||
|
mCenterOfMass.setY(aStream->ParseSingle(QString("%1 center of mass y").arg(GetName())));
|
||||||
|
mCenterOfMass.setZ(aStream->ParseSingle(QString("%1 center of mass z").arg(GetName())));
|
||||||
|
|
||||||
// TODO: Fill in XPhysMass::ParseData
|
mMomentsOfInertia.setX(aStream->ParseSingle(QString("%1 moments of inertia x").arg(GetName())));
|
||||||
|
mMomentsOfInertia.setY(aStream->ParseSingle(QString("%1 moments of inertia y").arg(GetName())));
|
||||||
|
mMomentsOfInertia.setZ(aStream->ParseSingle(QString("%1 moments of inertia y").arg(GetName())));
|
||||||
|
|
||||||
|
mProductsOfInertia.setX(aStream->ParseSingle(QString("%1 products of inertia x").arg(GetName())));
|
||||||
|
mProductsOfInertia.setY(aStream->ParseSingle(QString("%1 products of inertia y").arg(GetName())));
|
||||||
|
mProductsOfInertia.setZ(aStream->ParseSingle(QString("%1 products of inertia z").arg(GetName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XPhysMass::Clear()
|
void XPhysMass::Clear()
|
||||||
|
|||||||
@ -8,8 +8,8 @@
|
|||||||
class XPhysMass : public XAsset
|
class XPhysMass : public XAsset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XPhysMass();
|
explicit XPhysMass();
|
||||||
~XPhysMass();
|
~XPhysMass() = default;
|
||||||
|
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
|
|||||||
@ -4,32 +4,30 @@ XRectDef::XRectDef()
|
|||||||
: XAsset()
|
: XAsset()
|
||||||
, mX(0)
|
, mX(0)
|
||||||
, mY(0)
|
, mY(0)
|
||||||
, mW(0)
|
, mWidth(0)
|
||||||
, mH(0)
|
, mHeight(0)
|
||||||
, mHorzAlign(0)
|
, mHorzAlign(0)
|
||||||
, mVertAlign(0)
|
, mVertAlign(0)
|
||||||
{
|
{
|
||||||
SetName("Rectangle Definition");
|
SetName("Rectangle Definition");
|
||||||
}
|
}
|
||||||
|
|
||||||
XRectDef::~XRectDef()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XRectDef::ParseData(XDataStream *aStream)
|
void XRectDef::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mX = aStream->ParseSingle(QString("%1 x").arg(GetName()));
|
||||||
|
mY = aStream->ParseSingle(QString("%1 y").arg(GetName()));
|
||||||
// TODO: Fill in XRectDef::ParseData
|
mWidth = aStream->ParseSingle(QString("%1 width").arg(GetName()));
|
||||||
|
mHeight = aStream->ParseSingle(QString("%1 height").arg(GetName()));
|
||||||
|
mHorzAlign = aStream->ParseInt32(QString("%1 horizontal align").arg(GetName()));
|
||||||
|
mVertAlign = aStream->ParseInt32(QString("%1 vertical align").arg(GetName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XRectDef::Clear()
|
void XRectDef::Clear()
|
||||||
{
|
{
|
||||||
mX = 0;
|
mX = 0;
|
||||||
mY = 0;
|
mY = 0;
|
||||||
mW = 0;
|
mWidth = 0;
|
||||||
mH = 0;
|
mHeight = 0;
|
||||||
mHorzAlign = 0;
|
mHorzAlign = 0;
|
||||||
mVertAlign = 0;
|
mVertAlign = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ class XRectDef : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit XRectDef();
|
explicit XRectDef();
|
||||||
~XRectDef();
|
~XRectDef() = default;
|
||||||
|
|
||||||
void ParseData(XDataStream *aStream) override;
|
void ParseData(XDataStream *aStream) override;
|
||||||
void Clear() override;
|
void Clear() override;
|
||||||
@ -15,10 +15,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
float mX;
|
float mX;
|
||||||
float mY;
|
float mY;
|
||||||
float mW;
|
float mWidth;
|
||||||
float mH;
|
float mHeight;
|
||||||
int mHorzAlign;
|
qint32 mHorzAlign;
|
||||||
int mVertAlign;
|
qint32 mVertAlign;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XRECTDEF_H
|
#endif // XRECTDEF_H
|
||||||
|
|||||||
@ -13,16 +13,21 @@ XSrfTriangles::XSrfTriangles()
|
|||||||
SetName("Surface Triangles");
|
SetName("Surface Triangles");
|
||||||
}
|
}
|
||||||
|
|
||||||
XSrfTriangles::~XSrfTriangles()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XSrfTriangles::ParseData(XDataStream *aStream)
|
void XSrfTriangles::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mVertexLayerData = aStream->ParseInt32(QString("%1 vertex layer data").arg(GetName()));
|
||||||
|
mFirstVertex = aStream->ParseInt32(QString("%1 first vertex").arg(GetName()));
|
||||||
|
mVertexCount = aStream->ParseUInt32(QString("%1 vertex count").arg(GetName()));
|
||||||
|
mTriCount = aStream->ParseUInt32(QString("%1 tri count").arg(GetName()));
|
||||||
|
mBaseIndex = aStream->ParseInt32(QString("%1 base index").arg(GetName()));
|
||||||
|
|
||||||
// TODO: Fill in XSrfTriangles::ParseData
|
mTopMipMins.setX(aStream->ParseSingle(QString("%1 top mip min x").arg(GetName())));
|
||||||
|
mTopMipMins.setY(aStream->ParseSingle(QString("%1 top mip min y").arg(GetName())));
|
||||||
|
mTopMipMins.setZ(aStream->ParseSingle(QString("%1 top mip min z").arg(GetName())));
|
||||||
|
|
||||||
|
mTopMipMins.setX(aStream->ParseSingle(QString("%1 top mip max x").arg(GetName())));
|
||||||
|
mTopMipMins.setY(aStream->ParseSingle(QString("%1 top mip max y").arg(GetName())));
|
||||||
|
mTopMipMins.setZ(aStream->ParseSingle(QString("%1 top mip max z").arg(GetName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XSrfTriangles::Clear()
|
void XSrfTriangles::Clear()
|
||||||
|
|||||||
@ -9,17 +9,17 @@ class XSrfTriangles : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit XSrfTriangles();
|
explicit XSrfTriangles();
|
||||||
~XSrfTriangles();
|
~XSrfTriangles() = default;
|
||||||
|
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mVertexLayerData;
|
qint32 mVertexLayerData;
|
||||||
int mFirstVertex;
|
qint32 mFirstVertex;
|
||||||
quint32 mVertexCount;
|
quint32 mVertexCount;
|
||||||
quint32 mTriCount;
|
quint32 mTriCount;
|
||||||
int mBaseIndex;
|
qint32 mBaseIndex;
|
||||||
QVector3D mTopMipMins;
|
QVector3D mTopMipMins;
|
||||||
QVector3D mTopMipMaxs;
|
QVector3D mTopMipMaxs;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,16 +8,21 @@ XStatement::XStatement()
|
|||||||
SetName("Statement");
|
SetName("Statement");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStatement::~XStatement()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XStatement::ParseData(XDataStream *aStream)
|
void XStatement::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mNumEntries = aStream->ParseInt32(QString("%1 # entries").arg(GetName()));
|
||||||
|
|
||||||
// TODO: Fill in XStatement::ParseData
|
qint32 entriesPtr;
|
||||||
|
entriesPtr = aStream->ParseInt32(QString("%1 entries ptr").arg(GetName()));
|
||||||
|
if (entriesPtr)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mNumEntries; i++)
|
||||||
|
{
|
||||||
|
XExpressionEntry newEntry;
|
||||||
|
newEntry.ParsePtr(aStream);
|
||||||
|
mEntries.append(newEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStatement::Clear()
|
void XStatement::Clear()
|
||||||
|
|||||||
@ -10,14 +10,14 @@ class XStatement : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit XStatement();
|
explicit XStatement();
|
||||||
~XStatement();
|
~XStatement() = default;
|
||||||
|
|
||||||
void ParseData(XDataStream *aStream) override;
|
void ParseData(XDataStream *aStream) override;
|
||||||
void Clear() override;
|
void Clear() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mNumEntries;
|
qint32 mNumEntries;
|
||||||
QVector<XExpressionEntry*> mEntries;
|
QVector<XExpressionEntry> mEntries;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XSTATEMENT_H
|
#endif // XSTATEMENT_H
|
||||||
|
|||||||
@ -2,26 +2,18 @@
|
|||||||
|
|
||||||
XStreamDelayInfo::XStreamDelayInfo()
|
XStreamDelayInfo::XStreamDelayInfo()
|
||||||
: XAsset()
|
: XAsset()
|
||||||
, mPtr(0)
|
|
||||||
, mSize(0)
|
, mSize(0)
|
||||||
{
|
{
|
||||||
SetName("Stream Delay Info");
|
SetName("Stream Delay Info");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStreamDelayInfo::~XStreamDelayInfo()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XStreamDelayInfo::Clear()
|
void XStreamDelayInfo::Clear()
|
||||||
{
|
{
|
||||||
mPtr = nullptr;
|
//mPtr = nullptr;
|
||||||
mSize = 0;
|
mSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStreamDelayInfo::ParseData(XDataStream *aStream)
|
void XStreamDelayInfo::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mSize = aStream->ParseInt32(QString("%1 size").arg(GetName()));
|
||||||
|
|
||||||
// TODO: Fill in XStreamDelayInfo::ParseData
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,14 +7,14 @@ class XStreamDelayInfo : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XStreamDelayInfo();
|
XStreamDelayInfo();
|
||||||
~XStreamDelayInfo();
|
~XStreamDelayInfo() = default;
|
||||||
|
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const void *mPtr;
|
//const void *mPtr;
|
||||||
int mSize;
|
qint32 mSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XSTREAMDELAYINFO_H
|
#endif // XSTREAMDELAYINFO_H
|
||||||
|
|||||||
@ -2,23 +2,17 @@
|
|||||||
|
|
||||||
XStreamedSound::XStreamedSound()
|
XStreamedSound::XStreamedSound()
|
||||||
: XAsset()
|
: XAsset()
|
||||||
|
, mFileName()
|
||||||
{
|
{
|
||||||
SetName("Streamed Sound");
|
SetName("Streamed Sound");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStreamedSound::~XStreamedSound()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XStreamedSound::ParseData(XDataStream *aStream)
|
void XStreamedSound::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mFileName.ParseData(aStream);
|
||||||
|
|
||||||
// TODO: Fill in XStreamedSound::ParseData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStreamedSound::Clear()
|
void XStreamedSound::Clear()
|
||||||
{
|
{
|
||||||
|
mFileName.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,20 +2,19 @@
|
|||||||
#define XSTREAMEDSOUND_H
|
#define XSTREAMEDSOUND_H
|
||||||
|
|
||||||
#include "xasset.h"
|
#include "xasset.h"
|
||||||
|
#include "xstreamfilename.h"
|
||||||
class XStreamedFileName;
|
|
||||||
|
|
||||||
class XStreamedSound : public XAsset
|
class XStreamedSound : public XAsset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XStreamedSound();
|
XStreamedSound();
|
||||||
~XStreamedSound();
|
~XStreamedSound() = default;
|
||||||
|
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XStreamedFileName* mStreamed;
|
XStreamFileName mFileName;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XSTREAMEDSOUND_H
|
#endif // XSTREAMEDSOUND_H
|
||||||
|
|||||||
@ -1,24 +1,31 @@
|
|||||||
#include "xstreamfileinfo.h"
|
#include "xstreamfileinfo.h"
|
||||||
|
#include "xstreamfilename.h"
|
||||||
|
|
||||||
XStreamFileInfo::XStreamFileInfo()
|
XStreamFileInfo::XStreamFileInfo()
|
||||||
: XAsset()
|
: XAsset()
|
||||||
|
, mParent(nullptr)
|
||||||
|
, mRaw()
|
||||||
{
|
{
|
||||||
SetName("Stream File Info");
|
SetName("Stream File Info");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStreamFileInfo::~XStreamFileInfo()
|
XStreamFileInfo::XStreamFileInfo(XStreamFileName &aParent)
|
||||||
|
: XAsset()
|
||||||
|
, mParent(&aParent)
|
||||||
|
, mRaw()
|
||||||
{
|
{
|
||||||
|
SetName("Stream File Info");
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStreamFileInfo::Clear()
|
void XStreamFileInfo::Clear()
|
||||||
{
|
{
|
||||||
|
mRaw.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStreamFileInfo::ParseData(XDataStream *aStream)
|
void XStreamFileInfo::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
if (mParent && !mParent->GetFileIndex())
|
||||||
|
{
|
||||||
// TODO: Fill in XStreamFileInfo::ParseData
|
mRaw.ParseData(aStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,21 +2,23 @@
|
|||||||
#define XSTREAMFILEINFO_H
|
#define XSTREAMFILEINFO_H
|
||||||
|
|
||||||
#include "xasset.h"
|
#include "xasset.h"
|
||||||
#include "xstreamfilenamepacked.h"
|
|
||||||
#include "xstreamfilenameraw.h"
|
#include "xstreamfilenameraw.h"
|
||||||
|
|
||||||
|
class XStreamFileName;
|
||||||
|
|
||||||
class XStreamFileInfo : public XAsset
|
class XStreamFileInfo : public XAsset
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XStreamFileInfo();
|
XStreamFileInfo();
|
||||||
~XStreamFileInfo();
|
XStreamFileInfo(XStreamFileName& aParent);
|
||||||
|
~XStreamFileInfo() = default;
|
||||||
|
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
XStreamFileName* mParent;
|
||||||
XStreamFileNameRaw mRaw;
|
XStreamFileNameRaw mRaw;
|
||||||
XStreamFileNamePacked mPacked;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XSTREAMFILEINFO_H
|
#endif // XSTREAMFILEINFO_H
|
||||||
|
|||||||
@ -8,16 +8,11 @@ XStreamFileName::XStreamFileName()
|
|||||||
SetName("Stream File Name");
|
SetName("Stream File Name");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStreamFileName::~XStreamFileName()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XStreamFileName::ParseData(XDataStream *aStream)
|
void XStreamFileName::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mFileIndex = aStream->ParseUInt32(QString("%1 file index").arg(GetName()));
|
||||||
|
|
||||||
// TODO: Fill in XStreamFileName::ParseData
|
mInfo.ParseData(aStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStreamFileName::Clear()
|
void XStreamFileName::Clear()
|
||||||
@ -25,3 +20,8 @@ void XStreamFileName::Clear()
|
|||||||
mFileIndex = 0;
|
mFileIndex = 0;
|
||||||
mInfo.Clear();
|
mInfo.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quint32 XStreamFileName::GetFileIndex() const
|
||||||
|
{
|
||||||
|
return mFileIndex;
|
||||||
|
}
|
||||||
|
|||||||
@ -8,11 +8,13 @@ class XStreamFileName : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit XStreamFileName();
|
explicit XStreamFileName();
|
||||||
~XStreamFileName();
|
~XStreamFileName() = default;
|
||||||
|
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
|
|
||||||
|
quint32 GetFileIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
quint32 mFileIndex;
|
quint32 mFileIndex;
|
||||||
XStreamFileInfo mInfo;
|
XStreamFileInfo mInfo;
|
||||||
|
|||||||
@ -2,23 +2,20 @@
|
|||||||
|
|
||||||
XStreamFileNamePacked::XStreamFileNamePacked()
|
XStreamFileNamePacked::XStreamFileNamePacked()
|
||||||
: XAsset()
|
: XAsset()
|
||||||
|
, mOffset(0)
|
||||||
|
, mLength(0)
|
||||||
{
|
{
|
||||||
SetName("Stream File Name Packed");
|
SetName("Stream File Name Packed");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStreamFileNamePacked::~XStreamFileNamePacked()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XStreamFileNamePacked::ParseData(XDataStream *aStream)
|
void XStreamFileNamePacked::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mOffset = aStream->ParseUInt32(QString("%1 offset").arg(GetName()));
|
||||||
|
mLength = aStream->ParseUInt32(QString("%1 length").arg(GetName()));
|
||||||
// TODO: Fill in XStreamFileNamePacked::ParseData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStreamFileNamePacked::Clear()
|
void XStreamFileNamePacked::Clear()
|
||||||
{
|
{
|
||||||
|
mOffset = 0;
|
||||||
|
mLength = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class XStreamFileNamePacked : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XStreamFileNamePacked();
|
XStreamFileNamePacked();
|
||||||
~XStreamFileNamePacked();
|
~XStreamFileNamePacked() = default;
|
||||||
|
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
|
|||||||
@ -2,23 +2,23 @@
|
|||||||
|
|
||||||
XStreamFileNameRaw::XStreamFileNameRaw()
|
XStreamFileNameRaw::XStreamFileNameRaw()
|
||||||
: XAsset()
|
: XAsset()
|
||||||
|
, mDir()
|
||||||
|
, mName()
|
||||||
{
|
{
|
||||||
SetName("Stream File Name Raw");
|
SetName("Stream File Name Raw");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStreamFileNameRaw::~XStreamFileNameRaw()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XStreamFileNameRaw::ParseData(XDataStream *aStream)
|
void XStreamFileNameRaw::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mDir.ParsePtr(aStream, false);
|
||||||
|
mName.ParsePtr(aStream, false);
|
||||||
|
|
||||||
// TODO: Fill in XStreamFileNameRaw::ParseData
|
mDir.ParseData(aStream);
|
||||||
|
mName.ParseData(aStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XStreamFileNameRaw::Clear()
|
void XStreamFileNameRaw::Clear()
|
||||||
{
|
{
|
||||||
|
mDir.Clear();
|
||||||
|
mName.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,14 +8,14 @@ class XStreamFileNameRaw : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XStreamFileNameRaw();
|
XStreamFileNameRaw();
|
||||||
~XStreamFileNameRaw();
|
~XStreamFileNameRaw() = default;
|
||||||
|
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XString* mDir;
|
XString mDir;
|
||||||
XString* mName;
|
XString mName;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XSTREAMFILENAMERAW_H
|
#endif // XSTREAMFILENAMERAW_H
|
||||||
|
|||||||
@ -9,11 +9,6 @@ XStreamSourceInfo::XStreamSourceInfo()
|
|||||||
SetName("Stream Source Info");
|
SetName("Stream Source Info");
|
||||||
}
|
}
|
||||||
|
|
||||||
XStreamSourceInfo::~XStreamSourceInfo()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void XStreamSourceInfo::Clear()
|
void XStreamSourceInfo::Clear()
|
||||||
{
|
{
|
||||||
mStream = 0;
|
mStream = 0;
|
||||||
@ -23,7 +18,7 @@ void XStreamSourceInfo::Clear()
|
|||||||
|
|
||||||
void XStreamSourceInfo::ParseData(XDataStream *aStream)
|
void XStreamSourceInfo::ParseData(XDataStream *aStream)
|
||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
mStream = aStream->ParseUInt16(QString("%1 stream").arg(GetName()));
|
||||||
|
mOffset = aStream->ParseUInt16(QString("%1 offset").arg(GetName()));
|
||||||
// TODO: Fill in XStreamSourceInfo::ParseData
|
mType = aStream->ParseUInt32(QString("%1 type").arg(GetName()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,14 +7,14 @@ class XStreamSourceInfo : public XAsset
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XStreamSourceInfo();
|
XStreamSourceInfo();
|
||||||
~XStreamSourceInfo();
|
~XStreamSourceInfo() = default;
|
||||||
|
|
||||||
virtual void Clear() override;
|
virtual void Clear() override;
|
||||||
virtual void ParseData(XDataStream* aStream) override;
|
virtual void ParseData(XDataStream* aStream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
quint32 mStream;
|
quint16 mStream;
|
||||||
quint32 mOffset;
|
quint16 mOffset;
|
||||||
quint32 mType;
|
quint32 mType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -35,5 +35,19 @@ void XTextureDesc::ParseData(XDataStream *aStream)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
Q_UNUSED(aStream);
|
||||||
|
|
||||||
// TODO: Fill in XTextureDesc::ParseData
|
mResourceType = (XD3DResourceType)aStream->ParseInt32(QString("%1 resource type").arg(GetName()));
|
||||||
|
mWidth = aStream->ParseUInt32(QString("%1 width").arg(GetName()));
|
||||||
|
mHeight = aStream->ParseUInt32(QString("%1 height").arg(GetName()));
|
||||||
|
mDepth = aStream->ParseUInt32(QString("%1 depth").arg(GetName()));
|
||||||
|
mFormat = (XD3DFormat)aStream->ParseInt32(QString("%1 format").arg(GetName()));
|
||||||
|
mRowPitch = aStream->ParseUInt32(QString("%1 row pitch").arg(GetName()));
|
||||||
|
mSlicePitch = aStream->ParseUInt32(QString("%1 slice pitch").arg(GetName()));
|
||||||
|
mBitsPerPixel = aStream->ParseUInt32(QString("%1 bits per pixel").arg(GetName()));
|
||||||
|
mWidthInBlocks = aStream->ParseUInt32(QString("%1 width in blocks").arg(GetName()));
|
||||||
|
mHeightInBlocks = aStream->ParseUInt32(QString("%1 height in blocks").arg(GetName()));
|
||||||
|
mDepthInBlocks = aStream->ParseUInt32(QString("%1 depth in blocks").arg(GetName()));
|
||||||
|
mBytesPerBlock = aStream->ParseUInt32(QString("%1 bytes per block").arg(GetName()));
|
||||||
|
mExpBias = aStream->ParseInt32(QString("%1 exp bias").arg(GetName()));
|
||||||
|
mFlags = aStream->ParseUInt32(QString("%1 flags").arg(GetName()));
|
||||||
|
mMultiSampleType = (XD3DMultiSampleType)aStream->ParseInt32(QString("%1 multi-sample type").arg(GetName()));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ void XWaterWritable::ParseData(XDataStream *aStream)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
Q_UNUSED(aStream);
|
||||||
|
|
||||||
// TODO: Fill in XWaterWritable::ParseData
|
mFloatTime = aStream->ParseSingle(QString("%1 float time").arg(GetName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XWaterWritable::Clear()
|
void XWaterWritable::Clear()
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
XWindowDef::XWindowDef()
|
XWindowDef::XWindowDef()
|
||||||
: XAsset()
|
: XAsset()
|
||||||
, mName("")
|
, mName()
|
||||||
, mRect()
|
, mRect()
|
||||||
, mRectClient()
|
, mRectClient()
|
||||||
, mGroup("")
|
, mGroup()
|
||||||
, mStyle(0)
|
, mStyle(0)
|
||||||
, mBorder(0)
|
, mBorder(0)
|
||||||
, mOwnerDraw(0)
|
, mOwnerDraw(0)
|
||||||
@ -18,7 +18,7 @@ XWindowDef::XWindowDef()
|
|||||||
, mBackColor()
|
, mBackColor()
|
||||||
, mBorderColor()
|
, mBorderColor()
|
||||||
, mOutlineColor()
|
, mOutlineColor()
|
||||||
, mBackground(new XMaterial())
|
, mBackground()
|
||||||
{
|
{
|
||||||
SetName("Window Definition");
|
SetName("Window Definition");
|
||||||
}
|
}
|
||||||
@ -32,15 +32,66 @@ void XWindowDef::ParseData(XDataStream *aStream)
|
|||||||
{
|
{
|
||||||
Q_UNUSED(aStream);
|
Q_UNUSED(aStream);
|
||||||
|
|
||||||
// TODO: Fill in XWindowDef::ParseData
|
mName.ParsePtr(aStream, false);
|
||||||
|
|
||||||
|
mRect.ParseData(aStream);
|
||||||
|
mRectClient.ParseData(aStream);
|
||||||
|
|
||||||
|
mGroup.ParsePtr(aStream, false);
|
||||||
|
|
||||||
|
mStyle = aStream->ParseInt32(QString("%1 style").arg(GetName()));
|
||||||
|
mBorder = aStream->ParseInt32(QString("%1 border").arg(GetName()));
|
||||||
|
mOwnerDraw = aStream->ParseInt32(QString("%1 owner draw").arg(GetName()));
|
||||||
|
mOwnerDrawFlags = aStream->ParseInt32(QString("%1 owner draw flags").arg(GetName()));
|
||||||
|
mBorderSize = aStream->ParseSingle(QString("%1 border size").arg(GetName()));
|
||||||
|
mStaticFlags = aStream->ParseInt32(QString("%1 static flags").arg(GetName()));
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
mDynamicFlags[i] = aStream->ParseInt32(QString("%1 dynamic flag %2").arg(GetName()).arg(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
mNextTime = aStream->ParseInt32(QString("%1 next time").arg(GetName()));
|
||||||
|
|
||||||
|
float r, g, b, a;
|
||||||
|
|
||||||
|
r = aStream->ParseSingle(QString("%1 foreground red").arg(GetName()));
|
||||||
|
g = aStream->ParseSingle(QString("%1 foreground green").arg(GetName()));
|
||||||
|
b = aStream->ParseSingle(QString("%1 foreground blue").arg(GetName()));
|
||||||
|
a = aStream->ParseSingle(QString("%1 foreground alpha").arg(GetName()));
|
||||||
|
mForeColor = QColor(r, g, b, a);
|
||||||
|
|
||||||
|
r = aStream->ParseSingle(QString("%1 background red").arg(GetName()));
|
||||||
|
g = aStream->ParseSingle(QString("%1 background green").arg(GetName()));
|
||||||
|
b = aStream->ParseSingle(QString("%1 background blue").arg(GetName()));
|
||||||
|
a = aStream->ParseSingle(QString("%1 background alpha").arg(GetName()));
|
||||||
|
mBackColor = QColor(r, g, b, a);
|
||||||
|
|
||||||
|
r = aStream->ParseSingle(QString("%1 border red").arg(GetName()));
|
||||||
|
g = aStream->ParseSingle(QString("%1 border green").arg(GetName()));
|
||||||
|
b = aStream->ParseSingle(QString("%1 border blue").arg(GetName()));
|
||||||
|
a = aStream->ParseSingle(QString("%1 border alpha").arg(GetName()));
|
||||||
|
mBorderColor = QColor(r, g, b, a);
|
||||||
|
|
||||||
|
r = aStream->ParseSingle(QString("%1 outline red").arg(GetName()));
|
||||||
|
g = aStream->ParseSingle(QString("%1 outline green").arg(GetName()));
|
||||||
|
b = aStream->ParseSingle(QString("%1 outline blue").arg(GetName()));
|
||||||
|
a = aStream->ParseSingle(QString("%1 outline alpha").arg(GetName()));
|
||||||
|
mOutlineColor = QColor(r, g, b, a);
|
||||||
|
|
||||||
|
mBackground.ParsePtr(aStream, false);
|
||||||
|
|
||||||
|
mName.ParseData(aStream);
|
||||||
|
mGroup.ParseData(aStream);
|
||||||
|
mBackground.ParseData(aStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XWindowDef::Clear()
|
void XWindowDef::Clear()
|
||||||
{
|
{
|
||||||
mName.clear();
|
mName.Clear();
|
||||||
mRect.Clear();
|
mRect.Clear();
|
||||||
mRectClient.Clear();
|
mRectClient.Clear();
|
||||||
mGroup.clear();
|
mGroup.Clear();
|
||||||
mStyle = 0;
|
mStyle = 0;
|
||||||
mBorder = 0;
|
mBorder = 0;
|
||||||
mOwnerDraw = 0;
|
mOwnerDraw = 0;
|
||||||
@ -53,5 +104,5 @@ void XWindowDef::Clear()
|
|||||||
mBackColor = QColor();
|
mBackColor = QColor();
|
||||||
mBorderColor = QColor();
|
mBorderColor = QColor();
|
||||||
mOutlineColor = QColor();
|
mOutlineColor = QColor();
|
||||||
mBackground->Clear();
|
mBackground.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,10 +17,10 @@ public:
|
|||||||
void Clear() override;
|
void Clear() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString mName;
|
XString mName;
|
||||||
XRectDef mRect;
|
XRectDef mRect;
|
||||||
XRectDef mRectClient;
|
XRectDef mRectClient;
|
||||||
QString mGroup;
|
XString mGroup;
|
||||||
int mStyle;
|
int mStyle;
|
||||||
int mBorder;
|
int mBorder;
|
||||||
int mOwnerDraw;
|
int mOwnerDraw;
|
||||||
@ -33,7 +33,7 @@ private:
|
|||||||
QColor mBackColor;
|
QColor mBackColor;
|
||||||
QColor mBorderColor;
|
QColor mBorderColor;
|
||||||
QColor mOutlineColor;
|
QColor mOutlineColor;
|
||||||
XMaterial *mBackground;
|
XMaterial mBackground;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // XWINDOWDEF_H
|
#endif // XWINDOWDEF_H
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user