X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FTilemap.cc;fp=src%2FTilemap.cc;h=655475222c45e89754b1e37a39389fce4c84348a;hp=0000000000000000000000000000000000000000;hb=23d8f7a5fbd1eca7f46f2342c20ac5e28ae0128a;hpb=fa9438c66ae0154e6d9ad196e0fb39649d359da4 diff --git a/src/Tilemap.cc b/src/Tilemap.cc new file mode 100644 index 0000000..6554752 --- /dev/null +++ b/src/Tilemap.cc @@ -0,0 +1,189 @@ + +/******************************************************************************* + + 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 +#include +#include + +#include "Tilemap.hh" + + +struct Tilemap::Impl : public Mf::Mippleton +{ + Impl(const std::string& name) : + Mf::Mippleton(name), + magFilter_(GL_NEAREST), + minFilter_(GL_NEAREST), + nTilesS_(1), + nTilesT_(1), + wrapS_(GL_CLAMP), + wrapT_(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(); + importLogScript(script); + bindScriptConstants(script); + + if (script.doFile(filePath) != Mf::Script::SUCCESS) + { + std::string str; + script[-1].get(str); + Mf::logScript("%s", str.c_str()); + return; // TODO needs a better exit strategy + } + + Mf::logInfo("loading tiles from tilemap %s", filePath.c_str()); + + Mf::Script::Value globals = script.getGlobalTable(); + Mf::Script::Value top = script[-1]; + + globals.pushField("tiles_s"); + top.get(nTilesS_); + + globals.pushField("tiles_t"); + top.get(nTilesT_); + + globals.pushField("min_filter"); + top.get(minFilter_); + + globals.pushField("mag_filter"); + top.get(magFilter_); + + globals.pushField("wrap_s"); + top.get(wrapS_); + + globals.pushField("wrap_t"); + top.get(wrapT_); + } + + + bool getTileCoords(Tilemap::Index index, Mf::Scalar coords[8]) const + { + // make sure the index represents a real tile + if (index >= nTilesS_ * nTilesT_) return false; + + Mf::Scalar w = 1.0 / Mf::Scalar(nTilesS_); + Mf::Scalar h = 1.0 / Mf::Scalar(nTilesT_); + + coords[0] = Mf::Scalar(index % nTilesS_) * w; + coords[1] = (Mf::Scalar(nTilesT_ - 1) - + Mf::Scalar(index / nTilesS_)) * 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 magFilter_; + GLuint minFilter_; + unsigned nTilesS_; + unsigned nTilesT_; + GLuint wrapS_; + GLuint wrapT_; +}; + + +Tilemap::Tilemap(const std::string& name) : + Texture(name), + impl_(Tilemap::Impl::getInstance(name)) +{ + setMinFilter(impl_->minFilter_); + setMagFilter(impl_->magFilter_); + setWrapS(impl_->wrapS_); + setWrapT(impl_->wrapT_); +} + + +bool Tilemap::getTileCoords(Index index, Mf::Scalar coords[8]) const +{ + // pass through + return impl_->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: *************************************************/ +