/* Copyright 2015, Michele Santullo * This file is part of DoorKeeper. * * DoorKeeper is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * DoorKeeper is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with DoorKeeper. If not, see . */ namespace dk { template TileInfo::TileInfo (const LayerBase& parLayer) : tile_size(parLayer.tile_size()), map_size(parLayer.map_size()) { } template bool TileInfo::operator== (const TileInfo& parOther) const { return tile_size == parOther.tile_size and map_size == parOther.map_size; } template Viewport::Viewport (Tyler& parTyler, const TileInfo* parTileInfo) : m_view(parTileInfo->map_size - 1), m_pixel_offset(0), m_tyler(&parTyler), m_tile_info(parTileInfo) { DK_ASSERT(parTileInfo); DK_ASSERT(m_tyler); } template Viewport::Viewport (Tyler& parTyler, const TileInfo* parTileInfo, const coords& parPos) : m_view(parPos, parTileInfo->map_size - 1), m_pixel_offset(0), m_tyler(&parTyler), m_tile_info(parTileInfo) { DK_ASSERT(parTileInfo); DK_ASSERT(parPos < parPos + m_tile_info->map_size); //parSize > 0 DK_ASSERT(m_tile_info->map_size + parPos <= m_tile_info->map_size); DK_ASSERT(m_tyler); m_tyler->preload(m_view.position(), m_view.position() + this->size()); } template void Viewport::setFrom (const coords& parFrom) { DK_ASSERT(this->size() + parFrom <= m_tile_info->map_size); m_view.set_position(parFrom); m_tyler->preload(m_view.position(), m_view.position() + this->size()); } template typename Viewport::coords Viewport::size() const { return (m_view.upper() + 1); } template Viewport& Viewport::operator+= (const coords_f& parValue) { m_pixel_offset += parValue; clip_pixel_offset(); return *this; } template Viewport& Viewport::operator-= (const coords_f& parValue) { m_pixel_offset -= parValue; clip_pixel_offset(); return *this; } template void Viewport::clip_pixel_offset() { const auto& tile_size = m_tile_info->tile_size; for (uint32_t z = 0; z < D; ++z) { auto offs = static_cast(m_pixel_offset[z]); if (std::abs(offs) >= tile_size[z]) { auto curr_tile_size_f = static_cast(tile_size[z]); if (offs < 0) { do { offs += tile_size[z]; m_pixel_offset[z] += curr_tile_size_f; --m_view; } while(offs >= tile_size[z]); } else { DK_ASSERT(offs > 0); do { offs -= tile_size[z]; m_pixel_offset[z] -= curr_tile_size_f; ++m_view; } while(offs >= tile_size[z]); } } } } template auto Viewport::pixel_offset() const -> coords { return static_cast(m_pixel_offset); } template auto Viewport::upper() const -> const coords& { return m_view.upper(); } template auto Viewport::block_position() const -> const coords& { return m_view.position(); } } //namespace dk