map_func.h

Go to the documentation of this file.
00001 /* $Id: map_func.h 17248 2009-08-21 20:21:05Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #ifndef MAP_FUNC_H
00013 #define MAP_FUNC_H
00014 
00015 #include "tile_type.h"
00016 #include "map_type.h"
00017 #include "direction_func.h"
00018 
00019 extern uint _map_tile_mask;
00020 
00027 #define TILE_MASK(x) ((x) & _map_tile_mask)
00028 
00035 extern Tile *_m;
00036 
00043 extern TileExtended *_me;
00044 
00048 void AllocateMap(uint size_x, uint size_y);
00049 
00055 static inline uint MapLogX()
00056 {
00057   extern uint _map_log_x;
00058   return _map_log_x;
00059 }
00060 
00066 static inline uint MapLogY()
00067 {
00068   extern uint _map_log_y;
00069   return _map_log_y;
00070 }
00071 
00076 static inline uint MapSizeX()
00077 {
00078   extern uint _map_size_x;
00079   return _map_size_x;
00080 }
00081 
00086 static inline uint MapSizeY()
00087 {
00088   extern uint _map_size_y;
00089   return _map_size_y;
00090 }
00091 
00096 static inline uint MapSize()
00097 {
00098   extern uint _map_size;
00099   return _map_size;
00100 }
00101 
00106 static inline uint MapMaxX()
00107 {
00108   return MapSizeX() - 1;
00109 }
00110 
00115 static inline uint MapMaxY()
00116 {
00117   return MapSizeY() - 1;
00118 }
00119 
00126 static inline uint ScaleByMapSize(uint n)
00127 {
00128   /* Subtract 12 from shift in order to prevent integer overflow
00129    * for large values of n. It's safe since the min mapsize is 64x64.
00130    * Add (1<<4)-1 to round upwards. */
00131   return ((n << (MapLogX() + MapLogY() - 12)) + (1 << 4) - 1) >> 4;
00132 }
00133 
00134 
00141 static inline uint ScaleByMapSize1D(uint n)
00142 {
00143   /* Normal circumference for the X+Y is 256+256 = 1<<9
00144    * Note, not actually taking the full circumference into account,
00145    * just half of it.
00146    * (1<<9) - 1 is there to scale upwards. */
00147   return ((n << MapLogX()) + (n << MapLogY()) + (1 << 9) - 1) >> 9;
00148 }
00149 
00160 typedef int32 TileIndexDiff;
00161 
00169 static inline TileIndex TileXY(uint x, uint y)
00170 {
00171   return (y << MapLogX()) + x;
00172 }
00173 
00185 static inline TileIndexDiff TileDiffXY(int x, int y)
00186 {
00187   /* Multiplication gives much better optimization on MSVC than shifting.
00188    * 0 << shift isn't optimized to 0 properly.
00189    * Typically x and y are constants, and then this doesn't result
00190    * in any actual multiplication in the assembly code.. */
00191   return (y * MapSizeX()) + x;
00192 }
00193 
00194 static inline TileIndex TileVirtXY(uint x, uint y)
00195 {
00196   return (y >> 4 << MapLogX()) + (x >> 4);
00197 }
00198 
00199 
00205 static inline uint TileX(TileIndex tile)
00206 {
00207   return tile & MapMaxX();
00208 }
00209 
00215 static inline uint TileY(TileIndex tile)
00216 {
00217   return tile >> MapLogX();
00218 }
00219 
00230 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
00231 {
00232   return (tidc.y << MapLogX()) + tidc.x;
00233 }
00234 
00235 
00236 #ifndef _DEBUG
00237 
00244   #define TILE_ADD(x,y) ((x) + (y))
00245 #else
00246   extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
00247     const char *exp, const char *file, int line);
00248   #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
00249 #endif
00250 
00258 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
00259 
00263 TileIndex TileAddWrap(TileIndex tile, int addx, int addy);
00264 
00271 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
00272 {
00273   extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00274 
00275   assert(IsValidDiagDirection(dir));
00276   return _tileoffs_by_diagdir[dir];
00277 }
00278 
00285 static inline TileIndexDiffC TileIndexDiffCByDir(Direction dir)
00286 {
00287   extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00288 
00289   assert(IsValidDirection(dir));
00290   return _tileoffs_by_dir[dir];
00291 }
00292 
00303 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
00304 {
00305   int x = TileX(tile) + diff.x;
00306   int y = TileY(tile) + diff.y;
00307   /* Negative value will become big positive value after cast */
00308   if ((uint)x >= MapSizeX() || (uint)y >= MapSizeY()) return INVALID_TILE;
00309   return TileXY(x, y);
00310 }
00311 
00319 static inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
00320 {
00321   TileIndexDiffC difference;
00322 
00323   difference.x = TileX(tile_a) - TileX(tile_b);
00324   difference.y = TileY(tile_a) - TileY(tile_b);
00325 
00326   return difference;
00327 }
00328 
00329 /* Functions to calculate distances */
00330 uint DistanceManhattan(TileIndex, TileIndex); 
00331 uint DistanceSquare(TileIndex, TileIndex); 
00332 uint DistanceMax(TileIndex, TileIndex); 
00333 uint DistanceMaxPlusManhattan(TileIndex, TileIndex); 
00334 uint DistanceFromEdge(TileIndex); 
00335 
00346 #define TILE_LOOP(var, w, h, tile)                                                      \
00347   for (uint var = tile, cur_h = (h); cur_h > 0; --cur_h, var += TileDiffXY(0, 1) - (w)) \
00348     for (uint cur_w = (w); cur_w > 0; --cur_w, var++)
00349 
00357 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
00358 {
00359   extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00360 
00361   assert(IsValidDiagDirection(dir));
00362   return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
00363 }
00364 
00371 static inline TileIndexDiff TileOffsByDir(Direction dir)
00372 {
00373   extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00374 
00375   assert(IsValidDirection(dir));
00376   return ToTileIndexDiff(_tileoffs_by_dir[dir]);
00377 }
00378 
00386 static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
00387 {
00388   return TILE_ADD(tile, TileOffsByDiagDir(dir));
00389 }
00390 
00398 static inline DiagDirection DiagdirBetweenTiles(TileIndex tile_from, TileIndex tile_to)
00399 {
00400   int dx = (int)TileX(tile_to) - (int)TileX(tile_from);
00401   int dy = (int)TileY(tile_to) - (int)TileY(tile_from);
00402   if (dx == 0) {
00403     if (dy == 0) return INVALID_DIAGDIR;
00404     return (dy < 0 ? DIAGDIR_NW : DIAGDIR_SE);
00405   } else {
00406     if (dy != 0) return INVALID_DIAGDIR;
00407     return (dx < 0 ? DIAGDIR_NE : DIAGDIR_SW);
00408   }
00409 }
00410 
00418 typedef bool TestTileOnSearchProc(TileIndex tile, void *user_data);
00419 
00423 bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data);
00424 
00428 bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_data);
00429 
00435 static inline TileIndex RandomTileSeed(uint32 r)
00436 {
00437   return TILE_MASK(r);
00438 }
00439 
00446 #define RandomTile() RandomTileSeed(Random())
00447 
00451 uint GetClosestWaterDistance(TileIndex tile, bool water);
00452 
00453 #endif /* MAP_FUNC_H */

Generated on Wed Dec 23 23:27:51 2009 for OpenTTD by  doxygen 1.5.6