Merge pull request #3420 from boyu0/tilemap_plain_xml_format_support

Support for loading tilemaps with plain XML layer format
This commit is contained in:
minggo 2013-08-17 01:13:41 -07:00
commit 61e8b14601
1 changed files with 122 additions and 45 deletions

View File

@ -330,14 +330,50 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
}
else if (elementName == "tile")
{
TMXTilesetInfo* info = (TMXTilesetInfo*)pTMXMapInfo->getTilesets()->lastObject();
Dictionary *dict = new Dictionary();
pTMXMapInfo->setParentGID(info->_firstGid + atoi(valueForKey("id", attributeDict)));
pTMXMapInfo->getTileProperties()->setObject(dict, pTMXMapInfo->getParentGID());
CC_SAFE_RELEASE(dict);
pTMXMapInfo->setParentElement(TMXPropertyTile);
if (pTMXMapInfo->getParentElement() == TMXPropertyLayer)
{
TMXLayerInfo* layer = (TMXLayerInfo*)pTMXMapInfo->getLayers()->lastObject();
Size layerSize = layer->_layerSize;
unsigned int gid = (unsigned int)atoi(valueForKey("gid", attributeDict));
int tilesAmount = layerSize.width*layerSize.height;
do
{
// Check the gid is legal or not
CC_BREAK_IF(gid == 0);
if (tilesAmount > 1)
{
// Check the value is all set or not
CC_BREAK_IF(layer->_tiles[tilesAmount - 2] != 0 && layer->_tiles[tilesAmount - 1] != 0);
int currentTileIndex = tilesAmount - layer->_tiles[tilesAmount - 1] - 1;
layer->_tiles[currentTileIndex] = gid;
if (currentTileIndex != tilesAmount - 1)
{
--layer->_tiles[tilesAmount - 1];
}
}
else if(tilesAmount == 1)
{
if (layer->_tiles[0] == 0)
{
layer->_tiles[0] = gid;
}
}
} while (0);
}
else
{
TMXTilesetInfo* info = (TMXTilesetInfo*)pTMXMapInfo->getTilesets()->lastObject();
Dictionary *dict = new Dictionary();
pTMXMapInfo->setParentGID(info->_firstGid + atoi(valueForKey("id", attributeDict)));
pTMXMapInfo->getTileProperties()->setObject(dict, pTMXMapInfo->getParentGID());
CC_SAFE_RELEASE(dict);
pTMXMapInfo->setParentElement(TMXPropertyTile);
}
}
else if (elementName == "layer")
{
@ -411,7 +447,34 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
std::string encoding = valueForKey("encoding", attributeDict);
std::string compression = valueForKey("compression", attributeDict);
if( encoding == "base64" )
if (encoding == "")
{
pTMXMapInfo->setLayerAttribs(pTMXMapInfo->getLayerAttribs() | TMXLayerAttribNone);
TMXLayerInfo* layer = (TMXLayerInfo*)pTMXMapInfo->getLayers()->lastObject();
Size layerSize = layer->_layerSize;
int tilesAmount = layerSize.width*layerSize.height;
int *tiles = (int *) malloc(tilesAmount*sizeof(int));
for (int i = 0; i < tilesAmount; i++)
{
tiles[i] = 0;
}
/* Save the special index in tiles[tilesAmount - 1];
* When we load tiles, we can do this:
* tiles[tilesAmount - tiles[tilesAmount - 1] - 1] = tileNum;
* --tiles[tilesAmount - 1];
* We do this because we can easily contorl how much tiles we loaded without add a "curTilesAmount" into class member.
*/
if (tilesAmount > 1)
{
tiles[tilesAmount - 1] = tilesAmount - 1;
}
layer->_tiles = (unsigned int*) tiles;
}
else if (encoding == "base64")
{
int layerAttribs = pTMXMapInfo->getLayerAttribs();
pTMXMapInfo->setLayerAttribs(layerAttribs | TMXLayerAttribBase64);
@ -429,7 +492,6 @@ void TMXMapInfo::startElement(void *ctx, const char *name, const char **atts)
}
CCASSERT( compression == "" || compression == "gzip" || compression == "zlib", "TMX: unsupported compression method" );
}
CCASSERT( pTMXMapInfo->getLayerAttribs() != TMXLayerAttribNone, "TMX tile map: Only base64 and/or gzip/zlib maps are supported" );
}
else if (elementName == "object")
@ -622,52 +684,67 @@ void TMXMapInfo::endElement(void *ctx, const char *name)
int len = 0;
if(elementName == "data" && pTMXMapInfo->getLayerAttribs()&TMXLayerAttribBase64)
if(elementName == "data")
{
pTMXMapInfo->setStoringCharacters(false);
TMXLayerInfo* layer = (TMXLayerInfo*)pTMXMapInfo->getLayers()->lastObject();
std::string currentString = pTMXMapInfo->getCurrentString();
unsigned char *buffer;
len = base64Decode((unsigned char*)currentString.c_str(), (unsigned int)currentString.length(), &buffer);
if( ! buffer )
if (pTMXMapInfo->getLayerAttribs() & TMXLayerAttribBase64)
{
CCLOG("cocos2d: TiledMap: decode data error");
return;
}
if( pTMXMapInfo->getLayerAttribs() & (TMXLayerAttribGzip | TMXLayerAttribZlib) )
{
unsigned char *deflated;
Size s = layer->_layerSize;
// int sizeHint = s.width * s.height * sizeof(uint32_t);
int sizeHint = (int)(s.width * s.height * sizeof(unsigned int));
int inflatedLen = ZipUtils::ccInflateMemoryWithHint(buffer, len, &deflated, sizeHint);
CCASSERT(inflatedLen == sizeHint, "");
inflatedLen = (size_t)&inflatedLen; // XXX: to avoid warnings in compiler
pTMXMapInfo->setStoringCharacters(false);
delete [] buffer;
buffer = NULL;
if( ! deflated )
TMXLayerInfo* layer = (TMXLayerInfo*)pTMXMapInfo->getLayers()->lastObject();
std::string currentString = pTMXMapInfo->getCurrentString();
unsigned char *buffer;
len = base64Decode((unsigned char*)currentString.c_str(), (unsigned int)currentString.length(), &buffer);
if( ! buffer )
{
CCLOG("cocos2d: TiledMap: inflate data error");
CCLOG("cocos2d: TiledMap: decode data error");
return;
}
layer->_tiles = (unsigned int*) deflated;
if( pTMXMapInfo->getLayerAttribs() & (TMXLayerAttribGzip | TMXLayerAttribZlib) )
{
unsigned char *deflated;
Size s = layer->_layerSize;
// int sizeHint = s.width * s.height * sizeof(uint32_t);
int sizeHint = (int)(s.width * s.height * sizeof(unsigned int));
int inflatedLen = ZipUtils::ccInflateMemoryWithHint(buffer, len, &deflated, sizeHint);
CCASSERT(inflatedLen == sizeHint, "");
inflatedLen = (size_t)&inflatedLen; // XXX: to avoid warnings in compiler
delete [] buffer;
buffer = NULL;
if( ! deflated )
{
CCLOG("cocos2d: TiledMap: inflate data error");
return;
}
layer->_tiles = (unsigned int*) deflated;
}
else
{
layer->_tiles = (unsigned int*) buffer;
}
pTMXMapInfo->setCurrentString("");
}
else
else if (pTMXMapInfo->getLayerAttribs() & TMXLayerAttribNone)
{
layer->_tiles = (unsigned int*) buffer;
TMXLayerInfo* layer = (TMXLayerInfo*)pTMXMapInfo->getLayers()->lastObject();
Size layerSize = layer->_layerSize;
int tilesAmount = layerSize.width * layerSize.height;
//reset the layer->_tiles[tilesAmount - 1]
if (tilesAmount > 1 && layer->_tiles[tilesAmount - 2] == 0)
{
layer->_tiles[tilesAmount - 1] = 0;
}
}
pTMXMapInfo->setCurrentString("");
}
}
else if (elementName == "map")
{
// The map element has ended