# tilematrix_type.hpp

Go to the documentation of this file.

    00001 /* $Id: tilematrix_type.hpp 23735 2012-01-03 20:26:05Z rubidium $ */
    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 TILEMATRIX_TYPE_HPP
    00013 #define TILEMATRIX_TYPE_HPP
    00014
    00015 #include "core/alloc_func.hpp"
    00016 #include "tilearea_type.h"
    00017
    00028 template <typename T, uint N>
    00029 class TileMatrix {
    00030
    00034   void AllocateStorage(TileIndex tile)
    00035   {
    00036     uint old_left = TileX(this->area.tile) / N;
    00037     uint old_top  = TileY(this->area.tile) / N;
    00038     uint old_w    = this->area.w / N;
    00039     uint old_h    = this->area.h / N;
    00040
    00041     /* Add the square the tile is in to the tile area. We do this
    00042      * by adding top-left and bottom-right of the square. */
    00043     uint grid_x = (TileX(tile) / N) * N;
    00044     uint grid_y = (TileY(tile) / N) * N;
    00045     this->area.Add(TileXY(grid_x, grid_y));
    00046     this->area.Add(TileXY(grid_x + N - 1, grid_y + N - 1));
    00047
    00048     /* Allocate new storage. */
    00049     T *new_data = CallocT<T>(this->area.w / N * this->area.h / N);
    00050
    00051     if (old_w > 0) {
    00052       /* Copy old data if present. */
    00053       uint offs_x = old_left - TileX(this->area.tile) / N;
    00054       uint offs_y = old_top  - TileY(this->area.tile) / N;
    00055
    00056       for (uint row = 0; row < old_h; row++) {
    00057         MemCpyT(&new_data[(row + offs_y) * this->area.w / N + offs_x], &this->data[row * old_w], old_w);
    00058       }
    00059     }
    00060
    00061     free(this->data);
    00062     this->data = new_data;
    00063   }
    00064
    00065 public:
    00066   static const uint GRID = N;
    00067
    00068   TileArea area;
    00069
    00070   T *data;
    00071
    00072   TileMatrix() : area(INVALID_TILE, 0, 0), data(NULL) {}
    00073
    00074   ~TileMatrix()
    00075   {
    00076     free(this->data);
    00077   }
    00078
    00083   const TileArea& GetArea() const
    00084   {
    00085     return this->area;
    00086   }
    00087
    00094   static TileArea GetAreaForTile(TileIndex tile, uint extend = 0)
    00095   {
    00096     uint tile_x = (TileX(tile) / N) * N;
    00097     uint tile_y = (TileY(tile) / N) * N;
    00098     uint w = N, h = N;
    00099
    00100     w += min(extend * N, tile_x);
    00101     h += min(extend * N, tile_y);
    00102
    00103     tile_x -= min(extend * N, tile_x);
    00104     tile_y -= min(extend * N, tile_y);
    00105
    00106     w += min(extend * N, MapSizeX() - tile_x - w);
    00107     h += min(extend * N, MapSizeY() - tile_y - h);
    00108
    00109     return TileArea(TileXY(tile_x, tile_y), w, h);
    00110   }
    00111
    00116   void Add(TileIndex tile)
    00117   {
    00118     if (!this->area.Contains(tile)) {
    00119       this->AllocateStorage(tile);
    00120     }
    00121   }
    00122
    00128   T *Get(TileIndex tile)
    00129   {
    00130     this->Add(tile);
    00131
    00132     tile -= this->area.tile;
    00133     uint x = TileX(tile) / N;
    00134     uint y = TileY(tile) / N;
    00135
    00136     return &this->data[y * this->area.w / N + x];
    00137   }
    00138
    00140   inline T &operator[](TileIndex tile)
    00141   {
    00142     return *this->Get(tile);
    00143   }
    00144 };
    00145
    00146 #endif /* TILEMATRIX_TYPE_HPP */