Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef TRACK_FUNC_H
00013 #define TRACK_FUNC_H
00014
00015 #include "core/bitmath_func.hpp"
00016 #include "track_type.h"
00017 #include "direction_func.h"
00018 #include "slope_func.h"
00019
00029 #define FOR_EACH_SET_TRACK(var, track_bits) FOR_EACH_SET_BIT_EX(Track, var, TrackBits, track_bits)
00030
00038 static inline bool IsValidTrack(Track track)
00039 {
00040 return track < TRACK_END;
00041 }
00042
00050 static inline bool IsValidTrackdirForRoadVehicle(Trackdir trackdir)
00051 {
00052 return trackdir < TRACKDIR_END;
00053 }
00054
00062 static inline bool IsValidTrackdir(Trackdir trackdir)
00063 {
00064 return (1 << trackdir & TRACKDIR_BIT_MASK) != 0;
00065 }
00066
00076 static inline Track AxisToTrack(Axis a)
00077 {
00078 assert(IsValidAxis(a));
00079 return (Track)a;
00080 }
00081
00087 static inline TrackBits TrackToTrackBits(Track track)
00088 {
00089 assert(IsValidTrack(track));
00090 return (TrackBits)(1 << track);
00091 }
00092
00098 static inline TrackBits AxisToTrackBits(Axis a)
00099 {
00100 return TrackToTrackBits(AxisToTrack(a));
00101 }
00102
00109 static inline TrackBits CornerToTrackBits(Corner corner)
00110 {
00111 extern const TrackBits _corner_to_trackbits[];
00112 assert(IsValidCorner(corner));
00113 return _corner_to_trackbits[corner];
00114 }
00115
00121 static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
00122 {
00123 assert(IsValidTrackdir(trackdir));
00124 return (TrackdirBits)(1 << trackdir);
00125 }
00126
00141 static inline Track RemoveFirstTrack(TrackBits *tracks)
00142 {
00143 if (*tracks != TRACK_BIT_NONE && *tracks != INVALID_TRACK_BIT) {
00144 assert((*tracks & ~TRACK_BIT_MASK) == TRACK_BIT_NONE);
00145 Track first = (Track)FIND_FIRST_BIT(*tracks);
00146 ClrBit(*tracks, first);
00147 return first;
00148 }
00149 return INVALID_TRACK;
00150 }
00151
00166 static inline Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
00167 {
00168 if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) {
00169 assert((*trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
00170 Trackdir first = (Trackdir)FindFirstBit2x64(*trackdirs);
00171 ClrBit(*trackdirs, first);
00172 return first;
00173 }
00174 return INVALID_TRACKDIR;
00175 }
00176
00187 static inline Track FindFirstTrack(TrackBits tracks)
00188 {
00189 return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK;
00190 }
00191
00203 static inline Track TrackBitsToTrack(TrackBits tracks)
00204 {
00205 assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KillFirstBit(tracks & TRACK_BIT_MASK) == TRACK_BIT_NONE));
00206 return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK;
00207 }
00208
00221 static inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
00222 {
00223 assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
00224 return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR;
00225 }
00226
00227
00228
00229
00230
00231
00241 static inline Track TrackToOppositeTrack(Track t)
00242 {
00243 assert(IsValidTrack(t));
00244 return (Track)(t ^ 1);
00245 }
00246
00257 static inline Trackdir ReverseTrackdir(Trackdir trackdir)
00258 {
00259 assert(IsValidTrackdirForRoadVehicle(trackdir));
00260 return (Trackdir)(trackdir ^ 8);
00261 }
00262
00272 static inline Track TrackdirToTrack(Trackdir trackdir)
00273 {
00274 assert(IsValidTrackdir(trackdir));
00275 return (Track)(trackdir & 0x7);
00276 }
00277
00289 static inline Trackdir TrackToTrackdir(Track track)
00290 {
00291 assert(IsValidTrack(track));
00292 return (Trackdir)track;
00293 }
00294
00304 static inline TrackdirBits TrackToTrackdirBits(Track track)
00305 {
00306 Trackdir td = TrackToTrackdir(track);
00307 return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td)));
00308 }
00309
00318 static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
00319 {
00320 return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK);
00321 }
00322
00329 static inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
00330 {
00331 return (TrackdirBits)(bits * 0x101);
00332 }
00333
00340 static inline TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
00341 {
00342 return (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
00343 }
00344
00351 static inline TrackBits TrackStatusToTrackBits(TrackStatus ts)
00352 {
00353 return TrackdirBitsToTrackBits(TrackStatusToTrackdirBits(ts));
00354 }
00355
00364 static inline TrackdirBits TrackStatusToRedSignals(TrackStatus ts)
00365 {
00366 return (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK);
00367 }
00368
00376 static inline TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
00377 {
00378 return (TrackStatus)(trackdirbits | (red_signals << 16));
00379 }
00380
00391 static inline Trackdir NextTrackdir(Trackdir trackdir)
00392 {
00393 assert(IsValidTrackdir(trackdir));
00394 extern const Trackdir _next_trackdir[TRACKDIR_END];
00395 return _next_trackdir[trackdir];
00396 }
00397
00408 static inline TrackBits TrackCrossesTracks(Track track)
00409 {
00410 assert(IsValidTrack(track));
00411 extern const TrackBits _track_crosses_tracks[TRACK_END];
00412 return _track_crosses_tracks[track];
00413 }
00414
00427 static inline DiagDirection TrackdirToExitdir(Trackdir trackdir)
00428 {
00429 assert(IsValidTrackdirForRoadVehicle(trackdir));
00430 extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END];
00431 return _trackdir_to_exitdir[trackdir];
00432 }
00433
00449 static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
00450 {
00451 assert(IsValidTrack(track));
00452 assert(IsValidDiagDirection(diagdir));
00453 extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END];
00454 return _track_exitdir_to_trackdir[track][diagdir];
00455 }
00456
00474 static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir)
00475 {
00476 assert(IsValidTrack(track));
00477 assert(IsValidDiagDirection(diagdir));
00478 extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END];
00479 return _track_enterdir_to_trackdir[track][diagdir];
00480 }
00481
00486 static inline Trackdir TrackDirectionToTrackdir(Track track, Direction dir)
00487 {
00488 assert(IsValidTrack(track));
00489 assert(IsValidDirection(dir));
00490 extern const Trackdir _track_direction_to_trackdir[TRACK_END][DIR_END];
00491 return _track_direction_to_trackdir[track][dir];
00492 }
00493
00500 static inline Track DiagDirToDiagTrack(DiagDirection diagdir)
00501 {
00502 assert(IsValidDiagDirection(diagdir));
00503 return (Track)(diagdir & 1);
00504 }
00505
00512 static inline TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
00513 {
00514 assert(IsValidDiagDirection(diagdir));
00515 return TrackToTrackBits(DiagDirToDiagTrack(diagdir));
00516 }
00517
00525 static inline Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
00526 {
00527 assert(IsValidDiagDirection(diagdir));
00528 extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END];
00529 return _dir_to_diag_trackdir[diagdir];
00530 }
00531
00543 static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
00544 {
00545 assert(IsValidDiagDirection(diagdir));
00546 extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
00547 return _exitdir_reaches_trackdirs[diagdir];
00548 }
00549
00561 static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); }
00562
00572 static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir)
00573 {
00574 assert(IsValidTrackdir(trackdir));
00575 extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
00576 return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)];
00577 }
00578
00579
00580
00594 static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
00595 {
00596 assert(IsValidTrackdirForRoadVehicle(trackdir));
00597 extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
00598 return _track_crosses_trackdirs[TrackdirToTrack(trackdir)];
00599 }
00600
00607 static inline bool IsDiagonalTrack(Track track)
00608 {
00609 assert(IsValidTrack(track));
00610 return (track == TRACK_X) || (track == TRACK_Y);
00611 }
00612
00619 static inline bool IsDiagonalTrackdir(Trackdir trackdir)
00620 {
00621 assert(IsValidTrackdir(trackdir));
00622 return IsDiagonalTrack(TrackdirToTrack(trackdir));
00623 }
00624
00625
00633 static inline bool TracksOverlap(TrackBits bits)
00634 {
00635
00636 if (bits == TRACK_BIT_NONE || KillFirstBit(bits) == TRACK_BIT_NONE) return false;
00637
00638
00639
00640 return bits != TRACK_BIT_HORZ && bits != TRACK_BIT_VERT;
00641 }
00642
00650 static inline bool TrackOverlapsTracks(TrackBits tracks, Track track)
00651 {
00652 if (HasBit(tracks, track)) return true;
00653 return TracksOverlap(tracks | TrackToTrackBits(track));
00654 }
00655
00661 static inline bool IsReversingRoadTrackdir(Trackdir dir)
00662 {
00663 assert(IsValidTrackdirForRoadVehicle(dir));
00664 return (dir & 0x07) >= 6;
00665 }
00666
00672 static inline bool IsStraightRoadTrackdir(Trackdir dir)
00673 {
00674 assert(IsValidTrackdirForRoadVehicle(dir));
00675 return (dir & 0x06) == 0;
00676 }
00677
00688 static inline bool IsUphillTrackdir(Slope slope, Trackdir dir)
00689 {
00690 assert(IsValidTrackdirForRoadVehicle(dir));
00691 extern const TrackdirBits _uphill_trackdirs[];
00692 return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
00693 }
00694
00695 #endif