Skip to content

Commit

Permalink
Initial work on support for Wang Tiles (#1582)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bdtrotte authored and bjorn committed Jul 4, 2017
1 parent fb8c380 commit 9e174f4
Show file tree
Hide file tree
Showing 34 changed files with 2,661 additions and 6 deletions.
6 changes: 4 additions & 2 deletions src/libtiled/libtiled-src.pri
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ SOURCES += $$PWD/compression.cpp \
$$PWD/tileset.cpp \
$$PWD/tilesetformat.cpp \
$$PWD/tilesetmanager.cpp \
$$PWD/varianttomapconverter.cpp
$$PWD/varianttomapconverter.cpp \
$$PWD/wangset.cpp
HEADERS += $$PWD/compression.h \
$$PWD/filesystemwatcher.h \
$$PWD/gidmapper.h \
Expand Down Expand Up @@ -65,4 +66,5 @@ HEADERS += $$PWD/compression.h \
$$PWD/tileset.h \
$$PWD/tilesetformat.h \
$$PWD/tilesetmanager.h \
$$PWD/varianttomapconverter.h
$$PWD/varianttomapconverter.h \
$$PWD/wangset.h
2 changes: 2 additions & 0 deletions src/libtiled/libtiled.qbs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ DynamicLibrary {
"tilesetmanager.h",
"varianttomapconverter.cpp",
"varianttomapconverter.h",
"wangset.cpp",
"wangset.h",
]

Group {
Expand Down
51 changes: 51 additions & 0 deletions src/libtiled/mapreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "tilelayer.h"
#include "tilesetmanager.h"
#include "terrain.h"
#include "wangset.h"

#include <QCoreApplication>
#include <QDebug>
Expand Down Expand Up @@ -84,6 +85,7 @@ class MapReaderPrivate
void readTilesetGrid(Tileset &tileset);
void readTilesetImage(Tileset &tileset);
void readTilesetTerrainTypes(Tileset &tileset);
void readTilesetWangSets(Tileset &tileset);
ImageReference readImage();

Layer *tryReadLayer();
Expand Down Expand Up @@ -353,6 +355,8 @@ SharedTileset MapReaderPrivate::readTileset()
}
} else if (xml.name() == QLatin1String("terraintypes")) {
readTilesetTerrainTypes(*tileset);
} else if (xml.name() == QLatin1String("wangsets")) {
readTilesetWangSets(*tileset);
} else {
readUnknownElement();
}
Expand Down Expand Up @@ -564,6 +568,53 @@ void MapReaderPrivate::readTilesetTerrainTypes(Tileset &tileset)
}
}

void MapReaderPrivate::readTilesetWangSets(Tileset &tileset)
{
Q_ASSERT(xml.isStartElement() && xml.name() == QLatin1String("wangsets"));

while (xml.readNextStartElement()) {
if (xml.name() == QLatin1String("wangset")) {
const QXmlStreamAttributes atts = xml.attributes();
QString name = atts.value(QLatin1String("name")).toString();
int edges = atts.value(QLatin1String("edges")).toInt();
int corners = atts.value(QLatin1String("corners")).toInt();
int tile = atts.value(QLatin1String("tile")).toInt();

WangSet *wangSet = new WangSet(&tileset, edges, corners, name, tile);

tileset.addWangSet(wangSet);

while (xml.readNextStartElement()) {
if (xml.name() == QLatin1String("properties")) {
wangSet->mergeProperties(readProperties());
} else if (xml.name() == QLatin1String("wangtile")) {
const QXmlStreamAttributes tileAtts = xml.attributes();
int tileId = tileAtts.value(QLatin1String("tileid")).toInt();
unsigned wangId = tileAtts.value(QLatin1String("wangid")).toUInt();
bool fH = tileAtts.value(QLatin1String("hflip")).toInt();
bool fV = tileAtts.value(QLatin1String("vflip")).toInt();
bool fA = tileAtts.value(QLatin1String("dflip")).toInt();

Tile *tile = tileset.findOrCreateTile(tileId);

WangTile wangTile(tile, wangId);
wangTile.setFlippedHorizontally(fH);
wangTile.setFlippedVertically(fV);
wangTile.setFlippedAntiDiagonally(fA);

wangSet->addWangTile(wangTile);

xml.skipCurrentElement();
} else {
readUnknownElement();
}
}
} else {
readUnknownElement();
}
}
}

static void readLayerAttributes(Layer &layer,
const QXmlStreamAttributes &atts)
{
Expand Down
37 changes: 36 additions & 1 deletion src/libtiled/mapwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "tilelayer.h"
#include "tileset.h"
#include "terrain.h"
#include "wangset.h"

#include <QBuffer>
#include <QCoreApplication>
Expand Down Expand Up @@ -421,11 +422,45 @@ void MapWriterPrivate::writeTileset(QXmlStreamWriter &w, const Tileset &tileset,
}
w.writeEndElement(); // </animation>
}

w.writeEndElement(); // </tile>
}
}

// Write the wangsets
if (tileset.wangSetCount() > 0) {
w.writeStartElement(QLatin1String("wangsets"));
for (const WangSet *ws : tileset.wangSets()) {
w.writeStartElement(QLatin1String("wangset"));

w.writeAttribute(QLatin1String("name"), ws->name());
w.writeAttribute(QLatin1String("edges"), QString::number(ws->edgeColors()));
w.writeAttribute(QLatin1String("corners"), QString::number(ws->cornerColors()));
w.writeAttribute(QLatin1String("tile"), QString::number(ws->imageTileId()));

for (const WangTile &wangTile : ws->wangTiles()) {
w.writeStartElement(QLatin1String("wangtile"));
w.writeAttribute(QLatin1String("tileid"), QString::number(wangTile.tile()->id()));
w.writeAttribute(QLatin1String("wangid"), QString::number(wangTile.wangId()));

if (wangTile.flippedHorizontally())
w.writeAttribute(QLatin1String("hflip"), QString::number(1));

if (wangTile.flippedVertically())
w.writeAttribute(QLatin1String("vflip"), QString::number(1));

if (wangTile.flippedAntiDiagonally())
w.writeAttribute(QLatin1String("dflip"), QString::number(1));

w.writeEndElement(); // </wangtile>
}

writeProperties(w, ws->properties());

w.writeEndElement(); // </wangset>
}
w.writeEndElement(); // </wangsets>
}

w.writeEndElement();
}

Expand Down
2 changes: 2 additions & 0 deletions src/libtiled/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class TILEDSHARED_EXPORT Object
MapObjectType,
MapType,
TerrainType,
WangSetType,
TilesetType,
TileType
};
Expand Down Expand Up @@ -135,6 +136,7 @@ inline bool Object::isPartOfTileset() const
case Object::TilesetType:
case Object::TileType:
case Object::TerrainType:
case Object::WangSetType:
return true;
default:
return false;
Expand Down
40 changes: 40 additions & 0 deletions src/libtiled/tileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "terrain.h"
#include "tile.h"
#include "tilesetformat.h"
#include "wangset.h"

#include <QBitmap>

Expand Down Expand Up @@ -62,6 +63,7 @@ Tileset::~Tileset()
{
qDeleteAll(mTiles);
qDeleteAll(mTerrainTypes);
qDeleteAll(mWangSets);
}

void Tileset::setFormat(TilesetFormat *format)
Expand Down Expand Up @@ -505,6 +507,35 @@ void Tileset::recalculateTerrainDistances()
} while (bNewConnections);
}

void Tileset::addWangSet(WangSet *wangSet)
{
Q_ASSERT(wangSet->tileset() == this);

mWangSets.append(wangSet);
}

/**
* @brief Tileset::insertWangSet Adds a wangSet.
* @param wangSet A pointer to the wangset to add.
*/
void Tileset::insertWangSet(int index, WangSet *wangSet)
{
Q_ASSERT(wangSet->tileset() == this);

mWangSets.insert(index, wangSet);
}

/**
* @brief Tileset::takeWangSetAt Removes the wangset at a given index
* And returns it to the caller.
* @param index Index to take at.
* @return
*/
WangSet *Tileset::takeWangSetAt(int index)
{
return mWangSets.takeAt(index);
}

/**
* Adds a new tile to the end of the tileset.
*/
Expand Down Expand Up @@ -617,6 +648,7 @@ void Tileset::swap(Tileset &other)
std::swap(mTiles, other.mTiles);
std::swap(mNextTileId, other.mNextTileId);
std::swap(mTerrainTypes, other.mTerrainTypes);
std::swap(mWangSets, other.mWangSets);
std::swap(mTerrainDistancesDirty, other.mTerrainDistancesDirty);
std::swap(mLoaded, other.mLoaded);
std::swap(mBackgroundColor, other.mBackgroundColor);
Expand All @@ -629,11 +661,15 @@ void Tileset::swap(Tileset &other)
tile->mTileset = this;
for (auto terrain : mTerrainTypes)
terrain->mTileset = this;
for (auto wangSet : mWangSets)
wangSet->setTileset(this);

for (auto tile : other.mTiles)
tile->mTileset = &other;
for (auto terrain : other.mTerrainTypes)
terrain->mTileset = &other;
for (auto wangSet : other.mWangSets)
wangSet->setTileset(&other);
}

SharedTileset Tileset::clone() const
Expand Down Expand Up @@ -669,6 +705,10 @@ SharedTileset Tileset::clone() const
for (Terrain *terrain : mTerrainTypes)
c->mTerrainTypes.append(terrain->clone(c.data()));

c->mWangSets.reserve(mWangSets.size());
for (WangSet *wangSet : mWangSets)
c->mWangSets.append(wangSet->clone(c.data()));

return c;
}

Expand Down
25 changes: 25 additions & 0 deletions src/libtiled/tileset.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Tile;
class Tileset;
class TilesetFormat;
class Terrain;
class WangSet;

typedef QSharedPointer<Tileset> SharedTileset;

Expand Down Expand Up @@ -184,6 +185,14 @@ class TILEDSHARED_EXPORT Tileset : public Object

int terrainTransitionPenalty(int terrainType0, int terrainType1) const;

const QList<WangSet*> &wangSets() const;
int wangSetCount() const;
WangSet *wangSet(int index) const;

void addWangSet(WangSet *wangSet);
void insertWangSet(int index, WangSet *wangSet);
WangSet *takeWangSetAt(int index);

Tile *addTile(const QPixmap &image, const QString &source = QString());
void addTiles(const QList<Tile*> &tiles);
void removeTiles(const QList<Tile *> &tiles);
Expand Down Expand Up @@ -246,6 +255,7 @@ class TILEDSHARED_EXPORT Tileset : public Object
QMap<int, Tile*> mTiles;
int mNextTileId;
QList<Terrain*> mTerrainTypes;
QList<WangSet*> mWangSets;
bool mTerrainDistancesDirty;
bool mLoaded;
QColor mBackgroundColor;
Expand Down Expand Up @@ -553,6 +563,21 @@ inline Terrain *Tileset::terrain(int index) const
return index >= 0 ? mTerrainTypes[index] : nullptr;
}

inline const QList<WangSet*> &Tileset::wangSets() const
{
return mWangSets;
}

inline int Tileset::wangSetCount() const
{
return mWangSets.size();
}

inline WangSet *Tileset::wangSet(int index) const
{
return index >= 0 ? mWangSets[index] : nullptr;
}

/**
* Sets the next id to be used for tiles in this tileset.
*/
Expand Down
Loading

0 comments on commit 9e174f4

Please sign in to comment.