diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/gui/viewport.cpp | 24 | ||||
-rw-r--r-- | src/map.cpp | 208 | ||||
-rw-r--r-- | src/map.h | 110 | ||||
-rw-r--r-- | src/resources/imageset.cpp | 2 | ||||
-rw-r--r-- | src/resources/imageset.h | 14 | ||||
-rw-r--r-- | src/resources/mapreader.cpp | 151 | ||||
-rw-r--r-- | src/resources/mapreader.h | 4 | ||||
-rw-r--r-- | src/tileset.h | 3 |
9 files changed, 298 insertions, 228 deletions
@@ -1,3 +1,13 @@ +2008-04-08 Bjørn Lindeijer <bjorn@lindeijer.nl> + + * src/map.cpp, src/gui/viewport.cpp, src/tileset.h, src/map.h, + src/resources/imageset.cpp, src/resources/mapreader.cpp, + src/resources/imageset.h, src/resources/mapreader.h, + data/maps/new_3-1.tmx, data/maps/new_1-1.tmx: Implemented support for + an arbitrary number of map layers. The only layer requirement for map + layers are now that the fringe layer is called "Fringe" and that the + collision layer is called "Collision". + 2008-04-07 Bjørn Lindeijer <bjorn@lindeijer.nl> * src/particle.cpp, src/utils/xml.cpp, src/utils/xml.h, diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp index 7c68b577..33449659 100644 --- a/src/gui/viewport.cpp +++ b/src/gui/viewport.cpp @@ -48,6 +48,8 @@ #include <cassert> +extern volatile int tick_time; + Viewport::Viewport(): mMap(0), mViewX(0.0f), @@ -214,25 +216,17 @@ Viewport::draw(gcn::Graphics *gcnGraphics) // Draw tiles and sprites if (mMap) { - mMap->draw(graphics, (int) mViewX, (int) mViewY, 0); - drawTargetCursor(graphics); - mMap->draw(graphics, (int) mViewX, (int) mViewY, 1); - mMap->draw(graphics, (int) mViewX, (int) mViewY, 2); - if (mShowDebugPath) - { - mMap->drawCollision(graphics, (int) mViewX, (int) mViewY); - } - mMap->drawOverlay(graphics, mViewX, mViewY, - (int) config.getValue("OverlayDetail", 2)); + mMap->draw(graphics, (int) mViewX, (int) mViewY); + drawTargetCursor(graphics); // TODO: Draw the cursor with the sprite drawTargetName(graphics); - } - if (mShowDebugPath && mMap) - { - drawDebugPath(graphics); + if (mShowDebugPath) { + mMap->drawCollision(graphics, (int) mViewX, (int) mViewY); + drawDebugPath(graphics); + } } - // Draw player nickname, speech, and emotion sprite as needed + // Draw player names, speech, and emotion sprite as needed Beings &beings = beingManager->getAll(); for (BeingIterator i = beings.begin(); i != beings.end(); i++) { diff --git a/src/map.cpp b/src/map.cpp index c7d1d3b8..28d07022 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -28,6 +28,7 @@ #include <cassert> #include "beingmanager.h" +#include "configuration.h" #include "game.h" #include "graphics.h" #include "particle.h" @@ -41,6 +42,8 @@ #include "utils/dtor.h" #include "utils/tostring.h" +extern volatile int tick_time; + /** * A location on a tile map. Used for pathfinding, open list. */ @@ -63,6 +66,80 @@ struct Location MetaTile *tile; }; +MapLayer::MapLayer(int x, int y, int width, int height, bool isFringeLayer): + mX(x), mY(y), + mWidth(width), mHeight(height), + mIsFringeLayer(isFringeLayer) +{ + const int size = mWidth * mHeight; + mTiles = new Image*[size]; + std::fill_n(mTiles, size, (Image*) 0); +} + +MapLayer::~MapLayer() +{ + delete[] mTiles; +} + +void MapLayer::setTile(int x, int y, Image *img) +{ + mTiles[x + y * mWidth] = img; +} + +Image* MapLayer::getTile(int x, int y) const +{ + return mTiles[x + y * mWidth]; +} + +void MapLayer::draw(Graphics *graphics, + int startX, int startY, + int endX, int endY, + int scrollX, int scrollY, + const Sprites &sprites) const +{ + startX -= mX; + startY -= mY; + endX -= mX; + endY -= mY; + + if (startX < 0) startX = 0; + if (startY < 0) startY = 0; + if (endX > mWidth) endX = mWidth; + if (endY > mHeight) endY = mHeight; + + Sprites::const_iterator si = sprites.begin(); + + for (int y = startY; y < endY; y++) + { + // If drawing the fringe layer, make sure all sprites above this row of + // tiles have been drawn + if (mIsFringeLayer) { + while (si != sprites.end() && (*si)->getPixelY() <= y * 32 - 32) { + (*si)->draw(graphics, -scrollX, -scrollY); + si++; + } + } + + for (int x = startX; x < endX; x++) + { + Image *img = getTile(x, y); + if (img) { + const int px = (x + mX) * 32 - scrollX; + const int py = (y + mY) * 32 - scrollY + 32 - img->getHeight(); + graphics->drawImage(img, px, py); + } + } + } + + // Draw any remaining sprites + if (mIsFringeLayer) { + while (si != sprites.end()) { + (*si)->draw(graphics, -scrollX, -scrollY); + si++; + } + } +} + Map::Map(int width, int height, int tileWidth, int tileHeight): mWidth(width), mHeight(height), mTileWidth(tileWidth), mTileHeight(tileHeight), @@ -70,31 +147,26 @@ Map::Map(int width, int height, int tileWidth, int tileHeight): mOnClosedList(1), mOnOpenList(2), mLastScrollX(0.0f), mLastScrollY(0.0f) { - int size = mWidth * mHeight; + const int size = mWidth * mHeight; mMetaTiles = new MetaTile[size]; - for (int i=0; i < NB_BLOCKTYPES; i++) + for (int i = 0; i < NB_BLOCKTYPES; i++) { mOccupation[i] = new int[size]; memset(mOccupation[i], 0, size * sizeof(int)); } - mTiles = new Image*[size * 3]; - std::fill_n(mTiles, size * 3, (Image*)0); } Map::~Map() { - // clean up map data + // delete metadata, layers, tilesets and overlays delete[] mMetaTiles; - delete[] mTiles; for (int i=0; i < NB_BLOCKTYPES; i++) { delete[] mOccupation[i]; } - // clean up tilesets + for_each(mLayers.begin(), mLayers.end(), make_dtor(mLayers)); for_each(mTilesets.begin(), mTilesets.end(), make_dtor(mTilesets)); - mTilesets.clear(); - // clean up overlays for_each(mOverlays.begin(), mOverlays.end(), make_dtor(mOverlays)); } @@ -109,9 +181,9 @@ void Map::initializeOverlays() const std::string name = "overlay" + toString(i); Image *img = resman->getImage(getProperty(name + "image")); - float speedX = getFloatProperty(name + "scrollX"); - float speedY = getFloatProperty(name + "scrollY"); - float parallax = getFloatProperty(name + "parallax"); + const float speedX = getFloatProperty(name + "scrollX"); + const float speedY = getFloatProperty(name + "scrollY"); + const float parallax = getFloatProperty(name + "parallax"); if (img) { @@ -124,6 +196,11 @@ void Map::initializeOverlays() } } +void Map::addLayer(MapLayer *layer) +{ + mLayers.push_back(layer); +} + void Map::addTileset(Tileset *tileset) { mTilesets.push_back(tileset); @@ -137,63 +214,31 @@ bool spriteCompare(const Sprite *a, const Sprite *b) return a->getPixelY() < b->getPixelY(); } -void Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) +void Map::draw(Graphics *graphics, int scrollX, int scrollY) { int endPixelY = graphics->getHeight() + scrollY + mTileHeight - 1; - // If drawing the fringe layer, make sure sprites are sorted - SpriteIterator si; - if (layer == 1) - { - mSprites.sort(spriteCompare); - si = mSprites.begin(); - endPixelY += mMaxTileHeight - mTileHeight; - } + // TODO: Do this per-layer + endPixelY += mMaxTileHeight - mTileHeight; int startX = scrollX / mTileWidth; int startY = scrollY / mTileHeight; int endX = (graphics->getWidth() + scrollX + mTileWidth - 1) / mTileWidth; int endY = endPixelY / mTileHeight; - if (startX < 0) startX = 0; - if (startY < 0) startY = 0; - if (endX > mWidth) endX = mWidth; - if (endY > mHeight) endY = mHeight; + // Make sure sprites are sorted + mSprites.sort(spriteCompare); - for (int y = startY; y < endY; y++) - { - // If drawing the fringe layer, make sure all sprites above this row of - // tiles have been drawn - if (layer == 1) - { - while (si != mSprites.end() && (*si)->getPixelY() <= y * 32 - 32) - { - (*si)->draw(graphics, -scrollX, -scrollY); - si++; - } - } - - for (int x = startX; x < endX; x++) - { - Image *img = getTile(x, y, layer); - if (img) { - graphics->drawImage(img, - x * mTileWidth - scrollX, - y * mTileHeight - scrollY + - mTileHeight - img->getHeight()); - } - } + Layers::const_iterator layeri = mLayers.begin(); + for (; layeri != mLayers.end(); ++layeri) { + (*layeri)->draw(graphics, + startX, startY, endX, endY, + scrollX, scrollY, + mSprites); } - // Draw any remaining sprites - if (layer == 1) - { - while (si != mSprites.end()) - { - (*si)->draw(graphics, -scrollX, -scrollY); - si++; - } - } + drawOverlay(graphics, scrollX, scrollY, + (int) config.getValue("OverlayDetail", 2)); } void Map::drawCollision(Graphics *graphics, int scrollX, int scrollY) @@ -289,26 +334,10 @@ void Map::drawOverlay(Graphics *graphics, }; } -void Map::setTileWithGid(int x, int y, int layer, int gid) -{ - if (layer == 3) - { - Tileset *set = getTilesetWithGid(gid); - if (set && (gid - set->getFirstGid() != 0)) - { - blockTile(x, y, BLOCKTYPE_WALL); - } - } - else if (layer < 3) - { - setTile(x, y, layer, getTileWithGid(gid)); - } -} - class ContainsGidFunctor { public: - bool operator() (Tileset* set) + bool operator() (const Tileset* set) const { return (set->getFirstGid() <= gid && gid - set->getFirstGid() < (int)set->size()); @@ -326,17 +355,6 @@ Tileset* Map::getTilesetWithGid(int gid) const return (i == mTilesets.end()) ? NULL : *i; } -Image* Map::getTileWithGid(int gid) const -{ - Tileset *set = getTilesetWithGid(gid); - - if (set) { - return set->get(gid - set->getFirstGid()); - } - - return NULL; -} - void Map::blockTile(int x, int y, BlockType type) { if (type == BLOCKTYPE_NONE || x < 0 || y < 0 || x >= mWidth || y >= mHeight) @@ -412,16 +430,6 @@ bool Map::contains(int x, int y) const return x >= 0 && y >= 0 && x < mWidth && y < mHeight; } -void Map::setTile(int x, int y, int layer, Image *img) -{ - mTiles[x + y * mWidth + layer * (mWidth * mHeight)] = img; -} - -Image* Map::getTile(int x, int y, int layer) const -{ - return mTiles[x + y * mWidth + layer * (mWidth * mHeight)]; -} - MetaTile* Map::getMetaTile(int x, int y) const { return &mMetaTiles[x + y * mWidth]; @@ -484,8 +492,8 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w for (int dx = -1; dx <= 1; dx++) { // Calculate location of tile to check - int x = curr.x + dx; - int y = curr.y + dy; + const int x = curr.x + dx; + const int y = curr.y + dy; // Skip if if we're checking the same tile we're leaving from, // or if the new location falls outside of the map boundaries @@ -559,7 +567,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w // Update Gcost and Fcost of new tile newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; + newTile->Fcost = Gcost + newTile->Hcost; if (x != destX || y != destY) { // Add this tile to the open list @@ -576,7 +584,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w // Found a shorter route. // Update Gcost and Fcost of the new tile newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; + newTile->Fcost = Gcost + newTile->Hcost; // Set the current tile as the parent of the new tile newTile->parentX = curr.x; @@ -617,7 +625,7 @@ Path Map::findPath(int startX, int startY, int destX, int destY, unsigned char w return path; } -void Map::addParticleEffect (std::string effectFile, int x, int y) +void Map::addParticleEffect(const std::string &effectFile, int x, int y) { ParticleEffectData newEffect; newEffect.file = effectFile; @@ -32,6 +32,7 @@ class AmbientOverlay; class Graphics; class Image; +class MapLayer; class Particle; class Sprite; class Tileset; @@ -41,8 +42,7 @@ struct PATH_NODE; typedef std::vector<Tileset*> Tilesets; typedef std::list<Sprite*> Sprites; typedef Sprites::iterator SpriteIterator; - -extern volatile int tick_time; +typedef std::vector<MapLayer*> Layers; /** * A meta tile stores additional information about a location on a tile map. @@ -67,6 +67,56 @@ struct MetaTile }; /** + * A map layer. Stores a grid of tiles and their offset, and implements layer + * rendering. + */ +class MapLayer +{ + public: + /** + * Constructor, taking layer origin, size and whether this layer is the + * fringe layer. The fringe layer is the layer that draws the sprites. + * There can be only one fringe layer per map. + */ + MapLayer(int x, int y, int width, int height, bool isFringeLayer); + + /** + * Destructor. + */ + ~MapLayer(); + + /** + * Set tile image, with x and y in layer coordinates. + */ + void setTile(int x, int y, Image *img); + + /** + * Get tile image, with x and y in layer coordinates. + */ + Image *getTile(int x, int y) const; + + /** + * Draws this layer to the given graphics context. The coordinates are + * expected to be in map range and will be translated to local layer + * coordinates and clipped to the layer's dimensions. + * + * The given sprites are only drawn when this layer is the fringe + * layer. + */ + void draw(Graphics *graphics, + int startX, int startY, + int endX, int endY, + int scrollX, int scrollY, + const Sprites &sprites) const; + + private: + int mX, mY; + int mWidth, mHeight; + bool mIsFringeLayer; /**< Whether the sprites are drawn. */ + Image **mTiles; +}; + +/** * A tile map. */ class Map : public Properties @@ -98,9 +148,14 @@ class Map : public Properties void initializeOverlays(); /** - * Draws a map layer to the given graphics output. + * Draws the map to the given graphics output. This method draws all + * layers, sprites and overlay effects. + * + * TODO: For efficiency reasons, this method could take into account + * the clipping rectangle set on the Graphics object. However, + * currently the map is always drawn full-screen. */ - void draw(Graphics *graphics, int scrollX, int scrollY, int layer); + void draw(Graphics *graphics, int scrollX, int scrollY); /** * Visualizes collision layer for debugging @@ -108,34 +163,20 @@ class Map : public Properties void drawCollision(Graphics *graphics, int scrollX, int scrollY); /** - * Draws the overlay graphic to the given graphics output. - */ - void - drawOverlay(Graphics *graphics, float scrollX, float scrollY, - int detail); - - /** - * Adds a tileset to this map. - */ - void - addTileset(Tileset *tileset); - - /** - * Sets a tile using a global tile id. Used by the layer loading - * routine. + * Adds a layer to this map. The map takes ownership of the layer. */ - void - setTileWithGid(int x, int y, int layer, int gid); + void addLayer(MapLayer *layer); /** - * Set tile ID. + * Adds a tileset to this map. The map takes ownership of the tileset. */ - void setTile(int x, int y, int layer, Image *img); + void addTileset(Tileset *tileset); /** - * Get tile ID. + * Finds the tile set that a tile with the given global id is part of. */ - Image *getTile(int x, int y, int layer) const; + Tileset* + getTilesetWithGid(int gid) const; /** * Get tile reference. @@ -203,7 +244,7 @@ class Map : public Properties /** * Adds a particle effect */ - void addParticleEffect (std::string effectFile, int x, int y); + void addParticleEffect(const std::string &effectFile, int x, int y); /** * Initializes all added particle effects @@ -213,15 +254,11 @@ class Map : public Properties private: /** - * Converts a global tile id to the Image* pointing to the associated - * tile image. - */ - Image* getTileWithGid(int gid) const; - - /** - * Finds the tile set that a tile with the given global id is part of. + * Draws the overlay graphic to the given graphics output. */ - Tileset* getTilesetWithGid(int gid) const; + void + drawOverlay(Graphics *graphics, float scrollX, float scrollY, + int detail); /** * Tells whether the given coordinates fall within the map boundaries. @@ -243,15 +280,14 @@ class Map : public Properties int mTileWidth, mTileHeight; int mMaxTileHeight; MetaTile *mMetaTiles; - Image **mTiles; - + Layers mLayers; Tilesets mTilesets; Sprites mSprites; // Pathfinding members int mOnClosedList, mOnOpenList; - // Overlay Data + // Overlay data std::list<AmbientOverlay*> mOverlays; float mLastScrollX; float mLastScrollY; diff --git a/src/resources/imageset.cpp b/src/resources/imageset.cpp index 08a6a110..5618abfa 100644 --- a/src/resources/imageset.cpp +++ b/src/resources/imageset.cpp @@ -50,7 +50,7 @@ ImageSet::~ImageSet() } Image* -ImageSet::get(size_type i) +ImageSet::get(size_type i) const { if (i >= mImages.size()) { diff --git a/src/resources/imageset.h b/src/resources/imageset.h index 15c21d90..fa1840ec 100644 --- a/src/resources/imageset.h +++ b/src/resources/imageset.h @@ -47,14 +47,20 @@ class ImageSet : public Resource */ ~ImageSet(); - int getWidth() { return mWidth; }; + /** + * Returns the width of the images in the image set. + */ + int getWidth() const { return mWidth; }; - int getHeight() { return mHeight; }; + /** + * Returns the height of the images in the image set. + */ + int getHeight() const { return mHeight; }; typedef std::vector<Image*>::size_type size_type; - Image* get(size_type i); + Image* get(size_type i) const; - size_type size() { return mImages.size(); } + size_type size() const { return mImages.size(); } private: std::vector<Image*> mImages; diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index 3864580b..9c6c52aa 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -206,20 +206,17 @@ MapReader::readMap(const std::string &filename) Map* MapReader::readMap(xmlNodePtr node, const std::string &path) { - xmlChar *prop; - // Take the filename off the path - std::string pathDir = path.substr(0, path.rfind("/") + 1); + const std::string pathDir = path.substr(0, path.rfind("/") + 1); - prop = xmlGetProp(node, BAD_CAST "version"); - xmlFree(prop); + //xmlChar *prop = xmlGetProp(node, BAD_CAST "version"); + //xmlFree(prop); - int w = XML::getProperty(node, "width", 0); - int h = XML::getProperty(node, "height", 0); - int tilew = XML::getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); - int tileh = XML::getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); - int layerNr = 0; - Map *map = new Map(w, h, tilew, tileh); + const int w = XML::getProperty(node, "width", 0); + const int h = XML::getProperty(node, "height", 0); + const int tw = XML::getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); + const int th = XML::getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); + Map *map = new Map(w, h, tw, th); for_each_xml_child_node(childNode, node) { @@ -232,9 +229,7 @@ MapReader::readMap(xmlNodePtr node, const std::string &path) } else if (xmlStrEqual(childNode->name, BAD_CAST "layer")) { - logger->log("- Loading layer %d", layerNr); - readLayer(childNode, map, layerNr); - layerNr++; + readLayer(childNode, map); } else if (xmlStrEqual(childNode->name, BAD_CAST "properties")) { @@ -246,7 +241,8 @@ MapReader::readMap(xmlNodePtr node, const std::string &path) { if (xmlStrEqual(objectNode->name, BAD_CAST "object")) { - std::string objType = XML::getProperty(objectNode, "type", ""); + const std::string objType = + XML::getProperty(objectNode, "type", ""); if (objType == "WARP" || objType == "NPC" || objType == "SCRIPT" || objType == "SPAWN") @@ -255,9 +251,10 @@ MapReader::readMap(xmlNodePtr node, const std::string &path) continue; } - std::string objName = XML::getProperty(objectNode, "name", ""); - int objX = XML::getProperty(objectNode, "x", 0); - int objY = XML::getProperty(objectNode, "y", 0); + const std::string objName = + XML::getProperty(objectNode, "name", ""); + const int objX = XML::getProperty(objectNode, "x", 0); + const int objY = XML::getProperty(objectNode, "y", 0); logger->log("- Loading object name: %s type: %s at %d:%d", objName.c_str(), objType.c_str(), objX, objY); @@ -288,43 +285,67 @@ MapReader::readProperties(xmlNodePtr node, Properties* props) continue; // Example: <property name="name" value="value"/> - xmlChar *name = xmlGetProp(childNode, BAD_CAST "name"); - xmlChar *value = xmlGetProp(childNode, BAD_CAST "value"); + const std::string name = XML::getProperty(childNode, "name", ""); + const std::string value = XML::getProperty(childNode, "value", ""); - if (name && value) { - props->setProperty((const char*)name, (const char*)value); - } + if (!name.empty() && !value.empty()) + props->setProperty(name, value); + } +} - if (name) xmlFree(name); - if (value) xmlFree(value); +static void setTile(Map *map, MapLayer *layer, int x, int y, int gid) +{ + const Tileset * const set = map->getTilesetWithGid(gid); + if (layer) { + // Set regular tile on a layer + Image * const img = set ? set->get(gid - set->getFirstGid()) : 0; + layer->setTile(x, y, img); + } else { + // Set collision tile + if (set && (gid - set->getFirstGid() != 0)) + map->blockTile(x, y, Map::BLOCKTYPE_WALL); } } void -MapReader::readLayer(xmlNodePtr node, Map *map, int layer) +MapReader::readLayer(xmlNodePtr node, Map *map) { - int h = map->getHeight(); - int w = map->getWidth(); + // Layers are not necessarily the same size as the map + const int w = XML::getProperty(node, "width", map->getWidth()); + const int h = XML::getProperty(node, "height", map->getHeight()); + const int offsetX = XML::getProperty(node, "xoffset", 0); + const int offsetY = XML::getProperty(node, "yoffset", 0); + const std::string name = XML::getProperty(node, "name", ""); + + const bool isFringeLayer = (name == "Fringe"); + const bool isCollisionLayer = (name == "Collision"); + + MapLayer *layer = 0; + + if (!isCollisionLayer) { + layer = new MapLayer(offsetX, offsetY, w, h, isFringeLayer); + map->addLayer(layer); + } + + logger->log("- Loading layer \"%s\"", name.c_str()); int x = 0; int y = 0; - // Load the tile data. Layers are assumed to be map size, with (0,0) as - // origin. + // Load the tile data for_each_xml_child_node(childNode, node) { if (!xmlStrEqual(childNode->name, BAD_CAST "data")) continue; - xmlChar *encoding = xmlGetProp(childNode, BAD_CAST "encoding"); - xmlChar *compression = xmlGetProp(childNode, BAD_CAST "compression"); + const std::string encoding = + XML::getProperty(childNode, "encoding", ""); + const std::string compression = + XML::getProperty(childNode, "compression", ""); - if (encoding && xmlStrEqual(encoding, BAD_CAST "base64")) + if (encoding == "base64") { - xmlFree(encoding); - - if (compression && !xmlStrEqual(compression, BAD_CAST "gzip")) { + if (!compression.empty() && compression != "gzip") { logger->log("Warning: only gzip layer compression supported!"); - xmlFree(compression); return; } @@ -356,34 +377,29 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer) delete[] charData; if (binData) { - if (compression) { - if (xmlStrEqual(compression, BAD_CAST "gzip")) { - // Inflate the gzipped layer data - unsigned char *inflated; - unsigned int inflatedSize = - inflateMemory(binData, binLen, inflated); - - free(binData); - binData = inflated; - binLen = inflatedSize; - - if (inflated == NULL) - { - logger->log("Error: Could not decompress layer!"); - xmlFree(compression); - return; - } + if (compression == "gzip") { + // Inflate the gzipped layer data + unsigned char *inflated; + unsigned int inflatedSize = + inflateMemory(binData, binLen, inflated); + + free(binData); + binData = inflated; + binLen = inflatedSize; + + if (!inflated) { + logger->log("Error: Could not decompress layer!"); + return; } - xmlFree(compression); } for (int i = 0; i < binLen - 3; i += 4) { - int gid = binData[i] | + const int gid = binData[i] | binData[i + 1] << 8 | binData[i + 2] << 16 | binData[i + 3] << 24; - map->setTileWithGid(x, y, layer, gid); + setTile(map, layer, x, y, gid); x++; if (x == w) {x = 0; y++;} @@ -398,8 +414,8 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer) if (!xmlStrEqual(childNode2->name, BAD_CAST "tile")) continue; - int gid = XML::getProperty(childNode2, "gid", -1); - map->setTileWithGid(x, y, layer, gid); + const int gid = XML::getProperty(childNode2, "gid", -1); + setTile(map, layer, x, y, gid); x++; if (x == w) { @@ -431,20 +447,20 @@ MapReader::readTileset(xmlNodePtr node, return NULL; } - int firstGid = XML::getProperty(node, "firstgid", 0); - int tw = XML::getProperty(node, "tilewidth", map->getTileWidth()); - int th = XML::getProperty(node, "tileheight", map->getTileHeight()); + const int firstGid = XML::getProperty(node, "firstgid", 0); + const int tw = XML::getProperty(node, "tilewidth", map->getTileWidth()); + const int th = XML::getProperty(node, "tileheight", map->getTileHeight()); for_each_xml_child_node(childNode, node) { if (!xmlStrEqual(childNode->name, BAD_CAST "image")) continue; - xmlChar* source = xmlGetProp(childNode, BAD_CAST "source"); + const std::string source = XML::getProperty(childNode, "source", ""); - if (source) + if (!source.empty()) { - std::string sourceStr = std::string((const char*)source); + std::string sourceStr = source; sourceStr.erase(0, 3); // Remove "../" ResourceManager *resman = ResourceManager::getInstance(); @@ -454,14 +470,15 @@ MapReader::readTileset(xmlNodePtr node, { Tileset *set = new Tileset(tilebmp, tw, th, firstGid); tilebmp->decRef(); - xmlFree(source); return set; } else { - logger->log("Warning: Failed to load tileset (%s)", source); + logger->log("Warning: Failed to load tileset (%s)", + source.c_str()); } } + // Only one image element expected break; } diff --git a/src/resources/mapreader.h b/src/resources/mapreader.h index d16ff1d5..60056358 100644 --- a/src/resources/mapreader.h +++ b/src/resources/mapreader.h @@ -63,10 +63,10 @@ class MapReader readProperties(xmlNodePtr node, Properties* props); /** - * Reads a map layer. + * Reads a map layer and adds it to the given map. */ static void - readLayer(xmlNodePtr node, Map *map, int layer); + readLayer(xmlNodePtr node, Map *map); /** * Reads a tile set. diff --git a/src/tileset.h b/src/tileset.h index 6af69235..625fac1b 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -44,8 +44,7 @@ class Tileset : public ImageSet /** * Returns the first gid. */ - int - getFirstGid() + int getFirstGid() const { return mFirstGid; } |