# track_func.h

Go to the documentation of this file.

    00001 /* $Id: track_func.h 12313 2008-02-28 17:34:34Z frosch $ */
    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
    00027
    00028
    00034 static inline TrackBits TrackToTrackBits(Track track)
    00035 {
    00036   return (TrackBits)(1 << track);
    00037 }
    00038
    00044 static inline TrackBits AxisToTrackBits(Axis a)
    00045 {
    00046   return TrackToTrackBits(AxisToTrack(a));
    00047 }
    00048
    00055 static inline TrackBits CornerToTrackBits(Corner corner)
    00056 {
    00057   extern const TrackBits _corner_to_trackbits[];
    00058   assert(IsValidCorner(corner));
    00059   return _corner_to_trackbits[corner];
    00060 }
    00061
    00062
    00063
    00069 static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
    00070 {
    00071   return (TrackdirBits)(1 << trackdir);
    00072 }
    00073
    00088 static inline Track RemoveFirstTrack(TrackBits *tracks)
    00089 {
    00090   if (*tracks != TRACK_BIT_NONE && *tracks != INVALID_TRACK_BIT) {
    00091     Track first = (Track)FIND_FIRST_BIT(*tracks);
    00092     ClrBit(*tracks, first);
    00093     return first;
    00094   }
    00095   return INVALID_TRACK;
    00096 }
    00097
    00112 static inline Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
    00113 {
    00114   if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) {
    00115     Trackdir first = (Trackdir)FindFirstBit2x64(*trackdirs);
    00116     ClrBit(*trackdirs, first);
    00117     return first;
    00118   }
    00119   return INVALID_TRACKDIR;
    00120 }
    00121
    00132 static inline Track FindFirstTrack(TrackBits tracks)
    00133 {
    00134   return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK;
    00135 }
    00136
    00148 static inline Track TrackBitsToTrack(TrackBits tracks)
    00149 {
    00150   assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KillFirstBit(tracks & TRACK_BIT_MASK) == TRACK_BIT_NONE));
    00151   return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK;
    00152 }
    00153
    00166 static inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
    00167 {
    00168   assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
    00169   return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR;
    00170 }
    00171
    00179 static inline bool IsValidTrack(Track track)
    00180 {
    00181   return track < TRACK_END;
    00182 }
    00183
    00191 static inline bool IsValidTrackdir(Trackdir trackdir)
    00192 {
    00193   return (TrackdirToTrackdirBits(trackdir) & TRACKDIR_BIT_MASK) != 0;
    00194 }
    00195
    00196
    00197 /*
    00198  * Functions describing logical relations between Tracks, TrackBits, Trackdirs
    00199  * TrackdirBits, Direction and DiagDirections.
    00200  */
    00201
    00212 static inline Trackdir ReverseTrackdir(Trackdir trackdir)
    00213 {
    00214   assert(trackdir != INVALID_TRACKDIR);
    00215   return (Trackdir)(trackdir ^ 8);
    00216 }
    00217
    00227 static inline Track TrackdirToTrack(Trackdir trackdir)
    00228 {
    00229   return (Track)(trackdir & 0x7);
    00230 }
    00231
    00243 static inline Trackdir TrackToTrackdir(Track track)
    00244 {
    00245   return (Trackdir)track;
    00246 }
    00247
    00257 static inline TrackdirBits TrackToTrackdirBits(Track track)
    00258 {
    00259   Trackdir td = TrackToTrackdir(track);
    00260   return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td)));
    00261 }
    00262
    00271 static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
    00272 {
    00273   return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK);
    00274 }
    00275
    00282 static inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
    00283 {
    00284   return (TrackdirBits)(bits * 0x101);
    00285 }
    00286
    00293 static inline TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
    00294 {
    00295   return (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
    00296 }
    00297
    00304 static inline TrackBits TrackStatusToTrackBits(TrackStatus ts)
    00305 {
    00306   return TrackdirBitsToTrackBits(TrackStatusToTrackdirBits(ts));
    00307 }
    00308
    00317 static inline TrackdirBits TrackStatusToRedSignals(TrackStatus ts)
    00318 {
    00319   return (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK);
    00320 }
    00321
    00329 static inline TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
    00330 {
    00331   return (TrackStatus)(trackdirbits | (red_signals << 16));
    00332 }
    00333
    00344 static inline Trackdir NextTrackdir(Trackdir trackdir)
    00345 {
    00346   extern const Trackdir _next_trackdir[TRACKDIR_END];
    00347   return _next_trackdir[trackdir];
    00348 }
    00349
    00360 static inline TrackBits TrackCrossesTracks(Track track)
    00361 {
    00362   extern const TrackBits _track_crosses_tracks[TRACK_END];
    00363   return _track_crosses_tracks[track];
    00364 }
    00365
    00378 static inline DiagDirection TrackdirToExitdir(Trackdir trackdir)
    00379 {
    00380   extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END];
    00381   return _trackdir_to_exitdir[trackdir];
    00382 }
    00383
    00399 static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
    00400 {
    00401   extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END];
    00402   return _track_exitdir_to_trackdir[track][diagdir];
    00403 }
    00404
    00422 static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir)
    00423 {
    00424   extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END];
    00425   return _track_enterdir_to_trackdir[track][diagdir];
    00426 }
    00427
    00432 static inline Trackdir TrackDirectionToTrackdir(Track track, Direction dir)
    00433 {
    00434   extern const Trackdir _track_direction_to_trackdir[TRACK_END][DIR_END];
    00435   return _track_direction_to_trackdir[track][dir];
    00436 }
    00437
    00445 static inline Trackdir DiagdirToDiagTrackdir(DiagDirection diagdir)
    00446 {
    00447   extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END];
    00448   return _dir_to_diag_trackdir[diagdir];
    00449 }
    00450
    00462 static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
    00463 {
    00464   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
    00465   return _exitdir_reaches_trackdirs[diagdir];
    00466 }
    00467
    00479 static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); }
    00480
    00490 static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir)
    00491 {
    00492   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
    00493   return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)];
    00494 }
    00495 /* Note that there is no direct table for this function (there used to be),
    00496  * but it uses two simpeler tables to achieve the result */
    00497
    00511 static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
    00512 {
    00513   extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
    00514   return _track_crosses_trackdirs[TrackdirToTrack(trackdir)];
    00515 }
    00516
    00523 static inline bool IsDiagonalTrack(Track track)
    00524 {
    00525   return (track == TRACK_X) || (track == TRACK_Y);
    00526 }
    00527
    00534 static inline bool IsDiagonalTrackdir(Trackdir trackdir)
    00535 {
    00536   return IsDiagonalTrack(TrackdirToTrack(trackdir));
    00537 }
    00538
    00539
    00547 static inline bool TracksOverlap(TrackBits bits)
    00548 {
    00549   /* With no, or only one track, there is no overlap */
    00550   if (bits == TRACK_BIT_NONE || KillFirstBit(bits) == TRACK_BIT_NONE) return false;
    00551   /* We know that there are at least two tracks present. When there are more
    00552    * than 2 tracks, they will surely overlap. When there are two, they will
    00553    * always overlap unless they are lower & upper or right & left. */
    00554   return bits != TRACK_BIT_HORZ && bits != TRACK_BIT_VERT;
    00555 }
    00556
    00562 static inline bool IsReversingRoadTrackdir(Trackdir dir)
    00563 {
    00564   return (dir & 0x07) >= 6;
    00565 }
    00566
    00572 static inline bool IsStraightRoadTrackdir(Trackdir dir)
    00573 {
    00574   return (dir & 0x06) == 0;
    00575 }
    00576
    00587 static inline bool IsUphillTrackdir(Slope slope, Trackdir dir)
    00588 {
    00589   extern const TrackdirBits _uphill_trackdirs[];
    00590   return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
    00591 }
    00592
    00593 #endif /* TRACK_FUNC_H */