From d6645818b4b29a42dd617c92e23a525fe5170b6a Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 2 Aug 2008 22:48:57 +0000 Subject: [PATCH] (svn r13933) -Codechange [YAPP]: Handle through and PBS signals correctly in the signal code. (michi_cc) --- src/rail_cmd.cpp | 13 +++++++------ src/rail_map.h | 6 ++++++ src/signal.cpp | 18 +++++++++++++----- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 51ddec70fa..4ac7f76ac0 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -2181,12 +2181,13 @@ static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, b &= a; - /* When signals are not present (in neither - * direction), we pretend them to be green. (So if - * signals are only one way, the other way will - * implicitely become `red' */ - if ((a & 0xC) == 0) b |= 0xC; - if ((a & 0x3) == 0) b |= 0x3; + /* When signals are not present (in neither direction), + * we pretend them to be green. Otherwise, it depends on + * the signal type. For signals that are only active from + * one side, we set the missing signals explicitely to + * `green'. Otherwise, they implicitely become `red'. */ + if (!IsOnewaySignal(tile, TRACK_UPPER) || (a & SignalOnTrack(TRACK_UPPER)) == 0) b |= ~a & SignalOnTrack(TRACK_UPPER); + if (!IsOnewaySignal(tile, TRACK_LOWER) || (a & SignalOnTrack(TRACK_LOWER)) == 0) b |= ~a & SignalOnTrack(TRACK_LOWER); if ((b & 0x8) == 0) red_signals |= (TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E); if ((b & 0x4) == 0) red_signals |= (TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_UPPER_W); diff --git a/src/rail_map.h b/src/rail_map.h index 2d25feb5a1..8e47ea5f5d 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -368,6 +368,12 @@ static inline bool IsPresignalExit(TileIndex t, Track track) return GetSignalType(t, track) == SIGTYPE_EXIT || GetSignalType(t, track) == SIGTYPE_COMBO; } +/** One-way signals can't be passed the 'wrong' way. */ +static inline bool IsOnewaySignal(TileIndex t, Track track) +{ + return GetSignalType(t, track) != SIGTYPE_PBS; +} + static inline void CycleSignalSide(TileIndex t, Track track) { byte sig; diff --git a/src/signal.cpp b/src/signal.cpp index 1177b2ee20..857be866f3 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -256,6 +256,7 @@ enum SigFlags { SF_GREEN = 1 << 3, ///< green exitsignal found SF_GREEN2 = 1 << 4, ///< two or more green exits found SF_FULL = 1 << 5, ///< some of buffers was full, do not continue + SF_PBS = 1 << 6, ///< pbs signal found }; DECLARE_ENUM_AS_BIT_SET(SigFlags) @@ -323,13 +324,19 @@ static SigFlags ExploreSegment(Owner owner) Trackdir trackdir = (Trackdir)FindFirstBit((tracks * 0x101) & _enterdir_to_trackdirbits[enterdir]); Trackdir reversedir = ReverseTrackdir(trackdir); /* add (tile, reversetrackdir) to 'to-be-updated' set when there is - * ANY signal in REVERSE direction + * ANY conventional signal in REVERSE direction * (if it is a presignal EXIT and it changes, it will be added to 'to-be-done' set later) */ if (HasSignalOnTrackdir(tile, reversedir)) { - if (!_tbuset.Add(tile, reversedir)) return flags | SF_FULL; + if (IsPbsSignal(sig)) { + flags |= SF_PBS; + } else if (!_tbuset.Add(tile, reversedir)) { + return flags | SF_FULL; + } } + if (HasSignalOnTrackdir(tile, trackdir) && !IsOnewaySignal(tile, track)) flags |= SF_PBS; + /* if it is a presignal EXIT in OUR direction and we haven't found 2 green exits yes, do special check */ - if (!(flags & SF_GREEN2) && (sig & SIGTYPE_EXIT) && HasSignalOnTrackdir(tile, trackdir)) { // found presignal exit + if (!(flags & SF_GREEN2) && IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, trackdir)) { // found presignal exit if (flags & SF_EXIT) flags |= SF_EXIT2; // found two (or more) exits flags |= SF_EXIT; // found at least one exit - allow for compiler optimizations if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN) { // found green presignal exit @@ -337,6 +344,7 @@ static SigFlags ExploreSegment(Owner owner) flags |= SF_GREEN; } } + continue; } } @@ -434,13 +442,13 @@ static void UpdateSignalsAroundSegment(SigFlags flags) newstate = SIGNAL_STATE_RED; } } else { // entry, at least one exit, no green exit - if (sig & SIGTYPE_ENTRY && (flags & SF_EXIT && !(flags & SF_GREEN))) newstate = SIGNAL_STATE_RED; + if (IsPresignalEntry(tile, TrackdirToTrack(trackdir)) && flags & SF_EXIT && !(flags & SF_GREEN)) newstate = SIGNAL_STATE_RED; } } /* only when the state changes */ if (newstate != GetSignalStateByTrackdir(tile, trackdir)) { - if (sig & SIGTYPE_EXIT) { + if (IsPresignalExit(tile, TrackdirToTrack(trackdir))) { /* for pre-signal exits, add block to the global set */ DiagDirection exitdir = TrackdirToExitdir(ReverseTrackdir(trackdir)); _globset.Add(tile, exitdir); // do not check for full global set, first update all signals