OpenTTD: src/tilematrix_type.hpp Source File

OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

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
34 void AllocateStorage(TileIndex tile)
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
68 TileArea area;
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 */