src/rail_cmd.cpp
branchNewGRF_ports
changeset 6719 4cc327ad39d5
parent 6694 a10a42eefd52
child 6720 35756db7e577
equal deleted inserted replaced
6718:5a8b295aa345 6719:4cc327ad39d5
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file rail_cmd.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 #include "bridge_map.h"
     7 #include "bridge_map.h"
     6 #include "bridge.h"
     8 #include "bridge.h"
    75  *               11uuuudd => rail depot
    77  *               11uuuudd => rail depot
    76  */
    78  */
    77 
    79 
    78 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
    80 static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
    79 {
    81 {
    80 	TrackBits current; /* The current track layout */
    82 	TrackBits current; // The current track layout
    81 	TrackBits future; /* The track layout we want to build */
    83 	TrackBits future;  // The track layout we want to build
    82 	_error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
    84 	_error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
    83 
    85 
    84 	if (!IsPlainRailTile(tile)) return false;
    86 	if (!IsPlainRailTile(tile)) return false;
    85 
    87 
    86 	/* So, we have a tile with tracks on it (and possibly signals). Let's see
    88 	/* So, we have a tile with tracks on it (and possibly signals). Let's see
   107 }
   109 }
   108 
   110 
   109 
   111 
   110 static const TrackBits _valid_tileh_slopes[][15] = {
   112 static const TrackBits _valid_tileh_slopes[][15] = {
   111 
   113 
   112 // set of normal ones
   114 /* set of normal ones */
   113 {
   115 {
   114 	TRACK_BIT_ALL,
   116 	TRACK_BIT_ALL,
   115 	TRACK_BIT_RIGHT,
   117 	TRACK_BIT_RIGHT,
   116 	TRACK_BIT_UPPER,
   118 	TRACK_BIT_UPPER,
   117 	TRACK_BIT_X,
   119 	TRACK_BIT_X,
   129 	TRACK_BIT_X,
   131 	TRACK_BIT_X,
   130 	TRACK_BIT_UPPER,
   132 	TRACK_BIT_UPPER,
   131 	TRACK_BIT_RIGHT,
   133 	TRACK_BIT_RIGHT,
   132 },
   134 },
   133 
   135 
   134 // allowed rail for an evenly raised platform
   136 /* allowed rail for an evenly raised platform */
   135 {
   137 {
   136 	TRACK_BIT_NONE,
   138 	TRACK_BIT_NONE,
   137 	TRACK_BIT_LEFT,
   139 	TRACK_BIT_LEFT,
   138 	TRACK_BIT_LOWER,
   140 	TRACK_BIT_LOWER,
   139 	TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
   141 	TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
   188 
   190 
   189 
   191 
   190 static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   192 static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
   191 {
   193 {
   192 	if (IsSteepSlope(tileh)) {
   194 	if (IsSteepSlope(tileh)) {
   193 		if (existing == 0) {
   195 		if (_patches.build_on_slopes && existing == 0) {
   194 			TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
   196 			TrackBits valid = TRACK_BIT_CROSS | (HASBIT(1 << SLOPE_STEEP_W | 1 << SLOPE_STEEP_E, tileh) ? TRACK_BIT_VERT : TRACK_BIT_HORZ);
   195 			if (valid & rail_bits) return _price.terraform;
   197 			if (valid & rail_bits) return _price.terraform;
   196 		}
   198 		}
   197 	} else {
   199 	} else {
   198 		rail_bits |= existing;
   200 		rail_bits |= existing;
   199 
   201 
   200 		// don't allow building on the lower side of a coast
   202 		/* don't allow building on the lower side of a coast */
   201 		if (IsTileType(tile, MP_WATER) &&
   203 		if (IsTileType(tile, MP_WATER) &&
   202 				~_valid_tileh_slopes[1][tileh] & rail_bits) {
   204 				~_valid_tileh_slopes[1][tileh] & rail_bits) {
   203 			return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
   205 			return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
   204 		}
   206 		}
   205 
   207 
   206 		// no special foundation
   208 		/* no special foundation */
   207 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0)
   209 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0)
   208 			return 0;
   210 			return 0;
   209 
   211 
   210 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
   212 		if ((~_valid_tileh_slopes[1][tileh] & rail_bits) == 0 || ( // whole tile is leveled up
   211 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
   213 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
   226 /* Validate functions for rail building */
   228 /* Validate functions for rail building */
   227 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);}
   229 static inline bool ValParamTrackOrientation(Track track) {return IsValidTrack(track);}
   228 
   230 
   229 /** Build a single piece of rail
   231 /** Build a single piece of rail
   230  * @param tile tile  to build on
   232  * @param tile tile  to build on
       
   233  * @param flags operation to perform
   231  * @param p1 railtype of being built piece (normal, mono, maglev)
   234  * @param p1 railtype of being built piece (normal, mono, maglev)
   232  * @param p2 rail track to build
   235  * @param p2 rail track to build
   233  */
   236  */
   234 int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   237 int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   235 {
   238 {
   250 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   253 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   251 
   254 
   252 	switch (GetTileType(tile)) {
   255 	switch (GetTileType(tile)) {
   253 		case MP_RAILWAY:
   256 		case MP_RAILWAY:
   254 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   257 			if (!CheckTrackCombination(tile, trackbit, flags) ||
   255 					!EnsureNoVehicle(tile)) {
   258 					!EnsureNoVehicleOnGround(tile)) {
   256 				return CMD_ERROR;
   259 				return CMD_ERROR;
   257 			}
   260 			}
   258 			if (!IsTileOwner(tile, _current_player) ||
   261 			if (!IsTileOwner(tile, _current_player) ||
   259 					!IsCompatibleRail(GetRailType(tile), railtype)) {
   262 					!IsCompatibleRail(GetRailType(tile), railtype)) {
   260 				// Get detailed error message
   263 				/* Get detailed error message */
   261 				return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   264 				return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   262 			}
   265 			}
   263 
   266 
   264 			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
   267 			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
   265 			if (CmdFailed(ret)) return ret;
   268 			if (CmdFailed(ret)) return ret;
   285 			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
   288 			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
   286 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   289 				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   287 			}
   290 			}
   288 #undef M
   291 #undef M
   289 
   292 
   290 			if (!EnsureNoVehicle(tile)) return CMD_ERROR;
   293 			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
   291 
   294 
   292 			if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
   295 			if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
   293 				if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
   296 				if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
   294 
   297 
   295 				if ((track == TRACK_X && GetRoadBits(tile) == ROAD_Y) ||
   298 				RoadTypes roadtypes = GetRoadTypes(tile);
   296 						(track == TRACK_Y && GetRoadBits(tile) == ROAD_X)) {
   299 				RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
       
   300 				RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);
       
   301 				switch (roadtypes) {
       
   302 					default: break;
       
   303 					case ROADTYPES_TRAM:
       
   304 						/* Tram crossings must always have road. */
       
   305 						SetRoadOwner(tile, ROADTYPE_ROAD, _current_player);
       
   306 						roadtypes |= ROADTYPES_ROAD;
       
   307 						break;
       
   308 
       
   309 					case ROADTYPES_ROADTRAM: if (road == tram) break;
       
   310 						/* FALL THROUGH */
       
   311 					case ROADTYPES_ROADHWAY: // Road and highway are incompatible in this case
       
   312 					case ROADTYPES_TRAMHWAY: // Tram and highway are incompatible in this case
       
   313 					case ROADTYPES_ALL:      // Also incompatible
       
   314 						return CMD_ERROR;
       
   315 				}
       
   316 
       
   317 				road |= tram | GetRoadBits(tile, ROADTYPE_HWAY);
       
   318 
       
   319 				if ((track == TRACK_X && road == ROAD_Y) ||
       
   320 						(track == TRACK_Y && road == ROAD_X)) {
   297 					if (flags & DC_EXEC) {
   321 					if (flags & DC_EXEC) {
   298 						MakeRoadCrossing(tile, GetTileOwner(tile), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, GetTownIndex(tile));
   322 						MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile));
   299 					}
   323 					}
   300 					break;
   324 					break;
   301 				}
   325 				}
   302 			}
   326 			}
   303 
   327 
   328 	return cost + _price.build_rail;
   352 	return cost + _price.build_rail;
   329 }
   353 }
   330 
   354 
   331 /** Remove a single piece of track
   355 /** Remove a single piece of track
   332  * @param tile tile to remove track from
   356  * @param tile tile to remove track from
       
   357  * @param flags operation to perform
   333  * @param p1 unused
   358  * @param p1 unused
   334  * @param p2 rail orientation
   359  * @param p2 rail orientation
   335  */
   360  */
   336 int32 CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   361 int32 CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   337 {
   362 {
   348 	switch (GetTileType(tile)) {
   373 	switch (GetTileType(tile)) {
   349 		case MP_STREET: {
   374 		case MP_STREET: {
   350 			if (!IsLevelCrossing(tile) ||
   375 			if (!IsLevelCrossing(tile) ||
   351 					GetCrossingRailBits(tile) != trackbit ||
   376 					GetCrossingRailBits(tile) != trackbit ||
   352 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   377 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   353 					!EnsureNoVehicle(tile)) {
   378 					!EnsureNoVehicleOnGround(tile)) {
   354 				return CMD_ERROR;
   379 				return CMD_ERROR;
   355 			}
   380 			}
   356 
   381 
   357 			if (flags & DC_EXEC) {
   382 			if (flags & DC_EXEC) {
   358 				MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile));
   383 				MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY));
   359 			}
   384 			}
   360 			break;
   385 			break;
   361 		}
   386 		}
   362 
   387 
   363 		case MP_RAILWAY: {
   388 		case MP_RAILWAY: {
   364 			TrackBits present;
   389 			TrackBits present;
   365 
   390 
   366 			if (!IsPlainRailTile(tile) ||
   391 			if (!IsPlainRailTile(tile) ||
   367 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   392 					(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
   368 					!EnsureNoVehicle(tile)) {
   393 					!EnsureNoVehicleOnGround(tile)) {
   369 				return CMD_ERROR;
   394 				return CMD_ERROR;
   370 			}
   395 			}
   371 
   396 
   372 			present = GetTrackBits(tile);
   397 			present = GetTrackBits(tile);
   373 			if ((present & trackbit) == 0) return CMD_ERROR;
   398 			if ((present & trackbit) == 0) return CMD_ERROR;
   430 	int ey = TileY(end);
   455 	int ey = TileY(end);
   431 	int dx, dy, trdx, trdy;
   456 	int dx, dy, trdx, trdy;
   432 
   457 
   433 	if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR;
   458 	if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR;
   434 
   459 
   435 	// calculate delta x,y from start to end tile
   460 	/* calculate delta x,y from start to end tile */
   436 	dx = ex - x;
   461 	dx = ex - x;
   437 	dy = ey - y;
   462 	dy = ey - y;
   438 
   463 
   439 	// calculate delta x,y for the first direction
   464 	/* calculate delta x,y for the first direction */
   440 	trdx = _trackdelta[*trackdir].x;
   465 	trdx = _trackdelta[*trackdir].x;
   441 	trdy = _trackdelta[*trackdir].y;
   466 	trdy = _trackdelta[*trackdir].y;
   442 
   467 
   443 	if (!IsDiagonalTrackdir(*trackdir)) {
   468 	if (!IsDiagonalTrackdir(*trackdir)) {
   444 		trdx += _trackdelta[*trackdir ^ 1].x;
   469 		trdx += _trackdelta[*trackdir ^ 1].x;
   445 		trdy += _trackdelta[*trackdir ^ 1].y;
   470 		trdy += _trackdelta[*trackdir ^ 1].y;
   446 	}
   471 	}
   447 
   472 
   448 	// validate the direction
   473 	/* validate the direction */
   449 	while (
   474 	while (
   450 		(trdx <= 0 && dx > 0) ||
   475 		(trdx <= 0 && dx > 0) ||
   451 		(trdx >= 0 && dx < 0) ||
   476 		(trdx >= 0 && dx < 0) ||
   452 		(trdy <= 0 && dy > 0) ||
   477 		(trdy <= 0 && dy > 0) ||
   453 		(trdy >= 0 && dy < 0)
   478 		(trdy >= 0 && dy < 0)
   459 		} else { // other direction is invalid too, invalid drag
   484 		} else { // other direction is invalid too, invalid drag
   460 			return CMD_ERROR;
   485 			return CMD_ERROR;
   461 		}
   486 		}
   462 	}
   487 	}
   463 
   488 
   464 	// (for diagonal tracks, this is already made sure of by above test), but:
   489 	/* (for diagonal tracks, this is already made sure of by above test), but:
   465 	// for non-diagonal tracks, check if the start and end tile are on 1 line
   490 	 * for non-diagonal tracks, check if the start and end tile are on 1 line */
   466 	if (!IsDiagonalTrackdir(*trackdir)) {
   491 	if (!IsDiagonalTrackdir(*trackdir)) {
   467 		trdx = _trackdelta[*trackdir].x;
   492 		trdx = _trackdelta[*trackdir].x;
   468 		trdy = _trackdelta[*trackdir].y;
   493 		trdy = _trackdelta[*trackdir].y;
   469 		if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx))
   494 		if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx))
   470 			return CMD_ERROR;
   495 			return CMD_ERROR;
   473 	return 0;
   498 	return 0;
   474 }
   499 }
   475 
   500 
   476 /** Build a stretch of railroad tracks.
   501 /** Build a stretch of railroad tracks.
   477  * @param tile start tile of drag
   502  * @param tile start tile of drag
       
   503  * @param flags operation to perform
   478  * @param p1 end tile of drag
   504  * @param p1 end tile of drag
   479  * @param p2 various bitstuffed elements
   505  * @param p2 various bitstuffed elements
   480  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   506  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
   481  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   507  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
   482  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   508  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   513 
   539 
   514 		if (tile == end_tile) break;
   540 		if (tile == end_tile) break;
   515 
   541 
   516 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   542 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   517 
   543 
   518 		// toggle railbit for the non-diagonal tracks
   544 		/* toggle railbit for the non-diagonal tracks */
   519 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   545 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   520 	}
   546 	}
   521 
   547 
   522 	return (total_cost == 0) ? CMD_ERROR : total_cost;
   548 	return (total_cost == 0) ? CMD_ERROR : total_cost;
   523 }
   549 }
   524 
   550 
   525 /** Build rail on a stretch of track.
   551 /** Build rail on a stretch of track.
   526  * Stub for the unified rail builder/remover
   552  * Stub for the unified rail builder/remover
       
   553  * @param tile start tile of drag
       
   554  * @param flags operation to perform
       
   555  * @param p1 end tile of drag
       
   556  * @param p2 various bitstuffed elements
       
   557  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
       
   558  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
       
   559  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   527  * @see CmdRailTrackHelper
   560  * @see CmdRailTrackHelper
   528  */
   561  */
   529 int32 CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   562 int32 CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   530 {
   563 {
   531 	return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7));
   564 	return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7));
   532 }
   565 }
   533 
   566 
   534 /** Build rail on a stretch of track.
   567 /** Build rail on a stretch of track.
   535  * Stub for the unified rail builder/remover
   568  * Stub for the unified rail builder/remover
       
   569  * @param tile start tile of drag
       
   570  * @param flags operation to perform
       
   571  * @param p1 end tile of drag
       
   572  * @param p2 various bitstuffed elements
       
   573  * - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
       
   574  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
       
   575  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
   536  * @see CmdRailTrackHelper
   576  * @see CmdRailTrackHelper
   537  */
   577  */
   538 int32 CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   578 int32 CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   539 {
   579 {
   540 	return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7));
   580 	return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7));
   541 }
   581 }
   542 
   582 
   543 /** Build a train depot
   583 /** Build a train depot
   544  * @param tile position of the train depot
   584  * @param tile position of the train depot
       
   585  * @param flags operation to perform
   545  * @param p1 rail type
   586  * @param p1 rail type
   546  * @param p2 bit 0..1 entrance direction (DiagDirection)
   587  * @param p2 bit 0..1 entrance direction (DiagDirection)
   547  *
   588  *
   548  * @todo When checking for the tile slope,
   589  * @todo When checking for the tile slope,
   549  * distingush between "Flat land required" and "land sloped in wrong direction"
   590  * distingush between "Flat land required" and "land sloped in wrong direction"
   605 
   646 
   606 /** Build signals, alternate between double/single, signal/semaphore,
   647 /** Build signals, alternate between double/single, signal/semaphore,
   607  * pre/exit/combo-signals, and what-else not. If the rail piece does not
   648  * pre/exit/combo-signals, and what-else not. If the rail piece does not
   608  * have any signals, bit 4 (cycle signal-type) is ignored
   649  * have any signals, bit 4 (cycle signal-type) is ignored
   609  * @param tile tile where to build the signals
   650  * @param tile tile where to build the signals
       
   651  * @param flags operation to perform
   610  * @param p1 various bitstuffed elements
   652  * @param p1 various bitstuffed elements
   611  * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum)
   653  * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum)
   612  * - p1 = (bit 3)   - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   654  * - p1 = (bit 3)   - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   613  * - p1 = (bit 4)   - 0 = signals, 1 = semaphores
   655  * - p1 = (bit 4)   - 0 = signals, 1 = semaphores
   614  * @param p2 used for CmdBuildManySignals() to copy direction of first signal
   656  * @param p2 used for CmdBuildManySignals() to copy direction of first signal
   619 	Track track = (Track)GB(p1, 0, 3);
   661 	Track track = (Track)GB(p1, 0, 3);
   620 	bool pre_signal = HASBIT(p1, 3);
   662 	bool pre_signal = HASBIT(p1, 3);
   621 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   663 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
   622 	int32 cost;
   664 	int32 cost;
   623 
   665 
   624 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile))
   666 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile))
   625 		return CMD_ERROR;
   667 		return CMD_ERROR;
   626 
   668 
   627 	/* Protect against invalid signal copying */
   669 	/* Protect against invalid signal copying */
   628 	if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
   670 	if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
   629 
   671 
   645 	}
   687 	}
   646 
   688 
   647 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   689 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   648 
   690 
   649 	if (!HasSignalOnTrack(tile, track)) {
   691 	if (!HasSignalOnTrack(tile, track)) {
   650 		// build new signals
   692 		/* build new signals */
   651 		cost = _price.build_signals;
   693 		cost = _price.build_signals;
   652 	} else {
   694 	} else {
   653 		if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
   695 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
   654 			// convert signals <-> semaphores
   696 			/* convert signals <-> semaphores */
   655 			cost = _price.build_signals + _price.remove_signals;
   697 			cost = _price.build_signals + _price.remove_signals;
   656 		} else {
   698 		} else {
   657 			// it is free to change orientation/pre-exit-combo signals
   699 			/* it is free to change orientation/pre-exit-combo signals */
   658 			cost = 0;
   700 			cost = 0;
   659 		}
   701 		}
   660 	}
   702 	}
   661 
   703 
   662 	if (flags & DC_EXEC) {
   704 	if (flags & DC_EXEC) {
   663 		if (!HasSignals(tile)) {
   705 		if (!HasSignals(tile)) {
   664 			// there are no signals at all on this tile yet
   706 			/* there are no signals at all on this tile yet */
   665 			SetHasSignals(tile, true);
   707 			SetHasSignals(tile, true);
   666 			_m[tile].m2 |= 0xF0;              // all signals are on
   708 			SetSignalStates(tile, 0xF); // all signals are on
   667 			_m[tile].m3 &= ~0xF0;          // no signals built by default
   709 			SetPresentSignals(tile, 0); // no signals built by default
   668 			SetSignalType(tile, SIGTYPE_NORMAL);
   710 			SetSignalType(tile, track, SIGTYPE_NORMAL);
   669 			SetSignalVariant(tile, sigvar);
   711 			SetSignalVariant(tile, track, sigvar);
   670 		}
   712 		}
   671 
   713 
   672 		if (p2 == 0) {
   714 		if (p2 == 0) {
   673 			if (!HasSignalOnTrack(tile, track)) {
   715 			if (!HasSignalOnTrack(tile, track)) {
   674 				// build new signals
   716 				/* build new signals */
   675 				_m[tile].m3 |= SignalOnTrack(track);
   717 				SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track));
       
   718 				SetSignalType(tile, track, SIGTYPE_NORMAL);
       
   719 				SetSignalVariant(tile, track, sigvar);
   676 			} else {
   720 			} else {
   677 				if (pre_signal) {
   721 				if (pre_signal) {
   678 					// cycle between normal -> pre -> exit -> combo -> ...
   722 					/* cycle between normal -> pre -> exit -> combo -> ... */
   679 					SignalType type = GetSignalType(tile);
   723 					SignalType type = GetSignalType(tile, track);
   680 
   724 
   681 					SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   725 					SetSignalType(tile, track, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1));
   682 				} else {
   726 				} else {
   683 					CycleSignalSide(tile, track);
   727 					CycleSignalSide(tile, track);
   684 				}
   728 				}
   685 			}
   729 			}
   686 		} else {
   730 		} else {
   687 			/* If CmdBuildManySignals is called with copying signals, just copy the
   731 			/* If CmdBuildManySignals is called with copying signals, just copy the
   688 			 * direction of the first signal given as parameter by CmdBuildManySignals */
   732 			 * direction of the first signal given as parameter by CmdBuildManySignals */
   689 			_m[tile].m3 &= ~SignalOnTrack(track);
   733 			SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track)));
   690 			_m[tile].m3 |= p2 & SignalOnTrack(track);
   734 			SetSignalVariant(tile, track, sigvar);
   691 			SetSignalVariant(tile, sigvar);
       
   692 		}
   735 		}
   693 
   736 
   694 		MarkTileDirtyByTile(tile);
   737 		MarkTileDirtyByTile(tile);
   695 		SetSignalsOnBothDir(tile, track);
   738 		SetSignalsOnBothDir(tile, track);
   696 		YapfNotifyTrackLayoutChange(tile, track);
   739 		YapfNotifyTrackLayoutChange(tile, track);
   699 	return cost;
   742 	return cost;
   700 }
   743 }
   701 
   744 
   702 /** Build many signals by dragging; AutoSignals
   745 /** Build many signals by dragging; AutoSignals
   703  * @param tile start tile of drag
   746  * @param tile start tile of drag
       
   747  * @param flags operation to perform
   704  * @param p1  end tile of drag
   748  * @param p1  end tile of drag
   705  * @param p2 various bitstuffed elements
   749  * @param p2 various bitstuffed elements
   706  * - p2 = (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
   750  * - p2 = (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
   707  * - p2 = (bit  3)    - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   751  * - p2 = (bit  3)    - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   708  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   752  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
   737 
   781 
   738 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
   782 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
   739 
   783 
   740 	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
   784 	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
   741 
   785 
   742 	// copy the signal-style of the first rail-piece if existing
   786 	/* copy the signal-style of the first rail-piece if existing */
   743 	if (HasSignals(tile)) {
   787 	if (HasSignals(tile)) {
   744 		signals = _m[tile].m3 & SignalOnTrack(track);
   788 		signals = GetPresentSignals(tile) & SignalOnTrack(track);
   745 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   789 		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
   746 
   790 
   747 		// copy signal/semaphores style (independent of CTRL)
   791 		/* copy signal/semaphores style (independent of CTRL) */
   748 		semaphores = GetSignalVariant(tile) != SIG_ELECTRIC;
   792 		semaphores = GetSignalVariant(tile, track) != SIG_ELECTRIC;
   749 	} else { // no signals exist, drag a two-way signal stretch
   793 	} else { // no signals exist, drag a two-way signal stretch
   750 		signals = SignalOnTrack(track);
   794 		signals = SignalOnTrack(track);
   751 	}
   795 	}
   752 
   796 
   753 	/* signal_ctr         - amount of tiles already processed
   797 	/* signal_ctr         - amount of tiles already processed
   758 	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
   802 	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
   759 	 *              and convert all others to semaphore/signal
   803 	 *              and convert all others to semaphore/signal
   760 	 * remove     - 1 remove signals, 0 build signals */
   804 	 * remove     - 1 remove signals, 0 build signals */
   761 	signal_ctr = total_cost = 0;
   805 	signal_ctr = total_cost = 0;
   762 	for (;;) {
   806 	for (;;) {
   763 		// only build/remove signals with the specified density
   807 		/* only build/remove signals with the specified density */
   764 		if (signal_ctr % signal_density == 0) {
   808 		if (signal_ctr % signal_density == 0) {
   765 			uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3);
   809 			uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3);
   766 			SB(p1, 3, 1, mode);
   810 			SB(p1, 3, 1, mode);
   767 			SB(p1, 4, 1, semaphores);
   811 			SB(p1, 4, 1, semaphores);
   768 			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
   812 			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
   777 		if (tile == end_tile) break;
   821 		if (tile == end_tile) break;
   778 
   822 
   779 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   823 		tile += ToTileIndexDiff(_trackdelta[trackdir]);
   780 		signal_ctr++;
   824 		signal_ctr++;
   781 
   825 
   782 		// toggle railbit for the non-diagonal tracks (|, -- tracks)
   826 		/* toggle railbit for the non-diagonal tracks (|, -- tracks) */
   783 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   827 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
   784 	}
   828 	}
   785 
   829 
   786 	return error ? CMD_ERROR : total_cost;
   830 	return error ? CMD_ERROR : total_cost;
   787 }
   831 }
   788 
   832 
   789 /** Build signals on a stretch of track.
   833 /** Build signals on a stretch of track.
   790  * Stub for the unified signal builder/remover
   834  * Stub for the unified signal builder/remover
       
   835  * @param tile start tile of drag
       
   836  * @param flags operation to perform
       
   837  * @param p1  end tile of drag
       
   838  * @param p2 various bitstuffed elements
       
   839  * - p2 = (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
       
   840  * - p2 = (bit  3)    - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
       
   841  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
       
   842  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
       
   843  * - p2 = (bit 24-31) - user defined signals_density
   791  * @see CmdSignalTrackHelper
   844  * @see CmdSignalTrackHelper
   792  */
   845  */
   793 int32 CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   846 int32 CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   794 {
   847 {
   795 	return CmdSignalTrackHelper(tile, flags, p1, p2);
   848 	return CmdSignalTrackHelper(tile, flags, p1, p2);
   796 }
   849 }
   797 
   850 
   798 /** Remove signals
   851 /** Remove signals
   799  * @param tile coordinates where signal is being deleted from
   852  * @param tile coordinates where signal is being deleted from
   800  * @param various bitstuffed elements, only track information is used
   853  * @param flags operation to perform
   801  * - p1 = (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
   854  * @param p1 various bitstuffed elements, only track information is used
   802  * - p1 = (bit  3)    - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
   855  *           - (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
   803  * - p1 = (bit  4)    - 0 = signals, 1 = semaphores
   856  *           - (bit  3)    - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
       
   857  *           - (bit  4)    - 0 = signals, 1 = semaphores
       
   858  * @param p2 unused
   804  */
   859  */
   805 int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   860 int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   806 {
   861 {
   807 	Track track = (Track)GB(p1, 0, 3);
   862 	Track track = (Track)GB(p1, 0, 3);
   808 
   863 
   809 	if (!ValParamTrackOrientation(track) ||
   864 	if (!ValParamTrackOrientation(track) ||
   810 			!IsTileType(tile, MP_RAILWAY) ||
   865 			!IsTileType(tile, MP_RAILWAY) ||
   811 			!EnsureNoVehicle(tile) ||
   866 			!EnsureNoVehicleOnGround(tile) ||
   812 			!HasSignalOnTrack(tile, track)) {
   867 			!HasSignalOnTrack(tile, track)) {
   813 		return CMD_ERROR;
   868 		return CMD_ERROR;
   814 	}
   869 	}
   815 
   870 
   816 	/* Only water can remove signals from anyone */
   871 	/* Only water can remove signals from anyone */
   818 
   873 
   819 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   874 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   820 
   875 
   821 	/* Do it? */
   876 	/* Do it? */
   822 	if (flags & DC_EXEC) {
   877 	if (flags & DC_EXEC) {
   823 		_m[tile].m3 &= ~SignalOnTrack(track);
   878 		SetPresentSignals(tile, GetPresentSignals(tile) & ~SignalOnTrack(track));
   824 
   879 
   825 		/* removed last signal from tile? */
   880 		/* removed last signal from tile? */
   826 		if (GB(_m[tile].m3, 4, 4) == 0) {
   881 		if (GetPresentSignals(tile) == 0) {
   827 			SB(_m[tile].m2, 4, 4, 0);
   882 			SetSignalStates(tile, 0);
   828 			SetHasSignals(tile, false);
   883 			SetHasSignals(tile, false);
   829 			SetSignalVariant(tile, SIG_ELECTRIC); // remove any possible semaphores
   884 			SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
   830 		}
   885 		}
   831 
   886 
   832 		SetSignalsOnBothDir(tile, track);
   887 		SetSignalsOnBothDir(tile, track);
   833 		YapfNotifyTrackLayoutChange(tile, track);
   888 		YapfNotifyTrackLayoutChange(tile, track);
   834 
   889 
   838 	return _price.remove_signals;
   893 	return _price.remove_signals;
   839 }
   894 }
   840 
   895 
   841 /** Remove signals on a stretch of track.
   896 /** Remove signals on a stretch of track.
   842  * Stub for the unified signal builder/remover
   897  * Stub for the unified signal builder/remover
       
   898  * @param tile start tile of drag
       
   899  * @param flags operation to perform
       
   900  * @param p1  end tile of drag
       
   901  * @param p2 various bitstuffed elements
       
   902  * - p2 = (bit  0- 2) - track-orientation, valid values: 0-5 (Track enum)
       
   903  * - p2 = (bit  3)    - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
       
   904  * - p2 = (bit  4)    - 0 = signals, 1 = semaphores
       
   905  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
       
   906  * - p2 = (bit 24-31) - user defined signals_density
   843  * @see CmdSignalTrackHelper
   907  * @see CmdSignalTrackHelper
   844  */
   908  */
   845 int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   909 int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   846 {
   910 {
   847 	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit
   911 	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit
   863 {
   927 {
   864 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   928 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
   865 
   929 
   866 	if (GetRailType(tile) == totype) return CMD_ERROR;
   930 	if (GetRailType(tile) == totype) return CMD_ERROR;
   867 
   931 
   868 	if (!EnsureNoVehicle(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR;
   932 	if (!EnsureNoVehicleOnGround(tile) && (!IsCompatibleRail(GetRailType(tile), totype) || IsPlainRailTile(tile))) return CMD_ERROR;
   869 
   933 
   870 	// 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
   934 	/* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */
   871 	if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   935 	if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   872 
   936 
   873 	// change type.
   937 	/* change type. */
   874 	if (exec) {
   938 	if (exec) {
   875 		SetRailType(tile, totype);
   939 		SetRailType(tile, totype);
   876 		MarkTileDirtyByTile(tile);
   940 		MarkTileDirtyByTile(tile);
   877 
   941 
   878 		// notify YAPF about the track layout change
   942 		/* notify YAPF about the track layout change */
   879 		TrackBits tracks = GetTrackBits(tile);
   943 		TrackBits tracks = GetTrackBits(tile);
   880 		while (tracks != TRACK_BIT_NONE) {
   944 		while (tracks != TRACK_BIT_NONE) {
   881 			YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
   945 			YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
   882 		}
   946 		}
   883 
   947 
   904 extern int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
   968 extern int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
   905 
   969 
   906 /** Convert one rail type to the other. You can convert normal rail to
   970 /** Convert one rail type to the other. You can convert normal rail to
   907  * monorail/maglev easily or vice-versa.
   971  * monorail/maglev easily or vice-versa.
   908  * @param tile end tile of rail conversion drag
   972  * @param tile end tile of rail conversion drag
       
   973  * @param flags operation to perform
   909  * @param p1 start tile of drag
   974  * @param p1 start tile of drag
   910  * @param p2 new railtype to convert to
   975  * @param p2 new railtype to convert to
   911  */
   976  */
   912 int32 CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   977 int32 CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
   913 {
   978 {
   919 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   984 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   920 
   985 
   921 	if (!ValParamRailtype(p2)) return CMD_ERROR;
   986 	if (!ValParamRailtype(p2)) return CMD_ERROR;
   922 	if (p1 >= MapSize()) return CMD_ERROR;
   987 	if (p1 >= MapSize()) return CMD_ERROR;
   923 
   988 
   924 	// make sure sx,sy are smaller than ex,ey
   989 	/* make sure sx,sy are smaller than ex,ey */
   925 	ex = TileX(tile);
   990 	ex = TileX(tile);
   926 	ey = TileY(tile);
   991 	ey = TileY(tile);
   927 	sx = TileX(p1);
   992 	sx = TileX(p1);
   928 	sy = TileY(p1);
   993 	sy = TileY(p1);
   929 	if (ex < sx) Swap(ex, sx);
   994 	if (ex < sx) Swap(ex, sx);
   967 static int32 RemoveTrainDepot(TileIndex tile, uint32 flags)
  1032 static int32 RemoveTrainDepot(TileIndex tile, uint32 flags)
   968 {
  1033 {
   969 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
  1034 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
   970 		return CMD_ERROR;
  1035 		return CMD_ERROR;
   971 
  1036 
   972 	if (!EnsureNoVehicle(tile))
  1037 	if (!EnsureNoVehicleOnGround(tile))
   973 		return CMD_ERROR;
  1038 		return CMD_ERROR;
   974 
  1039 
   975 	if (flags & DC_EXEC) {
  1040 	if (flags & DC_EXEC) {
   976 		DiagDirection dir = GetRailDepotDirection(tile);
  1041 		DiagDirection dir = GetRailDepotDirection(tile);
   977 
  1042 
  1025 	}
  1090 	}
  1026 }
  1091 }
  1027 
  1092 
  1028 #include "table/track_land.h"
  1093 #include "table/track_land.h"
  1029 
  1094 
  1030 static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos)
  1095 static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint image, uint pos)
  1031 {
  1096 {
  1032 	bool side = (_opt.road_side != 0) && _patches.signal_side;
  1097 	bool side = (_opt.road_side != 0) && _patches.signal_side;
  1033 	static const Point SignalPositions[2][12] = {
  1098 	static const Point SignalPositions[2][12] = {
  1034 		{      /* Signals on the left side */
  1099 		{      /* Signals on the left side */
  1035 		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
  1100 		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
  1062 	SpriteID sprite;
  1127 	SpriteID sprite;
  1063 
  1128 
  1064 	/* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we
  1129 	/* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we
  1065 	 * just draw the standard signals, else we get the offset from _signal_base
  1130 	 * just draw the standard signals, else we get the offset from _signal_base
  1066 	 * and draw that sprite. All the signal sprites are loaded sequentially. */
  1131 	 * and draw that sprite. All the signal sprites are loaded sequentially. */
  1067 	if (_signal_base == 0 || (GetSignalType(tile) == 0 && GetSignalVariant(tile) == SIG_ELECTRIC)) {
  1132 	if (_signal_base == 0 || (GetSignalType(tile, track) == SIGTYPE_NORMAL && GetSignalVariant(tile, track) == SIG_ELECTRIC)) {
  1068 		sprite = SignalBase[side][GetSignalVariant(tile)][GetSignalType(tile)] + image + condition;
  1133 		sprite = SignalBase[side][GetSignalVariant(tile, track)][GetSignalType(tile, track)] + image + condition;
  1069 	} else {
  1134 	} else {
  1070 		sprite = _signal_base + (GetSignalType(tile) - 1) * 16 + GetSignalVariant(tile) * 64 + image + condition;
  1135 		sprite = _signal_base + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition;
  1071 	}
  1136 	}
  1072 
  1137 
  1073 	AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y));
  1138 	AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y));
  1074 }
  1139 }
  1075 
  1140 
  1173 
  1238 
  1174 /**
  1239 /**
  1175  * Draw ground sprite and track bits
  1240  * Draw ground sprite and track bits
  1176  * @param ti TileInfo
  1241  * @param ti TileInfo
  1177  * @param track TrackBits to draw
  1242  * @param track TrackBits to draw
  1178  * @param earth Draw as earth
       
  1179  * @param snow Draw as snow
       
  1180  * @param flat Always draw foundation
       
  1181  */
  1243  */
  1182 static void DrawTrackBits(TileInfo* ti, TrackBits track)
  1244 static void DrawTrackBits(TileInfo* ti, TrackBits track)
  1183 {
  1245 {
  1184 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
  1246 	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
  1185 	SpriteID image;
  1247 	SpriteID image;
  1186 	SpriteID pal = PAL_NONE;
  1248 	SpriteID pal = PAL_NONE;
  1187 	bool junction = false;
  1249 	bool junction = false;
  1188 
  1250 
  1189 	// Select the sprite to use.
  1251 	/* Select the sprite to use. */
  1190 	(image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
  1252 	(image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
  1191 	(image++,                           track == TRACK_BIT_X) ||
  1253 	(image++,                           track == TRACK_BIT_X) ||
  1192 	(image++,                           track == TRACK_BIT_UPPER) ||
  1254 	(image++,                           track == TRACK_BIT_UPPER) ||
  1193 	(image++,                           track == TRACK_BIT_LOWER) ||
  1255 	(image++,                           track == TRACK_BIT_LOWER) ||
  1194 	(image++,                           track == TRACK_BIT_RIGHT) ||
  1256 	(image++,                           track == TRACK_BIT_RIGHT) ||
  1208 	if (ti->tileh != SLOPE_FLAT) {
  1270 	if (ti->tileh != SLOPE_FLAT) {
  1209 		uint foundation = GetRailFoundation(ti->tileh, track);
  1271 		uint foundation = GetRailFoundation(ti->tileh, track);
  1210 
  1272 
  1211 		if (foundation != 0) DrawFoundation(ti, foundation);
  1273 		if (foundation != 0) DrawFoundation(ti, foundation);
  1212 
  1274 
  1213 		// DrawFoundation() modifies ti.
  1275 		/* DrawFoundation() modifies it.
  1214 		// Default sloped sprites..
  1276 		 * Default sloped sprites.. */
  1215 		if (ti->tileh != SLOPE_FLAT)
  1277 		if (ti->tileh != SLOPE_FLAT)
  1216 			image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
  1278 			image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
  1217 	}
  1279 	}
  1218 
  1280 
  1219 	switch (GetRailGroundType(ti->tile)) {
  1281 	switch (GetRailGroundType(ti->tile)) {
  1222 		default: break;
  1284 		default: break;
  1223 	}
  1285 	}
  1224 
  1286 
  1225 	DrawGroundSprite(image, pal);
  1287 	DrawGroundSprite(image, pal);
  1226 
  1288 
  1227 	// Draw track pieces individually for junction tiles
  1289 	/* Draw track pieces individually for junction tiles */
  1228 	if (junction) {
  1290 	if (junction) {
  1229 		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
  1291 		if (track & TRACK_BIT_X)     DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
  1230 		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
  1292 		if (track & TRACK_BIT_Y)     DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
  1231 		if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE);
  1293 		if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE);
  1232 		if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE);
  1294 		if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE);
  1238 
  1300 
  1239 }
  1301 }
  1240 
  1302 
  1241 static void DrawSignals(TileIndex tile, TrackBits rails)
  1303 static void DrawSignals(TileIndex tile, TrackBits rails)
  1242 {
  1304 {
  1243 #define MAYBE_DRAW_SIGNAL(x,y,z) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, GetSingleSignalState(tile, x), y - 0x4FB, z)
  1305 #define MAYBE_DRAW_SIGNAL(x,y,z,t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, t, GetSingleSignalState(tile, x), y - 0x4FB, z)
  1244 
  1306 
  1245 	if (!(rails & TRACK_BIT_Y)) {
  1307 	if (!(rails & TRACK_BIT_Y)) {
  1246 		if (!(rails & TRACK_BIT_X)) {
  1308 		if (!(rails & TRACK_BIT_X)) {
  1247 			if (rails & TRACK_BIT_LEFT) {
  1309 			if (rails & TRACK_BIT_LEFT) {
  1248 				MAYBE_DRAW_SIGNAL(2, 0x509, 0);
  1310 				MAYBE_DRAW_SIGNAL(2, 0x509, 0, TRACK_LEFT);
  1249 				MAYBE_DRAW_SIGNAL(3, 0x507, 1);
  1311 				MAYBE_DRAW_SIGNAL(3, 0x507, 1, TRACK_LEFT);
  1250 			}
  1312 			}
  1251 			if (rails & TRACK_BIT_RIGHT) {
  1313 			if (rails & TRACK_BIT_RIGHT) {
  1252 				MAYBE_DRAW_SIGNAL(0, 0x509, 2);
  1314 				MAYBE_DRAW_SIGNAL(0, 0x509, 2, TRACK_RIGHT);
  1253 				MAYBE_DRAW_SIGNAL(1, 0x507, 3);
  1315 				MAYBE_DRAW_SIGNAL(1, 0x507, 3, TRACK_RIGHT);
  1254 			}
  1316 			}
  1255 			if (rails & TRACK_BIT_UPPER) {
  1317 			if (rails & TRACK_BIT_UPPER) {
  1256 				MAYBE_DRAW_SIGNAL(3, 0x505, 4);
  1318 				MAYBE_DRAW_SIGNAL(3, 0x505, 4, TRACK_UPPER);
  1257 				MAYBE_DRAW_SIGNAL(2, 0x503, 5);
  1319 				MAYBE_DRAW_SIGNAL(2, 0x503, 5, TRACK_UPPER);
  1258 			}
  1320 			}
  1259 			if (rails & TRACK_BIT_LOWER) {
  1321 			if (rails & TRACK_BIT_LOWER) {
  1260 				MAYBE_DRAW_SIGNAL(1, 0x505, 6);
  1322 				MAYBE_DRAW_SIGNAL(1, 0x505, 6, TRACK_LOWER);
  1261 				MAYBE_DRAW_SIGNAL(0, 0x503, 7);
  1323 				MAYBE_DRAW_SIGNAL(0, 0x503, 7, TRACK_LOWER);
  1262 			}
  1324 			}
  1263 		} else {
  1325 		} else {
  1264 			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8);
  1326 			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8, TRACK_X);
  1265 			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9);
  1327 			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9, TRACK_X);
  1266 		}
  1328 		}
  1267 	} else {
  1329 	} else {
  1268 		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10);
  1330 		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10, TRACK_Y);
  1269 		MAYBE_DRAW_SIGNAL(2, 0x501, 11);
  1331 		MAYBE_DRAW_SIGNAL(2, 0x501, 11, TRACK_Y);
  1270 	}
  1332 	}
  1271 }
  1333 }
  1272 
  1334 
  1273 static void DrawTile_Track(TileInfo *ti)
  1335 static void DrawTile_Track(TileInfo *ti)
  1274 {
  1336 {
  1280 	if (IsPlainRailTile(ti->tile)) {
  1342 	if (IsPlainRailTile(ti->tile)) {
  1281 		TrackBits rails = GetTrackBits(ti->tile);
  1343 		TrackBits rails = GetTrackBits(ti->tile);
  1282 
  1344 
  1283 		DrawTrackBits(ti, rails);
  1345 		DrawTrackBits(ti, rails);
  1284 
  1346 
  1285 		if (_display_opt & DO_FULL_DETAIL) DrawTrackDetails(ti);
  1347 		if (HASBIT(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti);
  1286 
  1348 
  1287 		if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
  1349 		if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
  1288 	} else {
  1350 	} else {
  1289 		// draw depot/waypoint
  1351 		/* draw depot/waypoint */
  1290 		const DrawTileSprites* dts;
  1352 		const DrawTileSprites* dts;
  1291 		const DrawTileSeqStruct* dtss;
  1353 		const DrawTileSeqStruct* dtss;
  1292 		uint32 relocation;
  1354 		uint32 relocation;
  1293 
  1355 
  1294 		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
  1356 		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
  1299 			relocation = rti->total_offset;
  1361 			relocation = rti->total_offset;
  1300 
  1362 
  1301 			image = dts->ground_sprite;
  1363 			image = dts->ground_sprite;
  1302 			if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
  1364 			if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
  1303 
  1365 
  1304 			// adjust ground tile for desert
  1366 			/* adjust ground tile for desert
  1305 			// don't adjust for snow, because snow in depots looks weird
  1367 			 * don't adjust for snow, because snow in depots looks weird */
  1306 			if (IsSnowRailGround(ti->tile) && _opt.landscape == LT_TROPIC) {
  1368 			if (IsSnowRailGround(ti->tile) && _opt.landscape == LT_TROPIC) {
  1307 				if (image != SPR_FLAT_GRASS_TILE) {
  1369 				if (image != SPR_FLAT_GRASS_TILE) {
  1308 					image += rti->snow_offset; // tile with tracks
  1370 					image += rti->snow_offset; // tile with tracks
  1309 				} else {
  1371 				} else {
  1310 					image = SPR_FLAT_SNOWY_TILE; // flat ground
  1372 					image = SPR_FLAT_SNOWY_TILE; // flat ground
  1311 				}
  1373 				}
  1312 			}
  1374 			}
  1313 		} else {
  1375 		} else {
  1314 			// look for customization
  1376 			/* look for customization */
  1315 			byte stat_id = GetWaypointByTile(ti->tile)->stat_id;
  1377 			byte stat_id = GetWaypointByTile(ti->tile)->stat_id;
  1316 			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id);
  1378 			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id);
  1317 
  1379 
  1318 			if (statspec != NULL) {
  1380 			if (statspec != NULL) {
  1319 				// emulate station tile - open with building
  1381 				/* emulate station tile - open with building */
  1320 				const Station* st = ComposeWaypointStation(ti->tile);
  1382 				const Station* st = ComposeWaypointStation(ti->tile);
  1321 				uint gfx = 2;
  1383 				uint gfx = 2;
  1322 
  1384 
  1323 				if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
  1385 				if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
  1324 					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
  1386 					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
  1344 				} else {
  1406 				} else {
  1345 					goto default_waypoint;
  1407 					goto default_waypoint;
  1346 				}
  1408 				}
  1347 			} else {
  1409 			} else {
  1348 default_waypoint:
  1410 default_waypoint:
  1349 				// There is no custom layout, fall back to the default graphics
  1411 				/* There is no custom layout, fall back to the default graphics */
  1350 				dts = &_waypoint_gfx_table[GetWaypointAxis(ti->tile)];
  1412 				dts = &_waypoint_gfx_table[GetWaypointAxis(ti->tile)];
  1351 				relocation = 0;
  1413 				relocation = 0;
  1352 				image = dts->ground_sprite + rti->total_offset;
  1414 				image = dts->ground_sprite + rti->total_offset;
  1353 				if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
  1415 				if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
  1354 			}
  1416 			}
  1369 				image += rti->total_offset;
  1431 				image += rti->total_offset;
  1370 			} else {
  1432 			} else {
  1371 				image += relocation;
  1433 				image += relocation;
  1372 			}
  1434 			}
  1373 
  1435 
  1374 			if (_display_opt & DO_TRANS_BUILDINGS) {
  1436 			if (HASBIT(_transparent_opt, TO_BUILDINGS)) {
  1375 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1437 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1376 				pal = PALETTE_TO_TRANSPARENT;
  1438 				pal = PALETTE_TO_TRANSPARENT;
  1377 			} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
  1439 			} else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) {
  1378 				pal = _drawtile_track_palette;
  1440 				pal = _drawtile_track_palette;
  1379 			} else {
  1441 			} else {
  1431 	int cur;
  1493 	int cur;
  1432 	int cur_stack;
  1494 	int cur_stack;
  1433 	bool stop;
  1495 	bool stop;
  1434 	bool has_presignal;
  1496 	bool has_presignal;
  1435 
  1497 
  1436 	// presignal info
  1498 	/* presignal info */
  1437 	int presignal_exits;
  1499 	int presignal_exits;
  1438 	int presignal_exits_free;
  1500 	int presignal_exits_free;
  1439 
  1501 
  1440 	// these are used to keep track of the signals that change.
  1502 	/* these are used to keep track of the signals that change. */
  1441 	TrackdirByte bit[NUM_SSD_ENTRY];
  1503 	TrackdirByte bit[NUM_SSD_ENTRY];
  1442 	TileIndex tile[NUM_SSD_ENTRY];
  1504 	TileIndex tile[NUM_SSD_ENTRY];
  1443 
  1505 
  1444 	// these are used to keep track of the stack that modifies presignals recursively
  1506 	/* these are used to keep track of the stack that modifies presignals recursively */
  1445 	TileIndex next_tile[NUM_SSD_STACK];
  1507 	TileIndex next_tile[NUM_SSD_STACK];
  1446 	DiagDirectionByte next_dir[NUM_SSD_STACK];
  1508 	DiagDirectionByte next_dir[NUM_SSD_STACK];
  1447 
  1509 
  1448 };
  1510 };
  1449 
  1511 
  1450 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1512 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state)
  1451 {
  1513 {
  1452 	SetSignalsData* ssd = (SetSignalsData*)data;
  1514 	SetSignalsData* ssd = (SetSignalsData*)data;
       
  1515 	Track track = TrackdirToTrack(trackdir);
  1453 
  1516 
  1454 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1517 	if (!IsTileType(tile, MP_RAILWAY)) return false;
  1455 
  1518 
  1456 	// the tile has signals?
  1519 	/* the tile has signals? */
  1457 	if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) {
  1520 	if (HasSignalOnTrack(tile, track)) {
  1458 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1521 		if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
  1459 			// yes, add the signal to the list of signals
  1522 			/* yes, add the signal to the list of signals */
  1460 			if (ssd->cur != NUM_SSD_ENTRY) {
  1523 			if (ssd->cur != NUM_SSD_ENTRY) {
  1461 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1524 				ssd->tile[ssd->cur] = tile; // remember the tile index
  1462 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1525 				ssd->bit[ssd->cur] = trackdir; // and the controlling bit number
  1463 				ssd->cur++;
  1526 				ssd->cur++;
  1464 			}
  1527 			}
  1465 
  1528 
  1466 			// remember if this block has a presignal.
  1529 			/* remember if this block has a presignal. */
  1467 			ssd->has_presignal |= IsPresignalEntry(tile);
  1530 			ssd->has_presignal |= IsPresignalEntry(tile, track);
  1468 		}
  1531 		}
  1469 
  1532 
  1470 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) {
  1533 		if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile, track)) {
  1471 			// this is an exit signal that points out from the segment
  1534 			/* this is an exit signal that points out from the segment */
  1472 			ssd->presignal_exits++;
  1535 			ssd->presignal_exits++;
  1473 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1536 			if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED)
  1474 				ssd->presignal_exits_free++;
  1537 				ssd->presignal_exits_free++;
  1475 		}
  1538 		}
  1476 
  1539 
  1524 			direction = GetBridgeRampDirection(tile);
  1587 			direction = GetBridgeRampDirection(tile);
  1525 		}
  1588 		}
  1526 
  1589 
  1527 		dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
  1590 		dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
  1528 
  1591 
  1529 		// check for a vehicle with that trackdir on the start tile of the tunnel
  1592 		/* check for a vehicle with that trackdir on the start tile of the tunnel */
  1530 		if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true;
  1593 		if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true;
  1531 
  1594 
  1532 		// check for a vehicle with that trackdir on the end tile of the tunnel
  1595 		/* check for a vehicle with that trackdir on the end tile of the tunnel */
  1533 		if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
  1596 		if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
  1534 
  1597 
  1535 		// now check all tiles from start to end for a warping vehicle
  1598 		/* now check all tiles from start to end for a warping vehicle
  1536 		// NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile?
  1599 		 * NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile? */
  1537 		dest.track = 0x40;   //Vehicle inside a tunnel or on a bridge
  1600 		dest.track = 0x40;   //Vehicle inside a tunnel or on a bridge
  1538 		for (; tile != end; tile += TileOffsByDiagDir(direction)) {
  1601 		for (; tile != end; tile += TileOffsByDiagDir(direction)) {
  1539 			if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL)
  1602 			if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL)
  1540 				return true;
  1603 				return true;
  1541 		}
  1604 		}
  1542 
  1605 
  1543 		// no vehicle found
  1606 		/* no vehicle found */
  1544 		return false;
  1607 		return false;
  1545 	}
  1608 	}
  1546 
  1609 
  1547 	return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
  1610 	return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
  1548 }
  1611 }
  1593 
  1656 
  1594 static void ChangeSignalStates(SetSignalsData *ssd)
  1657 static void ChangeSignalStates(SetSignalsData *ssd)
  1595 {
  1658 {
  1596 	int i;
  1659 	int i;
  1597 
  1660 
  1598 	// thinking about presignals...
  1661 	/* thinking about presignals...
  1599 	// the presignal is green if,
  1662 	 * the presignal is green if,
  1600 	//   if no train is in the segment AND
  1663 	 *   if no train is in the segment AND
  1601 	//   there is at least one green exit signal OR
  1664 	 *   there is at least one green exit signal OR
  1602 	//   there are no exit signals in the segment
  1665 	 *   there are no exit signals in the segment */
  1603 
  1666 
  1604 	// then mark the signals in the segment accordingly
  1667 	/* then mark the signals in the segment accordingly */
  1605 	for (i = 0; i != ssd->cur; i++) {
  1668 	for (i = 0; i != ssd->cur; i++) {
  1606 		TileIndex tile = ssd->tile[i];
  1669 		TileIndex tile = ssd->tile[i];
  1607 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1670 		byte bit = SignalAgainstTrackdir(ssd->bit[i]);
  1608 		uint16 m2 = _m[tile].m2;
  1671 		uint signals = GetSignalStates(tile);
  1609 
  1672 		Track track = TrackdirToTrack(ssd->bit[i]);
  1610 		// presignals don't turn green if there is at least one presignal exit and none are free
  1673 
  1611 		if (IsPresignalEntry(tile)) {
  1674 		/* presignals don't turn green if there is at least one presignal exit and none are free */
       
  1675 		if (IsPresignalEntry(tile, track)) {
  1612 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1676 			int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free;
  1613 
  1677 
  1614 			// subtract for dual combo signals so they don't count themselves
  1678 			/* subtract for dual combo signals so they don't count themselves */
  1615 			if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1679 			if (IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, ssd->bit[i])) {
  1616 				ex--;
  1680 				ex--;
  1617 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1681 				if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--;
  1618 			}
  1682 			}
  1619 
  1683 
  1620 			// if we have exits and none are free, make red.
  1684 			/* if we have exits and none are free, make red. */
  1621 			if (ex && !exfree) goto make_red;
  1685 			if (ex && !exfree) goto make_red;
  1622 		}
  1686 		}
  1623 
  1687 
  1624 		// check if the signal is unaffected.
  1688 		/* check if the signal is unaffected. */
  1625 		if (ssd->stop) {
  1689 		if (ssd->stop) {
  1626 make_red:
  1690 make_red:
  1627 			// turn red
  1691 			/* turn red */
  1628 			if ((bit & m2) == 0) continue;
  1692 			if ((bit & signals) == 0) continue;
  1629 		} else {
  1693 		} else {
  1630 			// turn green
  1694 			/* turn green */
  1631 			if ((bit & m2) != 0) continue;
  1695 			if ((bit & signals) != 0) continue;
  1632 		}
  1696 		}
  1633 
  1697 
  1634 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1698 		/* Update signals on the other side of this exit-combo signal; it changed. */
  1635 		if (IsPresignalExit(tile)) {
  1699 		if (IsPresignalExit(tile, track)) {
  1636 			if (ssd->cur_stack != NUM_SSD_STACK) {
  1700 			if (ssd->cur_stack != NUM_SSD_STACK) {
  1637 				ssd->next_tile[ssd->cur_stack] = tile;
  1701 				ssd->next_tile[ssd->cur_stack] = tile;
  1638 				ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]];
  1702 				ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]];
  1639 				ssd->cur_stack++;
  1703 				ssd->cur_stack++;
  1640 			} else {
  1704 			} else {
  1641 				DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
  1705 				DEBUG(misc, 0, "NUM_SSD_STACK too small"); /// @todo WTF is this???
  1642 			}
  1706 			}
  1643 		}
  1707 		}
  1644 
  1708 
  1645 		// it changed, so toggle it
  1709 		/* it changed, so toggle it */
  1646 		_m[tile].m2 = m2 ^ bit;
  1710 		SetSignalStates(tile, signals ^ bit);
  1647 		MarkTileDirtyByTile(tile);
  1711 		MarkTileDirtyByTile(tile);
  1648 	}
  1712 	}
  1649 }
  1713 }
  1650 
  1714 
  1651 
  1715 
  1655 	int result = -1;
  1719 	int result = -1;
  1656 
  1720 
  1657 	ssd.cur_stack = 0;
  1721 	ssd.cur_stack = 0;
  1658 
  1722 
  1659 	for (;;) {
  1723 	for (;;) {
  1660 		// go through one segment and update all signals pointing into that segment.
  1724 		/* go through one segment and update all signals pointing into that segment. */
  1661 		ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
  1725 		ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0;
  1662 		ssd.has_presignal = false;
  1726 		ssd.has_presignal = false;
  1663 
  1727 
  1664 		FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
  1728 		FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, 0, direction, SetSignalsEnumProc, SetSignalsAfterProc, &ssd);
  1665 		ChangeSignalStates(&ssd);
  1729 		ChangeSignalStates(&ssd);
  1666 
  1730 
  1667 		// remember the result only for the first iteration.
  1731 		/* remember the result only for the first iteration. */
  1668 		if (result < 0) {
  1732 		if (result < 0) {
  1669 			// stay in depot while segment is occupied or while all presignal exits are blocked
  1733 			/* stay in depot while segment is occupied or while all presignal exits are blocked */
  1670 			result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0);
  1734 			result = ssd.stop || (ssd.presignal_exits > 0 && ssd.presignal_exits_free == 0);
  1671 		}
  1735 		}
  1672 
  1736 
  1673 		// if any exit signals were changed, we need to keep going to modify the stuff behind those.
  1737 		/* if any exit signals were changed, we need to keep going to modify the stuff behind those. */
  1674 		if (ssd.cur_stack == 0) break;
  1738 		if (ssd.cur_stack == 0) break;
  1675 
  1739 
  1676 		// one or more exit signals were changed, so we need to update another segment too.
  1740 		/* one or more exit signals were changed, so we need to update another segment too. */
  1677 		tile = ssd.next_tile[--ssd.cur_stack];
  1741 		tile = ssd.next_tile[--ssd.cur_stack];
  1678 		direction = ssd.next_dir[ssd.cur_stack];
  1742 		direction = ssd.next_dir[ssd.cur_stack];
  1679 	}
  1743 	}
  1680 
  1744 
  1681 	return result != 0;
  1745 	return result != 0;
  1764 
  1828 
  1765 	if (!IsPlainRailTile(tile)) return;
  1829 	if (!IsPlainRailTile(tile)) return;
  1766 
  1830 
  1767 	new_ground = RAIL_GROUND_GRASS;
  1831 	new_ground = RAIL_GROUND_GRASS;
  1768 
  1832 
  1769 	if (old_ground != RAIL_GROUND_BARREN) { /* wait until bottom is green */
  1833 	if (old_ground != RAIL_GROUND_BARREN) { // wait until bottom is green
  1770 		/* determine direction of fence */
  1834 		/* determine direction of fence */
  1771 		TrackBits rail = GetTrackBits(tile);
  1835 		TrackBits rail = GetTrackBits(tile);
  1772 
  1836 
  1773 		switch (rail) {
  1837 		switch (rail) {
  1774 			case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
  1838 			case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
  1851 		MarkTileDirtyByTile(tile);
  1915 		MarkTileDirtyByTile(tile);
  1852 	}
  1916 	}
  1853 }
  1917 }
  1854 
  1918 
  1855 
  1919 
  1856 static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode)
  1920 static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode)
  1857 {
  1921 {
  1858 	if (mode != TRANSPORT_RAIL) return 0;
  1922 	if (mode != TRANSPORT_RAIL) return 0;
  1859 
  1923 
  1860 	switch (GetRailTileType(tile)) {
  1924 	switch (GetRailTileType(tile)) {
  1861 		default: NOT_REACHED();
  1925 		default: NOT_REACHED();
  1865 			return (rails == TRACK_BIT_CROSS) ? ret | 0x40 : ret;
  1929 			return (rails == TRACK_BIT_CROSS) ? ret | 0x40 : ret;
  1866 		}
  1930 		}
  1867 
  1931 
  1868 		case RAIL_TILE_SIGNALS: {
  1932 		case RAIL_TILE_SIGNALS: {
  1869 			uint32 ret = GetTrackBits(tile) * 0x101;
  1933 			uint32 ret = GetTrackBits(tile) * 0x101;
  1870 			byte a;
  1934 			byte a = GetPresentSignals(tile);
  1871 			uint16 b;
  1935 			uint b = GetSignalStates(tile);
  1872 
       
  1873 			a = _m[tile].m3;
       
  1874 			b = _m[tile].m2;
       
  1875 
  1936 
  1876 			b &= a;
  1937 			b &= a;
  1877 
  1938 
  1878 			/* When signals are not present (in neither
  1939 			/* When signals are not present (in neither
  1879 			 * direction), we pretend them to be green. (So if
  1940 			 * direction), we pretend them to be green. (So if
  1880 			 * signals are only one way, the other way will
  1941 			 * signals are only one way, the other way will
  1881 			 * implicitely become `red' */
  1942 			 * implicitely become `red' */
  1882 			if ((a & 0xC0) == 0) b |= 0xC0;
  1943 			if ((a & 0xC) == 0) b |= 0xC;
  1883 			if ((a & 0x30) == 0) b |= 0x30;
  1944 			if ((a & 0x3) == 0) b |= 0x3;
  1884 
  1945 
  1885 			if ((b & 0x80) == 0) ret |= 0x10070000;
  1946 			if ((b & 0x8) == 0) ret |= 0x10070000;
  1886 			if ((b & 0x40) == 0) ret |= 0x07100000;
  1947 			if ((b & 0x4) == 0) ret |= 0x07100000;
  1887 			if ((b & 0x20) == 0) ret |= 0x20080000;
  1948 			if ((b & 0x2) == 0) ret |= 0x20080000;
  1888 			if ((b & 0x10) == 0) ret |= 0x08200000;
  1949 			if ((b & 0x1) == 0) ret |= 0x08200000;
  1889 
  1950 
  1890 			return ret;
  1951 			return ret;
  1891 		}
  1952 		}
  1892 
  1953 
  1893 		case RAIL_TILE_DEPOT:    return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101;
  1954 		case RAIL_TILE_DEPOT:    return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101;
  1911 		case RAIL_TILE_NORMAL:
  1972 		case RAIL_TILE_NORMAL:
  1912 			td->str = STR_1021_RAILROAD_TRACK;
  1973 			td->str = STR_1021_RAILROAD_TRACK;
  1913 			break;
  1974 			break;
  1914 
  1975 
  1915 		case RAIL_TILE_SIGNALS: {
  1976 		case RAIL_TILE_SIGNALS: {
  1916 			const StringID signal_type[] = {
  1977 			const StringID signal_type[4][4] = {
  1917 				STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
  1978 				{
  1918 				STR_RAILROAD_TRACK_WITH_PRESIGNALS,
  1979 					STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
  1919 				STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
  1980 					STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS,
  1920 				STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
  1981 					STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS,
       
  1982 					STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS
       
  1983 				},
       
  1984 				{
       
  1985 					STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS,
       
  1986 					STR_RAILROAD_TRACK_WITH_PRESIGNALS,
       
  1987 					STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS,
       
  1988 					STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS
       
  1989 				},
       
  1990 				{
       
  1991 					STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS,
       
  1992 					STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS,
       
  1993 					STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
       
  1994 					STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS
       
  1995 				},
       
  1996 				{
       
  1997 					STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS,
       
  1998 					STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS,
       
  1999 					STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS,
       
  2000 					STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
       
  2001 				}
  1921 			};
  2002 			};
  1922 
  2003 
  1923 			td->str = signal_type[GetSignalType(tile)];
  2004 			td->str = signal_type[GetSignalType(tile, TRACK_UPPER)][GetSignalType(tile, TRACK_LOWER)];
  1924 			break;
  2005 			break;
  1925 		}
  2006 		}
  1926 
  2007 
  1927 		case RAIL_TILE_DEPOT:
  2008 		case RAIL_TILE_DEPOT:
  1928 			td->str = STR_1023_RAILROAD_TRAIN_DEPOT;
  2009 			td->str = STR_1023_RAILROAD_TRAIN_DEPOT;
  1958 	byte fract_coord;
  2039 	byte fract_coord;
  1959 	byte fract_coord_leave;
  2040 	byte fract_coord_leave;
  1960 	DiagDirection dir;
  2041 	DiagDirection dir;
  1961 	int length;
  2042 	int length;
  1962 
  2043 
  1963 	// this routine applies only to trains in depot tiles
  2044 	/* this routine applies only to trains in depot tiles */
  1964 	if (v->type != VEH_TRAIN || !IsTileDepotType(tile, TRANSPORT_RAIL)) return VETSB_CONTINUE;
  2045 	if (v->type != VEH_TRAIN || !IsTileDepotType(tile, TRANSPORT_RAIL)) return VETSB_CONTINUE;
  1965 
  2046 
  1966 	/* depot direction */
  2047 	/* depot direction */
  1967 	dir = GetRailDepotDirection(tile);
  2048 	dir = GetRailDepotDirection(tile);
  1968 
  2049