Irrelevant now with the new maps hacking.

Index: docs/landscape.html
===================================================================
--- docs/landscape.html	(revision 725)
+++ docs/landscape.html	(working copy)
@@ -534,7 +534,25 @@
 <li>map_owner: <a href="#OwnershipInfo">owner</a> of the tunnel</li>
 <li>map3_lo bits 3..0 = <a href="#TrackType">track type</a> for railway tunnel, must be 0 for road tunnel</li>
 <li>map3_hi bit 7 set = on snow or desert</li>
+<li>map5 bits 3..2 clear (railway):
+<ul>
+<li>map3_hi bit 3 set: signals present
+<ul>
+<li>For track in the X direction:
+<table>
+<tr><td nowrap valign=top>map3_lo bit 4: </td><td align=left>signal in the SW direction</td></tr>
+<tr><td nowrap valign=top>map3_lo bit 5: </td><td align=left>signal in the NE direction</td></tr>
+</table></li>
+<li>For track in the Y direction:
+<table>
+<tr><td nowrap valign=top>map3_lo bit 4: </td><td align=left>signal in the NW direction</td></tr>
+<tr><td nowrap valign=top>map3_lo bit 5: </td><td align=left>signal in the SE direction</td></tr>
+</table></li>
+<li>map3_hi bits 2..0 = OpenTTD signal bits, see railway track documentation</li>
+<li>map3_hi bits 5..4: bit clear = signal shows red; same bits as in map3_lo</li>
 </ul>
+</ul>
+</ul>
 map5 bit 7 set: bridge
 <ul><li>
 map5 bit 6 clear: bridge ending
@@ -542,7 +560,25 @@
 <li>map5 bit 5: clear - northern, set - southern ending</li>
 <li>map3_lo bits 3..0 = <a href="#TrackType">type of track</a> on the bridge, must be 0 for road bridge</li>
 <li>map_owner: <a href="#OwnershipInfo">owner</a> of the bridge</li>
+<li>map5 bits 2..1 clear (railway):
+<ul>
+<li>map3_hi bit 3 set: signals present
+<ul>
+<li>For track in the X direction:
+<table>
+<tr><td nowrap valign=top>map3_lo bit 4: </td><td align=left>signal in the SW direction</td></tr>
+<tr><td nowrap valign=top>map3_lo bit 5: </td><td align=left>signal in the NE direction</td></tr>
+</table></li>
+<li>For track in the Y direction:
+<table>
+<tr><td nowrap valign=top>map3_lo bit 4: </td><td align=left>signal in the NW direction</td></tr>
+<tr><td nowrap valign=top>map3_lo bit 5: </td><td align=left>signal in the SE direction</td></tr>
+</table></li>
+<li>map3_hi bits 2..0 = OpenTTD signal bits, see railway track documentation</li>
+<li>map3_hi bits 5..4: bit clear = signal shows red; same bits as in map3_lo</li>
 </ul>
+</ul>
+</ul>
 map5 bit 6 set: bridge middle part
 <ul>
 <li>map5 bit 5 clear:
Index: tunnelbridge_cmd.c
===================================================================
--- tunnelbridge_cmd.c	(revision 725)
+++ tunnelbridge_cmd.c	(working copy)
@@ -187,6 +187,7 @@
 			railtype, /* map3_lo */
 			0x80 | direction | rail_or_road /* map5 */
 		);
+		_map3_hi[ti_start.tile] &= ~0x3f; // reset signals
 	}
 
 	lookflag = 0;
@@ -262,6 +263,8 @@
 			_map3_lo[ti.tile] &= 0xF;
 			_map3_lo[ti.tile] |= (byte)(railtype << 4);
 
+			_map3_hi[ti_start.tile] &= ~0x3f; // reset signals
+
 			MarkTileDirtyByTile(ti.tile);
 		}
 	}
@@ -492,6 +495,7 @@
 {
 	uint endtile;
 	int length;
+	int sigcost = 0;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 	
@@ -503,6 +507,18 @@
 	endtile = CheckTunnelBusy(tile, &length);
 	if (endtile == (uint)-1) return CMD_ERROR;
 
+	if (_map3_hi[tile] & 8) {
+		int cost = DoCommandByTile(tile, 0, 0, flags, CMD_REMOVE_SIGNALS);
+		if (cost == CMD_ERROR) return CMD_ERROR;
+		sigcost += cost;
+	}
+
+	if (_map3_hi[endtile] & 8) {
+		int cost = DoCommandByTile(endtile, 0, 0, flags, CMD_REMOVE_SIGNALS);
+		if (cost == CMD_ERROR) return CMD_ERROR;
+		sigcost += cost;
+	}
+
 	_build_tunnel_endtile = endtile;
 
 	if (flags & DC_EXEC) {
@@ -511,7 +527,7 @@
 		UpdateSignalsOnSegment(tile, _updsignals_tunnel_dir[_map5[tile]&3]);
 		UpdateSignalsOnSegment(endtile, _updsignals_tunnel_dir[_map5[endtile]&3]);
 	}
-	return  _price.clear_tunnel * (length + 1);
+	return  _price.clear_tunnel * (length + 1) + sigcost;
 }
 
 static uint FindEdgesOfBridge(uint tile, uint *endtile)
@@ -545,6 +561,7 @@
 	uint endtile;
 	Vehicle *v;
 	int direction;
+	int sigcost = 0;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
@@ -579,6 +596,18 @@
 		return CMD_ERROR;
 	}
 
+	if (_map3_hi[tile] & 8) {
+		int cost = DoCommandByTile(tile, 0, 0, flags, CMD_REMOVE_SIGNALS);
+		if (cost == CMD_ERROR) return CMD_ERROR;
+		sigcost += cost;
+	}
+
+	if (_map3_hi[endtile] & 8) {
+		int cost = DoCommandByTile(endtile, 0, 0, flags, CMD_REMOVE_SIGNALS);
+		if (cost == CMD_ERROR) return CMD_ERROR;
+		sigcost += cost;
+	}
+
 	if (flags & DC_EXEC) {
 		byte m5;
 		uint t = tile;
@@ -613,7 +642,7 @@
 		SetSignalsOnBothDir(endtile, direction);
 	}
 
-	return ((((endtile - tile) >> (direction?8:0))&0xFF)+1) * _price.clear_bridge;
+	return ((((endtile - tile) >> (direction?8:0))&0xFF)+1) * _price.clear_bridge + sigcost;
 }
 
 static int32 ClearTile_TunnelBridge(uint tile, byte flags) {
@@ -778,6 +807,8 @@
 	}
 }
 
+void DrawSignals(TileInfo *ti, byte m5, byte signals_have, byte signals_set);
+
 static void DrawTile_TunnelBridge(TileInfo *ti)
 {
 	uint32 image;
@@ -799,6 +830,12 @@
 		DrawGroundSprite(image);
 
 		AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z);
+
+		// draw signals?
+		if (_map3_hi[ti->tile] & 8) {
+			/* m5 is coded in rail bits - that's either DIAG_X or DIAG_Y for us. */
+			DrawSignals(ti, 1 + (ti->map5 & 1), _map3_lo[ti->tile] >> 2, _map3_hi[ti->tile] >> 2);
+		}
 	// draw bridge?
 	} else if ((byte)ti->map5 & 0x80) {
 		// get type of track on the bridge.
@@ -834,6 +871,12 @@
 			// draw ramp
 			if (!(_display_opt & DO_TRANS_BUILDINGS)) image = (image & 0x3FFF) | 0x03224000;
 			AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 7, ti->z);
+
+			// draw signals?
+			if (_map3_hi[ti->tile] & 8) {
+				/* m5 is coded in rail bits - that's either DIAG_X or DIAG_Y for us. */
+				DrawSignals(ti, 1 + (ti->map5 & 1), _map3_lo[ti->tile] >> 2, _map3_hi[ti->tile] >> 2);
+			}
 		} else {
 			// bridge middle part.
 			uint z;
@@ -873,7 +916,7 @@
 				DrawGroundSprite(image);
 			}
 			// get bridge sprites
-			b = _bridge_sprite_table[_map2[ti->tile]>>4][_map2[ti->tile]&0xF] + tmp * 4;
+			b = _bridge_sprite_table[_map2[ti->tile]>>4/*&0xC*/][_map2[ti->tile]&0xF] + tmp * 4;
 
 			z = GetBridgeHeight(ti->tile) + 5;
 			
@@ -882,12 +925,12 @@
 			if (!(_display_opt & DO_TRANS_BUILDINGS)) image = (image & 0x3FFF) | 0x03224000;
 			AddSortableSpriteToDraw(image, ti->x, ti->y, (ti->map5&1)?11:16, (ti->map5&1)?16:11, 1, z);
 
+			// draw roof
 			x = ti->x;
 			y = ti->y;
 			image = b[1];
 			if (!(_display_opt & DO_TRANS_BUILDINGS)) image = (image & 0x3FFF) | 0x03224000;
 
-			// draw roof
 			if (ti->map5&1) {
 				x += 12;
 				if (image&0x3FFF) AddSortableSpriteToDraw(image, x,y, 1, 16, 0x28, z);
@@ -1078,17 +1121,32 @@
 
 static uint32 GetTileTrackStatus_TunnelBridge(uint tile, int mode)
 {
-	uint32 result;
+	uint32 result = 0;
 	byte t, m5 = _map5[tile];
 
+	if (m5 & 8) {
+		/* has signals */
+		byte a = (_map3_lo[tile] & 0x30) << 2;
+		byte b = (_map3_hi[tile] & 0x30) << 2;
+
+		b &= a;
+
+		if ((a & 0xC0) == 0) { b |= 0xC0; }
+		if ((a & 0x30) == 0) { b |= 0x30; }
+
+		if ((b & 0x80) == 0) result |= 0x10070000;
+		if ((b & 0x40) == 0) result |= 0x7100000;
+		if ((b & 0x20) == 0) result |= 0x20080000;
+		if ((b & 0x10) == 0) result |= 0x8200000;
+	}
+
 	if ((m5 & 0xF0) == 0) {
 		if (((m5 & 0xC) >> 1) == mode) { /* XXX: possible problem when switching mode constants */
-			return m5&1 ? 0x202 : 0x101;
+			return result | (m5&1 ? 0x202 : 0x101);
 		}
 	} else if (m5 & 0x80) {
-		result = 0;
 		if ((m5 & 6) == mode) {
-			result = m5&1 ? 0x202 : 0x101;
+			result |= m5&1 ? 0x202 : 0x101;
 		}
 		if (m5 & 0x40) {
 			t = m5;
Index: rail_cmd.c
===================================================================
--- rail_cmd.c	(revision 725)
+++ rail_cmd.c	(working copy)
@@ -785,8 +785,8 @@
 /* build signals, p1 = track */
 int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
 {
-	uint tile;
-	byte m5;
+	uint tile = TILE_FROM_XY(x,y);
+	byte m5 = _map5[tile];
 	int32 cost;
 	int track = p1 & 0x7;
 	
@@ -794,23 +794,38 @@
 	assert(p2 == 0);
 	
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
-
-	tile = TILE_FROM_XY(x,y);
 	
 	if (!EnsureNoVehicle(tile))
 		return CMD_ERROR;
 
 	_error_message = STR_1005_NO_SUITABLE_RAILROAD_TRACK;
 	
-	// must be railway, and not a depot, and it must have a track in the suggested position.
-	if (!IS_TILETYPE(tile, MP_RAILWAY) || (m5=_map5[tile], m5&0x80) || !HASBIT(m5, track))
+	if (IS_TILETYPE(tile, MP_RAILWAY)) {
+		// must not be a depot, and it must have a track in the suggested position.
+		if ((m5 & RAIL_TYPE_SPECIAL) || !HASBIT(m5, track))
+			return CMD_ERROR;
+
+	} else if (IS_TILETYPE(tile, MP_TUNNELBRIDGE)) {
+		// must not be a road bridge (bit 7 zero, 2..1) nor a road tunnel (bit 7, 3..2)
+		if ((m5 & 0x80) ? (m5 & 6) : (m5 & 12))
+			return CMD_ERROR;
+		// can be only a bridge endpoint (if bridge)
+		if ((m5 & 0x80) && (m5 & 0x40))
+			return CMD_ERROR;
+
+	} else {
 		return CMD_ERROR;
+	}
 
 	// check rail combination
-	{
+	if (IS_TILETYPE(tile, MP_RAILWAY)) {
 		byte m = m5 & RAIL_BIT_MASK;
-		if (m != RAIL_BIT_DIAG1 && m != RAIL_BIT_DIAG2 && m != RAIL_BIT_UPPER && m != RAIL_BIT_LOWER && 
-				m != RAIL_BIT_LEFT && m != RAIL_BIT_RIGHT && m != (RAIL_BIT_UPPER|RAIL_BIT_LOWER) && m != (RAIL_BIT_LEFT|RAIL_BIT_RIGHT))
+
+		if (m != RAIL_BIT_DIAG1 && m != RAIL_BIT_DIAG2 &&
+		    m != RAIL_BIT_UPPER && m != RAIL_BIT_LOWER &&
+		    m != RAIL_BIT_LEFT && m != RAIL_BIT_RIGHT &&
+		    m != (RAIL_BIT_UPPER | RAIL_BIT_LOWER) &&
+		    m != (RAIL_BIT_LEFT | RAIL_BIT_RIGHT))
 			return CMD_ERROR;
 	}
 
@@ -820,28 +835,40 @@
 
 	// If it had signals previously it's no cost to build.
 	cost = 0;
-	if (!(m5 & RAIL_TYPE_SIGNALS)) {
+	if (IS_TILETYPE(tile, MP_RAILWAY) ? !(m5 & RAIL_TYPE_SIGNALS) : !(_map3_hi[tile] & 8)) {
 		cost = _price.build_signals;
 	}
 
 	if (flags & DC_EXEC) {
-		
-
-		if (!(m5 & RAIL_TYPE_SIGNALS)) {
-			_map5[tile] |= RAIL_TYPE_SIGNALS; // change into signals
-			_map2[tile] |= 0xF0;              // all signals are on
-			_map3_lo[tile] &= ~0xF0;          // no signals built by default
-			_map3_hi[tile] = (p1 & 8) ? 4 : 0;// initial presignal state, semaphores depend on ctrl key
-			goto ignore_presig;
+		if (IS_TILETYPE(tile, MP_RAILWAY)) {
+			if (!(m5 & RAIL_TYPE_SIGNALS)) {
+				_map5[tile] |= RAIL_TYPE_SIGNALS; // change into signals
+				_map2[tile] |= 0xF0;              // all signals are on
+				_map3_lo[tile] &= ~0xF0;          // no signals built by default
+				_map3_hi[tile] = (p1 & 8) ? 4 : 0;// initial presignal state, semaphores depend on ctrl key
+				p1 = 0;
+			}
+		} else {
+			if (!(_map3_hi[tile] & 8)) {
+				_map3_hi[tile] |= 8;              // change into signals
+				_map3_hi[tile] |= 0x30;           // all signals are on
+				_map3_lo[tile] &= ~0x30;          // no signals built by default
+				_map3_hi[tile] &= ~0x7;           // no OpenTTD bits set
+				if (p1 & 8) _map3_hi[tile] |= 4;  // semaphores depend on ctrl key
+				p1 = 0;
+			}
 		}
 
 		if (!(p1 & 8)) {
 			byte a,b,c,d;
-ignore_presig:
 			a = _signals_table[track];      // signal for this track in one direction
 			b = _signals_table[track + 8];  // signal for this track in the other direction
+			if (IS_TILETYPE(tile, MP_TUNNELBRIDGE)) {
+				assert(!(a & 0x3f) && !(b & 0x3f));
+				a >>= 2; b >>= 2;       // we have the signals in bits 4,5, not 6,7
+			}
 			c = a | b;
-			d = _map3_lo[tile] & c;					// mask of built signals. it only affects &0xF0
+			d = _map3_lo[tile] & c;         // mask of built signals. it only affects &0xF0
 
 			// Alternate between a|b, b, a
 			if ( d != 0 && d != a) {
@@ -853,7 +880,7 @@
 			// toggle between the signal types. Using low 2 bits of map3_hi.
 			_map3_hi[tile] = (_map3_hi[tile] & ~3) | ((_map3_hi[tile] + 1) & 3);
 		}
-		
+
 		MarkTileDirtyByTile(tile);
 		SetSignalsOnBothDir(tile, track);
 	}
@@ -880,13 +907,35 @@
 	if (!EnsureNoVehicle(tile))
 		return CMD_ERROR;
 
-	/* Signals can only exist on railways */
-	if (ti.type != MP_RAILWAY)
-		return CMD_ERROR;
+	/* Signals can only exist on railways... */
+	if (ti.type != MP_RAILWAY) {
+		/* ...and sometimes in tunnels/bridges. */
+		if (ti.type == MP_TUNNELBRIDGE) {
+			printf("a\n");
+			// tunnels/bridges are ok if they aren't road
+			if ((ti.map5 & 0x80) ? (ti.map5 & 6) : (ti.map5 & 12))
+				return CMD_ERROR;
+			printf("b\n");
+			// regarding bridges, we care only about endpoints
+			if ((ti.map5 & 0x80) && (ti.map5 & 0x40))
+				return CMD_ERROR;
+			printf("c\n");
+		} else {
+			return CMD_ERROR;
+		}
+	}
 
-	/* Map5 mode is 0x40 when there's signals */
-	if ((ti.map5 & RAIL_TYPE_MASK) != RAIL_TYPE_SIGNALS)
-		return CMD_ERROR;
+	if (ti.type == MP_RAILWAY) {
+		/* Map5 mode is 0x40 when there's signals */
+		if ((ti.map5 & RAIL_TYPE_MASK) != RAIL_TYPE_SIGNALS)
+			return CMD_ERROR;
+	} else {
+		/* For TUNNELBRIDGE we store it in bit 0x8 of map3_hi */
+			printf("d %x\n", _map3_hi[ti.tile]);
+		if (!(_map3_hi[ti.tile] & 8))
+			return CMD_ERROR;
+			printf("e\n");
+	}
 
 	/* Who owns the tile? */
 	if (_current_player != OWNER_WATER && !CheckTileOwnership(tile))
@@ -894,14 +943,23 @@
 
 	/* Do it? */
 	if (flags & DC_EXEC) {
-		byte bits = _map5[tile];
-		_map5[tile] &= ~RAIL_TYPE_SIGNALS;
-		_map2[tile] &= ~0xF0;
-		
-		/* TTDBUG: this code contains a bug, if a tile contains 2 signals
-		 * on separate tracks, it won't work properly for the 2nd track */		
-		SetSignalsOnBothDir(tile, FIND_FIRST_BIT(bits & RAIL_BIT_MASK)); 
+		byte track;
 
+		if (ti.type == MP_RAILWAY) {
+			/* TTDBUG: this code contains a bug, if a tile contains 2 signals
+			 * on separate tracks, it won't work properly for the 2nd track */
+			track = FIND_FIRST_BIT(_map5[tile] & RAIL_BIT_MASK);
+
+			_map5[tile] &= ~RAIL_TYPE_SIGNALS;
+			_map2[tile] &= ~0xF0;
+		} else {
+			track = _map5[tile] & 1;
+			_map3_hi[tile] &= ~30; // no signals active
+			_map3_hi[tile] &= ~8;  // and no signals altogether
+		}
+
+		SetSignalsOnBothDir(tile, track);
+
 		MarkTileDirtyByTile(tile);
 	}
 	
@@ -1255,6 +1313,40 @@
 	}
 }
 
+void DrawSignals(TileInfo *ti, byte m5, byte signals_have, byte signals_set)
+{
+#define HAS_SIGNAL(x) (signals_have & (byte)(1 << (x)))
+#define ISON_SIGNAL(x) (signals_set & (byte)(1 << (x)))
+#define MAYBE_DRAW_SIGNAL(x,y,z) if (HAS_SIGNAL(x)) DrawSignalHelper(ti, ISON_SIGNAL(x), ((y-0x4FB) << 4)|(z))
+
+	if (!(m5 & RAIL_BIT_DIAG2)) {
+		if (!(m5 & RAIL_BIT_DIAG1)) {
+			if (m5 & RAIL_BIT_LEFT) {
+				MAYBE_DRAW_SIGNAL(2, 0x509, 0);
+				MAYBE_DRAW_SIGNAL(3, 0x507, 1);
+			}
+			if (m5 & RAIL_BIT_RIGHT) {
+				MAYBE_DRAW_SIGNAL(0, 0x509, 2);
+				MAYBE_DRAW_SIGNAL(1, 0x507, 3);
+			}
+			if (m5 & RAIL_BIT_UPPER) {
+				MAYBE_DRAW_SIGNAL(3, 0x505, 4);
+				MAYBE_DRAW_SIGNAL(2, 0x503, 5);
+			}
+			if (m5 & RAIL_BIT_LOWER) {
+				MAYBE_DRAW_SIGNAL(1, 0x505, 6);
+				MAYBE_DRAW_SIGNAL(0, 0x503, 7);
+			}
+		} else {
+			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8);
+			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9);
+		}
+	} else {
+		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10);
+		MAYBE_DRAW_SIGNAL(2, 0x501, 11);
+	}
+}
+
 static void DrawTile_Track(TileInfo *ti)
 {
 	uint32 tracktype_offs, image;
@@ -1321,45 +1413,9 @@
 		}
 
 		/* draw signals also? */
-		if (!(ti->map5 & RAIL_TYPE_SIGNALS))
-			return;
+		if (ti->map5 & RAIL_TYPE_SIGNALS)
+			DrawSignals(ti, m5, _map3_lo[ti->tile] >> 4, _map2[ti->tile] >> 4);
 
-		{
-			byte m23;
-
-			m23 = (_map3_lo[ti->tile] >> 4) | (_map2[ti->tile] & 0xF0);
-
-#define HAS_SIGNAL(x) (m23 & (byte)(0x1 << (x)))
-#define ISON_SIGNAL(x) (m23 & (byte)(0x10 << (x)))
-#define MAYBE_DRAW_SIGNAL(x,y,z) if (HAS_SIGNAL(x)) DrawSignalHelper(ti, ISON_SIGNAL(x), ((y-0x4FB) << 4)|(z))
-
-		if (!(m5 & RAIL_BIT_DIAG2)) {
-			if (!(m5 & RAIL_BIT_DIAG1)) {
-				if (m5 & RAIL_BIT_LEFT) {
-					MAYBE_DRAW_SIGNAL(2, 0x509, 0);
-					MAYBE_DRAW_SIGNAL(3, 0x507, 1);
-				}
-				if (m5 & RAIL_BIT_RIGHT) {
-					MAYBE_DRAW_SIGNAL(0, 0x509, 2);
-					MAYBE_DRAW_SIGNAL(1, 0x507, 3);
-				}
-				if (m5 & RAIL_BIT_UPPER) {
-					MAYBE_DRAW_SIGNAL(3, 0x505, 4);
-					MAYBE_DRAW_SIGNAL(2, 0x503, 5);
-				}
-				if (m5 & RAIL_BIT_LOWER) {
-					MAYBE_DRAW_SIGNAL(1, 0x505, 6);
-					MAYBE_DRAW_SIGNAL(0, 0x503, 7);
-				}
-			} else {
-				MAYBE_DRAW_SIGNAL(3, 0x4FB, 8);
-				MAYBE_DRAW_SIGNAL(2, 0x4FD, 9);
-			}
-		} else {
-			MAYBE_DRAW_SIGNAL(3, 0x4FF, 10);
-			MAYBE_DRAW_SIGNAL(2, 0x501, 11);
-		}
-		}
 	} else {
 		const byte *s;
 		const DrawTrackSeqStruct *drss;
@@ -1472,7 +1528,41 @@
 			}
 		} else if (IS_RAIL_DEPOT(_map5[tile]))
 			return true; // don't look further if the tile is a depot
+
+	} else if (IS_TILETYPE(tile, MP_TUNNELBRIDGE)) {
+		printf("TB tile %x (%x, %x)\n", tile, _map5[tile], _map3_lo[tile]);
+		if ((_map3_hi[tile] & 8) && (_map3_lo[tile] & 0x30)) {
+			byte forward, reverse;
+
+			// signal bits for forward and reverse direction
+			forward = 0x10 + (track & 8) * 0x10;
+			reverse = 0x30 - forward;
+
+			// is the signal pointing in to the segment existing?
+			if (_map3_lo[tile] & forward) {
+				// yes, add the signal to the list of signals
+				printf("To update a signal of %x (track %d).\n", tile, track);
+				if (ssd->cur != NUM_SSD_ENTRY) {
+					ssd->tile[ssd->cur] = tile; // remember the tile index
+					ssd->bit[ssd->cur] = track; // and the controlling bit number
+					ssd->cur++;
+				}
+
+				// remember if this block has a presignal.
+				ssd->has_presignal |= (_map3_hi[tile]&1);
+			}
+			
+			// is this an exit signal that points out from the segment?
+			if ((_map3_hi[tile]&2) && _map3_lo[tile] & reverse) {
+				ssd->presignal_exits++;
+				if (_map3_hi[tile] & reverse)
+					ssd->presignal_exits_free++;
+			}
+
+			return true;
+		}
 	}
+
 	return false;
 }
 
@@ -1542,16 +1632,27 @@
 	for(i=0; i!=ssd->cur; i++) {
 		uint tile = ssd->tile[i];
 		byte bit = _signals_table[ssd->bit[i]];
-		byte m2 = _map2[tile];
+		byte revbit = _signals_table_other[ssd->bit[i]];
+		byte m2;
+		byte m3l = _map3_lo[tile];
 
+		if (IS_TILETYPE(tile, MP_RAILWAY)) {
+			m2 = _map2[tile];
+		} else { // MP_TUNNELBRIDGE
+			m2 = _map3_hi[tile] << 2;
+			m3l <<= 2;
+		}
+
+		printf("I want to turn %s signals at %x (track %d)\n", ssd->stop ? "red" : "green", ssd->tile[i], ssd->bit[i]);
+
 		// presignals don't turn green if there is at least one presignal exit and none are free
 		if (_map3_hi[tile] & 1) {
 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
 
 			// subtract for dual combo signals so they don't count themselves
-			if (_map3_hi[tile]&2 && _map3_lo[tile]&_signals_table_other[ssd->bit[i]]) {
+			if (_map3_hi[tile]&2 && (m3l & revbit)) {
 				ex--;
-				if ((_map2[tile]&_signals_table_other[ssd->bit[i]]) != 0) exfree--;
+				if ((m2 & revbit) != 0) exfree--;
 			}
 
 			// if we have exits and none are free, make red.
@@ -1583,7 +1684,11 @@
 		}
 		
 		// it changed, so toggle it
-		_map2[tile] = m2 ^ bit;
+		if (IS_TILETYPE(tile, MP_RAILWAY)) {
+			_map2[tile] = m2 ^ bit;
+		} else { // MP_TUNNELBRIDGE
+			_map3_hi[tile] = (m2 ^ bit) >> 2; // BUG: 2 highest bits destroyed
+		}
 		MarkTileDirtyByTile(tile);
 	}
 }
Index: train_cmd.c
===================================================================
--- train_cmd.c	(revision 725)
+++ train_cmd.c	(working copy)
@@ -986,6 +1028,12 @@
 			if (!(_map3_lo[tile] & _signal_onedir[track]) && _map3_lo[tile] & _signal_otherdir[track])
 				return true;
 		}
+
+	} else if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) && (_map3_hi[tile] & 8)) {
+		// make sure the train doesn't run against a oneway signal
+		byte m3 = _map3_lo[tile] << 2;
+		if (!(m3 & _signal_onedir[track]) && m3 & _signal_otherdir[track])
+			return true;
 	}
 
 	// stop  searching if we've found a destination that is closer already.
@@ -1192,14 +1249,23 @@
 } TrainTrackFollowerData;
 
 static bool TrainTrackFollower(uint tile, TrainTrackFollowerData *ttfd, int track, uint length, byte *state){
-	if (IS_TILETYPE(tile, MP_RAILWAY) && (_map5[tile]&0xC0) == 0x40) {
+	if ((IS_TILETYPE(tile, MP_RAILWAY) && (_map5[tile]&0xC0) == 0x40)
+	    || (IS_TILETYPE(tile, MP_TUNNELBRIDGE) && _map3_hi[tile]&8)) {
 		// the tile has a signal
 		byte m3 = _map3_lo[tile];
+		byte m2 = _map2[tile];
+
+		if (IS_TILETYPE(tile, MP_TUNNELBRIDGE)) {
+			// bitscheme shift to match railway's
+			m2 = _map3_hi[tile] << 2;
+			m3 <<= 2;
+		}
+
 		if (!(m3 & _signal_onedir[track])) {
 			// if one way signal not pointing towards us, stop going in this direction.
 			if (m3 & _signal_otherdir[track])
 				return true;
-		} else if (_map2[tile] & _signal_onedir[track]) {
+		} else if (m2 & _signal_onedir[track]) {
 			// green signal in our direction. either one way or two way.
 			*state = true;
 		} else if (m3 & _signal_otherdir[track]) {
@@ -1771,7 +1837,11 @@
 	int i;
 	if (IS_TILETYPE(tile, MP_RAILWAY) && (_map5[tile]&0xC0)==0x40) {
 		i = FindFirstBit2x64((_map5[tile]+(_map5[tile]<<8)) & _reachable_tracks[dir]);
+		printf("Updating plseg %x dir %d\n", tile, _otherside_signal_directions[i]);
 		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]);
+	} else if (IS_TILETYPE(tile, MP_TUNNELBRIDGE) && _map3_hi[tile]&8) {
+		printf("Updating seg %x dir %d\n", tile, dir);
+		UpdateSignalsOnSegment(tile, dir << 1);
 	}
 }
 
@@ -2028,24 +2098,29 @@
 	goto reverse_train_direction;
 
 red_light: {
+		byte m3 = _map3_lo[gp.new_tile];
+
+		if (IS_TILETYPE(gp.new_tile, MP_TUNNELBRIDGE))
+			m3 <<= 2; // convert to rail-like m3
+
 		/* find the first set bit in ts. need to do it in 2 steps, since
 		 * FIND_FIRST_BIT only handles 6 bits at a time. */
 		i = FindFirstBit2x64(ts);
 		
-		if (!(_map3_lo[gp.new_tile] & _signal_otherdir[i])) {
+		if (!(m3 & _signal_otherdir[i])) {
 			v->cur_speed = 0;
 			v->subspeed = 0;
 			v->progress = 255-100;
 			if (++v->load_unload_time_rem < 254)
 				return;
-		} else if (_map3_lo[gp.new_tile] & _signal_onedir[i]){
+		} else if (m3 & _signal_onedir[i]) {
 			v->cur_speed = 0;
 			v->subspeed = 0;
 			v->progress = 255-10;
 			if (++v->load_unload_time_rem < 254) {
 				uint o_tile = gp.new_tile + _tileoffs_by_dir[dir>>1];
 				/* check if a train is waiting on the other side */
-				if (VehicleFromPos(o_tile, (void*)( (o_tile<<8) | (dir^4)), (VehicleFromPosProc*)CheckVehicleAtSignal) == NULL)
+				if (VehicleFromPos(o_tile, (void*)((o_tile<<8) | (dir^4)), (VehicleFromPosProc*)CheckVehicleAtSignal) == NULL)
 					return;
 			}
 		}
