tilearea_type.h

Go to the documentation of this file.
00001 /* $Id: tilearea_type.h 26289 2014-02-02 14:53:26Z fonsinchen $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #ifndef TILEAREA_TYPE_H
00013 #define TILEAREA_TYPE_H
00014 
00015 #include "map_func.h"
00016 
00018 struct OrthogonalTileArea {
00019   TileIndex tile; 
00020   uint16 w;       
00021   uint16 h;       
00022 
00029   OrthogonalTileArea(TileIndex tile = INVALID_TILE, uint8 w = 0, uint8 h = 0) : tile(tile), w(w), h(h)
00030   {
00031   }
00032 
00033   OrthogonalTileArea(TileIndex start, TileIndex end);
00034 
00035   void Add(TileIndex to_add);
00036 
00040   void Clear()
00041   {
00042     this->tile = INVALID_TILE;
00043     this->w    = 0;
00044     this->h    = 0;
00045   }
00046 
00047   bool Intersects(const OrthogonalTileArea &ta) const;
00048 
00049   bool Contains(TileIndex tile) const;
00050 
00051   void ClampToMap();
00052 
00057   TileIndex GetCenterTile() const
00058   {
00059     return TILE_ADDXY(this->tile, this->w / 2, this->h / 2);
00060   }
00061 };
00062 
00064 struct DiagonalTileArea {
00065 
00066   TileIndex tile; 
00067   int16 a;        
00068   int16 b;        
00069 
00076   DiagonalTileArea(TileIndex tile = INVALID_TILE, int8 a = 0, int8 b = 0) : tile(tile), a(a), b(b)
00077   {
00078   }
00079 
00080   DiagonalTileArea(TileIndex start, TileIndex end);
00081 
00085   void Clear()
00086   {
00087     this->tile = INVALID_TILE;
00088     this->a    = 0;
00089     this->b    = 0;
00090   }
00091 
00092   bool Contains(TileIndex tile) const;
00093 };
00094 
00096 typedef OrthogonalTileArea TileArea;
00097 
00099 class TileIterator {
00100 protected:
00101   TileIndex tile; 
00102 
00107   TileIterator(TileIndex tile = INVALID_TILE) : tile(tile)
00108   {
00109   }
00110 
00111 public:
00113   virtual ~TileIterator()
00114   {
00115   }
00116 
00121   inline operator TileIndex () const
00122   {
00123     return this->tile;
00124   }
00125 
00129   virtual TileIterator& operator ++() = 0;
00130 
00134   virtual TileIterator *Clone() const = 0;
00135 };
00136 
00138 class OrthogonalTileIterator : public TileIterator {
00139 private:
00140   int w;          
00141   int x;          
00142   int y;          
00143 
00144 public:
00149   OrthogonalTileIterator(const OrthogonalTileArea &ta) : TileIterator(ta.w == 0 || ta.h == 0 ? INVALID_TILE : ta.tile), w(ta.w), x(ta.w), y(ta.h)
00150   {
00151   }
00152 
00158   OrthogonalTileIterator(TileIndex corner1, TileIndex corner2)
00159   {
00160     *this = OrthogonalTileIterator(OrthogonalTileArea(corner1, corner2));
00161   }
00162 
00166   inline TileIterator& operator ++()
00167   {
00168     assert(this->tile != INVALID_TILE);
00169 
00170     if (--this->x > 0) {
00171       this->tile++;
00172     } else if (--this->y > 0) {
00173       this->x = this->w;
00174       this->tile += TileDiffXY(1, 1) - this->w;
00175     } else {
00176       this->tile = INVALID_TILE;
00177     }
00178     return *this;
00179   }
00180 
00181   virtual TileIterator *Clone() const
00182   {
00183     return new OrthogonalTileIterator(*this);
00184   }
00185 };
00186 
00188 class DiagonalTileIterator : public TileIterator {
00189 private:
00190   uint base_x; 
00191   uint base_y; 
00192   int a_cur;   
00193   int b_cur;   
00194   int a_max;   
00195   int b_max;   
00196 
00197 public:
00198 
00203   DiagonalTileIterator(const DiagonalTileArea &ta) :
00204     TileIterator(ta.tile), base_x(TileX(ta.tile)), base_y(TileY(ta.tile)), a_cur(0), b_cur(0), a_max(ta.a), b_max(ta.b)
00205   {
00206   }
00207 
00213   DiagonalTileIterator(TileIndex corner1, TileIndex corner2)
00214   {
00215     *this = DiagonalTileIterator(DiagonalTileArea(corner1, corner2));
00216   }
00217 
00218   TileIterator& operator ++();
00219 
00220   virtual TileIterator *Clone() const
00221   {
00222     return new DiagonalTileIterator(*this);
00223   }
00224 };
00225 
00232 #define TILE_AREA_LOOP(var, ta) for (OrthogonalTileIterator var(ta); var != INVALID_TILE; ++var)
00233 
00234 #endif /* TILEAREA_TYPE_H */