From fc9e5d8b5bb42a6ca6bf6a160743e800dba74dcb Mon Sep 17 00:00:00 2001 From: = Date: Sun, 12 Jan 2025 19:01:33 -0500 Subject: [PATCH 1/4] Add .bik processing header. --- bink.h | 396 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 396 insertions(+) create mode 100644 bink.h diff --git a/bink.h b/bink.h new file mode 100644 index 0000000..ab7c0de --- /dev/null +++ b/bink.h @@ -0,0 +1,396 @@ +/* xoreos - A reimplementation of BioWare's Aurora engine + * + * xoreos is the legal property of its developers, whose names + * can be found in the AUTHORS file distributed with this source + * distribution. + * + * xoreos is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 3 + * of the License, or (at your option) any later version. + * + * xoreos is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xoreos. If not, see . + */ + +/** @file + * Decoding RAD Game Tools' Bink videos. + */ + +/* Based on the Bink implementation in FFmpeg (, + * which is released under the terms of version 2 or later of the GNU + * Lesser General Public License. + * + * The original copyright notes in the files + * - libavformat/bink.c + * - libavcodec/bink.c + * - libavcodec/binkdata.h + * - libavcodec/binkdsp.c + * - libavcodec/binkdsp.h + * - libavcodec/binkaudio.c + * read as follows: + * + * Bink demuxer + * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org) + * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) + * + * Bink video decoder + * Copyright (c) 2009 Konstantin Shishkov + * Copyright (C) 2011 Peter Ross + * + * Bink video decoder + * Copyright (C) 2009 Konstantin Shishkov + * + * Bink DSP routines + * Copyright (c) 2009 Konstantin Shishkov + * + * Bink Audio decoder + * Copyright (c) 2007-2011 Peter Ross (pross@xvid.org) + * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef VIDEO_BINK_H +#define VIDEO_BINK_H + +#include +#include + +#include "src/common/types.h" +#include "src/common/rational.h" + +#include "src/video/decoder.h" + +namespace Common { + class SeekableReadStream; + class BitStream; + class Huffman; + + class RDFT; + class DCT; +} + +namespace Sound { + class PacketizedAudioStream; +} + +namespace Video { + +/** A decoder for RAD Game Tools' Bink videos. */ +class Bink : public VideoDecoder { +public: + Bink(Common::SeekableReadStream *bink); + ~Bink(); + +protected: + void decodeNextTrackFrame(VideoTrack &track); + void checkAudioBuffer(AudioTrack &track, const Common::Timestamp &endTime); + +private: + static const int kAudioChannelsMax = 2; + static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11); + + enum AudioCodec { + kAudioCodecDCT, + kAudioCodecRDFT + }; + + /** An audio track. */ + struct AudioInfo { + uint16_t flags; + + uint32_t sampleRate; + uint8_t channels; + + uint32_t outSampleRate; + uint8_t outChannels; + + AudioCodec codec; + + bool first; + + uint32_t frameLen; + uint32_t overlapLen; + + uint32_t blockSize; + + uint32_t bandCount; + uint32_t *bands; + + float root; + + float coeffs[16 * kAudioBlockSizeMax]; + int16_t prevCoeffs[kAudioBlockSizeMax]; + + float *coeffsPtr[kAudioChannelsMax]; + + Common::RDFT *rdft; + Common::DCT *dct; + + AudioInfo(); + AudioInfo(const AudioInfo &audioInfo) = default; + ~AudioInfo(); + }; + + /** A video frame. */ + struct VideoFrame { + bool keyFrame; + + uint32_t offset; + uint32_t size; + + Common::BitStream *bits; + + VideoFrame(); + VideoFrame(const VideoFrame &videoFrame) = default; + ~VideoFrame(); + }; + + std::unique_ptr _bink; + + std::vector _audioTracks; ///< All audio tracks. + std::vector _frames; ///< All video frames. + + uint32_t _audioTrack; ///< Audio track to use. + + /** Load a Bink file. */ + void load(); + + class BinkVideoTrack : public FixedRateVideoTrack { + public: + BinkVideoTrack(uint32_t width, uint32_t height, uint32_t frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32_t id); + + uint32_t getWidth() const { return _width; } + uint32_t getHeight() const { return _height; } + int getCurFrame() const { return _curFrame; } + int getFrameCount() const { return _frameCount; } + + /** Decode a video packet. */ + void decodePacket(Graphics::Surface &surface, VideoFrame &frame); + + protected: + Common::Rational getFrameRate() const { return _frameRate; } + + private: + /** A decoder state. */ + struct DecodeContext { + VideoFrame *video; + + uint32_t planeIdx; + + uint32_t blockX; + uint32_t blockY; + + byte *dest; + byte *prev; + + byte *destStart, *destEnd; + byte *prevStart, *prevEnd; + + uint32_t pitch; + + int coordMap[64]; + int coordScaledMap1[64]; + int coordScaledMap2[64]; + int coordScaledMap3[64]; + int coordScaledMap4[64]; + }; + + /** IDs for different data types used in Bink video codec. */ + enum Source { + kSourceBlockTypes = 0, ///< 8x8 block types. + kSourceSubBlockTypes , ///< 16x16 block types (a subset of 8x8 block types). + kSourceColors , ///< Pixel values used for different block types. + kSourcePattern , ///< 8-bit values for 2-color pattern fill. + kSourceXOff , ///< X components of motion value. + kSourceYOff , ///< Y components of motion value. + kSourceIntraDC , ///< DC values for intrablocks with DCT. + kSourceInterDC , ///< DC values for interblocks with DCT. + kSourceRun , ///< Run lengths for special fill block. + + kSourceMAX + }; + + /** Bink video block types. */ + enum BlockType { + kBlockSkip = 0, ///< Skipped block. + kBlockScaled , ///< Block has size 16x16. + kBlockMotion , ///< Block is copied from previous frame with some offset. + kBlockRun , ///< Block is composed from runs of colors with custom scan order. + kBlockResidue , ///< Motion block with some difference added. + kBlockIntra , ///< Intra DCT block. + kBlockFill , ///< Block is filled with single color. + kBlockInter , ///< Motion block with DCT applied to the difference. + kBlockPattern , ///< Block is filled with two colors following custom pattern. + kBlockRaw ///< Uncoded 8x8 block. + }; + + /** Data structure for decoding and translating Huffman'd data. */ + struct Huffman { + int index; ///< Index of the Huffman codebook to use. + byte symbols[16]; ///< Huffman symbol => Bink symbol translation list. + + Huffman(); + }; + + /** Data structure used for decoding a single Bink data type. */ + struct Bundle { + int countLengths[2]; ///< Lengths of number of entries to decode (in bits). + int countLength; ///< Length of number of entries to decode (in bits) for the current plane. + + Huffman huffman; ///< Huffman codebook. + + std::unique_ptr data; ///< Buffer for decoded symbols. + + byte *dataEnd; ///< Pointer to the data end end. + byte *curDec; ///< Pointer to the data that wasn't yet decoded. + byte *curPtr; ///< Pointer to the data that wasn't yet read. + + Bundle(); + }; + + uint32_t _width; + uint32_t _height; + + int _curFrame; ///< Current Frame. + int _frameCount; + + Common::Rational _frameRate; ///< The frame rate of the video. + + bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV? + bool _hasAlpha; ///< Do video frames have alpha? + + uint32_t _id; ///< The BIK FourCC. + + Bundle _bundles[kSourceMAX]; ///< Bundles for decoding all data types. + + std::unique_ptr _huffman[16]; ///< The 16 Huffman codebooks used in Bink decoding. + + /** Huffman codebooks to use for decoding high nibbles in color data types. */ + Huffman _colHighHuffman[16]; + /** Value of the last decoded high nibble in color data types. */ + int _colLastVal; + + std::unique_ptr _curPlanes[4]; ///< The 4 color planes, YUVA, current frame. + std::unique_ptr _oldPlanes[4]; ///< The 4 color planes, YUVA, last frame. + + /** Initialize the bundles. */ + void initBundles(); + + /** Initialize the Huffman decoders. */ + void initHuffman(); + + /** Decode a video packet. */ + void videoPacket(VideoFrame &video); + + /** Decode a plane. */ + void decodePlane(VideoFrame &video, int planeIdx, bool isChroma); + + /** Read/Initialize a bundle for decoding a plane. */ + void readBundle(VideoFrame &video, Source source); + + /** Read the symbols for a Huffman code. */ + void readHuffman(VideoFrame &video, Huffman &huffman); + /** Merge two Huffman symbol lists. */ + void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size); + + /** Read and translate a symbol out of a Huffman code. */ + byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman); + + /** Get a direct value out of a bundle. */ + int32_t getBundleValue(Source source); + /** Read a count value out of a bundle. */ + uint32_t readBundleCount(VideoFrame &video, Bundle &bundle); + + // Handle the block types + void blockSkip (DecodeContext &ctx); + void blockScaledSkip (DecodeContext &ctx); + void blockScaledRun (DecodeContext &ctx); + void blockScaledIntra (DecodeContext &ctx); + void blockScaledFill (DecodeContext &ctx); + void blockScaledPattern(DecodeContext &ctx); + void blockScaledRaw (DecodeContext &ctx); + void blockScaled (DecodeContext &ctx); + void blockMotion (DecodeContext &ctx); + void blockRun (DecodeContext &ctx); + void blockResidue (DecodeContext &ctx); + void blockIntra (DecodeContext &ctx); + void blockFill (DecodeContext &ctx); + void blockInter (DecodeContext &ctx); + void blockPattern (DecodeContext &ctx); + void blockRaw (DecodeContext &ctx); + + // Read the bundles + void readRuns (VideoFrame &video, Bundle &bundle); + void readMotionValues(VideoFrame &video, Bundle &bundle); + void readBlockTypes (VideoFrame &video, Bundle &bundle); + void readPatterns (VideoFrame &video, Bundle &bundle); + void readColors (VideoFrame &video, Bundle &bundle); + void readDCS (VideoFrame &video, Bundle &bundle, int startBits, bool hasSign); + void readDCTCoeffs (VideoFrame &video, int16_t *block, bool isIntra); + void readResidue (VideoFrame &video, int16_t *block, int masksCount); + + // Bink video IDCT + void IDCT(int16_t *block); + void IDCTPut(DecodeContext &ctx, int16_t *block); + void IDCTAdd(DecodeContext &ctx, int16_t *block); + }; + + class BinkAudioTrack : public AudioTrack { + public: + BinkAudioTrack(size_t index, AudioInfo &audio); + ~BinkAudioTrack(); + + bool canBufferData() const; + + /** Decode audio data up to endTime. */ + void decodeAudio(Common::SeekableReadStream& bink, const std::vector& frames, const std::vector& audioTracks, const Common::Timestamp& endTime); + + protected: + Sound::AudioStream *getAudioStream() const; + + private: + size_t _index; + AudioInfo &_info; + Sound::PacketizedAudioStream *_audioStream; + uint32_t _curFrame; + Common::Timestamp _audioBuffered; + + float getFloat(Common::BitStream &bits); + + /** Decode an audio block. */ + void audioBlock(Common::BitStream &bits, int16_t *out); + /** Decode a DCT'd audio block. */ + void audioBlockDCT(Common::BitStream &bits); + /** Decode a RDFT'd audio block. */ + void audioBlockRDFT(Common::BitStream &bits); + + void readAudioCoeffs(Common::BitStream &bits, float *coeffs); + + static void floatToInt16Interleave(int16_t *dst, const float **src, uint32_t length, uint8_t channels); + }; + + void initAudioTrack(AudioInfo &audio); +}; + +} // End of namespace Video + +#endif // VIDEO_BINK_H From c649ee2b406468fe44e8eba25109458c9309d613 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 12 Jan 2025 20:12:01 -0500 Subject: [PATCH 2/4] Add .bik processing header. --- FastFile_WaW.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FastFile_WaW.pro b/FastFile_WaW.pro index c155886..a7c6012 100644 --- a/FastFile_WaW.pro +++ b/FastFile_WaW.pro @@ -20,7 +20,8 @@ HEADERS += \ enums.h \ mainwindow.h \ structs.h \ - utils.h + utils.h \ + bink.h FORMS += \ mainwindow.ui From 80f7a73573ac92928d04bcc74023525c88a911d4 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 12 Jan 2025 20:12:41 -0500 Subject: [PATCH 3/4] Treat bik file as a raw file, check file types. --- enums.h | 4 + mainwindow.cpp | 284 +++++++++++++++++++++++++++++++++++-------------- mainwindow.h | 7 +- structs.h | 22 ++++ utils.h | 3 + 5 files changed, 239 insertions(+), 81 deletions(-) diff --git a/enums.h b/enums.h index 415bf63..061aa87 100644 --- a/enums.h +++ b/enums.h @@ -1,6 +1,7 @@ #ifndef ENUMS_H #define ENUMS_H +#include "qtypes.h" enum LUMP_TYPE { LUMP_MATERIALS = 0x0, @@ -98,4 +99,7 @@ enum BSPVERSION_TYPE BSPVERSION_COD_BO = 45 }; +// Bink constants +const quint32 BINK_SURFACE32RGBA = 6; + #endif // ENUMS_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 8cd2ff6..2026fba 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -646,93 +646,124 @@ void MainWindow::ParseZoneIndex(QDataStream *aZoneFileStream) { void MainWindow::ParseAsset_LocalString(QDataStream *aZoneFileStream) { // Skip separator - aZoneFileStream->skipRawData(8); + qint32 langStrPtr, referenceStrPtr; + *aZoneFileStream >> langStrPtr >> referenceStrPtr; - // Parse local string asset contents - QString localStr; - char localStrChar; - *aZoneFileStream >> localStrChar; - while (localStrChar != 0) { - localStr += localStrChar; - *aZoneFileStream >> localStrChar; + // Parse language-specific string if present + QString langStr; + if (langStrPtr == -1) { + char langStrChar; + *aZoneFileStream >> langStrChar; + while (langStrChar != 0) { + langStr += langStrChar; + *aZoneFileStream >> langStrChar; + } + } else { + langStr = "MEMORY_REFERENCE"; } - // Parse rawfile name - QString aliasName; - char aliasNameChar; - *aZoneFileStream >> aliasNameChar; - while (aliasNameChar != 0) { - aliasName += aliasNameChar; - *aZoneFileStream >> aliasNameChar; + // Parse reference str ig present + QString referenceStr; + if (referenceStrPtr == -1) { + char referenceStrChar; + *aZoneFileStream >> referenceStrChar; + while (referenceStrChar != 0) { + referenceStr += referenceStrChar; + *aZoneFileStream >> referenceStrChar; + } + } else { + referenceStr = "MEMORY_REFERENCE"; } - // qDebug() << QString("%1 = %2").arg(aliasName).arg(localStr); - ui->listWidget_LocalString->addItem(QString("%1 = %2").arg(aliasName).arg(localStr)); + + const int localStrIndex = ui->listWidget_LocalString->count() + 1; + ui->listWidget_LocalString->addItem(QString("[%1] %2 = %3").arg(localStrIndex).arg(referenceStr).arg(langStr)); } void MainWindow::ParseAsset_RawFile(QDataStream *aZoneFileStream) { // Skip start separator FF FF FF FF (pointer?) aZoneFileStream->skipRawData(4); - quint32 gscLength; - *aZoneFileStream >> gscLength; + quint32 rawFileLength; + *aZoneFileStream >> rawFileLength; // Skip unknown 4 byte data aZoneFileStream->skipRawData(4); + bool isBik = false; + // Parse rawfile path QString rawFilePath; - char scriptPathChar; - *aZoneFileStream >> scriptPathChar; - while (scriptPathChar != 0) { - rawFilePath += scriptPathChar; - *aZoneFileStream >> scriptPathChar; + char rawFilePathChar; + *aZoneFileStream >> rawFilePathChar; + while (rawFilePathChar != 0) { + rawFilePath += rawFilePathChar; + *aZoneFileStream >> rawFilePathChar; } rawFilePath.replace(",", ""); - const QStringList pathParts = rawFilePath.split('/'); - if (pathParts.size() == 0) { - qDebug() << "Failed to parse ff path! " << rawFilePath; - exit(-1); - } else if (pathParts.size() == 1) { - const QString path = pathParts[0]; - QTreeWidgetItem *newRootItem = new QTreeWidgetItem(ui->treeWidget_Scripts); - newRootItem->setText(0, path); + if (rawFilePath.contains(".bik")) { + isBik = true; } else { - const QString path = pathParts[0]; - QTreeWidgetItem *newRootItem; - if (mTreeMap.contains(path)) { - newRootItem = mTreeMap[path]; - } else { - newRootItem = new QTreeWidgetItem(ui->treeWidget_Scripts); + const QStringList pathParts = rawFilePath.split('/'); + if (pathParts.size() == 0) { + qDebug() << "Failed to parse ff path! " << rawFilePath; + exit(-1); + } else if (pathParts.size() == 1) { + const QString path = pathParts[0]; + QTreeWidgetItem *newRootItem = new QTreeWidgetItem(ui->treeWidget_Scripts); newRootItem->setText(0, path); - mTreeMap[path] = newRootItem; - } - - QTreeWidgetItem *parentItem = newRootItem; - for (int i = 1; i < pathParts.size(); i++) { - const QString path = pathParts[i]; - QTreeWidgetItem *newChildItem; + } else { + const QString path = pathParts[0]; + QTreeWidgetItem *newRootItem; if (mTreeMap.contains(path)) { - newChildItem = mTreeMap[path]; + newRootItem = mTreeMap[path]; } else { - newChildItem = new QTreeWidgetItem(); - newChildItem->setText(0, path); - mTreeMap[path] = newChildItem; + newRootItem = new QTreeWidgetItem(ui->treeWidget_Scripts); + newRootItem->setText(0, path); + mTreeMap[path] = newRootItem; + } + + QTreeWidgetItem *parentItem = newRootItem; + for (int i = 1; i < pathParts.size(); i++) { + const QString path = pathParts[i]; + QTreeWidgetItem *newChildItem; + if (mTreeMap.contains(path)) { + newChildItem = mTreeMap[path]; + } else { + newChildItem = new QTreeWidgetItem(); + newChildItem->setText(0, path); + mTreeMap[path] = newChildItem; + } + parentItem->addChild(newChildItem); + parentItem = newChildItem; } - parentItem->addChild(newChildItem); - parentItem = newChildItem; } } - // Parse gsc contents - QString rawFileContents; - char rawFileContentsChar; - *aZoneFileStream >> rawFileContentsChar; - while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { - rawFileContents += rawFileContentsChar; + if (false && isBik) { + qDebug() << "rawFileLength: " << rawFileLength; + QByteArray bikData(rawFileLength, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), rawFileLength); + + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + QString rawFileContents; + char rawFileContentsChar; *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + rawFileContents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } + mRawFileMap[rawFilePath] = (rawFileContents.isEmpty()) ? ("EMPTY") : (rawFileContents); + qDebug() << QString("%1: %2").arg(rawFilePath).arg(rawFileContents); } - mRawFileMap[rawFilePath] = (rawFileContents.isEmpty()) ? ("EMPTY") : (rawFileContents); - // qDebug() << QString("%1: %2").arg(rawFilePath).arg(rawFileContents); } void MainWindow::ParseAsset_PhysPreset(QDataStream *aZoneFileStream) { @@ -744,29 +775,99 @@ void MainWindow::ParseAsset_XModel(QDataStream *aZoneFileStream) { } void MainWindow::ParseAsset_Material(QDataStream *aZoneFileStream) { + aZoneFileStream->skipRawData(27 * 4); + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + qDebug() << "materialNamePtr: " << materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + qDebug() << "Parsing Material: " << materialName; + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + qDebug() << "compressionPtr: " << compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + qDebug() << QString("Found material with DXT%1 compression!").arg(compression); + + *aZoneFileStream >> unknownSectionPtr; + qDebug() << "unknownSectionPtr: " << unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + qDebug() << "imageNamePtr: " << imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + qDebug() << "- Embeded image: " << imageName; + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); } void MainWindow::ParseAsset_PixelShader(QDataStream *aZoneFileStream) { } -void MainWindow::ParseAsset_TechSet(QDataStream *aZoneFileStream) { - aZoneFileStream->skipRawData(4); - // Parse techset name - QString techSetName; - char techSetNameChar; - *aZoneFileStream >> techSetNameChar; - while (techSetNameChar == 0) { - *aZoneFileStream >> techSetNameChar; - } - while (techSetNameChar != 0) { - techSetName += techSetNameChar; - *aZoneFileStream >> techSetNameChar; - } - techSetName.replace(",", ""); - ui->listWidget_TechSets->addItem(techSetName); - //qDebug() << "Tech Set: " << techSetName; +void MainWindow::ParseAsset_BikFile(QDataStream *aZoneFileStream) { + QByteArray testData(32, Qt::Uninitialized); + aZoneFileStream->readRawData(testData.data(), 32); + qDebug() << "Test Data: " << testData; + + //aZoneFileStream->skipRawData(4); + + quint32 fileSize; + //*aZoneFileStream >> fileSize; + //qDebug() << ".bik file size:" << fileSize; + + // // Parse rawfile path + // QString filePath; + // char filePathChar; + // *aZoneFileStream >> filePathChar; + // while (filePathChar != 0) { + // filePath += filePathChar; + // *aZoneFileStream >> filePathChar; + // } + + // QByteArray bikData(fileSize, Qt::Uninitialized); + // aZoneFileStream->readRawData(bikData.data(), fileSize); + // qDebug() << filePath; + + // QFile bikFile(QDir::currentPath() + "/" + filePath.split('/').last()); + // qDebug() << bikFile.fileName(); + // if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + // } + // bikFile.write(bikData); } void MainWindow::ParseAsset_Image(QDataStream *aZoneFileStream) { @@ -899,6 +1000,25 @@ void MainWindow::ParseAsset_D3DBSP(QDataStream *aZoneFileStream) { //D3DBSP_DUMP } +void MainWindow::ParseAsset_TechSet(QDataStream *aZoneFileStream) +{ + aZoneFileStream->skipRawData(4); + // Parse techset name + QString techSetName; + char techSetNameChar; + *aZoneFileStream >> techSetNameChar; + while (techSetNameChar == 0) { + *aZoneFileStream >> techSetNameChar; + } + while (techSetNameChar != 0) { + techSetName += techSetNameChar; + *aZoneFileStream >> techSetNameChar; + } + techSetName.replace(",", ""); + ui->listWidget_TechSets->addItem(techSetName); + qDebug() << "Tech Set: " << techSetName; +} + void MainWindow::ParseAsset_StringTable(QDataStream *aZoneFileStream) { aZoneFileStream->skipRawData(4); @@ -1029,8 +1149,8 @@ void MainWindow::on_pushButton_FastFile_clicked() { ParseAsset_Material(&zoneFileStream); } else if (typeStr == "SHADER") { // pixelshader ParseAsset_PixelShader(&zoneFileStream); - } else if (typeStr == "TECH SET") { // techset include - ParseAsset_TechSet(&zoneFileStream); + } else if (typeStr == "BIK FILE") { // bik file? + ParseAsset_BikFile(&zoneFileStream); } else if (typeStr == "IMAGE") { // image ParseAsset_Image(&zoneFileStream); } else if (typeStr == "SOUND") { // loaded_sound @@ -1061,6 +1181,8 @@ void MainWindow::on_pushButton_FastFile_clicked() { ParseAsset_Weapon(&zoneFileStream); } else if (typeStr == "D3DBSP DUMP") { // string_table ParseAsset_D3DBSP(&zoneFileStream); + } else if (typeStr == "TECH SET") { // string_table + ParseAsset_TechSet(&zoneFileStream); } else if (typeStr != "UNKNOWN") { qDebug() << "Found bad asset type!" << typeStr; } @@ -1126,8 +1248,8 @@ void MainWindow::on_pushButton_FastFile_2_clicked() { ParseAsset_Material(&zoneFileStream); } else if (typeStr == "SHADER") { // pixelshader ParseAsset_PixelShader(&zoneFileStream); - } else if (typeStr == "TECH SET") { // techset include - ParseAsset_TechSet(&zoneFileStream); + } else if (typeStr == "BIK FILE") { // .bik file + ParseAsset_BikFile(&zoneFileStream); } else if (typeStr == "IMAGE") { // image ParseAsset_Image(&zoneFileStream); } else if (typeStr == "SOUND") { // loaded_sound @@ -1158,7 +1280,9 @@ void MainWindow::on_pushButton_FastFile_2_clicked() { ParseAsset_Weapon(&zoneFileStream); } else if (typeStr == "D3DBSP DUMP") { // string_table ParseAsset_D3DBSP(&zoneFileStream); - } else if (typeStr != "UNKNOWN") { + } else if (typeStr == "TECH SET") { // string_table + ParseAsset_TechSet(&zoneFileStream); + } else { qDebug() << "Found bad asset type!" << typeStr; } } diff --git a/mainwindow.h b/mainwindow.h index cfee96c..058bf8f 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -59,6 +59,10 @@ #include #include +#include +#include +#include +#include QT_BEGIN_NAMESPACE namespace Ui { @@ -107,7 +111,7 @@ private slots: void ParseAsset_XModel(QDataStream *aZoneFileStream); void ParseAsset_Material(QDataStream *aZoneFileStream); void ParseAsset_PixelShader(QDataStream *aZoneFileStream); - void ParseAsset_TechSet(QDataStream *aZoneFileStream); + void ParseAsset_BikFile(QDataStream *aZoneFileStream); void ParseAsset_Image(QDataStream *aZoneFileStream); void ParseAsset_LoadedSound(QDataStream *aZoneFileStream); void ParseAsset_ColMapMP(QDataStream *aZoneFileStream); @@ -123,6 +127,7 @@ private slots: void ParseAsset_MenuFile(QDataStream *aZoneFileStream); void ParseAsset_Weapon(QDataStream *aZoneFileStream); void ParseAsset_D3DBSP(QDataStream *aZoneFileStream); + void ParseAsset_TechSet(QDataStream *aZoneFileStream); int LoadFile_D3DBSP(const QString aFilePath); diff --git a/structs.h b/structs.h index 443470e..f1f1406 100644 --- a/structs.h +++ b/structs.h @@ -16,4 +16,26 @@ struct LumpIndexEntry { quint32 length; }; +// Bink structure definitions +struct BINKRECT { + int Left; + int Top; + int Width; + int Height; +}; + +struct BINK { + int Width; + int Height; + uint32_t Frames; + uint32_t FrameNum; + uint32_t FrameRate; + uint32_t FrameRateDiv; + uint32_t ReadError; + uint32_t OpenFlags; + BINKRECT FrameRects; + uint32_t NumRects; + uint32_t FrameChangePercent; +}; + #endif // STRUCTS_H diff --git a/utils.h b/utils.h index 4a0bfc0..674ce30 100644 --- a/utils.h +++ b/utils.h @@ -2,6 +2,7 @@ #define UTILS_H #include "enums.h" +#include "qdir.h" #include #include @@ -45,6 +46,8 @@ public: return "MODEL"; } else if (cleanedType == "0D000000") { // shader PARTIALLY VERIFIED return "SHADER"; + } else if (cleanedType == "06000000") { // material PARTIALLY VERIFIED + return "MATERIAL"; } return "UNKNOWN"; } From a94bb60ca99e9ca68d5e45a8fca5434143d57f55 Mon Sep 17 00:00:00 2001 From: = Date: Wed, 23 Apr 2025 18:07:57 -0400 Subject: [PATCH 4/4] Update branch to main --- libs/zonefile/zonefile_cod5.cpp | 259 ++++++++++++++++++++------------ 1 file changed, 165 insertions(+), 94 deletions(-) diff --git a/libs/zonefile/zonefile_cod5.cpp b/libs/zonefile/zonefile_cod5.cpp index 78665ab..75f9dbe 100644 --- a/libs/zonefile/zonefile_cod5.cpp +++ b/libs/zonefile/zonefile_cod5.cpp @@ -314,18 +314,33 @@ RawFile ZoneFile_COD5::pParseAsset_RawFile(QDataStream *aZoneFileStream) { *aZoneFileStream >> scriptPathChar; } result.path.replace(",", ""); + const QStringList pathParts = result.path.split('/'); if (pathParts.size() == 0) { qDebug() << "Failed to parse ff path! " << result.path; exit(-1); } + if (result.path.contains(".bik")) { + qDebug() << "rawFileLength: " << result.length; + QByteArray bikData(result.length, Qt::Uninitialized); + aZoneFileStream->readRawData(bikData.data(), result.length); - // Parse gsc contents - char rawFileContentsChar; - *aZoneFileStream >> rawFileContentsChar; - while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { - result.contents += rawFileContentsChar; + //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last()); + //qDebug() << bikFile.fileName(); + //if (!bikFile.open(QIODevice::WriteOnly)) { + // qWarning() << "Failed to open .bik file for writing!"; + // return; + //} + //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName()); + //bikFile.write(bikData); + } else { + // Parse gsc contents + char rawFileContentsChar; *aZoneFileStream >> rawFileContentsChar; + while (rawFileContentsChar != 0 && rawFileContentsChar != -1) { + result.contents += rawFileContentsChar; + *aZoneFileStream >> rawFileContentsChar; + } } return result; } @@ -340,10 +355,10 @@ Model ZoneFile_COD5::pParseAsset_Model(QDataStream *aZoneFileStream) { qDebug() << "Model Info:"; *aZoneFileStream >> result.namePtr >> result.tagCount >> result.rootTagCount - >> result.surfCount >> result.unknownCount >> result.boneNamePtr - >> result.parentListPtr >> result.quatsPtr >> result.transPtr - >> result.partClassPtr >> result.baseMatPtr - >> result.surfsPtr >> result.materialHandlesPtr; + >> result.surfCount >> result.unknownCount >> result.boneNamePtr + >> result.parentListPtr >> result.quatsPtr >> result.transPtr + >> result.partClassPtr >> result.baseMatPtr + >> result.surfsPtr >> result.materialHandlesPtr; // Parse XModelLodInfo for (int i = 1; i <= 4; i++) { @@ -358,16 +373,16 @@ Model ZoneFile_COD5::pParseAsset_Model(QDataStream *aZoneFileStream) { aZoneFileStream->skipRawData(4); *aZoneFileStream >> result.lodInfo[i].partBits[0] - >> result.lodInfo[i].partBits[1] - >> result.lodInfo[i].partBits[2] - >> result.lodInfo[i].partBits[3]; + >> result.lodInfo[i].partBits[1] + >> result.lodInfo[i].partBits[2] + >> result.lodInfo[i].partBits[3]; } *aZoneFileStream >> result.collSurfsPtr >> result.numCollSurfs >> result.contents >> result.boneInfoPtr; quint32 intRadius, intMins[3], intMaxs[3]; *aZoneFileStream >> intRadius >> intMins[0] >> intMins[1] - >> intMins[2] >> intMaxs[0] >> intMaxs[1] >> intMaxs[2]; + >> intMins[2] >> intMaxs[0] >> intMaxs[1] >> intMaxs[2]; std::memcpy(&result.radius, &intRadius, sizeof(result.radius)); @@ -380,7 +395,7 @@ Model ZoneFile_COD5::pParseAsset_Model(QDataStream *aZoneFileStream) { std::memcpy(&result.maxs[2], &intMaxs[2], sizeof(result.maxs[3])); *aZoneFileStream >> result.numLods >> result.collLod >> result.streamInfoPtr - >> result.memUsage >> result.flags >> result.physPresetPtr >> result.physGeomsPtr; + >> result.memUsage >> result.flags >> result.physPresetPtr >> result.physGeomsPtr; // Parse model name char modelNameChar; @@ -396,8 +411,64 @@ Model ZoneFile_COD5::pParseAsset_Model(QDataStream *aZoneFileStream) { } Material ZoneFile_COD5::pParseAsset_Material(QDataStream *aZoneFileStream) { - Q_UNUSED(aZoneFileStream); + aZoneFileStream->skipRawData(27 * 4); + qint32 materialNamePtr; + *aZoneFileStream >> materialNamePtr; + qDebug() << "materialNamePtr: " << materialNamePtr; + if (materialNamePtr == -1) { + QString materialName; + char materialNameChar; + *aZoneFileStream >> materialNameChar; + while (materialNameChar != 0) { + materialName += materialNameChar; + *aZoneFileStream >> materialNameChar; + } + qDebug() << "Parsing Material: " << materialName; + } + + aZoneFileStream->skipRawData(3 * 4); + + qint32 compressionPtr, compression, unknownSectionPtr; + *aZoneFileStream >> compressionPtr; + qDebug() << "compressionPtr: " << compressionPtr; + if (compressionPtr == -1) { + *aZoneFileStream >> compression; + qDebug() << QString("Found material with DXT%1 compression!").arg(compression); + + *aZoneFileStream >> unknownSectionPtr; + qDebug() << "unknownSectionPtr: " << unknownSectionPtr; + if (unknownSectionPtr == -2) { + aZoneFileStream->skipRawData(6 * 4); + } + } + + qint32 imageNamePtr; + *aZoneFileStream >> imageNamePtr; + qDebug() << "imageNamePtr: " << imageNamePtr; + if (imageNamePtr == -1) { + QString imageName; + char imageNameChar; + *aZoneFileStream >> imageNameChar; + while (imageNameChar != 0) { + imageName += imageNameChar; + *aZoneFileStream >> imageNameChar; + } + qDebug() << "- Embeded image: " << imageName; + } + + QByteArray compressionData(4, Qt::Uninitialized); + QString compressionStr; + if (compressionPtr == -1) { + aZoneFileStream->skipRawData(2 * 4); + aZoneFileStream->readRawData(compressionData.data(), 4); + aZoneFileStream->skipRawData(4); + compressionStr = QString::fromUtf8(compressionData); + aZoneFileStream->skipRawData(4); + } + aZoneFileStream->skipRawData(4); + + // TODO: Fill out this material return Material(); } @@ -472,9 +543,9 @@ Image ZoneFile_COD5::pParseAsset_Image(QDataStream *aZoneFileStream) { aZoneFileStream->skipRawData(4); *aZoneFileStream >> result.unknowna >> result.unknownb - >> result.unknownc >> result.unknownd - >> result.unknowne >> result.unknownf - >> result.unknowng; + >> result.unknownc >> result.unknownd + >> result.unknowne >> result.unknownf + >> result.unknowng; aZoneFileStream->skipRawData(15 * 4); *aZoneFileStream >> result.unknownh >> result.unknowni; @@ -504,8 +575,8 @@ Image ZoneFile_COD5::pParseAsset_Image(QDataStream *aZoneFileStream) { aZoneFileStream->skipRawData(4); *aZoneFileStream >> result.unknown2 >> result.unknown3 - >> result.size1 >> result.size2 - >> result.unknown4 >> result.unknown5; + >> result.size1 >> result.size2 + >> result.unknown4 >> result.unknown5; aZoneFileStream->skipRawData(4); @@ -691,43 +762,43 @@ Animation ZoneFile_COD5::pParseAsset_Animation(QDataStream *aZoneFileStream) { aZoneFileStream->skipRawData(4); *aZoneFileStream - >> result.dataByteCount - >> result.dataShortCount - >> result.dataIntCount - >> result.randomDataByteCount - >> result.randomDataIntCount - >> result.numframes - >> result.isLooped - >> result.isDelta - >> result.noneRotatedBoneCount - >> result.twoDRotatedBoneCount - >> result.normalRotatedBoneCount - >> result.twoDRotatedBoneCount - >> result.normalRotatedBoneCount - >> result.normalTranslatedBoneCount - >> result.preciseTranslatedBoneCount - >> result.staticTranslatedBoneCount - >> result.noneTranslatedBoneCount - >> result.totalBoneCount - >> result.otherBoneCount1 - >> result.otherBoneCount2 - >> result.notifyCount - >> result.assetType - >> result.pad - >> result.randomDataShortCount - >> result.indexCount - >> result.frameRate - >> result.frequency - >> result.boneIDsPtr - >> result.dataBytePtr - >> result.dataShortPtr - >> result.dataIntPtr - >> result.randomDataShortPtr - >> result.randomDataBytePtr - >> result.randomDataIntPtr - >> result.longIndiciesPtr - >> result.notificationsPtr - >> result.deltaPartsPtr; + >> result.dataByteCount + >> result.dataShortCount + >> result.dataIntCount + >> result.randomDataByteCount + >> result.randomDataIntCount + >> result.numframes + >> result.isLooped + >> result.isDelta + >> result.noneRotatedBoneCount + >> result.twoDRotatedBoneCount + >> result.normalRotatedBoneCount + >> result.twoDRotatedBoneCount + >> result.normalRotatedBoneCount + >> result.normalTranslatedBoneCount + >> result.preciseTranslatedBoneCount + >> result.staticTranslatedBoneCount + >> result.noneTranslatedBoneCount + >> result.totalBoneCount + >> result.otherBoneCount1 + >> result.otherBoneCount2 + >> result.notifyCount + >> result.assetType + >> result.pad + >> result.randomDataShortCount + >> result.indexCount + >> result.frameRate + >> result.frequency + >> result.boneIDsPtr + >> result.dataBytePtr + >> result.dataShortPtr + >> result.dataIntPtr + >> result.randomDataShortPtr + >> result.randomDataBytePtr + >> result.randomDataIntPtr + >> result.longIndiciesPtr + >> result.notificationsPtr + >> result.deltaPartsPtr; // Read in x_anim file name QString xAnimName; @@ -798,21 +869,21 @@ MenuFile ZoneFile_COD5::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { quint32 hClientAlignInt, vClientAlignInt, styleInt, borderInt; *aZoneFileStream >> hClientAlignInt >> vClientAlignInt >> menu.groupPtr - >> styleInt >> borderInt >> menu.ownerDraw >> menu.ownerDrawFlags - >> menu.borderSize >> menu.staticFlags >> menu.dynamicFlags >> menu.nextTime; + >> styleInt >> borderInt >> menu.ownerDraw >> menu.ownerDrawFlags + >> menu.borderSize >> menu.staticFlags >> menu.dynamicFlags >> menu.nextTime; menu.hClientAlign = (MENU_H_ALIGNMENT)hClientAlignInt; menu.vClientAlign = (MENU_V_ALIGNMENT)vClientAlignInt; menu.style = (MENU_WINDOW_STYLE)styleInt; menu.border = (MENU_WINDOW_BORDER)borderInt; float foregroundColorR, foregroundColorG, foregroundColorB, foregroundColorA, - backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA, - borderColorR, borderColorG, borderColorB, borderColorA, - outlineColorR, outlineColorG, outlineColorB, outlineColorA; + backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA, + borderColorR, borderColorG, borderColorB, borderColorA, + outlineColorR, outlineColorG, outlineColorB, outlineColorA; *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA - >> backgroundColorR >> backgroundColorG >> backgroundColorB >> backgroundColorA - >> borderColorR >> borderColorG >> borderColorB >> borderColorA - >> outlineColorR >> outlineColorG >> outlineColorB >> outlineColorA; + >> backgroundColorR >> backgroundColorG >> backgroundColorB >> backgroundColorA + >> borderColorR >> borderColorG >> borderColorB >> borderColorA + >> outlineColorR >> outlineColorG >> outlineColorB >> outlineColorA; menu.foregroundColor = QColor(foregroundColorR, foregroundColorG, foregroundColorB, foregroundColorA); menu.backgroundColor = QColor(backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA); @@ -820,16 +891,16 @@ MenuFile ZoneFile_COD5::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { menu.outlineColor = QColor(outlineColorR, outlineColorG, outlineColorB, outlineColorA); *aZoneFileStream >> menu.materialPtr >> menu.fontPtr >> menu.fullScreen >> menu.itemCount - >> menu.fontIndex >> menu.cursorItem >> menu.fadeCycle >> menu.fadeClamp - >> menu.fadeAmount >> menu.fadeInAmount >> menu.blurRadius >> menu.onOpenPtr - >> menu.onFocusPtr >> menu.onClosePtr >> menu.onESCPtr >> menu.onKeyPtr - >> menu.visibleExpCount >> menu.expEntryPtr >> menu.allowedBindingPtr - >> menu.soundNamePtr >> menu.imageTrack; + >> menu.fontIndex >> menu.cursorItem >> menu.fadeCycle >> menu.fadeClamp + >> menu.fadeAmount >> menu.fadeInAmount >> menu.blurRadius >> menu.onOpenPtr + >> menu.onFocusPtr >> menu.onClosePtr >> menu.onESCPtr >> menu.onKeyPtr + >> menu.visibleExpCount >> menu.expEntryPtr >> menu.allowedBindingPtr + >> menu.soundNamePtr >> menu.imageTrack; float focusColorR, focusColorG, focusColorB, focusColorA, - disabledColorR, disabledColorG, disabledColorB, disabledColorA; + disabledColorR, disabledColorG, disabledColorB, disabledColorA; *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA - >> disabledColorR >> disabledColorG >> disabledColorB >> disabledColorA; + >> disabledColorR >> disabledColorG >> disabledColorB >> disabledColorA; menu.focusColor = QColor(focusColorR, focusColorG, focusColorB, focusColorA); menu.disabledColor = QColor(disabledColorR, disabledColorG, disabledColorB, disabledColorA); @@ -863,18 +934,18 @@ MenuFile ZoneFile_COD5::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { menu.itemRect = QRectF(itemRectX, itemRectY, itemRectWidth, itemRectHeight); *aZoneFileStream >> menu.itemHAlignment >> menu.itemVAlignment >> menu.itemGroupPtr - >> menu.itemWindowStyle >> menu.itemWindowBorder >> menu.itemOwnerDraw - >> menu.itemOwnerDrawFlags >> menu.itemBorderSize >> menu.itemStaticFlags - >> menu.itemDynamicFlags >> menu.itemNextTime; + >> menu.itemWindowStyle >> menu.itemWindowBorder >> menu.itemOwnerDraw + >> menu.itemOwnerDrawFlags >> menu.itemBorderSize >> menu.itemStaticFlags + >> menu.itemDynamicFlags >> menu.itemNextTime; float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA, - itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA, - itemBorderColorR, itemBorderColorG, itemBorderColorB, itemBorderColorA, - itemOutlineColorR, itemOutlineColorG, itemOutlineColorB, itemOutlineColorA; + itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA, + itemBorderColorR, itemBorderColorG, itemBorderColorB, itemBorderColorA, + itemOutlineColorR, itemOutlineColorG, itemOutlineColorB, itemOutlineColorA; *aZoneFileStream >> itemForegroundColorR >> itemForegroundColorG >> itemForegroundColorB >> itemForegroundColorA - >> itemBackgroundColorR >> itemBackgroundColorG >> itemBackgroundColorB >> itemBackgroundColorA - >> itemBorderColorR >> itemBorderColorG >> itemBorderColorB >> itemBorderColorA - >> itemOutlineColorR >> itemOutlineColorG >> itemOutlineColorB >> itemOutlineColorA; + >> itemBackgroundColorR >> itemBackgroundColorG >> itemBackgroundColorB >> itemBackgroundColorA + >> itemBorderColorR >> itemBorderColorG >> itemBorderColorB >> itemBorderColorA + >> itemOutlineColorR >> itemOutlineColorG >> itemOutlineColorB >> itemOutlineColorA; menu.itemForegroundColor = QColor(itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA); menu.itemBackgroundColor = QColor(itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA); @@ -889,9 +960,9 @@ MenuFile ZoneFile_COD5::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { quint32 hItemTextAlignInt, vItemTextAlignInt, itemType, fontTypeInt, textStyleInt; *aZoneFileStream >> hItemTextAlignInt >> vItemTextAlignInt >> itemType >> menu.dataType - >> menu.alignment >> fontTypeInt >> menu.textAlignMode >> menu.textalignx >> menu.textaligny - >> menu.textscale >> textStyleInt >> menu.gameMsgWindowIndex >> menu.gameMsgWindowMode - >> menu.testPtr >> menu.textSavegameInfo >> menu.parentPtr; + >> menu.alignment >> fontTypeInt >> menu.textAlignMode >> menu.textalignx >> menu.textaligny + >> menu.textscale >> textStyleInt >> menu.gameMsgWindowIndex >> menu.gameMsgWindowMode + >> menu.testPtr >> menu.textSavegameInfo >> menu.parentPtr; menu.itemText_hAlign = (MENU_H_ALIGNMENT)hItemTextAlignInt; menu.itemText_vAlign = (MENU_V_ALIGNMENT)vItemTextAlignInt; menu.itemType = (MENU_ITEM_TYPE)itemType; @@ -899,9 +970,9 @@ MenuFile ZoneFile_COD5::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { menu.textStyle = (MENU_ITEM_TEXTSTYLE)textStyleInt; *aZoneFileStream >> menu.mouseEnterText >> menu.mouseExitText >> menu.mouseEnter >> menu.mouseExit - >> menu.action >> menu.onAccept >> menu.onFocus >> menu.leaveFocus >> menu.dvar >> menu.dvarTest - >> menu.keyHandlerPtr >> menu.enableDvarPtr >> menu.dvarFlags >> menu.focusSoundPtr - >> menu.special >> menu.cursorPos; + >> menu.action >> menu.onAccept >> menu.onFocus >> menu.leaveFocus >> menu.dvar >> menu.dvarTest + >> menu.keyHandlerPtr >> menu.enableDvarPtr >> menu.dvarFlags >> menu.focusSoundPtr + >> menu.special >> menu.cursorPos; // itemDefData_t typeData; @@ -921,11 +992,11 @@ MenuFile ZoneFile_COD5::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { *aZoneFileStream >> menu.notselectable >> menu.noScrollBars >> menu.usePaging; float itemSelectBorderColorR, itemSelectBorderColorG, itemSelectBorderColorB, itemSelectBorderColorA, - itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA, - itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA; + itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA, + itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA; *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA - >> itemDisableColorR >> itemDisableColorG >> itemDisableColorB >> itemDisableColorA - >> itemFocusColorR >> itemFocusColorG >> itemFocusColorB >> itemFocusColorA; + >> itemDisableColorR >> itemDisableColorG >> itemDisableColorB >> itemDisableColorA + >> itemFocusColorR >> itemFocusColorG >> itemFocusColorB >> itemFocusColorA; menu.itemSelectBorderColor = QColor(itemSelectBorderColorR, itemSelectBorderColorG, itemSelectBorderColorB, itemSelectBorderColorA); menu.itemDisableColor = QColor(itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA); menu.itemFocusColor = QColor(itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA); @@ -935,7 +1006,7 @@ MenuFile ZoneFile_COD5::pParseAsset_MenuFile(QDataStream *aZoneFileStream) { // editFieldDef_s *editField; *aZoneFileStream >> menu.minVal >> menu.maxVal >> menu.defVal >> menu.range >> menu.maxChars - >> menu.maxCharsGotoNext >> menu.maxPaintChars >> menu.paintOffset; + >> menu.maxCharsGotoNext >> menu.maxPaintChars >> menu.paintOffset; // multiDef_s *multi; @@ -993,8 +1064,8 @@ StringTable ZoneFile_COD5::pParseAsset_StringTable(QDataStream *aZoneFileStream) aZoneFileStream->skipRawData(4); *aZoneFileStream - >> result.columnCount - >> result.rowCount; + >> result.columnCount + >> result.rowCount; // Todo fix this result.columnCount = 0;