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 */

Generated on Mon Feb 16 23:12:12 2009 for openttd by  doxygen 1.5.6