track_func.h

Go to the documentation of this file.
00001 /* $Id: track_func.h 21060 2010-10-30 17:51:07Z alberth $ */
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 */

Generated on Fri Mar 4 21:37:08 2011 for OpenTTD by  doxygen 1.6.1