(svn r13933) -Codechange [YAPP]: Handle through and PBS signals correctly in the signal code. (michi_cc)
authorrubidium
Sat, 02 Aug 2008 22:48:57 +0000
changeset 9791 7bcdf05e5e5b
parent 9790 5d5c70e0334e
child 9792 e6efb2eb4851
(svn r13933) -Codechange [YAPP]: Handle through and PBS signals correctly in the signal code. (michi_cc)
src/rail_cmd.cpp
src/rail_map.h
src/signal.cpp
--- a/src/rail_cmd.cpp	Sat Aug 02 22:48:43 2008 +0000
+++ b/src/rail_cmd.cpp	Sat Aug 02 22:48:57 2008 +0000
@@ -2181,12 +2181,13 @@
 
 			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);
--- a/src/rail_map.h	Sat Aug 02 22:48:43 2008 +0000
+++ b/src/rail_map.h	Sat Aug 02 22:48:57 2008 +0000
@@ -368,6 +368,12 @@
 	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;
--- a/src/signal.cpp	Sat Aug 02 22:48:43 2008 +0000
+++ b/src/signal.cpp	Sat Aug 02 22:48:57 2008 +0000
@@ -256,6 +256,7 @@
 	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 @@
 						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 @@
 								flags |= SF_GREEN;
 							}
 						}
+
 						continue;
 					}
 				}
@@ -434,13 +442,13 @@
 					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