Files
@ r18753:19e74c935c2d
Branch filter:
Location: cpp/openttd-patchpack/source/src/tilematrix_type.hpp
r18753:19e74c935c2d
3.8 KiB
text/x-c++hdr
(svn r23611) -Add: run the begin of the script already while generating, and don't sleep on DoCommand while doing so
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | /* $Id$ */
/*
* This file is part of OpenTTD.
* 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.
* 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.
* 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/>.
*/
/** @file tilematrix_type.hpp */
#ifndef TILEMATRIX_TYPE_HPP
#define TILEMATRIX_TYPE_HPP
#include "core/mem_func.hpp"
#include "tilearea_type.h"
/**
* A simple matrix that stores one value per N*N square of the map.
* Storage is only allocated for the part of the map that has values
* assigned.
*
* @note No constructor is called for newly allocated values, you
* have to do this yourself if needed.
* @tparam T The type of the stored items.
* @tparam N Grid size.
*/
template <typename T, uint N>
class TileMatrix {
/** Allocates space for a new tile in the matrix.
* @param tile Tile to add.
*/
void AllocateStorage(TileIndex tile)
{
uint old_left = TileX(this->area.tile) / N;
uint old_top = TileY(this->area.tile) / N;
uint old_w = this->area.w / N;
uint old_h = this->area.h / N;
/* Add the square the tile is in to the tile area. We do this
* by adding top-left and bottom-right of the square. */
uint grid_x = (TileX(tile) / N) * N;
uint grid_y = (TileY(tile) / N) * N;
this->area.Add(TileXY(grid_x, grid_y));
this->area.Add(TileXY(grid_x + N - 1, grid_y + N - 1));
/* Allocate new storage. */
T *new_data = CallocT<T>(this->area.w / N * this->area.h / N);
if (old_w > 0) {
/* Copy old data if present. */
uint offs_x = old_left - TileX(this->area.tile) / N;
uint offs_y = old_top - TileY(this->area.tile) / N;
for (uint row = 0; row < old_h; row++) {
MemCpyT(&new_data[(row + offs_y) * this->area.w / N + offs_x], &this->data[row * old_w], old_w);
}
}
free(this->data);
this->data = new_data;
}
public:
static const uint GRID = N;
TileArea area; ///< Area covered by the matrix.
T *data; ///< Pointer to data array.
TileMatrix() : area(INVALID_TILE, 0, 0), data(NULL) {}
~TileMatrix()
{
free(this->data);
}
/**
* Get the total covered area.
* @return The area covered by the matrix.
*/
const TileArea& GetArea() const
{
return this->area;
}
/**
* Get the area of the matrix square that contains a specific tile.
* @param The tile to get the map area for.
* @param extend Extend the area by this many squares on all sides.
* @return Tile area containing the tile.
*/
static TileArea GetAreaForTile(TileIndex tile, uint extend = 0)
{
uint tile_x = (TileX(tile) / N) * N;
uint tile_y = (TileY(tile) / N) * N;
uint w = N, h = N;
w += min(extend * N, tile_x);
h += min(extend * N, tile_y);
tile_x -= min(extend * N, tile_x);
tile_y -= min(extend * N, tile_y);
w += min(extend * N, MapSizeX() - tile_x - w);
h += min(extend * N, MapSizeY() - tile_y - h);
return TileArea(TileXY(tile_x, tile_y), w, h);
}
/**
* Extend the coverage area to include a tile.
* @param tile The tile to include.
*/
void Add(TileIndex tile)
{
if (!this->area.Contains(tile)) {
this->AllocateStorage(tile);
}
}
/**
* Get the value associated to a tile index.
* @param tile The tile to get the value for.
* @return Pointer to the value.
*/
T *Get(TileIndex tile)
{
this->Add(tile);
tile -= this->area.tile;
uint x = TileX(tile) / N;
uint y = TileY(tile) / N;
return &this->data[y * this->area.w / N + x];
}
/** Array access operator, see #Get. */
FORCEINLINE T &operator[](TileIndex tile)
{
return *this->Get(tile);
}
};
#endif /* TILEMATRIX_TYPE_HPP */
|