summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2005-09-29 11:03:48 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2005-09-29 11:03:48 +0000
commitc00d3acf930359740ae6125533b5233ae06b765e (patch)
treea1ba92c7142c455e95758b37daf35a959903bf8a /src
parent4d117b39c555966d7648a03e0127560278e47170 (diff)
downloadmana-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.cpp137
-rw-r--r--src/map.h60
-rw-r--r--src/resources/mapreader.cpp112
-rw-r--r--src/resources/mapreader.h46
-rw-r--r--src/resources/resourcemanager.cpp21
-rw-r--r--src/resources/resourcemanager.h23
-rw-r--r--src/tileset.h57
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;
}
diff --git a/src/map.h b/src/map.h
index c808bc90..7e0389d9 100644
--- a/src/map.h
+++ b/src/map.h
@@ -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