diff options
Diffstat (limited to 'MapTool/wii')
| -rw-r--r-- | MapTool/wii/archiveu8.cpp | 263 | ||||
| -rw-r--r-- | MapTool/wii/archiveu8.h | 61 | ||||
| -rw-r--r-- | MapTool/wii/common.cpp | 134 | ||||
| -rw-r--r-- | MapTool/wii/common.h | 111 | ||||
| -rw-r--r-- | MapTool/wii/filesystem.cpp | 141 | ||||
| -rw-r--r-- | MapTool/wii/filesystem.h | 73 | ||||
| -rw-r--r-- | MapTool/wii/stringtablebuilder.cpp | 25 | ||||
| -rw-r--r-- | MapTool/wii/stringtablebuilder.h | 22 | 
8 files changed, 830 insertions, 0 deletions
| diff --git a/MapTool/wii/archiveu8.cpp b/MapTool/wii/archiveu8.cpp new file mode 100644 index 0000000..d27dfde --- /dev/null +++ b/MapTool/wii/archiveu8.cpp @@ -0,0 +1,263 @@ +/******************************************************************************* +  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" + + + + + + +WiiArchiveU8::WiiArchiveU8() { } + +WiiArchiveU8::WiiArchiveU8(QDataStream &stream) { +	U8ReadInfo info; +	info.startPos = stream.device()->pos(); + +	quint32 magic; +	stream >> (quint32&)magic; + +	if (magic != 0x55AA382D) +		qWarning() << "WiiArchiveU8: tried to load an archive without the U8 magic"; + +	quint32 fstStart, fstSize, dataOffset; +	stream >> (quint32&)fstStart; +	stream >> (quint32&)fstSize; +	stream >> (quint32&)dataOffset; + +	// read the FST +	stream.device()->seek(info.startPos + fstStart); + +	// read the root node +	quint32 rootNodeLastChild; + +	stream.skipRawData(8); // ignore type, nameOffset and dataOffset +	stream >> (quint32&)rootNodeLastChild; + +	// but before we do this, read the string table +	qint64 savePos = stream.device()->pos(); +	stream.device()->seek(savePos + ((rootNodeLastChild - 1) * 12)); + +	int stringTableLength = fstSize - (rootNodeLastChild * 12); + +	QByteArray rawStringTable; +	rawStringTable.resize(stringTableLength); +	stream.readRawData(rawStringTable.data(), stringTableLength); + +	info.stringTable = QString::fromAscii(rawStringTable.constData(), stringTableLength); + +	// now read the root node +	stream.device()->seek(savePos); + +	qDebug() << "Reading root node: last child is" << rootNodeLastChild; +	info.currentNode = 1; +	this->readDir(stream, this->root, rootNodeLastChild, info); +} + + +void WiiArchiveU8::readDir(QDataStream &in, WiiDirectory &dir, int lastChild, U8ReadInfo &info) { +	// read every node in this directory + +	while (info.currentNode < lastChild) { +		info.currentNode++; + +		//qDebug() << "Reading @ pos" << in.device()->pos(); + +		quint32 value, dataOffset, size; +		in >> (quint32&)value; +		in >> (quint32&)dataOffset; +		in >> (quint32&)size; + +		int nameOffset = value & 0xFFFFFF; +		int type = value >> 24; + +		WiiFSObject *newObj; +		if (type == 0) +			newObj = new WiiFile; +		else if (type == 1) +			newObj = new WiiDirectory; +		else +			qFatal("WiiArchiveU8::readDir: Unknown fs obj type %d", type); + +		// get the name +		int nameSize = info.stringTable.indexOf(QChar::Null, nameOffset) - nameOffset; +		newObj->name = info.stringTable.mid(nameOffset, nameSize); + +		qDebug() << "Reading node" << info.currentNode << newObj->name << "- type:" << type << "size:" << size << "offset:" << dataOffset; + +		// read the contents +		if (newObj->isFile()) { +			// get the file data +			qint64 savePos = in.device()->pos(); +			in.device()->seek(info.startPos + dataOffset); + +			WiiFile *file = (WiiFile*)newObj; +			file->data.resize(size); +			in.readRawData(file->data.data(), size); + +			in.device()->seek(savePos); + +		} else if (newObj->isDirectory()) { +			// read the children +			this->readDir(in, *((WiiDirectory*)newObj), size, info); + +		} + +		qDebug() << "Adding" << newObj->name << "to" << dir.name; +		dir.addChild(newObj); +	}; +} + + + +void WiiArchiveU8::writeToDataStream(QDataStream &out) const { +	U8WriteInfo info; + +	// first off, before we do anything else, create the string table +	this->addNodeToStringTable(this->root, info.stringTableBuilder); + +	QByteArray stringTable = info.stringTableBuilder.pack(); + +	// calculate various fun offsets/sizes +	int nodeCount = 0; +	this->countNode(this->root, &nodeCount); + +	info.startPos = out.device()->pos(); + +	quint32 fstStart = 0x20; +	quint32 nodeDataSize = nodeCount * 12; +	quint32 stringTableSize = stringTable.length(); +	quint32 fstSize = nodeDataSize + stringTableSize; +	quint32 dataOffset = AlignUp(fstStart + fstSize, 0x20); + +	qDebug() << "Writing: fstStart" << fstStart << "nodeCount" << nodeCount; +	qDebug() << "nodeDataSize" << nodeDataSize << "stringTableSize" << stringTableSize; +	qDebug() << "fstSize" << fstSize << "dataOffset" << dataOffset; + +	// now write the header +	out << (quint32)0x55AA382D; +	out << (quint32)fstStart; +	out << (quint32)fstSize; +	out << (quint32)dataOffset; + +	WritePadding(0x10, out); + +	// write root node +	info.currentNode = 1; // root node is 1 +	info.currentRecursionLevel = 0; +	info.nextDataOffset = dataOffset; + +	out << (quint32)(0x01000000 << info.stringTableBuilder.add("")); +	out << (quint32)0; +	out << (quint32)nodeCount; + +	this->writeDir(out, this->root, info); + +	// write string table +	out.writeRawData(stringTable.constData(), stringTable.length()); + +	// write data (after padding) +	WritePadding(dataOffset - fstSize - fstStart, out); + +	this->writeNodeData(out, this->root); + +	// looks like we are finally done +} + + +void WiiArchiveU8::addNodeToStringTable(const WiiFSObject &node, WiiStringTableBuilder &table) const { +	table.add(node.name); + +	if (node.isDirectory()) { +		WiiDirectory *dir = (WiiDirectory*)&node; + +		foreach (WiiFSObject *p, dir->children) +			this->addNodeToStringTable(*p, table); +	} +} + + +void WiiArchiveU8::countNode(const WiiFSObject &node, int *countPtr) const { +	(*countPtr)++; + +	if (node.isDirectory()) { +		WiiDirectory *dir = (WiiDirectory*)&node; + +		foreach (WiiFSObject *p, dir->children) +			this->countNode(*p, countPtr); +	} +} + + +void WiiArchiveU8::writeDir(QDataStream &out, const WiiDirectory &dir, U8WriteInfo &info) const { +	foreach (WiiFSObject *p, dir.children) { +		info.currentNode++; + +		if (p->isDirectory()) { +			// write directory +			WiiDirectory *thisDir = (WiiDirectory*)p; + +			out << (quint32)(0x01000000 | info.stringTableBuilder.add(thisDir->name)); +			out << (quint32)info.currentRecursionLevel; + +			qint64 lastChildFieldPos = out.device()->pos(); +			out << (quint32)0; // placeholder + +			info.currentRecursionLevel++; + +			this->writeDir(out, *thisDir, info); + +			info.currentRecursionLevel--; + +			// write lastChild field +			qint64 dirEndPos = out.device()->pos(); + +			out.device()->seek(lastChildFieldPos); +			out << (quint32)info.currentNode; +			out.device()->seek(dirEndPos); + +		} else if (p->isFile()) { +			// write file +			WiiFile *thisFile = (WiiFile*)p; + +			out << (quint32)info.stringTableBuilder.add(thisFile->name); +			out << (quint32)info.nextDataOffset; +			out << (quint32)thisFile->data.size(); + +			info.nextDataOffset = AlignUp(info.nextDataOffset + thisFile->data.size(), 0x20); +		} +	} +} + + +void WiiArchiveU8::writeNodeData(QDataStream &out, const WiiFSObject &node) const { +	if (node.isDirectory()) { +		// write all the children's data +		WiiDirectory *thisDir = (WiiDirectory*)&node; + +		foreach (WiiFSObject *p, thisDir->children) +			this->writeNodeData(out, *p); + +	} else if (node.isFile()) { +		// write this file's data +		WiiFile *thisFile = (WiiFile*)&node; + +		int len = thisFile->data.length(); +		out.writeRawData(thisFile->data.constData(), len); +		WritePadding(AlignUp(len, 0x20) - len, out); +	} +} diff --git a/MapTool/wii/archiveu8.h b/MapTool/wii/archiveu8.h new file mode 100644 index 0000000..5561beb --- /dev/null +++ b/MapTool/wii/archiveu8.h @@ -0,0 +1,61 @@ +/******************************************************************************* +  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" +#include "stringtablebuilder.h" + + +struct U8ReadInfo { +	qint64 startPos; +	QString stringTable; +	int currentNode; +}; + +struct U8WriteInfo { +	qint64 startPos; +	WiiStringTableBuilder stringTableBuilder; +	int currentRecursionLevel; +	int currentNode; +	int nextDataOffset; +}; + + +class WiiArchiveU8 { +public: +	WiiArchiveU8(); +	WiiArchiveU8(QDataStream &stream); + +	WiiDirectory root; + +	void writeToDataStream(QDataStream &out) const; + +private: +	void readDir(QDataStream &in, WiiDirectory &dir, int lastChild, U8ReadInfo &info); + +	void addNodeToStringTable(const WiiFSObject &node, WiiStringTableBuilder &table) const; +	void countNode(const WiiFSObject &node, int *countPtr) const; + +	void writeDir(QDataStream &out, const WiiDirectory &dir, U8WriteInfo &info) const; + +	void writeNodeData(QDataStream &out, const WiiFSObject &node) const; +}; + +#endif // WIIARCHIVEU8_H diff --git a/MapTool/wii/common.cpp b/MapTool/wii/common.cpp new file mode 100644 index 0000000..8f552b3 --- /dev/null +++ b/MapTool/wii/common.cpp @@ -0,0 +1,134 @@ +/******************************************************************************* +  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 "common.h" + +QByteArray PadByteArray(const QByteArray original, int newLength, char padWith) { +	QByteArray newArray = original; + +	if (original.length() > newLength) { +		// the original array is longer than the length desired, so truncate it +		newArray.truncate(newLength); + +	} else if (original.length() < newLength) { +		// the original array is shorter, so pad it +		int oldLength = original.length(); +		newArray.resize(newLength); + +		for (int i = oldLength; i < newLength; i++) { +			newArray[i] = '\0'; +		} +	} + +	return newArray; +} + +QStringList ReadStringList(QDataStream &in) { +	QStringList output; + +	quint16 count; +	in >> (quint16&)count; +	in.skipRawData(2); // padding + +	QVector<quint32> stringOffsets(count); + +	// save the initial offset so we can get the strings later +	// string offsets are based on the first offset entry (after the count) +	// NOT on the section offset +	qint64 savedPos = in.device()->pos(); + +	for (int i = 0; i < count; i++) { +		quint32 offset; +		in >> (quint32&)offset; +		in.skipRawData(4); // unused? + +		stringOffsets[i] = offset; +	} + +	// ok, now we can get the strings +	for (int i = 0; i < count; i++) { +		in.device()->seek(savedPos + stringOffsets[i]); + +		// how fun: no length is stored for each string, they're just zero +		// terminated. so let's try to figure it out! +		int stringLength = 0; +		char check; + +		in >> (quint8&)check; +		while (check != 0) { +			stringLength += 1; +			in >> (quint8&)check; +		} + +		// now read the string +		char *buffer = new char[stringLength]; + +		in.device()->seek(savedPos + stringOffsets[i]); +		in.readRawData(buffer, stringLength); + +		output.append(QString::fromAscii(buffer, stringLength)); + +		delete[] buffer; + + +		qDebug() << "Read string:" << output.last(); +	} + +	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()); + +	QString str = QString::fromAscii(readStr.data(), readStr.length()); +	if (str.contains(QChar('\0'))) +		str.truncate(str.indexOf(QChar('\0'))); + +	return str; +} + +void WriteFixedLengthASCII(QDataStream &out, const QString str, int length) { +	QByteArray paddedStr = PadByteArray(str.toAscii(), length); +	out.writeRawData(paddedStr.constData(), paddedStr.length()); +} + + diff --git a/MapTool/wii/common.h b/MapTool/wii/common.h new file mode 100644 index 0000000..b440841 --- /dev/null +++ b/MapTool/wii/common.h @@ -0,0 +1,111 @@ +#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 AlignUp(quint32 value, quint32 alignTo) { +	return (value + alignTo - 1) & ~(alignTo - 1); +} + +inline quint32 AlignDown(quint32 value, quint32 alignTo) { +	return value & ~(alignTo - 1); +} + + +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; +} + +inline void WritePadding(int num, QDataStream &out) { +	for (int i = 0; i < num; i++) +		out << (quint8)0; +} + + + + +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(const 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(const 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); +void WriteStringList(QDataStream &out, QStringList list); + +QString ReadFixedLengthASCII(QDataStream &in, int length); +void WriteFixedLengthASCII(QDataStream &out, QString str, int length); + +#endif // WIICOMMON_H diff --git a/MapTool/wii/filesystem.cpp b/MapTool/wii/filesystem.cpp new file mode 100644 index 0000000..014b693 --- /dev/null +++ b/MapTool/wii/filesystem.cpp @@ -0,0 +1,141 @@ +/******************************************************************************* +  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) const { +	return (bool)(QString::compare(this->name, check, Qt::CaseInsensitive) == 0); +} + +bool WiiFSObject::isFile() const { return false; } +bool WiiFSObject::isDirectory() const { return false; } + +/******************************************************************************/ + +bool WiiFile::isFile() const { return true; } + +/******************************************************************************/ + +WiiDirectory::~WiiDirectory() { +	foreach (WiiFSObject *ptr, children) +		delete ptr; +} + +bool WiiDirectory::isDirectory() const { return true; } + +WiiFSObject *WiiDirectory::findByName(QString name, bool recursive) const { +	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 = (WiiDirectory*)currentDir->parent; + +		pathComponents.removeFirst(); +	} + +	// now we can loop through the path +	while (!pathComponents.isEmpty()) { +		QString next = pathComponents.takeFirst(); +		WiiFSObject *nextObj; + +		// get the next object in the path +		if (next == ".") { +			nextObj = currentDir; +		} else if (next == "..") { +			nextObj = currentDir->parent; +		} else { +			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 (WiiFSObject *)nextObj; +		} + +		// verify that this object is a directory +		if (!nextObj->isDirectory()) { +			qWarning() << "Failed to resolve path" << path << ": component" << next << "is not a directory"; +			return 0; +		} + +		// ok, this has to be a directory, so let's just continue +		currentDir = (WiiDirectory *)nextObj; +	} + +	// we should not reach here +	qWarning() << "Failed to resolve path" << path << ": unknown error"; +	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/MapTool/wii/filesystem.h b/MapTool/wii/filesystem.h new file mode 100644 index 0000000..7527a7d --- /dev/null +++ b/MapTool/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) const; + +	virtual bool isFile() const; +	virtual bool isDirectory() const; + + +protected: +	WiiFSObject(); // don't instantiate this class directly! +}; + + +/******************************************************************************/ + +class WiiFile : public WiiFSObject { +public: +	QByteArray data; + + +	bool isFile() const; +}; + +/******************************************************************************/ + +class WiiDirectory : public WiiFSObject { +public: +	~WiiDirectory(); + +	QList<WiiFSObject *> children; + + +	bool isDirectory() const; + +	WiiFSObject *findByName(QString name, bool recursive) const; +	WiiFSObject *resolvePath(QString path); +	bool addChild(WiiFSObject *obj); +}; + + +#endif // FILESYSTEM_H diff --git a/MapTool/wii/stringtablebuilder.cpp b/MapTool/wii/stringtablebuilder.cpp new file mode 100644 index 0000000..d1f2d2b --- /dev/null +++ b/MapTool/wii/stringtablebuilder.cpp @@ -0,0 +1,25 @@ +#include "stringtablebuilder.h" + +WiiStringTableBuilder::WiiStringTableBuilder() { +	m_nextOffset = 0; +	m_data = ""; +} + +quint32 WiiStringTableBuilder::add(QString str) { +	if (m_lookup.contains(str)) +		return m_lookup.value(str); + +	quint32 added = m_nextOffset; +	m_lookup.insert(str, added); + +	m_data.append(str.toAscii()); +	m_data.append('\0'); + +	m_nextOffset = m_data.length(); + +	return added; +} + +QByteArray WiiStringTableBuilder::pack() const { +	return m_data; +} diff --git a/MapTool/wii/stringtablebuilder.h b/MapTool/wii/stringtablebuilder.h new file mode 100644 index 0000000..4fce60f --- /dev/null +++ b/MapTool/wii/stringtablebuilder.h @@ -0,0 +1,22 @@ +#ifndef STRINGTABLEBUILDER_H +#define STRINGTABLEBUILDER_H + +#include "common.h" +#include <QtCore/QString> +#include <QtCore/QHash> +#include <QtCore/QByteArray> + +class WiiStringTableBuilder { +public: +    WiiStringTableBuilder(); + +	quint32 add(QString str); +	QByteArray pack() const; + +protected: +	int m_nextOffset; +	QByteArray m_data; +	QHash<QString, quint32> m_lookup; +}; + +#endif // STRINGTABLEBUILDER_H | 
