diff --git a/include/doorkeeper/components/pixelconv.hpp b/include/doorkeeper/components/pixelconv.hpp index 53d3811..2a3016e 100644 --- a/include/doorkeeper/components/pixelconv.hpp +++ b/include/doorkeeper/components/pixelconv.hpp @@ -31,8 +31,8 @@ namespace dk { PixelConv ( MapTypes parType, const coords& parTileSize ); - virtual coords to_pixel ( const coords& parFrom ) const = 0; - virtual coords pick_tile ( const coords& parPixelPoint ) const = 0; + virtual coords to_pixel ( const coords& parFrom, const coords& parOffset ) const = 0; + virtual coords pick_tile ( const coords& parPixelPoint, const coords& parOffset ) const = 0; MapTypes map_type ( void ) const; const coords& tile_size ( void ) const; @@ -51,8 +51,8 @@ namespace dk { explicit PixelConvSquare ( const coords& parTileSize ); virtual ~PixelConvSquare ( void ) noexcept = default; - virtual coords to_pixel ( const coords& parFrom ) const; - virtual coords pick_tile ( const coords& parPixelPoint ) const; + virtual coords to_pixel ( const coords& parFrom, const coords& parOffset ) const; + virtual coords pick_tile ( const coords& parPixelPoint, const coords& parOffset ) const; }; class PixelConvDiamond : public PixelConv<2> { @@ -64,8 +64,8 @@ namespace dk { PixelConvDiamond ( const coords& parTileSize, bool parStaggered, bool parFirstReentrant, const coords& parRatio ); virtual ~PixelConvDiamond ( void ) noexcept = default; - virtual coords to_pixel ( const coords& parFrom ) const; - virtual coords pick_tile ( const coords& parPixelPoint ) const; + virtual coords to_pixel ( const coords& parFrom, const coords& parOffset ) const; + virtual coords pick_tile ( const coords& parPixelPoint, const coords& parOffset ) const; protected: const coords m_ratio; @@ -81,8 +81,8 @@ namespace dk { PixelConvHex ( const coords& parTileSize, bool parFirstReentrant ); virtual ~PixelConvHex ( void ) noexcept = default; - virtual coords to_pixel ( const coords& parFrom ) const; - virtual coords pick_tile ( const coords& parPixelPoint ) const; + virtual coords to_pixel ( const coords& parFrom, const coords& parOffset ) const; + virtual coords pick_tile ( const coords& parPixelPoint, const coords& parOffset ) const; private: const CoordinateScalarType m_first_reentr; diff --git a/include/doorkeeper/components/tilecoords.hpp b/include/doorkeeper/components/tilecoords.hpp index 6dbc2d4..37ed57b 100644 --- a/include/doorkeeper/components/tilecoords.hpp +++ b/include/doorkeeper/components/tilecoords.hpp @@ -51,6 +51,7 @@ namespace dk { const CoordinateScalarType& operator[] ( int parIndex ) const; CoordinateScalarType& operator[] ( int parIndex ); + void set_position ( const coords& parPos ); const coords& position ( void ) const; const coords& upper ( void ) const; diff --git a/include/doorkeeper/components/tileiterator.hpp b/include/doorkeeper/components/tileiterator.hpp index 98af210..030289e 100644 --- a/include/doorkeeper/components/tileiterator.hpp +++ b/include/doorkeeper/components/tileiterator.hpp @@ -29,6 +29,7 @@ #include #include #include +#include namespace dk { template @@ -50,6 +51,12 @@ namespace dk { }; } //namespace implem + //TODO: replace with a custom iterator rewrite, not using iterator_facade. + //The idea is to have operator* return a Tile<>, which is heavy to + //construct but it's unlikely to be called very often, and then have + //operator-> return a TileHandle<> object that only wraps a pointer to + //the iterator's current state, so it's much more lightweight and it's not + //expected to be kept around by client code. template ::type> class TileIterator : public boost::iterator_facade, T, boost::random_access_traversal_tag, Tile, CoordinateDistType> { friend class boost::iterator_core_access; diff --git a/include/doorkeeper/components/viewport.hpp b/include/doorkeeper/components/viewport.hpp index 70e3760..f2cc5a4 100644 --- a/include/doorkeeper/components/viewport.hpp +++ b/include/doorkeeper/components/viewport.hpp @@ -21,6 +21,7 @@ #include "doorkeeper/primitivetypes.hpp" #include "doorkeeper/components/tileiterator.hpp" #include "doorkeeper/components/layer.hpp" +#include "doorkeeper/components/tilecoords.hpp" #include namespace dk { @@ -42,10 +43,8 @@ namespace dk { Viewport& operator= ( const Viewport& ) = default; - void setSize ( const coords& parSize ); void setFrom ( const coords& parFrom ); - void setFromSize ( const coords& parFrom, const coords& parSize ); - const coords& count ( void ) const { return m_size; } + coords size ( void ) const; template typename Layer::iterator begin ( Layer& parLayer ) const; @@ -61,8 +60,7 @@ namespace dk { typename Layer::const_iterator cend ( const Layer& parLayer ) const; private: - coords m_size; - coords m_position; + TileCoords m_view; Tyler& m_tyler; }; } //namespace dk diff --git a/include/doorkeeper/implem/pixelconv.inl b/include/doorkeeper/implem/pixelconv.inl index 1fa06ea..3af5173 100644 --- a/include/doorkeeper/implem/pixelconv.inl +++ b/include/doorkeeper/implem/pixelconv.inl @@ -40,12 +40,12 @@ namespace dk { } template - auto PixelConvSquare::to_pixel (const coords& parFrom) const -> coords { - return parFrom * this->tile_size(); + auto PixelConvSquare::to_pixel (const coords& parFrom, const coords& parOffset) const -> coords { + return (parFrom - parOffset) * this->tile_size(); } template - auto PixelConvSquare::pick_tile (const coords& parPixelPoint) const -> coords { - return parPixelPoint / this->tile_size(); + auto PixelConvSquare::pick_tile (const coords& parPixelPoint, const coords& parOffset) const -> coords { + return parPixelPoint / this->tile_size() + parOffset; } } //namespace dk diff --git a/include/doorkeeper/implem/tile.inl b/include/doorkeeper/implem/tile.inl index 54dcbfa..38876a8 100644 --- a/include/doorkeeper/implem/tile.inl +++ b/include/doorkeeper/implem/tile.inl @@ -49,6 +49,6 @@ namespace dk { template auto Tile::screen_position() const -> coords { - return m_pixconv->to_pixel(m_position.position()); + return m_pixconv->to_pixel(m_position.position(), m_block_offs); } } //namespace dk diff --git a/include/doorkeeper/implem/tilecoords.inl b/include/doorkeeper/implem/tilecoords.inl index 5d6e60a..3c57eb6 100644 --- a/include/doorkeeper/implem/tilecoords.inl +++ b/include/doorkeeper/implem/tilecoords.inl @@ -242,4 +242,10 @@ namespace dk { auto TileCoords::upper() const -> const coords& { return m_size; } + + template + void TileCoords::set_position (const coords& parPos) { + DK_ASSERT(parPos <= m_size); + m_pos = parPos; + } } //namespace dk diff --git a/include/doorkeeper/implem/tileiterator.inl b/include/doorkeeper/implem/tileiterator.inl index 6477c52..6dc01f4 100644 --- a/include/doorkeeper/implem/tileiterator.inl +++ b/include/doorkeeper/implem/tileiterator.inl @@ -47,8 +47,19 @@ namespace dk { } template - void TileIterator::advance (size_t /*parAdvance*/) { - //TODO: implement + void TileIterator::advance (size_t parAdvance) { + constexpr auto M = std::numeric_limits::max(); + typedef typename std::conditional< + (static_cast::type>(std::numeric_limits::max()) > static_cast::type>(M)), + size_t, + CoordinateScalarType + >::type LargestType; + + while (parAdvance) { + const auto inc = std::min(static_cast(parAdvance), static_cast(M)); + m_tile_range += inc; + parAdvance -= static_cast(inc); + } } template diff --git a/include/doorkeeper/implem/viewport.inl b/include/doorkeeper/implem/viewport.inl index 9b21dbd..7e5a6a6 100644 --- a/include/doorkeeper/implem/viewport.inl +++ b/include/doorkeeper/implem/viewport.inl @@ -24,20 +24,19 @@ namespace dk { template Viewport::Viewport (Tyler& parTyler, const coords& parSize, const coords& parPos) : - m_size(parSize), - m_position(parPos), + m_view(parPos, parSize - 1), m_tyler(parTyler) { - DK_ASSERT(parPos <= parPos + parSize); + DK_ASSERT(parPos < parPos + parSize); //parSize > 0 DK_ASSERT(parSize + parPos <= parTyler.map_size()); - m_tyler.preload(m_position, m_position + m_size); + m_tyler.preload(m_view.position(), m_view.position() + this->size()); } template template typename Layer::iterator Viewport::begin (Layer& parLayer) const { typedef typename Layer::iterator IterType; - return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_position, m_tyler.map_size() - 1); + return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_view.position(), m_tyler.map_size() - 1); } template @@ -63,7 +62,7 @@ namespace dk { template typename Layer::const_iterator Viewport::cbegin (const Layer& parLayer) const { typedef typename Layer::const_iterator IterType; - return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_position, m_tyler.map_size() - 1); + return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), m_view.position(), m_tyler.map_size() - 1); } template @@ -73,28 +72,15 @@ namespace dk { return IterType(&parLayer.m_tiles, parLayer.m_tilemap->pixel_conv(), make_past_end_coords(m_tyler.map_size() - 1), make_past_end_coords(m_tyler.map_size() - 1)); } - template - void Viewport::setSize (const coords& parSize) { - DK_ASSERT(m_position <= m_position + parSize); - DK_ASSERT(parSize + m_position <= m_tyler.map_size()); - m_size = parSize; - m_tyler.preload(m_position, m_position + m_size); - } - template void Viewport::setFrom (const coords& parFrom) { - DK_ASSERT(parFrom <= parFrom + m_size); - DK_ASSERT(m_size + parFrom <= m_tyler.map_size()); - m_position = parFrom; - m_tyler.preload(m_position, m_position + m_size); + DK_ASSERT(this->size() + parFrom < m_tyler.map_size()); + m_view.set_position(parFrom); + m_tyler.preload(m_view.position(), m_view.position() + this->size()); } template - void Viewport::setFromSize (const coords& parFrom, const coords& parSize) { - DK_ASSERT(parFrom <= parFrom + parSize); - DK_ASSERT(parSize + parFrom <= m_tyler.map_size()); - m_position = parFrom; - m_size = parSize; - m_tyler.preload(m_position, m_position + m_size); + typename Viewport::coords Viewport::size() const { + return (m_view.upper() + 1); } } //namespace dk diff --git a/src/pixelconv.cpp b/src/pixelconv.cpp index 80fbe5d..db55826 100644 --- a/src/pixelconv.cpp +++ b/src/pixelconv.cpp @@ -35,7 +35,7 @@ namespace dk { DK_ASSERT(parRatio > 0); } - auto PixelConvDiamond::to_pixel (const coords& parFrom) const -> coords { + auto PixelConvDiamond::to_pixel (const coords& parFrom, const coords& parOffset) const -> coords { if (m_staggered) { const auto from(parFrom); const CoordinateScalarType xoffs = m_first_reentr xor (from.y() bitand 1); @@ -49,7 +49,7 @@ namespace dk { } } - auto PixelConvDiamond::pick_tile (const coords& parPixelPoint) const -> coords { + auto PixelConvDiamond::pick_tile (const coords& parPixelPoint, const coords& parOffset) const -> coords { DK_ASSERT(false); //not implemented return coords(0); } @@ -60,12 +60,12 @@ namespace dk { { } - auto PixelConvHex::to_pixel (const coords& parFrom) const -> coords { + auto PixelConvHex::to_pixel (const coords& parFrom, const coords& parOffset) const -> coords { DK_ASSERT(false); //not implemented return coords(0); } - auto PixelConvHex::pick_tile (const coords& parPixelPoint) const -> coords { + auto PixelConvHex::pick_tile (const coords& parPixelPoint, const coords& parOffset) const -> coords { DK_ASSERT(false); //not implemented return coords(0); } diff --git a/test/main.cpp b/test/main.cpp index 436a531..cd359ab 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -38,7 +38,7 @@ namespace { inline dk::Vector<2> get_diamond_coordinates (const dk::TileIterator& parIterator, const dk::Vector<2>& parSize) { dk::PixelConvDiamond pconv(parSize, true, false); - return pconv.to_pixel(parIterator->block_position()); + return pconv.to_pixel(parIterator->block_position(), dk::Vector<2>(0)); } } //unnamed namespace @@ -113,7 +113,7 @@ int main() { //Main loop bool running = true; int y = 0; - dk::Viewport<2> viewport(tiler, coords2(10, 8), coords2(0)); + dk::Viewport<2> viewport(tiler, coords2(10, 6), coords2(0)); coords2 tile_size; SDL_QueryTexture(tile_0.get(), nullptr, nullptr, &tile_size.x(), &tile_size.y()); do { @@ -168,13 +168,13 @@ namespace { typedef dkh::AsciiMapSource::coords coords; parLayerInfo.path = parPath; - parLayerInfo.device.reset(new dkh::AsciiMapSource(parLayerInfo.path, coords(10, 8), dk::MapType_IsometricStaggered, coords(64, 64))); + parLayerInfo.device.reset(new dkh::AsciiMapSource(parLayerInfo.path, coords(10, 6), dk::MapType_IsometricStaggered, coords(64, 64))); parLayerInfo.layer = &parTiler.push_layer(parLayerInfo.device.get(), 0); } void printViewport (const dk::Viewport<2>& parView, const dk::Layer& parLayer) { int col = 0; - const auto tilecount = parView.count(); + const auto tilecount = parView.size(); for (auto itTile = parView.begin(parLayer), itTileEND = parView.end(parLayer); itTile != itTileEND; ++itTile) { std::cout << itTile->data(); ++col; diff --git a/test/unit/asciimapsource.cpp b/test/unit/asciimapsource.cpp index 4ce533a..8783ccf 100644 --- a/test/unit/asciimapsource.cpp +++ b/test/unit/asciimapsource.cpp @@ -78,7 +78,7 @@ TEST_F(asciimapsource, coordinates) { //Check isometric coordinates { const coords2 expected_coords(tsize * itTile->block_position()); - const auto returned_coords(iso_conv.to_pixel(itTile->block_position())); + const auto returned_coords(iso_conv.to_pixel(itTile->block_position(), coords2(0))); EXPECT_EQ(expected_coords, returned_coords); EXPECT_EQ(expected_coords, itTile->screen_position()); } @@ -90,7 +90,7 @@ TEST_F(asciimapsource, coordinates) { xoffs + itTile->block_position().x() * tsize.x(), itTile->block_position().y() * tsize.y() ); - const auto returned_coords(diamond_conv.to_pixel(itTile->block_position())); + const auto returned_coords(diamond_conv.to_pixel(itTile->block_position(), coords2(0))); EXPECT_EQ(expected_coords, returned_coords); } @@ -101,7 +101,7 @@ TEST_F(asciimapsource, coordinates) { xoffs + itTile->block_position().x() * tsize.x(), itTile->block_position().y() * tsize.y() ); - const auto returned_coords(diamond_conv2.to_pixel(itTile->block_position())); + const auto returned_coords(diamond_conv2.to_pixel(itTile->block_position(), coords2(0))); EXPECT_EQ(expected_coords, returned_coords); } }