track_func.h

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

Generated on Wed Dec 23 23:27:56 2009 for OpenTTD by  doxygen 1.5.6