--- /dev/null
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
+
+*******************************************************************************/
+
+#include "Deserializer.hh"
+#include "Mippleton.hh"
+#include "OpenGL.hh"
+#include "Serializable.hh"
+#include "Tilemap.hh"
+
+
+namespace Mf {
+
+
+class Tilemap::TilemapImpl : public Mippleton<TilemapImpl>
+{
+public:
+ TilemapImpl(const std::string& name) :
+ Mippleton<TilemapImpl>(name),
+ tilesU_(1),
+ tilesV_(1),
+ minFilter_(GL_NEAREST),
+ maxFilter_(GL_NEAREST),
+ wrapU_(GL_CLAMP),
+ wrapV_(GL_CLAMP)
+ {
+ loadFromFile();
+ }
+
+ void loadFromFile()
+ {
+ Deserializer deserializer(Tilemap::getPathToResource(getName()));
+
+ SerializablePtr root = deserializer.deserialize();
+
+ if (root)
+ {
+ std::map<std::string,SerializablePtr> rootObj;
+
+ if (root->get(rootObj))
+ {
+ std::map<std::string,SerializablePtr>::iterator it;
+
+ if ((it = rootObj.find("TilesU")) != rootObj.end())
+ {
+ long value;
+ if ((*it).second->get(value))
+ {
+ tilesU_ = unsigned(value);
+ }
+ }
+ if ((it = rootObj.find("TilesV")) != rootObj.end())
+ {
+ long value;
+ if ((*it).second->get(value))
+ {
+ tilesV_ = unsigned(value);
+ }
+ }
+ if ((it = rootObj.find("MinFilter")) != rootObj.end())
+ {
+ std::string value;
+ if ((*it).second->get(value))
+ {
+ if (value == "Linear")
+ {
+ minFilter_ = GL_LINEAR;
+ }
+ }
+ }
+ if ((it = rootObj.find("MaxFilter")) != rootObj.end())
+ {
+ std::string value;
+ if ((*it).second->get(value))
+ {
+ if (value == "Linear")
+ {
+ maxFilter_ = GL_LINEAR;
+ }
+ }
+ }
+ if ((it = rootObj.find("WrapU")) != rootObj.end())
+ {
+ std::string value;
+ if ((*it).second->get(value))
+ {
+ if (value == "Repeat")
+ {
+ wrapU_ = GL_REPEAT;
+ }
+ }
+ }
+ if ((it = rootObj.find("WrapV")) != rootObj.end())
+ {
+ std::string value;
+ if ((*it).second->get(value))
+ {
+ if (value == "Repeat")
+ {
+ wrapV_ = GL_REPEAT;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ unsigned tilesU_;
+ unsigned tilesV_;
+ GLuint minFilter_;
+ GLuint maxFilter_;
+ GLuint wrapU_;
+ GLuint wrapV_;
+};
+
+
+Tilemap::Tilemap(const std::string& name) :
+ Texture(name),
+ impl_(Tilemap::TilemapImpl::retain(name), &Tilemap::TilemapImpl::release)
+{
+ setMinFilter(impl_->minFilter_);
+ setMaxFilter(impl_->maxFilter_);
+ setWrapU(impl_->wrapU_);
+ setWrapV(impl_->wrapV_);
+ applyChanges();
+}
+
+
+bool Tilemap::getTileCoords(unsigned index, Scalar coords[8])
+{
+ // make sure the index represents a real tile
+ if (index >= impl_->tilesU_ * impl_->tilesV_) return false;
+
+ Scalar w = 1.0 / Scalar(impl_->tilesU_);
+ Scalar h = 1.0 / Scalar(impl_->tilesV_);
+
+ coords[0] = Scalar(index % impl_->tilesU_) * w;
+ coords[1] = (Scalar(impl_->tilesV_ - 1) -
+ Scalar(index / impl_->tilesU_)) * h;
+ coords[2] = coords[0] + w;
+ coords[3] = coords[1];
+ coords[4] = coords[2];
+ coords[5] = coords[1] + h;
+ coords[6] = coords[0];
+ coords[7] = coords[5];
+
+ return true;
+}
+
+bool Tilemap::getTileCoords(unsigned index, Scalar coords[8],
+ Orientation orientation)
+{
+ if (getTileCoords(index, coords))
+ {
+ if (orientation & FLIP)
+ {
+ // this looks kinda weird, but it's just swapping in a way that
+ // doesn't require an intermediate variable
+ coords[1] = coords[5];
+ coords[5] = coords[3];
+ coords[3] = coords[7];
+ coords[7] = coords[5];
+ }
+ if (orientation & REVERSE)
+ {
+ coords[0] = coords[2];
+ coords[2] = coords[6];
+ coords[4] = coords[6];
+ coords[6] = coords[0];
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+std::string Tilemap::getPathToResource(const std::string& name)
+{
+ return Resource::getPathToResource("tilemaps/" + name + ".json");
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+