diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2005-09-29 11:03:48 +0000 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2005-09-29 11:03:48 +0000 |
commit | c00d3acf930359740ae6125533b5233ae06b765e (patch) | |
tree | a1ba92c7142c455e95758b37daf35a959903bf8a /src | |
parent | 4d117b39c555966d7648a03e0127560278e47170 (diff) | |
download | mana-c00d3acf930359740ae6125533b5233ae06b765e.tar.gz mana-c00d3acf930359740ae6125533b5233ae06b765e.tar.bz2 mana-c00d3acf930359740ae6125533b5233ae06b765e.tar.xz mana-c00d3acf930359740ae6125533b5233ae06b765e.zip |
Moved tileset management into the map class and made sure the tilesets are
cleaned up properly on switching maps.
Diffstat (limited to 'src')
-rw-r--r-- | src/map.cpp | 137 | ||||
-rw-r--r-- | src/map.h | 60 | ||||
-rw-r--r-- | src/resources/mapreader.cpp | 112 | ||||
-rw-r--r-- | src/resources/mapreader.h | 46 | ||||
-rw-r--r-- | src/resources/resourcemanager.cpp | 21 | ||||
-rw-r--r-- | src/resources/resourcemanager.h | 23 | ||||
-rw-r--r-- | src/tileset.h | 57 |
7 files changed, 245 insertions, 211 deletions
diff --git a/src/map.cpp b/src/map.cpp index 2e1b3a00..e74a3203 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -22,7 +22,7 @@ */ #include "map.h" - +#include "tileset.h" #include "being.h" #include "graphics.h" @@ -44,40 +44,44 @@ bool Location::operator< (const Location &loc) const return tile->Fcost > loc.tile->Fcost; } - -Map::Map(): - width(0), height(0), - tileWidth(32), tileHeight(32), +Map::Map(int width, int height, int tileWidth, int tileHeight): + mWidth(width), mHeight(height), + mTileWidth(tileWidth), mTileHeight(tileHeight), onClosedList(1), onOpenList(2) { - metaTiles = new MetaTile[width * height]; - tiles = new Image*[width * height * 3]; -} - -Map::Map(int width, int height): - width(width), height(height), - tileWidth(32), tileHeight(32), - onClosedList(1), onOpenList(2) -{ - metaTiles = new MetaTile[width * height]; - tiles = new Image*[width * height * 3]; + metaTiles = new MetaTile[mWidth * mHeight]; + tiles = new Image*[mWidth * mHeight * 3]; } Map::~Map() { delete[] metaTiles; delete[] tiles; + + // Clean up tilesets + Tilesets::iterator i; + for (i = tilesets.begin(); i != tilesets.end(); i++) + { + delete (*i); + } + tilesets.clear(); } void Map::setSize(int width, int height) { - this->width = width; - this->height = height; + mWidth = width; + mHeight = height; delete[] metaTiles; delete[] tiles; - metaTiles = new MetaTile[width * height]; - tiles = new Image*[width * height * 3]; + metaTiles = new MetaTile[mWidth * mHeight]; + tiles = new Image*[mWidth * mHeight * 3]; +} + +void +Map::addTileset(Tileset *tileset) +{ + tilesets.push_back(tileset); } void @@ -90,8 +94,8 @@ Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) if (startX < 0) startX = 0; if (startY < 0) startY = 0; - if (endX >= width) endX = width - 1; - if (endY >= height) endY = height - 1; + if (endX >= mWidth) endX = mWidth - 1; + if (endY >= mHeight) endY = mHeight - 1; for (int y = startY; y < endY; y++) { @@ -106,9 +110,60 @@ Map::draw(Graphics *graphics, int scrollX, int scrollY, int layer) } void +Map::setTileWithGid(int x, int y, int layer, int gid) +{ + if (layer == 3) + { + Tileset *set = getTilesetWithGid(gid); + setWalk(x, y, (!set || (gid - set->getFirstGid() == 0))); + } + else if (layer < 3) + { + setTile(x, y, layer, getTileWithGid(gid)); + } +} + +Tileset* +Map::getTilesetWithGid(int gid) +{ + Tilesets::iterator i; + Tileset *set = NULL; + + // Find the tileset with the highest firstGid below/equal to gid + for (i = tilesets.begin(); i != tilesets.end(); ++i) + { + if ((*i)->getFirstGid() <= gid) { + set = (*i); + } + else { + break; + } + } + + if (set && (gid - set->getFirstGid()) < (int)set->spriteset.size()) + { + return set; + } + + return NULL; +} + +Image* +Map::getTileWithGid(int gid) +{ + Tileset *set = getTilesetWithGid(gid); + + if (set) { + return set->spriteset[gid - set->getFirstGid()]; + } + + return NULL; +} + +void Map::setWalk(int x, int y, bool walkable) { - metaTiles[x + y * width].walkable = walkable; + metaTiles[x + y * mWidth].walkable = walkable; } bool @@ -136,54 +191,30 @@ bool Map::tileCollides(int x, int y) { // You can't walk outside of the map - if (x < 0 || y < 0 || x >= width || y >= height) { + if (x < 0 || y < 0 || x >= mWidth || y >= mHeight) { return true; } // Check if the tile is walkable - return !metaTiles[x + y * width].walkable; + return !metaTiles[x + y * mWidth].walkable; } void Map::setTile(int x, int y, int layer, Image *img) { - tiles[x + y * width + layer * (width * height)] = img; + tiles[x + y * mWidth + layer * (mWidth * mHeight)] = img; } Image* Map::getTile(int x, int y, int layer) { - return tiles[x + y * width + layer * (width * height)]; + return tiles[x + y * mWidth + layer * (mWidth * mHeight)]; } MetaTile* Map::getMetaTile(int x, int y) { - return &metaTiles[x + y * width]; -} - -int -Map::getWidth() -{ - return width; -} - -int -Map::getHeight() -{ - return height; -} - -int -Map::getTileWidth() -{ - return tileWidth; -} - -int -Map::getTileHeight() -{ - return tileHeight; + return &metaTiles[x + y * mWidth]; } std::string @@ -262,7 +293,7 @@ Map::findPath(int startX, int startY, int destX, int destY) // Skip if if we're checking the same tile we're leaving from, // or if the new location falls outside of the map boundaries if ((dx == 0 && dy == 0) || - (x < 0 || y < 0 || x >= width || y >= height)) + (x < 0 || y < 0 || x >= mWidth || y >= mHeight)) { continue; } @@ -26,10 +26,12 @@ #include <list> #include <map> +#include <vector> class Being; class Graphics; class Image; +class Tileset; struct PATH_NODE; @@ -83,14 +85,9 @@ class Map { public: /** - * Constructor. + * Constructor, taking map and tile size as parameters. */ - Map(); - - /** - * Constructor that takes initial map size as parameters. - */ - Map(int width, int height); + Map(int width, int height, int tileWidth, int tileHeight); /** * Destructor. @@ -108,6 +105,19 @@ class Map void setSize(int width, int height); /** + * Adds a tileset to this map. + */ + void + addTileset(Tileset *tileset); + + /** + * Sets a tile using a global tile id. Used by the layer loading + * routine. + */ + void + setTileWithGid(int x, int y, int layer, int gid); + + /** * Set tile ID. */ void setTile(int x, int y, int layer, Image *img); @@ -140,28 +150,32 @@ class Map /** * Returns the width of this map. */ - int getWidth(); + int + getWidth() { return mWidth; } /** * Returns the height of this map. */ - int getHeight(); + int + getHeight() { return mHeight; } /** * Returns the tile width of this map. */ - int getTileWidth(); + int + getTileWidth() { return mTileWidth; } /** * Returns the tile height used by this map. */ - int getTileHeight(); + int + getTileHeight() { return mTileHeight; } /** * Find a path from one location to the next. */ - std::list<PATH_NODE> findPath( - int startX, int startY, int destX, int destY); + std::list<PATH_NODE> + findPath(int startX, int startY, int destX, int destY); /** * Get a map property. @@ -182,12 +196,28 @@ class Map void setProperty(const std::string &name, const std::string &value); private: - int width, height; - int tileWidth, tileHeight; + /** + * Converts a global tile id to the Image* pointing to the associated + * tile image. + */ + Image* + getTileWithGid(int gid); + + /** + * Finds the tile set that a tile with the given global id is part of. + */ + Tileset* + getTilesetWithGid(int gid); + + int mWidth, mHeight; + int mTileWidth, mTileHeight; MetaTile *metaTiles; Image **tiles; std::map<std::string,std::string> properties; + typedef std::vector<Tileset*> Tilesets; + Tilesets tilesets; + // Pathfinding members int onClosedList, onOpenList; }; diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index b5b1a142..bddc1092 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -27,10 +27,12 @@ #include <zlib.h> #include "resourcemanager.h" +#include "image.h" #include "../base64.h" #include "../log.h" #include "../map.h" +#include "../tileset.h" #include "../graphic/spriteset.h" @@ -43,9 +45,8 @@ const unsigned int DEFAULT_TILE_HEIGHT = 32; * expected to be freed by the caller. */ int -inflateMemory( - unsigned char *in, unsigned int inLength, - unsigned char *&out, unsigned int &outLength) +inflateMemory(unsigned char *in, unsigned int inLength, + unsigned char *&out, unsigned int &outLength) { int bufferSize = 256 * 1024; int ret; @@ -109,21 +110,8 @@ inflateMemory( return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; } -std::vector<Tileset*> MapReader::tilesets; - -Tileset::Tileset(Image *img, int w, int h, int firstGid): - Spriteset(img, w, h), - firstGid(firstGid) -{ -} - -int Tileset::getFirstGid() -{ - return firstGid; -} - - -Map *MapReader::readMap(const std::string &filename) +Map* +MapReader::readMap(const std::string &filename) { // Load the file through resource manager ResourceManager *resman = ResourceManager::getInstance(); @@ -140,8 +128,8 @@ Map *MapReader::readMap(const std::string &filename) // Inflate the gzipped map data unsigned char *inflated; unsigned int inflatedSize = 0; - int ret = inflateMemory( - (unsigned char*)buffer, fileSize, inflated, inflatedSize); + int ret = inflateMemory((unsigned char*)buffer, + fileSize, inflated, inflatedSize); free(buffer); if (ret == Z_MEM_ERROR) @@ -188,7 +176,8 @@ Map *MapReader::readMap(const std::string &filename) return map; } -Map* MapReader::readMap(xmlNodePtr node, const std::string &path) +Map* +MapReader::readMap(xmlNodePtr node, const std::string &path) { xmlChar *prop; @@ -200,11 +189,10 @@ Map* MapReader::readMap(xmlNodePtr node, const std::string &path) int w = getProperty(node, "width", 0); int h = getProperty(node, "height", 0); - // We only support tile width of 32 at the moment - //int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); - //int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); + int tilew = getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); + int tileh = getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); int layerNr = 0; - Map* map = new Map(w, h); + Map* map = new Map(w, h, tilew, tileh); for (node = node->xmlChildrenNode; node != NULL; node = node->next) { @@ -227,7 +215,7 @@ Map* MapReader::readMap(xmlNodePtr node, const std::string &path) { Tileset *tileset = readTileset(node, pathDir, map); if (tileset) { - tilesets.push_back(tileset); + map->addTileset(tileset); } } else if (xmlStrEqual(node->name, BAD_CAST "layer")) @@ -238,14 +226,11 @@ Map* MapReader::readMap(xmlNodePtr node, const std::string &path) } } - // Clean up tilesets - // TODO: Dereference them somewhere - tilesets.clear(); - return map; } -void MapReader::readLayer(xmlNodePtr node, Map *map, int layer) +void +MapReader::readLayer(xmlNodePtr node, Map *map, int layer) { node = node->xmlChildrenNode; int h = map->getHeight(); @@ -306,7 +291,7 @@ void MapReader::readLayer(xmlNodePtr node, Map *map, int layer) binData[i + 2] << 16 | binData[i + 3] << 24; - setTileWithGid(map, x, y, layer, gid); + map->setTileWithGid(x, y, layer, gid); x++; if (x == w) {x = 0; y++;} @@ -323,7 +308,7 @@ void MapReader::readLayer(xmlNodePtr node, Map *map, int layer) if (xmlStrEqual(n2->name, BAD_CAST "tile") && y < h) { int gid = getProperty(n2, "gid", -1); - setTileWithGid(map, x, y, layer, gid); + map->setTileWithGid(x, y, layer, gid); x++; if (x == w) {x = 0; y++;} @@ -341,10 +326,13 @@ void MapReader::readLayer(xmlNodePtr node, Map *map, int layer) } } -Tileset* MapReader::readTileset( - xmlNodePtr node, const std::string &path, Map *map) +Tileset* +MapReader::readTileset(xmlNodePtr node, + const std::string &path, + Map *map) { - if (xmlHasProp(node, BAD_CAST "source")) { + if (xmlHasProp(node, BAD_CAST "source")) + { logger->log("Warning: External tilesets not supported yet."); return NULL; } @@ -372,6 +360,7 @@ Tileset* MapReader::readTileset( if (tilebmp) { Tileset *set = new Tileset(tilebmp, tw, th, firstGid); + tilebmp->decRef(); xmlFree(source); return set; } @@ -389,7 +378,8 @@ Tileset* MapReader::readTileset( return NULL; } -int MapReader::getProperty(xmlNodePtr node, const char* name, int def) +int +MapReader::getProperty(xmlNodePtr node, const char* name, int def) { xmlChar *prop = xmlGetProp(node, BAD_CAST name); if (prop) { @@ -401,51 +391,3 @@ int MapReader::getProperty(xmlNodePtr node, const char* name, int def) return def; } } - -Image *MapReader::getTileWithGid(int gid) -{ - Tileset *set = getTilesetWithGid(gid); - - if (set) { - return set->spriteset[gid - set->getFirstGid()]; - } - - return NULL; -} - -Tileset *MapReader::getTilesetWithGid(int gid) -{ - std::vector<Tileset*>::iterator i; - Tileset *set = NULL; - - // Find the tileset with the highest firstGid below/eq to gid - for (i = tilesets.begin(); i != tilesets.end(); ++i) - { - if ((*i)->getFirstGid() <= gid) { - set = (*i); - } - else { - break; - } - } - - if (set && (gid - set->getFirstGid()) < (int)set->spriteset.size()) - { - return set; - } - - return NULL; -} - -void MapReader::setTileWithGid(Map *map, int x, int y, int layer, int gid) -{ - if (layer == 3) - { - Tileset *set = getTilesetWithGid(gid); - map->setWalk(x, y, - !set || (gid - set->getFirstGid() == 0)); - } - else if (layer < 3) { - map->setTile(x, y, layer, getTileWithGid(gid)); - } -} diff --git a/src/resources/mapreader.h b/src/resources/mapreader.h index f37a67c3..1e4ada64 100644 --- a/src/resources/mapreader.h +++ b/src/resources/mapreader.h @@ -21,8 +21,8 @@ * $Id$ */ -#ifndef _INCLUDED_MAPREADER_H -#define _INCLUDED_MAPREADER_H +#ifndef _TMW_MAPREADER_H_ +#define _TMW_MAPREADER_H_ #include <vector> @@ -31,25 +31,7 @@ #include "../graphic/spriteset.h" class Map; - -/** - * A tileset, which is basically just a spriteset but it stores a firstgid. - */ -class Tileset : public Spriteset { - public: - /** - * Constructor. - */ - Tileset(Image *img, int w, int h, int firstGid); - - /** - * Returns the first gid. - */ - int getFirstGid(); - - private: - int firstGid; -}; +class Tileset; /** * Reader for XML map files (*.tmx) @@ -88,28 +70,6 @@ class MapReader */ static int getProperty(xmlNodePtr node, const char* name, int def); - - /** - * Converts a global tile id to the Image* pointing to the associated - * tile image. - */ - static Image* - getTileWithGid(int gid); - - /** - * Finds the tile set that a tile with the given global id is part of. - */ - static Tileset* - getTilesetWithGid(int gid); - - /** - * Sets a tile using a global tile id. Used by the layer loading - * routine. - */ - static void - setTileWithGid(Map *map, int x, int y, int layer, int gid); - - static std::vector<Tileset*> tilesets; }; #endif diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 39b8dfff..c941e16e 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -62,18 +62,22 @@ ResourceManager::~ResourceManager() "to %d resources", danglingReferences, danglingResources); } -bool ResourceManager::setWriteDir(const std::string &path) +bool +ResourceManager::setWriteDir(const std::string &path) { return (bool)PHYSFS_setWriteDir(path.c_str()); } -void ResourceManager::addToSearchPath(const std::string &path, bool append) +void +ResourceManager::addToSearchPath(const std::string &path, bool append) { PHYSFS_addToSearchPath(path.c_str(), append ? 1 : 0); } -void ResourceManager::searchAndAddArchives( - const std::string &path, const std::string &ext, bool append) +void +ResourceManager::searchAndAddArchives(const std::string &path, + const std::string &ext, + bool append) { const char *dirSep = PHYSFS_getDirSeparator(); char **list = PHYSFS_enumerateFiles(path.c_str()); @@ -98,17 +102,20 @@ void ResourceManager::searchAndAddArchives( PHYSFS_freeList(list); } -bool ResourceManager::mkdir(const std::string &path) +bool +ResourceManager::mkdir(const std::string &path) { return (bool)PHYSFS_mkdir(path.c_str()); } -bool ResourceManager::exists(const std::string &path) +bool +ResourceManager::exists(const std::string &path) { return PHYSFS_exists(path.c_str()); } -bool ResourceManager::isDirectory(const std::string &path) +bool +ResourceManager::isDirectory(const std::string &path) { return PHYSFS_isDirectory(path.c_str()); } diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h index a11ea4cb..a5a66901 100644 --- a/src/resources/resourcemanager.h +++ b/src/resources/resourcemanager.h @@ -63,38 +63,45 @@ class ResourceManager ~ResourceManager(); /** - * Sets the write directory + * Sets the write directory. * * @param path The path of the directory to be added. * @return <code>true</code> on success, <code>false</code> otherwise. */ - bool setWriteDir(const std::string &path); + bool + setWriteDir(const std::string &path); /** * Adds a directory or archive to the search path. */ - void addToSearchPath(const std::string &path, bool append); + void + addToSearchPath(const std::string &path, bool append); /** * Searches for zip files and adds them to the search path. */ - void searchAndAddArchives( - const std::string &path, const std::string &ext, bool append); + void + searchAndAddArchives(const std::string &path, + const std::string &ext, + bool append); /** * Creates a directory in the write path */ - bool mkdir(const std::string &path); + bool + mkdir(const std::string &path); /** * Checks whether the given file or directory exists in the search path */ - bool exists(const std::string &path); + bool + exists(const std::string &path); /** * Checks whether the given path is a directory. */ - bool isDirectory(const std::string &path); + bool + isDirectory(const std::string &path); /** * Creates a resource and adds it to the resource map. The idPath is diff --git a/src/tileset.h b/src/tileset.h new file mode 100644 index 00000000..5fa4ade1 --- /dev/null +++ b/src/tileset.h @@ -0,0 +1,57 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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; either version 2 of the License, or + * any later version. + * + * The Mana World 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 for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMW_TILESET_H_ +#define _TMW_TILESET_H_ + +#include "graphic/spriteset.h" + +/** + * A tileset, which is basically just a spriteset but it stores a firstgid. + */ +class Tileset : public Spriteset +{ + public: + /** + * Constructor. + */ + Tileset(Image *img, int w, int h, int firstGid): + Spriteset(img, w, h), + mFirstGid(firstGid) + { + } + + /** + * Returns the first gid. + */ + int + getFirstGid() + { + return mFirstGid; + } + + private: + int mFirstGid; +}; + +#endif |