summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2006-10-07 14:57:15 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2006-10-07 14:57:15 +0000
commite4530c6d0cd180ab18469bf8e32fb978229dedde (patch)
tree218175c6d472315e59c988b168a25b7452cc3b00 /src
parent7b9a9c55d6e73ba9151042e27ad4bc330d11617f (diff)
downloadmana-e4530c6d0cd180ab18469bf8e32fb978229dedde.tar.gz
mana-e4530c6d0cd180ab18469bf8e32fb978229dedde.tar.bz2
mana-e4530c6d0cd180ab18469bf8e32fb978229dedde.tar.xz
mana-e4530c6d0cd180ab18469bf8e32fb978229dedde.zip
Added support for gzip compressed map layer data. Increased version to 0.0.22.
Cleaned up overlay initialization a bit.
Diffstat (limited to 'src')
-rw-r--r--src/map.cpp53
-rw-r--r--src/map.h18
-rw-r--r--src/properties.h29
-rw-r--r--src/resources/mapreader.cpp130
4 files changed, 130 insertions, 100 deletions
diff --git a/src/map.cpp b/src/map.cpp
index 23dd4350..8e85e6ee 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -32,10 +32,12 @@
#include "sprite.h"
#include "tileset.h"
+#include "resources/resourcemanager.h"
#include "resources/ambientoverlay.h"
#include "resources/image.h"
#include "utils/dtor.h"
+#include "utils/tostring.h"
/**
* A location on a tile map. Used for pathfinding, open list.
@@ -85,19 +87,32 @@ Map::~Map()
}
void
-Map::setSize(int width, int height)
+Map::initializeOverlays()
{
- delete[] mMetaTiles;
- delete[] mTiles;
+ ResourceManager *resman = ResourceManager::getInstance();
- mWidth = width;
- mHeight = height;
+ for (int i = 0;
+ hasProperty("overlay" + toString(i) + "image");
+ i++)
+ {
+ const std::string name = "overlay" + toString(i);
- int size = width * height;
+ Image *img = resman->getImage(getProperty(name + "image"));
+ float scrollX = getFloatProperty(name + "scrollX");
+ //float scrollY = getFloatProperty(name + "scrollY");
+ float parallax = getFloatProperty(name + "parallax");
- mMetaTiles = new MetaTile[size];
- mTiles = new Image*[size * 3];
- std::fill_n(mTiles, size * 3, (Image*)0);
+ if (img)
+ {
+ // TODO: For some reason scrollX is passed as speedX and speedY.
+ // Maybe Crush knows why?
+ mOverlays.push_back(
+ new AmbientOverlay(img, parallax, 0, 0, scrollX, scrollX));
+
+ // The AmbientOverlay takes control over the image.
+ img->decRef();
+ }
+ }
}
void
@@ -177,17 +192,17 @@ Map::drawOverlay(Graphics *graphics, float scrollX, float scrollY, int detail)
{
static int lastTick = tick_time;
- // detail 0: no overlays
+ // Detail 0: no overlays
if (detail <= 0) return;
if (mLastScrollX == 0.0f && mLastScrollY == 0.0f)
{
- // first call - initialisation
+ // First call - initialisation
mLastScrollX = scrollX;
mLastScrollY = scrollY;
}
- //update Overlays
+ // Update Overlays
int timePassed = get_elapsed_time(lastTick);
float dx = scrollX - mLastScrollX;
float dy = scrollY - mLastScrollY;
@@ -201,28 +216,18 @@ Map::drawOverlay(Graphics *graphics, float scrollX, float scrollY, int detail)
mLastScrollY = scrollY;
lastTick = tick_time;
- //draw overlays
+ // Draw overlays
for (i = mOverlays.begin(); i != mOverlays.end(); i++)
{
(*i)->draw(graphics, graphics->getWidth(), graphics->getHeight());
- // detail 1: only one overlay, higher: all overlays
+ // Detail 1: only one overlay, higher: all overlays
if (detail == 1)
break;
};
}
void
-Map::setOverlay(Image *image, float speedX, float speedY, float parallax)
-{
- if (!image)
- return;
-
- mOverlays.push_back(
- new AmbientOverlay(image, parallax, 0, 0, speedX, speedX));
-}
-
-void
Map::setTileWithGid(int x, int y, int layer, int gid)
{
if (layer == 3)
diff --git a/src/map.h b/src/map.h
index 18381d71..961326b8 100644
--- a/src/map.h
+++ b/src/map.h
@@ -83,24 +83,22 @@ class Map : public Properties
~Map();
/**
- * Draws a map layer to the given graphics output.
+ * Initialize map overlays. Should be called after all the properties
+ * are set.
*/
- void draw(Graphics *graphics, int scrollX, int scrollY, int layer);
+ void initializeOverlays();
/**
- * Sets Overlay Graphic and Scrollspeed
+ * Draws a map layer to the given graphics output.
*/
- void setOverlay(Image *image, float speedX, float speedY, float parallax);
+ void draw(Graphics *graphics, int scrollX, int scrollY, int layer);
/**
* Draws the overlay graphic to the given graphics output.
*/
- void drawOverlay(Graphics *graphics, float scrollX, float scrollY, int detail);
-
- /**
- * Sets the size of the map. This will destroy any existing map data.
- */
- void setSize(int width, int height);
+ void
+ drawOverlay(Graphics *graphics, float scrollX, float scrollY,
+ int detail);
/**
* Adds a tileset to this map.
diff --git a/src/properties.h b/src/properties.h
index 92690cd3..56e90c0e 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -26,6 +26,7 @@
#include <map>
#include <string>
+#include <sstream>
/**
* A class holding a set of properties.
@@ -39,16 +40,36 @@ class Properties
/**
* Get a map property.
*
- * @return the value of the given property or an empty string when it
+ * @param def default value, empty string by default
+ * @return the value of the given property or the given default when it
* doesn't exist.
*/
const std::string&
- getProperty(const std::string &name)
+ getProperty(const std::string &name, const std::string &def = "")
{
- const static std::string undefined = "";
PropertyMap::const_iterator i = mProperties.find(name);
+ return (i != mProperties.end()) ? i->second : def;
+ }
- return (i != mProperties.end()) ? i->second : undefined;
+ /**
+ * Gets a map property as a float.
+ *
+ * @param def default value, 0.0f by default
+ * @return the value of the given property, or 0.0f when it doesn't
+ * exist.
+ */
+ const float
+ getFloatProperty(const std::string &name, float def = 0.0f)
+ {
+ PropertyMap::const_iterator i = mProperties.find(name);
+ float ret = def;
+ if (i != mProperties.end())
+ {
+ std::stringstream ss;
+ ss.str(i->second);
+ ss >> ret;
+ }
+ return ret;
}
/**
diff --git a/src/resources/mapreader.cpp b/src/resources/mapreader.cpp
index 2377a8f4..2aea3dc5 100644
--- a/src/resources/mapreader.cpp
+++ b/src/resources/mapreader.cpp
@@ -52,7 +52,7 @@ inflateMemory(unsigned char *in, unsigned int inLength,
int ret;
z_stream strm;
- out = (unsigned char*)malloc(bufferSize);
+ out = (unsigned char*) malloc(bufferSize);
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
@@ -83,13 +83,13 @@ inflateMemory(unsigned char *in, unsigned int inLength,
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
- (void)inflateEnd(&strm);
+ (void) inflateEnd(&strm);
return ret;
}
if (ret != Z_STREAM_END)
{
- out = (unsigned char*)realloc(out, bufferSize * 2);
+ out = (unsigned char*) realloc(out, bufferSize * 2);
if (out == NULL)
{
@@ -106,10 +106,44 @@ inflateMemory(unsigned char *in, unsigned int inLength,
assert(strm.avail_in == 0);
outLength = bufferSize - strm.avail_out;
- (void)inflateEnd(&strm);
+ (void) inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
+int
+inflateMemory(unsigned char *in, unsigned int inLength,
+ unsigned char *&out)
+{
+ unsigned int outLength = 0;
+ int ret = inflateMemory(in, inLength, out, outLength);
+
+ if (ret != Z_OK || out == NULL)
+ {
+ if (ret == Z_MEM_ERROR)
+ {
+ logger->log("Error: Out of memory while decompressing map data!");
+ }
+ else if (ret == Z_VERSION_ERROR)
+ {
+ logger->log("Error: Incompatible zlib version!");
+ }
+ else if (ret == Z_DATA_ERROR)
+ {
+ logger->log("Error: Incorrect zlib compressed data!");
+ }
+ else
+ {
+ logger->log("Error: Unknown error while decompressing map data!");
+ }
+
+ free(out);
+ out = NULL;
+ outLength = 0;
+ }
+
+ return outLength;
+}
+
Map*
MapReader::readMap(const std::string &filename)
{
@@ -127,33 +161,17 @@ 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);
+ unsigned int inflatedSize = inflateMemory((unsigned char*) buffer,
+ fileSize, inflated);
free(buffer);
- if (ret == Z_MEM_ERROR)
- {
- logger->log("Error: Out of memory while decompressing map data!");
- return NULL;
- }
- else if (ret == Z_VERSION_ERROR)
- {
- logger->log("Error: Incompatible zlib version!");
- return NULL;
- }
- else if (ret == Z_DATA_ERROR)
+ if (inflated == NULL)
{
- logger->log("Error: Incorrect zlib compressed data!");
- return NULL;
- }
- else if (ret != Z_OK || inflated == NULL)
- {
- logger->log("Error: Unknown error while decompressing map data!");
+ logger->log("Could not decompress map file (%s)\n", filename.c_str());
return NULL;
}
- xmlDocPtr doc = xmlParseMemory((char*)inflated, inflatedSize);
+ xmlDocPtr doc = xmlParseMemory((char*) inflated, inflatedSize);
free(inflated);
// Parse the inflated map data
@@ -215,39 +233,7 @@ MapReader::readMap(xmlNodePtr node, const std::string &path)
}
}
- //set Overlays
- ResourceManager *resman = ResourceManager::getInstance();
- for (int i = 0; ; i++)
- {
- const std::string name = "overlay" + toString(i);
-
- if (!map->hasProperty(name + "image"))
- break; // Finished
-
- Image *img = resman->getImage(map->getProperty(name + "image"));
- float scrollX = 0.0f;
- float scrollY = 0.0f;
- float parallax = 0.0f;
- std::stringstream ss;
-
- if (map->hasProperty(name + "scrollX"))
- {
- ss.str(map->getProperty(name + "scrollX"));
- ss >> scrollX;
- }
- if (map->hasProperty(name + "scrollY"))
- {
- ss.str(map->getProperty(name + "scrollY"));
- ss >> scrollY;
- }
- if (map->hasProperty(name + "parallax"))
- {
- ss.str(map->getProperty(name + "parallax"));
- ss >> parallax;
- }
- map->setOverlay(img, scrollX, scrollY, parallax);
- img->decRef();
- }
+ map->initializeOverlays();
return map;
}
@@ -293,8 +279,8 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer)
{
xmlFree(encoding);
- if (compression) {
- logger->log("Warning: no layer compression supported!");
+ if (compression && !xmlStrEqual(compression, BAD_CAST "gzip")) {
+ logger->log("Warning: only gzip layer compression supported!");
xmlFree(compression);
return;
}
@@ -322,12 +308,32 @@ MapReader::readLayer(xmlNodePtr node, Map *map, int layer)
int binLen;
unsigned char *binData =
- php_base64_decode(charData, strlen((char*)charData),
- &binLen);
+ php_base64_decode(charData, strlen((char*)charData), &binLen);
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;
+ }
+ }
+ xmlFree(compression);
+ }
+
for (int i = 0; i < binLen - 3; i += 4) {
int gid = binData[i] |
binData[i + 1] << 8 |