diff options
author | Treeki <treeki@gmail.com> | 2010-10-09 01:00:16 +0200 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2010-10-09 01:00:16 +0200 |
commit | 7213ca723a65dff8ebb0c6c08669695217e60453 (patch) | |
tree | 1003cdfc9dd8fa21f2521c2e22071f391c555c78 | |
parent | c2cd2300ab03a41999b8e4e38cf0d29abb786918 (diff) | |
download | LayoutStudio-7213ca723a65dff8ebb0c6c08669695217e60453.tar.gz LayoutStudio-7213ca723a65dff8ebb0c6c08669695217e60453.zip |
material bugfixes, plus the beginning of U8 archive code, and a nice little API for handling archive filesystems
-rw-r--r-- | LayoutStudio.pro | 11 | ||||
-rw-r--r-- | lyt/common.h | 97 | ||||
-rw-r--r-- | lyt/materials/indirectstage.h | 8 | ||||
-rw-r--r-- | lyt/materials/material.cpp | 101 | ||||
-rw-r--r-- | lyt/materials/material.h | 49 | ||||
-rw-r--r-- | main.cpp | 6 | ||||
-rw-r--r-- | wii/archiveu8.cpp | 20 | ||||
-rw-r--r-- | wii/archiveu8.h | 37 | ||||
-rw-r--r-- | wii/common.cpp (renamed from lyt/common.cpp) | 1 | ||||
-rw-r--r-- | wii/common.h | 97 | ||||
-rw-r--r-- | wii/filesystem.cpp | 138 | ||||
-rw-r--r-- | wii/filesystem.h | 73 |
12 files changed, 478 insertions, 160 deletions
diff --git a/LayoutStudio.pro b/LayoutStudio.pro index 8665bcd..9c5df61 100644 --- a/LayoutStudio.pro +++ b/LayoutStudio.pro @@ -14,7 +14,6 @@ SOURCES += main.cpp \ lyt/binaryfilesection.cpp \ lyt/materials/material.cpp \ lyt/pane.cpp \ - lyt/common.cpp \ lyt/textbox.cpp \ lyt/picture.cpp \ lyt/window.cpp \ @@ -28,7 +27,10 @@ SOURCES += main.cpp \ lyt/materials/indirectstage.cpp \ lyt/materials/tevstage.cpp \ lyt/materials/alphacompare.cpp \ - lyt/materials/blendmode.cpp + lyt/materials/blendmode.cpp \ + wii/common.cpp \ + wii/archiveu8.cpp \ + wii/filesystem.cpp HEADERS += lsmainwindow.h \ lsglobals.h \ lyt/packagebase.h \ @@ -52,7 +54,10 @@ HEADERS += lsmainwindow.h \ lyt/materials/indirectstage.h \ lyt/materials/tevstage.h \ lyt/materials/alphacompare.h \ - lyt/materials/blendmode.h + lyt/materials/blendmode.h \ + wii/archiveu8.h \ + wii/common.h \ + wii/filesystem.h FORMS += lsmainwindow.ui RESOURCES += resources.qrc diff --git a/lyt/common.h b/lyt/common.h index c75813b..9c39339 100644 --- a/lyt/common.h +++ b/lyt/common.h @@ -19,13 +19,8 @@ #define LYTCOMMON_H #include <QtGlobal> -#include <QtCore/QByteArray> -#include <QtGui/QColor> -#include <QtCore/QPointF> -#include <QtCore/QDataStream> -#include <QtCore/QStringList> -#include <QtCore/QDebug> -#include <QtCore/QVector> + +#include "../wii/common.h" union Magic { char str[4]; @@ -39,97 +34,9 @@ union Version { -inline quint32 BitExtract(quint32 value, int count, int start) { - // this function relies on heavy compiler optimisation to be efficient :p - quint32 mask = 0; - for (int i = start; i < start+count; i++) { - mask |= (0x80000000 >> i); - } - - return (value & mask) >> (32 - (start + count)); -} - -inline quint32 BitInsert(quint32 value, int newValue, int count, int start) { - quint32 mask = 0; - for (int i = start; i < start+count; i++) { - mask |= (0x80000000 >> i); - } - - value &= ~mask; - value |= (newValue << (32 - (start + count))) & mask; - return value; -} - - - - - -QByteArray PadByteArray(QByteArray original, int newLength, char padWith='\0'); - -inline quint32 ColorToRGBA(QColor col) { - return (col.red() << 24) | (col.green() << 16) | (col.blue() << 8) | (col.alpha()); -} - -inline QColor RGBAToColor(quint32 col) { - return QColor(col >> 24, (col >> 16) & 0xFF, (col >> 8) & 0xFF, col & 0xFF); -} - -inline void ReadRGBA8Color(QColor &out, QDataStream &in) { - quint32 col; - in >> (quint32&)col; - out = RGBAToColor(col); -} - -inline void WriteRGBA8Color(QColor &in, QDataStream &out) { - out << (quint32)ColorToRGBA(in); -} - -inline void ReadS10Color(QColor &out, QDataStream &in) { - quint16 r, g, b, a; - in >> (quint16&)r; - in >> (quint16&)g; - in >> (quint16&)b; - in >> (quint16&)a; - out.setRgb(r, g, b, a); -} - -inline void WriteS10Color(QColor &in, QDataStream &out) { - out << (quint16)in.red(); - out << (quint16)in.green(); - out << (quint16)in.blue(); - out << (quint16)in.alpha(); -} - - - - struct LYTTexCoords { QPointF coord[4]; }; -inline void ReadPointF(QDataStream &stream, QPointF &point) { - float x, y; - stream >> x; - stream >> y; - point.setX(x); - point.setY(y); -} - -inline void WritePointF(QDataStream &stream, const QPointF &point) { - stream << (float)point.x(); - stream << (float)point.y(); -} - -inline void InitDataStream(QDataStream &stream) { - stream.setByteOrder(QDataStream::BigEndian); - stream.setVersion(QDataStream::Qt_4_5); -} - -QStringList ReadStringList(QDataStream &in); - -QString ReadFixedLengthASCII(QDataStream &in, int length); -void WriteFixedLengthASCII(QDataStream &out, QString str, int length); - - #endif // LYTCOMMON_H diff --git a/lyt/materials/indirectstage.h b/lyt/materials/indirectstage.h index 30c6f9d..8f381bf 100644 --- a/lyt/materials/indirectstage.h +++ b/lyt/materials/indirectstage.h @@ -30,10 +30,10 @@ public: void dumpToDebug(); - int texCoord; - int texMap; - int wrap_s; - int wrap_t; + quint8 texCoord; + quint8 texMap; + quint8 wrap_s; + quint8 wrap_t; }; diff --git a/lyt/materials/material.cpp b/lyt/materials/material.cpp index f79fd08..a4498c5 100644 --- a/lyt/materials/material.cpp +++ b/lyt/materials/material.cpp @@ -31,8 +31,61 @@ LYTLayout &LYTMaterial::layout() const { void LYTMaterial::dumpToDebug() { qDebug() << "LYTMaterial" << name << "@" << (void*)this; - // todo: move dumpToDebug calls for the various Material structs out of - // LYTMaterial::read...() and put them here, since it makes more sense + + for (int i = 0; i < 3; i++) + qDebug() << "Colour" << i << ":" << colours[i]; + + for (int i = 0; i < 4; i++) + qDebug() << "TEV Constant Colour" << i << ":" << tevKColour[i]; + + qDebug() << "TexMaps:" << texMaps.count(); + foreach (LYTTexMap texMap, texMaps) + texMap.dumpToDebug(); + + qDebug() << "TexSRTs:" << texSRTs.count(); + foreach (LYTTexSRT texSRT, texSRTs) + texSRT.dumpToDebug(); + + qDebug() << "TexCoordGens:" << texCoordGens.count(); + foreach (LYTTexCoordGen texCoordGen, texCoordGens) + texCoordGen.dumpToDebug(); + + if (hasChanCtrl) + chanCtrl.dumpToDebug(); + else + qDebug() << "ChanCtrl: none"; + + if (hasMatCol) + qDebug() << "MatCol:" << matCol; + else + qDebug() << "MatCol: none"; + + if (hasTevSwapTable) + tevSwapTable.dumpToDebug(); + else + qDebug() << "TevSwapTable: none"; + + qDebug() << "IndTexSRTs:" << indTexSRTs.count(); + foreach (LYTTexSRT indTexSRT, indTexSRTs) + indTexSRT.dumpToDebug(); + + qDebug() << "IndirectStages:" << indTexStages.count(); + foreach (LYTIndirectStage indTexStage, indTexStages) + indTexStage.dumpToDebug(); + + qDebug() << "TevStages:" << tevStages.count(); + foreach (LYTTevStage tevStage, tevStages) + tevStage.dumpToDebug(); + + if (hasAlphaCompare) + alphaCompare.dumpToDebug(); + else + qDebug() << "AlphaCompare: none"; + + if (hasBlendMode) + blendMode.dumpToDebug(); + else + qDebug() << "BlendMode: none"; } @@ -51,8 +104,9 @@ void LYTMaterial::readFromDataStream(QDataStream &in) { ReadRGBA8Color(this->tevKColour[i], in); - LYTMaterialResourceNum resourceNum; - in >> (quint32&)resourceNum.value; + quint32 resNumValue; + in >> (quint32&)resNumValue; + LYTMaterialResourceNum resourceNum(resNumValue); // this is really complicated -_- // first off: TexMap @@ -79,7 +133,7 @@ void LYTMaterial::readFromDataStream(QDataStream &in) { // ChanCtrl if (resourceNum.hasChanCtrl()) { this->hasChanCtrl = true; - this->readChanCtrl(in); + this->chanCtrl.readFromDataStream(in); } else { this->hasChanCtrl = false; } @@ -87,7 +141,7 @@ void LYTMaterial::readFromDataStream(QDataStream &in) { // MatCol if (resourceNum.hasMatCol()) { this->hasMatCol = true; - this->readMatCol(in); + ReadRGBA8Color(this->matCol, in); } else { this->hasMatCol = false; } @@ -95,7 +149,7 @@ void LYTMaterial::readFromDataStream(QDataStream &in) { // TevSwapTable if (resourceNum.hasTevSwapTable()) { this->hasTevSwapTable = true; - this->readTevSwapTable(in); + this->tevSwapTable.readFromDataStream(in); } else { this->hasTevSwapTable = false; } @@ -124,7 +178,7 @@ void LYTMaterial::readFromDataStream(QDataStream &in) { // AlphaCompare if (resourceNum.hasAlphaCompare()) { this->hasAlphaCompare = true; - this->readAlphaCompare(in); + this->alphaCompare.readFromDataStream(in); } else { this->hasAlphaCompare = false; } @@ -132,7 +186,7 @@ void LYTMaterial::readFromDataStream(QDataStream &in) { // BlendMode if (resourceNum.hasBlendMode()) { this->hasBlendMode = true; - this->readBlendMode(in); + this->blendMode.readFromDataStream(in); } else { this->hasBlendMode = false; } @@ -143,60 +197,31 @@ void LYTMaterial::readFromDataStream(QDataStream &in) { void LYTMaterial::readTexMap(QDataStream &in) { this->texMaps.append(LYTTexMap()); this->texMaps.last().readFromDataStream(in, m_layout); - this->texMaps.last().dumpToDebug(); } void LYTMaterial::readTexSRT(QDataStream &in) { this->texSRTs.append(LYTTexSRT()); this->texSRTs.last().readFromDataStream(in); - this->texSRTs.last().dumpToDebug(); } void LYTMaterial::readTexCoordGen(QDataStream &in) { this->texCoordGens.append(LYTTexCoordGen()); this->texCoordGens.last().readFromDataStream(in); - this->texCoordGens.last().dumpToDebug(); -} - -void LYTMaterial::readChanCtrl(QDataStream &in) { - this->chanCtrl.readFromDataStream(in); - this->chanCtrl.dumpToDebug(); -} - -void LYTMaterial::readMatCol(QDataStream &in) { - ReadRGBA8Color(this->matCol, in); -} - -void LYTMaterial::readTevSwapTable(QDataStream &in) { - this->tevSwapTable.readFromDataStream(in); - this->tevSwapTable.dumpToDebug(); } void LYTMaterial::readIndTexSRT(QDataStream &in) { this->indTexSRTs.append(LYTTexSRT()); this->indTexSRTs.last().readFromDataStream(in); - this->indTexSRTs.last().dumpToDebug(); } void LYTMaterial::readIndirectStage(QDataStream &in) { this->indTexStages.append(LYTIndirectStage()); this->indTexStages.last().readFromDataStream(in); - this->indTexStages.last().dumpToDebug(); } void LYTMaterial::readTevStage(QDataStream &in) { this->tevStages.append(LYTTevStage()); this->tevStages.last().readFromDataStream(in); - this->tevStages.last().dumpToDebug(); } -void LYTMaterial::readAlphaCompare(QDataStream &in) { - this->alphaCompare.readFromDataStream(in); - this->alphaCompare.dumpToDebug(); -} - -void LYTMaterial::readBlendMode(QDataStream &in) { - this->blendMode.readFromDataStream(in); - this->blendMode.dumpToDebug(); -} diff --git a/lyt/materials/material.h b/lyt/materials/material.h index bfdf80b..d605244 100644 --- a/lyt/materials/material.h +++ b/lyt/materials/material.h @@ -40,19 +40,37 @@ class LYTLayout; class LYTMaterialResourceNum { public: - quint32 value; - - inline int getTexMapNum() { return BitExtract(value, 4, 28); } - inline int getTexSRTNum() { return BitExtract(value, 4, 24); } - inline int getTexCoordGenNum() { return BitExtract(value, 4, 20); } - inline bool hasChanCtrl() { return BitExtract(value, 1, 6); } - inline bool hasMatCol() { return BitExtract(value, 1, 4); } - inline bool hasTevSwapTable() { return BitExtract(value, 1, 19); } - inline bool hasAlphaCompare() { return BitExtract(value, 1, 8); } - inline bool hasBlendMode() { return BitExtract(value, 1, 7); } - inline int getIndTexSRTNum() { return BitExtract(value, 2, 17); } - inline int getIndTexStageNum() { return BitExtract(value, 3, 14); } - inline int getTevStageNum() { return BitExtract(value, 5, 9); } + 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); } + + void setTexMapNum(int v) { m_value = BitInsert(m_value, v, 4, 28); } + void setTexSRTNum(int v) { m_value = BitInsert(m_value, v, 4, 24); } + void setTexCoordGenNum(int v) { m_value = BitInsert(m_value, v, 4, 20); } + void setHasChanCtrl(bool v) { m_value = BitInsert(m_value, v, 1, 6); } + void setHasMatCol(bool v) { m_value = BitInsert(m_value, v, 1, 4); } + void setHasTevSwapTable(bool v) { m_value = BitInsert(m_value, v, 1, 19); } + void setHasAlphaCompare(bool v) { m_value = BitInsert(m_value, v, 1, 8); } + void setHasBlendMode(bool v) { m_value = BitInsert(m_value, v, 1, 7); } + void setIndTexSRTNum(int v) { m_value = BitInsert(m_value, v, 2, 17); } + void setIndTexStageNum(int v) { m_value = BitInsert(m_value, v, 3, 14); } + void setTevStageNum(int v) { m_value = BitInsert(m_value, v, 5, 9); } + +private: + quint32 m_value; }; @@ -109,11 +127,6 @@ protected: void readTexMap(QDataStream &in); void readTexSRT(QDataStream &in); void readTexCoordGen(QDataStream &in); - void readChanCtrl(QDataStream &in); - void readMatCol(QDataStream &in); - void readTevSwapTable(QDataStream &in); - void readAlphaCompare(QDataStream &in); - void readBlendMode(QDataStream &in); void readIndirectStage(QDataStream &in); void readIndTexSRT(QDataStream &in); void readTevStage(QDataStream &in); @@ -28,8 +28,10 @@ int main(int argc, char *argv[]) { LSGlobals::setup(); - LYTDirectoryPackage package("H:\\ISOs\\NSMBWii\\Extracted\\Layout\\continue\\continue\\arc"); - LYTLayout layout(package, "continue_05.brlyt"); + //LYTDirectoryPackage package("H:\\ISOs\\NSMBWii\\Extracted\\Layout\\continue\\continue\\arc"); + //LYTLayout layout(package, "continue_05.brlyt"); + LYTDirectoryPackage package("H:\\ISOs\\TP\\banner\\arc_extr"); + LYTLayout layout(package, "banner.brlyt"); LSMainWindow w; w.show(); diff --git a/wii/archiveu8.cpp b/wii/archiveu8.cpp new file mode 100644 index 0000000..aeb3aac --- /dev/null +++ b/wii/archiveu8.cpp @@ -0,0 +1,20 @@ +/******************************************************************************* + 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 <http://www.gnu.org/licenses/>. +*******************************************************************************/ + +#include "archiveu8.h" + + diff --git a/wii/archiveu8.h b/wii/archiveu8.h new file mode 100644 index 0000000..66f3fbe --- /dev/null +++ b/wii/archiveu8.h @@ -0,0 +1,37 @@ +/******************************************************************************* + 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 <http://www.gnu.org/licenses/>. +*******************************************************************************/ + +#ifndef WIIARCHIVEU8_H +#define WIIARCHIVEU8_H + +#include "common.h" +#include "filesystem.h" + + + + +class WiiArchiveU8 { +public: + WiiArchiveU8(); + WiiArchiveU8(QDataStream &stream); + + WiiDirectory root; + + void writeToDataStream(QDataStream &out); +}; + +#endif // WIIARCHIVEU8_H diff --git a/lyt/common.cpp b/wii/common.cpp index ba86246..f4a961c 100644 --- a/lyt/common.cpp +++ b/wii/common.cpp @@ -107,3 +107,4 @@ void WriteFixedLengthASCII(QDataStream &out, QString str, int length) { out.writeRawData(paddedStr.constData(), paddedStr.length()); } + diff --git a/wii/common.h b/wii/common.h new file mode 100644 index 0000000..aa7dce0 --- /dev/null +++ b/wii/common.h @@ -0,0 +1,97 @@ +#ifndef WIICOMMON_H +#define WIICOMMON_H + +#include <QtGlobal> +#include <QtCore/QByteArray> +#include <QtGui/QColor> +#include <QtCore/QPointF> +#include <QtCore/QDataStream> +#include <QtCore/QStringList> +#include <QtCore/QDebug> +#include <QtCore/QVector> + +inline quint32 BitExtract(quint32 value, int count, int start) { + // this function relies on heavy compiler optimisation to be efficient :p + quint32 mask = 0; + for (int i = start; i < start+count; i++) { + mask |= (0x80000000 >> i); + } + + return (value & mask) >> (32 - (start + count)); +} + +inline quint32 BitInsert(quint32 value, int newValue, int count, int start) { + quint32 mask = 0; + for (int i = start; i < start+count; i++) { + mask |= (0x80000000 >> i); + } + + value &= ~mask; + value |= (newValue << (32 - (start + count))) & mask; + return value; +} + + + + + +QByteArray PadByteArray(QByteArray original, int newLength, char padWith='\0'); + +inline quint32 ColorToRGBA(QColor col) { + return (col.red() << 24) | (col.green() << 16) | (col.blue() << 8) | (col.alpha()); +} + +inline QColor RGBAToColor(quint32 col) { + return QColor(col >> 24, (col >> 16) & 0xFF, (col >> 8) & 0xFF, col & 0xFF); +} + +inline void ReadRGBA8Color(QColor &out, QDataStream &in) { + quint32 col; + in >> (quint32&)col; + out = RGBAToColor(col); +} + +inline void WriteRGBA8Color(QColor &in, QDataStream &out) { + out << (quint32)ColorToRGBA(in); +} + +inline void ReadS10Color(QColor &out, QDataStream &in) { + quint16 r, g, b, a; + in >> (quint16&)r; + in >> (quint16&)g; + in >> (quint16&)b; + in >> (quint16&)a; + out.setRgb(r, g, b, a); +} + +inline void WriteS10Color(QColor &in, QDataStream &out) { + out << (quint16)in.red(); + out << (quint16)in.green(); + out << (quint16)in.blue(); + out << (quint16)in.alpha(); +} + +inline void ReadPointF(QDataStream &stream, QPointF &point) { + float x, y; + stream >> x; + stream >> y; + point.setX(x); + point.setY(y); +} + +inline void WritePointF(QDataStream &stream, const QPointF &point) { + stream << (float)point.x(); + stream << (float)point.y(); +} + +inline void InitDataStream(QDataStream &stream) { + stream.setByteOrder(QDataStream::BigEndian); + stream.setVersion(QDataStream::Qt_4_5); +} + +QStringList ReadStringList(QDataStream &in); + +QString ReadFixedLengthASCII(QDataStream &in, int length); +void WriteFixedLengthASCII(QDataStream &out, QString str, int length); + +#endif // WIICOMMON_H diff --git a/wii/filesystem.cpp b/wii/filesystem.cpp new file mode 100644 index 0000000..9926109 --- /dev/null +++ b/wii/filesystem.cpp @@ -0,0 +1,138 @@ +/******************************************************************************* + 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 <http://www.gnu.org/licenses/>. +*******************************************************************************/ + +#include "filesystem.h" + + +/******************************************************************************/ + +WiiFSObject::WiiFSObject() { parent = 0; } +WiiFSObject::~WiiFSObject() { } + + + +void WiiFSObject::unlinkFromParent() { + if (this->parent == 0) + return; + + if (this->parent->isDirectory()) { + WiiDirectory *p = (WiiDirectory *)this->parent; + if (p->children.contains(this)) + p->children.removeAt(p->children.indexOf(this)); + } + + this->parent = 0; +} + +bool WiiFSObject::nameIsEqual(QString check) { + return (bool)(QString::compare(this->name, check, Qt::CaseInsensitive)); +} + +bool WiiFSObject::isFile() { return false; } +bool WiiFSObject::isDirectory() { return false; } + +/******************************************************************************/ + +bool WiiFile::isFile() { return true; } + +/******************************************************************************/ + +WiiDirectory::~WiiDirectory() { + foreach (WiiFSObject *ptr, children) + delete ptr; +} + +bool WiiDirectory::isDirectory() { return true; } + +WiiFSObject *WiiDirectory::findByName(QString name, bool recursive) { + foreach (WiiFSObject *obj, children) { + if (obj->nameIsEqual(name)) + return obj; + + if (recursive && obj->isDirectory()) { + WiiDirectory *dir = (WiiDirectory*)obj; + WiiFSObject *tryThis = dir->findByName(name, recursive); + + if (tryThis) + return tryThis; + } + } + + return 0; +} + +WiiFSObject *WiiDirectory::resolvePath(QString path) { + QStringList pathComponents = path.split('/'); + WiiDirectory *currentDir = this; + + // special case: handle absolute paths + if (pathComponents.at(0) == "") { + while (currentDir->parent != 0) + currentDir = currentDir->parent; + + pathComponents.removeFirst(); + } + + // now we can loop through the path + while (!pathComponents.isEmpty()) { + QString next = pathComponents.takeFirst(); + + // get the next object in the path + if (next == ".") { + next = currentDir; + } else if (next == "..") { + next = currentDir->parent; + } else { + WiiFSObject *nextObj = currentDir->findByName(next, false); + } + + if (nextObj == 0) { + qWarning() << "Failed to resolve path" << path << ": missing component" << next; + return 0; + } + + if (pathComponents.isEmpty()) { + // we've reached the end \o/ + return nextObj; + } + + // verify that this object is a directory + if (!nextObj->isDirectory()) { + qWarning() << "Failed to resolve path" << path << ": component" << next << "is not a directory"; + } + + // ok, this has to be a directory, so let's just continue + currentDir = (WiiDirectory *)nextObj; + } + + // we should not reach here + return 0; +} + +bool WiiDirectory::addChild(WiiFSObject *obj) { + // verify to make sure an object does not exist with this name + if (this->findByName(obj->name, false) != 0) + return false; + + obj->unlinkFromParent(); + + this->children.append(obj); + obj->parent = this; + + return true; +} + diff --git a/wii/filesystem.h b/wii/filesystem.h new file mode 100644 index 0000000..1a7ecfa --- /dev/null +++ b/wii/filesystem.h @@ -0,0 +1,73 @@ +/******************************************************************************* + 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 <http://www.gnu.org/licenses/>. +*******************************************************************************/ + +#ifndef WIIFILESYSTEM_H +#define WIIFILESYSTEM_H + +#include "common.h" + + +class WiiFSObject { + // abstract base class of all filesystem objects +public: + virtual ~WiiFSObject(); + + WiiFSObject *parent; + + QString name; + + + void unlinkFromParent(); + bool nameIsEqual(QString check); + + virtual bool isFile(); + virtual bool isDirectory(); + + +protected: + WiiFSObject(); // don't instantiate this class directly! +}; + + +/******************************************************************************/ + +class WiiFile : public WiiFSObject { +public: + QByteArray data; + + + bool isFile(); +}; + +/******************************************************************************/ + +class WiiDirectory : public WiiFSObject { +public: + ~WiiDirectory(); + + QList<WiiFSObject *> children; + + + bool isDirectory(); + + WiiFSObject *findByName(QString name, bool recursive); + WiiFSObject *resolvePath(QString path); + bool addChild(WiiFSObject *obj); +}; + + +#endif // FILESYSTEM_H |