src/map.h
branchnoai
changeset 9703 d2a6acdbd665
parent 9694 e72987579514
child 9704 197cb8c6ae17
equal deleted inserted replaced
9702:e782b59f1f6a 9703:d2a6acdbd665
    43  */
    43  */
    44 struct TileExtended {
    44 struct TileExtended {
    45 	byte m7; ///< Primarily used for newgrf support
    45 	byte m7; ///< Primarily used for newgrf support
    46 };
    46 };
    47 
    47 
       
    48 /**
       
    49  * Pointer to the tile-array.
       
    50  *
       
    51  * This variable points to the tile-array which contains the tiles of
       
    52  * the map.
       
    53  */
    48 extern Tile *_m;
    54 extern Tile *_m;
       
    55 
       
    56 /**
       
    57  * Pointer to the extended tile-array.
       
    58  *
       
    59  * This variable points to the extended tile-array which contains the tiles
       
    60  * of the map.
       
    61  */
    49 extern TileExtended *_me;
    62 extern TileExtended *_me;
    50 
    63 
       
    64 /**
       
    65  * Allocate a new map with the given size.
       
    66  */
    51 void AllocateMap(uint size_x, uint size_y);
    67 void AllocateMap(uint size_x, uint size_y);
    52 
    68 
    53 /**
    69 /**
    54  * Logarithm of the map size along the X side.
    70  * Logarithm of the map size along the X side.
    55  * @note try to avoid using this one
    71  * @note try to avoid using this one
   107 static inline uint MapMaxY()
   123 static inline uint MapMaxY()
   108 {
   124 {
   109 	return MapSizeY() - 1;
   125 	return MapSizeY() - 1;
   110 }
   126 }
   111 
   127 
   112 /* Scale a number relative to the map size */
   128 /**
   113 uint ScaleByMapSize(uint); // Scale relative to the number of tiles
   129  * Scales relative to the number of tiles.
   114 uint ScaleByMapSize1D(uint); // Scale relative to the circumference of the map
   130  */
   115 
   131 uint ScaleByMapSize(uint);
       
   132 
       
   133 /**
       
   134  * Scale relative to the circumference of the map.
       
   135  */
       
   136 uint ScaleByMapSize1D(uint);
       
   137 
       
   138 /**
       
   139  * The index/ID of a Tile.
       
   140  */
   116 typedef uint32 TileIndex;
   141 typedef uint32 TileIndex;
       
   142 
       
   143 /**
       
   144  * An offset value between to tiles.
       
   145  *
       
   146  * This value is used fro the difference between
       
   147  * to tiles. It can be added to a tileindex to get
       
   148  * the resulting tileindex of the start tile applied
       
   149  * with this saved difference.
       
   150  *
       
   151  * @see TileDiffXY(int, int)
       
   152  */
   117 typedef int32 TileIndexDiff;
   153 typedef int32 TileIndexDiff;
   118 
   154 
       
   155 /**
       
   156  * Returns the TileIndex of a coordinate.
       
   157  *
       
   158  * @param x The x coordinate of the tile
       
   159  * @param y The y coordinate of the tile
       
   160  * @return The TileIndex calculated by the coordinate
       
   161  */
   119 static inline TileIndex TileXY(uint x, uint y)
   162 static inline TileIndex TileXY(uint x, uint y)
   120 {
   163 {
   121 	return (y * MapSizeX()) + x;
   164 	return (y * MapSizeX()) + x;
   122 }
   165 }
   123 
   166 
       
   167 /**
       
   168  * Calculates an offset for the given coordinate(-offset).
       
   169  *
       
   170  * This function calculate an offset value which can be added to an
       
   171  * #TileIndex. The coordinates can be negative.
       
   172  *
       
   173  * @param x The offset in x direction
       
   174  * @param y The offset in y direction
       
   175  * @return The resulting offset value of the given coordinate
       
   176  * @see ToTileIndexDiff(TileIndexDiffC)
       
   177  */
   124 static inline TileIndexDiff TileDiffXY(int x, int y)
   178 static inline TileIndexDiff TileDiffXY(int x, int y)
   125 {
   179 {
   126 	/* Multiplication gives much better optimization on MSVC than shifting.
   180 	/* Multiplication gives much better optimization on MSVC than shifting.
   127 	 * 0 << shift isn't optimized to 0 properly.
   181 	 * 0 << shift isn't optimized to 0 properly.
   128 	 * Typically x and y are constants, and then this doesn't result
   182 	 * Typically x and y are constants, and then this doesn't result
   165 static inline uint TileY(TileIndex tile)
   219 static inline uint TileY(TileIndex tile)
   166 {
   220 {
   167 	return tile >> MapLogX();
   221 	return tile >> MapLogX();
   168 }
   222 }
   169 
   223 
   170 
   224 /**
       
   225  * A pair-construct of a TileIndexDiff.
       
   226  *
       
   227  * This can be used to save the difference between to
       
   228  * tiles as a pair of x and y value.
       
   229  */
   171 struct TileIndexDiffC {
   230 struct TileIndexDiffC {
   172 	int16 x;
   231 	int16 x;        ///< The x value of the coordinate
   173 	int16 y;
   232 	int16 y;        ///< The y value of the coordinate
   174 };
   233 };
   175 
   234 
       
   235 /**
       
   236  * Return the offset between to tiles from a TileIndexDiffC struct.
       
   237  *
       
   238  * This function works like #TileDiffXY(int, int) and returns the
       
   239  * difference between two tiles.
       
   240  *
       
   241  * @param tidc The coordinate of the offset as TileIndexDiffC
       
   242  * @return The difference between two tiles.
       
   243  * @see TileDiffXY(int, int)
       
   244  */
   176 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
   245 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
   177 {
   246 {
   178 	return (tidc.y << MapLogX()) + tidc.x;
   247 	return (tidc.y << MapLogX()) + tidc.x;
   179 }
   248 }
   180 
   249 
   181 
   250 
   182 #ifndef _DEBUG
   251 #ifndef _DEBUG
       
   252         /**
       
   253          * Adds to tiles together.
       
   254          *
       
   255          * @param x One tile
       
   256          * @param y An other tile to add
       
   257          * @return The resulting tile(index)
       
   258          */
   183 	#define TILE_ADD(x,y) ((x) + (y))
   259 	#define TILE_ADD(x,y) ((x) + (y))
   184 #else
   260 #else
   185 	extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
   261 	extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
   186 		const char *exp, const char *file, int line);
   262 		const char *exp, const char *file, int line);
   187 	#define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
   263 	#define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
   188 #endif
   264 #endif
   189 
   265 
       
   266 /**
       
   267  * Adds a given offset to a tile.
       
   268  *
       
   269  * @param tile The tile to add an offset on it
       
   270  * @param x The x offset to add to the tile
       
   271  * @param y The y offset to add to the tile
       
   272  */
   190 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
   273 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
   191 
   274 
       
   275 /**
       
   276  * Adds an offset to a tile and check if we are still on the map.
       
   277  */
   192 uint TileAddWrap(TileIndex tile, int addx, int addy);
   278 uint TileAddWrap(TileIndex tile, int addx, int addy);
   193 
   279 
       
   280 /**
       
   281  * Returns the TileIndexDiffC offset from a DiagDirection.
       
   282  *
       
   283  * @param dir The given direction
       
   284  * @return The offset as TileIndexDiffC value
       
   285  */
   194 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
   286 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
   195 {
   287 {
   196 	extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
   288 	extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
   197 
   289 
   198 	assert(IsValidDiagDirection(dir));
   290 	assert(IsValidDiagDirection(dir));
   199 	return _tileoffs_by_diagdir[dir];
   291 	return _tileoffs_by_diagdir[dir];
   200 }
   292 }
   201 
   293 /**
   202 /* Returns tile + the diff given in diff. If the result tile would end up
   294  * Add a TileIndexDiffC to a TileIndex and returns the new one.
       
   295  *
       
   296  * Returns tile + the diff given in diff. If the result tile would end up
   203  * outside of the map, INVALID_TILE is returned instead.
   297  * outside of the map, INVALID_TILE is returned instead.
       
   298  *
       
   299  * @param tile The base tile to add the offset on
       
   300  * @param diff The offset to add on the tile
       
   301  * @return The resulting TileIndex
   204  */
   302  */
   205 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
   303 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
   206 {
   304 {
   207 	int x = TileX(tile) + diff.x;
   305 	int x = TileX(tile) + diff.x;
   208 	int y = TileY(tile) + diff.y;
   306 	int y = TileY(tile) + diff.y;
   234 uint DistanceSquare(TileIndex, TileIndex); ///< euclidian- or L2-Norm squared
   332 uint DistanceSquare(TileIndex, TileIndex); ///< euclidian- or L2-Norm squared
   235 uint DistanceMax(TileIndex, TileIndex); ///< also known as L-Infinity-Norm
   333 uint DistanceMax(TileIndex, TileIndex); ///< also known as L-Infinity-Norm
   236 uint DistanceMaxPlusManhattan(TileIndex, TileIndex); ///< Max + Manhattan
   334 uint DistanceMaxPlusManhattan(TileIndex, TileIndex); ///< Max + Manhattan
   237 uint DistanceFromEdge(TileIndex); ///< shortest distance from any edge of the map
   335 uint DistanceFromEdge(TileIndex); ///< shortest distance from any edge of the map
   238 
   336 
   239 
   337 /**
       
   338  * Starts a loop which iterates to a square of tiles
       
   339  *
       
   340  * This macro starts 2 nested loops which iterates over a square of tiles.
       
   341  *
       
   342  * @param var The name of the variable which contains the current tile
       
   343  * @param w The width (x-width) of the square
       
   344  * @param h The heigth (y-width) of the square
       
   345  * @param tile The start tile of the square
       
   346  */
   240 #define BEGIN_TILE_LOOP(var, w, h, tile)                      \
   347 #define BEGIN_TILE_LOOP(var, w, h, tile)                      \
   241 	{                                                        \
   348 	{                                                        \
   242 		int h_cur = h;                                         \
   349 		int h_cur = h;                                         \
   243 		uint var = tile;                                       \
   350 		uint var = tile;                                       \
   244 		do {                                                   \
   351 		do {                                                   \
   245 			int w_cur = w;                                       \
   352 			int w_cur = w;                                       \
   246 			do {
   353 			do {
   247 
   354 /**
       
   355  * Ends the square-loop used before
       
   356  *
       
   357  * @see BEGIN_TILE_LOOP
       
   358  */
   248 #define END_TILE_LOOP(var, w, h, tile)                        \
   359 #define END_TILE_LOOP(var, w, h, tile)                        \
   249 			} while (++var, --w_cur != 0);                       \
   360 			} while (++var, --w_cur != 0);                       \
   250 		} while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \
   361 		} while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \
   251 	}
   362 	}
   252 
   363 /**
       
   364  * Convert a DiagDirection to a TileIndexDiff
       
   365  *
       
   366  * @param dir The DiagDirection
       
   367  * @return The resulting TileIndexDiff
       
   368  * @see TileIndexDiffCByDiagDir
       
   369  */
   253 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
   370 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
   254 {
   371 {
   255 	extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
   372 	extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
   256 
   373 
   257 	assert(IsValidDiagDirection(dir));
   374 	assert(IsValidDiagDirection(dir));
   258 	return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
   375 	return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
   259 }
   376 }
   260 
   377 
       
   378 /**
       
   379  * Convert a Direction to a TileIndexDiff.
       
   380  *
       
   381  * @param dir The direction to convert from
       
   382  * @return The resulting TileIndexDiff
       
   383  */
   261 static inline TileIndexDiff TileOffsByDir(Direction dir)
   384 static inline TileIndexDiff TileOffsByDir(Direction dir)
   262 {
   385 {
   263 	extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
   386 	extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
   264 
   387 
   265 	assert(IsValidDirection(dir));
   388 	assert(IsValidDirection(dir));
   266 	return ToTileIndexDiff(_tileoffs_by_dir[dir]);
   389 	return ToTileIndexDiff(_tileoffs_by_dir[dir]);
   267 }
   390 }
   268 
   391 
       
   392 /**
       
   393  * A callback function type for searching tiles.
       
   394  *
       
   395  * @param tile The tile to test
       
   396  * @param data additional data for the callback function to use
       
   397  * @return A boolean value, depend on the definition of the function.
       
   398  */
   269 typedef bool TestTileOnSearchProc(TileIndex tile, uint32 data);
   399 typedef bool TestTileOnSearchProc(TileIndex tile, uint32 data);
       
   400 
       
   401 /**
       
   402  * Searches for some cirumstances of a tile around a given tile with a helper function.
       
   403  */
   270 bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data);
   404 bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data);
   271 
   405 
   272 /* Approximation of the length of a straight track, relative to a diagonal
   406 /** Approximation of the length of a straight track, relative to a diagonal
   273  * track (ie the size of a tile side). #defined instead of const so it can
   407  * track (ie the size of a tile side).
       
   408  *
       
   409  * #defined instead of const so it can
   274  * stay integer. (no runtime float operations) Is this needed?
   410  * stay integer. (no runtime float operations) Is this needed?
   275  * Watch out! There are _no_ brackets around here, to prevent intermediate
   411  * Watch out! There are _no_ brackets around here, to prevent intermediate
   276  * rounding! Be careful when using this!
   412  * rounding! Be careful when using this!
   277  * This value should be sqrt(2)/2 ~ 0.7071 */
   413  * This value should be sqrt(2)/2 ~ 0.7071 */
   278 #define STRAIGHT_TRACK_LENGTH 7071/10000
   414 #define STRAIGHT_TRACK_LENGTH 7071/10000