26 /** Define basic enum properties */ |
31 /** Define basic enum properties */ |
27 template <> struct EnumPropsT<RailType> : MakeEnumPropsT<RailType, byte, RAILTYPE_BEGIN, RAILTYPE_END, INVALID_RAILTYPE> {}; |
32 template <> struct EnumPropsT<RailType> : MakeEnumPropsT<RailType, byte, RAILTYPE_BEGIN, RAILTYPE_END, INVALID_RAILTYPE> {}; |
28 typedef TinyEnumT<RailType> RailTypeByte; |
33 typedef TinyEnumT<RailType> RailTypeByte; |
29 |
34 |
30 |
35 |
31 /** These are used to specify a single track. |
36 /** |
32 * Can be translated to a trackbit with TrackToTrackbit */ |
37 * These are used to specify a single track. |
|
38 * Can be translated to a trackbit with TrackToTrackbit |
|
39 */ |
33 enum Track { |
40 enum Track { |
34 TRACK_BEGIN = 0, |
41 TRACK_BEGIN = 0, ///< Used for iterations |
35 TRACK_X = 0, |
42 TRACK_X = 0, ///< Track along the x-axis (north-east to south-west) |
36 TRACK_Y = 1, |
43 TRACK_Y = 1, ///< Track along the y-axis (north-west to south-east) |
37 TRACK_UPPER = 2, |
44 TRACK_UPPER = 2, ///< Track in the upper corner of the tile (north) |
38 TRACK_LOWER = 3, |
45 TRACK_LOWER = 3, ///< Track in the lower corner of the tile (south) |
39 TRACK_LEFT = 4, |
46 TRACK_LEFT = 4, ///< Track in the left corner of the tile (west) |
40 TRACK_RIGHT = 5, |
47 TRACK_RIGHT = 5, ///< Track in the right corner of the tile (east) |
41 TRACK_END, |
48 TRACK_END, ///< Used for iterations |
42 INVALID_TRACK = 0xFF |
49 INVALID_TRACK = 0xFF ///< Flag for an invalid track |
43 }; |
50 }; |
44 |
51 |
45 /** Allow incrementing of Track variables */ |
52 /** Allow incrementing of Track variables */ |
46 DECLARE_POSTFIX_INCREMENT(Track); |
53 DECLARE_POSTFIX_INCREMENT(Track); |
47 /** Define basic enum properties */ |
54 /** Define basic enum properties */ |
48 template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK> {}; |
55 template <> struct EnumPropsT<Track> : MakeEnumPropsT<Track, byte, TRACK_BEGIN, TRACK_END, INVALID_TRACK> {}; |
49 typedef TinyEnumT<Track> TrackByte; |
56 typedef TinyEnumT<Track> TrackByte; |
50 |
57 |
51 |
58 |
52 /** Convert an Axis to the corresponding Track |
59 /** |
|
60 * Convert an Axis to the corresponding Track |
53 * AXIS_X -> TRACK_X |
61 * AXIS_X -> TRACK_X |
54 * AXIS_Y -> TRACK_Y |
62 * AXIS_Y -> TRACK_Y |
55 * Uses the fact that they share the same internal encoding |
63 * Uses the fact that they share the same internal encoding |
|
64 * |
|
65 * @param a the axis to convert |
|
66 * @return the track corresponding to the axis |
56 */ |
67 */ |
57 static inline Track AxisToTrack(Axis a) |
68 static inline Track AxisToTrack(Axis a) |
58 { |
69 { |
59 return (Track)a; |
70 return (Track)a; |
60 } |
71 } |
61 |
72 |
62 |
73 |
63 /** Bitfield corresponding to Track */ |
74 /** Bitfield corresponding to Track */ |
64 enum TrackBits { |
75 enum TrackBits { |
65 TRACK_BIT_NONE = 0U, |
76 TRACK_BIT_NONE = 0U, ///< No track |
66 TRACK_BIT_X = 1U << TRACK_X, |
77 TRACK_BIT_X = 1U << TRACK_X, ///< X-axis track |
67 TRACK_BIT_Y = 1U << TRACK_Y, |
78 TRACK_BIT_Y = 1U << TRACK_Y, ///< Y-axis track |
68 TRACK_BIT_UPPER = 1U << TRACK_UPPER, |
79 TRACK_BIT_UPPER = 1U << TRACK_UPPER, ///< Upper track |
69 TRACK_BIT_LOWER = 1U << TRACK_LOWER, |
80 TRACK_BIT_LOWER = 1U << TRACK_LOWER, ///< Lower track |
70 TRACK_BIT_LEFT = 1U << TRACK_LEFT, |
81 TRACK_BIT_LEFT = 1U << TRACK_LEFT, ///< Left track |
71 TRACK_BIT_RIGHT = 1U << TRACK_RIGHT, |
82 TRACK_BIT_RIGHT = 1U << TRACK_RIGHT, ///< Right track |
72 TRACK_BIT_CROSS = TRACK_BIT_X | TRACK_BIT_Y, |
83 TRACK_BIT_CROSS = TRACK_BIT_X | TRACK_BIT_Y, ///< X-Y-axis cross |
73 TRACK_BIT_HORZ = TRACK_BIT_UPPER | TRACK_BIT_LOWER, |
84 TRACK_BIT_HORZ = TRACK_BIT_UPPER | TRACK_BIT_LOWER, ///< Upper and lower track |
74 TRACK_BIT_VERT = TRACK_BIT_LEFT | TRACK_BIT_RIGHT, |
85 TRACK_BIT_VERT = TRACK_BIT_LEFT | TRACK_BIT_RIGHT, ///< Left and right track |
75 TRACK_BIT_3WAY_NE = TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT, |
86 TRACK_BIT_3WAY_NE = TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT,///< "Arrow" to the north-east |
76 TRACK_BIT_3WAY_SE = TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_RIGHT, |
87 TRACK_BIT_3WAY_SE = TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_RIGHT,///< "Arrow" to the south-east |
77 TRACK_BIT_3WAY_SW = TRACK_BIT_X | TRACK_BIT_LOWER | TRACK_BIT_LEFT, |
88 TRACK_BIT_3WAY_SW = TRACK_BIT_X | TRACK_BIT_LOWER | TRACK_BIT_LEFT, ///< "Arrow" to the south-west |
78 TRACK_BIT_3WAY_NW = TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_LEFT, |
89 TRACK_BIT_3WAY_NW = TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_LEFT, ///< "Arrow" to the north-west |
79 TRACK_BIT_ALL = TRACK_BIT_CROSS | TRACK_BIT_HORZ | TRACK_BIT_VERT, |
90 TRACK_BIT_ALL = TRACK_BIT_CROSS | TRACK_BIT_HORZ | TRACK_BIT_VERT, ///< All possible tracks |
80 TRACK_BIT_MASK = 0x3FU, |
91 TRACK_BIT_MASK = 0x3FU, ///< Bitmask for the first 6 bits |
81 TRACK_BIT_WORMHOLE = 0x40U, |
92 TRACK_BIT_WORMHOLE = 0x40U, ///< Bitflag for a wormhole (used for tunnels) |
82 TRACK_BIT_DEPOT = 0x80U, |
93 TRACK_BIT_DEPOT = 0x80U, ///< Bitflag for a depot |
83 INVALID_TRACK_BIT = 0xFF |
94 INVALID_TRACK_BIT = 0xFF ///< Flag for an invalid trackbits value |
84 }; |
95 }; |
85 |
96 |
86 /** Define basic enum properties */ |
97 /** Define basic enum properties */ |
87 template <> struct EnumPropsT<TrackBits> : MakeEnumPropsT<TrackBits, byte, TRACK_BIT_NONE, TRACK_BIT_ALL, INVALID_TRACK_BIT> {}; |
98 template <> struct EnumPropsT<TrackBits> : MakeEnumPropsT<TrackBits, byte, TRACK_BIT_NONE, TRACK_BIT_ALL, INVALID_TRACK_BIT> {}; |
88 typedef TinyEnumT<TrackBits> TrackBitsByte; |
99 typedef TinyEnumT<TrackBits> TrackBitsByte; |
89 |
100 |
90 DECLARE_ENUM_AS_BIT_SET(TrackBits); |
101 DECLARE_ENUM_AS_BIT_SET(TrackBits); |
91 |
102 |
92 /** |
103 /** |
93 * Maps a Track to the corresponding TrackBits value |
104 * Maps a Track to the corresponding TrackBits value |
|
105 * @param track the track to convert |
|
106 * @return the converted TrackBits value of the track |
94 */ |
107 */ |
95 static inline TrackBits TrackToTrackBits(Track track) |
108 static inline TrackBits TrackToTrackBits(Track track) |
96 { |
109 { |
97 return (TrackBits)(1 << track); |
110 return (TrackBits)(1 << track); |
98 } |
111 } |
99 |
112 |
100 |
113 /** |
|
114 * Maps an Axis to the corresponding TrackBits value |
|
115 * @param a the axis to convert |
|
116 * @return the converted TrackBits value of the axis |
|
117 */ |
101 static inline TrackBits AxisToTrackBits(Axis a) |
118 static inline TrackBits AxisToTrackBits(Axis a) |
102 { |
119 { |
103 return TrackToTrackBits(AxisToTrack(a)); |
120 return TrackToTrackBits(AxisToTrack(a)); |
104 } |
121 } |
105 |
122 |
106 |
123 |
107 /** These are a combination of tracks and directions. Values are 0-5 in one |
124 /** |
|
125 * Enumeration for tracks and directions. |
|
126 * |
|
127 * These are a combination of tracks and directions. Values are 0-5 in one |
108 * direction (corresponding to the Track enum) and 8-13 in the other direction. |
128 * direction (corresponding to the Track enum) and 8-13 in the other direction. |
109 * 6, 7, 14 and 15 are used to encode the reversing of road vehicles. Those |
129 * 6, 7, 14 and 15 are used to encode the reversing of road vehicles. Those |
110 * reversing track dirs are not considered to be 'valid' except in a small |
130 * reversing track dirs are not considered to be 'valid' except in a small |
111 * corner in the road vehicle controller. |
131 * corner in the road vehicle controller. |
112 */ |
132 */ |
113 enum Trackdir { |
133 enum Trackdir { |
114 TRACKDIR_BEGIN = 0, |
134 TRACKDIR_BEGIN = 0, ///< Used for iterations |
115 TRACKDIR_X_NE = 0, |
135 TRACKDIR_X_NE = 0, ///< X-axis and direction to north-east |
116 TRACKDIR_Y_SE = 1, |
136 TRACKDIR_Y_SE = 1, ///< Y-axis and direction to south-east |
117 TRACKDIR_UPPER_E = 2, |
137 TRACKDIR_UPPER_E = 2, ///< Upper track and direction to east |
118 TRACKDIR_LOWER_E = 3, |
138 TRACKDIR_LOWER_E = 3, ///< Lower track and direction to east |
119 TRACKDIR_LEFT_S = 4, |
139 TRACKDIR_LEFT_S = 4, ///< Left track and direction to south |
120 TRACKDIR_RIGHT_S = 5, |
140 TRACKDIR_RIGHT_S = 5, ///< Right track and direction to south |
121 TRACKDIR_RVREV_NE = 6, |
141 TRACKDIR_RVREV_NE = 6, ///< (Road vehicle) reverse direction north-east |
122 TRACKDIR_RVREV_SE = 7, |
142 TRACKDIR_RVREV_SE = 7, ///< (Road vehicle) reverse direction south-east |
123 TRACKDIR_X_SW = 8, |
143 TRACKDIR_X_SW = 8, ///< X-axis and direction to south-west |
124 TRACKDIR_Y_NW = 9, |
144 TRACKDIR_Y_NW = 9, ///< Y-axis and direction to north-west |
125 TRACKDIR_UPPER_W = 10, |
145 TRACKDIR_UPPER_W = 10, ///< Upper track and direction to west |
126 TRACKDIR_LOWER_W = 11, |
146 TRACKDIR_LOWER_W = 11, ///< Lower track and direction to west |
127 TRACKDIR_LEFT_N = 12, |
147 TRACKDIR_LEFT_N = 12, ///< Left track and direction to north |
128 TRACKDIR_RIGHT_N = 13, |
148 TRACKDIR_RIGHT_N = 13, ///< Right track and direction to north |
129 TRACKDIR_RVREV_SW = 14, |
149 TRACKDIR_RVREV_SW = 14, ///< (Road vehicle) reverse direction south-west |
130 TRACKDIR_RVREV_NW = 15, |
150 TRACKDIR_RVREV_NW = 15, ///< (Road vehicle) reverse direction north-west |
131 TRACKDIR_END, |
151 TRACKDIR_END, ///< Used for iterations |
132 INVALID_TRACKDIR = 0xFF, |
152 INVALID_TRACKDIR = 0xFF, ///< Flag for an invalid trackdir |
133 }; |
153 }; |
134 |
154 |
135 /** Define basic enum properties */ |
155 /** Define basic enum properties */ |
136 template <> struct EnumPropsT<Trackdir> : MakeEnumPropsT<Trackdir, byte, TRACKDIR_BEGIN, TRACKDIR_END, INVALID_TRACKDIR> {}; |
156 template <> struct EnumPropsT<Trackdir> : MakeEnumPropsT<Trackdir, byte, TRACKDIR_BEGIN, TRACKDIR_END, INVALID_TRACKDIR> {}; |
137 typedef TinyEnumT<Trackdir> TrackdirByte; |
157 typedef TinyEnumT<Trackdir> TrackdirByte; |
138 |
158 |
139 /** These are a combination of tracks and directions. Values are 0-5 in one |
159 /** |
140 * direction (corresponding to the Track enum) and 8-13 in the other direction. */ |
160 * Enumeration of bitmasks for the TrackDirs |
|
161 * |
|
162 * These are a combination of tracks and directions. Values are 0-5 in one |
|
163 * direction (corresponding to the Track enum) and 8-13 in the other direction. |
|
164 */ |
141 enum TrackdirBits { |
165 enum TrackdirBits { |
142 TRACKDIR_BIT_NONE = 0x0000, |
166 TRACKDIR_BIT_NONE = 0x0000, ///< No track build |
143 TRACKDIR_BIT_X_NE = 0x0001, |
167 TRACKDIR_BIT_X_NE = 0x0001, ///< Track x-axis, direction north-east |
144 TRACKDIR_BIT_Y_SE = 0x0002, |
168 TRACKDIR_BIT_Y_SE = 0x0002, ///< Track y-axis, direction south-east |
145 TRACKDIR_BIT_UPPER_E = 0x0004, |
169 TRACKDIR_BIT_UPPER_E = 0x0004, ///< Track upper, direction east |
146 TRACKDIR_BIT_LOWER_E = 0x0008, |
170 TRACKDIR_BIT_LOWER_E = 0x0008, ///< Track lower, direction east |
147 TRACKDIR_BIT_LEFT_S = 0x0010, |
171 TRACKDIR_BIT_LEFT_S = 0x0010, ///< Track left, direction south |
148 TRACKDIR_BIT_RIGHT_S = 0x0020, |
172 TRACKDIR_BIT_RIGHT_S = 0x0020, ///< Track right, direction south |
149 /* Again, note the two missing values here. This enables trackdir -> track conversion by doing (trackdir & 0xFF) */ |
173 /* Again, note the two missing values here. This enables trackdir -> track conversion by doing (trackdir & 0xFF) */ |
150 TRACKDIR_BIT_X_SW = 0x0100, |
174 TRACKDIR_BIT_X_SW = 0x0100, ///< Track x-axis, direction south-west |
151 TRACKDIR_BIT_Y_NW = 0x0200, |
175 TRACKDIR_BIT_Y_NW = 0x0200, ///< Track y-axis, direction north-west |
152 TRACKDIR_BIT_UPPER_W = 0x0400, |
176 TRACKDIR_BIT_UPPER_W = 0x0400, ///< Track upper, direction west |
153 TRACKDIR_BIT_LOWER_W = 0x0800, |
177 TRACKDIR_BIT_LOWER_W = 0x0800, ///< Track lower, direction west |
154 TRACKDIR_BIT_LEFT_N = 0x1000, |
178 TRACKDIR_BIT_LEFT_N = 0x1000, ///< Track left, direction north |
155 TRACKDIR_BIT_RIGHT_N = 0x2000, |
179 TRACKDIR_BIT_RIGHT_N = 0x2000, ///< Track right, direction north |
156 TRACKDIR_BIT_MASK = 0x3F3F, |
180 TRACKDIR_BIT_MASK = 0x3F3F, ///< Bitmask for bit-operations |
157 INVALID_TRACKDIR_BIT = 0xFFFF, |
181 INVALID_TRACKDIR_BIT = 0xFFFF, ///< Flag for an invalid trackdirbit value |
158 }; |
182 }; |
159 |
183 |
160 /** Define basic enum properties */ |
184 /** Define basic enum properties */ |
161 template <> struct EnumPropsT<TrackdirBits> : MakeEnumPropsT<TrackdirBits, uint16, TRACKDIR_BIT_NONE, TRACKDIR_BIT_MASK, INVALID_TRACKDIR_BIT> {}; |
185 template <> struct EnumPropsT<TrackdirBits> : MakeEnumPropsT<TrackdirBits, uint16, TRACKDIR_BIT_NONE, TRACKDIR_BIT_MASK, INVALID_TRACKDIR_BIT> {}; |
162 typedef TinyEnumT<TrackdirBits> TrackdirBitsShort; |
186 typedef TinyEnumT<TrackdirBits> TrackdirBitsShort; |
276 } |
327 } |
277 return INVALID_TRACKDIR; |
328 return INVALID_TRACKDIR; |
278 } |
329 } |
279 |
330 |
280 /** |
331 /** |
281 * Returns first Track from TrackBits or INVALID_TRACK |
332 * Returns first Track from TrackBits or INVALID_TRACK |
282 */ |
333 * |
|
334 * This function returns the first Track found in the TrackBits value as Track-value. |
|
335 * It returns INVALID_TRACK if the parameter is TRACK_BIT_NONE or INVALID_TRACK_BIT. |
|
336 * |
|
337 * @param tracks The TrackBits value |
|
338 * @return The first Track found or INVALID_TRACK |
|
339 * @see RemoveFirstTrack |
|
340 */ |
283 static inline Track FindFirstTrack(TrackBits tracks) |
341 static inline Track FindFirstTrack(TrackBits tracks) |
284 { |
342 { |
285 return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK; |
343 return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK; |
286 } |
344 } |
287 |
345 |
288 /** |
346 /** |
289 * Converts TrackBits to Track. TrackBits must contain just one Track or INVALID_TRACK_BIT! |
347 * Converts TrackBits to Track. |
290 */ |
348 * |
|
349 * This function converts a TrackBits value to a Track value. As it |
|
350 * is not possible to convert two or more tracks to one track the |
|
351 * parameter must contain only one track or be the INVALID_TRACK_BIT value. |
|
352 * |
|
353 * @param tracks The TrackBits value to convert |
|
354 * @return The Track from the value or INVALID_TRACK |
|
355 * @pre tracks must contains only one Track or be INVALID_TRACK_BIT |
|
356 */ |
291 static inline Track TrackBitsToTrack(TrackBits tracks) |
357 static inline Track TrackBitsToTrack(TrackBits tracks) |
292 { |
358 { |
293 assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KILL_FIRST_BIT(tracks & TRACK_BIT_MASK) == 0)); |
359 assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KILL_FIRST_BIT(tracks & TRACK_BIT_MASK) == 0)); |
294 return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK; |
360 return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK; |
295 } |
361 } |
296 |
362 |
297 /** |
363 /** |
298 * Returns first Trackdir from TrackdirBits or INVALID_TRACKDIR |
364 * Returns first Trackdir from TrackdirBits or INVALID_TRACKDIR |
299 */ |
365 * |
|
366 * This function returns the first Trackdir in the given TrackdirBits value or |
|
367 * INVALID_TRACKDIR if the value is TRACKDIR_BIT_NONE. The TrackdirBits must |
|
368 * not be INVALID_TRACKDIR_BIT. |
|
369 * |
|
370 * @param trackdirs The TrackdirBits value |
|
371 * @return The first Trackdir from the TrackdirBits or INVALID_TRACKDIR on TRACKDIR_BIT_NONE. |
|
372 * @pre trackdirs must not be INVALID_TRACKDIR_BIT |
|
373 * @see RemoveFirstTrackdir |
|
374 */ |
300 static inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs) |
375 static inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs) |
301 { |
376 { |
302 assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE); |
377 assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE); |
303 return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR; |
378 return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR; |
304 } |
379 } |
305 |
380 |
306 /** |
381 /** |
307 * These functions check the validity of Tracks and Trackdirs. assert against |
382 * Checks if a Track is valid. |
308 * them when convenient. |
383 * |
309 */ |
384 * @param track The value to check |
310 static inline bool IsValidTrack(Track track) { return track < TRACK_END; } |
385 * @return true if the given value is a valid track. |
311 static inline bool IsValidTrackdir(Trackdir trackdir) { return (TrackdirToTrackdirBits(trackdir) & TRACKDIR_BIT_MASK) != 0; } |
386 * @note Use this in an assert() |
312 |
387 */ |
313 /** |
388 static inline bool IsValidTrack(Track track) |
|
389 { |
|
390 return track < TRACK_END; |
|
391 } |
|
392 |
|
393 /** |
|
394 * Checks if a Trackdir is valid. |
|
395 * |
|
396 * @param trackdir The value to check |
|
397 * @return true if the given valie is a valid Trackdir |
|
398 * @note Use this in an assert() |
|
399 */ |
|
400 static inline bool IsValidTrackdir(Trackdir trackdir) |
|
401 { |
|
402 return (TrackdirToTrackdirBits(trackdir) & TRACKDIR_BIT_MASK) != 0; |
|
403 } |
|
404 |
|
405 /* |
314 * Functions to map tracks to the corresponding bits in the signal |
406 * Functions to map tracks to the corresponding bits in the signal |
315 * presence/status bytes in the map. You should not use these directly, but |
407 * presence/status bytes in the map. You should not use these directly, but |
316 * wrapper functions below instead. XXX: Which are these? |
408 * wrapper functions below instead. XXX: Which are these? |
317 */ |
409 */ |
318 |
410 |
352 * TrackdirBits, Direction and DiagDirections. |
444 * TrackdirBits, Direction and DiagDirections. |
353 */ |
445 */ |
354 |
446 |
355 /** |
447 /** |
356 * Maps a trackdir to the reverse trackdir. |
448 * Maps a trackdir to the reverse trackdir. |
|
449 * |
|
450 * Returns the reverse trackdir of a Trackdir value. The reverse trackdir |
|
451 * is the same track with the other direction on it. |
|
452 * |
|
453 * @param trackdir The Trackdir value |
|
454 * @return The reverse trackdir |
|
455 * @pre trackdir must not be INVALID_TRACKDIR |
357 */ |
456 */ |
358 static inline Trackdir ReverseTrackdir(Trackdir trackdir) |
457 static inline Trackdir ReverseTrackdir(Trackdir trackdir) |
359 { |
458 { |
360 assert(trackdir != INVALID_TRACKDIR); |
459 assert(trackdir != INVALID_TRACKDIR); |
361 return (Trackdir)(trackdir ^ 8); |
460 return (Trackdir)(trackdir ^ 8); |
362 } |
461 } |
363 |
462 |
364 /** |
463 /** |
365 * Returns the Track that a given Trackdir represents |
464 * Returns the Track that a given Trackdir represents |
366 */ |
465 * |
367 static inline Track TrackdirToTrack(Trackdir trackdir) { return (Track)(trackdir & 0x7); } |
466 * This function filters the Track which is used in the Trackdir value and |
368 |
467 * returns it as a Track value. |
369 /** |
468 * |
370 * Returns a Trackdir for the given Track. Since every Track corresponds to |
469 * @param trackdir The trackdir value |
371 * two Trackdirs, we choose the one which points between NE and S. |
470 * @return The Track which is used in the value |
372 * Note that the actual implementation is quite futile, but this might change |
471 */ |
|
472 static inline Track TrackdirToTrack(Trackdir trackdir) |
|
473 { |
|
474 return (Track)(trackdir & 0x7); |
|
475 } |
|
476 |
|
477 /** |
|
478 * Returns a Trackdir for the given Track |
|
479 * |
|
480 * Since every Track corresponds to two Trackdirs, we choose the |
|
481 * one which points between NE and S. Note that the actual |
|
482 * implementation is quite futile, but this might change |
373 * in the future. |
483 * in the future. |
374 */ |
484 * |
375 static inline Trackdir TrackToTrackdir(Track track) { return (Trackdir)track; } |
485 * @param track The given Track |
376 |
486 * @return The Trackdir from the given Track |
377 /** |
487 */ |
378 * Returns a TrackdirBit mask that contains the two TrackdirBits that |
488 static inline Trackdir TrackToTrackdir(Track track) |
|
489 { |
|
490 return (Trackdir)track; |
|
491 } |
|
492 |
|
493 /** |
|
494 * Returns a TrackdirBit mask from a given Track |
|
495 * |
|
496 * The TrackdirBit mask contains the two TrackdirBits that |
379 * correspond with the given Track (one for each direction). |
497 * correspond with the given Track (one for each direction). |
|
498 * |
|
499 * @param track The track to get the TrackdirBits from |
|
500 * @return The TrackdirBits which the selected tracks |
380 */ |
501 */ |
381 static inline TrackdirBits TrackToTrackdirBits(Track track) |
502 static inline TrackdirBits TrackToTrackdirBits(Track track) |
382 { |
503 { |
383 Trackdir td = TrackToTrackdir(track); |
504 Trackdir td = TrackToTrackdir(track); |
384 return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td))); |
505 return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td))); |
385 } |
506 } |
386 |
507 |
387 /** |
508 /** |
388 * Discards all directional information from the given TrackdirBits. Any |
509 * Discards all directional information from a TrackdirBits value |
389 * Track which is present in either direction will be present in the result. |
510 * |
|
511 * Any Track which is present in either direction will be present in the result. |
|
512 * |
|
513 * @param bits The TrackdirBits to get the TrackBits from |
|
514 * @return The TrackBits |
390 */ |
515 */ |
391 static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits) |
516 static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits) |
392 { |
517 { |
393 return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK); |
518 return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK); |
394 } |
519 } |
395 |
520 |
396 /** |
521 /** |
397 * Maps a trackdir to the trackdir that you will end up on if you go straight |
522 * Maps a trackdir to the trackdir that you will end up on if you go straight |
398 * ahead. This will be the same trackdir for diagonal trackdirs, but a |
523 * ahead. |
|
524 * |
|
525 * This will be the same trackdir for diagonal trackdirs, but a |
399 * different (alternating) one for straight trackdirs |
526 * different (alternating) one for straight trackdirs |
|
527 * |
|
528 * @param trackdir The given trackdir |
|
529 * @return The next Trackdir value of the next tile. |
400 */ |
530 */ |
401 static inline Trackdir NextTrackdir(Trackdir trackdir) |
531 static inline Trackdir NextTrackdir(Trackdir trackdir) |
402 { |
532 { |
403 extern const Trackdir _next_trackdir[TRACKDIR_END]; |
533 extern const Trackdir _next_trackdir[TRACKDIR_END]; |
404 return _next_trackdir[trackdir]; |
534 return _next_trackdir[trackdir]; |
405 } |
535 } |
406 |
536 |
407 /** |
537 /** |
408 * Maps a track to all tracks that make 90 deg turns with it. |
538 * Maps a track to all tracks that make 90 deg turns with it. |
|
539 * |
|
540 * For the diagonal directions these are the complement of the |
|
541 * direction, for the straight directions these are the |
|
542 * two vertical or horizontal tracks, depend on the given direction |
|
543 * |
|
544 * @param track The given track |
|
545 * @return The TrackBits with the tracks marked which cross the given track by 90 deg. |
409 */ |
546 */ |
410 static inline TrackBits TrackCrossesTracks(Track track) |
547 static inline TrackBits TrackCrossesTracks(Track track) |
411 { |
548 { |
412 extern const TrackBits _track_crosses_tracks[TRACK_END]; |
549 extern const TrackBits _track_crosses_tracks[TRACK_END]; |
413 return _track_crosses_tracks[track]; |
550 return _track_crosses_tracks[track]; |
414 } |
551 } |
415 |
552 |
416 /** |
553 /** |
417 * Maps a trackdir to the (4-way) direction the tile is exited when following |
554 * Maps a trackdir to the (4-way) direction the tile is exited when following |
418 * that trackdir. |
555 * that trackdir. |
|
556 * |
|
557 * For the diagonal directions these are the same directions. For |
|
558 * the straight directions these are the directions from the imagined |
|
559 * base-tile to the bordering tile which will be joined if the given |
|
560 * straight direction is leaved from the base-tile. |
|
561 * |
|
562 * @param trackdir The given track direction |
|
563 * @return The direction which points to the resulting tile if following the Trackdir |
419 */ |
564 */ |
420 static inline DiagDirection TrackdirToExitdir(Trackdir trackdir) |
565 static inline DiagDirection TrackdirToExitdir(Trackdir trackdir) |
421 { |
566 { |
422 extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END]; |
567 extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END]; |
423 return _trackdir_to_exitdir[trackdir]; |
568 return _trackdir_to_exitdir[trackdir]; |
424 } |
569 } |
425 |
570 |
426 /** |
571 /** |
427 * Maps a track and an (4-way) dir to the trackdir that represents the track |
572 * Maps a track and an (4-way) dir to the trackdir that represents the track |
428 * with the exit in the given direction. |
573 * with the exit in the given direction. |
|
574 * |
|
575 * For the diagonal tracks the resulting track direction are clear for a given |
|
576 * DiagDirection. It either matches the direction or it returns INVALID_TRACKDIR, |
|
577 * as a TRACK_X cannot be applied with DIAG_SE. |
|
578 * For the straight tracks the resulting track direction will be the |
|
579 * direction which the DiagDirection is pointing. But this will be INVALID_TRACKDIR |
|
580 * if the DiagDirection is pointing 'away' the track. |
|
581 * |
|
582 * @param track The track to applie an direction on |
|
583 * @param diagdir The DiagDirection to applie on |
|
584 * @return The resulting track direction or INVALID_TRACKDIR if not possible. |
429 */ |
585 */ |
430 static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir) |
586 static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir) |
431 { |
587 { |
432 extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END]; |
588 extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END]; |
433 return _track_exitdir_to_trackdir[track][diagdir]; |
589 return _track_exitdir_to_trackdir[track][diagdir]; |
434 } |
590 } |
435 |
591 |
436 /** |
592 /** |
437 * Maps a track and an (4-way) dir to the trackdir that represents the track |
593 * Maps a track and an (4-way) dir to the trackdir that represents the track |
438 * with the exit in the given direction. |
594 * with the entry in the given direction. |
|
595 * |
|
596 * For the diagonal tracks the return value is clear, its either the matching |
|
597 * track direction or INVALID_TRACKDIR. |
|
598 * For the straight tracks this returns the track direction which results if |
|
599 * you follow the DiagDirection and then turn by 45 deg left or right on the |
|
600 * next tile. The new direction on the new track will be the returning Trackdir |
|
601 * value. If the parameters makes no sense like the track TRACK_UPPER and the |
|
602 * diraction DIAGDIR_NE (target track cannot be reached) this function returns |
|
603 * INVALID_TRACKDIR. |
|
604 * |
|
605 * @param track The target track |
|
606 * @param diagdir The direction to "come from" |
|
607 * @return the resulting Trackdir or INVALID_TRACKDIR if not possible. |
439 */ |
608 */ |
440 static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir) |
609 static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir) |
441 { |
610 { |
442 extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END]; |
611 extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END]; |
443 return _track_enterdir_to_trackdir[track][diagdir]; |
612 return _track_enterdir_to_trackdir[track][diagdir]; |
454 } |
623 } |
455 |
624 |
456 /** |
625 /** |
457 * Maps a (4-way) direction to the diagonal trackdir that runs in that |
626 * Maps a (4-way) direction to the diagonal trackdir that runs in that |
458 * direction. |
627 * direction. |
|
628 * |
|
629 * @param diagdir The direction |
|
630 * @return The resulting Trackdir direction |
459 */ |
631 */ |
460 static inline Trackdir DiagdirToDiagTrackdir(DiagDirection diagdir) |
632 static inline Trackdir DiagdirToDiagTrackdir(DiagDirection diagdir) |
461 { |
633 { |
462 extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END]; |
634 extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END]; |
463 return _dir_to_diag_trackdir[diagdir]; |
635 return _dir_to_diag_trackdir[diagdir]; |
464 } |
636 } |
465 |
637 |
466 /** |
638 /** |
467 * Returns all trackdirs that can be reached when entering a tile from a given |
639 * Returns all trackdirs that can be reached when entering a tile from a given |
468 * (diagonal) direction. This will obviously include 90 degree turns, since no |
640 * (diagonal) direction. |
469 * information is available about the exact angle of entering */ |
641 * |
|
642 * This will obviously include 90 degree turns, since no information is available |
|
643 * about the exact angle of entering |
|
644 * |
|
645 * @param diagdir The joining direction |
|
646 * @return The TrackdirBits which can be used from the given direction |
|
647 * @see DiagdirReachesTracks |
|
648 */ |
470 static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir) |
649 static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir) |
471 { |
650 { |
472 extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END]; |
651 extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END]; |
473 return _exitdir_reaches_trackdirs[diagdir]; |
652 return _exitdir_reaches_trackdirs[diagdir]; |
474 } |
653 } |
475 |
654 |
476 /** |
655 /** |
477 * Returns all tracks that can be reached when entering a tile from a given |
656 * Returns all tracks that can be reached when entering a tile from a given |
478 * (diagonal) direction. This will obviously include 90 degree turns, since no |
657 * (diagonal) direction. |
479 * information is available about the exact angle of entering */ |
658 * |
|
659 * This will obviously include 90 degree turns, since no |
|
660 * information is available about the exact angle of entering |
|
661 * |
|
662 * @param diagdir The joining irection |
|
663 * @return The tracks which can be used |
|
664 * @see DiagdirReachesTrackdirs |
|
665 */ |
480 static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); } |
666 static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); } |
481 |
667 |
482 /** |
668 /** |
483 * Maps a trackdir to the trackdirs that can be reached from it (ie, when |
669 * Maps a trackdir to the trackdirs that can be reached from it (ie, when |
484 * entering the next tile. This will include 90 degree turns! |
670 * entering the next tile. |
|
671 * |
|
672 * This will include 90 degree turns! |
|
673 * |
|
674 * @param trackdir The track direction which will be leaved |
|
675 * @return The track directions which can be used from this direction (in the next tile) |
485 */ |
676 */ |
486 static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir) |
677 static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir) |
487 { |
678 { |
488 extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END]; |
679 extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END]; |
489 return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)]; |
680 return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)]; |
490 } |
681 } |
491 |
|
492 /* Note that there is no direct table for this function (there used to be), |
682 /* Note that there is no direct table for this function (there used to be), |
493 * but it uses two simpeler tables to achieve the result */ |
683 * but it uses two simpeler tables to achieve the result */ |
494 |
684 |
495 |
|
496 /** |
685 /** |
497 * Maps a trackdir to all trackdirs that make 90 deg turns with it. |
686 * Maps a trackdir to all trackdirs that make 90 deg turns with it. |
|
687 * |
|
688 * For the diagonal tracks this returns the track direction bits |
|
689 * of the other axis in both directions, which cannot be joined by |
|
690 * the given track direction. |
|
691 * For the straight tracks this returns all possible 90 deg turns |
|
692 * either on the current tile (which no train can joined) or on the |
|
693 * bordering tiles. |
|
694 * |
|
695 * @param trackdir The track direction |
|
696 * @return The TrackdirBits which are (more or less) 90 deg turns. |
498 */ |
697 */ |
499 static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir) |
698 static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir) |
500 { |
699 { |
501 extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END]; |
700 extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END]; |
502 return _track_crosses_trackdirs[TrackdirToTrack(trackdir)]; |
701 return _track_crosses_trackdirs[TrackdirToTrack(trackdir)]; |
503 } |
702 } |
504 |
703 |
505 |
704 /** |
506 /* Checks if a given Track is diagonal */ |
705 * Checks if a given Track is diagonal |
507 static inline bool IsDiagonalTrack(Track track) { return (track == TRACK_X) || (track == TRACK_Y); } |
706 * |
508 |
707 * @param track The given track to check |
509 /* Checks if a given Trackdir is diagonal. */ |
708 * @return true if diagonal, else false |
510 static inline bool IsDiagonalTrackdir(Trackdir trackdir) { return IsDiagonalTrack(TrackdirToTrack(trackdir)); } |
709 */ |
511 |
710 static inline bool IsDiagonalTrack(Track track) |
|
711 { |
|
712 return (track == TRACK_X) || (track == TRACK_Y); |
|
713 } |
|
714 |
|
715 /** |
|
716 * Checks if a given Trackdir is diagonal. |
|
717 * |
|
718 * @param trackdir The given trackdir |
|
719 * @return true if the trackdir use a diagonal track |
|
720 */ |
|
721 static inline bool IsDiagonalTrackdir(Trackdir trackdir) |
|
722 { |
|
723 return IsDiagonalTrack(TrackdirToTrack(trackdir)); |
|
724 } |
512 |
725 |
513 /** |
726 /** |
514 * Returns a pointer to the Railtype information for a given railtype |
727 * Returns a pointer to the Railtype information for a given railtype |
515 * @param railtype the rail type which the information is requested for |
728 * @param railtype the rail type which the information is requested for |
516 * @return The pointer to the RailtypeInfo |
729 * @return The pointer to the RailtypeInfo |