diff options
author | Andrei Karas <akaras@inbox.ru> | 2017-10-10 22:14:45 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2017-10-10 22:15:57 +0300 |
commit | aa3f63fd497558a02feb3ddbc44f31eac091f39b (patch) | |
tree | 0e28b9b1f0501dd8be9e1a38db4ec1777fa3fbfa /src/resources/mapreader.cpp | |
parent | 7c10a6b61e9d06a4ae9cc9f942dfacb6fcfd9d3d (diff) | |
download | manaverse-aa3f63fd497558a02feb3ddbc44f31eac091f39b.tar.gz manaverse-aa3f63fd497558a02feb3ddbc44f31eac091f39b.tar.bz2 manaverse-aa3f63fd497558a02feb3ddbc44f31eac091f39b.tar.xz manaverse-aa3f63fd497558a02feb3ddbc44f31eac091f39b.zip |
Remove most unused files.
Diffstat (limited to 'src/resources/mapreader.cpp')
-rw-r--r-- | src/resources/mapreader.cpp | 1324 |
1 files changed, 0 insertions, 1324 deletions
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp deleted file mode 100644 index 4d0b89b3a..000000000 --- a/src/resources/mapreader.cpp +++ /dev/null @@ -1,1324 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "resources/mapreader.h" - -#include "configuration.h" -#ifdef USE_OPENGL -#include "graphicsmanager.h" -#endif // USE_OPENGL -#include "main.h" - -#include "const/resources/map/map.h" - -#include "enums/resources/map/collisiontype.h" -#include "enums/resources/map/mapitemtype.h" - -#include "fs/virtfs/fs.h" - -#include "resources/map/map.h" -#include "resources/map/mapheights.h" -#include "resources/map/maplayer.h" -#include "resources/map/tileset.h" - -#include "resources/beingcommon.h" -#include "resources/animation/animation.h" - -#include "resources/image/image.h" - -#ifdef USE_OPENGL -#include "resources/db/mapdb.h" -#include "resources/loaders/atlasloader.h" -#include "resources/loaders/emptyatlasloader.h" -#endif // USE_OPENGL - -#include "resources/map/tileanimation.h" - -#include "resources/loaders/imageloader.h" - -#include "resources/loaders/walklayerloader.h" - -#include "utils/base64.h" -#include "utils/checkutils.h" -#include "utils/delete2.h" -#include "utils/stringmap.h" - -#include "utils/translation/podict.h" - -#include <zlib.h> - -#include "debug.h" - -typedef std::map<std::string, XmlNodePtr>::iterator LayerInfoIterator; -typedef std::set<XML::Document*>::iterator DocIterator; - -#ifdef USE_OPENGL -Resource *MapReader::mEmptyAtlas = nullptr; -#endif // USE_OPENGL - -namespace -{ - std::map<std::string, XmlNodePtr> mKnownLayers; - std::set<XML::Document*> mKnownDocs; -} // namespace - -static int inflateMemory(unsigned char *restrict const in, - const unsigned int inLength, - unsigned char *&restrict out, - unsigned int &restrict outLength); - -static int inflateMemory(unsigned char *restrict const in, - const unsigned int inLength, - unsigned char *&restrict out); - -static std::string resolveRelativePath(std::string base, std::string relative) -{ - // Remove trailing "/", if present - size_t i = base.length(); - if (base.at(i - 1) == '/') - base.erase(i - 1, i); - - while (relative.substr(0, 3) == "../") - { - relative.erase(0, 3); // Remove "../" - if (!base.empty()) // If base is already empty, we can't trim anymore - { - i = base.find_last_of('/'); - if (i == std::string::npos) - i = 0; - base.erase(i, base.length()); // Remove deepest folder in base - } - } - - // Re-add trailing slash, if needed - if (!base.empty() && base[base.length() - 1] != '/') - base.append("/"); - - return base + relative; -} - -/** - * Inflates either zlib or gzip deflated memory. The inflated memory is - * expected to be freed by the caller. - */ -int inflateMemory(unsigned char *restrict const in, - const unsigned int inLength, - unsigned char *&restrict out, - unsigned int &restrict outLength) -{ - int bufferSize = 256 * 1024; - out = static_cast<unsigned char*>(calloc(bufferSize, 1)); - - z_stream strm; - strm.zalloc = nullptr; - strm.zfree = nullptr; - strm.opaque = nullptr; - strm.next_in = in; - strm.avail_in = inLength; - strm.next_out = out; - strm.avail_out = bufferSize; - -PRAGMACLANG6GCC(GCC diagnostic push) -PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast") - int ret = inflateInit2(&strm, 15 + 32); -PRAGMACLANG6GCC(GCC diagnostic pop) - - if (ret != Z_OK) - return ret; - - do - { - if (strm.next_out == nullptr) - { - inflateEnd(&strm); - return Z_MEM_ERROR; - } - - ret = inflate(&strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR) - return ret; - - switch (ret) - { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - A_FALLTHROUGH - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void) inflateEnd(&strm); - return ret; - default: - break; - } - - if (ret != Z_STREAM_END) - { - out = static_cast<unsigned char*>(realloc(out, bufferSize * 2)); - - if (out == nullptr) - { - inflateEnd(&strm); - return Z_MEM_ERROR; - } - - strm.next_out = out + CAST_SIZE(bufferSize); - strm.avail_out = bufferSize; - bufferSize *= 2; - } - } - while (ret != Z_STREAM_END); - - outLength = bufferSize - strm.avail_out; - (void) inflateEnd(&strm); - return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; -} - -int inflateMemory(unsigned char *restrict const in, - const unsigned int inLength, - unsigned char *&restrict out) -{ - unsigned int outLength = 0; - const int ret = inflateMemory(in, inLength, out, outLength); - - if (ret != Z_OK || (out == nullptr)) - { - if (ret == Z_MEM_ERROR) - { - reportAlways("Error: Out of memory while decompressing map data!"); - } - else if (ret == Z_VERSION_ERROR) - { - reportAlways("Error: Incompatible zlib version!"); - } - else if (ret == Z_DATA_ERROR) - { - reportAlways("Error: Incorrect zlib compressed data!"); - } - else - { - reportAlways("Error: Unknown error while decompressing map data!"); - } - - free(out); - out = nullptr; - outLength = 0; - } - - return outLength; -} - -void MapReader::addLayerToList(const std::string &fileName, - const SkipError skipError) -{ - XML::Document *doc = new XML::Document(fileName, - UseVirtFs_true, - skipError); - XmlNodePtrConst node = doc->rootNode(); - if (node == nullptr) - { - delete doc; - return; - } - - int cnt = 0; - for_each_xml_child_node(childNode, node) - { - if (!xmlNameEqual(childNode, "layer")) - continue; - std::string name = XML::getProperty(childNode, "name", ""); - if (name.empty()) - continue; - name = toLower(name); - logger->log("found patch layer: " + name); - mKnownLayers[name] = childNode; - mKnownDocs.insert(doc); - cnt ++; - } - if (cnt == 0) - delete doc; -} - -Map *MapReader::readMap(const std::string &restrict filename, - const std::string &restrict realFilename) -{ - BLOCK_START("MapReader::readMap str") - logger->log("Attempting to read map %s", realFilename.c_str()); - - XML::Document doc(realFilename, UseVirtFs_true, SkipError_false); - if (!doc.isLoaded()) - { - BLOCK_END("MapReader::readMap str") - return createEmptyMap(filename, realFilename); - } - - XmlNodePtrConst node = doc.rootNode(); - - Map *map = nullptr; - // Parse the inflated map data - if (node != nullptr) - { - if (!xmlNameEqual(node, "map")) - logger->log("Error: Not a map file (%s)!", realFilename.c_str()); - else - map = readMap(node, realFilename); - } - else - { - reportAlways("Error while parsing map file (%s)!", - realFilename.c_str()); - } - - if (map != nullptr) - { - map->setProperty("_filename", realFilename); - map->setProperty("_realfilename", filename); - - if (map->getProperty("music").empty()) - updateMusic(map); - - map->updateConditionLayers(); - map->preCacheLayers(); - } - - BLOCK_END("MapReader::readMap str") - return map; -} - -void MapReader::loadLayers(const std::string &path) -{ - BLOCK_START("MapReader::loadLayers") - loadXmlDir2(path, addLayerToList, ".tmx", SkipError_false); - BLOCK_END("MapReader::loadLayers") -} - -void MapReader::unloadTempLayers() -{ - FOR_EACH (DocIterator, it, mKnownDocs) - delete (*it); - mKnownLayers.clear(); - mKnownDocs.clear(); -} - -static void loadReplaceLayer(const LayerInfoIterator &it, - Map *const map) A_NONNULL(2); -static void loadReplaceLayer(const LayerInfoIterator &it, - Map *const map) -{ - MapReader::readLayer((*it).second, map); -} - -Map *MapReader::readMap(XmlNodePtrConst node, const std::string &path) -{ - if (node == nullptr) - return nullptr; - - BLOCK_START("MapReader::readMap xml") - // Take the filename off the path - const std::string pathDir = path.substr(0, path.rfind('/') + 1); - - const int w = XML::getProperty(node, "width", 0); - const int h = XML::getProperty(node, "height", 0); - const int tilew = XML::getProperty(node, "tilewidth", -1); - const int tileh = XML::getProperty(node, "tileheight", -1); - - const bool showWarps = config.getBoolValue("warpParticle"); - const std::string warpPath = pathJoin(paths.getStringValue("particles"), - paths.getStringValue("portalEffectFile")); - - if (tilew < 0 || tileh < 0) - { - reportAlways("MapReader: Warning: " - "Uninitialized tile width or height value for map: %s", - path.c_str()); - BLOCK_END("MapReader::readMap xml") - return nullptr; - } - - logger->log("loading replace layer list"); - loadLayers(path + "_replace.d"); - - Map *const map = new Map(path, - w, h, - tilew, tileh); - - const std::string fileName = path.substr(path.rfind(dirSeparator) + 1); - map->setProperty("shortName", fileName); - -#ifdef USE_OPENGL - BLOCK_START("MapReader::readMap load atlas") - if (graphicsManager.getUseAtlases()) - { - const MapInfo *const info = MapDB::getMapAtlas(fileName); - if (info != nullptr) - { - map->setAtlas(Loader::getAtlas( - info->atlas, - *info->files)); - } - else - { - reportAlways("Missing atlas for map: %s", - fileName.c_str()); - } - } - BLOCK_END("MapReader::readMap load atlas") -#endif // USE_OPENGL - - for_each_xml_child_node(childNode, node) - { - if (xmlNameEqual(childNode, "tileset")) - { - Tileset *const tileset = readTileset(childNode, pathDir, map); - if (tileset != nullptr) - map->addTileset(tileset); - } - else if (xmlNameEqual(childNode, "layer")) - { - std::string name = XML::getProperty(childNode, "name", ""); - name = toLower(name); - LayerInfoIterator it = mKnownLayers.find(name); - if (it == mKnownLayers.end()) - { - readLayer(childNode, map); - } - else - { - logger->log("load replace layer: " + name); - loadReplaceLayer(it, map); - } - } - else if (xmlNameEqual(childNode, "properties")) - { - readProperties(childNode, map); - map->setVersion(atoi(map->getProperty( - "manaplus version").c_str())); - } - else if (xmlNameEqual(childNode, "objectgroup")) - { - // The object group offset is applied to each object individually - const int tileOffsetX = XML::getProperty(childNode, "x", 0); - const int tileOffsetY = XML::getProperty(childNode, "y", 0); - const int offsetX = tileOffsetX * tilew; - const int offsetY = tileOffsetY * tileh; - const bool showParticles = - config.getBoolValue("mapparticleeffects"); - - for_each_xml_child_node(objectNode, childNode) - { - if (xmlNameEqual(objectNode, "object")) - { - std::string objType = XML::getProperty( - objectNode, "type", ""); - - objType = toUpper(objType); - -/* - if (objType == "NPC" || - objType == "SCRIPT") - { - logger->log("hidden obj: " + objType); - // 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); - const int objW = XML::getProperty(objectNode, "width", 0); - const int objH = XML::getProperty(objectNode, "height", 0); - - logger->log("- Loading object name: %s type: %s at %d:%d" - " (%dx%d)", objName.c_str(), objType.c_str(), - objX, objY, objW, objH); - - if (objType == "PARTICLE_EFFECT") - { - if (objName.empty()) - { - logger->log1(" Warning: No particle file given"); - continue; - } - - if (showParticles) - { - map->addParticleEffect(objName, - objX + offsetX, - objY + offsetY, - objW, - objH); - } - else - { - logger->log("Ignore particle effect: " + objName); - } - } - else if (objType == "WARP") - { - if (showWarps) - { - map->addParticleEffect(warpPath, - objX, objY, objW, objH); - } - map->addPortal(objName, MapItemType::PORTAL, - objX, objY, objW, objH); - } - else if (objType == "SPAWN") - { - // TRANSLATORS: spawn name -// map->addPortal(_("Spawn: ") + objName, -// MapItemType::PORTAL, -// objX, objY, objW, objH); - } - else if (objType == "MUSIC") - { - map->addRange(objName, MapItemType::MUSIC, - objX, objY, objW, objH); - } - else - { - logger->log1(" Warning: Unknown object type"); - } - } - } - } - } - - map->initializeAmbientLayers(); - map->clearIndexedTilesets(); - map->setActorsFix(0, atoi(map->getProperty("actorsfix").c_str())); - map->reduce(); - map->setWalkLayer(Loader::getWalkLayer(fileName, map)); - unloadTempLayers(); - map->updateDrawLayersList(); - BLOCK_END("MapReader::readMap xml") - return map; -} - -void MapReader::readProperties(XmlNodeConstPtrConst node, - Properties *const props) -{ - BLOCK_START("MapReader::readProperties") - if (node == nullptr) - { - BLOCK_END("MapReader::readProperties") - return; - } - - for_each_xml_child_node(childNode, node) - { - if (!xmlNameEqual(childNode, "property")) - continue; - - // Example: <property name="name" value="value"/> - const std::string name = XML::getProperty(childNode, "name", ""); - const std::string value = XML::getProperty(childNode, "value", ""); - - if (!name.empty() && !value.empty()) - { - if (name == "name") - props->setProperty(name, translator->getStr(value)); - else - props->setProperty(name, value); - } - } - BLOCK_END("MapReader::readProperties") -} - -inline static void setTile(Map *const map, - MapLayer *const layer, - const MapLayerTypeT &layerType, - MapHeights *const heights, - const int x, const int y, - const int gid) A_NONNULL(1); - -inline static void setTile(Map *const map, - MapLayer *const layer, - const MapLayerTypeT &layerType, - MapHeights *const heights, - const int x, const int y, - const int gid) -{ - const Tileset * const set = map->getTilesetWithGid(gid); - switch (layerType) - { - case MapLayerType::TILES: - { - Image *const img = set != nullptr ? - set->get(gid - set->getFirstGid()) : nullptr; - if (layer != nullptr) - layer->setTile(x, y, img); - break; - } - - case MapLayerType::COLLISION: - { - if (set != nullptr) - { - if (map->getVersion() >= 1) - { - const int collisionId = gid - set->getFirstGid(); - CollisionTypeT type; - if (collisionId < 0 || - collisionId >= CAST_S32(CollisionType::COLLISION_MAX)) - { - type = CollisionType::COLLISION_EMPTY; - } - else - { - type = static_cast<CollisionTypeT>(collisionId); - } - switch (type) - { - case CollisionType::COLLISION_EMPTY: - map->addBlockMask(x, y, BlockType::GROUND); - break; - case CollisionType::COLLISION_WALL: - map->addBlockMask(x, y, BlockType::WALL); - break; - case CollisionType::COLLISION_AIR: - map->addBlockMask(x, y, BlockType::AIR); - break; - case CollisionType::COLLISION_WATER: - map->addBlockMask(x, y, BlockType::WATER); - break; - case CollisionType::COLLISION_GROUNDTOP: - map->addBlockMask(x, y, BlockType::GROUNDTOP); - break; - case CollisionType::COLLISION_PLAYER_WALL: - map->addBlockMask(x, y, BlockType::PLAYERWALL); - break; - case CollisionType::COLLISION_MONSTER_WALL: - map->addBlockMask(x, y, BlockType::MONSTERWALL); - break; - case CollisionType::COLLISION_MAX: - default: - break; - } - } - else - { - if (gid - set->getFirstGid() != 0) - map->addBlockMask(x, y, BlockType::WALL); - } - } - break; - } - - case MapLayerType::HEIGHTS: - { - if (set == nullptr || heights == nullptr) - break; - if (map->getVersion() >= 2) - { - heights->setHeight(x, y, CAST_U8( - gid - set->getFirstGid() + 1)); - } - else - { - Image *const img = set->get(gid - set->getFirstGid()); - if (layer != nullptr) - layer->setTile(x, y, img); - } - break; - } - - default: - case MapLayerType::ACTIONS: - break; - } -} - -bool MapReader::readBase64Layer(XmlNodeConstPtrConst childNode, - Map *const map, - MapLayer *const layer, - const MapLayerTypeT &layerType, - MapHeights *const heights, - const std::string &compression, - int &restrict x, int &restrict y, - const int w, const int h) -{ - if (childNode == nullptr) - return false; - - if (!compression.empty() && compression != "gzip" - && compression != "zlib") - { - reportAlways("Warning: only gzip and zlib layer" - " compression supported!"); - return false; - } - - // Read base64 encoded map file - if (!XmlHaveChildContent(childNode)) - return true; - - const size_t len = strlen(XmlChildContent(childNode)) + 1; - unsigned char *charData = new unsigned char[len + 1]; - const char *const xmlChars = XmlChildContent(childNode); - const char *charStart = reinterpret_cast<const char*>(xmlChars); - if (charStart == nullptr) - { - delete [] charData; - return false; - } - - unsigned char *charIndex = charData; - - while (*charStart != 0) - { - if (*charStart != ' ' && - *charStart != '\t' && - *charStart != '\n') - { - *charIndex = *charStart; - charIndex++; - } - charStart++; - } - *charIndex = '\0'; - - int binLen; - unsigned char *binData = php3_base64_decode(charData, - CAST_S32(strlen(reinterpret_cast<char*>( - charData))), &binLen); - - delete [] charData; -// XmlFree(const_cast<char*>(xmlChars)); - - if (binData != nullptr) - { - if (compression == "gzip" || compression == "zlib") - { - // Inflate the gzipped layer data - unsigned char *inflated = nullptr; - const unsigned int inflatedSize = - inflateMemory(binData, binLen, inflated); - - free(binData); - binData = inflated; - binLen = inflatedSize; - - if (inflated == nullptr) - { - reportAlways("Error: Could not decompress layer!"); - return false; - } - } - - const std::map<int, TileAnimation*> &tileAnimations - = map->getTileAnimations(); - - const bool hasAnimations = !tileAnimations.empty(); - if (hasAnimations) - { - for (int i = 0; i < binLen - 3; i += 4) - { - const int gid = binData[i] | - binData[i + 1] << 8 | - binData[i + 2] << 16 | - binData[i + 3] << 24; - - setTile(map, layer, layerType, heights, x, y, gid); - TileAnimationMapCIter it = tileAnimations.find(gid); - if (it != tileAnimations.end()) - { - TileAnimation *const ani = it->second; - if (ani != nullptr) - ani->addAffectedTile(layer, x + y * w); - } - - x++; - if (x == w) - { - x = 0; y++; - - // When we're done, don't crash on too much data - if (y == h) - break; - } - } - } - else - { - for (int i = 0; i < binLen - 3; i += 4) - { - const int gid = binData[i] | - binData[i + 1] << 8 | - binData[i + 2] << 16 | - binData[i + 3] << 24; - - setTile(map, layer, layerType, heights, x, y, gid); - - x++; - if (x == w) - { - x = 0; y++; - - // When we're done, don't crash on too much data - if (y == h) - break; - } - } - } - free(binData); - } - return true; -} - -bool MapReader::readCsvLayer(XmlNodeConstPtrConst childNode, - Map *const map, - MapLayer *const layer, - const MapLayerTypeT &layerType, - MapHeights *const heights, - int &restrict x, int &restrict y, - const int w, const int h) -{ - if (childNode == nullptr) - return false; - - if (!XmlHaveChildContent(childNode)) - return true; - - const char *const xmlChars = XmlChildContent(childNode); - const char *const data = reinterpret_cast<const char*>(xmlChars); - if (data == nullptr) - return false; - - std::string csv(data); - size_t oldPos = 0; - - const std::map<int, TileAnimation*> &tileAnimations - = map->getTileAnimations(); - const bool hasAnimations = !tileAnimations.empty(); - - if (hasAnimations) - { - while (oldPos != std::string::npos) - { - const size_t pos = csv.find_first_of(',', oldPos); - if (pos == std::string::npos) - return false; - - const int gid = atoi(csv.substr(oldPos, pos - oldPos).c_str()); - setTile(map, layer, layerType, heights, x, y, gid); - TileAnimationMapCIter it = tileAnimations.find(gid); - if (it != tileAnimations.end()) - { - TileAnimation *const ani = it->second; - if (ani != nullptr) - ani->addAffectedTile(layer, x + y * w); - } - - x++; - if (x == w) - { - x = 0; y++; - - // When we're done, don't crash on too much data - if (y == h) - return false; - } - oldPos = pos + 1; - } - } - else - { - while (oldPos != std::string::npos) - { - const size_t pos = csv.find_first_of(',', oldPos); - if (pos == std::string::npos) - return false; - - const int gid = atoi(csv.substr(oldPos, pos - oldPos).c_str()); - setTile(map, layer, layerType, heights, x, y, gid); - - x++; - if (x == w) - { - x = 0; y++; - - // When we're done, don't crash on too much data - if (y == h) - return false; - } - oldPos = pos + 1; - } - } - return true; -} - -void MapReader::readLayer(XmlNodeConstPtr node, Map *const map) -{ - if (node == nullptr) - return; - - // 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, "x", 0); - const int offsetY = XML::getProperty(node, "y", 0); - std::string name = XML::getProperty(node, "name", ""); - name = toLower(name); - - const bool isFringeLayer = (name.substr(0, 6) == "fringe"); - const bool isCollisionLayer = (name.substr(0, 9) == "collision"); - const bool isHeightLayer = (name.substr(0, 7) == "heights"); - const bool isActionsLayer = (name.substr(0, 7) == "actions"); - int mask = 1; - int tileCondition = -1; - int conditionLayer = 0; - - MapLayerTypeT layerType = MapLayerType::TILES; - if (isCollisionLayer) - layerType = MapLayerType::COLLISION; - else if (isHeightLayer) - layerType = MapLayerType::HEIGHTS; - else if (isActionsLayer) - layerType = MapLayerType::ACTIONS; - - map->indexTilesets(); - - MapLayer *layer = nullptr; - MapHeights *heights = nullptr; - - logger->log("- Loading layer \"%s\"", name.c_str()); - int x = 0; - int y = 0; - - // Load the tile data - for_each_xml_child_node(childNode, node) - { - if (xmlNameEqual(childNode, "properties")) - { - for_each_xml_child_node(prop, childNode) - { - if (!xmlNameEqual(prop, "property")) - continue; - const std::string pname = XML::getProperty(prop, "name", ""); - const std::string value = XML::getProperty(prop, "value", ""); - // ignoring any layer if property Hidden is 1 - if (pname == "Hidden") - { - if (value == "1") - return; - } - else if (pname == "Version") - { - if (value > CHECK_VERSION) - return; - } - else if (pname == "NotVersion") - { - if (value <= CHECK_VERSION) - return; - } - else if (pname == "Mask") - { - mask = atoi(value.c_str()); - } - else if (pname == "TileCondition") - { - tileCondition = atoi(value.c_str()); - } - else if (pname == "ConditionLayer") - { - conditionLayer = atoi(value.c_str()); - } - else if (pname == "SideView") - { - if (value != "down") - return; - } - } - } - - if (!xmlNameEqual(childNode, "data")) - continue; - - // Disable for future usage "TileCondition" attribute - // if already set ConditionLayer to non zero - if (conditionLayer != 0) - tileCondition = -1; - - switch (layerType) - { - case MapLayerType::TILES: - { - layer = new MapLayer(name, - offsetX, offsetY, - w, h, - isFringeLayer, - mask, - tileCondition); - map->addLayer(layer); - break; - } - case MapLayerType::HEIGHTS: - { - heights = new MapHeights(w, h); - map->addHeights(heights); - break; - } - default: - case MapLayerType::ACTIONS: - case MapLayerType::COLLISION: - break; - } - - const std::string encoding = - XML::getProperty(childNode, "encoding", ""); - const std::string compression = - XML::getProperty(childNode, "compression", ""); - - if (encoding == "base64") - { - if (readBase64Layer(childNode, map, layer, layerType, - heights, compression, x, y, w, h)) - { - continue; - } - else - { - return; - } - } - else if (encoding == "csv") - { - if (readCsvLayer(childNode, map, layer, layerType, - heights, x, y, w, h)) - { - continue; - } - else - { - return; - } - } - else - { - const std::map<int, TileAnimation*> &tileAnimations - = map->getTileAnimations(); - const bool hasAnimations = !tileAnimations.empty(); - - // Read plain XML map file - for_each_xml_child_node(childNode2, childNode) - { - if (!xmlNameEqual(childNode2, "tile")) - continue; - - const int gid = XML::getProperty(childNode2, "gid", -1); - setTile(map, layer, layerType, heights, x, y, gid); - if (hasAnimations) - { - TileAnimationMapCIter it = tileAnimations.find(gid); - if (it != tileAnimations.end()) - { - TileAnimation *const ani = it->second; - if (ani != nullptr) - ani->addAffectedTile(layer, x + y * w); - } - } - - x++; - if (x == w) - { - x = 0; y++; - if (y >= h) - break; - } - } - } - - if (y < h) - std::cerr << "TOO SMALL!\n"; - if (x != 0) - std::cerr << "TOO SMALL!\n"; - - // There can be only one data element - break; - } -} - -Tileset *MapReader::readTileset(XmlNodePtr node, - const std::string &path, - Map *const map) -{ - BLOCK_START("MapReader::readTileset") - if (node == nullptr) - { - BLOCK_END("MapReader::readTileset") - return nullptr; - } - - const int firstGid = XML::getProperty(node, "firstgid", 0); - const int margin = XML::getProperty(node, "margin", 0); - const int spacing = XML::getProperty(node, "spacing", 0); - XML::Document* doc = nullptr; - Tileset *set = nullptr; - std::string pathDir(path); - std::map<std::string, std::string> props; - - if (XmlHasProp(node, "source")) - { - std::string filename = XML::getProperty(node, "source", ""); - filename = resolveRelativePath(path, filename); - - doc = new XML::Document(filename, UseVirtFs_true, SkipError_false); - node = doc->rootNode(); - if (node == nullptr) - { - delete doc; - BLOCK_END("MapReader::readTileset") - return nullptr; - } - - // Reset path to be realtive to the tsx file - pathDir = filename.substr(0, filename.rfind('/') + 1); - } - - 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 (xmlNameEqual(childNode, "image")) - { - // ignore second other <image> tags in tileset - if (set != nullptr) - continue; - - const std::string source = XML::getProperty( - childNode, "source", ""); - - if (!source.empty()) - { - Image *const tilebmp = Loader::getImage( - resolveRelativePath(pathDir, source)); - - if (tilebmp != nullptr) - { - set = new Tileset(tilebmp, - tw, th, - firstGid, - margin, - spacing); - tilebmp->decRef(); -#ifdef USE_OPENGL - if (tilebmp->getType() == ImageType::Image && - map->haveAtlas() == true && - graphicsManager.getUseAtlases()) - { - reportAlways("Error: image '%s' not present in atlas", - source.c_str()); - } -#endif // USE_OPENGL - } - else - { - reportAlways("Error: Failed to load tileset (%s)", - source.c_str()); - } - } - } - else if (xmlNameEqual(childNode, "properties")) - { - for_each_xml_child_node(propertyNode, childNode) - { - if (!xmlNameEqual(propertyNode, "property")) - continue; - const std::string name = XML::getProperty( - propertyNode, "name", ""); - if (!name.empty()) - props[name] = XML::getProperty(propertyNode, "value", ""); - } - } - else if (xmlNameEqual(childNode, "tile")) - { - bool haveAnimation(false); - - for_each_xml_child_node(tileNode, childNode) - { - const bool isProps = xmlNameEqual(tileNode, "properties"); - const bool isAnim = xmlNameEqual(tileNode, "animation"); - if (!isProps && !isAnim) - continue; - - const int tileGID = firstGid + XML::getProperty( - childNode, "id", 0); - - Animation *ani = new Animation("from map"); - - if (isProps) - { - // read tile properties to a map for simpler handling - StringIntMap tileProperties; - for_each_xml_child_node(propertyNode, tileNode) - { - if (!xmlNameEqual(propertyNode, "property")) - continue; - - haveAnimation = true; - const std::string name = XML::getProperty( - propertyNode, "name", ""); - const int value = XML::getProperty( - propertyNode, "value", 0); - if (!name.empty()) - { - tileProperties[name] = value; - logger->log("Tile Prop of %d \"%s\" = \"%d\"", - tileGID, name.c_str(), value); - } - } - - // create animation - if (set == nullptr || - !config.getBoolValue("playMapAnimations")) - { - delete ani; - continue; - } - - for (int i = 0; ; i++) - { - const std::string iStr(toString(i)); - StringIntMapCIter iFrame - = tileProperties.find("animation-frame" + iStr); - StringIntMapCIter iDelay - = tileProperties.find("animation-delay" + iStr); - // possible need add random attribute? - if (iFrame != tileProperties.end() - && iDelay != tileProperties.end()) - { - ani->addFrame(set->get(iFrame->second), - iDelay->second, 0, 0, 100); - } - else - { - break; - } - } - } - else if (isAnim && !haveAnimation) - { - for_each_xml_child_node(frameNode, tileNode) - { - if (!xmlNameEqual(frameNode, "frame")) - continue; - - const int tileId = XML::getProperty( - frameNode, "tileid", 0); - const int duration = XML::getProperty( - frameNode, "duration", 0) / 10; - - if (set != nullptr) - { - ani->addFrame(set->get(tileId), - duration, - 0, 0, 100); - } - } - } - - if (ani->getLength() > 0) - map->addAnimation(tileGID, new TileAnimation(ani)); - else - delete2(ani) - } - } - } - - delete doc; - - if (set != nullptr) - set->setProperties(props); - BLOCK_END("MapReader::readTileset") - return set; -} - -Map *MapReader::createEmptyMap(const std::string &restrict filename, - const std::string &restrict realFilename) -{ - logger->log1("Creating empty map"); - Map *const map = new Map("empty map", - 300, 300, - mapTileSize, mapTileSize); - map->setProperty("_filename", realFilename); - map->setProperty("_realfilename", filename); - updateMusic(map); - map->setCustom(true); - MapLayer *layer = new MapLayer("nolayer", - 0, 0, - 300, 300, - false, - 1, - -1); - map->addLayer(layer); - layer = new MapLayer("nolayer", - 0, 0, - 300, 300, - true, - 1, - -1); - map->addLayer(layer); - map->updateDrawLayersList(); - map->updateConditionLayers(); - map->preCacheLayers(); - - return map; -} - -void MapReader::updateMusic(Map *const map) -{ - std::string name = map->getProperty("shortName"); - const size_t p = name.rfind('.'); - if (p != std::string::npos) - name = name.substr(0, p); - name.append(".ogg"); - if (VirtFs::exists(pathJoin(paths.getStringValue("music"), name))) - map->setProperty("music", name); -} - -#ifdef USE_OPENGL -void MapReader::loadEmptyAtlas() -{ - if (!graphicsManager.getUseAtlases()) - return; - - const MapInfo *const info = MapDB::getAtlas( - paths.getStringValue("emptyAtlasName")); - if (info != nullptr) - { - mEmptyAtlas = Loader::getEmptyAtlas( - info->atlas, - *info->files); - delete info; - } -} - -void MapReader::unloadEmptyAtlas() -{ - if (mEmptyAtlas != nullptr) - mEmptyAtlas->decRef(); -} -#endif // USE_OPENGL |