# track_func.h

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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 "slope_func.h"
    00018
    00028 #define FOR_EACH_SET_TRACK(var, track_bits) FOR_EACH_SET_BIT_EX(Track, var, TrackBits, track_bits)
    00029
    00039 static inline Track AxisToTrack(Axis a)
    00040 {
    00041   return (Track)a;
    00042 }
    00043
    00049 static inline TrackBits TrackToTrackBits(Track track)
    00050 {
    00051   return (TrackBits)(1 << track);
    00052 }
    00053
    00059 static inline TrackBits AxisToTrackBits(Axis a)
    00060 {
    00061   return TrackToTrackBits(AxisToTrack(a));
    00062 }
    00063
    00070 static inline TrackBits CornerToTrackBits(Corner corner)
    00071 {
    00072   extern const TrackBits _corner_to_trackbits[];
    00073   assert(IsValidCorner(corner));
    00074   return _corner_to_trackbits[corner];
    00075 }
    00076
    00077
    00078
    00084 static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
    00085 {
    00086   return (TrackdirBits)(1 << trackdir);
    00087 }
    00088
    00103 static inline Track RemoveFirstTrack(TrackBits *tracks)
    00104 {
    00105   if (*tracks != TRACK_BIT_NONE && *tracks != INVALID_TRACK_BIT) {
    00106     Track first = (Track)FIND_FIRST_BIT(*tracks);
    00107     ClrBit(*tracks, first);
    00108     return first;
    00109   }
    00110   return INVALID_TRACK;
    00111 }
    00112
    00127 static inline Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
    00128 {
    00129   if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) {
    00130     Trackdir first = (Trackdir)FindFirstBit2x64(*trackdirs);
    00131     ClrBit(*trackdirs, first);
    00132     return first;
    00133   }
    00134   return INVALID_TRACKDIR;
    00135 }
    00136
    00147 static inline Track FindFirstTrack(TrackBits tracks)
    00148 {
    00149   return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK;
    00150 }
    00151
    00163 static inline Track TrackBitsToTrack(TrackBits tracks)
    00164 {
    00165   assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KillFirstBit(tracks & TRACK_BIT_MASK) == TRACK_BIT_NONE));
    00166   return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK;
    00167 }
    00168
    00181 static inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
    00182 {
    00183   assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
    00184   return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR;
    00185 }
    00186
    00194 static inline bool IsValidTrack(Track track)
    00195 {
    00196   return track < TRACK_END;
    00197 }
    00198
    00206 static inline bool IsValidTrackdir(Trackdir trackdir)
    00207 {
    00208   return (TrackdirToTrackdirBits(trackdir) & TRACKDIR_BIT_MASK) != 0;
    00209 }
    00210
    00211
    00212 /*
    00213  * Functions describing logical relations between Tracks, TrackBits, Trackdirs
    00214  * TrackdirBits, Direction and DiagDirections.
    00215  */
    00216
    00226 static inline Track TrackToOppositeTrack(Track t)
    00227 {
    00228   assert(t != INVALID_TRACK);
    00229   return (Track)(t ^ 1);
    00230 }
    00231
    00242 static inline Trackdir ReverseTrackdir(Trackdir trackdir)
    00243 {
    00244   assert(trackdir != INVALID_TRACKDIR);
    00245   return (Trackdir)(trackdir ^ 8);
    00246 }
    00247
    00257 static inline Track TrackdirToTrack(Trackdir trackdir)
    00258 {
    00259   return (Track)(trackdir & 0x7);
    00260 }
    00261
    00273 static inline Trackdir TrackToTrackdir(Track track)
    00274 {
    00275   return (Trackdir)track;
    00276 }
    00277
    00287 static inline TrackdirBits TrackToTrackdirBits(Track track)
    00288 {
    00289   Trackdir td = TrackToTrackdir(track);
    00290   return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td)));
    00291 }
    00292
    00301 static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
    00302 {
    00303   return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK);
    00304 }
    00305
    00312 static inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
    00313 {
    00314   return (TrackdirBits)(bits * 0x101);
    00315 }
    00316
    00323 static inline TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
    00324 {
    00325   return (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
    00326 }
    00327
    00334 static inline TrackBits TrackStatusToTrackBits(TrackStatus ts)
    00335 {
    00336   return TrackdirBitsToTrackBits(TrackStatusToTrackdirBits(ts));
    00337 }
    00338
    00347 static inline TrackdirBits TrackStatusToRedSignals(TrackStatus ts)
    00348 {
    00349   return (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK);
    00350 }
    00351
    00359 static inline TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
    00360 {
    00361   return (TrackStatus)(trackdirbits | (red_signals << 16));
    00362 }
    00363
    00374 static inline Trackdir NextTrackdir(Trackdir trackdir)
    00375 {
    00376   extern const Trackdir _next_trackdir[TRACKDIR_END];
    00377   return _next_trackdir[trackdir];
    00378 }
    00379
    00390 static inline TrackBits TrackCrossesTracks(Track track)
    00391 {
    00392   extern const TrackBits _track_crosses_tracks[TRACK_END];
    00393   return _track_crosses_tracks[track];
    00394 }
    00395
    00408 static inline DiagDirection TrackdirToExitdir(Trackdir trackdir)
    00409 {
    00410   extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END];
    00411   return _trackdir_to_exitdir[trackdir];
    00412 }
    00413
    00429 static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
    00430 {
    00431   extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END];
    00432   return _track_exitdir_to_trackdir[track][diagdir];
    00433 }
    00434
    00452 static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir)
    00453 {
    00454   extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END];
    00455   return _track_enterdir_to_trackdir[track][diagdir];
    00456 }
    00457
    00462 static inline Trackdir TrackDirectionToTrackdir(Track track, Direction dir)
    00463 {
    00464   extern const Trackdir _track_direction_to_trackdir[TRACK_END][DIR_END];
    00465   return _track_direction_to_trackdir[track][dir];
    00466 }
    00467
    00474 static inline Track DiagDirToDiagTrack(DiagDirection diagdir)
    00475 {
    00476   return (Track)(diagdir & 1);
    00477 }
    00478
    00485 static inline TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
    00486 {
    00487   return TrackToTrackBits(DiagDirToDiagTrack(diagdir));
    00488 }
    00489
    00497 static inline Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
    00498 {
    00499   extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END];
    00500   return _dir_to_diag_trackdir[diagdir];
    00501 }
    00502
    00514 static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
    00515 {
    00516   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
    00517   return _exitdir_reaches_trackdirs[diagdir];
    00518 }
    00519
    00531 static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); }
    00532
    00542 static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir)
    00543 {
    00544   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
    00545   return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)];
    00546 }
    00547 /* Note that there is no direct table for this function (there used to be),
    00548  * but it uses two simpeler tables to achieve the result */
    00549
    00563 static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
    00564 {
    00565   extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
    00566   return _track_crosses_trackdirs[TrackdirToTrack(trackdir)];
    00567 }
    00568
    00575 static inline bool IsDiagonalTrack(Track track)
    00576 {
    00577   return (track == TRACK_X) || (track == TRACK_Y);
    00578 }
    00579
    00586 static inline bool IsDiagonalTrackdir(Trackdir trackdir)
    00587 {
    00588   return IsDiagonalTrack(TrackdirToTrack(trackdir));
    00589 }
    00590
    00591
    00599 static inline bool TracksOverlap(TrackBits bits)
    00600 {
    00601   /* With no, or only one track, there is no overlap */
    00602   if (bits == TRACK_BIT_NONE || KillFirstBit(bits) == TRACK_BIT_NONE) return false;
    00603   /* We know that there are at least two tracks present. When there are more
    00604    * than 2 tracks, they will surely overlap. When there are two, they will
    00605    * always overlap unless they are lower & upper or right & left. */
    00606   return bits != TRACK_BIT_HORZ && bits != TRACK_BIT_VERT;
    00607 }
    00608
    00616 static inline bool TrackOverlapsTracks(TrackBits tracks, Track track)
    00617 {
    00618   if (HasBit(tracks, track)) return true;
    00619   return TracksOverlap(tracks | TrackToTrackBits(track));
    00620 }
    00621
    00627 static inline bool IsReversingRoadTrackdir(Trackdir dir)
    00628 {
    00629   return (dir & 0x07) >= 6;
    00630 }
    00631
    00637 static inline bool IsStraightRoadTrackdir(Trackdir dir)
    00638 {
    00639   return (dir & 0x06) == 0;
    00640 }
    00641
    00652 static inline bool IsUphillTrackdir(Slope slope, Trackdir dir)
    00653 {
    00654   extern const TrackdirBits _uphill_trackdirs[];
    00655   return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
    00656 }
    00657
    00658 #endif /* TRACK_FUNC_H */