# track_func.h

Go to the documentation of this file.

    00001 /* $Id: track_func.h 13941 2008-08-02 22:51:07Z rubidium $ */
    00002
    00005 #ifndef TRACK_FUNC_H
    00006 #define TRACK_FUNC_H
    00007
    00008 #include "core/bitmath_func.hpp"
    00009 #include "track_type.h"
    00010 #include "direction_type.h"
    00011 #include "slope_func.h"
    00012
    00022 static inline Track AxisToTrack(Axis a)
    00023 {
    00024   return (Track)a;
    00025 }
    00026
    00032 static inline TrackBits TrackToTrackBits(Track track)
    00033 {
    00034   return (TrackBits)(1 << track);
    00035 }
    00036
    00042 static inline TrackBits AxisToTrackBits(Axis a)
    00043 {
    00044   return TrackToTrackBits(AxisToTrack(a));
    00045 }
    00046
    00053 static inline TrackBits CornerToTrackBits(Corner corner)
    00054 {
    00055   extern const TrackBits _corner_to_trackbits[];
    00056   assert(IsValidCorner(corner));
    00057   return _corner_to_trackbits[corner];
    00058 }
    00059
    00060
    00061
    00067 static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
    00068 {
    00069   return (TrackdirBits)(1 << trackdir);
    00070 }
    00071
    00086 static inline Track RemoveFirstTrack(TrackBits *tracks)
    00087 {
    00088   if (*tracks != TRACK_BIT_NONE && *tracks != INVALID_TRACK_BIT) {
    00089     Track first = (Track)FIND_FIRST_BIT(*tracks);
    00090     ClrBit(*tracks, first);
    00091     return first;
    00092   }
    00093   return INVALID_TRACK;
    00094 }
    00095
    00110 static inline Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
    00111 {
    00112   if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) {
    00113     Trackdir first = (Trackdir)FindFirstBit2x64(*trackdirs);
    00114     ClrBit(*trackdirs, first);
    00115     return first;
    00116   }
    00117   return INVALID_TRACKDIR;
    00118 }
    00119
    00130 static inline Track FindFirstTrack(TrackBits tracks)
    00131 {
    00132   return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK;
    00133 }
    00134
    00146 static inline Track TrackBitsToTrack(TrackBits tracks)
    00147 {
    00148   assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KillFirstBit(tracks & TRACK_BIT_MASK) == TRACK_BIT_NONE));
    00149   return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK;
    00150 }
    00151
    00164 static inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
    00165 {
    00166   assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
    00167   return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR;
    00168 }
    00169
    00177 static inline bool IsValidTrack(Track track)
    00178 {
    00179   return track < TRACK_END;
    00180 }
    00181
    00189 static inline bool IsValidTrackdir(Trackdir trackdir)
    00190 {
    00191   return (TrackdirToTrackdirBits(trackdir) & TRACKDIR_BIT_MASK) != 0;
    00192 }
    00193
    00194
    00195 /*
    00196  * Functions describing logical relations between Tracks, TrackBits, Trackdirs
    00197  * TrackdirBits, Direction and DiagDirections.
    00198  */
    00199
    00209 static inline Track TrackToOppositeTrack(Track t)
    00210 {
    00211   assert(t != INVALID_TRACK);
    00212   return (Track)(t ^ 1);
    00213 }
    00214
    00225 static inline Trackdir ReverseTrackdir(Trackdir trackdir)
    00226 {
    00227   assert(trackdir != INVALID_TRACKDIR);
    00228   return (Trackdir)(trackdir ^ 8);
    00229 }
    00230
    00240 static inline Track TrackdirToTrack(Trackdir trackdir)
    00241 {
    00242   return (Track)(trackdir & 0x7);
    00243 }
    00244
    00256 static inline Trackdir TrackToTrackdir(Track track)
    00257 {
    00258   return (Trackdir)track;
    00259 }
    00260
    00270 static inline TrackdirBits TrackToTrackdirBits(Track track)
    00271 {
    00272   Trackdir td = TrackToTrackdir(track);
    00273   return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td)));
    00274 }
    00275
    00284 static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
    00285 {
    00286   return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK);
    00287 }
    00288
    00295 static inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
    00296 {
    00297   return (TrackdirBits)(bits * 0x101);
    00298 }
    00299
    00306 static inline TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
    00307 {
    00308   return (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
    00309 }
    00310
    00317 static inline TrackBits TrackStatusToTrackBits(TrackStatus ts)
    00318 {
    00319   return TrackdirBitsToTrackBits(TrackStatusToTrackdirBits(ts));
    00320 }
    00321
    00330 static inline TrackdirBits TrackStatusToRedSignals(TrackStatus ts)
    00331 {
    00332   return (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK);
    00333 }
    00334
    00342 static inline TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
    00343 {
    00344   return (TrackStatus)(trackdirbits | (red_signals << 16));
    00345 }
    00346
    00357 static inline Trackdir NextTrackdir(Trackdir trackdir)
    00358 {
    00359   extern const Trackdir _next_trackdir[TRACKDIR_END];
    00360   return _next_trackdir[trackdir];
    00361 }
    00362
    00373 static inline TrackBits TrackCrossesTracks(Track track)
    00374 {
    00375   extern const TrackBits _track_crosses_tracks[TRACK_END];
    00376   return _track_crosses_tracks[track];
    00377 }
    00378
    00391 static inline DiagDirection TrackdirToExitdir(Trackdir trackdir)
    00392 {
    00393   extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END];
    00394   return _trackdir_to_exitdir[trackdir];
    00395 }
    00396
    00412 static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
    00413 {
    00414   extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END];
    00415   return _track_exitdir_to_trackdir[track][diagdir];
    00416 }
    00417
    00435 static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir)
    00436 {
    00437   extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END];
    00438   return _track_enterdir_to_trackdir[track][diagdir];
    00439 }
    00440
    00445 static inline Trackdir TrackDirectionToTrackdir(Track track, Direction dir)
    00446 {
    00447   extern const Trackdir _track_direction_to_trackdir[TRACK_END][DIR_END];
    00448   return _track_direction_to_trackdir[track][dir];
    00449 }
    00450
    00457 static inline Track DiagDirToDiagTrack(DiagDirection diagdir)
    00458 {
    00459   return (Track)(diagdir & 1);
    00460 }
    00461
    00468 static inline TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
    00469 {
    00470   return TrackToTrackBits(DiagDirToDiagTrack(diagdir));
    00471 }
    00472
    00480 static inline Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
    00481 {
    00482   extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END];
    00483   return _dir_to_diag_trackdir[diagdir];
    00484 }
    00485
    00497 static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
    00498 {
    00499   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
    00500   return _exitdir_reaches_trackdirs[diagdir];
    00501 }
    00502
    00514 static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); }
    00515
    00525 static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir)
    00526 {
    00527   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
    00528   return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)];
    00529 }
    00530 /* Note that there is no direct table for this function (there used to be),
    00531  * but it uses two simpeler tables to achieve the result */
    00532
    00546 static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
    00547 {
    00548   extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
    00549   return _track_crosses_trackdirs[TrackdirToTrack(trackdir)];
    00550 }
    00551
    00558 static inline bool IsDiagonalTrack(Track track)
    00559 {
    00560   return (track == TRACK_X) || (track == TRACK_Y);
    00561 }
    00562
    00569 static inline bool IsDiagonalTrackdir(Trackdir trackdir)
    00570 {
    00571   return IsDiagonalTrack(TrackdirToTrack(trackdir));
    00572 }
    00573
    00574
    00582 static inline bool TracksOverlap(TrackBits bits)
    00583 {
    00584   /* With no, or only one track, there is no overlap */
    00585   if (bits == TRACK_BIT_NONE || KillFirstBit(bits) == TRACK_BIT_NONE) return false;
    00586   /* We know that there are at least two tracks present. When there are more
    00587    * than 2 tracks, they will surely overlap. When there are two, they will
    00588    * always overlap unless they are lower & upper or right & left. */
    00589   return bits != TRACK_BIT_HORZ && bits != TRACK_BIT_VERT;
    00590 }
    00591
    00599 static inline bool TrackOverlapsTracks(TrackBits tracks, Track track)
    00600 {
    00601   if (HasBit(tracks, track)) return true;
    00602   return TracksOverlap(tracks | TrackToTrackBits(track));
    00603 }
    00604
    00610 static inline bool IsReversingRoadTrackdir(Trackdir dir)
    00611 {
    00612   return (dir & 0x07) >= 6;
    00613 }
    00614
    00620 static inline bool IsStraightRoadTrackdir(Trackdir dir)
    00621 {
    00622   return (dir & 0x06) == 0;
    00623 }
    00624
    00635 static inline bool IsUphillTrackdir(Slope slope, Trackdir dir)
    00636 {
    00637   extern const TrackdirBits _uphill_trackdirs[];
    00638   return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
    00639 }
    00640
    00641 #endif /* TRACK_FUNC_H */