diff --git a/engine/compilers/Make-32bit/Makefile b/engine/compilers/Make-32bit/Makefile index 4154e3ba3..410364651 100644 --- a/engine/compilers/Make-32bit/Makefile +++ b/engine/compilers/Make-32bit/Makefile @@ -28,6 +28,7 @@ clean: .PHONY: all debug release clean -include x Torque2D.mk +-include x TmxParser.mk -include x zlib -include x lpng -include x ljpeg diff --git a/engine/compilers/Make-32bit/TmxParser.mk b/engine/compilers/Make-32bit/TmxParser.mk new file mode 100644 index 000000000..563fbcfc4 --- /dev/null +++ b/engine/compilers/Make-32bit/TmxParser.mk @@ -0,0 +1,64 @@ +# I release this sample under the MIT license: free for any use, provided +# you hold me harmless from any such use you make, and you retain my +# copyright on the actual sources. +# Copyright 2005 Jon Watte. + +LIBNAME := TmxParser +SOURCES := $(shell find ../../lib/TmxParser -name "*.cpp") + +LDFLAGS_TmxParser := -g -m32 + +CFLAGS_TmxParser := -MMD -I. -m32 -msse -mmmx -march=i686 + +CFLAGS_TmxParser += -I../../lib/TmxParser +CFLAGS_TmxParser += -I../../lib/TmxParser/base64 +CFLAGS_TmxParser += -I../../lib/TmxParser/tinyxml + +CFLAGS_TmxParser += -DUNICODE +CFLAGS_TmxParser += -DLINUX + +CFLAGS_DEBUG_TmxParser := $(CFLAGS_TmxParser) -ggdb +CFLAGS_DEBUG_TmxParser += -DTORQUE_DEBUG +CFLAGS_DEBUG_TmxParser += -DTORQUE_DEBUG_GUARD +CFLAGS_DEBUG_TmxParser += -DTORQUE_NET_STATS + +CFLAGS_TmxParser += -O3 + +CC := gcc +LD := gcc + +TARGET_TmxParser := lib/libTmxParser.a +TARGET_TmxParser_DEBUG := lib/libTmxParser_DEBUG.a + +LIB_TARGETS += $(TARGET_TmxParser) +LIB_TARGETS_DEBUG += $(TARGET_TmxParser_DEBUG) + +OBJS_TmxParser := $(patsubst ../../lib/TmxParser/%,Release/TmxParser/%.o,$(SOURCES)) +OBJS_TmxParser_DEBUG := $(patsubst ../../lib/TmxParser/%,Debug/TmxParser/%.o,$(SOURCES)) + +# Deriving the variable name from the target name is the secret sauce +# of the build system. +# +$(TARGET_TmxParser): $(OBJS_TmxParser) + @mkdir -p $(dir $@) + ar cr $@ $(OBJS_TmxParser) + +$(TARGET_TmxParser_DEBUG): $(OBJS_TmxParser_DEBUG) + @mkdir -p $(dir $@) + ar cr $@ $(OBJS_TmxParser_DEBUG) + +Release/TmxParser/%.o: ../../lib/TmxParser/% + @mkdir -p $(dir $@) + $(CC) -c $(CFLAGS_TmxParser) $< -o $@ + +Debug/TmxParser/%.o: ../../lib/TmxParser/% + @mkdir -p $(dir $@) + $(CC) -c $(CFLAGS_DEBUG_TmxParser) $< -o $@ + +release_TmxParser: $(TARGET_TmxParser) +debug_TmxParser: $(TARGET_TmxParser_DEBUG) + +.PHONY: debug_TmxParser release_TmxParser + +DEPS += $(patsubst %.o,%.d,$(OBJS_TmxParser)) +DEPS += $(patsubst %.o,%.d,$(OBJS_TmxParser_DEBUG)) diff --git a/engine/compilers/Make-32bit/Torque2D.mk b/engine/compilers/Make-32bit/Torque2D.mk index 9a2a40ce6..9ac5e8a86 100644 --- a/engine/compilers/Make-32bit/Torque2D.mk +++ b/engine/compilers/Make-32bit/Torque2D.mk @@ -78,10 +78,13 @@ CFLAGS += -I../../lib/freetype CFLAGS += -I../../lib/libvorbis/include CFLAGS += -I../../lib/libogg/include CFLAGS += -I../../lib/openal/LINUX/ +CFLAGS += -I../../lib/TmxParser/ CFLAGS += -DLINUX CFLAGS += -Di386 +CFLAGS += -Wno-invalid-offsetof + CFLAGS_DEBUG := $(CFLAGS) -ggdb CFLAGS_DEBUG += -DTORQUE_DEBUG diff --git a/engine/compilers/Make-64bit/Makefile b/engine/compilers/Make-64bit/Makefile index 7d5240e40..58ce4ce04 100644 --- a/engine/compilers/Make-64bit/Makefile +++ b/engine/compilers/Make-64bit/Makefile @@ -28,6 +28,7 @@ clean: .PHONY: all debug release clean -include x Torque2D.mk +-include x TmxParser.mk -include x zlib -include x lpng -include x ljpeg diff --git a/engine/compilers/Make-64bit/TmxParser.mk b/engine/compilers/Make-64bit/TmxParser.mk new file mode 100644 index 000000000..1eb064ef1 --- /dev/null +++ b/engine/compilers/Make-64bit/TmxParser.mk @@ -0,0 +1,64 @@ +# I release this sample under the MIT license: free for any use, provided +# you hold me harmless from any such use you make, and you retain my +# copyright on the actual sources. +# Copyright 2005 Jon Watte. + +LIBNAME := TmxParser +SOURCES := $(shell find ../../lib/TmxParser -name "*.cpp") + +LDFLAGS_TmxParser := -g -m64 + +CFLAGS_TmxParser := -MMD -I. -m64 -msse -mmmx -march=x86-64 + +CFLAGS_TmxParser += -I../../lib/TmxParser +CFLAGS_TmxParser += -I../../lib/TmxParser/base64 +CFLAGS_TmxParser += -I../../lib/TmxParser/tinyxml + +CFLAGS_TmxParser += -DUNICODE +CFLAGS_TmxParser += -DLINUX + +CFLAGS_DEBUG_TmxParser := $(CFLAGS_TmxParser) -ggdb +CFLAGS_DEBUG_TmxParser += -DTORQUE_DEBUG +CFLAGS_DEBUG_TmxParser += -DTORQUE_DEBUG_GUARD +CFLAGS_DEBUG_TmxParser += -DTORQUE_NET_STATS + +CFLAGS_TmxParser += -O3 + +CC := gcc +LD := gcc + +TARGET_TmxParser := lib/libTmxParser.a +TARGET_TmxParser_DEBUG := lib/libTmxParser_DEBUG.a + +LIB_TARGETS += $(TARGET_TmxParser) +LIB_TARGETS_DEBUG += $(TARGET_TmxParser_DEBUG) + +OBJS_TmxParser := $(patsubst ../../lib/TmxParser/%,Release/TmxParser/%.o,$(SOURCES)) +OBJS_TmxParser_DEBUG := $(patsubst ../../lib/TmxParser/%,Debug/TmxParser/%.o,$(SOURCES)) + +# Deriving the variable name from the target name is the secret sauce +# of the build system. +# +$(TARGET_TmxParser): $(OBJS_TmxParser) + @mkdir -p $(dir $@) + ar cr $@ $(OBJS_TmxParser) + +$(TARGET_TmxParser_DEBUG): $(OBJS_TmxParser_DEBUG) + @mkdir -p $(dir $@) + ar cr $@ $(OBJS_TmxParser_DEBUG) + +Release/TmxParser/%.o: ../../lib/TmxParser/% + @mkdir -p $(dir $@) + $(CC) -c $(CFLAGS_TmxParser) $< -o $@ + +Debug/TmxParser/%.o: ../../lib/TmxParser/% + @mkdir -p $(dir $@) + $(CC) -c $(CFLAGS_DEBUG_TmxParser) $< -o $@ + +release_TmxParser: $(TARGET_TmxParser) +debug_TmxParser: $(TARGET_TmxParser_DEBUG) + +.PHONY: debug_TmxParser release_TmxParser + +DEPS += $(patsubst %.o,%.d,$(OBJS_TmxParser)) +DEPS += $(patsubst %.o,%.d,$(OBJS_TmxParser_DEBUG)) diff --git a/engine/compilers/Make-64bit/Torque2D.mk b/engine/compilers/Make-64bit/Torque2D.mk index 5fd6bbc50..ca2b4754a 100644 --- a/engine/compilers/Make-64bit/Torque2D.mk +++ b/engine/compilers/Make-64bit/Torque2D.mk @@ -76,11 +76,14 @@ CFLAGS += -I../../lib/freetype CFLAGS += -I../../lib/libvorbis/include CFLAGS += -I../../lib/libogg/include CFLAGS += -I../../lib/openal/LINUX/ +CFLAGS += -I../../lib/TmxParser/ CFLAGS += -DLINUX CFLAGS += -D__amd64__ CFLAGS += -DTORQUE_64 +CFLAGS += -Wno-invalid-offsetof + CFLAGS_DEBUG := $(CFLAGS) -ggdb CFLAGS_DEBUG += -DTORQUE_DEBUG diff --git a/engine/lib/TmxParser/Tmx.h b/engine/lib/TmxParser/Tmx.h new file mode 100644 index 000000000..d70350110 --- /dev/null +++ b/engine/lib/TmxParser/Tmx.h @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// TmxImage.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include "TmxMap.h" +#include "TmxTileset.h" +#include "TmxTile.h" +#include "TmxImage.h" +#include "TmxLayer.h" +#include "TmxObject.h" +#include "TmxObjectGroup.h" +#include "TmxEllipse.h" +#include "TmxPolygon.h" +#include "TmxPolyline.h" +#include "TmxPropertySet.h" +#include "TmxUtil.h" +#include "TmxImageLayer.h" \ No newline at end of file diff --git a/engine/lib/TmxParser/TmxEllipse.cpp b/engine/lib/TmxParser/TmxEllipse.cpp new file mode 100644 index 000000000..4ce7f9d72 --- /dev/null +++ b/engine/lib/TmxParser/TmxEllipse.cpp @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// TmxPolygon.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxEllipse.h" + +namespace Tmx +{ + Ellipse::Ellipse( int _x, int _y, int width, int height ) + : x(_x+(width/2)) + , y(_y+(height/2)) + , radiusX(width/2) + , radiusY(height/2) + { + } +} diff --git a/engine/lib/TmxParser/TmxEllipse.h b/engine/lib/TmxParser/TmxEllipse.h new file mode 100644 index 000000000..242b3beac --- /dev/null +++ b/engine/lib/TmxParser/TmxEllipse.h @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------------- +// TmxPolygon.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include + +#include "TmxPoint.h" + +class TiXmlNode; + +namespace Tmx +{ + //------------------------------------------------------------------------- + // Class to store a Polygon of an Object. + //------------------------------------------------------------------------- + class Ellipse + { + public: + Ellipse( int x, int y, int width, int height ); + + // Get the center of the object, in pixels. + int GetCenterX() const { return x; } + + // Get the center of the object, in pixels. + int GetCenterY() const { return y; } + + // Get the RadiusX of the object, in pixels. + int GetRadiusX() const { return radiusX; } + + // Get the RadiusY of the object, in pixels. + int GetRadiusY() const { return radiusY; } + + private: + int x; + int y; + int radiusX; + int radiusY; + }; +}; \ No newline at end of file diff --git a/engine/lib/TmxParser/TmxImage.cpp b/engine/lib/TmxParser/TmxImage.cpp new file mode 100644 index 000000000..52659bd22 --- /dev/null +++ b/engine/lib/TmxParser/TmxImage.cpp @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// TmxImage.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxImage.h" + +namespace Tmx +{ + Image::Image() + : source() + , width() + , height() + , transparent_color() + {} + + Image::~Image() + {} + + void Image::Parse(const TiXmlNode *imageNode) + { + const TiXmlElement* imageElem = imageNode->ToElement(); + + // Read all the attribute into member variables. + source = imageElem->Attribute("source"); + + imageElem->Attribute("width", &width); + imageElem->Attribute("height", &height); + + const char *trans = imageElem->Attribute("trans"); + if (trans) + { + transparent_color = trans; + } + } +}; diff --git a/engine/lib/TmxParser/TmxImage.h b/engine/lib/TmxParser/TmxImage.h new file mode 100644 index 000000000..e5a8bdaed --- /dev/null +++ b/engine/lib/TmxParser/TmxImage.h @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------------- +// TmxImage.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include + +class TiXmlNode; + +namespace Tmx +{ + //------------------------------------------------------------------------- + // An image within a tileset. + //------------------------------------------------------------------------- + class Image + { + public: + Image(); + ~Image(); + + // Parses an image element. + void Parse(const TiXmlNode *imageNode); + + // Get the path to the file of the image (relative to the map) + const std::string &GetSource() const { return source; } + + // Get the width of the image. + int GetWidth() const { return width; } + + // Get the height of the image. + int GetHeight() const { return height; } + + // Get the transparent color used in the image. + const std::string &GetTransparentColor() const + { return transparent_color; } + + private: + std::string source; + int width; + int height; + std::string transparent_color; + }; +}; diff --git a/engine/lib/TmxParser/TmxImageLayer.cpp b/engine/lib/TmxParser/TmxImageLayer.cpp new file mode 100644 index 000000000..3b145015f --- /dev/null +++ b/engine/lib/TmxParser/TmxImageLayer.cpp @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------------- +// TmxTileset.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxImageLayer.h" +#include "TmxImage.h" + +using std::vector; +using std::string; + +namespace Tmx +{ + ImageLayer::ImageLayer(const Tmx::Map *_map) + : map(_map) + , name() + , width(0) + , height(0) + , image(NULL) + , opacity(0) + , visible(0) + , zOrder(0) + + { + } + + ImageLayer::~ImageLayer() + { + delete image; + } + + void ImageLayer::Parse(const TiXmlNode *imageLayerNode) + { + const TiXmlElement *imagenLayerElem = imageLayerNode->ToElement(); + + // Read all the attributes into local variables. + name = imagenLayerElem->Attribute("name"); + + imagenLayerElem->Attribute("width", &width); + imagenLayerElem->Attribute("height", &height); + + const char *opacityStr = imagenLayerElem->Attribute("opacity"); + if (opacityStr) + { + opacity = (float)atof(opacityStr); + } + + const char *visibleStr = imagenLayerElem->Attribute("visible"); + if (visibleStr) + { + visible = atoi(visibleStr) != 0; // to prevent visual c++ from complaining.. + } + + // Parse the image. + const TiXmlNode *imageNode = imagenLayerElem->FirstChild("image"); + + if (imageNode) + { + image = new Image(); + image->Parse(imageNode); + } + + // Parse the properties if any. + const TiXmlNode *propertiesNode = imagenLayerElem->FirstChild("properties"); + + if (propertiesNode) + { + properties.Parse(propertiesNode); + } + } + +}; diff --git a/engine/lib/TmxParser/TmxImageLayer.h b/engine/lib/TmxParser/TmxImageLayer.h new file mode 100644 index 000000000..cd251c43b --- /dev/null +++ b/engine/lib/TmxParser/TmxImageLayer.h @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------------- +// TmxTileset.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include +#include + +#include "TmxPropertySet.h" + +class TiXmlNode; + +namespace Tmx +{ + class Map; + class Image; + + //------------------------------------------------------------------------- + // A class used for storing information about each of the tilesets. + // A tileset is a collection of tiles, of whom each may contain properties. + // The tileset class itself does not have properties. + //------------------------------------------------------------------------- + class ImageLayer + { + public: + ImageLayer(const Tmx::Map *_map); + ~ImageLayer(); + + // Parse a ImageLayer element. + void Parse(const TiXmlNode *imageLayerNode); + + // Returns the name of the ImageLayer. + const std::string &GetName() const { return name; } + + // Get the width of the ImageLayer. + int GetWidth() const { return width; } + + // Get the height of the ImageLayer. + int GetHeight() const { return height; } + + // Get the visibility of the ImageLayer. + bool IsVisible() const { return visible; } + + // Returns a variable containing information + // about the image of the ImageLayer. + const Tmx::Image* GetImage() const { return image; } + + // Get a set of properties regarding the ImageLayer. + const Tmx::PropertySet &GetProperties() const { return properties; } + + // Get the zorder of the ImageLayer. + int GetZOrder() const { return zOrder; } + + // Set the zorder of the ImageLayer. + void SetZOrder( int z ) { zOrder = z; } + + private: + const Tmx::Map *map; + + std::string name; + + int width; + int height; + + float opacity; + bool visible; + int zOrder; + + Tmx::Image* image; + + Tmx::PropertySet properties; + }; +}; diff --git a/engine/lib/TmxParser/TmxLayer.cpp b/engine/lib/TmxParser/TmxLayer.cpp new file mode 100644 index 000000000..6a44b9f66 --- /dev/null +++ b/engine/lib/TmxParser/TmxLayer.cpp @@ -0,0 +1,278 @@ +//----------------------------------------------------------------------------- +// TmxLayer.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" +#include "../../lib/zlib/zlib.h" +#include +#include + +#include "TmxLayer.h" +#include "TmxUtil.h" +#include "TmxMap.h" +#include "TmxTileset.h" + +namespace Tmx +{ + Layer::Layer(const Map *_map) + : map(_map) + , name() + , width(0) + , height(0) + , opacity(1.0f) + , visible(true) + , zOrder(0) + , properties() + , encoding(TMX_ENCODING_XML) + , compression(TMX_COMPRESSION_NONE) + { + // Set the map to null to specify that it is not yet allocated. + tile_map = NULL; + } + + Layer::~Layer() + { + // If the tile map is allocated, delete it from the memory. + if (tile_map) + { + delete [] tile_map; + tile_map = NULL; + } + } + + void Layer::Parse(const TiXmlNode *layerNode) + { + const TiXmlElement *layerElem = layerNode->ToElement(); + + // Read the attributes. + name = layerElem->Attribute("name"); + + layerElem->Attribute("width", &width); + layerElem->Attribute("height", &height); + + const char *opacityStr = layerElem->Attribute("opacity"); + if (opacityStr) + { + opacity = (float)atof(opacityStr); + } + + const char *visibleStr = layerElem->Attribute("visible"); + if (visibleStr) + { + visible = atoi(visibleStr) != 0; // to prevent visual c++ from complaining.. + } + + // Read the properties. + const TiXmlNode *propertiesNode = layerNode->FirstChild("properties"); + if (propertiesNode) + { + properties.Parse(propertiesNode); + } + + // Allocate memory for reading the tiles. + tile_map = new MapTile[width * height]; + + const TiXmlNode *dataNode = layerNode->FirstChild("data"); + const TiXmlElement *dataElem = dataNode->ToElement(); + + const char *encodingStr = dataElem->Attribute("encoding"); + const char *compressionStr = dataElem->Attribute("compression"); + + // Check for encoding. + if (encodingStr) + { + if (!strcmp(encodingStr, "base64")) + { + encoding = TMX_ENCODING_BASE64; + } + else if (!strcmp(encodingStr, "csv")) + { + encoding = TMX_ENCODING_CSV; + } + } + + // Check for compression. + if (compressionStr) + { + if (!strcmp(compressionStr, "gzip")) + { + compression = TMX_COMPRESSION_GZIP; + } + else if (!strcmp(compressionStr, "zlib")) + { + compression = TMX_COMPRESSION_ZLIB; + } + } + + // Decode. + switch (encoding) + { + case TMX_ENCODING_XML: + ParseXML(dataNode); + break; + + case TMX_ENCODING_BASE64: + ParseBase64(dataElem->GetText()); + break; + + case TMX_ENCODING_CSV: + ParseCSV(dataElem->GetText()); + break; + } + } + + void Layer::ParseXML(const TiXmlNode *dataNode) + { + const TiXmlNode *tileNode = dataNode->FirstChild("tile"); + int tileCount = 0; + + while (tileNode) + { + const TiXmlElement *tileElem = tileNode->ToElement(); + + unsigned gid = 0; + + // Read the Global-ID of the tile. + const char* gidText = tileElem->Attribute("gid"); + + // Convert to an unsigned. + sscanf(gidText, "%u", &gid); + + // Find the tileset index. + const int tilesetIndex = map->FindTilesetIndex(gid); + if (tilesetIndex != -1) + { + // If valid, set up the map tile with the tileset. + const Tmx::Tileset* tileset = map->GetTileset(tilesetIndex); + tile_map[tileCount] = MapTile(gid, tileset->GetFirstGid(), tilesetIndex); + } + else + { + // Otherwise, make it null. + tile_map[tileCount] = MapTile(gid, 0, -1); + } + + tileNode = dataNode->IterateChildren("tile", tileNode); + tileCount++; + } + } + + void Layer::ParseBase64(const std::string &innerText) + { + const std::string &text = Util::DecodeBase64(innerText); + + // Temporary array of gids to be converted to map tiles. + unsigned *out = 0; + + if (compression == TMX_COMPRESSION_ZLIB) + { + // Use zlib to uncompress the layer into the temporary array of tiles. + uLongf outlen = width * height * 4; + out = (unsigned *)malloc(outlen); + uncompress( + (Bytef*)out, &outlen, + (const Bytef*)text.c_str(), text.size()); + + } + else if (compression == TMX_COMPRESSION_GZIP) + { + // Use the utility class for decompressing (which uses zlib) + out = (unsigned *)Util::DecompressGZIP( + text.c_str(), + text.size(), + width * height * 4); + } + else + { + out = (unsigned *)malloc(text.size()); + + // Copy every gid into the temporary array since + // the decoded string is an array of 32-bit integers. + memcpy(out, text.c_str(), text.size()); + } + + // Convert the gids to map tiles. + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + unsigned gid = out[y * width + x]; + + // Find the tileset index. + const int tilesetIndex = map->FindTilesetIndex(gid); + if (tilesetIndex != -1) + { + // If valid, set up the map tile with the tileset. + const Tmx::Tileset* tileset = map->GetTileset(tilesetIndex); + tile_map[y * width + x] = MapTile(gid, tileset->GetFirstGid(), tilesetIndex); + } + else + { + // Otherwise, make it null. + tile_map[y * width + x] = MapTile(gid, 0, -1); + } + } + } + + // Free the temporary array from memory. + free(out); + } + + void Layer::ParseCSV(const std::string &innerText) + { + // Duplicate the string for use with C stdio. + char *csv = strdup(innerText.c_str()); + + // Iterate through every token of ';' in the CSV string. + char *pch = strtok(csv, ","); + int tileCount = 0; + + while (pch) + { + unsigned gid; + sscanf(pch, "%u", &gid); + + // Find the tileset index. + const int tilesetIndex = map->FindTilesetIndex(gid); + if (tilesetIndex != -1) + { + // If valid, set up the map tile with the tileset. + const Tmx::Tileset* tileset = map->GetTileset(tilesetIndex); + tile_map[tileCount] = MapTile(gid, tileset->GetFirstGid(), tilesetIndex); + } + else + { + // Otherwise, make it null. + tile_map[tileCount] = MapTile(gid, 0, -1); + } + + pch = strtok(NULL, ","); + tileCount++; + } + + free(csv); + } +}; diff --git a/engine/lib/TmxParser/TmxLayer.h b/engine/lib/TmxParser/TmxLayer.h new file mode 100644 index 000000000..762d1e05a --- /dev/null +++ b/engine/lib/TmxParser/TmxLayer.h @@ -0,0 +1,151 @@ +//----------------------------------------------------------------------------- +// TmxLayer.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include + +#include "TmxPropertySet.h" +#include "TmxMapTile.h" + +class TiXmlNode; + +namespace Tmx +{ + class Map; + + //------------------------------------------------------------------------- + // Type used for the encoding of the layer data. + //------------------------------------------------------------------------- + enum LayerEncodingType + { + TMX_ENCODING_XML, + TMX_ENCODING_BASE64, + TMX_ENCODING_CSV + }; + + //------------------------------------------------------------------------- + // Type used for the compression of the layer data. + //------------------------------------------------------------------------- + enum LayerCompressionType + { + TMX_COMPRESSION_NONE, + TMX_COMPRESSION_ZLIB, + TMX_COMPRESSION_GZIP + }; + + //------------------------------------------------------------------------- + // Used for storing information about the tile ids for every layer. + // This class also have a property set. + //------------------------------------------------------------------------- + class Layer + { + private: + // Prevent copy constructor. + Layer(const Layer &_layer); + + public: + Layer(const Tmx::Map *_map); + ~Layer(); + + // Parse a layer node. + void Parse(const TiXmlNode *layerNode); + + // Get the name of the layer. + const std::string &GetName() const { return name; } + + // Get the width of the layer, in tiles. + int GetWidth() const { return width; } + + // Get the height of the layer, in tiles. + int GetHeight() const { return height; } + + // Get the visibility of the layer + bool IsVisible() const { return visible; } + + // Get the property set. + const Tmx::PropertySet &GetProperties() const { return properties; } + + // Pick a specific tile from the list. + unsigned GetTileId(int x, int y) const { return tile_map[y * width + x].id; } + + // Get the tileset index for a tileset from the list. + int GetTileTilesetIndex(int x, int y) const { return tile_map[y * width + x].tilesetId; } + + // Get whether a tile is flipped horizontally. + bool IsTileFlippedHorizontally(int x, int y) const + { return tile_map[y * width + x].flippedHorizontally; } + + // Get whether a tile is flipped vertically. + bool IsTileFlippedVertically(int x, int y) const + { return tile_map[y * width + x].flippedVertically; } + + // Get whether a tile is flipped diagonally. + bool IsTileFlippedDiagonally(int x, int y) const + { return tile_map[y * width + x].flippedDiagonally; } + + // Get a tile specific to the map. + const Tmx::MapTile& GetTile(int x, int y) const { return tile_map[y * width + x]; } + + // Get the type of encoding that was used for parsing the layer data. + // See: LayerEncodingType + Tmx::LayerEncodingType GetEncoding() const { return encoding; } + + // Get the type of compression that was used for parsing the layer data. + // See: LayerCompressionType + Tmx::LayerCompressionType GetCompression() const { return compression; } + + // Get the zorder of the layer. + int GetZOrder() const { return zOrder; } + + // Set the zorder of the layer. + void SetZOrder( int z ) { zOrder = z; } + + private: + void ParseXML(const TiXmlNode *dataNode); + void ParseBase64(const std::string &innerText); + void ParseCSV(const std::string &innerText); + + const Tmx::Map *map; + + std::string name; + + int width; + int height; + + float opacity; + bool visible; + int zOrder; + + Tmx::PropertySet properties; + + Tmx::MapTile *tile_map; + + Tmx::LayerEncodingType encoding; + Tmx::LayerCompressionType compression; + }; +}; diff --git a/engine/lib/TmxParser/TmxMap.cpp b/engine/lib/TmxParser/TmxMap.cpp new file mode 100644 index 000000000..8d187abb8 --- /dev/null +++ b/engine/lib/TmxParser/TmxMap.cpp @@ -0,0 +1,329 @@ +//----------------------------------------------------------------------------- +// TmxMap.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" +#include + +#include "TmxMap.h" +#include "TmxTileset.h" +#include "TmxLayer.h" +#include "TmxObjectGroup.h" +#include "TmxImageLayer.h" + +#ifdef USE_SDL2_LOAD +#include +#endif + +using std::vector; +using std::string; + +namespace Tmx +{ + Map::Map() + : file_name() + , file_path() + , version(0.0) + , orientation(TMX_MO_ORTHOGONAL) + , width(0) + , height(0) + , tile_width(0) + , tile_height(0) + , layers() + , object_groups() + , tilesets() + , has_error(false) + , error_code(0) + , error_text() + {} + + Map::~Map() + { + // Iterate through all of the object groups and delete each of them. + vector< ObjectGroup* >::iterator ogIter; + for (ogIter = object_groups.begin(); ogIter != object_groups.end(); ++ogIter) + { + ObjectGroup *objectGroup = (*ogIter); + + if (objectGroup) + { + delete objectGroup; + objectGroup = NULL; + } + } + + // Iterate through all of the layers and delete each of them. + vector< Layer* >::iterator lIter; + for (lIter = layers.begin(); lIter != layers.end(); ++lIter) + { + Layer *layer = (*lIter); + + if (layer) + { + delete layer; + layer = NULL; + } + } + + // Iterate through all of the layers and delete each of them. + vector< ImageLayer* >::iterator ilIter; + for (ilIter = image_layers.begin(); ilIter != image_layers.end(); ++ilIter) + { + ImageLayer *layer = (*ilIter); + + if (layer) + { + delete layer; + layer = NULL; + } + } + + // Iterate through all of the tilesets and delete each of them. + vector< Tileset* >::iterator tsIter; + for (tsIter = tilesets.begin(); tsIter != tilesets.end(); ++tsIter) + { + Tileset *tileset = (*tsIter); + + if (tileset) + { + delete tileset; + tileset = NULL; + } + } + } + + void Map::ParseFile(const string &fileName) + { + file_name = fileName; + + int lastSlash = fileName.find_last_of("/"); + + // Get the directory of the file using substring. + if (lastSlash > 0) + { + file_path = fileName.substr(0, lastSlash + 1); + } + else + { + file_path = ""; + } + + char* fileText; + int fileSize; + + // Open the file for reading. +#ifdef USE_SDL2_LOAD + SDL_RWops * file = SDL_RWFromFile (fileName.c_str(), "rb"); +#else + FILE *file = fopen(fileName.c_str(), "rb"); +#endif + + // Check if the file could not be opened. + if (!file) + { + has_error = true; + error_code = TMX_COULDNT_OPEN; + error_text = "Could not open the file."; + return; + } + + // Find out the file size. +#ifdef USE_SDL2_LOAD + fileSize = file->size(file); +#else + fseek(file, 0, SEEK_END); + fileSize = ftell(file); + fseek(file, 0, SEEK_SET); +#endif + + // Check if the file size is valid. + if (fileSize <= 0) + { + has_error = true; + error_code = TMX_INVALID_FILE_SIZE; + error_text = "The size of the file is invalid."; + return; + } + + // Allocate memory for the file and read it into the memory. + fileText = new char[fileSize + 1]; + fileText[fileSize] = 0; +#ifdef USE_SDL2_LOAD + file->read(file, fileText, 1, fileSize); +#else + fread(fileText, 1, fileSize, file); +#endif + +#ifdef USE_SDL2_LOAD + file->close(file); +#else + fclose(file); +#endif + + // Copy the contents into a C++ string and delete it from memory. + std::string text(fileText, fileText+fileSize); + delete [] fileText; + + ParseText(text); + } + + void Map::ParseText(const string &text) + { + // Create a tiny xml document and use it to parse the text. + TiXmlDocument doc; + doc.Parse(text.c_str()); + + // Check for parsing errors. + if (doc.Error()) + { + has_error = true; + error_code = TMX_PARSING_ERROR; + error_text = doc.ErrorDesc(); + return; + } + + TiXmlNode *mapNode = doc.FirstChild("map"); + TiXmlElement* mapElem = mapNode->ToElement(); + + // Read the map attributes. + mapElem->Attribute("version", &version); + mapElem->Attribute("width", &width); + mapElem->Attribute("height", &height); + mapElem->Attribute("tilewidth", &tile_width); + mapElem->Attribute("tileheight", &tile_height); + + // Read the orientation + std::string orientationStr = mapElem->Attribute("orientation"); + + if (!orientationStr.compare("orthogonal")) + { + orientation = TMX_MO_ORTHOGONAL; + } + else if (!orientationStr.compare("isometric")) + { + orientation = TMX_MO_ISOMETRIC; + } + else if (!orientationStr.compare("staggered")) + { + orientation = TMX_MO_STAGGERED; + } + + + const TiXmlNode *node = mapElem->FirstChild(); + int zOrder = 0; + while( node ) + { + // Read the map properties. + if( strcmp( node->Value(), "properties" ) == 0 ) + { + properties.Parse(node); + } + + // Iterate through all of the tileset elements. + if( strcmp( node->Value(), "tileset" ) == 0 ) + { + // Allocate a new tileset and parse it. + Tileset *tileset = new Tileset(); + tileset->Parse(node->ToElement()); + + // Add the tileset to the list. + tilesets.push_back(tileset); + } + + // Iterate through all of the layer elements. + if( strcmp( node->Value(), "layer" ) == 0 ) + { + // Allocate a new layer and parse it. + Layer *layer = new Layer(this); + layer->Parse(node); + layer->SetZOrder( zOrder ); + ++zOrder; + + // Add the layer to the list. + layers.push_back(layer); + } + + // Iterate through all of the imagen layer elements. + if( strcmp( node->Value(), "imagelayer" ) == 0 ) + { + // Allocate a new layer and parse it. + ImageLayer *imageLayer = new ImageLayer(this); + imageLayer->Parse(node); + imageLayer->SetZOrder( zOrder ); + ++zOrder; + + // Add the layer to the list. + image_layers.push_back(imageLayer); + } + + // Iterate through all of the objectgroup elements. + if( strcmp( node->Value(), "objectgroup" ) == 0 ) + { + // Allocate a new object group and parse it. + ObjectGroup *objectGroup = new ObjectGroup(); + objectGroup->Parse(node); + objectGroup->SetZOrder( zOrder ); + ++zOrder; + + // Add the object group to the list. + object_groups.push_back(objectGroup); + } + + node = node->NextSibling(); + } + } + + int Map::FindTilesetIndex(int gid) const + { + // Clean up the flags from the gid (thanks marwes91). + gid &= ~(FlippedHorizontallyFlag | FlippedVerticallyFlag | FlippedDiagonallyFlag); + + for (int i = tilesets.size() - 1; i > -1; --i) + { + // If the gid beyond the tileset gid return its index. + if (gid >= tilesets[i]->GetFirstGid()) + { + return i; + } + } + + return -1; + } + + const Tileset *Map::FindTileset(int gid) const + { + for (int i = tilesets.size() - 1; i > -1; --i) + { + // If the gid beyond the tileset gid return it. + if (gid >= tilesets[i]->GetFirstGid()) + { + return tilesets[i]; + } + } + + return NULL; + } +}; diff --git a/engine/lib/TmxParser/TmxMap.h b/engine/lib/TmxParser/TmxMap.h new file mode 100644 index 000000000..61c1d6b86 --- /dev/null +++ b/engine/lib/TmxParser/TmxMap.h @@ -0,0 +1,196 @@ +//----------------------------------------------------------------------------- +// TmxMap.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include +#include + +#include "TmxPropertySet.h" + +namespace Tmx +{ + class Layer; + class ImageLayer; + class ObjectGroup; + class Tileset; + + //------------------------------------------------------------------------- + // Error in handling of the Map class. + //------------------------------------------------------------------------- + enum MapError + { + // A file could not be opened. (usually due to permission problems) + TMX_COULDNT_OPEN = 0x01, + + // There was an error in parsing the TMX file. + // This is being caused by TinyXML parsing problems. + TMX_PARSING_ERROR = 0x02, + + // The size of the file is invalid. + TMX_INVALID_FILE_SIZE = 0x04 + }; + + //------------------------------------------------------------------------- + // The way the map is viewed. + //------------------------------------------------------------------------- + enum MapOrientation + { + // This map is an orthogonal map. + TMX_MO_ORTHOGONAL = 0x01, + + // This map is an isometric map. + TMX_MO_ISOMETRIC = 0x02, + + // This map is an isometric staggered map. + TMX_MO_STAGGERED = 0x03 + }; + + //------------------------------------------------------------------------- + // This class is the root class of the parser. + // It has all of the information in regard to the TMX file. + // This class has a property set. + //------------------------------------------------------------------------- + class Map + { + private: + // Prevent copy constructor. + Map(const Map &_map); + + public: + Map(); + ~Map(); + + // Read a file and parse it. + // Note: use '/' instead of '\\' as it is using '/' to find the path. + void ParseFile(const std::string &fileName); + + // Parse text containing TMX formatted XML. + void ParseText(const std::string &text); + + // Get the filename used to read the map. + const std::string &GetFilename() { return file_name; } + + // Get a path to the directory of the map file if any. + const std::string &GetFilepath() const { return file_path; } + + // Get the version of the map. + double GetVersion() const { return version; } + + // Get the orientation of the map. + Tmx::MapOrientation GetOrientation() const { return orientation; } + + // Get the width of the map, in tiles. + int GetWidth() const { return width; } + + // Get the height of the map, in tiles. + int GetHeight() const { return height; } + + // Get the width of a tile, in pixels. + int GetTileWidth() const { return tile_width; } + + // Get the height of a tile, in pixels. + int GetTileHeight() const { return tile_height; } + + // Get the layer at a certain index. + const Tmx::Layer *GetLayer(int index) const { return layers.at(index); } + + // Get the amount of layers. + int GetNumLayers() const { return layers.size(); } + + // Get the whole layers collection. + const std::vector< Tmx::Layer* > &GetLayers() const { return layers; } + + // Get the object group at a certain index. + const Tmx::ObjectGroup *GetObjectGroup(int index) const { return object_groups.at(index); } + + // Get the amount of object groups. + int GetNumObjectGroups() const { return object_groups.size(); } + + // Get the whole object group collection. + const std::vector< Tmx::ObjectGroup* > &GetObjectGroups() const { return object_groups; } + + // Get the layer at a certain index. + const Tmx::ImageLayer *GetImageLayer(int index) const { return image_layers.at(index); } + + // Get the amount of layers. + int GetNumImageLayers() const { return image_layers.size(); } + + // Get the whole layers collection. + const std::vector< Tmx::ImageLayer* > &GetImageLayers() const { return image_layers; } + + // Find the tileset index for a tileset using a tile gid. + int FindTilesetIndex(int gid) const; + + // Find a tileset for a specific gid. + const Tmx::Tileset *FindTileset(int gid) const; + + // Get a tileset by an index. + const Tmx::Tileset *GetTileset(int index) const { return tilesets.at(index); } + + // Get the amount of tilesets. + int GetNumTilesets() const { return tilesets.size(); } + + // Get the collection of tilesets. + const std::vector< Tmx::Tileset* > &GetTilesets() const { return tilesets; } + + // Get whether there was an error or not. + bool HasError() const { return has_error; } + + // Get an error string containing the error in text format. + const std::string &GetErrorText() const { return error_text; } + + // Get a number that identifies the error. (TMX_ preceded constants) + unsigned char GetErrorCode() const { return error_code; } + + // Get the property set. + const Tmx::PropertySet &GetProperties() const { return properties; } + + private: + std::string file_name; + std::string file_path; + + double version; + Tmx::MapOrientation orientation; + + int width; + int height; + int tile_width; + int tile_height; + + std::vector< Tmx::Layer* > layers; + std::vector< Tmx::ImageLayer* > image_layers; + std::vector< Tmx::ObjectGroup* > object_groups; + std::vector< Tmx::Tileset* > tilesets; + + bool has_error; + unsigned char error_code; + std::string error_text; + + Tmx::PropertySet properties; + }; +}; diff --git a/engine/lib/TmxParser/TmxMapTile.h b/engine/lib/TmxParser/TmxMapTile.h new file mode 100644 index 000000000..96005d500 --- /dev/null +++ b/engine/lib/TmxParser/TmxMapTile.h @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// TmxMapTile.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +namespace Tmx +{ + //------------------------------------------------------------------------- + // Flags that may be in the first two bits of the gid. + //------------------------------------------------------------------------- + const unsigned FlippedHorizontallyFlag = 0x80000000; + const unsigned FlippedVerticallyFlag = 0x40000000; + const unsigned FlippedDiagonallyFlag = 0x20000000; + + //------------------------------------------------------------------------- + // Struct to store information about a specific tile in the map layer. + //------------------------------------------------------------------------- + struct MapTile + { + // Default constructor. + MapTile() + : tilesetId(0) + , id(0) + , flippedHorizontally(false) + , flippedVertically(false) + , flippedDiagonally(false) + {} + + // Will take a gid and read the attributes from the first + // two bits of it. + MapTile(unsigned _gid, int _tilesetFirstGid, unsigned _tilesetId) + : tilesetId(_tilesetId) + , id(_gid & ~(FlippedHorizontallyFlag | FlippedVerticallyFlag | FlippedDiagonallyFlag)) + , flippedHorizontally((_gid & FlippedHorizontallyFlag) != 0) + , flippedVertically((_gid & FlippedVerticallyFlag) != 0) + , flippedDiagonally((_gid & FlippedDiagonallyFlag) != 0) + { + id -= _tilesetFirstGid; + } + + // Tileset id. + int tilesetId; + + // Id. + unsigned id; + + // True when the tile should be drawn flipped horizontally. + bool flippedHorizontally; + + // True when the tile should be drawn flipped vertically. + bool flippedVertically; + + // True when the tile should be drawn flipped diagonally. + bool flippedDiagonally; + }; +}; diff --git a/engine/lib/TmxParser/TmxObject.cpp b/engine/lib/TmxParser/TmxObject.cpp new file mode 100644 index 000000000..d162abefa --- /dev/null +++ b/engine/lib/TmxParser/TmxObject.cpp @@ -0,0 +1,124 @@ +//----------------------------------------------------------------------------- +// TmxObject.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxObject.h" +#include "TmxPolygon.h" +#include "TmxPolyline.h" +#include "TmxEllipse.h" + +namespace Tmx +{ + Object::Object() + : name() + , type() + , x(0) + , y(0) + , width(0) + , height(0) + , gid(0) + , ellipse(0) + , polygon(0) + , polyline(0) + , properties() + {} + + Object::~Object() + { + if (ellipse != 0) + { + delete ellipse; + ellipse = 0; + } + if (polygon != 0) + { + delete polygon; + polygon = 0; + } + if (polyline != 0) + { + delete polyline; + polyline = 0; + } + } + + void Object::Parse(const TiXmlNode *objectNode) + { + const TiXmlElement *objectElem = objectNode->ToElement(); + + // Read the attributes of the object. + const char *tempName = objectElem->Attribute("name"); + const char *tempType = objectElem->Attribute("type"); + + if (tempName) name = tempName; + if (tempType) type = tempType; + + objectElem->Attribute("x", &x); + objectElem->Attribute("y", &y); + objectElem->Attribute("width", &width); + objectElem->Attribute("height", &height); + objectElem->Attribute("gid", &gid); + + // Read the ellipse of the object if there are any. + const TiXmlNode *ellipseNode = objectNode->FirstChild("ellipse"); + if (ellipseNode) + { + if (ellipse != 0) + delete ellipse; + + ellipse = new Ellipse(x,y,width,height); + } + + // Read the Polygon and Polyline of the object if there are any. + const TiXmlNode *polygonNode = objectNode->FirstChild("polygon"); + if (polygonNode) + { + if (polygon != 0) + delete polygon; + + polygon = new Polygon(); + polygon->Parse(polygonNode); + } + const TiXmlNode *polylineNode = objectNode->FirstChild("polyline"); + if (polylineNode) + { + if (polyline != 0) + delete polyline; + + polyline = new Polyline(); + polyline->Parse(polylineNode); + } + + // Read the properties of the object. + const TiXmlNode *propertiesNode = objectNode->FirstChild("properties"); + if (propertiesNode) + { + properties.Parse(propertiesNode); + } + } +}; diff --git a/engine/lib/TmxParser/TmxObject.h b/engine/lib/TmxParser/TmxObject.h new file mode 100644 index 000000000..a9a91efca --- /dev/null +++ b/engine/lib/TmxParser/TmxObject.h @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------- +// TmxObject.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include + +#include "TmxPropertySet.h" + +class TiXmlNode; + +namespace Tmx +{ + class Ellipse; + class Polygon; + class Polyline; + + //------------------------------------------------------------------------- + // Class used for representing a single object from the objectgroup. + //------------------------------------------------------------------------- + class Object + { + public: + Object(); + ~Object(); + + // Parse an object node. + void Parse(const TiXmlNode *objectNode); + + // Get the name of the object. + const std::string &GetName() const { return name; } + + // Get the type of the object. + const std::string &GetType() const { return type; } + + // Get the left side of the object, in pixels. + int GetX() const { return x; } + + // Get the top side of the object, in pixels. + int GetY() const { return y; } + + // Get the width of the object, in pixels. + int GetWidth() const { return width; } + + // Get the height of the object, in pixels. + int GetHeight() const { return height; } + + // Get the Global ID of the tile associated with this object. + int GetGid() const { return gid; } + + // Get the ellipse. + const Tmx::Ellipse *GetEllipse() const { return ellipse; } + + // Get the Polygon. + const Tmx::Polygon *GetPolygon() const { return polygon; } + + // Get the Polyline. + const Tmx::Polyline *GetPolyline() const { return polyline; } + + // Get the property set. + const Tmx::PropertySet &GetProperties() const { return properties; } + + private: + std::string name; + std::string type; + + int x; + int y; + int width; + int height; + int gid; + + Tmx::Ellipse *ellipse; + Tmx::Polygon *polygon; + Tmx::Polyline *polyline; + + Tmx::PropertySet properties; + }; +}; diff --git a/engine/lib/TmxParser/TmxObjectGroup.cpp b/engine/lib/TmxParser/TmxObjectGroup.cpp new file mode 100644 index 000000000..8c6e73fe3 --- /dev/null +++ b/engine/lib/TmxParser/TmxObjectGroup.cpp @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// TmxObjectGroup.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxObjectGroup.h" +#include "TmxObject.h" + +namespace Tmx +{ + ObjectGroup::ObjectGroup() + : name() + , width(0) + , height(0) + , zOrder(0) + {} + + ObjectGroup::~ObjectGroup() + { + for(std::size_t i = 0; i < objects.size(); i++) + { + Object *obj = objects.at(i); + delete obj; + } + } + + void ObjectGroup::Parse(const TiXmlNode *objectGroupNode) + { + const TiXmlElement *objectGroupElem = objectGroupNode->ToElement(); + if (objectGroupElem) { + // Read the object group attributes. + const char* nom = objectGroupElem->Attribute("name"); + if (nom) + name = nom; + + objectGroupElem->Attribute("width", &width); + objectGroupElem->Attribute("height", &height); + objectGroupElem->Attribute("visible", &visible); + } + // Read the properties. + const TiXmlNode *propertiesNode = objectGroupNode->FirstChild("properties"); + if (propertiesNode) + { + properties.Parse(propertiesNode); + } + + // Iterate through all of the object elements. + const TiXmlNode *objectNode = objectGroupNode->FirstChild("object"); + while (objectNode) + { + // Allocate a new object and parse it. + Object *object = new Object(); + object->Parse(objectNode); + + // Add the object to the list. + objects.push_back(object); + + objectNode = objectGroupNode->IterateChildren("object", objectNode); + } + } + +}; diff --git a/engine/lib/TmxParser/TmxObjectGroup.h b/engine/lib/TmxParser/TmxObjectGroup.h new file mode 100644 index 000000000..e4fd99435 --- /dev/null +++ b/engine/lib/TmxParser/TmxObjectGroup.h @@ -0,0 +1,98 @@ +//----------------------------------------------------------------------------- +// TmxObjectGroup.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include +#include + +#include "TmxPropertySet.h" + +class TiXmlNode; + +namespace Tmx +{ + class Object; + + //------------------------------------------------------------------------- + // A class used for holding a list of objects. + // This class doesn't have a property set. + //------------------------------------------------------------------------- + class ObjectGroup + { + public: + ObjectGroup(); + ~ObjectGroup(); + + // Parse an objectgroup node. + void Parse(const TiXmlNode *objectGroupNode); + + // Get the name of the object group. + const std::string &GetName() const { return name; } + + // Get the width of the object group, in pixels. + // Note: do not rely on this due to temporary bug in tiled. + int GetWidth() const { return width; } + + // Get the height of the object group, in pixels. + // Note: do not rely on this due to temporary bug in tiled. + int GetHeight() const { return height; } + + // Get a single object. + const Tmx::Object *GetObject(int index) const { return objects.at(index); } + + // Get the number of objects in the list. + int GetNumObjects() const { return objects.size(); } + + // Get whether the object layer is visible. + int GetVisibility() const { return visible; } + + // Get the property set. + const Tmx::PropertySet &GetProperties() const { return properties; } + + // Get the whole list of objects. + const std::vector< Tmx::Object* > &GetObjects() const { return objects; } + + // Get the zorder of the object group. + int GetZOrder() const { return zOrder; } + + // Set the zorder of the object group. + void SetZOrder( int z ) { zOrder = z; } + + private: + std::string name; + + int width; + int height; + int visible; + int zOrder; + + Tmx::PropertySet properties; + + std::vector< Tmx::Object* > objects; + }; +}; diff --git a/engine/lib/TmxParser/TmxPoint.h b/engine/lib/TmxParser/TmxPoint.h new file mode 100644 index 000000000..e35f18803 --- /dev/null +++ b/engine/lib/TmxParser/TmxPoint.h @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// TmxPoint.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +namespace Tmx +{ + //------------------------------------------------------------------------- + // Used to store a vertex of a Polygon/Polyline. + //------------------------------------------------------------------------- + struct Point + { + double x; + double y; + }; +} diff --git a/engine/lib/TmxParser/TmxPolygon.cpp b/engine/lib/TmxParser/TmxPolygon.cpp new file mode 100644 index 000000000..9c4958dab --- /dev/null +++ b/engine/lib/TmxParser/TmxPolygon.cpp @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// TmxPolygon.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxPolygon.h" + +namespace Tmx +{ + Polygon::Polygon() + : points() + { + } + + void Polygon::Parse(const TiXmlNode *polygonNode) + { + char *pointsLine = strdup(polygonNode->ToElement()->Attribute("points")); + + char *token = strtok(pointsLine, " "); + while (token) + { + Point point; + sscanf(token, "%lf,%lf", &point.x, &point.y); + + points.push_back(point); + + token = strtok(0, " "); + } + + free(pointsLine); + } +} diff --git a/engine/lib/TmxParser/TmxPolygon.h b/engine/lib/TmxParser/TmxPolygon.h new file mode 100644 index 000000000..ccbac799f --- /dev/null +++ b/engine/lib/TmxParser/TmxPolygon.h @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// TmxPolygon.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include + +#include "TmxPoint.h" + +class TiXmlNode; + +namespace Tmx +{ + //------------------------------------------------------------------------- + // Class to store a Polygon of an Object. + //------------------------------------------------------------------------- + class Polygon + { + public: + Polygon(); + + // Parse the polygon node. + void Parse(const TiXmlNode *polygonNode); + + // Get one of the vertices. + const Tmx::Point &GetPoint(int index) const { return points[index]; } + + // Get the number of vertices. + int GetNumPoints() const { return points.size(); } + + private: + std::vector< Tmx::Point > points; + }; +}; diff --git a/engine/lib/TmxParser/TmxPolyline.cpp b/engine/lib/TmxParser/TmxPolyline.cpp new file mode 100644 index 000000000..4f6d166f2 --- /dev/null +++ b/engine/lib/TmxParser/TmxPolyline.cpp @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------- +// TmxPolyline.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxPolyline.h" + +namespace Tmx +{ + Polyline::Polyline() + : points() + { + } + + void Polyline::Parse(const TiXmlNode *polylineNode) + { + char *pointsLine = strdup(polylineNode->ToElement()->Attribute("points")); + + char *token = strtok(pointsLine, " "); + while (token) + { + Point point; + sscanf(token, "%lf,%lf", &point.x, &point.y); + + points.push_back(point); + + token = strtok(0, " "); + } + + free(pointsLine); + } +} diff --git a/engine/lib/TmxParser/TmxPolyline.h b/engine/lib/TmxParser/TmxPolyline.h new file mode 100644 index 000000000..bfc3e1ebe --- /dev/null +++ b/engine/lib/TmxParser/TmxPolyline.h @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// TmxPolyline.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include + +#include "TmxPoint.h" + +class TiXmlNode; + +namespace Tmx +{ + //------------------------------------------------------------------------- + // Class to store a Polyline of an Object. + //------------------------------------------------------------------------- + class Polyline + { + public: + Polyline(); + + // Parse the polyline node. + void Parse(const TiXmlNode *polylineNode); + + // Get one of the vertices. + const Tmx::Point &GetPoint(int index) const { return points[index]; } + + // Get the number of vertices. + int GetNumPoints() const { return points.size(); } + + private: + std::vector< Tmx::Point > points; + }; +}; diff --git a/engine/lib/TmxParser/TmxPropertySet.cpp b/engine/lib/TmxParser/TmxPropertySet.cpp new file mode 100644 index 000000000..b2551cffe --- /dev/null +++ b/engine/lib/TmxParser/TmxPropertySet.cpp @@ -0,0 +1,94 @@ +//----------------------------------------------------------------------------- +// TmxPropertySet.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxPropertySet.h" + +using std::string; +using std::map; + +namespace Tmx +{ + + PropertySet::PropertySet() : properties() + {} + + PropertySet::~PropertySet() + { + properties.clear(); + } + + void PropertySet::Parse(const TiXmlNode *propertiesNode) + { + // Iterate through all of the property nodes. + const TiXmlNode *propertyNode = propertiesNode->FirstChild("property"); + string propertyName; + string propertyValue; + + while (propertyNode) + { + const TiXmlElement* propertyElem = propertyNode->ToElement(); + + // Read the attributes of the property and add it to the map + propertyName = string(propertyElem->Attribute("name")); + propertyValue = string(propertyElem->Attribute("value")); + properties[propertyName] = propertyValue; + + propertyNode = propertiesNode->IterateChildren( + "property", propertyNode); + } + } + + string PropertySet::GetLiteralProperty(const string &name) const + { + // Find the property in the map. + map< string, string >::const_iterator iter = properties.find(name); + + if (iter == properties.end()) + return std::string(""); + + return iter->second; + } + + int PropertySet::GetNumericProperty(const string &name) const + { + return atoi(GetLiteralProperty(name).c_str()); + } + + float PropertySet::GetFloatProperty(const string &name) const + { + return float(atof(GetLiteralProperty(name).c_str())); + } + + bool PropertySet::HasProperty( const string& name ) const + { + if( properties.empty() ) return false; + return ( properties.find(name) != properties.end() ); + } + +}; diff --git a/engine/lib/TmxParser/TmxPropertySet.h b/engine/lib/TmxParser/TmxPropertySet.h new file mode 100644 index 000000000..34686ac51 --- /dev/null +++ b/engine/lib/TmxParser/TmxPropertySet.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// TmxPropertySet.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include +#include + +class TiXmlNode; + +namespace Tmx +{ + //----------------------------------------------------------------------------- + // This class contains a map of properties. + //----------------------------------------------------------------------------- + class PropertySet + { + public: + PropertySet(); + ~PropertySet(); + + // Parse a node containing all the property nodes. + void Parse(const TiXmlNode *propertiesNode); + + // Get a numeric property (integer). + int GetNumericProperty(const std::string &name) const; + // Get a numeric property (float). + float GetFloatProperty(const std::string &name) const; + + // Get a literal property (string). + std::string GetLiteralProperty(const std::string &name) const; + + // Returns the amount of properties. + int GetSize() const { return properties.size(); } + + bool HasProperty( const std::string& name ) const; + + // Returns the STL map of the properties. + std::map< std::string, std::string > GetList() const + { return properties; } + + // Returns whether there are no properties. + bool Empty() const { return properties.empty(); } + + private: + std::map< std::string, std::string > properties; + + }; +}; diff --git a/engine/lib/TmxParser/TmxTile.cpp b/engine/lib/TmxParser/TmxTile.cpp new file mode 100644 index 000000000..3c58bb380 --- /dev/null +++ b/engine/lib/TmxParser/TmxTile.cpp @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// TmxTile.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +// Major revisions: Casey Doran +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxTile.h" + +namespace Tmx +{ + Tile::Tile() : properties() + {} + + Tile::~Tile() + {} + + void Tile::Parse(const TiXmlNode *tileNode) + { + const TiXmlElement *tileElem = tileNode->ToElement(); + + // Parse the attributes. + tileElem->Attribute("id", &id); + + // Parse the properties if any. + const TiXmlNode *propertiesNode = tileNode->FirstChild("properties"); + + if (propertiesNode) + { + properties.Parse(propertiesNode); + } + + //Parse the objects, if any + const TiXmlNode *objectsNode = tileNode->FirstChild("objectgroup"); + + if (objectsNode){ + objects.Parse(objectsNode); + } + } +}; diff --git a/engine/lib/TmxParser/TmxTile.h b/engine/lib/TmxParser/TmxTile.h new file mode 100644 index 000000000..cff3f21bd --- /dev/null +++ b/engine/lib/TmxParser/TmxTile.h @@ -0,0 +1,66 @@ +//----------------------------------------------------------------------------- +// TmxTile.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +// Major revisions: Casey Doran +//----------------------------------------------------------------------------- +#pragma once + +#include "TmxPropertySet.h" +#include "TmxObjectGroup.h" + +namespace Tmx +{ + //------------------------------------------------------------------------- + // Class to contain information about every tile in the tileset/tiles + // element. + // It may expand if there are more elements or attributes added into the + // the tile element. + // This class also contains a property set. + //------------------------------------------------------------------------- + class Tile + { + public: + Tile(); + ~Tile(); + + // Parse a tile node. + void Parse(const TiXmlNode *tileNode); + + // Get the Id. (relative to the tilset) + int GetId() const { return id; } + + // Get a set of properties regarding the tile. + const Tmx::PropertySet &GetProperties() const { return properties; } + const Tmx::ObjectGroup &GetObjectGroup() const{ return + objects;} + + private: + int id; + + Tmx::PropertySet properties; + Tmx::ObjectGroup objects; + }; +}; diff --git a/engine/lib/TmxParser/TmxTileset.cpp b/engine/lib/TmxParser/TmxTileset.cpp new file mode 100644 index 000000000..fecc11d93 --- /dev/null +++ b/engine/lib/TmxParser/TmxTileset.cpp @@ -0,0 +1,131 @@ +//----------------------------------------------------------------------------- +// TmxTileset.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include "tinyxml/tinyxml.h" + +#include "TmxTileset.h" +#include "TmxImage.h" +#include "TmxTile.h" + +using std::vector; +using std::string; + +namespace Tmx +{ + Tileset::Tileset() + : first_gid(0) + , name() + , tile_width(0) + , tile_height(0) + , margin(0) + , spacing(0) + , image(NULL) + , tiles() + { + } + + Tileset::~Tileset() + { + // Delete the image from memory if allocated. + if (image) + { + delete image; + image = NULL; + } + + // Iterate through all of the tiles in the set and delete each of them. + vector< Tile* >::iterator tIter; + for (tIter = tiles.begin(); tIter != tiles.end(); ++tIter) + { + Tile *tile = (*tIter); + + if (tile) + { + delete tile; + tile = NULL; + } + } + } + + void Tileset::Parse(const TiXmlNode *tilesetNode) + { + const TiXmlElement *tilesetElem = tilesetNode->ToElement(); + + // Read all the attributes into local variables. + tilesetElem->Attribute("firstgid", &first_gid); + tilesetElem->Attribute("tilewidth", &tile_width); + tilesetElem->Attribute("tileheight", &tile_height); + tilesetElem->Attribute("margin", &margin); + tilesetElem->Attribute("spacing", &spacing); + + name = tilesetElem->Attribute("name"); + + // Parse the image. + const TiXmlNode *imageNode = tilesetNode->FirstChild("image"); + + if (imageNode) + { + image = new Image(); + image->Parse(imageNode); + } + + // Iterate through all of the tile elements and parse each. + const TiXmlNode *tileNode = tilesetNode->FirstChild("tile"); + while (tileNode) + { + // Allocate a new tile and parse it. + Tile *tile = new Tile(); + tile->Parse(tileNode); + + // Add the tile to the collection. + tiles.push_back(tile); + + tileNode = tilesetNode->IterateChildren("tile", tileNode); + } + + // Parse the properties if any. + const TiXmlNode *propertiesNode = tilesetNode->FirstChild("properties"); + + if (propertiesNode) + { + properties.Parse(propertiesNode); + } + } + + const Tile *Tileset::GetTile(int index) const + { + for (unsigned int i = 0; i < tiles.size(); ++i) + { + if (tiles.at(i)->GetId() == index) + { + return tiles.at(i); + } + } + + return NULL; + } +}; diff --git a/engine/lib/TmxParser/TmxTileset.h b/engine/lib/TmxParser/TmxTileset.h new file mode 100644 index 000000000..9424f9155 --- /dev/null +++ b/engine/lib/TmxParser/TmxTileset.h @@ -0,0 +1,103 @@ +//----------------------------------------------------------------------------- +// TmxTileset.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include +#include + +#include "TmxPropertySet.h" + +class TiXmlNode; + +namespace Tmx +{ + class Image; + class Tile; + + //------------------------------------------------------------------------- + // A class used for storing information about each of the tilesets. + // A tileset is a collection of tiles, of whom each may contain properties. + // The tileset class itself does not have properties. + //------------------------------------------------------------------------- + class Tileset + { + public: + Tileset(); + ~Tileset(); + + // Parse a tileset element. + void Parse(const TiXmlNode *tilesetNode); + + // Returns the global id of the first tile. + int GetFirstGid() const { return first_gid; } + + // Returns the name of the tileset. + const std::string &GetName() const { return name; } + + // Get the width of a single tile. + int GetTileWidth() const { return tile_width; } + + // Get the height of a single tile. + int GetTileHeight() const { return tile_height; } + + // Get the margin of the tileset. + int GetMargin() const { return margin; } + + // Get the spacing of the tileset. + int GetSpacing() const { return spacing; } + + // Returns a variable containing information + // about the image of the tileset. + const Tmx::Image* GetImage() const { return image; } + + // Returns a a single tile of the set. + const Tmx::Tile *GetTile(int index) const; + + // Returns the whole tile collection. + const std::vector< Tmx::Tile *> &GetTiles() const { return tiles; } + + // Get a set of properties regarding the tile. + const Tmx::PropertySet &GetProperties() const { return properties; } + + private: + int first_gid; + + std::string name; + + int tile_width; + int tile_height; + int margin; + int spacing; + + Tmx::Image* image; + + std::vector< Tmx::Tile* > tiles; + + Tmx::PropertySet properties; + }; +}; diff --git a/engine/lib/TmxParser/TmxUtil.cpp b/engine/lib/TmxParser/TmxUtil.cpp new file mode 100644 index 000000000..01f520c92 --- /dev/null +++ b/engine/lib/TmxParser/TmxUtil.cpp @@ -0,0 +1,107 @@ +//----------------------------------------------------------------------------- +// TmxUtil.cpp +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#include +#include "../../lib/zlib/zlib.h" + +#include "TmxUtil.h" +#include "base64/base64.h" + +namespace Tmx { + std::string Util::DecodeBase64(const std::string &str) + { + return base64_decode(str); + } + + char *Util::DecompressGZIP(const char *data, int dataSize, int expectedSize) + { + int bufferSize = expectedSize; + int ret; + z_stream strm; + char *out = (char*)malloc(bufferSize); + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.next_in = (Bytef*)data; + strm.avail_in = dataSize; + strm.next_out = (Bytef*)out; + strm.avail_out = bufferSize; + + ret = inflateInit2(&strm, 15 + 32); + + if (ret != Z_OK) + { + free(out); + return NULL; + } + + do + { + ret = inflate(&strm, Z_SYNC_FLUSH); + + switch (ret) + { + case Z_NEED_DICT: + case Z_STREAM_ERROR: + ret = Z_DATA_ERROR; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&strm); + free(out); + return NULL; + } + + if (ret != Z_STREAM_END) + { + out = (char *) realloc(out, bufferSize * 2); + + if (!out) + { + inflateEnd(&strm); + free(out); + return NULL; + } + + strm.next_out = (Bytef *)(out + bufferSize); + strm.avail_out = bufferSize; + bufferSize *= 2; + } + } + while (ret != Z_STREAM_END); + + if (strm.avail_in != 0) + { + free(out); + return NULL; + } + + inflateEnd(&strm); + + return out; + } +}; diff --git a/engine/lib/TmxParser/TmxUtil.h b/engine/lib/TmxParser/TmxUtil.h new file mode 100644 index 000000000..0bb18fec0 --- /dev/null +++ b/engine/lib/TmxParser/TmxUtil.h @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// TmxUtil.h +// +// Copyright (c) 2010-2013, Tamir Atias +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TAMIR ATIAS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Tamir Atias +//----------------------------------------------------------------------------- +#pragma once + +#include + +namespace Tmx +{ + class Util + { + public: + // Decode a base-64 encoded string. + static std::string DecodeBase64(const std::string &str); + + // Decompress a gzip encoded byte array. + static char* DecompressGZIP(const char *data, int dataSize, int expectedSize); + }; +}; diff --git a/engine/lib/TmxParser/base64/base64.cpp b/engine/lib/TmxParser/base64/base64.cpp new file mode 100644 index 000000000..50006d4f3 --- /dev/null +++ b/engine/lib/TmxParser/base64/base64.cpp @@ -0,0 +1,123 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ + +#include "base64.h" +#include + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + +std::string base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} \ No newline at end of file diff --git a/engine/lib/TmxParser/base64/base64.h b/engine/lib/TmxParser/base64/base64.h new file mode 100644 index 000000000..2af9b82f5 --- /dev/null +++ b/engine/lib/TmxParser/base64/base64.h @@ -0,0 +1,35 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ +#ifndef TMXPARSER_BASE64_H_ +#define TMXPARSER_BASE64_H_ + +#include + +std::string base64_encode(unsigned char const* , unsigned int len); +std::string base64_decode(std::string const& s); + +#endif \ No newline at end of file diff --git a/engine/lib/TmxParser/tinyxml/tinystr.h b/engine/lib/TmxParser/tinyxml/tinystr.h new file mode 100644 index 000000000..3c2aa9d54 --- /dev/null +++ b/engine/lib/TmxParser/tinyxml/tinystr.h @@ -0,0 +1,319 @@ +/* +www.sourceforge.net/projects/tinyxml +Original file by Yves Berquin. + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +/* + * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005. + * + * - completely rewritten. compact, clean, and fast implementation. + * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems) + * - fixed reserve() to work as per specification. + * - fixed buggy compares operator==(), operator<(), and operator>() + * - fixed operator+=() to take a const ref argument, following spec. + * - added "copy" constructor with length, and most compare operators. + * - added swap(), clear(), size(), capacity(), operator+(). + */ + +#ifndef TIXML_USE_STL + +#ifndef TIXML_STRING_INCLUDED +#define TIXML_STRING_INCLUDED + +#include +#include + +/* The support for explicit isn't that universal, and it isn't really + required - it is used to check that the TiXmlString class isn't incorrectly + used. Be nice to old compilers and macro it here: +*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + #define TIXML_EXPLICIT explicit +#elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + #define TIXML_EXPLICIT explicit +#else + #define TIXML_EXPLICIT +#endif + + +/* + TiXmlString is an emulation of a subset of the std::string template. + Its purpose is to allow compiling TinyXML on compilers with no or poor STL support. + Only the member functions relevant to the TinyXML project have been implemented. + The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase + a string and there's no more room, we allocate a buffer twice as big as we need. +*/ +class TiXmlString +{ + public : + // The size type used + typedef size_t size_type; + + // Error value for find primitive + static const size_type npos; // = -1; + + + // TiXmlString empty constructor + TiXmlString () : rep_(&nullrep_) + { + } + + // TiXmlString copy constructor + TiXmlString ( const TiXmlString & copy) : rep_(0) + { + init(copy.length()); + memcpy(start(), copy.data(), length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0) + { + init( static_cast( strlen(copy) )); + memcpy(start(), copy, length()); + } + + // TiXmlString constructor, based on a string + TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0) + { + init(len); + memcpy(start(), str, len); + } + + // TiXmlString destructor + ~TiXmlString () + { + quit(); + } + + // = operator + TiXmlString& operator = (const char * copy) + { + return assign( copy, (size_type)strlen(copy)); + } + + // = operator + TiXmlString& operator = (const TiXmlString & copy) + { + return assign(copy.start(), copy.length()); + } + + + // += operator. Maps to append + TiXmlString& operator += (const char * suffix) + { + return append(suffix, static_cast( strlen(suffix) )); + } + + // += operator. Maps to append + TiXmlString& operator += (char single) + { + return append(&single, 1); + } + + // += operator. Maps to append + TiXmlString& operator += (const TiXmlString & suffix) + { + return append(suffix.data(), suffix.length()); + } + + + // Convert a TiXmlString into a null-terminated char * + const char * c_str () const { return rep_->str; } + + // Convert a TiXmlString into a char * (need not be null terminated). + const char * data () const { return rep_->str; } + + // Return the length of a TiXmlString + size_type length () const { return rep_->size; } + + // Alias for length() + size_type size () const { return rep_->size; } + + // Checks if a TiXmlString is empty + bool empty () const { return rep_->size == 0; } + + // Return capacity of string + size_type capacity () const { return rep_->capacity; } + + + // single char extraction + const char& at (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // [] operator + char& operator [] (size_type index) const + { + assert( index < length() ); + return rep_->str[ index ]; + } + + // find a char in a string. Return TiXmlString::npos if not found + size_type find (char lookup) const + { + return find(lookup, 0); + } + + // find a char in a string from an offset. Return TiXmlString::npos if not found + size_type find (char tofind, size_type offset) const + { + if (offset >= length()) return npos; + + for (const char* p = c_str() + offset; *p != '\0'; ++p) + { + if (*p == tofind) return static_cast< size_type >( p - c_str() ); + } + return npos; + } + + void clear () + { + //Lee: + //The original was just too strange, though correct: + // TiXmlString().swap(*this); + //Instead use the quit & re-init: + quit(); + init(0,0); + } + + /* Function to reserve a big amount of data when we know we'll need it. Be aware that this + function DOES NOT clear the content of the TiXmlString if any exists. + */ + void reserve (size_type cap); + + TiXmlString& assign (const char* str, size_type len); + + TiXmlString& append (const char* str, size_type len); + + void swap (TiXmlString& other) + { + Rep* r = rep_; + rep_ = other.rep_; + other.rep_ = r; + } + + private: + + void init(size_type sz) { init(sz, sz); } + void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; } + char* start() const { return rep_->str; } + char* finish() const { return rep_->str + rep_->size; } + + struct Rep + { + size_type size, capacity; + char str[1]; + }; + + void init(size_type sz, size_type cap) + { + if (cap) + { + // Lee: the original form: + // rep_ = static_cast(operator new(sizeof(Rep) + cap)); + // doesn't work in some cases of new being overloaded. Switching + // to the normal allocation, although use an 'int' for systems + // that are overly picky about structure alignment. + const size_type bytesNeeded = sizeof(Rep) + cap; + const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); + rep_ = reinterpret_cast( new int[ intsNeeded ] ); + + rep_->str[ rep_->size = sz ] = '\0'; + rep_->capacity = cap; + } + else + { + rep_ = &nullrep_; + } + } + + void quit() + { + if (rep_ != &nullrep_) + { + // The rep_ is really an array of ints. (see the allocator, above). + // Cast it back before delete, so the compiler won't incorrectly call destructors. + delete [] ( reinterpret_cast( rep_ ) ); + } + } + + Rep * rep_; + static Rep nullrep_; + +} ; + + +inline bool operator == (const TiXmlString & a, const TiXmlString & b) +{ + return ( a.length() == b.length() ) // optimization on some platforms + && ( strcmp(a.c_str(), b.c_str()) == 0 ); // actual compare +} +inline bool operator < (const TiXmlString & a, const TiXmlString & b) +{ + return strcmp(a.c_str(), b.c_str()) < 0; +} + +inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); } +inline bool operator > (const TiXmlString & a, const TiXmlString & b) { return b < a; } +inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); } +inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); } + +inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; } +inline bool operator == (const char* a, const TiXmlString & b) { return b == a; } +inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); } +inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); } + +TiXmlString operator + (const TiXmlString & a, const TiXmlString & b); +TiXmlString operator + (const TiXmlString & a, const char* b); +TiXmlString operator + (const char* a, const TiXmlString & b); + + +/* + TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString. + Only the operators that we need for TinyXML have been developped. +*/ +class TiXmlOutStream : public TiXmlString +{ +public : + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const TiXmlString & in) + { + *this += in; + return *this; + } + + // TiXmlOutStream << operator. + TiXmlOutStream & operator << (const char * in) + { + *this += in; + return *this; + } + +} ; + +#endif // TIXML_STRING_INCLUDED +#endif // TIXML_USE_STL diff --git a/engine/lib/TmxParser/tinyxml/tinyxml.h b/engine/lib/TmxParser/tinyxml/tinyxml.h new file mode 100644 index 000000000..afe8eb888 --- /dev/null +++ b/engine/lib/TmxParser/tinyxml/tinyxml.h @@ -0,0 +1,1802 @@ +/* +www.sourceforge.net/projects/tinyxml +Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + + +#ifndef TINYXML_INCLUDED +#define TINYXML_INCLUDED + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable : 4530 ) +#pragma warning( disable : 4786 ) +#endif + +#include +#include +#include +#include +#include + +// Help out windows: +#if defined( _DEBUG ) && !defined( DEBUG ) +#define DEBUG +#endif + +#ifdef TIXML_USE_STL + #include + #include + #include + #define TIXML_STRING std::string +#else + #include "tinystr.h" + #define TIXML_STRING TiXmlString +#endif + +// Deprecated library function hell. Compilers want to use the +// new safe versions. This probably doesn't fully address the problem, +// but it gets closer. There are too many compilers for me to fully +// test. If you get compilation troubles, undefine TIXML_SAFE +#define TIXML_SAFE + +#ifdef TIXML_SAFE + #if defined(_MSC_VER) && (_MSC_VER >= 1400 ) + // Microsoft visual studio, version 2005 and higher. + #define TIXML_SNPRINTF _snprintf_s + #define TIXML_SSCANF sscanf_s + #elif defined(_MSC_VER) && (_MSC_VER >= 1200 ) + // Microsoft visual studio, version 6 and higher. + //#pragma message( "Using _sn* functions." ) + #define TIXML_SNPRINTF _snprintf + #define TIXML_SSCANF sscanf + #elif defined(__GNUC__) && (__GNUC__ >= 3 ) + // GCC version 3 and higher.s + //#warning( "Using sn* functions." ) + #define TIXML_SNPRINTF snprintf + #define TIXML_SSCANF sscanf + #else + #define TIXML_SNPRINTF snprintf + #define TIXML_SSCANF sscanf + #endif +#endif + +class TiXmlDocument; +class TiXmlElement; +class TiXmlComment; +class TiXmlUnknown; +class TiXmlAttribute; +class TiXmlText; +class TiXmlDeclaration; +class TiXmlParsingData; + +const int TIXML_MAJOR_VERSION = 2; +const int TIXML_MINOR_VERSION = 6; +const int TIXML_PATCH_VERSION = 1; + +/* Internal structure for tracking location of items + in the XML file. +*/ +struct TiXmlCursor +{ + TiXmlCursor() { Clear(); } + void Clear() { row = col = -1; } + + int row; // 0 based. + int col; // 0 based. +}; + + +/** + Implements the interface to the "Visitor pattern" (see the Accept() method.) + If you call the Accept() method, it requires being passed a TiXmlVisitor + class to handle callbacks. For nodes that contain other nodes (Document, Element) + you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves + are simply called with Visit(). + + If you return 'true' from a Visit method, recursive parsing will continue. If you return + false, no children of this node or its sibilings will be Visited. + + All flavors of Visit methods have a default implementation that returns 'true' (continue + visiting). You need to only override methods that are interesting to you. + + Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting. + + You should never change the document from a callback. + + @sa TiXmlNode::Accept() +*/ +class TiXmlVisitor +{ +public: + virtual ~TiXmlVisitor() {} + + /// Visit a document. + virtual bool VisitEnter( const TiXmlDocument& /*doc*/ ) { return true; } + /// Visit a document. + virtual bool VisitExit( const TiXmlDocument& /*doc*/ ) { return true; } + + /// Visit an element. + virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ ) { return true; } + /// Visit an element. + virtual bool VisitExit( const TiXmlElement& /*element*/ ) { return true; } + + /// Visit a declaration + virtual bool Visit( const TiXmlDeclaration& /*declaration*/ ) { return true; } + /// Visit a text node + virtual bool Visit( const TiXmlText& /*text*/ ) { return true; } + /// Visit a comment node + virtual bool Visit( const TiXmlComment& /*comment*/ ) { return true; } + /// Visit an unknow node + virtual bool Visit( const TiXmlUnknown& /*unknown*/ ) { return true; } +}; + +// Only used by Attribute::Query functions +enum +{ + TIXML_SUCCESS, + TIXML_NO_ATTRIBUTE, + TIXML_WRONG_TYPE +}; + + +// Used by the parsing routines. +enum TiXmlEncoding +{ + TIXML_ENCODING_UNKNOWN, + TIXML_ENCODING_UTF8, + TIXML_ENCODING_LEGACY +}; + +const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN; + +/** TiXmlBase is a base class for every class in TinyXml. + It does little except to establish that TinyXml classes + can be printed and provide some utility functions. + + In XML, the document and elements can contain + other elements and other types of nodes. + + @verbatim + A Document can contain: Element (container or leaf) + Comment (leaf) + Unknown (leaf) + Declaration( leaf ) + + An Element can contain: Element (container or leaf) + Text (leaf) + Attributes (not on tree) + Comment (leaf) + Unknown (leaf) + + A Decleration contains: Attributes (not on tree) + @endverbatim +*/ +class TiXmlBase +{ + friend class TiXmlNode; + friend class TiXmlElement; + friend class TiXmlDocument; + +public: + TiXmlBase() : userData(0) {} + virtual ~TiXmlBase() {} + + /** All TinyXml classes can print themselves to a filestream + or the string class (TiXmlString in non-STL mode, std::string + in STL mode.) Either or both cfile and str can be null. + + This is a formatted print, and will insert + tabs and newlines. + + (For an unformatted stream, use the << operator.) + */ + virtual void Print( FILE* cfile, int depth ) const = 0; + + /** The world does not agree on whether white space should be kept or + not. In order to make everyone happy, these global, static functions + are provided to set whether or not TinyXml will condense all white space + into a single space or not. The default is to condense. Note changing this + value is not thread safe. + */ + static void SetCondenseWhiteSpace( bool condense ) { condenseWhiteSpace = condense; } + + /// Return the current white space setting. + static bool IsWhiteSpaceCondensed() { return condenseWhiteSpace; } + + /** Return the position, in the original source file, of this node or attribute. + The row and column are 1-based. (That is the first row and first column is + 1,1). If the returns values are 0 or less, then the parser does not have + a row and column value. + + Generally, the row and column value will be set when the TiXmlDocument::Load(), + TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set + when the DOM was created from operator>>. + + The values reflect the initial load. Once the DOM is modified programmatically + (by adding or changing nodes and attributes) the new values will NOT update to + reflect changes in the document. + + There is a minor performance cost to computing the row and column. Computation + can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value. + + @sa TiXmlDocument::SetTabSize() + */ + int Row() const { return location.row + 1; } + int Column() const { return location.col + 1; } ///< See Row() + + void SetUserData( void* user ) { userData = user; } ///< Set a pointer to arbitrary user data. + void* GetUserData() { return userData; } ///< Get a pointer to arbitrary user data. + const void* GetUserData() const { return userData; } ///< Get a pointer to arbitrary user data. + + // Table that returs, for a given lead byte, the total number of bytes + // in the UTF-8 sequence. + static const int utf8ByteTable[256]; + + virtual const char* Parse( const char* p, + TiXmlParsingData* data, + TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0; + + /** Expands entities in a string. Note this should not contian the tag's '<', '>', etc, + or they will be transformed into entities! + */ + static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out ); + + enum + { + TIXML_NO_ERROR = 0, + TIXML_ERROR, + TIXML_ERROR_OPENING_FILE, + TIXML_ERROR_PARSING_ELEMENT, + TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, + TIXML_ERROR_READING_ELEMENT_VALUE, + TIXML_ERROR_READING_ATTRIBUTES, + TIXML_ERROR_PARSING_EMPTY, + TIXML_ERROR_READING_END_TAG, + TIXML_ERROR_PARSING_UNKNOWN, + TIXML_ERROR_PARSING_COMMENT, + TIXML_ERROR_PARSING_DECLARATION, + TIXML_ERROR_DOCUMENT_EMPTY, + TIXML_ERROR_EMBEDDED_NULL, + TIXML_ERROR_PARSING_CDATA, + TIXML_ERROR_DOCUMENT_TOP_ONLY, + + TIXML_ERROR_STRING_COUNT + }; + +protected: + + static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding ); + + inline static bool IsWhiteSpace( char c ) + { + return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); + } + inline static bool IsWhiteSpace( int c ) + { + if ( c < 256 ) + return IsWhiteSpace( (char) c ); + return false; // Again, only truly correct for English/Latin...but usually works. + } + + #ifdef TIXML_USE_STL + static bool StreamWhiteSpace( std::istream * in, TIXML_STRING * tag ); + static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag ); + #endif + + /* Reads an XML name into the string provided. Returns + a pointer just past the last character of the name, + or 0 if the function has an error. + */ + static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding ); + + /* Reads text. Returns a pointer past the given end tag. + Wickedly complex options, but it keeps the (sensitive) code in one place. + */ + static const char* ReadText( const char* in, // where to start + TIXML_STRING* text, // the string read + bool ignoreWhiteSpace, // whether to keep the white space + const char* endTag, // what ends this text + bool ignoreCase, // whether to ignore case in the end tag + TiXmlEncoding encoding ); // the current encoding + + // If an entity has been found, transform it into a character. + static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding ); + + // Get a character, while interpreting entities. + // The length can be from 0 to 4 bytes. + inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding ) + { + assert( p ); + if ( encoding == TIXML_ENCODING_UTF8 ) + { + *length = utf8ByteTable[ *((const unsigned char*)p) ]; + assert( *length >= 0 && *length < 5 ); + } + else + { + *length = 1; + } + + if ( *length == 1 ) + { + if ( *p == '&' ) + return GetEntity( p, _value, length, encoding ); + *_value = *p; + return p+1; + } + else if ( *length ) + { + //strncpy( _value, p, *length ); // lots of compilers don't like this function (unsafe), + // and the null terminator isn't needed + for( int i=0; p[i] && i<*length; ++i ) { + _value[i] = p[i]; + } + return p + (*length); + } + else + { + // Not valid text. + return 0; + } + } + + // Return true if the next characters in the stream are any of the endTag sequences. + // Ignore case only works for english, and should only be relied on when comparing + // to English words: StringEqual( p, "version", true ) is fine. + static bool StringEqual( const char* p, + const char* endTag, + bool ignoreCase, + TiXmlEncoding encoding ); + + static const char* errorString[ TIXML_ERROR_STRING_COUNT ]; + + TiXmlCursor location; + + /// Field containing a generic user pointer + void* userData; + + // None of these methods are reliable for any language except English. + // Good for approximation, not great for accuracy. + static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding ); + static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding ); + inline static int ToLower( int v, TiXmlEncoding encoding ) + { + if ( encoding == TIXML_ENCODING_UTF8 ) + { + if ( v < 128 ) return tolower( v ); + return v; + } + else + { + return tolower( v ); + } + } + static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + +private: + TiXmlBase( const TiXmlBase& ); // not implemented. + void operator=( const TiXmlBase& base ); // not allowed. + + struct Entity + { + const char* str; + unsigned int strLength; + char chr; + }; + enum + { + NUM_ENTITY = 5, + MAX_ENTITY_LENGTH = 6 + + }; + static Entity entity[ NUM_ENTITY ]; + static bool condenseWhiteSpace; +}; + + +/** The parent class for everything in the Document Object Model. + (Except for attributes). + Nodes have siblings, a parent, and children. A node can be + in a document, or stand on its own. The type of a TiXmlNode + can be queried, and it can be cast to its more defined type. +*/ +class TiXmlNode : public TiXmlBase +{ + friend class TiXmlDocument; + friend class TiXmlElement; + +public: + #ifdef TIXML_USE_STL + + /** An input stream operator, for every class. Tolerant of newlines and + formatting, but doesn't expect them. + */ + friend std::istream& operator >> (std::istream& in, TiXmlNode& base); + + /** An output stream operator, for every class. Note that this outputs + without any newlines or formatting, as opposed to Print(), which + includes tabs and new lines. + + The operator<< and operator>> are not completely symmetric. Writing + a node to a stream is very well defined. You'll get a nice stream + of output, without any extra whitespace or newlines. + + But reading is not as well defined. (As it always is.) If you create + a TiXmlElement (for example) and read that from an input stream, + the text needs to define an element or junk will result. This is + true of all input streams, but it's worth keeping in mind. + + A TiXmlDocument will read nodes until it reads a root element, and + all the children of that root element. + */ + friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base); + + /// Appends the XML node or attribute to a std::string. + friend std::string& operator<< (std::string& out, const TiXmlNode& base ); + + #endif + + /** The types of XML nodes supported by TinyXml. (All the + unsupported types are picked up by UNKNOWN.) + */ + enum NodeType + { + TINYXML_DOCUMENT, + TINYXML_ELEMENT, + TINYXML_COMMENT, + TINYXML_UNKNOWN, + TINYXML_TEXT, + TINYXML_DECLARATION, + TINYXML_TYPECOUNT + }; + + virtual ~TiXmlNode(); + + /** The meaning of 'value' changes for the specific type of + TiXmlNode. + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + + The subclasses will wrap this function. + */ + const char *Value() const { return value.c_str (); } + + #ifdef TIXML_USE_STL + /** Return Value() as a std::string. If you only use STL, + this is more efficient than calling Value(). + Only available in STL mode. + */ + const std::string& ValueStr() const { return value; } + #endif + + const TIXML_STRING& ValueTStr() const { return value; } + + /** Changes the value of the node. Defined as: + @verbatim + Document: filename of the xml file + Element: name of the element + Comment: the comment text + Unknown: the tag contents + Text: the text string + @endverbatim + */ + void SetValue(const char * _value) { value = _value;} + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Delete all the children of this node. Does not affect 'this'. + void Clear(); + + /// One step up the DOM. + TiXmlNode* Parent() { return parent; } + const TiXmlNode* Parent() const { return parent; } + + const TiXmlNode* FirstChild() const { return firstChild; } ///< The first child of this node. Will be null if there are no children. + TiXmlNode* FirstChild() { return firstChild; } + const TiXmlNode* FirstChild( const char * value ) const; ///< The first child of this node with the matching 'value'. Will be null if none found. + /// The first child of this node with the matching 'value'. Will be null if none found. + TiXmlNode* FirstChild( const char * _value ) { + // Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe) + // call the method, cast the return back to non-const. + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value )); + } + const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children. + TiXmlNode* LastChild() { return lastChild; } + + const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children. + TiXmlNode* LastChild( const char * _value ) { + return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value )); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* FirstChild( const std::string& _value ) const { return FirstChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* FirstChild( const std::string& _value ) { return FirstChild (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* LastChild( const std::string& _value ) const { return LastChild (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* LastChild( const std::string& _value ) { return LastChild (_value.c_str ()); } ///< STL std::string form. + #endif + + /** An alternate way to walk the children of a node. + One way to iterate over nodes is: + @verbatim + for( child = parent->FirstChild(); child; child = child->NextSibling() ) + @endverbatim + + IterateChildren does the same thing with the syntax: + @verbatim + child = 0; + while( child = parent->IterateChildren( child ) ) + @endverbatim + + IterateChildren takes the previous child as input and finds + the next one. If the previous child is null, it returns the + first. IterateChildren will return null when done. + */ + const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) ); + } + + /// This flavor of IterateChildren searches for children with a particular 'value' + const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const; + TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) { return IterateChildren (_value.c_str (), previous); } ///< STL std::string form. + #endif + + /** Add a new node related to this. Adds a child past the LastChild. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertEndChild( const TiXmlNode& addThis ); + + + /** Add a new node related to this. Adds a child past the LastChild. + + NOTE: the node to be added is passed by pointer, and will be + henceforth owned (and deleted) by tinyXml. This method is efficient + and avoids an extra copy, but should be used with care as it + uses a different memory model than the other insert functions. + + @sa InsertEndChild + */ + TiXmlNode* LinkEndChild( TiXmlNode* addThis ); + + /** Add a new node related to this. Adds a child before the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis ); + + /** Add a new node related to this. Adds a child after the specified child. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis ); + + /** Replace a child of this node. + Returns a pointer to the new object or NULL if an error occured. + */ + TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis ); + + /// Delete a child of this node. + bool RemoveChild( TiXmlNode* removeThis ); + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling() const { return prev; } + TiXmlNode* PreviousSibling() { return prev; } + + /// Navigate to a sibling node. + const TiXmlNode* PreviousSibling( const char * ) const; + TiXmlNode* PreviousSibling( const char *_prev ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlNode* PreviousSibling( const std::string& _value ) const { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* PreviousSibling( const std::string& _value ) { return PreviousSibling (_value.c_str ()); } ///< STL std::string form. + const TiXmlNode* NextSibling( const std::string& _value) const { return NextSibling (_value.c_str ()); } ///< STL std::string form. + TiXmlNode* NextSibling( const std::string& _value) { return NextSibling (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Navigate to a sibling node. + const TiXmlNode* NextSibling() const { return next; } + TiXmlNode* NextSibling() { return next; } + + /// Navigate to a sibling node with the given 'value'. + const TiXmlNode* NextSibling( const char * ) const; + TiXmlNode* NextSibling( const char* _next ) { + return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement() const; + TiXmlElement* NextSiblingElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() ); + } + + /** Convenience function to get through elements. + Calls NextSibling and ToElement. Will skip all non-Element + nodes. Returns 0 if there is not another element. + */ + const TiXmlElement* NextSiblingElement( const char * ) const; + TiXmlElement* NextSiblingElement( const char *_next ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* NextSiblingElement( const std::string& _value) const { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* NextSiblingElement( const std::string& _value) { return NextSiblingElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement() const; + TiXmlElement* FirstChildElement() { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() ); + } + + /// Convenience function to get through elements. + const TiXmlElement* FirstChildElement( const char * _value ) const; + TiXmlElement* FirstChildElement( const char * _value ) { + return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) ); + } + + #ifdef TIXML_USE_STL + const TiXmlElement* FirstChildElement( const std::string& _value ) const { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + TiXmlElement* FirstChildElement( const std::string& _value ) { return FirstChildElement (_value.c_str ()); } ///< STL std::string form. + #endif + + /** Query the type (as an enumerated value, above) of this node. + The possible types are: DOCUMENT, ELEMENT, COMMENT, + UNKNOWN, TEXT, and DECLARATION. + */ + int Type() const { return type; } + + /** Return a pointer to the Document this node lives in. + Returns null if not in a document. + */ + const TiXmlDocument* GetDocument() const; + TiXmlDocument* GetDocument() { + return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() ); + } + + /// Returns true if this node has no children. + bool NoChildren() const { return !firstChild; } + + virtual const TiXmlDocument* ToDocument() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlElement* ToElement() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlComment* ToComment() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlUnknown* ToUnknown() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlText* ToText() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + virtual TiXmlDocument* ToDocument() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlElement* ToElement() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlComment* ToComment() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlText* ToText() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type. + + /** Create an exact duplicate of this node and return it. The memory must be deleted + by the caller. + */ + virtual TiXmlNode* Clone() const = 0; + + /** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the + XML tree will be conditionally visited and the host will be called back + via the TiXmlVisitor interface. + + This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse + the XML for the callbacks, so the performance of TinyXML is unchanged by using this + interface versus any other.) + + The interface has been based on ideas from: + + - http://www.saxproject.org/ + - http://c2.com/cgi/wiki?HierarchicalVisitorPattern + + Which are both good references for "visiting". + + An example of using Accept(): + @verbatim + TiXmlPrinter printer; + tinyxmlDoc.Accept( &printer ); + const char* xmlcstr = printer.CStr(); + @endverbatim + */ + virtual bool Accept( TiXmlVisitor* visitor ) const = 0; + +protected: + TiXmlNode( NodeType _type ); + + // Copy to the allocated object. Shared functionality between Clone, Copy constructor, + // and the assignment operator. + void CopyTo( TiXmlNode* target ) const; + + #ifdef TIXML_USE_STL + // The real work of the input operator. + virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0; + #endif + + // Figure out what is at *p, and parse it. Returns null if it is not an xml node. + TiXmlNode* Identify( const char* start, TiXmlEncoding encoding ); + + TiXmlNode* parent; + NodeType type; + + TiXmlNode* firstChild; + TiXmlNode* lastChild; + + TIXML_STRING value; + + TiXmlNode* prev; + TiXmlNode* next; + +private: + TiXmlNode( const TiXmlNode& ); // not implemented. + void operator=( const TiXmlNode& base ); // not allowed. +}; + + +/** An attribute is a name-value pair. Elements have an arbitrary + number of attributes, each with a unique name. + + @note The attributes are not TiXmlNodes, since they are not + part of the tinyXML document object model. There are other + suggested ways to look at this problem. +*/ +class TiXmlAttribute : public TiXmlBase +{ + friend class TiXmlAttributeSet; + +public: + /// Construct an empty attribute. + TiXmlAttribute() : TiXmlBase() + { + document = 0; + prev = next = 0; + } + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlAttribute( const std::string& _name, const std::string& _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + #endif + + /// Construct an attribute with a name and value. + TiXmlAttribute( const char * _name, const char * _value ) + { + name = _name; + value = _value; + document = 0; + prev = next = 0; + } + + const char* Name() const { return name.c_str(); } ///< Return the name of this attribute. + const char* Value() const { return value.c_str(); } ///< Return the value of this attribute. + #ifdef TIXML_USE_STL + const std::string& ValueStr() const { return value; } ///< Return the value of this attribute. + #endif + int IntValue() const; ///< Return the value of this attribute, converted to an integer. + double DoubleValue() const; ///< Return the value of this attribute, converted to a double. + + // Get the tinyxml string representation + const TIXML_STRING& NameTStr() const { return name; } + + /** QueryIntValue examines the value string. It is an alternative to the + IntValue() method with richer error checking. + If the value is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. + + A specialized but useful call. Note that for success it returns 0, + which is the opposite of almost all other TinyXml calls. + */ + int QueryIntValue( int* _value ) const; + /// QueryDoubleValue examines the value string. See QueryIntValue(). + int QueryDoubleValue( double* _value ) const; + + void SetName( const char* _name ) { name = _name; } ///< Set the name of this attribute. + void SetValue( const char* _value ) { value = _value; } ///< Set the value. + + void SetIntValue( int _value ); ///< Set the value from an integer. + void SetDoubleValue( double _value ); ///< Set the value from a double. + + #ifdef TIXML_USE_STL + /// STL std::string form. + void SetName( const std::string& _name ) { name = _name; } + /// STL std::string form. + void SetValue( const std::string& _value ) { value = _value; } + #endif + + /// Get the next sibling attribute in the DOM. Returns null at end. + const TiXmlAttribute* Next() const; + TiXmlAttribute* Next() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() ); + } + + /// Get the previous sibling attribute in the DOM. Returns null at beginning. + const TiXmlAttribute* Previous() const; + TiXmlAttribute* Previous() { + return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() ); + } + + bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; } + bool operator<( const TiXmlAttribute& rhs ) const { return name < rhs.name; } + bool operator>( const TiXmlAttribute& rhs ) const { return name > rhs.name; } + + /* Attribute parsing starts: first letter of the name + returns: the next char after the value end quote + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + // Prints this Attribute to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + + // [internal use] + // Set the document pointer so the attribute can report errors. + void SetDocument( TiXmlDocument* doc ) { document = doc; } + +private: + TiXmlAttribute( const TiXmlAttribute& ); // not implemented. + void operator=( const TiXmlAttribute& base ); // not allowed. + + TiXmlDocument* document; // A pointer back to a document, for error reporting. + TIXML_STRING name; + TIXML_STRING value; + TiXmlAttribute* prev; + TiXmlAttribute* next; +}; + + +/* A class used to manage a group of attributes. + It is only used internally, both by the ELEMENT and the DECLARATION. + + The set can be changed transparent to the Element and Declaration + classes that use it, but NOT transparent to the Attribute + which has to implement a next() and previous() method. Which makes + it a bit problematic and prevents the use of STL. + + This version is implemented with circular lists because: + - I like circular lists + - it demonstrates some independence from the (typical) doubly linked list. +*/ +class TiXmlAttributeSet +{ +public: + TiXmlAttributeSet(); + ~TiXmlAttributeSet(); + + void Add( TiXmlAttribute* attribute ); + void Remove( TiXmlAttribute* attribute ); + + const TiXmlAttribute* First() const { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + TiXmlAttribute* First() { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; } + const TiXmlAttribute* Last() const { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + TiXmlAttribute* Last() { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; } + + TiXmlAttribute* Find( const char* _name ) const; + TiXmlAttribute* FindOrCreate( const char* _name ); + +# ifdef TIXML_USE_STL + TiXmlAttribute* Find( const std::string& _name ) const; + TiXmlAttribute* FindOrCreate( const std::string& _name ); +# endif + + +private: + //*ME: Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element), + //*ME: this class must be also use a hidden/disabled copy-constructor !!! + TiXmlAttributeSet( const TiXmlAttributeSet& ); // not allowed + void operator=( const TiXmlAttributeSet& ); // not allowed (as TiXmlAttribute) + + TiXmlAttribute sentinel; +}; + + +/** The element is a container class. It has a value, the element name, + and can contain other elements, text, comments, and unknowns. + Elements also contain an arbitrary number of attributes. +*/ +class TiXmlElement : public TiXmlNode +{ +public: + /// Construct an element. + TiXmlElement (const char * in_value); + + #ifdef TIXML_USE_STL + /// std::string constructor. + TiXmlElement( const std::string& _value ); + #endif + + TiXmlElement( const TiXmlElement& ); + + void operator=( const TiXmlElement& base ); + + virtual ~TiXmlElement(); + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + */ + const char* Attribute( const char* name ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an integer, + the integer value will be put in the return 'i', if 'i' + is non-null. + */ + const char* Attribute( const char* name, int* i ) const; + + /** Given an attribute name, Attribute() returns the value + for the attribute of that name, or null if none exists. + If the attribute exists and can be converted to an double, + the double value will be put in the return 'd', if 'd' + is non-null. + */ + const char* Attribute( const char* name, double* d ) const; + + /** QueryIntAttribute examines the attribute - it is an alternative to the + Attribute() method with richer error checking. + If the attribute is an integer, it is stored in 'value' and + the call returns TIXML_SUCCESS. If it is not + an integer, it returns TIXML_WRONG_TYPE. If the attribute + does not exist, then TIXML_NO_ATTRIBUTE is returned. + */ + int QueryIntAttribute( const char* name, int* _value ) const; + /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute(). + int QueryDoubleAttribute( const char* name, double* _value ) const; + /// QueryFloatAttribute examines the attribute - see QueryIntAttribute(). + int QueryFloatAttribute( const char* name, float* _value ) const { + double d; + int result = QueryDoubleAttribute( name, &d ); + if ( result == TIXML_SUCCESS ) { + *_value = (float)d; + } + return result; + } + + #ifdef TIXML_USE_STL + /// QueryStringAttribute examines the attribute - see QueryIntAttribute(). + int QueryStringAttribute( const char* name, std::string* _value ) const { + const char* cstr = Attribute( name ); + if ( cstr ) { + *_value = std::string( cstr ); + return TIXML_SUCCESS; + } + return TIXML_NO_ATTRIBUTE; + } + + /** Template form of the attribute query which will try to read the + attribute into the specified type. Very easy, very powerful, but + be careful to make sure to call this with the correct type. + + NOTE: This method doesn't work correctly for 'string' types that contain spaces. + + @return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE + */ + template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + + std::stringstream sstream( node->ValueStr() ); + sstream >> *outValue; + if ( !sstream.fail() ) + return TIXML_SUCCESS; + return TIXML_WRONG_TYPE; + } + + int QueryValueAttribute( const std::string& name, std::string* outValue ) const + { + const TiXmlAttribute* node = attributeSet.Find( name ); + if ( !node ) + return TIXML_NO_ATTRIBUTE; + *outValue = node->ValueStr(); + return TIXML_SUCCESS; + } + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char* name, const char * _value ); + + #ifdef TIXML_USE_STL + const std::string* Attribute( const std::string& name ) const; + const std::string* Attribute( const std::string& name, int* i ) const; + const std::string* Attribute( const std::string& name, double* d ) const; + int QueryIntAttribute( const std::string& name, int* _value ) const; + int QueryDoubleAttribute( const std::string& name, double* _value ) const; + + /// STL std::string form. + void SetAttribute( const std::string& name, const std::string& _value ); + ///< STL std::string form. + void SetAttribute( const std::string& name, int _value ); + ///< STL std::string form. + void SetDoubleAttribute( const std::string& name, double value ); + #endif + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetAttribute( const char * name, int value ); + + /** Sets an attribute of name to a given value. The attribute + will be created if it does not exist, or changed if it does. + */ + void SetDoubleAttribute( const char * name, double value ); + + /** Deletes an attribute with the given name. + */ + void RemoveAttribute( const char * name ); + #ifdef TIXML_USE_STL + void RemoveAttribute( const std::string& name ) { RemoveAttribute (name.c_str ()); } ///< STL std::string form. + #endif + + const TiXmlAttribute* FirstAttribute() const { return attributeSet.First(); } ///< Access the first attribute in this element. + TiXmlAttribute* FirstAttribute() { return attributeSet.First(); } + const TiXmlAttribute* LastAttribute() const { return attributeSet.Last(); } ///< Access the last attribute in this element. + TiXmlAttribute* LastAttribute() { return attributeSet.Last(); } + + /** Convenience function for easy access to the text inside an element. Although easy + and concise, GetText() is limited compared to getting the TiXmlText child + and accessing it directly. + + If the first child of 'this' is a TiXmlText, the GetText() + returns the character string of the Text node, else null is returned. + + This is a convenient method for getting the text of simple contained text: + @verbatim + This is text + const char* str = fooElement->GetText(); + @endverbatim + + 'str' will be a pointer to "This is text". + + Note that this function can be misleading. If the element foo was created from + this XML: + @verbatim + This is text + @endverbatim + + then the value of str would be null. The first child node isn't a text node, it is + another element. From this XML: + @verbatim + This is text + @endverbatim + GetText() will return "This is ". + + WARNING: GetText() accesses a child node - don't become confused with the + similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are + safe type casts on the referenced node. + */ + const char* GetText() const; + + /// Creates a new Element and returns it - the returned element is a copy. + virtual TiXmlNode* Clone() const; + // Print the Element to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: next char past '<' + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + + void CopyTo( TiXmlElement* target ) const; + void ClearThis(); // like clear, but initializes 'this' object as well + + // Used to be public [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + /* [internal use] + Reads the "value" of the element -- another element, or text. + This should terminate with the current end tag. + */ + const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + +private: + TiXmlAttributeSet attributeSet; +}; + + +/** An XML comment. +*/ +class TiXmlComment : public TiXmlNode +{ +public: + /// Constructs an empty comment. + TiXmlComment() : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) {} + /// Construct a comment from text. + TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT ) { + SetValue( _value ); + } + TiXmlComment( const TiXmlComment& ); + void operator=( const TiXmlComment& base ); + + virtual ~TiXmlComment() {} + + /// Returns a copy of this Comment. + virtual TiXmlNode* Clone() const; + // Write this Comment to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /* Attribtue parsing starts: at the ! of the !-- + returns: next char past '>' + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlComment* target ) const; + + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif +// virtual void StreamOut( TIXML_OSTREAM * out ) const; + +private: + +}; + + +/** XML text. A text node can have 2 ways to output the next. "normal" output + and CDATA. It will default to the mode it was parsed from the XML file and + you generally want to leave it alone, but you can change the output mode with + SetCDATA() and query it with CDATA(). +*/ +class TiXmlText : public TiXmlNode +{ + friend class TiXmlElement; +public: + /** Constructor for text element. By default, it is treated as + normal, encoded text. If you want it be output as a CDATA text + element, set the parameter _cdata to 'true' + */ + TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) + { + SetValue( initValue ); + cdata = false; + } + virtual ~TiXmlText() {} + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TINYXML_TEXT) + { + SetValue( initValue ); + cdata = false; + } + #endif + + TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TINYXML_TEXT ) { copy.CopyTo( this ); } + void operator=( const TiXmlText& base ) { base.CopyTo( this ); } + + // Write this text object to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + /// Queries whether this represents text using a CDATA section. + bool CDATA() const { return cdata; } + /// Turns on or off a CDATA representation of text. + void SetCDATA( bool _cdata ) { cdata = _cdata; } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + /// [internal use] Creates a new Element and returns it. + virtual TiXmlNode* Clone() const; + void CopyTo( TiXmlText* target ) const; + + bool Blank() const; // returns true if all white space and new lines + // [internal use] + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + bool cdata; // true if this should be input and output as a CDATA style text element +}; + + +/** In correct XML the declaration is the first entry in the file. + @verbatim + + @endverbatim + + TinyXml will happily read or write files without a declaration, + however. There are 3 possible attributes to the declaration: + version, encoding, and standalone. + + Note: In this version of the code, the attributes are + handled as special cases, not generic attributes, simply + because there can only be at most 3 and they are always the same. +*/ +class TiXmlDeclaration : public TiXmlNode +{ +public: + /// Construct an empty declaration. + TiXmlDeclaration() : TiXmlNode( TiXmlNode::TINYXML_DECLARATION ) {} + +#ifdef TIXML_USE_STL + /// Constructor. + TiXmlDeclaration( const std::string& _version, + const std::string& _encoding, + const std::string& _standalone ); +#endif + + /// Construct. + TiXmlDeclaration( const char* _version, + const char* _encoding, + const char* _standalone ); + + TiXmlDeclaration( const TiXmlDeclaration& copy ); + void operator=( const TiXmlDeclaration& copy ); + + virtual ~TiXmlDeclaration() {} + + /// Version. Will return an empty string if none was found. + const char *Version() const { return version.c_str (); } + /// Encoding. Will return an empty string if none was found. + const char *Encoding() const { return encoding.c_str (); } + /// Is this a standalone document? + const char *Standalone() const { return standalone.c_str (); } + + /// Creates a copy of this Declaration and returns it. + virtual TiXmlNode* Clone() const; + // Print this declaration to a FILE stream. + virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const; + virtual void Print( FILE* cfile, int depth ) const { + Print( cfile, depth, 0 ); + } + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* visitor ) const; + +protected: + void CopyTo( TiXmlDeclaration* target ) const; + // used to be public + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + + TIXML_STRING version; + TIXML_STRING encoding; + TIXML_STRING standalone; +}; + + +/** Any tag that tinyXml doesn't recognize is saved as an + unknown. It is a tag of text, but should not be modified. + It will be written back to the XML, unchanged, when the file + is saved. + + DTD tags get thrown into TiXmlUnknowns. +*/ +class TiXmlUnknown : public TiXmlNode +{ +public: + TiXmlUnknown() : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) {} + virtual ~TiXmlUnknown() {} + + TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::TINYXML_UNKNOWN ) { copy.CopyTo( this ); } + void operator=( const TiXmlUnknown& copy ) { copy.CopyTo( this ); } + + /// Creates a copy of this Unknown and returns it. + virtual TiXmlNode* Clone() const; + // Print this Unknown to a FILE stream. + virtual void Print( FILE* cfile, int depth ) const; + + virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding ); + + virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected: + void CopyTo( TiXmlUnknown* target ) const; + + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + +}; + + +/** Always the top level node. A document binds together all the + XML pieces. It can be saved, loaded, and printed to the screen. + The 'value' of a document node is the xml file name. +*/ +class TiXmlDocument : public TiXmlNode +{ +public: + /// Create an empty document, that has no name. + TiXmlDocument(); + /// Create a document with a name. The name of the document is also the filename of the xml. + TiXmlDocument( const char * documentName ); + + #ifdef TIXML_USE_STL + /// Constructor. + TiXmlDocument( const std::string& documentName ); + #endif + + TiXmlDocument( const TiXmlDocument& copy ); + void operator=( const TiXmlDocument& copy ); + + virtual ~TiXmlDocument() {} + + /** Load a file using the current document value. + Returns true if successful. Will delete any existing + document data before loading. + */ + bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the current document value. Returns true if successful. + bool SaveFile() const; + /// Load a file using the given filename. Returns true if successful. + bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given filename. Returns true if successful. + bool SaveFile( const char * filename ) const; + /** Load a file using the given FILE*. Returns true if successful. Note that this method + doesn't stream - the entire object pointed at by the FILE* + will be interpreted as an XML file. TinyXML doesn't stream in XML from the current + file location. Streaming may be added in the future. + */ + bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + /// Save a file using the given FILE*. Returns true if successful. + bool SaveFile( FILE* ) const; + + #ifdef TIXML_USE_STL + bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ) ///< STL std::string version. + { + return LoadFile( filename.c_str(), encoding ); + } + bool SaveFile( const std::string& filename ) const ///< STL std::string version. + { + return SaveFile( filename.c_str() ); + } + #endif + + /** Parse the given null terminated block of xml data. Passing in an encoding to this + method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml + to use that encoding, regardless of what TinyXml might otherwise try to detect. + */ + virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING ); + + /** Get the root element -- the only top level element -- of the document. + In well formed XML, there should only be one. TinyXml is tolerant of + multiple elements at the document level. + */ + const TiXmlElement* RootElement() const { return FirstChildElement(); } + TiXmlElement* RootElement() { return FirstChildElement(); } + + /** If an error occurs, Error will be set to true. Also, + - The ErrorId() will contain the integer identifier of the error (not generally useful) + - The ErrorDesc() method will return the name of the error. (very useful) + - The ErrorRow() and ErrorCol() will return the location of the error (if known) + */ + bool Error() const { return error; } + + /// Contains a textual (english) description of the error if one occurs. + const char * ErrorDesc() const { return errorDesc.c_str (); } + + /** Generally, you probably want the error string ( ErrorDesc() ). But if you + prefer the ErrorId, this function will fetch it. + */ + int ErrorId() const { return errorId; } + + /** Returns the location (if known) of the error. The first column is column 1, + and the first row is row 1. A value of 0 means the row and column wasn't applicable + (memory errors, for example, have no row/column) or the parser lost the error. (An + error in the error reporting, in that case.) + + @sa SetTabSize, Row, Column + */ + int ErrorRow() const { return errorLocation.row+1; } + int ErrorCol() const { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow() + + /** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol()) + to report the correct values for row and column. It does not change the output + or input in any way. + + By calling this method, with a tab size + greater than 0, the row and column of each node and attribute is stored + when the file is loaded. Very useful for tracking the DOM back in to + the source file. + + The tab size is required for calculating the location of nodes. If not + set, the default of 4 is used. The tabsize is set per document. Setting + the tabsize to 0 disables row/column tracking. + + Note that row and column tracking is not supported when using operator>>. + + The tab size needs to be enabled before the parse or load. Correct usage: + @verbatim + TiXmlDocument doc; + doc.SetTabSize( 8 ); + doc.Load( "myfile.xml" ); + @endverbatim + + @sa Row, Column + */ + void SetTabSize( int _tabsize ) { tabsize = _tabsize; } + + int TabSize() const { return tabsize; } + + /** If you have handled the error, it can be reset with this call. The error + state is automatically cleared if you Parse a new XML block. + */ + void ClearError() { error = false; + errorId = 0; + errorDesc = ""; + errorLocation.row = errorLocation.col = 0; + //errorLocation.last = 0; + } + + /** Write the document to standard out using formatted printing ("pretty print"). */ + void Print() const { } + + /* Write the document to a string using formatted printing ("pretty print"). This + will allocate a character array (new char[]) and return it as a pointer. The + calling code pust call delete[] on the return char* to avoid a memory leak. + */ + //char* PrintToMemory() const; + + /// Print this Document to a FILE stream. + virtual void Print( FILE* cfile, int depth = 0 ) const + { + + } + // [internal use] + void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding ); + + virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type. + + /** Walk the XML tree visiting this node and all of its children. + */ + virtual bool Accept( TiXmlVisitor* content ) const; + +protected : + // [internal use] + virtual TiXmlNode* Clone() const; + #ifdef TIXML_USE_STL + virtual void StreamIn( std::istream * in, TIXML_STRING * tag ); + #endif + +private: + void CopyTo( TiXmlDocument* target ) const; + + bool error; + int errorId; + TIXML_STRING errorDesc; + int tabsize; + TiXmlCursor errorLocation; + bool useMicrosoftBOM; // the UTF-8 BOM were found when read. Note this, and try to write. +}; + + +/** + A TiXmlHandle is a class that wraps a node pointer with null checks; this is + an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml + DOM structure. It is a separate utility class. + + Take an example: + @verbatim + + + + + + + @endverbatim + + Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very + easy to write a *lot* of code that looks like: + + @verbatim + TiXmlElement* root = document.FirstChildElement( "Document" ); + if ( root ) + { + TiXmlElement* element = root->FirstChildElement( "Element" ); + if ( element ) + { + TiXmlElement* child = element->FirstChildElement( "Child" ); + if ( child ) + { + TiXmlElement* child2 = child->NextSiblingElement( "Child" ); + if ( child2 ) + { + // Finally do something useful. + @endverbatim + + And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity + of such code. A TiXmlHandle checks for null pointers so it is perfectly safe + and correct to use: + + @verbatim + TiXmlHandle docHandle( &document ); + TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement(); + if ( child2 ) + { + // do something useful + @endverbatim + + Which is MUCH more concise and useful. + + It is also safe to copy handles - internally they are nothing more than node pointers. + @verbatim + TiXmlHandle handleCopy = handle; + @endverbatim + + What they should not be used for is iteration: + + @verbatim + int i=0; + while ( true ) + { + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement(); + if ( !child ) + break; + // do something + ++i; + } + @endverbatim + + It seems reasonable, but it is in fact two embedded while loops. The Child method is + a linear walk to find the element, so this code would iterate much more than it needs + to. Instead, prefer: + + @verbatim + TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement(); + + for( child; child; child=child->NextSiblingElement() ) + { + // do something + } + @endverbatim +*/ +class TiXmlHandle +{ +public: + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + TiXmlHandle( TiXmlNode* _node ) { this->node = _node; } + /// Copy constructor + TiXmlHandle( const TiXmlHandle& ref ) { this->node = ref.node; } + TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; } + + /// Return a handle to the first child node. + TiXmlHandle FirstChild() const; + /// Return a handle to the first child node with the given name. + TiXmlHandle FirstChild( const char * value ) const; + /// Return a handle to the first child element. + TiXmlHandle FirstChildElement() const; + /// Return a handle to the first child element with the given name. + TiXmlHandle FirstChildElement( const char * value ) const; + + /** Return a handle to the "index" child with the given name. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( const char* value, int index ) const; + /** Return a handle to the "index" child. + The first child is 0, the second 1, etc. + */ + TiXmlHandle Child( int index ) const; + /** Return a handle to the "index" child element with the given name. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( const char* value, int index ) const; + /** Return a handle to the "index" child element. + The first child element is 0, the second 1, etc. Note that only TiXmlElements + are indexed: other types are not counted. + */ + TiXmlHandle ChildElement( int index ) const; + + #ifdef TIXML_USE_STL + TiXmlHandle FirstChild( const std::string& _value ) const { return FirstChild( _value.c_str() ); } + TiXmlHandle FirstChildElement( const std::string& _value ) const { return FirstChildElement( _value.c_str() ); } + + TiXmlHandle Child( const std::string& _value, int index ) const { return Child( _value.c_str(), index ); } + TiXmlHandle ChildElement( const std::string& _value, int index ) const { return ChildElement( _value.c_str(), index ); } + #endif + + /** Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* ToNode() const { return node; } + /** Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); } + /** Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* ToText() const { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); } + /** Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); } + + /** @deprecated use ToNode. + Return the handle as a TiXmlNode. This may return null. + */ + TiXmlNode* Node() const { return ToNode(); } + /** @deprecated use ToElement. + Return the handle as a TiXmlElement. This may return null. + */ + TiXmlElement* Element() const { return ToElement(); } + /** @deprecated use ToText() + Return the handle as a TiXmlText. This may return null. + */ + TiXmlText* Text() const { return ToText(); } + /** @deprecated use ToUnknown() + Return the handle as a TiXmlUnknown. This may return null. + */ + TiXmlUnknown* Unknown() const { return ToUnknown(); } + +private: + TiXmlNode* node; +}; + + +/** Print to memory functionality. The TiXmlPrinter is useful when you need to: + + -# Print to memory (especially in non-STL mode) + -# Control formatting (line endings, etc.) + + When constructed, the TiXmlPrinter is in its default "pretty printing" mode. + Before calling Accept() you can call methods to control the printing + of the XML document. After TiXmlNode::Accept() is called, the printed document can + be accessed via the CStr(), Str(), and Size() methods. + + TiXmlPrinter uses the Visitor API. + @verbatim + TiXmlPrinter printer; + printer.SetIndent( "\t" ); + + doc.Accept( &printer ); + fprintf( stdout, "%s", printer.CStr() ); + @endverbatim +*/ +class TiXmlPrinter : public TiXmlVisitor +{ +public: + TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ), + buffer(), indent( " " ), lineBreak( "\n" ) {} + + virtual bool VisitEnter( const TiXmlDocument& doc ); + virtual bool VisitExit( const TiXmlDocument& doc ); + + virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute ); + virtual bool VisitExit( const TiXmlElement& element ); + + virtual bool Visit( const TiXmlDeclaration& declaration ); + virtual bool Visit( const TiXmlText& text ); + virtual bool Visit( const TiXmlComment& comment ); + virtual bool Visit( const TiXmlUnknown& unknown ); + + /** Set the indent characters for printing. By default 4 spaces + but tab (\t) is also useful, or null/empty string for no indentation. + */ + void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; } + /// Query the indention string. + const char* Indent() { return indent.c_str(); } + /** Set the line breaking string. By default set to newline (\n). + Some operating systems prefer other characters, or can be + set to the null/empty string for no indenation. + */ + void SetLineBreak( const char* _lineBreak ) { lineBreak = _lineBreak ? _lineBreak : ""; } + /// Query the current line breaking string. + const char* LineBreak() { return lineBreak.c_str(); } + + /** Switch over to "stream printing" which is the most dense formatting without + linebreaks. Common when the XML is needed for network transmission. + */ + void SetStreamPrinting() { indent = ""; + lineBreak = ""; + } + /// Return the result. + const char* CStr() { return buffer.c_str(); } + /// Return the length of the result string. + size_t Size() { return buffer.size(); } + + #ifdef TIXML_USE_STL + /// Return the result. + const std::string& Str() { return buffer; } + #endif + +private: + void DoIndent() { + for( int i=0; i), ASSET_ID_FIELD_PREFIX ) + +//----------------------------------------------------------------------------- + +ConsoleGetType( TypeTmxMapAssetPtr ) +{ + // Fetch asset Id. + return (*((AssetPtr*)dptr)).getAssetId(); +} + +//----------------------------------------------------------------------------- + +ConsoleSetType( TypeTmxMapAssetPtr ) +{ + // Was a single argument specified? + if( argc == 1 ) + { + // Yes, so fetch field value. + const char* pFieldValue = argv[0]; + + // Fetch asset pointer. + AssetPtr* pAssetPtr = dynamic_cast*>((AssetPtrBase*)(dptr)); + + // Is the asset pointer the correct type? + if ( pAssetPtr == NULL ) + { + // No, so fail. + Con::warnf( "(TypeTmxMapAssetPtr) - Failed to set asset Id '%d'.", pFieldValue ); + return; + } + + // Set asset. + pAssetPtr->setAssetId( pFieldValue ); + + return; + } + + // Warn. + Con::warnf( "(TypeTmxMapAssetPtr) - Cannot set multiple args to a single asset." ); +} + +//------------------------------------------------------------------------------ + +IMPLEMENT_CONOBJECT(TmxMapAsset); + +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ + +TmxMapAsset::TmxMapAsset() : mMapFile(StringTable->EmptyString), + mParser(NULL) + +{ +} + +//------------------------------------------------------------------------------ + +TmxMapAsset::~TmxMapAsset() +{ + if (mParser) + { + delete mParser; + } +} + +//------------------------------------------------------------------------------ + +void TmxMapAsset::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + // Fields. + addProtectedField("MapFile", TypeAssetLooseFilePath, Offset(mMapFile, TmxMapAsset), &setMapFile, &getMapFile, &defaultProtectedWriteFn, ""); + +} + +//------------------------------------------------------------------------------ + +bool TmxMapAsset::onAdd() +{ + // Call Parent. + if (!Parent::onAdd()) + return false; + + return true; +} + +//------------------------------------------------------------------------------ + +void TmxMapAsset::onRemove() +{ + // Call Parent. + Parent::onRemove(); +} + + +//------------------------------------------------------------------------------ + +void TmxMapAsset::setMapFile( const char* pMapFile ) +{ + // Sanity! + AssertFatal( pMapFile != NULL, "Cannot use a NULL map file." ); + + // Fetch image file. + pMapFile = StringTable->insert( pMapFile ); + + // Ignore no change, + if ( pMapFile == mMapFile ) + return; + + // Update. + mMapFile = getOwned() ? expandAssetFilePath( pMapFile ) : StringTable->insert( pMapFile ); + + // Refresh the asset. + refreshAsset(); +} + +//------------------------------------------------------------------------------ + +void TmxMapAsset::initializeAsset( void ) +{ + // Call parent. + Parent::initializeAsset(); + + // Ensure the image-file is expanded. + mMapFile = expandAssetFilePath( mMapFile ); + + calculateMap(); +} + +//------------------------------------------------------------------------------ + +void TmxMapAsset::onAssetRefresh( void ) +{ + // Ignore if not yet added to the sim. + if ( !isProperlyAdded() ) + return; + + // Call parent. + Parent::onAssetRefresh(); + + calculateMap(); +} + +//----------------------------------------------------------------------------- + +void TmxMapAsset::onTamlPreWrite( void ) +{ + // Call parent. + Parent::onTamlPreWrite(); + + // Ensure the image-file is collapsed. + mMapFile = collapseAssetFilePath( mMapFile ); +} + +//----------------------------------------------------------------------------- + +void TmxMapAsset::onTamlPostWrite( void ) +{ + // Call parent. + Parent::onTamlPostWrite(); + + // Ensure the image-file is expanded. + mMapFile = expandAssetFilePath( mMapFile ); +} + +//---------------------------------------------------------------------------- + +void TmxMapAsset::calculateMap() +{ + if (mParser) + { + delete mParser; + mParser = NULL; + } + + mParser = new Tmx::Map(); + mParser->ParseFile( mMapFile ); + + if (mParser->HasError()) + { + // No, so warn. + Con::warnf( "Map '%' could not be parsed: error code (%d) - %s.", getAssetId(), mParser->GetErrorCode(), mParser->GetErrorText().c_str() ); + delete mParser; + mParser = NULL; + return; + } +} + +bool TmxMapAsset::isAssetValid() +{ + return (mParser != NULL); +} + +StringTableEntry TmxMapAsset::getOrientation() +{ + if (!isAssetValid()) return StringTable->EmptyString; + + switch(mParser->GetOrientation()) + { + case Tmx::TMX_MO_ORTHOGONAL: + { + return StringTable->insert("ortho"); + } + case Tmx::TMX_MO_ISOMETRIC: + { + return StringTable->insert("iso"); + } + case Tmx::TMX_MO_STAGGERED: + { + return StringTable->insert("stag"); + } + default: + { + return StringTable->EmptyString; + } + } +} + +int TmxMapAsset::getLayerCount() +{ + if (!isAssetValid()) return 0; + + return mParser->GetNumLayers(); +} + +Tmx::Map* TmxMapAsset::getParser() +{ + if (!isAssetValid()) return NULL; + + return mParser; +} \ No newline at end of file diff --git a/engine/source/2d/assets/TmxMapAsset.h b/engine/source/2d/assets/TmxMapAsset.h new file mode 100644 index 000000000..1158a447d --- /dev/null +++ b/engine/source/2d/assets/TmxMapAsset.h @@ -0,0 +1,77 @@ +#ifndef _TMXMAP_ASSET_H_ +#define _TMXMAP_ASSET_H_ + +#ifndef _ASSET_PTR_H_ +#include "assets/assetPtr.h" +#endif + +#include + +//----------------------------------------------------------------------------- + +DefineConsoleType( TypeTmxMapAssetPtr ) + +//----------------------------------------------------------------------------- + +class TmxMapAsset : public AssetBase +{ + +////T2D SIM/CONSOLE setup//////////////////// +private: + typedef AssetBase Parent; + +public: + + TmxMapAsset(); + virtual ~TmxMapAsset(); + + /// Core. + static void initPersistFields(); + virtual bool onAdd(); + virtual void onRemove(); + + /// Declare Console Object. + DECLARE_CONOBJECT(TmxMapAsset); +////////////////////////////////////////////// + + +private: + + /// Configuration. + StringTableEntry mMapFile; + +public: + + void setMapFile( const char* pMapFile ); + inline StringTableEntry getMapFile( void ) const { return mMapFile; }; + + + StringTableEntry getOrientation(); + int getLayerCount(); + + Tmx::Map* getParser(); + +private: + + Tmx::Map* mParser; + + void calculateMap( void ); + virtual bool isAssetValid(); + +protected: + virtual void initializeAsset( void ); + virtual void onAssetRefresh( void ); + + /// Taml callbacks. + virtual void onTamlPreWrite( void ); + virtual void onTamlPostWrite( void ); + + +protected: + + static bool setMapFile( void* obj, const char* data ) { static_cast(obj)->setMapFile(data); return false; } + static const char* getMapFile(void* obj, const char* data) { return static_cast(obj)->getMapFile(); } + +}; + +#endif //_TMXMAP_ASSET_H_ \ No newline at end of file diff --git a/engine/source/2d/assets/TmxMapAsset_ScriptBinding.h b/engine/source/2d/assets/TmxMapAsset_ScriptBinding.h new file mode 100644 index 000000000..f31e833a6 --- /dev/null +++ b/engine/source/2d/assets/TmxMapAsset_ScriptBinding.h @@ -0,0 +1,26 @@ + +ConsoleMethod(TmxMapAsset, setMapFile, void, 3, 3, "(MapFile) Sets the map file (tmx file).\n" + "@return No return value.") +{ + object->setMapFile( argv[2] ); +} + +//----------------------------------------------------------------------------- + +ConsoleMethod(TmxMapAsset, getMapFile, const char*, 2, 2, "() Gets the map file.\n" + "@return Returns the tmx map file.") +{ + return object->getMapFile(); +} + +ConsoleMethod(TmxMapAsset, getOrientation, const char*, 2, 2, "() Gets the map orientation.\n" + "@return Returns the tmx map orientation layout.") +{ + return object->getOrientation(); +} + +ConsoleMethod(TmxMapAsset, getLayerCount, S32, 2, 2, "() Gets the number of tile layers.\n" + "@return Returns the numer of tile layers in the map.") +{ + return object->getLayerCount(); +} \ No newline at end of file diff --git a/engine/source/2d/sceneobject/SceneObject.h b/engine/source/2d/sceneobject/SceneObject.h index 0d5c790cf..d924d07aa 100755 --- a/engine/source/2d/sceneobject/SceneObject.h +++ b/engine/source/2d/sceneobject/SceneObject.h @@ -373,7 +373,7 @@ class SceneObject : /// Body. virtual ePhysicsProxyType getPhysicsProxyType( void ) const { return PhysicsProxy::PHYSIC_PROXY_SCENEOBJECT; } inline b2Body* getBody( void ) const { return mpBody; } - void setBodyType( const b2BodyType type ); + virtual void setBodyType( const b2BodyType type ); inline b2BodyType getBodyType(void) const { if ( mpScene ) return mpBody->GetType(); else return mBodyDefinition.type; } inline void setActive( const bool active ) { if ( mpScene ) mpBody->SetActive( active ); else mBodyDefinition.active = active; } inline bool getActive(void) const { if ( mpScene ) return mpBody->IsActive(); else return mBodyDefinition.active; } diff --git a/engine/source/2d/sceneobject/TmxMapSprite.cpp b/engine/source/2d/sceneobject/TmxMapSprite.cpp new file mode 100644 index 000000000..1f0fa4265 --- /dev/null +++ b/engine/source/2d/sceneobject/TmxMapSprite.cpp @@ -0,0 +1,715 @@ +#include "TmxMapSprite.h" + +#include "assets/assetManager.h" +#include + +//script bindings +#include "TmxMapSprite_ScriptBinding.h" + + + +//----------------------------------------------------------------------------- + +IMPLEMENT_CONOBJECT(TmxMapSprite); + +//------------------------------------------------------------------------------ + +TmxMapSprite::TmxMapSprite() : mMapPixelToMeterFactor(0.03f), + mLastTileAsset(StringTable->EmptyString), + mLastTileImage(StringTable->EmptyString) +{ + mAutoSizing = true; + setBodyType(b2_staticBody); +} + +//------------------------------------------------------------------------------ + +TmxMapSprite::~TmxMapSprite() +{ + ClearMap(); +} + +void TmxMapSprite::initPersistFields() +{ + // Call parent. + Parent::initPersistFields(); + + addProtectedField("Map", TypeTmxMapAssetPtr, Offset(mMapAsset, TmxMapSprite), &setMap, &getMap, &writeMap, ""); + addProtectedField("MapToMeterFactor", TypeF32, Offset(mMapPixelToMeterFactor, TmxMapSprite), &setMapToMeterFactor, &getMapToMeterFactor, &writeMapToMeterFactor, ""); +} + +bool TmxMapSprite::onAdd() +{ + auto layerIdx = mLayers.begin(); + for (layerIdx; layerIdx != mLayers.end(); ++layerIdx) + { + + (*layerIdx)->onAdd(); + } + auto objectsIdx = mObjects.begin(); + for (objectsIdx; objectsIdx != mObjects.end(); ++objectsIdx){ + (*objectsIdx)->onAdd(); + } + return (Parent::onAdd()); + +} + +void TmxMapSprite::onRemove() +{ + auto layerIdx = mLayers.begin(); + for (layerIdx; layerIdx != mLayers.end(); ++layerIdx) + { + + // (*layerIdx)->onRemove(); + } + auto objectsIdx = mObjects.begin(); + for (objectsIdx; objectsIdx != mObjects.end(); ++objectsIdx){ + // (*objectsIdx)->onRemove(); + } + Parent::onRemove(); +} + +void TmxMapSprite::OnRegisterScene(Scene* pScene) +{ + + Parent::OnRegisterScene(pScene); + auto layerIdx = mLayers.begin(); + for(layerIdx; layerIdx != mLayers.end(); ++layerIdx) + { + + pScene->addToScene(*layerIdx); + } + auto objectsIdx = mObjects.begin(); + for (objectsIdx; objectsIdx != mObjects.end(); ++objectsIdx){ + pScene->addToScene(*objectsIdx); + } + +} + +void TmxMapSprite::OnUnregisterScene( Scene* pScene ) +{ + Parent::OnUnregisterScene(pScene); + + auto layerIdx = mLayers.begin(); + for(layerIdx; layerIdx != mLayers.end(); ++layerIdx) + { + //(*layerIdx)->OnUnregisterScene(pScene); + } + auto objectsIdx = mObjects.begin(); + for (objectsIdx; objectsIdx != mObjects.end(); ++objectsIdx){ + //(*objectsIdx)->OnUnregisterScene(pScene); + } +} + +void TmxMapSprite::setPosition( const Vector2& position ) +{ + Parent::setPosition(position); + auto layerIdx = mLayers.begin(); + for(layerIdx; layerIdx != mLayers.end(); ++layerIdx) + { + (*layerIdx)->setPosition(position); + } + +} + +void TmxMapSprite::ClearMap() +{ + auto layerIdx = mLayers.begin(); + for(layerIdx; layerIdx != mLayers.end(); ++layerIdx) + { + //CompositeSprite* sprite = *layerIdx; + //delete sprite; + } + mLayers.clear(); + auto objectsIdx = mObjects.begin(); + for (objectsIdx; objectsIdx != mObjects.end(); ++objectsIdx){ + SceneObject* object = *objectsIdx; + delete object; + } + mObjects.clear(); +} +void TmxMapSprite::BuildMap() +{ + // Debug Profiling. + PROFILE_SCOPE(TmxMapSprite_BuildMap); + + + ClearMap(); + auto mapParser = mMapAsset->getParser(); + + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + F32 halfTileHeight = static_cast(tileHeight * 0.5); + + F32 width = (mapParser->GetWidth() * tileWidth); + F32 height = (mapParser->GetHeight() * tileHeight); + + F32 originY = height / 2 - halfTileHeight; + F32 originX = 0; + + Vector2 tileSize(tileWidth, tileHeight); + Vector2 originSize(originX, originY); + + Tmx::MapOrientation orient = mapParser->GetOrientation(); + + auto layerItr = mapParser->GetLayers().begin(); + for(layerItr; layerItr != mapParser->GetLayers().end(); ++layerItr) + { + Tmx::Layer* layer = *layerItr; + + //use default layer number, unless someone realy wants to override it. + S32 layerNumber = 31 - layer->GetZOrder(); + if (layer->GetProperties().HasProperty(TMX_MAP_LAYER_ID_PROP)) + layerNumber = layer->GetProperties().GetNumericProperty(TMX_MAP_LAYER_ID_PROP); + + auto compSprite = CreateLayer(layerNumber, orient == Tmx::TMX_MO_ISOMETRIC); + + U32 xTiles = mapParser->GetWidth(); + U32 yTiles = mapParser->GetHeight(); + for(U32 x=0; x < xTiles; ++x) + { + for (U32 y=0; y < yTiles; ++y) + { + const Tmx::MapTile& tile = layer->GetTile(x, y); + if (tile.tilesetId == TMX_MAP_NO_TILE) continue; //no tile at this location + + const Tmx::Tileset* tset = mapParser->GetTileset(tile.tilesetId); + + StringTableEntry assetName = GetTilesetAsset(tset); + if (assetName == StringTable->EmptyString) continue; + + U32 localFrame = tile.id; + F32 spriteHeight = static_cast( tset->GetTileHeight() ); + F32 spriteWidth = static_cast( tset->GetTileWidth() ); + + //F32 heightOffset = (spriteHeight - tileHeight) / 2; + //F32 widthOffset = (spriteWidth - tileWidth) / 2; + auto thisTilePosition = Vector2(static_cast(x), static_cast(yTiles - y)); + auto bId = compSprite->addSprite( SpriteBatchItem::LogicalPosition( thisTilePosition.scriptThis()) ); + compSprite->selectSpriteId(bId); + compSprite->setSpriteImage(assetName, localFrame); + auto thisTileSize = Vector2(spriteWidth * mMapPixelToMeterFactor, spriteHeight * mMapPixelToMeterFactor); + compSprite->setSpriteSize( thisTileSize); + + compSprite->setSpriteFlipX(tile.flippedHorizontally); + compSprite->setSpriteFlipY(tile.flippedVertically); + const Tmx::Tile* tileobj= tset->GetTile(tile.id); + if (tileobj) { + if (tileobj->GetObjectGroup().GetNumObjects() > 0) { + auto thisTileAbsolutePosition = Vector2(thisTilePosition.x * spriteWidth, (yTiles * spriteHeight) - (thisTilePosition.y * spriteHeight)); + addObjectGroup(&tset->GetTile(tile.id)->GetObjectGroup(), &thisTileAbsolutePosition); + } + } + + } + } + + } + + //now do object groups... + auto groupIdx = mapParser->GetObjectGroups().begin(); + + for(groupIdx; groupIdx != mapParser->GetObjectGroups().end(); ++groupIdx) + { + auto groupLayer = *groupIdx; + addObjectGroup(groupLayer, NULL); + + } +} + +void TmxMapSprite::addObjectGroup(const Tmx::ObjectGroup* objectGroup, const Vector2* offset ) { + auto mapParser = mMapAsset->getParser(); + Tmx::MapOrientation orient = mapParser->GetOrientation(); + //use default layer number, unless someone realy wants to override it. + S32 layerNumber = 31 - objectGroup->GetZOrder(); + if (objectGroup->GetProperties().HasProperty(TMX_MAP_LAYER_ID_PROP)) + layerNumber = objectGroup->GetProperties().GetNumericProperty(TMX_MAP_LAYER_ID_PROP); + + auto compSprite = CreateLayer(layerNumber, orient == Tmx::TMX_MO_ISOMETRIC); + + auto objectIdx = objectGroup->GetObjects().begin(); + for (objectIdx; objectIdx != objectGroup->GetObjects().end(); ++objectIdx) + { + auto object = *objectIdx; + //do a number of things. + //try it as a script reference + if (object->GetType() == TMX_MAP_SCRIPT_OBJECT || objectGroup->GetName() == TMX_MAP_SCRIPT_OBJECT) { + addScriptObject(object, layerNumber, offset); + continue; //don't allow script refs to have a sprite or physics presence... + } + //try it as a tile + auto gid = object->GetGid(); + auto tileSet = mapParser->FindTileset(gid); + if (tileSet != NULL) { + addObjectAsSprite(tileSet, object, mapParser, gid, compSprite, offset); + continue; + } + //try it as a physics object. + if (object->GetName() == TMX_MAP_COLLISION_OBJECT || object->GetType() == TMX_MAP_COLLISION_OBJECT || objectGroup->GetName() == TMX_MAP_COLLISION_OBJECT) { + //try to add some physics bodies... + + if (object->GetPolyline() != NULL) { + addPhysicsPolyLine(object, compSprite, offset); + } + else if (object->GetPolygon() != NULL) { + addPhysicsPolygon(object, compSprite, offset); + } + else if (object->GetEllipse() != NULL) { + addPhysicsEllipse(object, compSprite, offset); + } + else { + //must be a rectangle. + addPhysicsRectangle(object, compSprite, offset); + } + continue; + } + } +} + +void TmxMapSprite::addScriptObject(const Tmx::Object* object, S32 layerNumber, const Vector2* offset) { + std::string result; + if (object->GetProperties().HasProperty(TMX_MAP_SCRIPT_FUNCTION)) { + result = Con::evaluatef("%s();", object->GetProperties().GetLiteralProperty(TMX_MAP_SCRIPT_FUNCTION).c_str()); + } + else if (object->GetName() == TMX_MAP_SCRIPT_FUNCTION) { + result = Con::evaluatef("%s();", object->GetType().c_str()); + } + else if (object->GetType() == TMX_MAP_SCRIPT_FUNCTION) { + result = Con::evaluatef("%s();", object->GetName().c_str()); + } + //Con::printf("Executed a script and got %s back", result.c_str()); + + //set the object's layer... + char layer[128]; + dItoa(layerNumber, layer); + Con::evaluatef("%s.SceneLayer = %s;", result.c_str(), layer); + //set the object's position... + Vector2 pixLoc = Vector2( + static_cast(object->GetX()), + static_cast(object->GetY()) + ); + if (offset){ + pixLoc.x += offset->x; + pixLoc.y += offset->y; + } + const char* loc = PixelToCoord(pixLoc).scriptThis(); + Con::evaluatef("%s.position = \"%s\";", result.c_str(), loc); + + //assign the rest of the properties from TMX + std::map list = object->GetProperties().GetList(); + for (auto iter = list.begin(); + iter != list.end(); + iter++) { + if ( + iter->first != std::string(TMX_MAP_SCRIPT_FUNCTION) + && + iter->second != std::string(TMX_MAP_SCRIPT_FUNCTION) + ) { + //Con::printf("generating code to set property %s of %s to value %s", iter->first.c_str(), result.c_str(), iter->second.c_str()); + Con::evaluatef("%s.%s = %s;", result.c_str(), iter->first.c_str(), iter->second.c_str()); + } + } +} + +void TmxMapSprite::addObjectAsSprite(const Tmx::Tileset* tileSet, Tmx::Object* object, Tmx::Map * mapParser, U32 gid, CompositeSprite* compSprite, const Vector2* offset){ + + F32 objectWidth = static_cast(object->GetWidth()); + F32 objectHeight = static_cast(object->GetHeight()); + Vector2 vTile = + Vector2 + ( + static_cast(object->GetX()), + static_cast(object->GetY()) + ); + + Vector2 pos = PixelToCoord( vTile); + + if (offset) { + pos.x += offset->x; + pos.y += offset->y; + } + + S32 frameNumber = gid - tileSet->GetFirstGid(); + StringTableEntry assetName = GetTilesetAsset(tileSet); + + auto bId = compSprite->addSprite( SpriteBatchItem::LogicalPosition( pos.scriptThis()) ); + compSprite->selectSpriteId(bId); + compSprite->setSpriteImage(assetName, frameNumber); + compSprite->setSpriteSize(Vector2( objectWidth * mMapPixelToMeterFactor, objectHeight * mMapPixelToMeterFactor)); + compSprite->setSpriteFlipX(false); + compSprite->setSpriteFlipY(false); + + +} + +void TmxMapSprite::addPhysicsPolyLine(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset){ + auto mapParser = mMapAsset->getParser(); + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + F32 mapHeight = (mapParser->GetHeight() * tileHeight); + Vector2 tileSize(tileWidth, tileHeight); + Tmx::MapOrientation orient = mapParser->GetOrientation(); + b2Vec2 origin = b2Vec2 + ( + static_cast(object->GetX()), + static_cast(object->GetY()) + ); + if (offset){ + origin.x += offset->x; + origin.y += offset->y; + } + + + //weird additions and subtractions in this area due to the fact that this engine uses bottom->left as origin, and TMX uses top->right. + //it's hacky, but it works. + Vector2 heightoffset = Vector2( origin.x, mapHeight-(origin.y)); + Vector2 tilecoord = CoordToTile(heightoffset, tileSize, orient == Tmx::TMX_MO_ISOMETRIC); + b2Vec2 nativePoint = tilecoord; + nativePoint += b2Vec2(-tileWidth/2,tileHeight/2); + // nativePoint += b2Vec2(object->GetWidth()/2.0f, -(object->GetHeight()/2.0f)); //adjust for tmx defining from bottom left point while t2d defines from center... + // nativePoint *= mMapPixelToMeterFactor; + const Tmx::Polyline* line = object->GetPolyline(); + + U32 points = line->GetNumPoints(); + if (points > 0){ + //find object height: + F32 min = line->GetPoint(0).y; + F32 max = line->GetPoint(0).y; + for (U32 i = 0; i < points; i++){ + Tmx::Point point = line->GetPoint(i); + if (point.y > max) + max = point.y; + if (point.y < min) + min = point.y; + } + + F32 polylineHeight = max - min; + for (U32 i = 0; i < points-1; i++){ + + Tmx::Point first = line->GetPoint(i); + Tmx::Point second = line->GetPoint(i+1); + + Vector2 firstvec = Vector2(nativePoint.x + first.x, nativePoint.y - first.y); + Vector2 secondvec = Vector2(nativePoint.x + second.x, nativePoint.y - second.y); + + compSprite->createEdgeCollisionShape(firstvec * mMapPixelToMeterFactor, secondvec * mMapPixelToMeterFactor, false, false, Vector2(), Vector2()); + + } + } + + + +} + +void TmxMapSprite::addPhysicsPolygon(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset){ + auto mapParser = mMapAsset->getParser(); + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + F32 height = (mapParser->GetHeight() * tileHeight); + Vector2 tileSize(tileWidth, tileHeight); + Tmx::MapOrientation orient = mapParser->GetOrientation(); + const Tmx::Polygon* line = object->GetPolygon(); + int points = line->GetNumPoints(); + b2Vec2* pointsdata = new b2Vec2[points]; + b2Vec2 origin = b2Vec2 + ( + static_cast(object->GetX()), + static_cast(object->GetY()) + ); + if (offset){ + origin.x += offset->x; + origin.y += offset->y; + } + for (int i = 0; i < points; i++) + { + Tmx::Point tmxPoint = line->GetPoint(i); + + //weird additions and subtractions in this area due to the fact that this engine uses bottom->left as origin, and TMX uses top->right. + //it's hacky, but it works. + Vector2 isocoord = Vector2( tmxPoint.x + origin.x, height-(origin.y+tmxPoint.y)); + Vector2 tilecoord = CoordToTile(isocoord,tileSize,orient == Tmx::TMX_MO_ISOMETRIC); + b2Vec2 nativePoint = tilecoord; + nativePoint += b2Vec2(-tileWidth/2,tileHeight/2); + nativePoint *= mMapPixelToMeterFactor; + pointsdata[i] = nativePoint; + + } + compSprite->createPolygonCollisionShape(points, pointsdata); + delete[] pointsdata; +} + +void TmxMapSprite::addPhysicsEllipse(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset){ + auto mapParser = mMapAsset->getParser(); + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + F32 mapHeight = (mapParser->GetHeight() * tileHeight); + Vector2 tileSize(tileWidth, tileHeight); + Tmx::MapOrientation orient = mapParser->GetOrientation(); + const Tmx::Ellipse* ellipse = object->GetEllipse(); + b2Vec2 origin = b2Vec2 + ( + static_cast(ellipse->GetCenterX()), + static_cast(ellipse->GetCenterY()) + ); + if (offset){ + origin.x += offset->x; + origin.y += offset->y; + } + + F32 ellipseHeight = static_cast(ellipse->GetRadiusY()); + F32 ellipseWidth = static_cast(ellipse->GetRadiusX()); + + //tmx allows arbitrary ellipses, t2d only lets us use circles. approximate ellipses with a height:width ratio of 1/2 - 2with a circle, otherwise fail. + F32 ratio = ellipseHeight/ellipseWidth; + if (ratio < 0.5f || ratio > 2.0f){ + Con::warnf("TMX map has an ellipse collision body with H:W ratio outside of our approximatable bounds. Use a different shape."); + return; + } + + + //weird additions and subtractions in this area due to the fact that this engine uses bottom->left as origin, and TMX uses top->right. + //it's hacky, but it works. + Vector2 originOffset = Vector2( origin.x, mapHeight-(origin.y)); + Vector2 tilecoord = CoordToTile(originOffset ,tileSize,orient == Tmx::TMX_MO_ISOMETRIC); + b2Vec2 nativePoint = tilecoord; + nativePoint += b2Vec2(-tileWidth/2,tileHeight/2); + nativePoint *= mMapPixelToMeterFactor; + compSprite->createCircleCollisionShape( (ellipseHeight > ellipseWidth ? ellipseHeight : ellipseWidth ) * mMapPixelToMeterFactor, nativePoint); + + +} + +void TmxMapSprite::addPhysicsRectangle(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset){ + auto mapParser = mMapAsset->getParser(); + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + F32 mapHeight = (mapParser->GetHeight() * tileHeight); + Vector2 tileSize(tileWidth, tileHeight); + Tmx::MapOrientation orient = mapParser->GetOrientation(); + b2Vec2 origin = b2Vec2 + ( + static_cast(object->GetX()), + static_cast(object->GetY()) + ); + if (offset){ + origin.x += offset->x; + origin.y += offset->y; + } + + + //weird additions and subtractions in this area due to the fact that this engine uses bottom->left as origin, and TMX uses top->right. + //it's hacky, but it works. + Vector2 heightoffset = Vector2( origin.x, mapHeight-(origin.y)); + Vector2 tilecoord = CoordToTile(heightoffset, tileSize, orient == Tmx::TMX_MO_ISOMETRIC); + b2Vec2 nativePoint = tilecoord; + nativePoint += b2Vec2(-tileWidth/2,tileHeight/2); + nativePoint += b2Vec2(object->GetWidth()/2.0f, -(object->GetHeight()/2.0f)); //adjust for tmx defining from bottom left point while t2d defines from center... + nativePoint *= mMapPixelToMeterFactor; + compSprite->createPolygonBoxCollisionShape(object->GetWidth()*mMapPixelToMeterFactor, object->GetHeight()*mMapPixelToMeterFactor, nativePoint); + + +} + +Vector2 TmxMapSprite::CoordToTile(Vector2& pos, Vector2& tileSize, bool isIso) +{ + + if (isIso) + { + Vector2 newPos( + pos.x / tileSize.y, + pos.y / tileSize.y + ); + + return newPos; + } + else + { + return pos; + } +} + +Vector2 TmxMapSprite::PixelToCoord(Vector2& pixPos){ + auto mapParser = mMapAsset->getParser(); + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + F32 mapHeight = (mapParser->GetHeight() * tileHeight); + Vector2 tileSize(tileWidth, tileHeight); + Tmx::MapOrientation orient = mapParser->GetOrientation(); + Vector2 heightOffset = Vector2(pixPos.x, mapHeight - (pixPos.y)); + Vector2 tilecoord = CoordToTile(heightOffset, tileSize, orient == Tmx::TMX_MO_ISOMETRIC); + b2Vec2 nativePoint = tilecoord; + nativePoint += b2Vec2(-tileWidth / 2, tileHeight / 2); + nativePoint *= mMapPixelToMeterFactor; + return nativePoint; +} + +Vector2 TmxMapSprite::TileToCoord(Vector2& pos, Vector2& tileSize, Vector2& offset, bool isIso) +{ + if (isIso) + { + Vector2 newPos( + static_cast( (pos.x - pos.y) * tileSize.y), + static_cast( offset.y - (pos.x + pos.y) * tileSize.y * 0.5 ) + ); + + return newPos; + } + else + { + Vector2 newpos(pos.x*tileSize.x*mMapPixelToMeterFactor, pos.y*tileSize.y*mMapPixelToMeterFactor); + return newpos; + } +} + +CompositeSprite* TmxMapSprite::CreateLayer(U32 layerIndex, bool isIso) +{ + CompositeSprite* compSprite = new CompositeSprite(); + mLayers.push_back(compSprite); + + auto scene = this->getScene(); + if (scene) + scene->addToScene(compSprite); + + if (isIso) + compSprite->setBatchLayout( CompositeSprite::ISOMETRIC_LAYOUT ); + else + compSprite->setBatchLayout(CompositeSprite::RECTILINEAR_LAYOUT); + + auto mapParser = mMapAsset->getParser(); + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + compSprite->setDefaultSpriteSize(Vector2(tileWidth, tileHeight) * mMapPixelToMeterFactor); + compSprite->setDefaultSpriteStride(Vector2(tileWidth, tileHeight) * mMapPixelToMeterFactor); + + + compSprite->setPosition(getPosition()); + compSprite->setSceneLayer(layerIndex); + compSprite->setBatchSortMode(SceneRenderQueue::RENDER_SORT_ZAXIS); + compSprite->setBatchIsolated(true); + compSprite->setBodyType(b2_staticBody); + + return compSprite; +} + +const char* TmxMapSprite::getFileName(const char* path) +{ + auto pStr = dStrrchr(path, '\\'); + if (pStr == NULL) + pStr = dStrrchr(path, '/'); + if (pStr == NULL) + return NULL; + + pStr = pStr+1; + + auto pDot = dStrrchr(pStr, '.'); + U32 file_len = pDot - pStr; + if (file_len >= 1024) return NULL; + + char buffer[1024]; + dStrncpy(buffer, pStr, file_len); + buffer[file_len] = 0; + return StringTable->insert(buffer); +} + +StringTableEntry TmxMapSprite::GetTilesetAsset(const Tmx::Tileset* tileSet) +{ + StringTableEntry assetName = StringTable->insert( tileSet->GetProperties().GetLiteralProperty(TMX_MAP_TILESET_ASSETNAME_PROP).c_str() ); + if (assetName == StringTable->EmptyString) + { + //we fall back to using the image filename as an asset name query. + //if that comes back with any hits, we use the first one. + //If you don't want to name your asset the same as your art tile set name, + //you need to set a custom "AssetName" property on the tile set to override this. + + auto imageSource = tileSet->GetImage()->GetSource().c_str(); + StringTableEntry imageName = getFileName(imageSource); + + if (imageName == mLastTileImage) + { + //this is a quick memoize optimization to cut down on asset queries. + //if we are requesting the same assetName from what we already found, we just return that. + return mLastTileAsset; + } + + mLastTileImage = imageName; + + AssetQuery query; + S32 count = AssetDatabase.findAssetName(&query, imageName); + if (count > 0) + { + assetName = query.first(); + mLastTileAsset = StringTable->insert( assetName ); + } + } + + return assetName; +} + +const char* TmxMapSprite::getTileProperty(StringTableEntry lName, StringTableEntry pName, U32 x,U32 y){ + //we'll need a parser and to iterate over the layers + auto mapParser = mMapAsset->getParser(); + auto layerItr = mapParser->GetLayers().begin(); + for(layerItr; layerItr != mapParser->GetLayers().end(); ++layerItr) + { + Tmx::Layer* layer = *layerItr; + + //look for a layer with a name that matches lName + if (std::string(lName) != layer->GetName()) + continue; + //we found one, get the tile properties at the xy of that layer + Tmx::MapTile tile = layer->GetTile(x,y); + const Tmx::Tileset *tset = mapParser->GetTileset(tile.tilesetId); + //make sure they're asking for valid x and y + if (tset == NULL) + return ""; + + const Tmx::PropertySet pset = tset->GetTile(tile.id)->GetProperties(); + if (pset.HasProperty(pName)){ + + //we have the result, put it in the string table and return it + std::string presult = pset.GetLiteralProperty(pName); + StringTableEntry s = StringTable->insert(presult.c_str()); + + return s; + } + else + return ""; + } + + //no layer or property of that name. + //return empty + return ""; + +} + +Vector2 TmxMapSprite::getTileSize(){ + Tmx::Map* mapParser = mMapAsset->getParser(); + F32 tileWidth = static_cast(mapParser->GetTileWidth()); + F32 tileHeight = static_cast(mapParser->GetTileHeight()); + return Vector2(tileWidth, tileHeight); + +} + +bool TmxMapSprite::isIsoMap(){ + Tmx::Map* mapParser = mMapAsset->getParser(); + Tmx::MapOrientation orient = mapParser->GetOrientation(); + return orient == Tmx::TMX_MO_ISOMETRIC; +} + +void TmxMapSprite::setBodyType(const b2BodyType type){ + Parent::setBodyType(type); + + auto layerIdx = mLayers.begin(); + for(layerIdx; layerIdx != mLayers.end(); ++layerIdx) + { + + (*layerIdx)->setBodyType(type); + } + + auto objectsIdx = mObjects.begin(); + for (objectsIdx; objectsIdx != mObjects.end(); ++objectsIdx){ + (*objectsIdx)->setBodyType(type); + } + + +} \ No newline at end of file diff --git a/engine/source/2d/sceneobject/TmxMapSprite.h b/engine/source/2d/sceneobject/TmxMapSprite.h new file mode 100644 index 000000000..5bb104a8b --- /dev/null +++ b/engine/source/2d/sceneobject/TmxMapSprite.h @@ -0,0 +1,93 @@ +#ifndef _TMXMAP_SPRITE_H +#define _TMXMAP_SPRITE_H + +#ifndef _COMPOSITE_SPRITE_H_ +#include "2d/sceneobject/CompositeSprite.h" +#endif + +#ifndef _TMXMAP_ASSET_H_ +#include "2d/assets/TmxMapAsset.h" +#endif + + +#define TMX_MAP_TILESET_ASSETNAME_PROP "AssetName" +#define TMX_MAP_LAYER_ID_PROP "LayerId" +#define TMX_MAP_COLLISION_OBJECT "Collision" +#define TMX_MAP_SCRIPT_OBJECT "Script" +#define TMX_MAP_SCRIPT_FUNCTION "Function" +#define TMX_MAP_NO_TILE -1 + +class TmxMapSprite : public SceneObject +{ +protected: + typedef SceneObject Parent; + +////////CORE/////////////////////////////// +public: + TmxMapSprite(); + virtual ~TmxMapSprite(); + + static void initPersistFields(); + virtual bool onAdd(); + virtual void onRemove(); + virtual void OnRegisterScene(Scene* scene); + virtual void OnUnregisterScene( Scene* pScene ); + virtual void setPosition( const Vector2& position ); + + /// Declare Console Object. + DECLARE_CONOBJECT( TmxMapSprite ); + +////////////////////////////////////////// + +private: //config + + AssetPtr mMapAsset; + F32 mMapPixelToMeterFactor; //This translates TMX pixel/image coordinate space into T2D scene coordinate space. + //The default is to set every pixel equal to 0.03 meters (or about 33 pixels per meter) + //This should match up with the rest of your asset design resolution. + Vector mLayers; + Vector mObjects; + + StringTableEntry mLastTileAsset; + StringTableEntry mLastTileImage; + + void BuildMap(); + void ClearMap(); + CompositeSprite* CreateLayer(U32 layerIndex, bool isIso); + const char* getFileName(const char* path); + StringTableEntry GetTilesetAsset(const Tmx::Tileset* tileSet); + void addObjectGroup(const Tmx::ObjectGroup* objectGroup, const Vector2* offset); + void addScriptObject(const Tmx::Object* object, S32 layerNumber, const Vector2* offset); + void addObjectAsSprite(const Tmx::Tileset* tileSet, Tmx::Object* object, Tmx::Map * mapParser, U32 gid, CompositeSprite* compSprite, const Vector2* offset); + void addPhysicsPolyLine(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset); + void addPhysicsPolygon(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset); + void addPhysicsEllipse(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset); + void addPhysicsRectangle(Tmx::Object* object, CompositeSprite* compSprite, const Vector2* offset); + +public: + inline bool setMap( const char* pMapAssetId ){ if (pMapAssetId == NULL) return false; mMapAsset = pMapAssetId; BuildMap(); return false;} + inline StringTableEntry getMap( void ) const { return mMapAsset.getAssetId(); } + inline bool setMapToMeterFactor( F32 factor ) {mMapPixelToMeterFactor = factor; BuildMap(); return false;} + inline F32 getMapToMeterFactor( void ) const {return mMapPixelToMeterFactor;} + const char* getTileProperty(StringTableEntry lName, StringTableEntry pName, U32 x,U32 y); + Vector2 CoordToTile(Vector2& pos, Vector2& tileSize, bool isIso); + Vector2 TileToCoord(Vector2& pos, Vector2& tileSize, Vector2& offset, bool isIso); + Vector2 PixelToCoord(Vector2& pixPos); + Vector2 getTileSize(); + bool isIsoMap(); + void setBodyType(const b2BodyType type); + +protected: + static bool setMap(void* obj, const char* data) { return static_cast(obj)->setMap(data);} + static const char* getMap(void* obj, const char* data) { return static_cast(obj)->getMap(); } + static bool writeMap( void* obj, StringTableEntry pFieldName ) { return static_cast(obj)->mMapAsset.notNull(); } + + static bool setMapToMeterFactor(void* obj, const char* data) {return static_cast(obj)->setMapToMeterFactor( dAtof(data) ); } + static StringTableEntry getMapToMeterFactor(void* obj, const char* data) {return Con::getFloatArg( static_cast(obj)->getMapToMeterFactor() );} + static bool writeMapToMeterFactor(void* obj, StringTableEntry pFieldName) {return static_cast(obj)->mMapPixelToMeterFactor != 0.1f;} + + +}; + + +#endif //_TMXMAP_SPRITE_H diff --git a/engine/source/2d/sceneobject/TmxMapSprite_ScriptBinding.h b/engine/source/2d/sceneobject/TmxMapSprite_ScriptBinding.h new file mode 100644 index 000000000..344614c17 --- /dev/null +++ b/engine/source/2d/sceneobject/TmxMapSprite_ScriptBinding.h @@ -0,0 +1,41 @@ +ConsoleMethodWithDocs(TmxMapSprite, getMapToMeterFactor, F32, 2, 2, "() Returns the factor used to translate map pixels into scene meters\n" + "") +{ + return object->getMapToMeterFactor(); +} + +ConsoleMethodWithDocs(TmxMapSprite, setMapToMeterFactor, void, 3, 3, "(factor) Sets the factor used to translate map pixels into scene meters\n" + "") +{ + F32 factor = dAtof(argv[2]); + object->setMapToMeterFactor(factor); +} + + +ConsoleMethodWithDocs(TmxMapSprite, getTileProperty, const char*, 6, 6, "(layerName, propertyName, x, y) Gets a property value for the specific x/y coord on the given layer.\n" + "The property value or blank if one can not be found.") +{ + StringTableEntry lName = StringTable->insert(argv[2]); + StringTableEntry pName = StringTable->insert(argv[3]); + S32 x = dAtoi(argv[4]); + S32 y = dAtoi(argv[5]); + + return object->getTileProperty(lName, pName, x, y); +} + + +ConsoleMethodWithDocs(TmxMapSprite, WorldCoordToTile, const char*, 3,3,"Convert a world coordinate into a local tile coordinate\n" + "@Return a tile coordinate as string (x y)") +{ + Vector2 worldPoint(argv[2]); + Vector2 localPoint = object->getLocalPoint(worldPoint); + Vector2 tileSize = object->getTileSize(); + auto tilePoint = object->CoordToTile(localPoint, tileSize, object->isIsoMap()); + return tilePoint.scriptThis(); +} + +ConsoleMethodWithDocs(TmxMapSprite, setMap, void, 3,3,"Set the map this MapSprite is to load.") +{ + object ->setMap(argv[2]); +} + diff --git a/toybox/ToyAssets/1/assets/images/Woodland_x3.asset.taml b/toybox/ToyAssets/1/assets/images/Woodland_x3.asset.taml new file mode 100644 index 000000000..bfa03cbce --- /dev/null +++ b/toybox/ToyAssets/1/assets/images/Woodland_x3.asset.taml @@ -0,0 +1,8 @@ + diff --git a/toybox/ToyAssets/1/assets/images/Woodland_x3.png b/toybox/ToyAssets/1/assets/images/Woodland_x3.png new file mode 100644 index 000000000..0efb2d91e Binary files /dev/null and b/toybox/ToyAssets/1/assets/images/Woodland_x3.png differ diff --git a/toybox/ToyAssets/1/assets/images/town.asset.taml b/toybox/ToyAssets/1/assets/images/town.asset.taml new file mode 100644 index 000000000..7f1ed5dc3 --- /dev/null +++ b/toybox/ToyAssets/1/assets/images/town.asset.taml @@ -0,0 +1,10 @@ + diff --git a/toybox/ToyAssets/1/assets/images/town.png b/toybox/ToyAssets/1/assets/images/town.png new file mode 100644 index 000000000..5ac1f6d4f Binary files /dev/null and b/toybox/ToyAssets/1/assets/images/town.png differ diff --git a/toybox/ToyAssets/1/assets/images/town1.asset.taml b/toybox/ToyAssets/1/assets/images/town1.asset.taml new file mode 100644 index 000000000..93ec0072c --- /dev/null +++ b/toybox/ToyAssets/1/assets/images/town1.asset.taml @@ -0,0 +1,8 @@ + diff --git a/toybox/ToyAssets/1/assets/images/town1.png b/toybox/ToyAssets/1/assets/images/town1.png new file mode 100644 index 000000000..91af7dbe6 Binary files /dev/null and b/toybox/ToyAssets/1/assets/images/town1.png differ diff --git a/toybox/ToyAssets/1/assets/maps/testtown.asset.taml b/toybox/ToyAssets/1/assets/maps/testtown.asset.taml new file mode 100644 index 000000000..43612b08d --- /dev/null +++ b/toybox/ToyAssets/1/assets/maps/testtown.asset.taml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + -0.5 -0.5 + 0.5 -0.5 + -0.5 0.5 + 0.5 0.5 + + + + + + + + + diff --git a/toybox/ToyAssets/1/assets/maps/testtown.tmx b/toybox/ToyAssets/1/assets/maps/testtown.tmx new file mode 100644 index 000000000..5c2a6841a --- /dev/null +++ b/toybox/ToyAssets/1/assets/maps/testtown.tmx @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + H4sIAAAAAAAAA+3VYQ7CIAwFYK5qdgXjbTwCR4EzqclIXl7aDQwFdP3xQkRk3zrLUgghv5MWGLXMdrnPfSuMo3xPyNV9uWF/r5/7RvmOgr6ztfj/vpKv9vlqFulcsPQd1Y/XjPBhbhD2Sb/T5qx8XIMVfLh3pDnJt8GY9nGDecv6Rfp+hfqxT+sPrClfE/u7py+SgT9L54vUy1zfnr4SzcXnC9cP50b7atwcK1+xfGPC++ndH2ejdF3prIzCul6+lufGNZ/pk+o3y1feuzW+8r4Y5fvse9+DPaL5HntmP98Y6vrS2qeNLbE4/9znvn/x1cR9v+/LSl6AqcfwABkAAA== + + + + + H4sIAAAAAAAAA+1Xy04CMRQte597RfwE4y8YE7/AuCQkhBiXhA9g7YK48RdcE7Z+iz8iaEvmwOHOaafDwEY54WaG6W177qO3rXMHHPCP0PK/1n6nWHj5Uf/F3Fb3zLeft8rfG8HMe+LfT8V/zM1A27d/n3vp+PfrVnmMJrA2t/37FY2N/5ibgbYjL8eiTxM/oq+1WcUzOk+hc+HlUvRt4kfbFzareMbmgU6sb7uBD2MxUPG0MQdszFVfti2XK+uh/7N/f8kQRpXuxNhWyqEI2Cb0n2bYVRdj89/mQQwrm2gNgF/KjxMzTo7Pl31MDYvlSwD7ltcA+KX8OHNrn4wrdLlPnbrNvuU8nkbm7Ji5GKw7SvCL1jCB2Lpl/3W9fBXPwO89wQ+8eiTMLYit/Tl10drC/IYkt/Su+PUSAn52rlT+rWBqvIrvh5eH4gl/KH5twS18+yz65PpNrQ1bX+qujxDfm+LJgm8z8kXVvqzWho3vwK1rQ99867tNDIpv8PFbIfA7bLJnn5gfOe7gxfHdB3j91sk/8Gqyf/D+wH5/jejkrNuYDfv03zZ+W4L2nWBnzpmAUbmvuc36AuTU5wC1v22Dnnif0dOu29w6g7ydC35dI1X87P4xM0/nyjkfA/PH3WHJj+K9S3619g23eb7C3SHw43gHTnde7jO49khX8at7D4E9Nv/4PBP220cvT25zPx6K8Uaki/OCyr9cwJ5U/jWFyr/c+wfsCbrIP66vuxDshZx/qfMf7vgAdJF/6q6bqlt2PNuu8i91jond8QPUXXfh0nWLx1PtqfxT+Qg/KXuRh7EzrqpbPJ5tXzidf3WhOCgbq9afbQ9j7YKf4pC7/6Z06taTA/4mfgFE/BMNABkAAA== + + + + + + + + + + + + + + + + + + H4sIAAAAAAAAA+2Yy0oDMRSGzyiigpeNStG6cqEi6k6kFqmufAYpiHTv5SF8hD6dbryAongpqCDU6h/MkBgynSiTy0A++Mi0PUxOTmZ6OiWKRCKRcOnCz5yYHvxykIuOsYRoPOkfM4HPJ3NibFHFvPOe5rZN03cCfTiCx/DE8bxNZXQ9N7vUBuAgHOIOwxE4SqImrmsj78c0nIEV7iycg9Wcc7S4NlmES3AZrnBX4RpcV2LlWrcU5ZoXBdvfGtyCdbjNbcAduKvET5GoNeMVPvL8TGtuiu5+aytjuoZ0lGutklVzm6RrkNeS1vqAx+zzsUH6mvuinXHsE5PvQF89xKQ/FNlDytgrz+GF+3SMuIRX8BreeM5F5RbewUPuA4lezNT1BFu9rat57wk+wxfYgfckejGzqJ7wX97gu/T6g0QvZrrsCUnGb/dT6XgDbsIF+unHjFrG+c6KSqwk6K6/EOgZxvh6rv1FSZ8fg6gdx2S//0JIa9Nh6/+OPY0mcRH36PYqJL8BZBBzwgAZAAA= + + + + + H4sIAAAAAAAAA+3VOwrCUBRF0TgBKwekg3QMOhlHoI0f8ItfFEwhbgtBkRfBKOcazoJdpAjvdDfLzMysjIt6wBv1mnqBRdCngXpEwpBGNKbJD99pfPDPlGY0pwUtafXNUSWtaUNb2tGeDtJFz450evg+Uy7aYmbV49v26n6vblL3KsptS92rCLet6F5FuW1NagneNbP/0FYPKNChrnpEMD31gIq7Ah5xH08AGQAA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toybox/tmxMapToy/1/main.cs b/toybox/tmxMapToy/1/main.cs new file mode 100644 index 000000000..b83ae5707 --- /dev/null +++ b/toybox/tmxMapToy/1/main.cs @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////// +// All map assets for this toy came from: https://github.com/themanaworld/tmwa-client-data +///////////////////////////////////////////////////// + +function TmxMapToy::create( %this ) +{ + // Set the sandbox drag mode availability. + Sandbox.allowManipulation( pan ); + + // Set the manipulation mode. + Sandbox.useManipulation( pan ); + + // Reset the toy. + TmxMapToy.reset(); +} + + +//----------------------------------------------------------------------------- + +function TmxMapToy::destroy( %this ) +{ +} + +//----------------------------------------------------------------------------- + +function TmxMapToy::reset( %this ) +{ + // Clear the scene. + SandboxScene.clear(); + + %mapSprite = new TmxMapSprite() + { + Map = "ToyAssets:testtown_map"; + }; + SandboxScene.add( %mapSprite ); + + + +} + +function Player(){ +//add a simple dynamic sprite to collide with the tiles + %db = new Sprite(TestAnimation) + { + }; + + %db.createCircleCollisionShape(0.2); + SandboxScene.add( %db ); + return %db; +} + +//----------------------------------------------------------------------------- diff --git a/toybox/tmxMapToy/1/module.taml b/toybox/tmxMapToy/1/module.taml new file mode 100644 index 000000000..9c07d265b --- /dev/null +++ b/toybox/tmxMapToy/1/module.taml @@ -0,0 +1,10 @@ +