OpenTTD
tilematrix_type.hpp
Go to the documentation of this file.
1 /* $Id: tilematrix_type.hpp 23735 2012-01-03 20:26:05Z rubidium $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef TILEMATRIX_TYPE_HPP
13 #define TILEMATRIX_TYPE_HPP
14 
15 #include "core/alloc_func.hpp"
16 #include "tilearea_type.h"
17 
28 template <typename T, uint N>
29 class TileMatrix {
30 
35  {
36  uint old_left = TileX(this->area.tile) / N;
37  uint old_top = TileY(this->area.tile) / N;
38  uint old_w = this->area.w / N;
39  uint old_h = this->area.h / N;
40 
41  /* Add the square the tile is in to the tile area. We do this
42  * by adding top-left and bottom-right of the square. */
43  uint grid_x = (TileX(tile) / N) * N;
44  uint grid_y = (TileY(tile) / N) * N;
45  this->area.Add(TileXY(grid_x, grid_y));
46  this->area.Add(TileXY(grid_x + N - 1, grid_y + N - 1));
47 
48  /* Allocate new storage. */
49  T *new_data = CallocT<T>(this->area.w / N * this->area.h / N);
50 
51  if (old_w > 0) {
52  /* Copy old data if present. */
53  uint offs_x = old_left - TileX(this->area.tile) / N;
54  uint offs_y = old_top - TileY(this->area.tile) / N;
55 
56  for (uint row = 0; row < old_h; row++) {
57  MemCpyT(&new_data[(row + offs_y) * this->area.w / N + offs_x], &this->data[row * old_w], old_w);
58  }
59  }
60 
61  free(this->data);
62  this->data = new_data;
63  }
64 
65 public:
66  static const uint GRID = N;
67 
69 
70  T *data;
71 
72  TileMatrix() : area(INVALID_TILE, 0, 0), data(NULL) {}
73 
74  ~TileMatrix()
75  {
76  free(this->data);
77  }
78 
83  const TileArea& GetArea() const
84  {
85  return this->area;
86  }
87 
94  static TileArea GetAreaForTile(TileIndex tile, uint extend = 0)
95  {
96  uint tile_x = (TileX(tile) / N) * N;
97  uint tile_y = (TileY(tile) / N) * N;
98  uint w = N, h = N;
99 
100  w += min(extend * N, tile_x);
101  h += min(extend * N, tile_y);
102 
103  tile_x -= min(extend * N, tile_x);
104  tile_y -= min(extend * N, tile_y);
105 
106  w += min(extend * N, MapSizeX() - tile_x - w);
107  h += min(extend * N, MapSizeY() - tile_y - h);
108 
109  return TileArea(TileXY(tile_x, tile_y), w, h);
110  }
111 
116  void Add(TileIndex tile)
117  {
118  if (!this->area.Contains(tile)) {
119  this->AllocateStorage(tile);
120  }
121  }
122 
128  T *Get(TileIndex tile)
129  {
130  this->Add(tile);
131 
132  tile -= this->area.tile;
133  uint x = TileX(tile) / N;
134  uint y = TileY(tile) / N;
135 
136  return &this->data[y * this->area.w / N + x];
137  }
138 
140  inline T &operator[](TileIndex tile)
141  {
142  return *this->Get(tile);
143  }
144 };
145 
146 #endif /* TILEMATRIX_TYPE_HPP */