diff options
author | Ira Rice <irarice@gmail.com> | 2008-09-25 00:15:44 +0000 |
---|---|---|
committer | Ira Rice <irarice@gmail.com> | 2008-09-25 00:15:44 +0000 |
commit | 489a429bea6739dfa25503b9329bd9e33bffb856 (patch) | |
tree | 8112f6fd988fdc0610329b6bc14ee3f9d5801092 /src/resources/mapreader.cpp | |
parent | 2dc8eadff1e67bb70b1772ecc19c9e1e2e40a5b4 (diff) | |
download | mana-489a429bea6739dfa25503b9329bd9e33bffb856.tar.gz mana-489a429bea6739dfa25503b9329bd9e33bffb856.tar.bz2 mana-489a429bea6739dfa25503b9329bd9e33bffb856.tar.xz mana-489a429bea6739dfa25503b9329bd9e33bffb856.zip |
Merged the Tametomo branch into trunk.
Diffstat (limited to 'src/resources/mapreader.cpp')
-rw-r--r-- | src/resources/mapreader.cpp | 218 |
1 files changed, 119 insertions, 99 deletions
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp index e2b47e66..ab3b0cae 100644 --- a/src/resources/mapreader.cpp +++ b/src/resources/mapreader.cpp @@ -145,8 +145,7 @@ inflateMemory(unsigned char *in, unsigned int inLength, return outLength; } -Map* -MapReader::readMap(const std::string &filename) +Map* MapReader::readMap(const std::string &filename) { // Load the file through resource manager ResourceManager *resman = ResourceManager::getInstance(); @@ -206,19 +205,13 @@ 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); - - prop = xmlGetProp(node, BAD_CAST "version"); - xmlFree(prop); + const std::string pathDir = path.substr(0, path.rfind("/") + 1); - 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; + const int w = XML::getProperty(node, "width", 0); + const int h = XML::getProperty(node, "height", 0); + const int tilew = XML::getProperty(node, "tilewidth", DEFAULT_TILE_WIDTH); + const int tileh = XML::getProperty(node, "tileheight", DEFAULT_TILE_HEIGHT); Map *map = new Map(w, h, tilew, tileh); for_each_xml_child_node(childNode, node) @@ -232,9 +225,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 +237,29 @@ 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 @@ -271,8 +276,7 @@ MapReader::readMap(xmlNodePtr node, const std::string &path) return map; } -void -MapReader::readProperties(xmlNodePtr node, Properties* props) +void MapReader::readProperties(xmlNodePtr node, Properties* props) { for_each_xml_child_node(childNode, node) { @@ -280,43 +284,65 @@ 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) xmlFree(name); - if (value) xmlFree(value); + if (!name.empty() && !value.empty()) + props->setProperty(name, value); } } -void -MapReader::readLayer(xmlNodePtr node, Map *map, int layer) +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 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.substr(0,6) == "Fringe"); + const bool isCollisionLayer = (name.substr(0,9) == "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"); - - if (encoding && xmlStrEqual(encoding, BAD_CAST "base64")) + continue; + + const std::string encoding = + XML::getProperty(childNode, "encoding", ""); + const std::string compression = + XML::getProperty(childNode, "compression", ""); + + 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; } @@ -324,15 +350,15 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer) xmlNodePtr dataChild = childNode->xmlChildrenNode; if (!dataChild) continue; - + int len = strlen((const char*)dataChild->content) + 1; unsigned char *charData = new unsigned char[len + 1]; const char *charStart = (const char*)dataChild->content; unsigned char *charIndex = charData; - + while (*charStart) { if (*charStart != ' ' && *charStart != '\t' && - *charStart != '\n') + *charStart != '\n') { *charIndex = *charStart; charIndex++; @@ -348,40 +374,34 @@ 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) { + if (x == w) + { x = 0; y++; - - // When we're done, don't crash on too much data if (y == h) break; } @@ -390,29 +410,29 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer) } } else { - // Read plain XML map file - for_each_xml_child_node(childNode2, childNode) - { - if (!xmlStrEqual(childNode2->name, BAD_CAST "tile")) + // Read plain XML map file + for_each_xml_child_node(childNode2, childNode) + { + if (!xmlStrEqual(childNode2->name, BAD_CAST "tile")) continue; - - int gid = XML::getProperty(childNode2, "gid", -1); - map->setTileWithGid(x, y, layer, gid); - - x++; - if (x == w) { - x = 0; y++; - if (y >= h) - break; - } - } + + const int gid = XML::getProperty(childNode2, "gid", -1); + setTile(map, layer, x, y, gid); + + x++; + if (x == w) { + x = 0; y++; + if (y >= h) + break; + } + } } - + if (y < h) std::cerr << "TOO SMALL!\n"; if (x) std::cerr << "TOO SMALL!\n"; - + // There can be only one data element break; } @@ -429,20 +449,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(); @@ -452,14 +472,14 @@ 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; } |