# map_func.h

Go to the documentation of this file.

    00001 /* $Id: map_func.h 14847 2009-01-05 17:48:54Z rubidium $ */
    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, void *user_data);
    00390
    00394 bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data);
    00395
    00399 bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_data);
    00400
    00406 static inline TileIndex RandomTileSeed(uint32 r)
    00407 {
    00408   return TILE_MASK(r);
    00409 }
    00410
    00417 #define RandomTile() RandomTileSeed(Random())
    00418
    00419 #endif /* MAP_FUNC_H */