From ebcc95da4c26369511caa90d89c5ed06e1e4853a Mon Sep 17 00:00:00 2001 From: Treeki Date: Thu, 14 Oct 2010 20:17:20 +0200 Subject: brlyt packing added, plus some changes in the existing API (mostly for const correctness). brlyt writing may still need some testing (especially for the material structs) --- LayoutStudio.pro | 3 +- README.markdown | 5 +- lyt/archivepackage.cpp | 26 +++--- lyt/archivepackage.h | 26 +++--- lyt/binaryfile.cpp | 8 +- lyt/binaryfile.h | 2 +- lyt/binaryfilesection.cpp | 33 +++++-- lyt/binaryfilesection.h | 11 ++- lyt/bounding.cpp | 9 +- lyt/bounding.h | 8 +- lyt/common.h | 4 + lyt/directorypackage.cpp | 22 ++--- lyt/directorypackage.h | 24 ++--- lyt/group.cpp | 4 +- lyt/group.h | 2 +- lyt/layout.cpp | 183 +++++++++++++++++++++++++++++++++++++- lyt/layout.h | 14 ++- lyt/materials/alphacompare.cpp | 4 +- lyt/materials/alphacompare.h | 4 +- lyt/materials/blendmode.cpp | 4 +- lyt/materials/blendmode.h | 4 +- lyt/materials/chanctrl.cpp | 6 +- lyt/materials/chanctrl.h | 4 +- lyt/materials/indirectstage.cpp | 4 +- lyt/materials/indirectstage.h | 4 +- lyt/materials/material.cpp | 82 ++++++++++++++++- lyt/materials/material.h | 30 +++---- lyt/materials/materialcontainer.h | 76 ++++++++++++++++ lyt/materials/tevstage.cpp | 6 +- lyt/materials/tevstage.h | 4 +- lyt/materials/tevswaptable.cpp | 6 +- lyt/materials/tevswaptable.h | 4 +- lyt/materials/texcoordgen.cpp | 6 +- lyt/materials/texcoordgen.h | 4 +- lyt/materials/texmap.cpp | 4 +- lyt/materials/texmap.h | 4 +- lyt/materials/texsrt.cpp | 4 +- lyt/materials/texsrt.h | 4 +- lyt/packagebase.h | 18 ++-- lyt/pane.cpp | 21 ++++- lyt/pane.h | 10 ++- lyt/picture.cpp | 21 +++-- lyt/picture.h | 6 +- lyt/textbox.cpp | 26 ++++-- lyt/textbox.h | 8 +- lyt/window.cpp | 33 +++---- lyt/window.h | 12 +-- main.cpp | 8 +- wii/archiveu8.cpp | 10 +-- wii/archiveu8.h | 10 +-- wii/common.cpp | 28 +++++- wii/common.h | 5 +- wii/filesystem.cpp | 14 +-- wii/filesystem.h | 12 +-- wii/stringtablebuilder.cpp | 2 +- wii/stringtablebuilder.h | 2 +- 56 files changed, 677 insertions(+), 221 deletions(-) create mode 100644 lyt/materials/materialcontainer.h diff --git a/LayoutStudio.pro b/LayoutStudio.pro index 0b6a395..49f2d40 100644 --- a/LayoutStudio.pro +++ b/LayoutStudio.pro @@ -61,7 +61,8 @@ HEADERS += lsmainwindow.h \ wii/common.h \ wii/filesystem.h \ lyt/archivepackage.h \ - wii/stringtablebuilder.h + wii/stringtablebuilder.h \ + lyt/materials/materialcontainer.h FORMS += lsmainwindow.ui RESOURCES += resources.qrc diff --git a/README.markdown b/README.markdown index 9a3852d..f41ca8a 100644 --- a/README.markdown +++ b/README.markdown @@ -14,13 +14,12 @@ GX GPU emulation in the [Dolphin][dol] GameCube/Wii emulator. ### Implemented Features ### -- BRLYT reading (materials are not yet fully implemented) +- BRLYT reading, writing (writing is not fully tested yet) - Simple API for manipulating layout files from other code - Wii filesystem API (currently only supports U8 archives) ### Planned Features ### -- BRLYT writing (partially done) - BRLAN reading/writing - Graphical interface for editing layouts and animations - Rendering of layouts using OpenGL and Dolphin's GX emulation @@ -29,9 +28,7 @@ GX GPU emulation in the [Dolphin][dol] GameCube/Wii emulator. ### Current (Short-Term) TODO ### - Disassemble code that sets up indirect textures for materials -- Test code for material structs - Add usd1 handling -- Add LYTLayout packing - Add TPL file support diff --git a/lyt/archivepackage.cpp b/lyt/archivepackage.cpp index 6b5a476..eaabbf2 100644 --- a/lyt/archivepackage.cpp +++ b/lyt/archivepackage.cpp @@ -40,17 +40,17 @@ LYTArchivePackage::~LYTArchivePackage() { -WiiArchiveU8 *LYTArchivePackage::archive() { +WiiArchiveU8 *LYTArchivePackage::archive() const { return m_archive; } -QString LYTArchivePackage::filename() { +QString LYTArchivePackage::filename() const { return m_filename; } -QStringList LYTArchivePackage::listSubDirIfExists(QString dirName) { +QStringList LYTArchivePackage::listSubDirIfExists(QString dirName) const { WiiFSObject *obj = this->m_archive->root.resolvePath(dirName); if (obj && obj->isDirectory()) { @@ -67,7 +67,7 @@ QStringList LYTArchivePackage::listSubDirIfExists(QString dirName) { } -QByteArray LYTArchivePackage::getFileFromSubDirIfExists(QString dirName, QString fileName) { +QByteArray LYTArchivePackage::getFileFromSubDirIfExists(QString dirName, QString fileName) const { WiiFSObject *obj = this->m_archive->root.resolvePath(QString("%1/%2").arg(dirName, fileName)); if (obj && obj->isFile()) { @@ -92,37 +92,37 @@ bool LYTArchivePackage::writeFileToSubDir(QString dirName, QString fileName, QBy -QStringList LYTArchivePackage::listAnims() { +QStringList LYTArchivePackage::listAnims() const { return this->listSubDirIfExists("arc/anim"); } -QStringList LYTArchivePackage::listLayouts() { +QStringList LYTArchivePackage::listLayouts() const { return this->listSubDirIfExists("arc/blyt"); } -QStringList LYTArchivePackage::listTextures() { +QStringList LYTArchivePackage::listTextures() const { return this->listSubDirIfExists("arc/timg"); } -QStringList LYTArchivePackage::listFonts() { +QStringList LYTArchivePackage::listFonts() const { return this->listSubDirIfExists("arc/font"); } -QByteArray LYTArchivePackage::getAnim(QString name) { +QByteArray LYTArchivePackage::getAnim(QString name) const { return this->getFileFromSubDirIfExists("arc/anim", name); } -QByteArray LYTArchivePackage::getLayout(QString name) { +QByteArray LYTArchivePackage::getLayout(QString name) const { return this->getFileFromSubDirIfExists("arc/blyt", name); } -QByteArray LYTArchivePackage::getTexture(QString name) { +QByteArray LYTArchivePackage::getTexture(QString name) const { return this->getFileFromSubDirIfExists("arc/timg", name); } -QByteArray LYTArchivePackage::getFont(QString name) { +QByteArray LYTArchivePackage::getFont(QString name) const { return this->getFileFromSubDirIfExists("arc/font", name); } @@ -163,6 +163,6 @@ bool LYTArchivePackage::savePackage() { } -QString LYTArchivePackage::description() { +QString LYTArchivePackage::description() const { return m_filename; } diff --git a/lyt/archivepackage.h b/lyt/archivepackage.h index 7ef1abd..e2d5f25 100644 --- a/lyt/archivepackage.h +++ b/lyt/archivepackage.h @@ -28,15 +28,15 @@ public: ~LYTArchivePackage(); - QStringList listAnims(); - QStringList listLayouts(); - QStringList listTextures(); - QStringList listFonts(); + QStringList listAnims() const; + QStringList listLayouts() const; + QStringList listTextures() const; + QStringList listFonts() const; - QByteArray getAnim(QString name); - QByteArray getLayout(QString name); - QByteArray getTexture(QString name); - QByteArray getFont(QString name); + QByteArray getAnim(QString name) const; + QByteArray getLayout(QString name) const; + QByteArray getTexture(QString name) const; + QByteArray getFont(QString name) const; bool writeAnim(QString name, QByteArray data); bool writeLayout(QString name, QByteArray data); @@ -44,15 +44,15 @@ public: bool writeFont(QString name, QByteArray data); bool savePackage(); - QString description(); + QString description() const; - WiiArchiveU8 *archive(); - QString filename(); + WiiArchiveU8 *archive() const; + QString filename() const; protected: - QStringList listSubDirIfExists(QString dirName); - QByteArray getFileFromSubDirIfExists(QString dirName, QString fileName); + QStringList listSubDirIfExists(QString dirName) const; + QByteArray getFileFromSubDirIfExists(QString dirName, QString fileName) const; bool writeFileToSubDir(QString dirName, QString fileName, QByteArray data); WiiArchiveU8 *m_archive; diff --git a/lyt/binaryfile.cpp b/lyt/binaryfile.cpp index 2b285c2..26ca8a0 100644 --- a/lyt/binaryfile.cpp +++ b/lyt/binaryfile.cpp @@ -20,13 +20,11 @@ #include -LYTBinaryFile::LYTBinaryFile(Magic magic, Version version) { - this->magic.value = magic.value; - this->version.value = version.value; +LYTBinaryFile::LYTBinaryFile(Magic m, Version v) : magic(m), version(v) { } -LYTBinaryFile::LYTBinaryFile(QByteArray data) { +LYTBinaryFile::LYTBinaryFile(QByteArray data) : magic(0), version(0) { QDataStream reader(data); InitDataStream(reader); @@ -49,7 +47,7 @@ LYTBinaryFile::LYTBinaryFile(QByteArray data) { } -QByteArray LYTBinaryFile::pack() { +QByteArray LYTBinaryFile::pack() const { // first off, calculate filesize for the header quint32 fileSize = 16; diff --git a/lyt/binaryfile.h b/lyt/binaryfile.h index c449858..0c94776 100644 --- a/lyt/binaryfile.h +++ b/lyt/binaryfile.h @@ -28,7 +28,7 @@ public: LYTBinaryFile(Magic magic, Version version); LYTBinaryFile(QByteArray data); - QByteArray pack(); + QByteArray pack() const; Magic magic; Version version; diff --git a/lyt/binaryfilesection.cpp b/lyt/binaryfilesection.cpp index a06810d..5115cda 100644 --- a/lyt/binaryfilesection.cpp +++ b/lyt/binaryfilesection.cpp @@ -17,14 +17,23 @@ #include "binaryfilesection.h" -LYTBinaryFileSection::LYTBinaryFileSection() { +LYTBinaryFileSection::LYTBinaryFileSection() : magic(0) { } +LYTBinaryFileSection::LYTBinaryFileSection(Magic m) : magic(m) { +} + +LYTBinaryFileSection::LYTBinaryFileSection(Magic m, QByteArray d) : magic(m), data(d) { +} -void LYTBinaryFileSection::writeToDataStream(QDataStream &out) { + +void LYTBinaryFileSection::writeToDataStream(QDataStream &out) const { out << (quint32)magic.value; - out << (quint32)data.length() + 8; + out << (quint32)AlignUp(data.length() + 8, 4); out.writeRawData(data.constData(), data.length()); + + int align = AlignUp(data.length(), 4) - data.length(); + WritePadding(align, out); } void LYTBinaryFileSection::readFromDataStream(QDataStream &in) { @@ -40,6 +49,20 @@ void LYTBinaryFileSection::readFromDataStream(QDataStream &in) { } -int LYTBinaryFileSection::writtenSize() { - return 8 + this->data.length(); +int LYTBinaryFileSection::writtenSize() const { + return 8 + AlignUp(this->data.length(), 4); +} + + +QDataStream *LYTBinaryFileSection::createReadStream() const { + QDataStream *stream = new QDataStream(this->data); + InitDataStream(*stream); + return stream; +} + + +QDataStream *LYTBinaryFileSection::createWriteStream() { + QDataStream *stream = new QDataStream(&this->data, QIODevice::ReadWrite); + InitDataStream(*stream); + return stream; } diff --git a/lyt/binaryfilesection.h b/lyt/binaryfilesection.h index 3e82bbb..be1ef94 100644 --- a/lyt/binaryfilesection.h +++ b/lyt/binaryfilesection.h @@ -24,15 +24,20 @@ class LYTBinaryFileSection { public: - LYTBinaryFileSection(); + LYTBinaryFileSection(); + LYTBinaryFileSection(Magic magic); + LYTBinaryFileSection(Magic magic, QByteArray data); Magic magic; QByteArray data; - void writeToDataStream(QDataStream &out); + QDataStream *createReadStream() const; + QDataStream *createWriteStream(); + + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - int writtenSize(); + int writtenSize() const; }; diff --git a/lyt/bounding.cpp b/lyt/bounding.cpp index fea80d1..ce506b3 100644 --- a/lyt/bounding.cpp +++ b/lyt/bounding.cpp @@ -24,7 +24,12 @@ LYTBounding::LYTBounding(LYTLayout &layout) : LYTPane(layout) { } -void LYTBounding::dumpToDebug(bool showHeading) { +Magic LYTBounding::magic() const { + return Magic('bnd1'); +} + + +void LYTBounding::dumpToDebug(bool showHeading) const { if (showHeading) qDebug() << "LYTBounding" << name << "@" << (void*)this; @@ -33,7 +38,7 @@ void LYTBounding::dumpToDebug(bool showHeading) { -void LYTBounding::writeToDataStream(QDataStream &out) { +void LYTBounding::writeToDataStream(QDataStream &out) const { LYTPane::writeToDataStream(out); } diff --git a/lyt/bounding.h b/lyt/bounding.h index d5beffd..23a29aa 100644 --- a/lyt/bounding.h +++ b/lyt/bounding.h @@ -29,11 +29,13 @@ public: LYTBounding(LYTLayout &layout); - void writeToDataStream(QDataStream &out); + Magic magic() const; + + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(bool showHeading=true); + void dumpToDebug(bool showHeading=true) const; }; -#endif // LYTPICTURE_H +#endif // LYTBOUNDING_H diff --git a/lyt/common.h b/lyt/common.h index 9c39339..49061ce 100644 --- a/lyt/common.h +++ b/lyt/common.h @@ -25,11 +25,15 @@ union Magic { char str[4]; quint32 value; + + Magic(quint32 v) : value(v) { } }; union Version { char str[2]; quint16 value; + + Version(quint16 v) : value(v) { } }; diff --git a/lyt/directorypackage.cpp b/lyt/directorypackage.cpp index e8f31b9..dd8c39d 100644 --- a/lyt/directorypackage.cpp +++ b/lyt/directorypackage.cpp @@ -26,7 +26,7 @@ LYTDirectoryPackage::LYTDirectoryPackage(QString path) : LYTPackageBase() { -QStringList LYTDirectoryPackage::listSubDirIfExists(QString dirName) { +QStringList LYTDirectoryPackage::listSubDirIfExists(QString dirName) const { QDir search(m_path); if (search.cd(dirName)) { @@ -37,7 +37,7 @@ QStringList LYTDirectoryPackage::listSubDirIfExists(QString dirName) { } -QByteArray LYTDirectoryPackage::getFileFromSubDirIfExists(QString dirName, QString fileName) { +QByteArray LYTDirectoryPackage::getFileFromSubDirIfExists(QString dirName, QString fileName) const { QDir search(m_path); if (search.cd(dirName)) { @@ -71,37 +71,37 @@ bool LYTDirectoryPackage::writeFileToSubDir(QString dirName, QString fileName, Q -QStringList LYTDirectoryPackage::listAnims() { +QStringList LYTDirectoryPackage::listAnims() const { return this->listSubDirIfExists("anim"); } -QStringList LYTDirectoryPackage::listLayouts() { +QStringList LYTDirectoryPackage::listLayouts() const { return this->listSubDirIfExists("blyt"); } -QStringList LYTDirectoryPackage::listTextures() { +QStringList LYTDirectoryPackage::listTextures() const { return this->listSubDirIfExists("timg"); } -QStringList LYTDirectoryPackage::listFonts() { +QStringList LYTDirectoryPackage::listFonts() const { return this->listSubDirIfExists("font"); } -QByteArray LYTDirectoryPackage::getAnim(QString name) { +QByteArray LYTDirectoryPackage::getAnim(QString name) const { return this->getFileFromSubDirIfExists("anim", name); } -QByteArray LYTDirectoryPackage::getLayout(QString name) { +QByteArray LYTDirectoryPackage::getLayout(QString name) const { return this->getFileFromSubDirIfExists("blyt", name); } -QByteArray LYTDirectoryPackage::getTexture(QString name) { +QByteArray LYTDirectoryPackage::getTexture(QString name) const { return this->getFileFromSubDirIfExists("timg", name); } -QByteArray LYTDirectoryPackage::getFont(QString name) { +QByteArray LYTDirectoryPackage::getFont(QString name) const { return this->getFileFromSubDirIfExists("font", name); } @@ -131,6 +131,6 @@ bool LYTDirectoryPackage::savePackage() { } -QString LYTDirectoryPackage::description() { +QString LYTDirectoryPackage::description() const { return m_path; } diff --git a/lyt/directorypackage.h b/lyt/directorypackage.h index 80d12f9..df8a50e 100644 --- a/lyt/directorypackage.h +++ b/lyt/directorypackage.h @@ -24,15 +24,15 @@ class LYTDirectoryPackage : public LYTPackageBase { public: LYTDirectoryPackage(QString path); - QStringList listAnims(); - QStringList listLayouts(); - QStringList listTextures(); - QStringList listFonts(); + QStringList listAnims() const; + QStringList listLayouts() const; + QStringList listTextures() const; + QStringList listFonts() const; - QByteArray getAnim(QString name); - QByteArray getLayout(QString name); - QByteArray getTexture(QString name); - QByteArray getFont(QString name); + QByteArray getAnim(QString name) const; + QByteArray getLayout(QString name) const; + QByteArray getTexture(QString name) const; + QByteArray getFont(QString name) const; bool writeAnim(QString name, QByteArray data); bool writeLayout(QString name, QByteArray data); @@ -40,12 +40,12 @@ public: bool writeFont(QString name, QByteArray data); bool savePackage(); - QString description(); - QString path(); + QString description() const; + QString path() const; protected: - QStringList listSubDirIfExists(QString dirName); - QByteArray getFileFromSubDirIfExists(QString dirName, QString fileName); + QStringList listSubDirIfExists(QString dirName) const; + QByteArray getFileFromSubDirIfExists(QString dirName, QString fileName) const; bool writeFileToSubDir(QString dirName, QString fileName, QByteArray data); diff --git a/lyt/group.cpp b/lyt/group.cpp index 10b534d..4573459 100644 --- a/lyt/group.cpp +++ b/lyt/group.cpp @@ -23,12 +23,12 @@ LYTGroup::LYTGroup() { -void LYTGroup::writeToDataStream(QDataStream &out) { +void LYTGroup::writeToDataStream(QDataStream &out) const { WriteFixedLengthASCII(out, name, 0x10); // write the contents out << (quint16)panes.count(); - out.skipRawData(2); // padding + WritePadding(2, out); foreach (LYTPane *pane, panes) { WriteFixedLengthASCII(out, pane->name, 0x10); diff --git a/lyt/group.h b/lyt/group.h index 5e48803..a20287b 100644 --- a/lyt/group.h +++ b/lyt/group.h @@ -28,7 +28,7 @@ public: LYTGroup(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in, LYTPane &linkedPane); QString name; diff --git a/lyt/layout.cpp b/lyt/layout.cpp index 5dfebd0..afe8a67 100644 --- a/lyt/layout.cpp +++ b/lyt/layout.cpp @@ -40,13 +40,16 @@ void LYTLayout::clear() { this->m_fontRefs.clear(); this->m_textureRefs.clear(); - foreach (LYTMaterial *material, materials.values()) - delete material; + foreach (LYTMaterialContainerEntry materialEntry, materials.list) + delete materialEntry.second; this->materials.clear(); if (this->rootPane != 0) delete this->rootPane; + + foreach (LYTGroup *group, groups) + delete group; } @@ -158,7 +161,8 @@ void LYTLayout::readLyt1(LYTBinaryFileSection §ion) { QDataStream in(section.data); InitDataStream(in); - in.skipRawData(4); // unused in newer nw4r::lyt versions - TODO: add support + in >> (quint8&)flags; // seems to be unused in newer nw4r::lyt versions (but still in file)? + in.skipRawData(3); // padding in >> (float&)width; in >> (float&)height; @@ -213,7 +217,7 @@ void LYTLayout::readMat1(LYTBinaryFileSection §ion) { material->readFromDataStream(in); material->dumpToDebug(); - materials.insert(material->name, material); + materials.addMaterial(material->name, material); } } @@ -238,3 +242,174 @@ LYTPane *LYTLayout::createPaneObj(LYTBinaryFileSection §ion) { return pane; } + + + +QByteArray LYTLayout::pack() { + qDebug() << "Writing layout"; + + // before we start writing the file, find out a bunch of info + qDebug() << "Compiling texture ref list"; + m_textureRefs = this->generateTextureRefs(); + + qDebug() << "Compiling font ref list"; + m_fontRefs = this->generateFontRefs(); + + // now start writing the file + Magic magic('RLYT'); + Version version(0x000A); + + LYTBinaryFile file(magic, version); + + QDataStream *stream; + + // write lyt1 + file.sections.append(LYTBinaryFileSection(Magic('lyt1'))); + stream = file.sections.last().createWriteStream(); + (*stream) << (quint8)flags; + WritePadding(3, *stream); + (*stream) << (float)this->width; + (*stream) << (float)this->height; + delete stream; + + // write txl1 + file.sections.append(LYTBinaryFileSection(Magic('txl1'))); + stream = file.sections.last().createWriteStream(); + WriteStringList(*stream, this->m_textureRefs); + delete stream; + + // write fnl1 + file.sections.append(LYTBinaryFileSection(Magic('fnl1'))); + stream = file.sections.last().createWriteStream(); + WriteStringList(*stream, this->m_fontRefs); + delete stream; + + // write mat1 + file.sections.append(LYTBinaryFileSection(Magic('mat1'))); + this->writeMat1(file.sections.last()); + + // next up: write the pane tree + this->writePane(file, this->rootPane); + + // now write groups + this->writeGroups(file); + + // and we're done! + return file.pack(); +} + + + +QStringList LYTLayout::generateTextureRefs() const { + QStringList out; + + foreach (LYTMaterialContainerEntry matEntry, materials.list) { + foreach (LYTTexMap texMap, matEntry.second->texMaps) { + if (!out.contains(texMap.textureName)) + out.append(texMap.textureName); + } + } + + out.sort(); + + return out; +} + + +QStringList LYTLayout::generateFontRefs() const { + QStringList out; + + this->rootPane->addFontRefsToList(out); + + out.sort(); + + return out; +} + + + +void LYTLayout::writeMat1(LYTBinaryFileSection §ion) const { + QDataStream *stream = section.createWriteStream(); + + (*stream) << (quint16)this->materials.count(); + WritePadding(2, *stream); + + // now, assign space for the mat1 offsets, we'll set them later + qint64 matOffsetPos = stream->device()->pos(); + + WritePadding(4 * this->materials.count(), *stream); + QVector materialOffsets(this->materials.count()); + + // write them + for (int i = 0; i < this->materials.count(); i++) { + // add 8 to the offset to account for nw4r::ut::BinaryBlockHeader + materialOffsets[i] = stream->device()->pos() + 8; + this->materials.getMaterialByIndex(i)->writeToDataStream(*stream); + + // pad it if needed + qint64 checkPadding = stream->device()->pos(); + int padding = AlignUp(checkPadding, 4) - checkPadding; + WritePadding(padding, *stream); + } + + // and now write the offsets + qint64 endMatPos = stream->device()->pos(); + stream->device()->seek(matOffsetPos); + + for (int i = 0; i < materialOffsets.count(); i++) { + (*stream) << (quint32)materialOffsets[i]; + } + + stream->device()->seek(endMatPos); + + delete stream; +} + + +void LYTLayout::writePane(LYTBinaryFile &file, LYTPane *pane) const { + file.sections.append(LYTBinaryFileSection(pane->magic())); + + QDataStream *stream = file.sections.last().createWriteStream(); + pane->writeToDataStream(*stream); + delete stream; + + + if (!pane->children.isEmpty()) { + file.sections.append(LYTBinaryFileSection(Magic('pas1'))); + + foreach (LYTPane *p, pane->children) { + this->writePane(file, p); + } + + file.sections.append(LYTBinaryFileSection(Magic('pae1'))); + } +} + + +void LYTLayout::writeGroups(LYTBinaryFile &file) const { + QDataStream *stream; + + // first, write a dummy group for the root + file.sections.append(LYTBinaryFileSection(Magic('grp1'))); + stream = file.sections.last().createWriteStream(); + + WriteFixedLengthASCII(*stream, "RootGroup", 0x10); + WritePadding(4, *stream); + + delete stream; + + // now write the children + if (!this->groups.isEmpty()) { + file.sections.append(LYTBinaryFileSection(Magic('grs1'))); + + foreach (LYTGroup *p, this->groups) { + file.sections.append(LYTBinaryFileSection(Magic('grp1'))); + + stream = file.sections.last().createWriteStream(); + p->writeToDataStream(*stream); + delete stream; + } + + file.sections.append(LYTBinaryFileSection('gre1')); + } +} diff --git a/lyt/layout.h b/lyt/layout.h index 88e62dd..092be44 100644 --- a/lyt/layout.h +++ b/lyt/layout.h @@ -20,6 +20,7 @@ #include "packagebase.h" #include "materials/material.h" +#include "materials/materialcontainer.h" #include "group.h" #include "pane.h" #include "textbox.h" @@ -44,10 +45,14 @@ public: void clear(); LYTPackageBase &package() const; + QByteArray pack(); + + quint8 flags; + float width; float height; - QMap materials; + LYTMaterialContainer materials; LYTPane *rootPane; QList groups; @@ -72,6 +77,13 @@ protected: LYTPane *createPaneObj(LYTBinaryFileSection §ion); + QStringList generateTextureRefs() const; + QStringList generateFontRefs() const; + + void writeMat1(LYTBinaryFileSection §ion) const; + void writePane(LYTBinaryFile &file, LYTPane *pane) const; + void writeGroups(LYTBinaryFile &file) const; + friend class LYTPane; friend class LYTTextBox; friend class LYTPicture; diff --git a/lyt/materials/alphacompare.cpp b/lyt/materials/alphacompare.cpp index a0e2f0f..85a9952 100644 --- a/lyt/materials/alphacompare.cpp +++ b/lyt/materials/alphacompare.cpp @@ -21,7 +21,7 @@ LYTAlphaCompare::LYTAlphaCompare() { } -void LYTAlphaCompare::dumpToDebug() { +void LYTAlphaCompare::dumpToDebug() const { qDebug() << "LYTAlphaCompare @" << (void*)this; qDebug() << "Comp0:" << comp0 << "- Ref0:" << ref0; qDebug() << "Comp1:" << comp1 << "- Ref1:" << ref1; @@ -29,7 +29,7 @@ void LYTAlphaCompare::dumpToDebug() { } -void LYTAlphaCompare::writeToDataStream(QDataStream &out) { +void LYTAlphaCompare::writeToDataStream(QDataStream &out) const { out << (quint8)(comp0 | (comp1 << 4)); out << (quint8)op; out << (quint8)ref0; diff --git a/lyt/materials/alphacompare.h b/lyt/materials/alphacompare.h index 0287252..4cc0861 100644 --- a/lyt/materials/alphacompare.h +++ b/lyt/materials/alphacompare.h @@ -25,10 +25,10 @@ class LYTAlphaCompare { public: LYTAlphaCompare(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; quint8 comp0; quint8 ref0; diff --git a/lyt/materials/blendmode.cpp b/lyt/materials/blendmode.cpp index d02cd9b..bcbc234 100644 --- a/lyt/materials/blendmode.cpp +++ b/lyt/materials/blendmode.cpp @@ -21,14 +21,14 @@ LYTBlendMode::LYTBlendMode() { } -void LYTBlendMode::dumpToDebug() { +void LYTBlendMode::dumpToDebug() const { qDebug() << "LYTBlendMode @" << (void*)this; qDebug() << "srcFactor:" << srcFactor << "- destFactor:" << destFactor; qDebug() << "op:" << op << "- type:" << type; } -void LYTBlendMode::writeToDataStream(QDataStream &out) { +void LYTBlendMode::writeToDataStream(QDataStream &out) const { out << (quint8)type; out << (quint8)srcFactor; out << (quint8)destFactor; diff --git a/lyt/materials/blendmode.h b/lyt/materials/blendmode.h index 5f5847f..71d8cc0 100644 --- a/lyt/materials/blendmode.h +++ b/lyt/materials/blendmode.h @@ -25,10 +25,10 @@ class LYTBlendMode { public: LYTBlendMode(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; quint8 type; quint8 srcFactor; diff --git a/lyt/materials/chanctrl.cpp b/lyt/materials/chanctrl.cpp index 5f32e65..1e3f4f8 100644 --- a/lyt/materials/chanctrl.cpp +++ b/lyt/materials/chanctrl.cpp @@ -21,16 +21,16 @@ LYTChanCtrl::LYTChanCtrl() { } -void LYTChanCtrl::dumpToDebug() { +void LYTChanCtrl::dumpToDebug() const { qDebug() << "LYTChanCtrl @" << (void*)this; qDebug() << "ColourMatSrc:" << colourMatSrc << "- AlphaMatSrc:" << alphaMatSrc; } -void LYTChanCtrl::writeToDataStream(QDataStream &out) { +void LYTChanCtrl::writeToDataStream(QDataStream &out) const { out << (quint8)colourMatSrc; out << (quint8)alphaMatSrc; - out.skipRawData(2); // padding + WritePadding(2, out); } diff --git a/lyt/materials/chanctrl.h b/lyt/materials/chanctrl.h index f0183e1..2224837 100644 --- a/lyt/materials/chanctrl.h +++ b/lyt/materials/chanctrl.h @@ -25,10 +25,10 @@ class LYTChanCtrl { public: LYTChanCtrl(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; quint8 colourMatSrc; quint8 alphaMatSrc; diff --git a/lyt/materials/indirectstage.cpp b/lyt/materials/indirectstage.cpp index c1e6d87..362fcaf 100644 --- a/lyt/materials/indirectstage.cpp +++ b/lyt/materials/indirectstage.cpp @@ -21,14 +21,14 @@ LYTIndirectStage::LYTIndirectStage() { } -void LYTIndirectStage::dumpToDebug() { +void LYTIndirectStage::dumpToDebug() const { qDebug() << "LYTIndirectStage @" << (void*)this; qDebug() << "texCoord:" << this->texCoord << "- texMap:" << this->texMap; qDebug() << "wrap_s:" << this->wrap_s << "- wrap_t:" << this->wrap_t; } -void LYTIndirectStage::writeToDataStream(QDataStream &out) { +void LYTIndirectStage::writeToDataStream(QDataStream &out) const { out << (quint8)texCoord; out << (quint8)texMap; out << (quint8)wrap_s; diff --git a/lyt/materials/indirectstage.h b/lyt/materials/indirectstage.h index 8f381bf..c00b091 100644 --- a/lyt/materials/indirectstage.h +++ b/lyt/materials/indirectstage.h @@ -25,10 +25,10 @@ class LYTIndirectStage { public: LYTIndirectStage(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; quint8 texCoord; quint8 texMap; diff --git a/lyt/materials/material.cpp b/lyt/materials/material.cpp index a4498c5..a775553 100644 --- a/lyt/materials/material.cpp +++ b/lyt/materials/material.cpp @@ -29,7 +29,7 @@ LYTLayout &LYTMaterial::layout() const { } -void LYTMaterial::dumpToDebug() { +void LYTMaterial::dumpToDebug() const { qDebug() << "LYTMaterial" << name << "@" << (void*)this; for (int i = 0; i < 3; i++) @@ -90,8 +90,86 @@ void LYTMaterial::dumpToDebug() { -void LYTMaterial::writeToDataStream(QDataStream &out) { +void LYTMaterial::writeToDataStream(QDataStream &out) const { WriteFixedLengthASCII(out, name, 0x14); + + for (int i = 0; i < 3; i++) + WriteS10Color(this->colours[i], out); + + for (int i = 0; i < 4; i++) + WriteRGBA8Color(this->tevKColour[i], out); + + + LYTMaterialResourceNum resourceNum; + resourceNum.setTexMapNum(texMaps.count()); + resourceNum.setTexSRTNum(texSRTs.count()); + resourceNum.setTexCoordGenNum(texCoordGens.count()); + resourceNum.setHasChanCtrl(hasChanCtrl); + resourceNum.setHasMatCol(hasMatCol); + resourceNum.setHasTevSwapTable(hasTevSwapTable); + resourceNum.setIndTexSRTNum(indTexSRTs.count()); + resourceNum.setIndTexStageNum(indTexStages.count()); + resourceNum.setTevStageNum(tevStages.count()); + resourceNum.setHasAlphaCompare(hasAlphaCompare); + resourceNum.setHasBlendMode(hasBlendMode); + out << (quint32)resourceNum.value(); + + + // TexMap + for (int i = 0; i < texMaps.count(); i++) { + texMaps.at(i).writeToDataStream(out, this->m_layout); + } + + // TexSRT + for (int i = 0; i < texSRTs.count(); i++) { + texSRTs.at(i).writeToDataStream(out); + } + + // TexCoordGen + for (int i = 0; i < texCoordGens.count(); i++) { + texCoordGens.at(i).writeToDataStream(out); + } + + // ChanCtrl + if (hasChanCtrl) { + chanCtrl.writeToDataStream(out); + } + + // MatCol + if (hasMatCol) { + WriteRGBA8Color(this->matCol, out); + } + + // TevSwapTable + if (hasTevSwapTable) { + tevSwapTable.writeToDataStream(out); + } + + // IndTexSRT + for (int i = 0; i < indTexSRTs.count(); i++) { + indTexSRTs.at(i).writeToDataStream(out); + } + + // IndTexStage + for (int i = 0; i < indTexStages.count(); i++) { + indTexStages.at(i).writeToDataStream(out); + } + + // TevStage + for (int i = 0; i < tevStages.count(); i++) { + tevStages.at(i).writeToDataStream(out); + } + + // AlphaCompare + if (hasAlphaCompare) { + alphaCompare.writeToDataStream(out); + } + + // BlendMode + if (hasBlendMode) { + blendMode.writeToDataStream(out); + } + } void LYTMaterial::readFromDataStream(QDataStream &in) { diff --git a/lyt/materials/material.h b/lyt/materials/material.h index d605244..a42a9d8 100644 --- a/lyt/materials/material.h +++ b/lyt/materials/material.h @@ -43,19 +43,19 @@ public: LYTMaterialResourceNum() : m_value(0) { } LYTMaterialResourceNum(int initValue) : m_value(initValue) { } - quint32 value() { return m_value; } - - int getTexMapNum() { return BitExtract(m_value, 4, 28); } - int getTexSRTNum() { return BitExtract(m_value, 4, 24); } - int getTexCoordGenNum() { return BitExtract(m_value, 4, 20); } - bool hasChanCtrl() { return BitExtract(m_value, 1, 6); } - bool hasMatCol() { return BitExtract(m_value, 1, 4); } - bool hasTevSwapTable() { return BitExtract(m_value, 1, 19); } - bool hasAlphaCompare() { return BitExtract(m_value, 1, 8); } - bool hasBlendMode() { return BitExtract(m_value, 1, 7); } - int getIndTexSRTNum() { return BitExtract(m_value, 2, 17); } - int getIndTexStageNum() { return BitExtract(m_value, 3, 14); } - int getTevStageNum() { return BitExtract(m_value, 5, 9); } + quint32 value() const { return m_value; } + + int getTexMapNum() const { return BitExtract(m_value, 4, 28); } + int getTexSRTNum() const { return BitExtract(m_value, 4, 24); } + int getTexCoordGenNum() const { return BitExtract(m_value, 4, 20); } + bool hasChanCtrl() const { return BitExtract(m_value, 1, 6); } + bool hasMatCol() const { return BitExtract(m_value, 1, 4); } + bool hasTevSwapTable() const { return BitExtract(m_value, 1, 19); } + bool hasAlphaCompare() const { return BitExtract(m_value, 1, 8); } + bool hasBlendMode() const { return BitExtract(m_value, 1, 7); } + int getIndTexSRTNum() const { return BitExtract(m_value, 2, 17); } + int getIndTexStageNum() const { return BitExtract(m_value, 3, 14); } + int getTevStageNum() const { return BitExtract(m_value, 5, 9); } void setTexMapNum(int v) { m_value = BitInsert(m_value, v, 4, 28); } void setTexSRTNum(int v) { m_value = BitInsert(m_value, v, 4, 24); } @@ -83,10 +83,10 @@ public: ~LYTMaterial(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; LYTLayout &layout() const; diff --git a/lyt/materials/materialcontainer.h b/lyt/materials/materialcontainer.h new file mode 100644 index 0000000..4787bfc --- /dev/null +++ b/lyt/materials/materialcontainer.h @@ -0,0 +1,76 @@ +/******************************************************************************* + This file is part of LayoutStudio (http://github.com/Treeki/LayoutStudio) + Copyright (c) 2010 Treeki (treeki@gmail.com) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2.0. + + This program 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 2.0 for more details. + + You should have received a copy of the GNU General Public License 2.0 + along with this program. If not, see . +*******************************************************************************/ + +#ifndef LYTMATERIALCONTAINER_H +#define LYTMATERIALCONTAINER_H + +#include +#include +#include "material.h" + +typedef QPair LYTMaterialContainerEntry; + +class LYTMaterialContainer { +public: + LYTMaterialContainer() { }; + + QList list; + + + void addMaterial(QString name, LYTMaterial *material) { + LYTMaterialContainerEntry entry; + entry.first = name; + entry.second = material; + this->list.append(entry); + } + + void clear() { this->list.clear(); } + int count() const { return this->list.count(); } + + + LYTMaterial *getMaterialByName(QString name) const { + foreach (LYTMaterialContainerEntry entry, this->list) { + if (entry.first == name) + return entry.second; + } + + return 0; + } + + LYTMaterial *getMaterialByIndex(int index) const { + return this->list.at(index).second; + } + + int getIndexOfName(QString name) const { + int i = 0; + + foreach (LYTMaterialContainerEntry entry, this->list) { + if (entry.first == name) + return i; + i += 1; + } + + return -1; + } + + + QString getNameOfIndex(int index) const { + return this->list.at(index).first; + } +}; + +#endif // LYTMATERIALCONTAINER_H diff --git a/lyt/materials/tevstage.cpp b/lyt/materials/tevstage.cpp index 7244e4e..768e252 100644 --- a/lyt/materials/tevstage.cpp +++ b/lyt/materials/tevstage.cpp @@ -21,7 +21,7 @@ LYTTevStage::LYTTevStage() { } -void LYTTevStage::dumpToDebug() { +void LYTTevStage::dumpToDebug() const { qDebug() << "LYTTevStage @" << (void*)this; qDebug() << "TEV order: texCoord" << texCoord << ", colour" << colour << ", texMap" << texMap; qDebug() << "SwapMode: ras" << rasSwapMode << ", tex" << texSwapMode; @@ -43,13 +43,13 @@ void LYTTevStage::dumpToDebug() { } -void LYTTevStage::writeToDataStream(QDataStream &out) { +void LYTTevStage::writeToDataStream(QDataStream &out) const { char data[0x10]; qMemSet(data, 0, 0x10); // TEV order: data[0] = texCoord; - colour = data[1]; + data[1] = colour; data[2] = texMap & 0xFF; data[3] = BitInsert(data[3], texMap >> 8, 1, 32 - 1); diff --git a/lyt/materials/tevstage.h b/lyt/materials/tevstage.h index 6132800..d052d9a 100644 --- a/lyt/materials/tevstage.h +++ b/lyt/materials/tevstage.h @@ -25,10 +25,10 @@ class LYTTevStage { public: LYTTevStage(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; // TEV order: int texCoord; diff --git a/lyt/materials/tevswaptable.cpp b/lyt/materials/tevswaptable.cpp index 05ed497..a13a491 100644 --- a/lyt/materials/tevswaptable.cpp +++ b/lyt/materials/tevswaptable.cpp @@ -21,18 +21,18 @@ LYTTevSwapTable::LYTTevSwapTable() { } -void LYTTevSwapTable::dumpToDebug() { +void LYTTevSwapTable::dumpToDebug() const { qDebug() << "LYTTevSwapTable @" << (void*)this; for (int i = 0; i < 4; i++) { - LYTTevSwapMode *m = &mode[i]; + const LYTTevSwapMode *m = &mode[i]; qDebug() << i << ":" << m->red << "," << m->green << "," << m->blue << "," << m->alpha; } } -void LYTTevSwapTable::writeToDataStream(QDataStream &out) { +void LYTTevSwapTable::writeToDataStream(QDataStream &out) const { for (int i = 0; i < 4; i++) { quint8 val = 0; val |= mode[i].red; diff --git a/lyt/materials/tevswaptable.h b/lyt/materials/tevswaptable.h index a73facf..608df45 100644 --- a/lyt/materials/tevswaptable.h +++ b/lyt/materials/tevswaptable.h @@ -32,10 +32,10 @@ class LYTTevSwapTable { public: LYTTevSwapTable(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; LYTTevSwapMode mode[4]; }; diff --git a/lyt/materials/texcoordgen.cpp b/lyt/materials/texcoordgen.cpp index 3d2ac75..91bdad9 100644 --- a/lyt/materials/texcoordgen.cpp +++ b/lyt/materials/texcoordgen.cpp @@ -21,17 +21,17 @@ LYTTexCoordGen::LYTTexCoordGen() { } -void LYTTexCoordGen::dumpToDebug() { +void LYTTexCoordGen::dumpToDebug() const { qDebug() << "LYTTexCoordGen @" << (void*)this; qDebug() << "GenType:" << genType << "- Mtx:" << mtx << "- Src:" << src; } -void LYTTexCoordGen::writeToDataStream(QDataStream &out) { +void LYTTexCoordGen::writeToDataStream(QDataStream &out) const { out << (quint8)genType; out << (quint8)src; out << (quint8)mtx; - out.skipRawData(1); // padding + WritePadding(1, out); } diff --git a/lyt/materials/texcoordgen.h b/lyt/materials/texcoordgen.h index f65750c..5756b70 100644 --- a/lyt/materials/texcoordgen.h +++ b/lyt/materials/texcoordgen.h @@ -25,10 +25,10 @@ class LYTTexCoordGen { public: LYTTexCoordGen(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; quint8 genType; quint8 src; diff --git a/lyt/materials/texmap.cpp b/lyt/materials/texmap.cpp index 74fb7a9..4991139 100644 --- a/lyt/materials/texmap.cpp +++ b/lyt/materials/texmap.cpp @@ -21,14 +21,14 @@ LYTTexMap::LYTTexMap() { } -void LYTTexMap::dumpToDebug() { +void LYTTexMap::dumpToDebug() const { qDebug() << "LYTTexMap @" << (void*)this << ":" << textureName; qDebug() << "- wrap_s:" << wrap_s << "- wrap_t:" << wrap_t; qDebug() << "- mag_filter:" << mag_filter << "- min_filter:" << min_filter; } -void LYTTexMap::writeToDataStream(QDataStream &out, LYTLayout &layout) { +void LYTTexMap::writeToDataStream(QDataStream &out, LYTLayout &layout) const { quint16 texNum = layout.m_textureRefs.indexOf(textureName); out << (quint16)texNum; diff --git a/lyt/materials/texmap.h b/lyt/materials/texmap.h index e630a39..1200080 100644 --- a/lyt/materials/texmap.h +++ b/lyt/materials/texmap.h @@ -27,10 +27,10 @@ class LYTTexMap { public: LYTTexMap(); - void writeToDataStream(QDataStream &out, LYTLayout &layout); + void writeToDataStream(QDataStream &out, LYTLayout &layout) const; void readFromDataStream(QDataStream &in, LYTLayout &layout); - void dumpToDebug(); + void dumpToDebug() const; QString textureName; int wrap_s; diff --git a/lyt/materials/texsrt.cpp b/lyt/materials/texsrt.cpp index 7ffc83e..55ddb9c 100644 --- a/lyt/materials/texsrt.cpp +++ b/lyt/materials/texsrt.cpp @@ -21,7 +21,7 @@ LYTTexSRT::LYTTexSRT() { } -void LYTTexSRT::dumpToDebug() { +void LYTTexSRT::dumpToDebug() const { qDebug() << "LYTTexSRT @" << (void*)this; qDebug() << "Scale:" << xScale << "," << yScale; qDebug() << "Rotation:" << rotate; @@ -29,7 +29,7 @@ void LYTTexSRT::dumpToDebug() { } -void LYTTexSRT::writeToDataStream(QDataStream &out) { +void LYTTexSRT::writeToDataStream(QDataStream &out) const { out << (float)xTrans; out << (float)yTrans; out << (float)rotate; diff --git a/lyt/materials/texsrt.h b/lyt/materials/texsrt.h index 6bcee02..8841c18 100644 --- a/lyt/materials/texsrt.h +++ b/lyt/materials/texsrt.h @@ -25,10 +25,10 @@ class LYTTexSRT { public: LYTTexSRT(); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; float xTrans; float yTrans; diff --git a/lyt/packagebase.h b/lyt/packagebase.h index 9ad45c0..6129e0b 100644 --- a/lyt/packagebase.h +++ b/lyt/packagebase.h @@ -27,15 +27,15 @@ public: LYTPackageBase(); virtual ~LYTPackageBase(); - virtual QStringList listAnims() = 0; - virtual QStringList listLayouts() = 0; - virtual QStringList listTextures() = 0; - virtual QStringList listFonts() = 0; + virtual QStringList listAnims() const = 0; + virtual QStringList listLayouts() const = 0; + virtual QStringList listTextures() const = 0; + virtual QStringList listFonts() const = 0; - virtual QByteArray getAnim(QString name) = 0; - virtual QByteArray getLayout(QString name) = 0; - virtual QByteArray getTexture(QString name) = 0; - virtual QByteArray getFont(QString name) = 0; + virtual QByteArray getAnim(QString name) const = 0; + virtual QByteArray getLayout(QString name) const = 0; + virtual QByteArray getTexture(QString name) const = 0; + virtual QByteArray getFont(QString name) const = 0; virtual bool writeAnim(QString name, QByteArray data) = 0; virtual bool writeLayout(QString name, QByteArray data) = 0; @@ -43,7 +43,7 @@ public: virtual bool writeFont(QString name, QByteArray data) = 0; virtual bool savePackage() = 0; - virtual QString description() = 0; + virtual QString description() const = 0; }; #endif // LYTPACKAGEBASE_H diff --git a/lyt/pane.cpp b/lyt/pane.cpp index bcba81b..7ae768a 100644 --- a/lyt/pane.cpp +++ b/lyt/pane.cpp @@ -27,7 +27,7 @@ LYTPane::~LYTPane() { delete ptr; } -LYTPane *LYTPane::findPaneByName(QString name, bool recursive) { +LYTPane *LYTPane::findPaneByName(QString name, bool recursive) const { foreach (LYTPane *pane, this->children) { if (pane->name == name) return pane; @@ -47,7 +47,11 @@ LYTLayout &LYTPane::layout() const { } -void LYTPane::dumpToDebug(bool showHeading) { +Magic LYTPane::magic() const { + return Magic('pan1'); +} + +void LYTPane::dumpToDebug(bool showHeading) const { if (showHeading) qDebug() << "LYTPane" << name << "@" << (void*)this; @@ -61,11 +65,11 @@ void LYTPane::dumpToDebug(bool showHeading) { -void LYTPane::writeToDataStream(QDataStream &out) { +void LYTPane::writeToDataStream(QDataStream &out) const { out << (quint8)flags; out << (quint8)origin; out << (quint8)alpha; - out.skipRawData(1); // padding + WritePadding(1, out); WriteFixedLengthASCII(out, name, 0x10); WriteFixedLengthASCII(out, userdata, 8); @@ -102,3 +106,12 @@ void LYTPane::readFromDataStream(QDataStream &in) { in >> (float&)width; in >> (float&)height; } + + +void LYTPane::addFontRefsToList(QStringList &list) const { + //qDebug() << "Getting font refs for" << this->name; + + foreach (LYTPane *p, this->children) { + p->addFontRefsToList(list); + } +} diff --git a/lyt/pane.h b/lyt/pane.h index a2c751b..8b80029 100644 --- a/lyt/pane.h +++ b/lyt/pane.h @@ -33,12 +33,16 @@ public: virtual ~LYTPane(); - virtual void writeToDataStream(QDataStream &out); + virtual Magic magic() const; + + virtual void writeToDataStream(QDataStream &out) const; virtual void readFromDataStream(QDataStream &in); - virtual void dumpToDebug(bool showHeading=true); + virtual void dumpToDebug(bool showHeading=true) const; + + virtual void addFontRefsToList(QStringList &list) const; - LYTPane *findPaneByName(QString name, bool recursive); + LYTPane *findPaneByName(QString name, bool recursive) const; LYTLayout &layout() const; diff --git a/lyt/picture.cpp b/lyt/picture.cpp index f00027b..8cd5f1f 100644 --- a/lyt/picture.cpp +++ b/lyt/picture.cpp @@ -24,7 +24,12 @@ LYTPicture::LYTPicture(LYTLayout &layout) : LYTPane(layout) { } -void LYTPicture::dumpToDebug(bool showHeading) { +Magic LYTPicture::magic() const { + return Magic('pic1'); +} + + +void LYTPicture::dumpToDebug(bool showHeading) const { if (showHeading) qDebug() << "LYTPicture" << name << "@" << (void*)this; @@ -43,19 +48,19 @@ void LYTPicture::dumpToDebug(bool showHeading) { -void LYTPicture::writeToDataStream(QDataStream &out) { +void LYTPicture::writeToDataStream(QDataStream &out) const { LYTPane::writeToDataStream(out); for (int i = 0; i < 4; i++) WriteRGBA8Color(vtxColours[i], out); // calculate the material number - int materialNum = m_layout.materials.keys().indexOf(materialName); + int materialNum = m_layout.materials.getIndexOfName(materialName); out << (quint16)materialNum; // write texcoords out << (quint8)texCoords.count(); - out.skipRawData(1); // padding + WritePadding(1, out); foreach (LYTTexCoords texCoord, texCoords) { for (int i = 0; i < 4; i++) @@ -74,7 +79,7 @@ void LYTPicture::readFromDataStream(QDataStream &in) { quint16 materialNum; in >> (quint16&)materialNum; - materialName = m_layout.materials.keys().at(materialNum); + materialName = m_layout.materials.getNameOfIndex(materialNum); // read texcoords quint8 texCoordNum; @@ -83,8 +88,8 @@ void LYTPicture::readFromDataStream(QDataStream &in) { texCoords.resize(texCoordNum); - foreach (LYTTexCoords texCoord, texCoords) { - for (int i = 0; i < 4; i++) - ReadPointF(in, texCoord.coord[i]); + for (int i = 0; i < texCoordNum; i++) { + for (int j = 0; j < 4; j++) + ReadPointF(in, texCoords[i].coord[j]); } } diff --git a/lyt/picture.h b/lyt/picture.h index 3c73708..fbb3cf4 100644 --- a/lyt/picture.h +++ b/lyt/picture.h @@ -29,10 +29,12 @@ public: LYTPicture(LYTLayout &layout); - void writeToDataStream(QDataStream &out); + Magic magic() const; + + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(bool showHeading=true); + void dumpToDebug(bool showHeading=true) const; QColor vtxColours[4]; QString materialName; diff --git a/lyt/textbox.cpp b/lyt/textbox.cpp index 8552c3d..e1b640e 100644 --- a/lyt/textbox.cpp +++ b/lyt/textbox.cpp @@ -24,7 +24,12 @@ LYTTextBox::LYTTextBox(LYTLayout &layout) : LYTPane(layout) { } -void LYTTextBox::dumpToDebug(bool showHeading) { +Magic LYTTextBox::magic() const { + return Magic('txt1'); +} + + +void LYTTextBox::dumpToDebug(bool showHeading) const { if (showHeading) qDebug() << "LYTTextBox" << name << "@" << (void*)this; @@ -41,7 +46,7 @@ void LYTTextBox::dumpToDebug(bool showHeading) { -void LYTTextBox::writeToDataStream(QDataStream &out) { +void LYTTextBox::writeToDataStream(QDataStream &out) const { LYTPane::writeToDataStream(out); // lengths are stored in bytes (including zero terminator) not characters @@ -49,7 +54,7 @@ void LYTTextBox::writeToDataStream(QDataStream &out) { out << (quint16)((text.length() + 1) * 2); // calculate the material and font numbers - int materialNum = m_layout.materials.keys().indexOf(materialName); + int materialNum = m_layout.materials.getIndexOfName(materialName); int fontNum = m_layout.m_fontRefs.indexOf(fontName); out << (quint16)materialNum; @@ -58,7 +63,7 @@ void LYTTextBox::writeToDataStream(QDataStream &out) { out << (quint8)alignment; out << (quint8)alignmentOverride; - out.skipRawData(2); // padding + WritePadding(2, out); out << (quint32)0x74; // fixed offset to textbox contents @@ -74,6 +79,8 @@ void LYTTextBox::writeToDataStream(QDataStream &out) { const ushort *convertedText = text.utf16(); for (int i = 0; i < text.length(); i++) out << (quint16)convertedText[i]; + + out << (quint16)0; // zeroterm } @@ -99,7 +106,7 @@ void LYTTextBox::readFromDataStream(QDataStream &in) { in >> (quint16&)materialNum; in >> (quint16&)fontNum; - materialName = m_layout.materials.keys().at(materialNum); + materialName = m_layout.materials.getNameOfIndex(materialNum); fontName = m_layout.m_fontRefs.at(fontNum); in >> (quint8&)alignment; @@ -130,3 +137,12 @@ void LYTTextBox::readFromDataStream(QDataStream &in) { text.setUtf16(rawText, stringLength); delete[] rawText; } + + +void LYTTextBox::addFontRefsToList(QStringList &list) const { + LYTPane::addFontRefsToList(list); + + if (!list.contains(this->fontName)) { + list.append(this->fontName); + } +} diff --git a/lyt/textbox.h b/lyt/textbox.h index 9a12e18..c61ef3a 100644 --- a/lyt/textbox.h +++ b/lyt/textbox.h @@ -27,10 +27,14 @@ public: LYTTextBox(LYTLayout &layout); - void writeToDataStream(QDataStream &out); + Magic magic() const; + + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(bool showHeading=true); + void dumpToDebug(bool showHeading=true) const; + + void addFontRefsToList(QStringList &list) const; quint16 bufferLength; QString text; diff --git a/lyt/window.cpp b/lyt/window.cpp index cc26491..52d2db9 100644 --- a/lyt/window.cpp +++ b/lyt/window.cpp @@ -23,13 +23,13 @@ LYTWindowFrame::LYTWindowFrame(LYTWindow &window) : m_window(window) { } -void LYTWindowFrame::writeToDataStream(QDataStream &out) { +void LYTWindowFrame::writeToDataStream(QDataStream &out) const { // calculate the material number - int materialNum = m_window.m_layout.materials.keys().indexOf(materialName); + int materialNum = m_window.m_layout.materials.getIndexOfName(materialName); out << (quint16)materialNum; out << (quint8)type; - out.skipRawData(1); // padding + WritePadding(1, out); } void LYTWindowFrame::readFromDataStream(QDataStream &in) { @@ -37,13 +37,13 @@ void LYTWindowFrame::readFromDataStream(QDataStream &in) { quint16 materialNum; in >> (quint16&)materialNum; - materialName = m_window.m_layout.materials.keys().at(materialNum); + materialName = m_window.m_layout.materials.getNameOfIndex(materialNum); in >> (quint8&)type; in.skipRawData(1); // padding } -void LYTWindowFrame::dumpToDebug() { +void LYTWindowFrame::dumpToDebug() const { qDebug() << "LYTWindowFrame @" << (void*)this << "- type:" << type << "- material:" << materialName; } @@ -59,9 +59,12 @@ LYTWindow::~LYTWindow() { -// all of this needs to be done +Magic LYTWindow::magic() const { + return Magic('wnd1'); +} + -void LYTWindow::dumpToDebug(bool showHeading) { +void LYTWindow::dumpToDebug(bool showHeading) const { if (showHeading) qDebug() << "LYTWindow" << name << "@" << (void*)this; @@ -88,7 +91,7 @@ void LYTWindow::dumpToDebug(bool showHeading) { -void LYTWindow::writeToDataStream(QDataStream &out) { +void LYTWindow::writeToDataStream(QDataStream &out) const { LYTPane::writeToDataStream(out); out << (float)contentOverflowLeft; @@ -97,7 +100,7 @@ void LYTWindow::writeToDataStream(QDataStream &out) { out << (float)contentOverflowBottom; out << (quint8)frames.count(); - out.skipRawData(3); // padding + WritePadding(3, out); out << (quint32)0x68; // offset to content struct out << (quint32)(0x7C + (contentTexCoords.count()*0x20)); // offset to frame offset list @@ -106,12 +109,12 @@ void LYTWindow::writeToDataStream(QDataStream &out) { WriteRGBA8Color(contentVtxColours[i], out); // calculate the material number - int materialNum = m_layout.materials.keys().indexOf(contentMaterialName); + int materialNum = m_layout.materials.getIndexOfName(contentMaterialName); out << (quint16)materialNum; // write texcoords out << (quint8)contentTexCoords.count(); - out.skipRawData(1); // padding + WritePadding(1, out); foreach (LYTTexCoords texCoord, contentTexCoords) { for (int i = 0; i < 4; i++) @@ -165,7 +168,7 @@ void LYTWindow::readFromDataStream(QDataStream &in) { quint16 materialNum; in >> (quint16&)materialNum; - contentMaterialName = m_layout.materials.keys().at(materialNum); + contentMaterialName = m_layout.materials.getNameOfIndex(materialNum); // read texcoords quint8 texCoordNum; @@ -174,9 +177,9 @@ void LYTWindow::readFromDataStream(QDataStream &in) { contentTexCoords.resize(texCoordNum); - foreach (LYTTexCoords texCoord, contentTexCoords) { - for (int i = 0; i < 4; i++) - ReadPointF(in, texCoord.coord[i]); + for (int i = 0; i < texCoordNum; i++) { + for (int j = 0; j < 4; j++) + ReadPointF(in, contentTexCoords[i].coord[j]); } // read frame offset list diff --git a/lyt/window.h b/lyt/window.h index a37e2cb..062167f 100644 --- a/lyt/window.h +++ b/lyt/window.h @@ -32,10 +32,10 @@ public: LYTWindowFrame(LYTWindow &window); - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(); + void dumpToDebug() const; quint8 type; // 0-5; controls texture flipping; must investigate this more QString materialName; @@ -51,10 +51,12 @@ public: ~LYTWindow(); - void writeToDataStream(QDataStream &out); + Magic magic() const; + + void writeToDataStream(QDataStream &out) const; void readFromDataStream(QDataStream &in); - void dumpToDebug(bool showHeading=true); + void dumpToDebug(bool showHeading=true) const; float contentOverflowLeft; @@ -70,7 +72,7 @@ public: protected: - void writeContentInfo(QDataStream &out); + void writeContentInfo(QDataStream &out) const; void readContentInfo(QDataStream &in); friend class LYTWindowFrame; diff --git a/main.cpp b/main.cpp index b830731..795386c 100644 --- a/main.cpp +++ b/main.cpp @@ -40,7 +40,13 @@ int main(int argc, char *argv[]) { LYTArchivePackage package("H:\\ISOs\\NSMBWii\\Extracted\\Layout\\continue\\continue.arc"); LYTLayout layout(package, "continue_05.brlyt"); - package.savePackage(); + QByteArray brlyt = layout.pack(); + QFile file("H:\\ISOs\\NSMBWii\\Extracted\\Layout\\continue\\continue\\arc\\blyt\\continue_05_repack.brlyt"); + file.open(QFile::WriteOnly); + file.write(brlyt); + file.close(); + //package.writeLayout("continue_05.brlyt", brlyt); + //package.savePackage(); //LYTDirectoryPackage package("H:\\ISOs\\NSMBWii\\Extracted\\Layout\\continue\\continue\\arc"); diff --git a/wii/archiveu8.cpp b/wii/archiveu8.cpp index 5e0ad5d..d27dfde 100644 --- a/wii/archiveu8.cpp +++ b/wii/archiveu8.cpp @@ -124,7 +124,7 @@ void WiiArchiveU8::readDir(QDataStream &in, WiiDirectory &dir, int lastChild, U8 -void WiiArchiveU8::writeToDataStream(QDataStream &out) { +void WiiArchiveU8::writeToDataStream(QDataStream &out) const { U8WriteInfo info; // first off, before we do anything else, create the string table @@ -179,7 +179,7 @@ void WiiArchiveU8::writeToDataStream(QDataStream &out) { } -void WiiArchiveU8::addNodeToStringTable(WiiFSObject &node, WiiStringTableBuilder &table) { +void WiiArchiveU8::addNodeToStringTable(const WiiFSObject &node, WiiStringTableBuilder &table) const { table.add(node.name); if (node.isDirectory()) { @@ -191,7 +191,7 @@ void WiiArchiveU8::addNodeToStringTable(WiiFSObject &node, WiiStringTableBuilder } -void WiiArchiveU8::countNode(WiiFSObject &node, int *countPtr) { +void WiiArchiveU8::countNode(const WiiFSObject &node, int *countPtr) const { (*countPtr)++; if (node.isDirectory()) { @@ -203,7 +203,7 @@ void WiiArchiveU8::countNode(WiiFSObject &node, int *countPtr) { } -void WiiArchiveU8::writeDir(QDataStream &out, WiiDirectory &dir, U8WriteInfo &info) { +void WiiArchiveU8::writeDir(QDataStream &out, const WiiDirectory &dir, U8WriteInfo &info) const { foreach (WiiFSObject *p, dir.children) { info.currentNode++; @@ -244,7 +244,7 @@ void WiiArchiveU8::writeDir(QDataStream &out, WiiDirectory &dir, U8WriteInfo &in } -void WiiArchiveU8::writeNodeData(QDataStream &out, WiiFSObject &node) { +void WiiArchiveU8::writeNodeData(QDataStream &out, const WiiFSObject &node) const { if (node.isDirectory()) { // write all the children's data WiiDirectory *thisDir = (WiiDirectory*)&node; diff --git a/wii/archiveu8.h b/wii/archiveu8.h index 6f54ba2..5561beb 100644 --- a/wii/archiveu8.h +++ b/wii/archiveu8.h @@ -45,17 +45,17 @@ public: WiiDirectory root; - void writeToDataStream(QDataStream &out); + void writeToDataStream(QDataStream &out) const; private: void readDir(QDataStream &in, WiiDirectory &dir, int lastChild, U8ReadInfo &info); - void addNodeToStringTable(WiiFSObject &node, WiiStringTableBuilder &table); - void countNode(WiiFSObject &node, int *countPtr); + void addNodeToStringTable(const WiiFSObject &node, WiiStringTableBuilder &table) const; + void countNode(const WiiFSObject &node, int *countPtr) const; - void writeDir(QDataStream &out, WiiDirectory &dir, U8WriteInfo &info); + void writeDir(QDataStream &out, const WiiDirectory &dir, U8WriteInfo &info) const; - void writeNodeData(QDataStream &out, WiiFSObject &node); + void writeNodeData(QDataStream &out, const WiiFSObject &node) const; }; #endif // WIIARCHIVEU8_H diff --git a/wii/common.cpp b/wii/common.cpp index f4a961c..8f552b3 100644 --- a/wii/common.cpp +++ b/wii/common.cpp @@ -17,7 +17,7 @@ #include "common.h" -QByteArray PadByteArray(QByteArray original, int newLength, char padWith) { +QByteArray PadByteArray(const QByteArray original, int newLength, char padWith) { QByteArray newArray = original; if (original.length() > newLength) { @@ -91,6 +91,30 @@ QStringList ReadStringList(QDataStream &in) { return output; } +void WriteStringList(QDataStream &out, const QStringList list) { + out << (quint16)list.count(); + WritePadding(2, out); + + // calculate offsets for every string, and write them + // offset 0 points to the first entry in the offset list, etc, so + // take that into account for the string offset calculation + quint32 currentOffset = list.count() * 8; + + foreach (QString str, list) { + out << (quint32)currentOffset; + WritePadding(4, out); // unused? + + currentOffset += str.length() + 1; + } + + // now write the strings + foreach (QString str, list) { + QByteArray rawStr = str.toAscii(); + rawStr.append('\0'); + out.writeRawData(rawStr.constData(), rawStr.length()); + } +} + QString ReadFixedLengthASCII(QDataStream &in, int length) { QByteArray readStr(length, '\0'); in.readRawData(readStr.data(), readStr.length()); @@ -102,7 +126,7 @@ QString ReadFixedLengthASCII(QDataStream &in, int length) { return str; } -void WriteFixedLengthASCII(QDataStream &out, QString str, int length) { +void WriteFixedLengthASCII(QDataStream &out, const QString str, int length) { QByteArray paddedStr = PadByteArray(str.toAscii(), length); out.writeRawData(paddedStr.constData(), paddedStr.length()); } diff --git a/wii/common.h b/wii/common.h index 34f1526..b440841 100644 --- a/wii/common.h +++ b/wii/common.h @@ -64,7 +64,7 @@ inline void ReadRGBA8Color(QColor &out, QDataStream &in) { out = RGBAToColor(col); } -inline void WriteRGBA8Color(QColor &in, QDataStream &out) { +inline void WriteRGBA8Color(const QColor in, QDataStream &out) { out << (quint32)ColorToRGBA(in); } @@ -77,7 +77,7 @@ inline void ReadS10Color(QColor &out, QDataStream &in) { out.setRgb(r, g, b, a); } -inline void WriteS10Color(QColor &in, QDataStream &out) { +inline void WriteS10Color(const QColor in, QDataStream &out) { out << (quint16)in.red(); out << (quint16)in.green(); out << (quint16)in.blue(); @@ -103,6 +103,7 @@ inline void InitDataStream(QDataStream &stream) { } QStringList ReadStringList(QDataStream &in); +void WriteStringList(QDataStream &out, QStringList list); QString ReadFixedLengthASCII(QDataStream &in, int length); void WriteFixedLengthASCII(QDataStream &out, QString str, int length); diff --git a/wii/filesystem.cpp b/wii/filesystem.cpp index 09fe207..014b693 100644 --- a/wii/filesystem.cpp +++ b/wii/filesystem.cpp @@ -38,16 +38,16 @@ void WiiFSObject::unlinkFromParent() { this->parent = 0; } -bool WiiFSObject::nameIsEqual(QString check) { +bool WiiFSObject::nameIsEqual(QString check) const { return (bool)(QString::compare(this->name, check, Qt::CaseInsensitive) == 0); } -bool WiiFSObject::isFile() { return false; } -bool WiiFSObject::isDirectory() { return false; } +bool WiiFSObject::isFile() const { return false; } +bool WiiFSObject::isDirectory() const { return false; } /******************************************************************************/ -bool WiiFile::isFile() { return true; } +bool WiiFile::isFile() const { return true; } /******************************************************************************/ @@ -56,9 +56,9 @@ WiiDirectory::~WiiDirectory() { delete ptr; } -bool WiiDirectory::isDirectory() { return true; } +bool WiiDirectory::isDirectory() const { return true; } -WiiFSObject *WiiDirectory::findByName(QString name, bool recursive) { +WiiFSObject *WiiDirectory::findByName(QString name, bool recursive) const { foreach (WiiFSObject *obj, children) { if (obj->nameIsEqual(name)) return obj; @@ -108,7 +108,7 @@ WiiFSObject *WiiDirectory::resolvePath(QString path) { if (pathComponents.isEmpty()) { // we've reached the end \o/ - return nextObj; + return (WiiFSObject *)nextObj; } // verify that this object is a directory diff --git a/wii/filesystem.h b/wii/filesystem.h index 1a7ecfa..7527a7d 100644 --- a/wii/filesystem.h +++ b/wii/filesystem.h @@ -32,10 +32,10 @@ public: void unlinkFromParent(); - bool nameIsEqual(QString check); + bool nameIsEqual(QString check) const; - virtual bool isFile(); - virtual bool isDirectory(); + virtual bool isFile() const; + virtual bool isDirectory() const; protected: @@ -50,7 +50,7 @@ public: QByteArray data; - bool isFile(); + bool isFile() const; }; /******************************************************************************/ @@ -62,9 +62,9 @@ public: QList children; - bool isDirectory(); + bool isDirectory() const; - WiiFSObject *findByName(QString name, bool recursive); + WiiFSObject *findByName(QString name, bool recursive) const; WiiFSObject *resolvePath(QString path); bool addChild(WiiFSObject *obj); }; diff --git a/wii/stringtablebuilder.cpp b/wii/stringtablebuilder.cpp index 679247c..d1f2d2b 100644 --- a/wii/stringtablebuilder.cpp +++ b/wii/stringtablebuilder.cpp @@ -20,6 +20,6 @@ quint32 WiiStringTableBuilder::add(QString str) { return added; } -QByteArray WiiStringTableBuilder::pack() { +QByteArray WiiStringTableBuilder::pack() const { return m_data; } diff --git a/wii/stringtablebuilder.h b/wii/stringtablebuilder.h index f416a37..4fce60f 100644 --- a/wii/stringtablebuilder.h +++ b/wii/stringtablebuilder.h @@ -11,7 +11,7 @@ public: WiiStringTableBuilder(); quint32 add(QString str); - QByteArray pack(); + QByteArray pack() const; protected: int m_nextOffset; -- cgit v1.2.3