# map_func.h

Go to the documentation of this file.

    00001 /* $Id: map_func.h 15620 2009-03-05 17:21:42Z 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
    00028 extern Tile *_m;
    00029
    00036 extern TileExtended *_me;
    00037
    00041 void AllocateMap(uint size_x, uint size_y);
    00042
    00048 static inline uint MapLogX()
    00049 {
    00050   extern uint _map_log_x;
    00051   return _map_log_x;
    00052 }
    00053
    00059 static inline uint MapLogY()
    00060 {
    00061   extern uint _map_log_y;
    00062   return _map_log_y;
    00063 }
    00064
    00069 static inline uint MapSizeX()
    00070 {
    00071   extern uint _map_size_x;
    00072   return _map_size_x;
    00073 }
    00074
    00079 static inline uint MapSizeY()
    00080 {
    00081   extern uint _map_size_y;
    00082   return _map_size_y;
    00083 }
    00084
    00089 static inline uint MapSize()
    00090 {
    00091   extern uint _map_size;
    00092   return _map_size;
    00093 }
    00094
    00099 static inline uint MapMaxX()
    00100 {
    00101   return MapSizeX() - 1;
    00102 }
    00103
    00108 static inline uint MapMaxY()
    00109 {
    00110   return MapSizeY() - 1;
    00111 }
    00112
    00116 uint ScaleByMapSize(uint);
    00117
    00121 uint ScaleByMapSize1D(uint);
    00122
    00133 typedef int32 TileIndexDiff;
    00134
    00142 static inline TileIndex TileXY(uint x, uint y)
    00143 {
    00144   return (y * MapSizeX()) + x;
    00145 }
    00146
    00158 static inline TileIndexDiff TileDiffXY(int x, int y)
    00159 {
    00160   /* Multiplication gives much better optimization on MSVC than shifting.
    00161    * 0 << shift isn't optimized to 0 properly.
    00162    * Typically x and y are constants, and then this doesn't result
    00163    * in any actual multiplication in the assembly code.. */
    00164   return (y * MapSizeX()) + x;
    00165 }
    00166
    00167 static inline TileIndex TileVirtXY(uint x, uint y)
    00168 {
    00169   return (y >> 4 << MapLogX()) + (x >> 4);
    00170 }
    00171
    00172
    00178 static inline uint TileX(TileIndex tile)
    00179 {
    00180   return tile & MapMaxX();
    00181 }
    00182
    00188 static inline uint TileY(TileIndex tile)
    00189 {
    00190   return tile >> MapLogX();
    00191 }
    00192
    00203 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
    00204 {
    00205   return (tidc.y << MapLogX()) + tidc.x;
    00206 }
    00207
    00208
    00209 #ifndef _DEBUG
    00210
    00217   #define TILE_ADD(x,y) ((x) + (y))
    00218 #else
    00219   extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add,
    00220     const char *exp, const char *file, int line);
    00221   #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__))
    00222 #endif
    00223
    00231 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y))
    00232
    00236 TileIndex TileAddWrap(TileIndex tile, int addx, int addy);
    00237
    00244 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
    00245 {
    00246   extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
    00247
    00248   assert(IsValidDiagDirection(dir));
    00249   return _tileoffs_by_diagdir[dir];
    00250 }
    00251
    00258 static inline TileIndexDiffC TileIndexDiffCByDir(Direction dir)
    00259 {
    00260   extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
    00261
    00262   assert(IsValidDirection(dir));
    00263   return _tileoffs_by_dir[dir];
    00264 }
    00265
    00276 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
    00277 {
    00278   int x = TileX(tile) + diff.x;
    00279   int y = TileY(tile) + diff.y;
    00280   if (x < 0 || y < 0 || x > (int)MapMaxX() || y > (int)MapMaxY())
    00281     return INVALID_TILE;
    00282   else
    00283     return TileXY(x, y);
    00284 }
    00285
    00293 static inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
    00294 {
    00295   TileIndexDiffC difference;
    00296
    00297   difference.x = TileX(tile_a) - TileX(tile_b);
    00298   difference.y = TileY(tile_a) - TileY(tile_b);
    00299
    00300   return difference;
    00301 }
    00302
    00303 /* Functions to calculate distances */
    00304 uint DistanceManhattan(TileIndex, TileIndex);
    00305 uint DistanceSquare(TileIndex, TileIndex);
    00306 uint DistanceMax(TileIndex, TileIndex);
    00307 uint DistanceMaxPlusManhattan(TileIndex, TileIndex);
    00308 uint DistanceFromEdge(TileIndex);
    00309
    00320 #define BEGIN_TILE_LOOP(var, w, h, tile)                      \
    00321   {                                                        \
    00322     int h_cur = h;                                         \
    00323     uint var = tile;                                       \
    00324     do {                                                   \
    00325       int w_cur = w;                                       \
    00326       do {
    00327
    00332 #define END_TILE_LOOP(var, w, h, tile)                        \
    00333       } while (++var, --w_cur != 0);                       \
    00334     } while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \
    00335   }
    00336
    00343 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
    00344 {
    00345   extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END];
    00346
    00347   assert(IsValidDiagDirection(dir));
    00348   return ToTileIndexDiff(_tileoffs_by_diagdir[dir]);
    00349 }
    00350
    00357 static inline TileIndexDiff TileOffsByDir(Direction dir)
    00358 {
    00359   extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
    00360
    00361   assert(IsValidDirection(dir));
    00362   return ToTileIndexDiff(_tileoffs_by_dir[dir]);
    00363 }
    00364
    00372 static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
    00373 {
    00374   return TILE_ADD(tile, TileOffsByDiagDir(dir));
    00375 }
    00376
    00384 typedef bool TestTileOnSearchProc(TileIndex tile, void *user_data);
    00385
    00389 bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data);
    00390
    00394 bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_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 */