changeset 18559:820b3ec0b86d draft

(svn r23404) -Add: Tilematrix structure (michi_cc).
author terkhen <terkhen@openttd.org>
date Sat, 03 Dec 2011 22:19:09 +0000
parents 8e86f44a1130
children 488cc0d0b505
files projects/openttd_vs100.vcxproj projects/openttd_vs100.vcxproj.filters projects/openttd_vs80.vcproj projects/openttd_vs90.vcproj source.list src/tilematrix_type.hpp
diffstat 6 files changed, 159 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/projects/openttd_vs100.vcxproj
+++ b/projects/openttd_vs100.vcxproj
@@ -573,6 +573,7 @@
     <ClInclude Include="..\src\tilearea_type.h" />
     <ClInclude Include="..\src\tilehighlight_func.h" />
     <ClInclude Include="..\src\tilehighlight_type.h" />
+    <ClInclude Include="..\src\tilematrix_type.hpp" />
     <ClInclude Include="..\src\timetable.h" />
     <ClInclude Include="..\src\toolbar_gui.h" />
     <ClInclude Include="..\src\town.h" />
--- a/projects/openttd_vs100.vcxproj.filters
+++ b/projects/openttd_vs100.vcxproj.filters
@@ -942,6 +942,9 @@
     <ClInclude Include="..\src\tilehighlight_type.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\tilematrix_type.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\src\timetable.h">
       <Filter>Header Files</Filter>
     </ClInclude>
--- a/projects/openttd_vs80.vcproj
+++ b/projects/openttd_vs80.vcproj
@@ -1567,6 +1567,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\tilematrix_type.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\timetable.h"
 				>
 			</File>
--- a/projects/openttd_vs90.vcproj
+++ b/projects/openttd_vs90.vcproj
@@ -1564,6 +1564,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\tilematrix_type.hpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\timetable.h"
 				>
 			</File>
--- a/source.list
+++ b/source.list
@@ -306,6 +306,7 @@
 tilearea_type.h
 tilehighlight_func.h
 tilehighlight_type.h
+tilematrix_type.hpp
 timetable.h
 toolbar_gui.h
 town.h
new file mode 100644
--- /dev/null
+++ b/src/tilematrix_type.hpp
@@ -0,0 +1,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 */