summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2008-07-01 17:41:30 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2008-07-01 17:41:30 +0000
commit4ca8675700dfae625376c4afdd30b8590d68087e (patch)
tree7f661baf3d566fcf5d0318da13e29c13098cf21a /src/resources
parentcf5cfbcb8ff63005b1e08f9718ce3f80f919271e (diff)
downloadmana-client-4ca8675700dfae625376c4afdd30b8590d68087e.tar.gz
mana-client-4ca8675700dfae625376c4afdd30b8590d68087e.tar.bz2
mana-client-4ca8675700dfae625376c4afdd30b8590d68087e.tar.xz
mana-client-4ca8675700dfae625376c4afdd30b8590d68087e.zip
Merged revisions 4044-4067 via svnmerge from
https://themanaworld.svn.sourceforge.net/svnroot/themanaworld/tmw/trunk ........ r4044 | b_lindeijer | 2008-04-07 11:02:38 +0200 (Mon, 07 Apr 2008) | 2 lines Added support for basing one sprite definition on another by including it. ........ r4057 | b_lindeijer | 2008-04-08 20:43:44 +0200 (Tue, 08 Apr 2008) | 4 lines 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". ........ r4067 | b_lindeijer | 2008-04-11 00:03:57 +0200 (Fri, 11 Apr 2008) | 3 lines Fixed some compiler warnings and don't try to load particle effects when no file is set. ........
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/imageset.cpp2
-rw-r--r--src/resources/imageset.h14
-rw-r--r--src/resources/mapreader.cpp164
-rw-r--r--src/resources/mapreader.h4
-rw-r--r--src/resources/spritedef.cpp98
-rw-r--r--src/resources/spritedef.h6
6 files changed, 176 insertions, 112 deletions
diff --git a/src/resources/imageset.cpp b/src/resources/imageset.cpp
index 4b6dd592..1a753648 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 2a080fb0..328b66e0 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,15 +241,31 @@ MapReader::readMap(xmlNodePtr node, const std::string &path)
{
if (xmlStrEqual(objectNode->name, BAD_CAST "object"))
{
- std::string objName = XML::getProperty(objectNode, "name", "");
- std::string objType = XML::getProperty(objectNode, "type", "");
- int objX = XML::getProperty(objectNode, "x", 0);
- int objY = XML::getProperty(objectNode, "y", 0);
+ const std::string objType =
+ XML::getProperty(objectNode, "type", "");
+
+ if (objType == "WARP" || objType == "NPC" ||
+ objType == "SCRIPT" || objType == "SPAWN")
+ {
+ // Silently skip server-side objects.
+ continue;
+ }
+
+ 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);
+
if (objType == "PARTICLE_EFFECT")
{
+ if (objName.empty()) {
+ logger->log(" Warning: No particle file given");
+ continue;
+ }
+
map->addParticleEffect(objName, objX, objY);
}
else
@@ -280,43 +291,66 @@ 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
+ map->setWalk(x, y, (!set || (gid - set->getFirstGid() == 0)));
}
}
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;
}
@@ -348,34 +382,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++;}
@@ -390,8 +419,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) {
@@ -423,20 +452,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();
@@ -446,14 +475,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/resources/spritedef.cpp b/src/resources/spritedef.cpp
index 334474d7..ebc60240 100644
--- a/src/resources/spritedef.cpp
+++ b/src/resources/spritedef.cpp
@@ -70,33 +70,8 @@ SpriteDef *SpriteDef::load(std::string const &animationFile, int variant)
}
}
- // Get the variant
- int variant_num = XML::getProperty(rootNode, "variants", 0);
- int variant_offset = 0;
-
- if (variant_num > 0 && variant < variant_num)
- {
- variant_offset = variant * XML::getProperty(rootNode, "variant_offset", 0);
- }
-
SpriteDef *def = new SpriteDef;
-
- for_each_xml_child_node(node, rootNode)
- {
- if (xmlStrEqual(node->name, BAD_CAST "imageset"))
- {
- def->loadImageSet(node, palettes);
- }
- else if (xmlStrEqual(node->name, BAD_CAST "action"))
- {
- def->loadAction(node, variant_offset);
- }
- else if (xmlStrEqual(node->name, BAD_CAST "include"))
- {
- def->includeSprite(node);
- }
- }
-
+ def->loadSprite(rootNode, variant, palettes);
def->substituteActions();
return def;
}
@@ -119,11 +94,47 @@ void SpriteDef::substituteActions()
substituteAction(ACTION_DEAD, ACTION_HURT);
}
+void SpriteDef::loadSprite(xmlNodePtr spriteNode, int variant,
+ const std::string &palettes)
+{
+ // Get the variant
+ const int variantCount = XML::getProperty(spriteNode, "variants", 0);
+ int variant_offset = 0;
+
+ if (variantCount > 0 && variant < variantCount)
+ {
+ variant_offset =
+ variant * XML::getProperty(spriteNode, "variant_offset", 0);
+ }
+
+ for_each_xml_child_node(node, spriteNode)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "imageset"))
+ {
+ loadImageSet(node, palettes);
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "action"))
+ {
+ loadAction(node, variant_offset);
+ }
+ else if (xmlStrEqual(node->name, BAD_CAST "include"))
+ {
+ includeSprite(node);
+ }
+ }
+}
+
void SpriteDef::loadImageSet(xmlNodePtr node, std::string const &palettes)
{
- int width = XML::getProperty(node, "width", 0);
- int height = XML::getProperty(node, "height", 0);
- std::string name = XML::getProperty(node, "name", "");
+ const std::string name = XML::getProperty(node, "name", "");
+
+ // We don't allow redefining image sets. This way, an included sprite
+ // definition will use the already loaded image set with the same name.
+ if (mImageSets.find(name) != mImageSets.end())
+ return;
+
+ const int width = XML::getProperty(node, "width", 0);
+ const int height = XML::getProperty(node, "height", 0);
std::string imageSrc = XML::getProperty(node, "src", "");
Dye::instantiate(imageSrc, palettes);
@@ -184,9 +195,9 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
Action *action, ImageSet *imageSet,
int variant_offset)
{
- std::string directionName =
+ const std::string directionName =
XML::getProperty(animationNode, "direction", "");
- SpriteDirection directionType = makeSpriteDirection(directionName);
+ const SpriteDirection directionType = makeSpriteDirection(directionName);
if (directionType == DIRECTION_INVALID)
{
@@ -201,7 +212,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
// Get animation frames
for_each_xml_child_node(frameNode, animationNode)
{
- int delay = XML::getProperty(frameNode, "delay", 0);
+ const int delay = XML::getProperty(frameNode, "delay", 0);
int offsetX = XML::getProperty(frameNode, "offsetX", 0);
int offsetY = XML::getProperty(frameNode, "offsetY", 0);
offsetY -= imageSet->getHeight() - 32;
@@ -209,7 +220,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
{
- int index = XML::getProperty(frameNode, "index", -1);
+ const int index = XML::getProperty(frameNode, "index", -1);
if (index < 0)
{
@@ -230,7 +241,7 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
{
int start = XML::getProperty(frameNode, "start", -1);
- int end = XML::getProperty(frameNode, "end", -1);
+ const int end = XML::getProperty(frameNode, "end", -1);
if (start < 0 || end < 0)
{
@@ -263,12 +274,23 @@ SpriteDef::loadAnimation(xmlNodePtr animationNode,
void
SpriteDef::includeSprite(xmlNodePtr includeNode)
{
+ // TODO: Perform circular dependency check, since it's easy to crash the
+ // client this way.
const std::string filename = XML::getProperty(includeNode, "file", "");
- ResourceManager *resman = ResourceManager::getInstance();
- SpriteDef *sprite = resman->getSprite("graphics/sprites/" + filename);
- // TODO: Somehow implement actually including it
- sprite->decRef();
+ if (filename.empty())
+ return;
+
+ XML::Document doc("graphics/sprites/" + filename);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "sprite"))
+ {
+ logger->log("Error, no sprite root node in %s", filename.c_str());
+ return;
+ }
+
+ loadSprite(rootNode, 0);
}
void
diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h
index 531dfb3d..72c2566f 100644
--- a/src/resources/spritedef.h
+++ b/src/resources/spritedef.h
@@ -92,6 +92,12 @@ class SpriteDef : public Resource
~SpriteDef();
/**
+ * Loads a sprite element.
+ */
+ void loadSprite(xmlNodePtr spriteNode, int variant,
+ const std::string &palettes = "");
+
+ /**
* Loads an imageset element.
*/
void loadImageSet(xmlNodePtr node, std::string const &palettes);