author | truebrain |
Mon, 30 Jun 2008 13:51:28 +0000 | |
branch | noai |
changeset 11102 | aacdde10b4ad |
parent 10829 | 8a0ec0f0f928 |
child 11126 | 72d4c9314c72 |
permissions | -rw-r--r-- |
9723 | 1 |
/* $Id$ */ |
2 |
||
10455
22c441f5adf9
(svn r12997) [NoAI] -Sync: with trunk r12895:12996.
rubidium
parents:
9724
diff
changeset
|
3 |
/** @file map_func.h Functions related to maps. */ |
9723 | 4 |
|
5 |
#ifndef MAP_FUNC_H |
|
6 |
#define MAP_FUNC_H |
|
7 |
||
8 |
#include "tile_type.h" |
|
9 |
#include "map_type.h" |
|
10 |
#include "direction_func.h" |
|
11 |
||
12 |
extern uint _map_tile_mask; |
|
13 |
||
14 |
/** |
|
15 |
* 'Wraps' the given tile to it is within the map. It does |
|
16 |
* this by masking the 'high' bits of. |
|
17 |
* @param x the tile to 'wrap' |
|
18 |
*/ |
|
19 |
||
20 |
#define TILE_MASK(x) ((x) & _map_tile_mask) |
|
21 |
/** |
|
22 |
* Asserts when the tile is outside of the map. |
|
23 |
* @param x the tile to check |
|
24 |
*/ |
|
25 |
#define TILE_ASSERT(x) assert(TILE_MASK(x) == (x)); |
|
26 |
||
27 |
/** |
|
28 |
* Pointer to the tile-array. |
|
29 |
* |
|
30 |
* This variable points to the tile-array which contains the tiles of |
|
31 |
* the map. |
|
32 |
*/ |
|
33 |
extern Tile *_m; |
|
34 |
||
35 |
/** |
|
36 |
* Pointer to the extended tile-array. |
|
37 |
* |
|
38 |
* This variable points to the extended tile-array which contains the tiles |
|
39 |
* of the map. |
|
40 |
*/ |
|
41 |
extern TileExtended *_me; |
|
42 |
||
43 |
/** |
|
44 |
* Allocate a new map with the given size. |
|
45 |
*/ |
|
46 |
void AllocateMap(uint size_x, uint size_y); |
|
47 |
||
48 |
/** |
|
49 |
* Logarithm of the map size along the X side. |
|
50 |
* @note try to avoid using this one |
|
51 |
* @return 2^"return value" == MapSizeX() |
|
52 |
*/ |
|
53 |
static inline uint MapLogX() |
|
54 |
{ |
|
55 |
extern uint _map_log_x; |
|
56 |
return _map_log_x; |
|
57 |
} |
|
58 |
||
59 |
/** |
|
9724
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
60 |
* Logarithm of the map size along the y side. |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
61 |
* @note try to avoid using this one |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
62 |
* @return 2^"return value" == MapSizeY() |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
63 |
*/ |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
64 |
static inline uint MapLogY() |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
65 |
{ |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
66 |
extern uint _map_log_y; |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
67 |
return _map_log_y; |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
68 |
} |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
69 |
|
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
70 |
/** |
9723 | 71 |
* Get the size of the map along the X |
72 |
* @return the number of tiles along the X of the map |
|
73 |
*/ |
|
74 |
static inline uint MapSizeX() |
|
75 |
{ |
|
76 |
extern uint _map_size_x; |
|
77 |
return _map_size_x; |
|
78 |
} |
|
79 |
||
80 |
/** |
|
81 |
* Get the size of the map along the Y |
|
82 |
* @return the number of tiles along the Y of the map |
|
83 |
*/ |
|
84 |
static inline uint MapSizeY() |
|
85 |
{ |
|
86 |
extern uint _map_size_y; |
|
87 |
return _map_size_y; |
|
88 |
} |
|
89 |
||
90 |
/** |
|
91 |
* Get the size of the map |
|
92 |
* @return the number of tiles of the map |
|
93 |
*/ |
|
94 |
static inline uint MapSize() |
|
95 |
{ |
|
96 |
extern uint _map_size; |
|
97 |
return _map_size; |
|
98 |
} |
|
99 |
||
100 |
/** |
|
101 |
* Gets the maximum X coordinate within the map, including MP_VOID |
|
102 |
* @return the maximum X coordinate |
|
103 |
*/ |
|
104 |
static inline uint MapMaxX() |
|
105 |
{ |
|
106 |
return MapSizeX() - 1; |
|
107 |
} |
|
108 |
||
109 |
/** |
|
110 |
* Gets the maximum X coordinate within the map, including MP_VOID |
|
111 |
* @return the maximum X coordinate |
|
112 |
*/ |
|
113 |
static inline uint MapMaxY() |
|
114 |
{ |
|
115 |
return MapSizeY() - 1; |
|
116 |
} |
|
117 |
||
118 |
/** |
|
119 |
* Scales relative to the number of tiles. |
|
120 |
*/ |
|
121 |
uint ScaleByMapSize(uint); |
|
122 |
||
123 |
/** |
|
124 |
* Scale relative to the circumference of the map. |
|
125 |
*/ |
|
126 |
uint ScaleByMapSize1D(uint); |
|
127 |
||
128 |
/** |
|
129 |
* An offset value between to tiles. |
|
130 |
* |
|
131 |
* This value is used fro the difference between |
|
132 |
* to tiles. It can be added to a tileindex to get |
|
133 |
* the resulting tileindex of the start tile applied |
|
134 |
* with this saved difference. |
|
135 |
* |
|
136 |
* @see TileDiffXY(int, int) |
|
137 |
*/ |
|
138 |
typedef int32 TileIndexDiff; |
|
139 |
||
140 |
/** |
|
141 |
* Returns the TileIndex of a coordinate. |
|
142 |
* |
|
143 |
* @param x The x coordinate of the tile |
|
144 |
* @param y The y coordinate of the tile |
|
145 |
* @return The TileIndex calculated by the coordinate |
|
146 |
*/ |
|
147 |
static inline TileIndex TileXY(uint x, uint y) |
|
148 |
{ |
|
149 |
return (y * MapSizeX()) + x; |
|
150 |
} |
|
151 |
||
152 |
/** |
|
153 |
* Calculates an offset for the given coordinate(-offset). |
|
154 |
* |
|
155 |
* This function calculate an offset value which can be added to an |
|
156 |
* #TileIndex. The coordinates can be negative. |
|
157 |
* |
|
158 |
* @param x The offset in x direction |
|
159 |
* @param y The offset in y direction |
|
160 |
* @return The resulting offset value of the given coordinate |
|
161 |
* @see ToTileIndexDiff(TileIndexDiffC) |
|
162 |
*/ |
|
163 |
static inline TileIndexDiff TileDiffXY(int x, int y) |
|
164 |
{ |
|
165 |
/* Multiplication gives much better optimization on MSVC than shifting. |
|
166 |
* 0 << shift isn't optimized to 0 properly. |
|
167 |
* Typically x and y are constants, and then this doesn't result |
|
168 |
* in any actual multiplication in the assembly code.. */ |
|
169 |
return (y * MapSizeX()) + x; |
|
170 |
} |
|
171 |
||
172 |
static inline TileIndex TileVirtXY(uint x, uint y) |
|
173 |
{ |
|
174 |
return (y >> 4 << MapLogX()) + (x >> 4); |
|
175 |
} |
|
176 |
||
177 |
||
178 |
/** |
|
179 |
* Get the X component of a tile |
|
180 |
* @param tile the tile to get the X component of |
|
181 |
* @return the X component |
|
182 |
*/ |
|
183 |
static inline uint TileX(TileIndex tile) |
|
184 |
{ |
|
185 |
return tile & MapMaxX(); |
|
186 |
} |
|
187 |
||
188 |
/** |
|
189 |
* Get the Y component of a tile |
|
190 |
* @param tile the tile to get the Y component of |
|
191 |
* @return the Y component |
|
192 |
*/ |
|
193 |
static inline uint TileY(TileIndex tile) |
|
194 |
{ |
|
195 |
return tile >> MapLogX(); |
|
196 |
} |
|
197 |
||
198 |
/** |
|
199 |
* Return the offset between to tiles from a TileIndexDiffC struct. |
|
200 |
* |
|
201 |
* This function works like #TileDiffXY(int, int) and returns the |
|
202 |
* difference between two tiles. |
|
203 |
* |
|
204 |
* @param tidc The coordinate of the offset as TileIndexDiffC |
|
205 |
* @return The difference between two tiles. |
|
206 |
* @see TileDiffXY(int, int) |
|
207 |
*/ |
|
208 |
static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc) |
|
209 |
{ |
|
210 |
return (tidc.y << MapLogX()) + tidc.x; |
|
211 |
} |
|
212 |
||
213 |
||
214 |
#ifndef _DEBUG |
|
215 |
/** |
|
216 |
* Adds to tiles together. |
|
217 |
* |
|
218 |
* @param x One tile |
|
219 |
* @param y An other tile to add |
|
220 |
* @return The resulting tile(index) |
|
221 |
*/ |
|
222 |
#define TILE_ADD(x,y) ((x) + (y)) |
|
223 |
#else |
|
224 |
extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add, |
|
225 |
const char *exp, const char *file, int line); |
|
226 |
#define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__)) |
|
227 |
#endif |
|
228 |
||
229 |
/** |
|
230 |
* Adds a given offset to a tile. |
|
231 |
* |
|
232 |
* @param tile The tile to add an offset on it |
|
233 |
* @param x The x offset to add to the tile |
|
234 |
* @param y The y offset to add to the tile |
|
235 |
*/ |
|
236 |
#define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y)) |
|
237 |
||
238 |
/** |
|
239 |
* Adds an offset to a tile and check if we are still on the map. |
|
240 |
*/ |
|
9724
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
241 |
TileIndex TileAddWrap(TileIndex tile, int addx, int addy); |
9723 | 242 |
|
243 |
/** |
|
244 |
* Returns the TileIndexDiffC offset from a DiagDirection. |
|
245 |
* |
|
246 |
* @param dir The given direction |
|
247 |
* @return The offset as TileIndexDiffC value |
|
248 |
*/ |
|
249 |
static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir) |
|
250 |
{ |
|
251 |
extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END]; |
|
252 |
||
253 |
assert(IsValidDiagDirection(dir)); |
|
254 |
return _tileoffs_by_diagdir[dir]; |
|
255 |
} |
|
256 |
||
257 |
/** |
|
9724
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
258 |
* Returns the TileIndexDiffC offset from a Direction. |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
259 |
* |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
260 |
* @param dir The given direction |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
261 |
* @return The offset as TileIndexDiffC value |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
262 |
*/ |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
263 |
static inline TileIndexDiffC TileIndexDiffCByDir(Direction dir) |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
264 |
{ |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
265 |
extern const TileIndexDiffC _tileoffs_by_dir[DIR_END]; |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
266 |
|
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
267 |
assert(IsValidDirection(dir)); |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
268 |
return _tileoffs_by_dir[dir]; |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
269 |
} |
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
270 |
|
b39bc69bb2f2
(svn r12051) [NoAI] -Sync: with trunk (r11795:12050).
rubidium
parents:
9723
diff
changeset
|
271 |
/** |
9723 | 272 |
* Add a TileIndexDiffC to a TileIndex and returns the new one. |
273 |
* |
|
274 |
* Returns tile + the diff given in diff. If the result tile would end up |
|
275 |
* outside of the map, INVALID_TILE is returned instead. |
|
276 |
* |
|
277 |
* @param tile The base tile to add the offset on |
|
278 |
* @param diff The offset to add on the tile |
|
279 |
* @return The resulting TileIndex |
|
280 |
*/ |
|
281 |
static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff) |
|
282 |
{ |
|
283 |
int x = TileX(tile) + diff.x; |
|
284 |
int y = TileY(tile) + diff.y; |
|
285 |
if (x < 0 || y < 0 || x > (int)MapMaxX() || y > (int)MapMaxY()) |
|
286 |
return INVALID_TILE; |
|
287 |
else |
|
288 |
return TileXY(x, y); |
|
289 |
} |
|
290 |
||
291 |
/** |
|
292 |
* Returns the diff between two tiles |
|
293 |
* |
|
294 |
* @param tile_a from tile |
|
295 |
* @param tile_b to tile |
|
296 |
* @return the difference between tila_a and tile_b |
|
297 |
*/ |
|
298 |
static inline TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b) |
|
299 |
{ |
|
300 |
TileIndexDiffC difference; |
|
301 |
||
302 |
difference.x = TileX(tile_a) - TileX(tile_b); |
|
303 |
difference.y = TileY(tile_a) - TileY(tile_b); |
|
304 |
||
305 |
return difference; |
|
306 |
} |
|
307 |
||
308 |
/* Functions to calculate distances */ |
|
309 |
uint DistanceManhattan(TileIndex, TileIndex); ///< also known as L1-Norm. Is the shortest distance one could go over diagonal tracks (or roads) |
|
310 |
uint DistanceSquare(TileIndex, TileIndex); ///< euclidian- or L2-Norm squared |
|
311 |
uint DistanceMax(TileIndex, TileIndex); ///< also known as L-Infinity-Norm |
|
312 |
uint DistanceMaxPlusManhattan(TileIndex, TileIndex); ///< Max + Manhattan |
|
313 |
uint DistanceFromEdge(TileIndex); ///< shortest distance from any edge of the map |
|
314 |
||
315 |
/** |
|
316 |
* Starts a loop which iterates to a square of tiles |
|
317 |
* |
|
318 |
* This macro starts 2 nested loops which iterates over a square of tiles. |
|
319 |
* |
|
320 |
* @param var The name of the variable which contains the current tile |
|
321 |
* @param w The width (x-width) of the square |
|
322 |
* @param h The heigth (y-width) of the square |
|
323 |
* @param tile The start tile of the square |
|
324 |
*/ |
|
325 |
#define BEGIN_TILE_LOOP(var, w, h, tile) \ |
|
326 |
{ \ |
|
327 |
int h_cur = h; \ |
|
328 |
uint var = tile; \ |
|
329 |
do { \ |
|
330 |
int w_cur = w; \ |
|
331 |
do { |
|
332 |
/** |
|
333 |
* Ends the square-loop used before |
|
334 |
* |
|
335 |
* @see BEGIN_TILE_LOOP |
|
336 |
*/ |
|
337 |
#define END_TILE_LOOP(var, w, h, tile) \ |
|
338 |
} while (++var, --w_cur != 0); \ |
|
339 |
} while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \ |
|
340 |
} |
|
341 |
/** |
|
342 |
* Convert a DiagDirection to a TileIndexDiff |
|
343 |
* |
|
344 |
* @param dir The DiagDirection |
|
345 |
* @return The resulting TileIndexDiff |
|
346 |
* @see TileIndexDiffCByDiagDir |
|
347 |
*/ |
|
348 |
static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir) |
|
349 |
{ |
|
350 |
extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END]; |
|
351 |
||
352 |
assert(IsValidDiagDirection(dir)); |
|
353 |
return ToTileIndexDiff(_tileoffs_by_diagdir[dir]); |
|
354 |
} |
|
355 |
||
356 |
/** |
|
357 |
* Convert a Direction to a TileIndexDiff. |
|
358 |
* |
|
359 |
* @param dir The direction to convert from |
|
360 |
* @return The resulting TileIndexDiff |
|
361 |
*/ |
|
362 |
static inline TileIndexDiff TileOffsByDir(Direction dir) |
|
363 |
{ |
|
364 |
extern const TileIndexDiffC _tileoffs_by_dir[DIR_END]; |
|
365 |
||
366 |
assert(IsValidDirection(dir)); |
|
367 |
return ToTileIndexDiff(_tileoffs_by_dir[dir]); |
|
368 |
} |
|
369 |
||
370 |
/** |
|
371 |
* Adds a DiagDir to a tile. |
|
372 |
* |
|
373 |
* @param tile The current tile |
|
374 |
* @param dir The direction in which we want to step |
|
375 |
* @return the moved tile |
|
376 |
*/ |
|
377 |
static inline TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir) |
|
378 |
{ |
|
379 |
return TILE_ADD(tile, TileOffsByDiagDir(dir)); |
|
380 |
} |
|
381 |
||
382 |
/** |
|
383 |
* A callback function type for searching tiles. |
|
384 |
* |
|
385 |
* @param tile The tile to test |
|
386 |
* @param data additional data for the callback function to use |
|
387 |
* @return A boolean value, depend on the definition of the function. |
|
388 |
*/ |
|
389 |
typedef bool TestTileOnSearchProc(TileIndex tile, uint32 data); |
|
390 |
||
391 |
/** |
|
392 |
* Searches for some cirumstances of a tile around a given tile with a helper function. |
|
393 |
*/ |
|
10829 | 394 |
bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, uint32 data); |
9723 | 395 |
|
396 |
/** |
|
397 |
* Get a random tile out of a given seed. |
|
398 |
* @param r the random 'seed' |
|
399 |
* @return a valid tile |
|
400 |
*/ |
|
401 |
static inline TileIndex RandomTileSeed(uint32 r) |
|
402 |
{ |
|
403 |
return TILE_MASK(r); |
|
404 |
} |
|
405 |
||
406 |
/** |
|
407 |
* Get a valid random tile. |
|
408 |
* @note a define so 'random' gets inserted in the place where it is actually |
|
409 |
* called, thus making the random traces more explicit. |
|
410 |
* @return a valid tile |
|
411 |
*/ |
|
412 |
#define RandomTile() RandomTileSeed(Random()) |
|
413 |
||
414 |
#endif /* MAP_FUNC_H */ |