1 /* 2 * This file is part of OpenTTD. 3 * OpenTTD 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, version 2. 4 * OpenTTD 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. 5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. 6 */ 7 8 /** @file bitmap_type.hpp Bitmap functions. */ 9 10 #ifndef BITMAP_TYPE_HPP 11 #define BITMAP_TYPE_HPP 12 13 #include <vector> 14 15 /** Represents a tile area containing containing individually set tiles. 16 * Each tile must be contained within the preallocated area. 17 * A std::vector<bool> is used to mark which tiles are contained. 18 */ 19 class BitmapTileArea : public TileArea { 20 protected: 21 std::vector<bool> data; 22 Index(uint x,uint y)23 inline uint Index(uint x, uint y) const { return y * this->w + x; } 24 Index(TileIndex tile)25 inline uint Index(TileIndex tile) const { return Index(TileX(tile) - TileX(this->tile), TileY(tile) - TileY(this->tile)); } 26 27 public: BitmapTileArea()28 BitmapTileArea() 29 { 30 this->tile = INVALID_TILE; 31 this->w = 0; 32 this->h = 0; 33 } 34 BitmapTileArea(const TileArea & ta)35 BitmapTileArea(const TileArea &ta) 36 { 37 this->tile = ta.tile; 38 this->w = ta.w; 39 this->h = ta.h; 40 this->data.resize(Index(this->w, this->h)); 41 } 42 43 /** 44 * Reset and clear the BitmapTileArea. 45 */ Reset()46 void Reset() 47 { 48 this->tile = INVALID_TILE; 49 this->w = 0; 50 this->h = 0; 51 this->data.clear(); 52 } 53 54 /** 55 * Initialize the BitmapTileArea with the specified Rect. 56 * @param rect Rect to use. 57 */ Initialize(const Rect & r)58 void Initialize(const Rect &r) 59 { 60 this->tile = TileXY(r.left, r.top); 61 this->w = r.right - r.left + 1; 62 this->h = r.bottom - r.top + 1; 63 this->data.clear(); 64 this->data.resize(Index(w, h)); 65 } 66 Initialize(const TileArea & ta)67 void Initialize(const TileArea &ta) 68 { 69 this->tile = ta.tile; 70 this->w = ta.w; 71 this->h = ta.h; 72 this->data.clear(); 73 this->data.resize(Index(w, h)); 74 } 75 76 /** 77 * Add a tile as part of the tile area. 78 * @param tile Tile to add. 79 */ SetTile(TileIndex tile)80 inline void SetTile(TileIndex tile) 81 { 82 assert(this->Contains(tile)); 83 this->data[Index(tile)] = true; 84 } 85 86 /** 87 * Clear a tile from the tile area. 88 * @param tile Tile to clear 89 */ ClrTile(TileIndex tile)90 inline void ClrTile(TileIndex tile) 91 { 92 assert(this->Contains(tile)); 93 this->data[Index(tile)] = false; 94 } 95 96 /** 97 * Test if a tile is part of the tile area. 98 * @param tile Tile to check 99 */ HasTile(TileIndex tile)100 inline bool HasTile(TileIndex tile) const 101 { 102 return this->Contains(tile) && this->data[Index(tile)]; 103 } 104 }; 105 106 /** Iterator to iterate over all tiles belonging to a bitmaptilearea. */ 107 class BitmapTileIterator : public OrthogonalTileIterator { 108 protected: 109 const BitmapTileArea *bitmap; 110 public: 111 /** 112 * Construct the iterator. 113 * @param bitmap BitmapTileArea to iterate. 114 */ BitmapTileIterator(const BitmapTileArea & bitmap)115 BitmapTileIterator(const BitmapTileArea &bitmap) : OrthogonalTileIterator(bitmap), bitmap(&bitmap) 116 { 117 if (!this->bitmap->HasTile(TileIndex(this->tile))) ++(*this); 118 } 119 120 inline TileIterator& operator ++() 121 { 122 (*this).OrthogonalTileIterator::operator++(); 123 while (this->tile != INVALID_TILE && !this->bitmap->HasTile(TileIndex(this->tile))) { 124 (*this).OrthogonalTileIterator::operator++(); 125 } 126 return *this; 127 } 128 Clone()129 virtual TileIterator *Clone() const 130 { 131 return new BitmapTileIterator(*this); 132 } 133 }; 134 135 #endif /* BITMAP_TYPE_HPP */ 136