107 static inline uint MapMaxY() |
123 static inline uint MapMaxY() |
108 { |
124 { |
109 return MapSizeY() - 1; |
125 return MapSizeY() - 1; |
110 } |
126 } |
111 |
127 |
112 /* Scale a number relative to the map size */ |
128 /** |
113 uint ScaleByMapSize(uint); // Scale relative to the number of tiles |
129 * Scales relative to the number of tiles. |
114 uint ScaleByMapSize1D(uint); // Scale relative to the circumference of the map |
130 */ |
115 |
131 uint ScaleByMapSize(uint); |
|
132 |
|
133 /** |
|
134 * Scale relative to the circumference of the map. |
|
135 */ |
|
136 uint ScaleByMapSize1D(uint); |
|
137 |
|
138 /** |
|
139 * The index/ID of a Tile. |
|
140 */ |
116 typedef uint32 TileIndex; |
141 typedef uint32 TileIndex; |
|
142 |
|
143 /** |
|
144 * An offset value between to tiles. |
|
145 * |
|
146 * This value is used fro the difference between |
|
147 * to tiles. It can be added to a tileindex to get |
|
148 * the resulting tileindex of the start tile applied |
|
149 * with this saved difference. |
|
150 * |
|
151 * @see TileDiffXY(int, int) |
|
152 */ |
117 typedef int32 TileIndexDiff; |
153 typedef int32 TileIndexDiff; |
118 |
154 |
|
155 /** |
|
156 * Returns the TileIndex of a coordinate. |
|
157 * |
|
158 * @param x The x coordinate of the tile |
|
159 * @param y The y coordinate of the tile |
|
160 * @return The TileIndex calculated by the coordinate |
|
161 */ |
119 static inline TileIndex TileXY(uint x, uint y) |
162 static inline TileIndex TileXY(uint x, uint y) |
120 { |
163 { |
121 return (y * MapSizeX()) + x; |
164 return (y * MapSizeX()) + x; |
122 } |
165 } |
123 |
166 |
|
167 /** |
|
168 * Calculates an offset for the given coordinate(-offset). |
|
169 * |
|
170 * This function calculate an offset value which can be added to an |
|
171 * #TileIndex. The coordinates can be negative. |
|
172 * |
|
173 * @param x The offset in x direction |
|
174 * @param y The offset in y direction |
|
175 * @return The resulting offset value of the given coordinate |
|
176 * @see ToTileIndexDiff(TileIndexDiffC) |
|
177 */ |
124 static inline TileIndexDiff TileDiffXY(int x, int y) |
178 static inline TileIndexDiff TileDiffXY(int x, int y) |
125 { |
179 { |
126 /* Multiplication gives much better optimization on MSVC than shifting. |
180 /* Multiplication gives much better optimization on MSVC than shifting. |
127 * 0 << shift isn't optimized to 0 properly. |
181 * 0 << shift isn't optimized to 0 properly. |
128 * Typically x and y are constants, and then this doesn't result |
182 * Typically x and y are constants, and then this doesn't result |
165 static inline uint TileY(TileIndex tile) |
219 static inline uint TileY(TileIndex tile) |
166 { |
220 { |
167 return tile >> MapLogX(); |
221 return tile >> MapLogX(); |
168 } |
222 } |
169 |
223 |
170 |
224 /** |
|
225 * A pair-construct of a TileIndexDiff. |
|
226 * |
|
227 * This can be used to save the difference between to |
|
228 * tiles as a pair of x and y value. |
|
229 */ |
171 struct TileIndexDiffC { |
230 struct TileIndexDiffC { |
172 int16 x; |
231 int16 x; ///< The x value of the coordinate |
173 int16 y; |
232 int16 y; ///< The y value of the coordinate |
174 }; |
233 }; |
175 |
234 |
|
235 /** |
|
236 * Return the offset between to tiles from a TileIndexDiffC struct. |
|
237 * |
|
238 * This function works like #TileDiffXY(int, int) and returns the |
|
239 * difference between two tiles. |
|
240 * |
|
241 * @param tidc The coordinate of the offset as TileIndexDiffC |
|
242 * @return The difference between two tiles. |
|
243 * @see TileDiffXY(int, int) |
|
244 */ |
176 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc) |
245 static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc) |
177 { |
246 { |
178 return (tidc.y << MapLogX()) + tidc.x; |
247 return (tidc.y << MapLogX()) + tidc.x; |
179 } |
248 } |
180 |
249 |
181 |
250 |
182 #ifndef _DEBUG |
251 #ifndef _DEBUG |
|
252 /** |
|
253 * Adds to tiles together. |
|
254 * |
|
255 * @param x One tile |
|
256 * @param y An other tile to add |
|
257 * @return The resulting tile(index) |
|
258 */ |
183 #define TILE_ADD(x,y) ((x) + (y)) |
259 #define TILE_ADD(x,y) ((x) + (y)) |
184 #else |
260 #else |
185 extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add, |
261 extern TileIndex TileAdd(TileIndex tile, TileIndexDiff add, |
186 const char *exp, const char *file, int line); |
262 const char *exp, const char *file, int line); |
187 #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__)) |
263 #define TILE_ADD(x, y) (TileAdd((x), (y), #x " + " #y, __FILE__, __LINE__)) |
188 #endif |
264 #endif |
189 |
265 |
|
266 /** |
|
267 * Adds a given offset to a tile. |
|
268 * |
|
269 * @param tile The tile to add an offset on it |
|
270 * @param x The x offset to add to the tile |
|
271 * @param y The y offset to add to the tile |
|
272 */ |
190 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y)) |
273 #define TILE_ADDXY(tile, x, y) TILE_ADD(tile, TileDiffXY(x, y)) |
191 |
274 |
|
275 /** |
|
276 * Adds an offset to a tile and check if we are still on the map. |
|
277 */ |
192 uint TileAddWrap(TileIndex tile, int addx, int addy); |
278 uint TileAddWrap(TileIndex tile, int addx, int addy); |
193 |
279 |
|
280 /** |
|
281 * Returns the TileIndexDiffC offset from a DiagDirection. |
|
282 * |
|
283 * @param dir The given direction |
|
284 * @return The offset as TileIndexDiffC value |
|
285 */ |
194 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir) |
286 static inline TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir) |
195 { |
287 { |
196 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END]; |
288 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END]; |
197 |
289 |
198 assert(IsValidDiagDirection(dir)); |
290 assert(IsValidDiagDirection(dir)); |
199 return _tileoffs_by_diagdir[dir]; |
291 return _tileoffs_by_diagdir[dir]; |
200 } |
292 } |
201 |
293 /** |
202 /* Returns tile + the diff given in diff. If the result tile would end up |
294 * Add a TileIndexDiffC to a TileIndex and returns the new one. |
|
295 * |
|
296 * Returns tile + the diff given in diff. If the result tile would end up |
203 * outside of the map, INVALID_TILE is returned instead. |
297 * outside of the map, INVALID_TILE is returned instead. |
|
298 * |
|
299 * @param tile The base tile to add the offset on |
|
300 * @param diff The offset to add on the tile |
|
301 * @return The resulting TileIndex |
204 */ |
302 */ |
205 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff) |
303 static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff) |
206 { |
304 { |
207 int x = TileX(tile) + diff.x; |
305 int x = TileX(tile) + diff.x; |
208 int y = TileY(tile) + diff.y; |
306 int y = TileY(tile) + diff.y; |
234 uint DistanceSquare(TileIndex, TileIndex); ///< euclidian- or L2-Norm squared |
332 uint DistanceSquare(TileIndex, TileIndex); ///< euclidian- or L2-Norm squared |
235 uint DistanceMax(TileIndex, TileIndex); ///< also known as L-Infinity-Norm |
333 uint DistanceMax(TileIndex, TileIndex); ///< also known as L-Infinity-Norm |
236 uint DistanceMaxPlusManhattan(TileIndex, TileIndex); ///< Max + Manhattan |
334 uint DistanceMaxPlusManhattan(TileIndex, TileIndex); ///< Max + Manhattan |
237 uint DistanceFromEdge(TileIndex); ///< shortest distance from any edge of the map |
335 uint DistanceFromEdge(TileIndex); ///< shortest distance from any edge of the map |
238 |
336 |
239 |
337 /** |
|
338 * Starts a loop which iterates to a square of tiles |
|
339 * |
|
340 * This macro starts 2 nested loops which iterates over a square of tiles. |
|
341 * |
|
342 * @param var The name of the variable which contains the current tile |
|
343 * @param w The width (x-width) of the square |
|
344 * @param h The heigth (y-width) of the square |
|
345 * @param tile The start tile of the square |
|
346 */ |
240 #define BEGIN_TILE_LOOP(var, w, h, tile) \ |
347 #define BEGIN_TILE_LOOP(var, w, h, tile) \ |
241 { \ |
348 { \ |
242 int h_cur = h; \ |
349 int h_cur = h; \ |
243 uint var = tile; \ |
350 uint var = tile; \ |
244 do { \ |
351 do { \ |
245 int w_cur = w; \ |
352 int w_cur = w; \ |
246 do { |
353 do { |
247 |
354 /** |
|
355 * Ends the square-loop used before |
|
356 * |
|
357 * @see BEGIN_TILE_LOOP |
|
358 */ |
248 #define END_TILE_LOOP(var, w, h, tile) \ |
359 #define END_TILE_LOOP(var, w, h, tile) \ |
249 } while (++var, --w_cur != 0); \ |
360 } while (++var, --w_cur != 0); \ |
250 } while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \ |
361 } while (var += TileDiffXY(0, 1) - (w), --h_cur != 0); \ |
251 } |
362 } |
252 |
363 /** |
|
364 * Convert a DiagDirection to a TileIndexDiff |
|
365 * |
|
366 * @param dir The DiagDirection |
|
367 * @return The resulting TileIndexDiff |
|
368 * @see TileIndexDiffCByDiagDir |
|
369 */ |
253 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir) |
370 static inline TileIndexDiff TileOffsByDiagDir(DiagDirection dir) |
254 { |
371 { |
255 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END]; |
372 extern const TileIndexDiffC _tileoffs_by_diagdir[DIAGDIR_END]; |
256 |
373 |
257 assert(IsValidDiagDirection(dir)); |
374 assert(IsValidDiagDirection(dir)); |
258 return ToTileIndexDiff(_tileoffs_by_diagdir[dir]); |
375 return ToTileIndexDiff(_tileoffs_by_diagdir[dir]); |
259 } |
376 } |
260 |
377 |
|
378 /** |
|
379 * Convert a Direction to a TileIndexDiff. |
|
380 * |
|
381 * @param dir The direction to convert from |
|
382 * @return The resulting TileIndexDiff |
|
383 */ |
261 static inline TileIndexDiff TileOffsByDir(Direction dir) |
384 static inline TileIndexDiff TileOffsByDir(Direction dir) |
262 { |
385 { |
263 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END]; |
386 extern const TileIndexDiffC _tileoffs_by_dir[DIR_END]; |
264 |
387 |
265 assert(IsValidDirection(dir)); |
388 assert(IsValidDirection(dir)); |
266 return ToTileIndexDiff(_tileoffs_by_dir[dir]); |
389 return ToTileIndexDiff(_tileoffs_by_dir[dir]); |
267 } |
390 } |
268 |
391 |
|
392 /** |
|
393 * A callback function type for searching tiles. |
|
394 * |
|
395 * @param tile The tile to test |
|
396 * @param data additional data for the callback function to use |
|
397 * @return A boolean value, depend on the definition of the function. |
|
398 */ |
269 typedef bool TestTileOnSearchProc(TileIndex tile, uint32 data); |
399 typedef bool TestTileOnSearchProc(TileIndex tile, uint32 data); |
|
400 |
|
401 /** |
|
402 * Searches for some cirumstances of a tile around a given tile with a helper function. |
|
403 */ |
270 bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data); |
404 bool CircularTileSearch(TileIndex tile, uint size, TestTileOnSearchProc proc, uint32 data); |
271 |
405 |
272 /* Approximation of the length of a straight track, relative to a diagonal |
406 /** Approximation of the length of a straight track, relative to a diagonal |
273 * track (ie the size of a tile side). #defined instead of const so it can |
407 * track (ie the size of a tile side). |
|
408 * |
|
409 * #defined instead of const so it can |
274 * stay integer. (no runtime float operations) Is this needed? |
410 * stay integer. (no runtime float operations) Is this needed? |
275 * Watch out! There are _no_ brackets around here, to prevent intermediate |
411 * Watch out! There are _no_ brackets around here, to prevent intermediate |
276 * rounding! Be careful when using this! |
412 * rounding! Be careful when using this! |
277 * This value should be sqrt(2)/2 ~ 0.7071 */ |
413 * This value should be sqrt(2)/2 ~ 0.7071 */ |
278 #define STRAIGHT_TRACK_LENGTH 7071/10000 |
414 #define STRAIGHT_TRACK_LENGTH 7071/10000 |