map_func.h

Go to the documentation of this file.
00001 /* $Id: map_func.h 11961 2008-01-23 17:08:35Z belugas $ */
00002 
00005 #ifndef MAP_FUNC_H
00006 #define MAP_FUNC_H
00007 
00008 #include "tile_type.h"
00009 #include "map_type.h"
00010 #include "direction_func.h"
00011 
00012 extern uint _map_tile_mask;
00013 
00020 #define TILE_MASK(x) ((x) & _map_tile_mask)
00021 
00025 #define TILE_ASSERT(x) assert(TILE_MASK(x) == (x));
00026 
00033 extern Tile *_m;
00034 
00041 extern TileExtended *_me;
00042 
00046 void AllocateMap(uint size_x, uint size_y);
00047 
00053 static inline uint MapLogX()
00054 {
00055   extern uint _map_log_x;
00056   return _map_log_x;
00057 }
00058 
00064 static inline uint MapLogY()
00065 {
00066   extern uint _map_log_y;
00067   return _map_log_y;
00068 }
00069 
00074 static inline uint MapSizeX()
00075 {
00076   extern uint _map_size_x;
00077   return _map_size_x;
00078 }
00079 
00084 static inline uint MapSizeY()
00085 {
00086   extern uint _map_size_y;
00087   return _map_size_y;
00088 }
00089 
00094 static inline uint MapSize()
00095 {
00096   extern uint _map_size;
00097   return _map_size;
00098 }
00099 
00104 static inline uint MapMaxX()
00105 {
00106   return MapSizeX() - 1;
00107 }
00108 
00113 static inline uint MapMaxY()
00114 {
00115   return MapSizeY() - 1;
00116 }
00117 
00121 uint ScaleByMapSize(uint);
00122 
00126 uint ScaleByMapSize1D(uint);
00127 
00138 typedef int32 TileIndexDiff;
00139 
00147 static inline TileIndex TileXY(uint x, uint y)
00148 {
00149   return (y * MapSizeX()) + x;
00150 }
00151 
00163 static inline TileIndexDiff TileDiffXY(int x, int y)
00164 {
00165   /* Multiplication gives much better optimization on MSVC than shifting.
00166    * 0 << shift isn't optimized to 0 properly.
00167    * Typically x and y are constants, and then this doesn't result
00168    * in any actual multiplication in the assembly code.. */
00169   return (y * MapSizeX()) + x;
00170 }
00171 
00172 static inline TileIndex TileVirtXY(uint x, uint y)
00173 {
00174   return (y >> 4 << MapLogX()) + (x >> 4);
00175 }
00176 
00177 
00183 static inline uint TileX(TileIndex tile)
00184 {
00185   return tile & MapMaxX();
00186 }
00187 
00193 static inline uint TileY(TileIndex tile)
00194 {
00195   return tile >> MapLogX();
00196 }
00197 
00208 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
00209 {
00210   return (tidc.y << MapLogX()) + tidc.x;
00211 }
00212 
00213 
00214 #ifndef _DEBUG
00215 
00222   #define TILE_ADD(x,y) ((x) + (y))
00223 #else
00224   extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
00225     const char *exp, const char *file, int line);
00226   #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
00227 #endif
00228 
00236 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
00237 
00241 TileIndex TileAddWrap(TileIndex tile, int addx, int addy);
00242 
00249 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
00250 {
00251   extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00252 
00253   assert(IsValidDiagDirection(dir));
00254   return _tileoffs_by_diagdir[dir];
00255 }
00256 
00263 static inline TileIndexDiffC TileIndexDiffCByDir(Direction dir)
00264 {
00265   extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00266 
00267   assert(IsValidDirection(dir));
00268   return _tileoffs_by_dir[dir];
00269 }
00270 
00281 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
00282 {
00283   int x = TileX(tile) + diff.x;
00284   int y = TileY(tile) + diff.y;
00285   if (x < 0 || y < 0 || x > (int)MapMaxX() || y > (int)MapMaxY())
00286     return INVALID_TILE;
00287   else
00288     return TileXY(x, y);
00289 }
00290 
00298 static inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
00299 {
00300   TileIndexDiffC difference;
00301 
00302   difference.x = TileX(tile_a) - TileX(tile_b);
00303   difference.y = TileY(tile_a) - TileY(tile_b);
00304 
00305   return difference;
00306 }
00307 
00308 /* Functions to calculate distances */
00309 uint DistanceManhattan(TileIndex, TileIndex); 
00310 uint DistanceSquare(TileIndex, TileIndex); 
00311 uint DistanceMax(TileIndex, TileIndex); 
00312 uint DistanceMaxPlusManhattan(TileIndex, TileIndex); 
00313 uint DistanceFromEdge(TileIndex); 
00314 
00325 #define BEGIN_TILE_LOOP(var, w, h, tile)                      \
00326   {                                                        \
00327     int h_cur = h;                                         \
00328     uint var = tile;                                       \
00329     do {                                                   \
00330       int w_cur = w;                                       \
00331       do {
00332 
00337 #define END_TILE_LOOP(var, w, h, tile)                        \
00338       } while (++var, --w_cur != 0);                       \
00339     } while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \
00340   }
00341 
00348 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
00349 {
00350   extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
00351 
00352   assert(IsValidDiagDirection(dir));
00353   return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
00354 }
00355 
00362 static inline TileIndexDiff TileOffsByDir(Direction dir)
00363 {
00364   extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
00365 
00366   assert(IsValidDirection(dir));
00367   return ToTileIndexDiff(_tileoffs_by_dir[dir]);
00368 }
00369 
00377 static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
00378 {
00379   return TILE_ADD(tile, TileOffsByDiagDir(dir));
00380 }
00381 
00389 typedef bool TestTileOnSearchProc(TileIndex tile, uint32 data);
00390 
00394 bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data);
00395 
00401 static inline TileIndex RandomTileSeed(uint32 r)
00402 {
00403   return TILE_MASK(r);
00404 }
00405 
00412 #define RandomTile() RandomTileSeed(Random())
00413 
00414 #endif /* MAP_FUNC_H */

Generated on Mon Sep 22 20:34:16 2008 for openttd by  doxygen 1.5.6