00001
00002
00003
00004
00005
00006
00007
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
00129
00130
00131 return ((n << (MapLogX() + MapLogY() - 12)) + (1 << 4) - 1) >> 4;
00132 }
00133
00134
00141 static inline uint ScaleByMapSize1D(uint n)
00142 {
00143
00144
00145
00146
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
00188
00189
00190
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
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
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