OpenTTD Source: src/map_func.h Source File

OpenTTD Source 14.1

map_func.h
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10 #ifndef MAP_FUNC_H
11 #define MAP_FUNC_H
12
13 #include "core/math_func.hpp"
14 #include "tile_type.h"
15 #include "map_type.h"
16 #include "direction_func.h"
17
25 class Tile {
26 private:
27 friend struct Map;
32 struct TileBase {
33 byte type;
34 byte height;
35 uint16_t m2;
36 byte m1;
37 byte m3;
38 byte m4;
39 byte m5;
40 };
41
42 static_assert(sizeof(TileBase) == 8);
43
48 struct TileExtended {
49 byte m6;
50 byte m7;
51 uint16_t m8;
52 };
53
54 static TileBase *base_tiles;
55 static TileExtended *extended_tiles;
56
57 TileIndex tile;
58
59 public:
64 debug_inline Tile(TileIndex tile) : tile(tile) {}
65
70 Tile(uint tile) : tile(tile) {}
71
75 debug_inline constexpr operator TileIndex() const { return tile; }
76
80 debug_inline constexpr operator uint() const { return tile.base(); }
81
89 debug_inline byte &type()
90 {
91 return base_tiles[tile.base()].type;
92 }
93
101 debug_inline byte &height()
102 {
103 return base_tiles[tile.base()].height;
104 }
105
113 debug_inline byte &m1()
114 {
115 return base_tiles[tile.base()].m1;
116 }
117
125 debug_inline uint16_t &m2()
126 {
127 return base_tiles[tile.base()].m2;
128 }
129
137 debug_inline byte &m3()
138 {
139 return base_tiles[tile.base()].m3;
140 }
141
149 debug_inline byte &m4()
150 {
151 return base_tiles[tile.base()].m4;
152 }
153
161 debug_inline byte &m5()
162 {
163 return base_tiles[tile.base()].m5;
164 }
165
173 debug_inline byte &m6()
174 {
175 return extended_tiles[tile.base()].m6;
176 }
177
185 debug_inline byte &m7()
186 {
187 return extended_tiles[tile.base()].m7;
188 }
189
197 debug_inline uint16_t &m8()
198 {
199 return extended_tiles[tile.base()].m8;
200 }
201 };
202
206 struct Map {
207 private:
211 struct Iterator {
212 typedef Tile value_type;
213 typedef Tile *pointer;
214 typedef Tile &reference;
215 typedef size_t difference_type;
216 typedef std::forward_iterator_tag iterator_category;
217
218 explicit Iterator(TileIndex index) : index(index) {}
219 bool operator==(const Iterator &other) const { return this->index == other.index; }
220 bool operator!=(const Iterator &other) const { return !(*this == other); }
221 Tile operator*() const { return this->index; }
222 Iterator & operator++() { this->index++; return *this; }
223 private:
224 TileIndex index;
225 };
226
227 /*
228 * Iterable ensemble of all Tiles
229 */
230 struct IterateWrapper {
231 Iterator begin() { return Iterator(0); }
232 Iterator end() { return Iterator(Map::Size()); }
233 bool empty() { return false; }
234 };
235
236 static uint log_x;
237 static uint log_y;
238 static uint size_x;
239 static uint size_y;
240 static uint size;
241 static uint tile_mask;
242
243 public:
244 static void Allocate(uint size_x, uint size_y);
245
251 debug_inline static uint LogX()
252 {
253 return Map::log_x;
254 }
255
261 static inline uint LogY()
262 {
263 return Map::log_y;
264 }
265
270 debug_inline static uint SizeX()
271 {
272 return Map::size_x;
273 }
274
279 static inline uint SizeY()
280 {
281 return Map::size_y;
282 }
283
288 debug_inline static uint Size()
289 {
290 return Map::size;
291 }
292
297 debug_inline static uint MaxX()
298 {
299 return Map::SizeX() - 1;
300 }
301
306 static inline uint MaxY()
307 {
308 return Map::SizeY() - 1;
309 }
310
311
317 static inline TileIndex WrapToMap(TileIndex tile)
318 {
319 return tile.base() & Map::tile_mask;
320 }
321
328 static inline uint ScaleBySize(uint n)
329 {
330 /* Subtract 12 from shift in order to prevent integer overflow
331 * for large values of n. It's safe since the min mapsize is 64x64. */
332 return CeilDiv(n << (Map::LogX() + Map::LogY() - 12), 1 << 4);
333 }
334
341 static inline uint ScaleBySize1D(uint n)
342 {
343 /* Normal circumference for the X+Y is 256+256 = 1<<9
344 * Note, not actually taking the full circumference into account,
345 * just half of it. */
346 return CeilDiv((n << Map::LogX()) + (n << Map::LogY()), 1 << 9);
347 }
348
354 static bool IsInitialized()
355 {
356 return Tile::base_tiles != nullptr;
357 }
358
363 static IterateWrapper Iterate() { return IterateWrapper(); }
364 };
365
376 typedef int32_t TileIndexDiff;
377
385 debug_inline static TileIndex TileXY(uint x, uint y)
386 {
387 return (y << Map::LogX()) + x;
388 }
389
401 inline TileIndexDiff TileDiffXY(int x, int y)
402 {
403 /* Multiplication gives much better optimization on MSVC than shifting.
404 * 0 << shift isn't optimized to 0 properly.
405 * Typically x and y are constants, and then this doesn't result
406 * in any actual multiplication in the assembly code.. */
407 return (y * Map::SizeX()) + x;
408 }
409
416 debug_inline static TileIndex TileVirtXY(uint x, uint y)
417 {
418 return (y >> 4 << Map::LogX()) + (x >> 4);
419 }
420
421
427 debug_inline static uint TileX(TileIndex tile)
428 {
429 return tile.base() & Map::MaxX();
430 }
431
437 debug_inline static uint TileY(TileIndex tile)
438 {
439 return tile.base() >> Map::LogX();
440 }
441
452 inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
453 {
454 return (tidc.y << Map::LogX()) + tidc.x;
455 }
456
457
458 #ifndef _DEBUG
459
466 # define TILE_ADD(x, y) ((x) + (y))
467 #else
468 extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
469 const char *exp, const char *file, int line);
470 # define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
471 #endif
472
480 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
481
482 TileIndex TileAddWrap(TileIndex tile, int addx, int addy);
483
490 inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
491 {
492 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
493
494 assert(IsValidDiagDirection(dir));
495 return _tileoffs_by_diagdir[dir];
496 }
497
504 inline TileIndexDiffC TileIndexDiffCByDir(Direction dir)
505 {
506 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
507
508 assert(IsValidDirection(dir));
509 return _tileoffs_by_dir[dir];
510 }
511
522 inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
523 {
524 int x = TileX(tile) + diff.x;
525 int y = TileY(tile) + diff.y;
526 /* Negative value will become big positive value after cast */
527 if ((uint)x >= Map::SizeX() || (uint)y >= Map::SizeY()) return INVALID_TILE;
528 return TileXY(x, y);
529 }
530
538 inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
539 {
540 TileIndexDiffC difference;
541
542 difference.x = TileX(tile_a) - TileX(tile_b);
543 difference.y = TileY(tile_a) - TileY(tile_b);
544
545 return difference;
546 }
547
548 /* Functions to calculate distances */
549 uint DistanceManhattan(TileIndex, TileIndex);
550 uint DistanceSquare(TileIndex, TileIndex);
551 uint DistanceMax(TileIndex, TileIndex);
552 uint DistanceMaxPlusManhattan(TileIndex, TileIndex);
553 uint DistanceFromEdge(TileIndex);
554 uint DistanceFromEdgeDir(TileIndex, DiagDirection);
555
563 inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
564 {
565 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
566
567 assert(IsValidDiagDirection(dir));
568 return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
569 }
570
577 inline TileIndexDiff TileOffsByDir(Direction dir)
578 {
579 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
580
581 assert(IsValidDirection(dir));
582 return ToTileIndexDiff(_tileoffs_by_dir[dir]);
583 }
584
592 inline TileIndex TileAddByDir(TileIndex tile, Direction dir)
593 {
594 return TILE_ADD(tile, TileOffsByDir(dir));
595 }
596
604 inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
605 {
606 return TILE_ADD(tile, TileOffsByDiagDir(dir));
607 }
608
616 inline DiagDirection DiagdirBetweenTiles(TileIndex tile_from, TileIndex tile_to)
617 {
618 int dx = (int)TileX(tile_to) - (int)TileX(tile_from);
619 int dy = (int)TileY(tile_to) - (int)TileY(tile_from);
620 if (dx == 0) {
621 if (dy == 0) return INVALID_DIAGDIR;
622 return (dy < 0 ? DIAGDIR_NW : DIAGDIR_SE);
623 } else {
624 if (dy != 0) return INVALID_DIAGDIR;
625 return (dx < 0 ? DIAGDIR_NE : DIAGDIR_SW);
626 }
627 }
628
636 typedef bool TestTileOnSearchProc(TileIndex tile, void *user_data);
637
638 bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data);
639 bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_data);
640
646 inline TileIndex RandomTileSeed(uint32_t r)
647 {
648 return Map::WrapToMap(r);
649 }
650
657 #define RandomTile() RandomTileSeed(Random())
658
659 uint GetClosestWaterDistance(TileIndex tile, bool water);
660
661 #endif /* MAP_FUNC_H */
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:437
TileIndexDiffCByDiagDir
TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
Returns the TileIndexDiffC offset from a DiagDirection.
Definition: map_func.h:490
DIAGDIR_SE
@ DIAGDIR_SE
Southeast.
Definition: direction_type.h:76
TileOffsByDir
TileIndexDiff TileOffsByDir(Direction dir)
Convert a Direction to a TileIndexDiff.
Definition: map_func.h:577
Tile::TileExtended::m8
uint16_t m8
General purpose.
Definition: map_func.h:51
Tile::TileBase
Data that is stored per tile.
Definition: map_func.h:32
Map::size_y
static uint size_y
Size of the map along the Y.
Definition: map_func.h:239
TILE_ADD
#define TILE_ADD(x, y)
Adds two tiles together.
Definition: map_func.h:466
_tileoffs_by_dir
const TileIndexDiffC _tileoffs_by_dir[]
'Lookup table' for tile offsets given a Direction
Tile::TileBase::m4
byte m4
General purpose.
Definition: map_func.h:38
Direction
Direction
Defines the 8 directions on the map.
Definition: direction_type.h:24
Tile::Tile
Tile(uint tile)
Create the tile wrapper for the given tile.
Definition: map_func.h:70
Map
Size related data of the map.
Definition: map_func.h:206
AddTileIndexDiffCWrap
TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
Add a TileIndexDiffC to a TileIndex and returns the new one.
Definition: map_func.h:522
TestTileOnSearchProc
bool TestTileOnSearchProc(TileIndex tile, void *user_data)
A callback function type for searching tiles.
Definition: map_func.h:636
Tile::TileBase::type
byte type
The type (bits 4..7), bridges (2..3), rainforest/desert (0..1)
Definition: map_func.h:33
Map::MaxX
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:297
Map::LogX
static debug_inline uint LogX()
Logarithm of the map size along the X side.
Definition: map_func.h:251
Map::size_x
static uint size_x
Size of the map along the X.
Definition: map_func.h:238
math_func.hpp
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition: direction_type.h:79
Map::ScaleBySize1D
static uint ScaleBySize1D(uint n)
Scales the given value by the maps circumference, where the given value is for a 256 by 256 map.
Definition: map_func.h:341
Map::Allocate
static void Allocate(uint size_x, uint size_y)
(Re)allocates a map with the given dimension
Definition: map.cpp:41
Tile::m8
debug_inline uint16_t & m8()
General purpose.
Definition: map_func.h:197
Map::WrapToMap
static TileIndex WrapToMap(TileIndex tile)
'Wraps' the given "tile" so it is within the map.
Definition: map_func.h:317
Tile::TileBase::m2
uint16_t m2
Primarily used for indices to towns, industries and stations.
Definition: map_func.h:35
Map::IsInitialized
static bool IsInitialized()
Check whether the map has been initialized, as to not try to save the map during crashlog when the ma...
Definition: map_func.h:354
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
Tile::m6
debug_inline byte & m6()
General purpose.
Definition: map_func.h:173
Tile::Tile
debug_inline Tile(TileIndex tile)
Create the tile wrapper for the given tile.
Definition: map_func.h:64
Tile
Wrapper class to abstract away the way the tiles are stored.
Definition: map_func.h:25
CeilDiv
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition: math_func.hpp:320
CircularTileSearch
bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data)
Function performing a search around a center tile and going outward, thus in circle.
Definition: map.cpp:260
Tile::TileBase::m5
byte m5
General purpose.
Definition: map_func.h:39
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
DIAGDIR_NW
@ DIAGDIR_NW
Northwest.
Definition: direction_type.h:78
Tile::m5
debug_inline byte & m5()
General purpose.
Definition: map_func.h:161
Map::ScaleBySize
static uint ScaleBySize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map.
Definition: map_func.h:328
_tileoffs_by_diagdir
const TileIndexDiffC _tileoffs_by_diagdir[]
'Lookup table' for tile offsets given a DiagDirection
Tile::m1
debug_inline byte & m1()
Primarily used for ownership information.
Definition: map_func.h:113
Tile::m4
debug_inline byte & m4()
General purpose.
Definition: map_func.h:149
DIAGDIR_SW
@ DIAGDIR_SW
Southwest.
Definition: direction_type.h:77
Tile::m7
debug_inline byte & m7()
Primarily used for newgrf support.
Definition: map_func.h:185
DistanceSquare
uint DistanceSquare(TileIndex, TileIndex)
euclidian- or L2-Norm squared
Definition: map.cpp:176
DistanceFromEdgeDir
uint DistanceFromEdgeDir(TileIndex, DiagDirection)
distance from the map edge in given direction
Definition: map.cpp:236
ToTileIndexDiff
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition: map_func.h:452
Tile::m2
debug_inline uint16_t & m2()
Primarily used for indices to towns, industries and stations.
Definition: map_func.h:125
DistanceManhattan
uint DistanceManhattan(TileIndex, TileIndex)
also known as L1-Norm. Is the shortest distance one could go over diagonal tracks (or roads)
Definition: map.cpp:159
Map::Iterate
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition: map_func.h:363
IsValidDirection
bool IsValidDirection(Direction d)
Checks if an integer value is a valid Direction.
Definition: direction_func.h:32
Tile::TileBase::m3
byte m3
General purpose.
Definition: map_func.h:37
Tile::TileExtended::m7
byte m7
Primarily used for newgrf support.
Definition: map_func.h:50
Tile::extended_tiles
static TileExtended * extended_tiles
Pointer to the extended tile-array.
Definition: map_func.h:55
map_type.h
TileDiffXY
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:401
Map::Iterator
Iterator to iterate all Tiles.
Definition: map_func.h:211
INVALID_DIAGDIR
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition: direction_type.h:80
TileIndexDiff
int32_t TileIndexDiff
An offset value between two tiles.
Definition: map_func.h:376
Tile::TileBase::height
byte height
The height of the northern corner.
Definition: map_func.h:34
DistanceFromEdge
uint DistanceFromEdge(TileIndex)
shortest distance from any edge of the map
Definition: map.cpp:219
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:73
TileAddByDir
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition: map_func.h:592
Map::log_x
static uint log_x
2^_map_log_x == _map_size_x
Definition: map_func.h:236
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:563
Map::log_y
static uint log_y
2^_map_log_y == _map_size_y
Definition: map_func.h:237
TileIndexDiffC
A pair-construct of a TileIndexDiff.
Definition: map_type.h:31
Map::SizeX
static debug_inline uint SizeX()
Get the size of the map along the X.
Definition: map_func.h:270
TileIndexDiffCByDir
TileIndexDiffC TileIndexDiffCByDir(Direction dir)
Returns the TileIndexDiffC offset from a Direction.
Definition: map_func.h:504
IsValidDiagDirection
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
Definition: direction_func.h:21
Tile::height
debug_inline byte & height()
The height of the northern corner.
Definition: map_func.h:101
DiagdirBetweenTiles
DiagDirection DiagdirBetweenTiles(TileIndex tile_from, TileIndex tile_to)
Determines the DiagDirection to get from one tile to another.
Definition: map_func.h:616
Map::MaxY
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition: map_func.h:306
DistanceMaxPlusManhattan
uint DistanceMaxPlusManhattan(TileIndex, TileIndex)
Max + Manhattan.
Definition: map.cpp:207
tile_type.h
Tile::TileExtended::m6
byte m6
General purpose.
Definition: map_func.h:49
DIR_END
@ DIR_END
Used to iterate.
Definition: direction_type.h:34
Map::Size
static debug_inline uint Size()
Get the size of the map.
Definition: map_func.h:288
Map::IterateWrapper
Definition: map_func.h:230
Map::tile_mask
static uint tile_mask
_map_size - 1 (to mask the mapsize)
Definition: map_func.h:241
Tile::tile
TileIndex tile
The tile to access the map data for.
Definition: map_func.h:57
TileIndex
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition: tile_type.h:87
TileIndexDiffC::y
int16_t y
The y value of the coordinate.
Definition: map_type.h:33
Map::LogY
static uint LogY()
Logarithm of the map size along the y side.
Definition: map_func.h:261
TileXY
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition: map_func.h:385
Tile::base_tiles
static TileBase * base_tiles
Pointer to the tile-array.
Definition: map_func.h:54
DistanceMax
uint DistanceMax(TileIndex, TileIndex)
also known as L-Infinity-Norm
Definition: map.cpp:191
TileVirtXY
static debug_inline TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition: map_func.h:416
TileX
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:427
TileIndexToTileIndexDiffC
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition: map_func.h:538
DIAGDIR_NE
@ DIAGDIR_NE
Northeast, upper right on your monitor.
Definition: direction_type.h:75
Tile::TileExtended
Data that is stored per tile.
Definition: map_func.h:48
Tile::TileBase::m1
byte m1
Primarily used for ownership information.
Definition: map_func.h:36
Tile::m3
debug_inline byte & m3()
General purpose.
Definition: map_func.h:137
TileAddByDiagDir
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition: map_func.h:604
GetClosestWaterDistance
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition: map.cpp:342
TileIndexDiffC::x
int16_t x
The x value of the coordinate.
Definition: map_type.h:32
TileAddWrap
TileIndex TileAddWrap(TileIndex tile, int addx, int addy)
This function checks if we add addx/addy to tile, if we do wrap around the edges.
Definition: map.cpp:116
Map::size
static uint size
The number of tiles on the map.
Definition: map_func.h:240
RandomTileSeed
TileIndex RandomTileSeed(uint32_t r)
Get a random tile out of a given seed.
Definition: map_func.h:646
direction_func.h
Map::SizeY
static uint SizeY()
Get the size of the map along the Y.
Definition: map_func.h:279
Tile::type
debug_inline byte & type()
The type (bits 4..7), bridges (2..3), rainforest/desert (0..1)
Definition: map_func.h:89