-
-/*******************************************************************************
-
- 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 <Moof/Library.hh>
-#include <Moof/OpenGL.hh>
-#include <Moof/Script.hh>
-
-#include "Tilemap.hh"
-
-
-struct Tilemap::Impl : public Mf::Library<Impl>
-{
- Impl(const std::string& name) :
- Mf::Library<Impl>(name),
- mMagFilter(GL_NEAREST),
- mMinFilter(GL_NEAREST),
- mTilesS(1),
- mTilesT(1),
- mWrapS(GL_CLAMP),
- mWrapT(GL_CLAMP)
- {
- loadFromFile();
- }
-
-
- static void bindScriptConstants(Mf::Script& script)
- {
- script.push(GL_CLAMP); script.set("CLAMP");
- script.push(GL_REPEAT); script.set("REPEAT");
- script.push(GL_LINEAR); script.set("LINEAR");
- script.push(GL_NEAREST); script.set("NEAREST");
- script.push(GL_LINEAR_MIPMAP_LINEAR); script.set("LINEAR_MIPMAP_LINEAR");
- script.push(GL_LINEAR_MIPMAP_NEAREST); script.set("LINEAR_MIPMAP_NEAREST");
- script.push(GL_NEAREST_MIPMAP_LINEAR); script.set("NEAREST_MIPMAP_LINEAR");
- script.push(GL_NEAREST_MIPMAP_NEAREST); script.set("NEAREST_MIPMAP_NEAREST");
- }
-
- void loadFromFile()
- {
- Mf::Script script;
- std::string filePath = Tilemap::getPath(getName());
-
- script.importStandardLibraries();
- importLogFunctions(script);
- bindScriptConstants(script);
-
- if (script.doFile(filePath) != Mf::Script::SUCCESS)
- {
- std::string str;
- script[-1].get(str);
- Mf::logWarning(str);
- return; // TODO needs a better exit strategy
- }
-
- Mf::logInfo << "loading tiles from tilemap " << filePath << std::endl;
-
- Mf::Script::Slot globals = script.getGlobalTable();
- Mf::Script::Slot top = script[-1];
-
- globals.pushField("tiles_s");
- top.get(mTilesS);
-
- globals.pushField("tiles_t");
- top.get(mTilesT);
-
- globals.pushField("min_filter");
- top.get(mMinFilter);
-
- globals.pushField("mag_filter");
- top.get(mMagFilter);
-
- globals.pushField("wrap_s");
- top.get(mWrapS);
-
- globals.pushField("wrap_t");
- top.get(mWrapT);
- }
-
-
- bool getTileCoords(Tilemap::Index index, Mf::Scalar coords[8]) const
- {
- // make sure the index represents a real tile
- if (index >= mTilesS * mTilesT) return false;
-
- Mf::Scalar w = 1.0 / Mf::Scalar(mTilesS);
- Mf::Scalar h = 1.0 / Mf::Scalar(mTilesT);
-
- coords[0] = Mf::Scalar(index % mTilesS) * w;
- coords[1] = (Mf::Scalar(mTilesT - 1) -
- Mf::Scalar(index / mTilesS)) * 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;
- }
-
-
- GLuint mMagFilter;
- GLuint mMinFilter;
- unsigned mTilesS;
- unsigned mTilesT;
- GLuint mWrapS;
- GLuint mWrapT;
-};
-
-
-Tilemap::Tilemap(const std::string& name) :
- Texture(name),
- mImpl(Tilemap::Impl::getInstance(name))
-{
- setMinFilter(mImpl->mMinFilter);
- setMagFilter(mImpl->mMagFilter);
- setWrapS(mImpl->mWrapS);
- setWrapT(mImpl->mWrapT);
-}
-
-
-bool Tilemap::getTileCoords(Index index, Mf::Scalar coords[8]) const
-{
- // pass through
- return mImpl->getTileCoords(index, coords);
-}
-
-bool Tilemap::getTileCoords(Index index, Mf::Scalar coords[8],
- Orientation orientation) const
-{
- 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::getPath(const std::string& name)
-{
- return Resource::getPath("tilemaps/" + name + ".lua");
-}
-
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-