ManaPlus
Namespaces | Typedefs | Functions | Variables
mapreader.cpp File Reference

(986a3bf)

#include "resources/mapreader.h"
#include "configuration.h"
#include "graphicsmanager.h"
#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"
#include "resources/db/mapdb.h"
#include "resources/loaders/atlasloader.h"
#include "resources/loaders/emptyatlasloader.h"
#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"

Go to the source code of this file.

Namespaces

 anonymous_namespace{mapreader.cpp}
 

Typedefs

typedef std::map< std::string, xmlNodePtr >::iterator LayerInfoIterator
 
typedef std::set< XML::Document * >::iterator DocIterator
 

Functions

static int inflateMemory (unsigned char *in, unsigned int inLength, unsigned char *&out, unsigned int &outLength)
 
static int inflateMemory (unsigned char *in, unsigned int inLength, unsigned char *&out)
 
static std::string resolveRelativePath (std::string base, std::string relative)
 
static void loadReplaceLayer (LayerInfoIterator &it, Map *map)
 
static void setTile (Map *map, MapLayer *layer, MapLayerTypeT &layerType, MapHeights *heights, int x, int y, int gid)
 

Variables

std::map< std::string, xmlNodePtr > anonymous_namespace{mapreader.cpp}::mKnownLayers
 
std::set< XML::Document * > anonymous_namespace{mapreader.cpp}::mKnownDocs
 

Typedef Documentation

◆ DocIterator

typedef std::set<XML::Document*>::iterator DocIterator

Definition at line 73 of file mapreader.cpp.

◆ LayerInfoIterator

typedef std::map<std::string, xmlNodePtr >::iterator LayerInfoIterator

Definition at line 72 of file mapreader.cpp.

Function Documentation

◆ inflateMemory() [1/2]

int inflateMemory ( unsigned char *  in,
unsigned int  inLength,
unsigned char *&  out 
)
static

Definition at line 196 of file mapreader.cpp.

199 {
200  unsigned int outLength = 0;
201  const int ret = inflateMemory(in, inLength, out, outLength);
202 
203  if (ret != Z_OK || (out == nullptr))
204  {
205  if (ret == Z_MEM_ERROR)
206  {
207  reportAlways("Error: Out of memory while decompressing map data!")
208  }
209  else if (ret == Z_VERSION_ERROR)
210  {
211  reportAlways("Error: Incompatible zlib version!")
212  }
213  else if (ret == Z_DATA_ERROR)
214  {
215  reportAlways("Error: Incorrect zlib compressed data!")
216  }
217  else
218  {
219  reportAlways("Error: Unknown error while decompressing map data!")
220  }
221 
222  free(out);
223  out = nullptr;
224  outLength = 0;
225  }
226 
227  return outLength;
228 }
#define reportAlways(...)
Definition: checkutils.h:253
static int inflateMemory(unsigned char *in, unsigned int inLength, unsigned char *&out, unsigned int &outLength)
Definition: mapreader.cpp:124

References inflateMemory(), and reportAlways.

◆ inflateMemory() [2/2]

int inflateMemory ( unsigned char *  in,
unsigned int  inLength,
unsigned char *&  out,
unsigned int &  outLength 
)
static

Inflates either zlib or gzip deflated memory. The inflated memory is expected to be freed by the caller.

Definition at line 124 of file mapreader.cpp.

128 {
129  int bufferSize = 256 * 1024;
130  out = static_cast<unsigned char*>(calloc(bufferSize, 1));
131 
132  z_stream strm;
133  strm.zalloc = nullptr;
134  strm.zfree = nullptr;
135  strm.opaque = nullptr;
136  strm.next_in = in;
137  strm.avail_in = inLength;
138  strm.next_out = out;
139  strm.avail_out = bufferSize;
140 
141 PRAGMACLANG6GCC(GCC diagnostic push)
142 PRAGMACLANG6GCC(GCC diagnostic ignored "-Wold-style-cast")
143  int ret = inflateInit2(&strm, 15 + 32);
144 PRAGMACLANG6GCC(GCC diagnostic pop)
145 
146  if (ret != Z_OK)
147  return ret;
148 
149  do
150  {
151  if (strm.next_out == nullptr)
152  {
153  inflateEnd(&strm);
154  return Z_MEM_ERROR;
155  }
156 
157  ret = inflate(&strm, Z_NO_FLUSH);
158  if (ret == Z_STREAM_ERROR)
159  return ret;
160 
161  switch (ret)
162  {
163  case Z_NEED_DICT:
164  ret = Z_DATA_ERROR;
166  case Z_DATA_ERROR:
167  case Z_MEM_ERROR:
168  (void) inflateEnd(&strm);
169  return ret;
170  default:
171  break;
172  }
173 
174  if (ret != Z_STREAM_END)
175  {
176  out = static_cast<unsigned char*>(realloc(out, bufferSize * 2));
177 
178  if (out == nullptr)
179  {
180  inflateEnd(&strm);
181  return Z_MEM_ERROR;
182  }
183 
184  strm.next_out = out + CAST_SIZE(bufferSize);
185  strm.avail_out = bufferSize;
186  bufferSize *= 2;
187  }
188  }
189  while (ret != Z_STREAM_END);
190 
191  outLength = bufferSize - strm.avail_out;
192  (void) inflateEnd(&strm);
193  return Z_OK;
194 }
#define CAST_SIZE
Definition: cast.h:34
#define A_FALLTHROUGH
Definition: localconsts.h:193
#define PRAGMACLANG6GCC(str)
Definition: localconsts.h:240

References A_FALLTHROUGH, CAST_SIZE, and PRAGMACLANG6GCC.

Referenced by inflateMemory(), and MapReader::readBase64Layer().

◆ loadReplaceLayer()

static void loadReplaceLayer ( LayerInfoIterator it,
Map map 
)
static

Definition at line 324 of file mapreader.cpp.

326 {
327  MapReader::readLayer((*it).second, map);
328 }
static void readLayer(const xmlNodePtr node, Map *const map)
Definition: mapreader.cpp:883

References MapReader::readLayer().

◆ resolveRelativePath()

static std::string resolveRelativePath ( std::string  base,
std::string  relative 
)
static

Definition at line 94 of file mapreader.cpp.

95 {
96  // Remove trailing "/", if present
97  size_t i = base.length();
98  if (base.at(i - 1) == '/')
99  base.erase(i - 1, i);
100 
101  while (relative.substr(0, 3) == "../")
102  {
103  relative.erase(0, 3); // Remove "../"
104  if (!base.empty()) // If base is already empty, we can't trim anymore
105  {
106  i = base.find_last_of('/');
107  if (i == std::string::npos)
108  i = 0;
109  base.erase(i, base.length()); // Remove deepest folder in base
110  }
111  }
112 
113  // Re-add trailing slash, if needed
114  if (!base.empty() && base[base.length() - 1] != '/')
115  base.append("/");
116 
117  return base + relative;
118 }

References anonymous_namespace{stringutils.cpp}::base.

Referenced by MapReader::readTileset().

◆ setTile()

static void setTile ( Map map,
MapLayer layer,
MapLayerTypeT layerType,
MapHeights heights,
int  x,
int  y,
int  gid 
)
inlinestatic

Definition at line 559 of file mapreader.cpp.

565 {
566  const Tileset * const set = map->getTilesetWithGid(gid);
567  switch (layerType)
568  {
569  case MapLayerType::TILES:
570  {
571  if (layer == nullptr)
572  break;
573  if (set != nullptr &&
574  !set->isEmpty())
575  {
576  Image *const img = set->get(gid - set->getFirstGid());
577  layer->setTile(x, y, img);
578  }
579  else
580  {
581  layer->setTile(x, y, nullptr);
582  }
583  break;
584  }
585 
587  {
588  if (set != nullptr)
589  {
590  if (map->getVersion() >= 1)
591  {
592  const int collisionId = gid - set->getFirstGid();
593  CollisionTypeT type;
594  if (collisionId < 0 ||
595  collisionId >= CAST_S32(CollisionType::COLLISION_MAX))
596  {
598  }
599  else
600  {
601  type = static_cast<CollisionTypeT>(collisionId);
602  }
603  switch (type)
604  {
607  break;
610  break;
612  map->addBlockMask(x, y, BlockType::AIR);
613  break;
616  break;
619  break;
622  break;
625  break;
627  default:
628  break;
629  }
630  }
631  else
632  {
633  if (gid - set->getFirstGid() != 0)
635  }
636  }
637  break;
638  }
639 
641  {
642  if (set == nullptr || heights == nullptr)
643  break;
644  if (map->getVersion() >= 2)
645  {
646  heights->setHeight(x, y, CAST_U8(
647  gid - set->getFirstGid() + 1));
648  }
649  else
650  {
651  Image *const img = set->get(gid - set->getFirstGid());
652  if (layer != nullptr)
653  layer->setTile(x, y, img);
654  }
655  break;
656  }
657 
658  default:
660  break;
661  }
662 }
#define CAST_S32
Definition: cast.h:30
#define CAST_U8
Definition: cast.h:27
Image * get(const size_type i) const
Definition: imageset.cpp:67
void setHeight(const int x, const int y, const uint8_t height)
Definition: mapheights.cpp:41
void setTile(const int x, const int y, Image *const img)
Definition: maplayer.h:78
int getVersion() const
Definition: map.h:310
void addBlockMask(const int x, const int y, const BlockTypeT type)
Definition: map.cpp:707
const Tileset * getTilesetWithGid(const int gid) const
Definition: map.cpp:700
bool isEmpty() const
Definition: tileset.h:100
int getFirstGid() const
Definition: tileset.h:58
CollisionType ::T CollisionTypeT
Definition: collisiontype.h:40
@ PLAYERWALL
Definition: blocktype.h:37
@ MONSTERWALL
Definition: blocktype.h:38
@ GROUNDTOP
Definition: blocktype.h:36

References MapLayerType::ACTIONS, Map::addBlockMask(), BlockType::AIR, CAST_S32, CAST_U8, MapLayerType::COLLISION, CollisionType::COLLISION_AIR, CollisionType::COLLISION_EMPTY, CollisionType::COLLISION_GROUNDTOP, CollisionType::COLLISION_MAX, CollisionType::COLLISION_MONSTER_WALL, CollisionType::COLLISION_PLAYER_WALL, CollisionType::COLLISION_WALL, CollisionType::COLLISION_WATER, ImageSet::get(), Tileset::getFirstGid(), Map::getTilesetWithGid(), Map::getVersion(), BlockType::GROUND, BlockType::GROUNDTOP, MapLayerType::HEIGHTS, Tileset::isEmpty(), BlockType::MONSTERWALL, BlockType::PLAYERWALL, MapHeights::setHeight(), MapLayer::setTile(), MapLayerType::TILES, BlockType::WALL, BlockType::WATER, x, and y.

Referenced by MapReader::readBase64Layer(), MapReader::readCsvLayer(), and MapReader::readLayer().