track_func.h

Go to the documentation of this file.
00001 /* $Id: track_func.h 18809 2010-01-15 16:41:15Z rubidium $ */
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 static inline Track AxisToTrack(Axis a)
00029 {
00030   return (Track)a;
00031 }
00032 
00038 static inline TrackBits TrackToTrackBits(Track track)
00039 {
00040   return (TrackBits)(1 << track);
00041 }
00042 
00048 static inline TrackBits AxisToTrackBits(Axis a)
00049 {
00050   return TrackToTrackBits(AxisToTrack(a));
00051 }
00052 
00059 static inline TrackBits CornerToTrackBits(Corner corner)
00060 {
00061   extern const TrackBits _corner_to_trackbits[];
00062   assert(IsValidCorner(corner));
00063   return _corner_to_trackbits[corner];
00064 }
00065 
00066 
00067 
00073 static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
00074 {
00075   return (TrackdirBits)(1 << trackdir);
00076 }
00077 
00092 static inline Track RemoveFirstTrack(TrackBits *tracks)
00093 {
00094   if (*tracks != TRACK_BIT_NONE && *tracks != INVALID_TRACK_BIT) {
00095     Track first = (Track)FIND_FIRST_BIT(*tracks);
00096     ClrBit(*tracks, first);
00097     return first;
00098   }
00099   return INVALID_TRACK;
00100 }
00101 
00116 static inline Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
00117 {
00118   if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) {
00119     Trackdir first = (Trackdir)FindFirstBit2x64(*trackdirs);
00120     ClrBit(*trackdirs, first);
00121     return first;
00122   }
00123   return INVALID_TRACKDIR;
00124 }
00125 
00136 static inline Track FindFirstTrack(TrackBits tracks)
00137 {
00138   return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK;
00139 }
00140 
00152 static inline Track TrackBitsToTrack(TrackBits tracks)
00153 {
00154   assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KillFirstBit(tracks & TRACK_BIT_MASK) == TRACK_BIT_NONE));
00155   return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK;
00156 }
00157 
00170 static inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
00171 {
00172   assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
00173   return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR;
00174 }
00175 
00183 static inline bool IsValidTrack(Track track)
00184 {
00185   return track < TRACK_END;
00186 }
00187 
00195 static inline bool IsValidTrackdir(Trackdir trackdir)
00196 {
00197   return (TrackdirToTrackdirBits(trackdir) & TRACKDIR_BIT_MASK) != 0;
00198 }
00199 
00200 
00201 /*
00202  * Functions describing logical relations between Tracks, TrackBits, Trackdirs
00203  * TrackdirBits, Direction and DiagDirections.
00204  */
00205 
00215 static inline Track TrackToOppositeTrack(Track t)
00216 {
00217   assert(t != INVALID_TRACK);
00218   return (Track)(t ^ 1);
00219 }
00220 
00231 static inline Trackdir ReverseTrackdir(Trackdir trackdir)
00232 {
00233   assert(trackdir != INVALID_TRACKDIR);
00234   return (Trackdir)(trackdir ^ 8);
00235 }
00236 
00246 static inline Track TrackdirToTrack(Trackdir trackdir)
00247 {
00248   return (Track)(trackdir & 0x7);
00249 }
00250 
00262 static inline Trackdir TrackToTrackdir(Track track)
00263 {
00264   return (Trackdir)track;
00265 }
00266 
00276 static inline TrackdirBits TrackToTrackdirBits(Track track)
00277 {
00278   Trackdir td = TrackToTrackdir(track);
00279   return (TrackdirBits)(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td)));
00280 }
00281 
00290 static inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
00291 {
00292   return (TrackBits)((bits | (bits >> 8)) & TRACK_BIT_MASK);
00293 }
00294 
00301 static inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
00302 {
00303   return (TrackdirBits)(bits * 0x101);
00304 }
00305 
00312 static inline TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
00313 {
00314   return (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
00315 }
00316 
00323 static inline TrackBits TrackStatusToTrackBits(TrackStatus ts)
00324 {
00325   return TrackdirBitsToTrackBits(TrackStatusToTrackdirBits(ts));
00326 }
00327 
00336 static inline TrackdirBits TrackStatusToRedSignals(TrackStatus ts)
00337 {
00338   return (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK);
00339 }
00340 
00348 static inline TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
00349 {
00350   return (TrackStatus)(trackdirbits | (red_signals << 16));
00351 }
00352 
00363 static inline Trackdir NextTrackdir(Trackdir trackdir)
00364 {
00365   extern const Trackdir _next_trackdir[TRACKDIR_END];
00366   return _next_trackdir[trackdir];
00367 }
00368 
00379 static inline TrackBits TrackCrossesTracks(Track track)
00380 {
00381   extern const TrackBits _track_crosses_tracks[TRACK_END];
00382   return _track_crosses_tracks[track];
00383 }
00384 
00397 static inline DiagDirection TrackdirToExitdir(Trackdir trackdir)
00398 {
00399   extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END];
00400   return _trackdir_to_exitdir[trackdir];
00401 }
00402 
00418 static inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
00419 {
00420   extern const Trackdir _track_exitdir_to_trackdir[TRACK_END][DIAGDIR_END];
00421   return _track_exitdir_to_trackdir[track][diagdir];
00422 }
00423 
00441 static inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir)
00442 {
00443   extern const Trackdir _track_enterdir_to_trackdir[TRACK_END][DIAGDIR_END];
00444   return _track_enterdir_to_trackdir[track][diagdir];
00445 }
00446 
00451 static inline Trackdir TrackDirectionToTrackdir(Track track, Direction dir)
00452 {
00453   extern const Trackdir _track_direction_to_trackdir[TRACK_END][DIR_END];
00454   return _track_direction_to_trackdir[track][dir];
00455 }
00456 
00463 static inline Track DiagDirToDiagTrack(DiagDirection diagdir)
00464 {
00465   return (Track)(diagdir & 1);
00466 }
00467 
00474 static inline TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
00475 {
00476   return TrackToTrackBits(DiagDirToDiagTrack(diagdir));
00477 }
00478 
00486 static inline Trackdir DiagDirToDiagTrackdir(DiagDirection diagdir)
00487 {
00488   extern const Trackdir _dir_to_diag_trackdir[DIAGDIR_END];
00489   return _dir_to_diag_trackdir[diagdir];
00490 }
00491 
00503 static inline TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
00504 {
00505   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
00506   return _exitdir_reaches_trackdirs[diagdir];
00507 }
00508 
00520 static inline TrackBits DiagdirReachesTracks(DiagDirection diagdir) { return TrackdirBitsToTrackBits(DiagdirReachesTrackdirs(diagdir)); }
00521 
00531 static inline TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir)
00532 {
00533   extern const TrackdirBits _exitdir_reaches_trackdirs[DIAGDIR_END];
00534   return _exitdir_reaches_trackdirs[TrackdirToExitdir(trackdir)];
00535 }
00536 /* Note that there is no direct table for this function (there used to be),
00537  * but it uses two simpeler tables to achieve the result */
00538 
00552 static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
00553 {
00554   extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
00555   return _track_crosses_trackdirs[TrackdirToTrack(trackdir)];
00556 }
00557 
00564 static inline bool IsDiagonalTrack(Track track)
00565 {
00566   return (track == TRACK_X) || (track == TRACK_Y);
00567 }
00568 
00575 static inline bool IsDiagonalTrackdir(Trackdir trackdir)
00576 {
00577   return IsDiagonalTrack(TrackdirToTrack(trackdir));
00578 }
00579 
00580 
00588 static inline bool TracksOverlap(TrackBits bits)
00589 {
00590   /* With no, or only one track, there is no overlap */
00591   if (bits == TRACK_BIT_NONE || KillFirstBit(bits) == TRACK_BIT_NONE) return false;
00592   /* We know that there are at least two tracks present. When there are more
00593    * than 2 tracks, they will surely overlap. When there are two, they will
00594    * always overlap unless they are lower & upper or right & left. */
00595   return bits != TRACK_BIT_HORZ && bits != TRACK_BIT_VERT;
00596 }
00597 
00605 static inline bool TrackOverlapsTracks(TrackBits tracks, Track track)
00606 {
00607   if (HasBit(tracks, track)) return true;
00608   return TracksOverlap(tracks | TrackToTrackBits(track));
00609 }
00610 
00616 static inline bool IsReversingRoadTrackdir(Trackdir dir)
00617 {
00618   return (dir & 0x07) >= 6;
00619 }
00620 
00626 static inline bool IsStraightRoadTrackdir(Trackdir dir)
00627 {
00628   return (dir & 0x06) == 0;
00629 }
00630 
00641 static inline bool IsUphillTrackdir(Slope slope, Trackdir dir)
00642 {
00643   extern const TrackdirBits _uphill_trackdirs[];
00644   return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
00645 }
00646 
00647 #endif /* TRACK_FUNC_H */

Generated on Fri Apr 30 21:55:28 2010 for OpenTTD by  doxygen 1.6.1