108 lines
3.2 KiB
C++
108 lines
3.2 KiB
C++
/*
|
|
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
|
|
|
This file is part of MyCurry.
|
|
|
|
MyCurry 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.
|
|
|
|
MyCurry 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 MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "tileiterator.hpp"
|
|
#include "worldviewport.hpp"
|
|
#include "worldgrid.hpp"
|
|
#include "compatibility.h"
|
|
#include <cassert>
|
|
#include <ciso646>
|
|
|
|
namespace curry {
|
|
namespace {
|
|
const uint16_t g_invalid_index = 0xFFFF;
|
|
vec2i first_col_starting_pixel (const vec2i& parViewportPos, const vec2i& parTileSize) a_pure;
|
|
|
|
vec2i first_col_starting_pixel (const vec2i& parViewportPos, const vec2i& parTileSize) {
|
|
const auto& pos = parViewportPos;
|
|
const auto& ts = parTileSize;
|
|
|
|
return vec2i(
|
|
(pos.x() > 0 ? -pos.x() % ts.x() : -pos.x()),
|
|
(pos.y() > 0 ? -pos.y() % ts.y() : -pos.y())
|
|
);
|
|
}
|
|
} //unnamed namespace
|
|
|
|
TileIterator::TileIterator (WorldViewport* parViewport, bool parEnd) :
|
|
m_viewport(parViewport),
|
|
m_index(parEnd ? g_invalid_index : 0)
|
|
{
|
|
assert(m_viewport);
|
|
m_pixel_pos = first_col_starting_pixel(
|
|
vector_cast<vec2i>(m_viewport->position()),
|
|
m_viewport->world()->tile_size()
|
|
);
|
|
}
|
|
|
|
void TileIterator::increment() {
|
|
assert(m_index != vec2i(g_invalid_index));
|
|
|
|
const WorldGrid& world = *m_viewport->world();
|
|
vec2i tile_size(world.tile_size());
|
|
auto first_tile_pos = first_col_starting_pixel(
|
|
vector_cast<vec2i>(m_viewport->position()),
|
|
m_viewport->world()->tile_size()
|
|
);
|
|
vec2i pos(tile_size * vector_cast<vec2i>(m_index) + first_tile_pos);
|
|
|
|
assert(pos.x() > -tile_size.x() and pos.x() < m_viewport->size().x());
|
|
assert(pos.y() > -tile_size.y() and pos.y() < m_viewport->size().y());
|
|
|
|
const float right_border = std::min(
|
|
m_viewport->size().x(),
|
|
static_cast<float>(world_size_pixel(world).x()) - m_viewport->position().x()
|
|
);
|
|
const float bottom_border = std::min(
|
|
m_viewport->size().y(),
|
|
static_cast<float>(world_size_pixel(world).y()) - m_viewport->position().y()
|
|
);
|
|
|
|
if (static_cast<float>(pos.x() + tile_size.x()) < right_border) {
|
|
++m_index.x();
|
|
}
|
|
else if (static_cast<float>(pos.y() + tile_size.y()) < bottom_border) {
|
|
m_index.x() = 0;
|
|
++m_index.y();
|
|
m_pixel_pos.x() = first_tile_pos.x();
|
|
m_pixel_pos.y() += tile_size.y();
|
|
}
|
|
else {
|
|
m_index = vec2us(g_invalid_index);
|
|
}
|
|
//std::cout << "got index " << m_index << " pixel " <<
|
|
//m_index * tile_size - m_viewport->position() << '\n';
|
|
m_pixel_pos = tile_size * vector_cast<vec2i>(m_index) + first_tile_pos;
|
|
}
|
|
|
|
ScreenTile TileIterator::dereference() const {
|
|
auto index = vector_cast<vec2us>(m_index);
|
|
return ScreenTile {
|
|
m_viewport->tile(index),
|
|
m_pixel_pos
|
|
};
|
|
}
|
|
|
|
bool TileIterator::equal (const TileIterator& parOther) const {
|
|
return m_viewport == parOther.m_viewport and
|
|
m_index == parOther.m_index
|
|
;
|
|
}
|
|
} //namespace curry
|