Changeset - r5731:f5f88f3094dd
[Not reviewed]
master
0 2 0
Darkvater - 17 years ago 2007-01-19 00:01:52
darkvater@openttd.org
(svn r8274) -Codechange (r8151): Move the automatic semaphore/signal checks inside the CMD_ functions where they are supposed to be. Achieve this by adding a seperate bit to p1/p2 to hold the CTRL-modifier. While here, use proper types, and 'unify' the parameter bit-meanings. 0 - ctrl-pressed, 1 - signal/semaphore, 2-4 - trackbits, 5 - remove (internal), 24-31 - drag density.
2 files changed with 50 insertions and 46 deletions:
0 comments (0 inline, 0 general)
src/rail_cmd.cpp
Show inline comments
 
@@ -598,31 +598,29 @@ int32 CmdBuildTrainDepot(TileIndex tile,
 
	}
 

	
 
	return cost + _price.build_train_depot;
 
}
 

	
 
/** Build signals, alternate between double/single, signal/semaphore,
 
 * pre/exit/combo-signals, and what-else not
 
 * pre/exit/combo-signals, and what-else not. If the rail piece does not
 
 * have any signals, bit 4 (cycle signal-type) is ignored
 
 * @param tile tile where to build the signals
 
 * @param p1 various bitstuffed elements
 
 * - p1 = (bit 0-2) - track-orientation, valid values: 0-5 (Track enum)
 
 * - p1 = (bit 3)   - choose semaphores/signals or cycle normal/pre/exit/combo depending on context
 
 * - p1 = (bit 0)   - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
 
 * - p1 = (bit 1)   - 0 = signals, 1 = semaphores
 
 * - p1 = (bit 2-4) - track-orientation, valid values: 0-5 (Track enum)
 
 * @param p2 used for CmdBuildManySignals() to copy direction of first signal
 
 * TODO: p2 should be replaced by two bits for "along" and "against" the track.
 
 */
 
int32 CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	SignalVariant sigvar;
 
	bool pre_signal;
 
	Track track = (Track)(p1 & 0x7);
 
	bool pre_signal = HASBIT(p1, 0);
 
	SignalVariant sigvar = HASBIT(p1, 1) ? SIG_SEMAPHORE : SIG_ELECTRIC;
 
	Track track = (Track)GB(p1, 2, 3);
 
	int32 cost;
 

	
 
	// Same bit, used in different contexts
 
	sigvar = HASBIT(p1, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC;
 
	pre_signal = HASBIT(p1, 3);
 

	
 
	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 

	
 
	/* Protect against invalid signal copying */
 
	if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
 

	
 
@@ -699,29 +697,31 @@ int32 CmdBuildSingleSignal(TileIndex til
 
}
 

	
 
/** Build many signals by dragging; AutoSignals
 
 * @param tile start tile of drag
 
 * @param p1  end tile of drag
 
 * @param p2 various bitstuffed elements
 
 * - p2 = (bit  0)    - 0 = build, 1 = remove signals
 
 * - p2 = (bit  3)    - 0 = signals, 1 = semaphores
 
 * - p2 = (bit  4- 6) - track-orientation, valid values: 0-5 (Track enum)
 
 * - p2 = (bit  0)    - 1 = override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
 
 * - p2 = (bit  1)    - 0 = signals, 1 = semaphores
 
 * - p2 = (bit  2- 4) - track-orientation, valid values: 0-5 (Track enum)
 
 * - p2 = (bit  5)    - 0 = build, 1 = remove signals
 
 * - p2 = (bit 24-31) - user defined signals_density
 
 */
 
static int32 CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	int32 ret, total_cost, signal_ctr;
 
	byte signals;
 
	bool error = true;
 
	TileIndex end_tile;
 

	
 
	int mode = p2 & 0x1;
 
	Track track = (Track)GB(p2, 4, 3);
 
	bool mode = HASBIT(p2, 0);
 
	bool semaphores = HASBIT(p2, 1);
 
	Track track = (Track)GB(p2, 2, 3);
 
	bool remove = HASBIT(p2, 5);
 
	Trackdir trackdir = TrackToTrackdir(track);
 
	byte semaphores = (HASBIT(p2, 3) ? 8 : 0);
 
	byte signal_density = (p2 >> 24);
 
	byte signal_density = GB(p2, 24, 8);
 

	
 
	if (p1 >= MapSize()) return CMD_ERROR;
 
	end_tile = p1;
 
	if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
 

	
 
	if (!IsTileType(tile, MP_RAILWAY)) return CMD_ERROR;
 
@@ -739,30 +739,34 @@ static int32 CmdSignalTrackHelper(TileIn
 
	// copy the signal-style of the first rail-piece if existing
 
	if (HasSignals(tile)) {
 
		signals = _m[tile].m3 & SignalOnTrack(track);
 
		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
 

	
 
		// copy signal/semaphores style (independent of CTRL)
 
		semaphores = (GetSignalVariant(tile) == SIG_ELECTRIC ? 0 : 8);
 
		semaphores = GetSignalVariant(tile) != SIG_ELECTRIC;
 
	} else { // no signals exist, drag a two-way signal stretch
 
		signals = SignalOnTrack(track);
 
	}
 

	
 
	/* signal_ctr         - amount of tiles already processed
 
	 * signals_density    - patch setting to put signal on every Nth tile (double space on |, -- tracks)
 
	 **********
 
	 * trackdir   - trackdir to build with autorail
 
	 * semaphores - semaphores or signals
 
	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
 
	 *              and convert all others to semaphore/signal
 
	 * mode       - 1 remove signals, 0 build signals */
 
	 * remove     - 1 remove signals, 0 build signals */
 
	signal_ctr = total_cost = 0;
 
	for (;;) {
 
		// only build/remove signals with the specified density
 
		if (signal_ctr % signal_density == 0) {
 
			ret = DoCommand(tile, TrackdirToTrack(trackdir) | semaphores, signals, flags, (mode == 1) ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
 
			int p1 = 0;
 
			SB(p1, 0, 1, mode);
 
			SB(p1, 1, 1, semaphores);
 
			SB(p1, 2, 3, TrackdirToTrack(trackdir));
 
			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
 

	
 
			/* Be user-friendly and try placing signals as much as possible */
 
			if (!CmdFailed(ret)) {
 
				error = false;
 
				total_cost += ret;
 
			}
 
@@ -788,17 +792,20 @@ int32 CmdBuildSignalTrack(TileIndex tile
 
{
 
	return CmdSignalTrackHelper(tile, flags, p1, p2);
 
}
 

	
 
/** Remove signals
 
 * @param tile coordinates where signal is being deleted from
 
 * @param p1 track to remove signal from (Track enum)
 
 * @param various bitstuffed elements, only track information is used
 
 * - p1 = (bit  0)    - override signal/semaphore, or pre/exit/combo signal (CTRL-toggle)
 
 * - p1 = (bit  1)    - 0 = signals, 1 = semaphores
 
 * - p1 = (bit  2- 4) - track-orientation, valid values: 0-5 (Track enum)
 
 */
 
int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Track track = (Track)(p1 & 0x7);
 
	Track track = (Track)GB(p1, 2, 3);
 

	
 
	if (!ValParamTrackOrientation(track) ||
 
			!IsTileType(tile, MP_RAILWAY) ||
 
			!EnsureNoVehicle(tile) ||
 
			!HasSignalOnTrack(tile, track)) {
 
		return CMD_ERROR;
 
@@ -832,13 +839,13 @@ int32 CmdRemoveSingleSignal(TileIndex ti
 
/** Remove signals on a stretch of track.
 
 * Stub for the unified signal builder/remover
 
 * @see CmdSignalTrackHelper
 
 */
 
int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 0));
 
	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit
 
}
 

	
 
typedef int32 DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
 

	
 
static int32 DoConvertRail(TileIndex tile, RailType totype, bool exec)
 
{
src/rail_gui.cpp
Show inline comments
 
@@ -161,37 +161,36 @@ static void PlaceRail_Station(TileIndex 
 
				CMD_BUILD_RAILROAD_STATION | CMD_NO_WATER | CMD_AUTO | CMD_MSG(STR_100F_CAN_T_BUILD_RAILROAD_STATION));
 
	}
 
}
 

	
 
static void GenericPlaceSignals(TileIndex tile)
 
{
 
	uint trackstat;
 
	byte trackstat;
 
	uint i;
 

	
 
	trackstat = (byte)GetTileTrackStatus(tile, TRANSPORT_RAIL);
 

	
 
	if ((trackstat & 0x30)) // N-S direction
 
		trackstat = (_tile_fract_coords.x <= _tile_fract_coords.y) ? 0x20 : 0x10;
 
	if (trackstat & TRACK_BIT_VERT) // N-S direction
 
		trackstat = (_tile_fract_coords.x <= _tile_fract_coords.y) ? TRACK_BIT_RIGHT : TRACK_BIT_LEFT;
 

	
 
	if ((trackstat & 0x0C)) // E-W direction
 
		trackstat = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? 4 : 8;
 
	if (trackstat & TRACK_BIT_HORZ) // E-W direction
 
		trackstat = (_tile_fract_coords.x + _tile_fract_coords.y <= 15) ? TRACK_BIT_UPPER : TRACK_BIT_LOWER;
 

	
 
	// Lookup the bit index
 
	i = 0;
 
	if (trackstat != 0) {
 
		for (; !(trackstat & 1); trackstat >>= 1) i++;
 
	}
 

	
 
	if (!_remove_button_clicked) {
 
		uint32 p1 = _ctrl_pressed ? 8 : 0;
 
		if (IsTileType(tile, MP_RAILWAY) && !HasSignals(tile) && _cur_year < _patches.semaphore_build_before) {
 
			/* Reverse the logic, so semaphores are normally built, and light
 
			 * signals can be built with ctrl held down. */
 
			p1 = _ctrl_pressed ? 0 : 8;
 
		}
 
		DoCommandP(tile, i + p1, 0, CcPlaySound1E,
 
		uint32 p1 = 0;
 
		SB(p1, 0, 1, _ctrl_pressed);
 
		SB(p1, 1, 1, _ctrl_pressed ^ (_cur_year < _patches.semaphore_build_before));
 
		SB(p1, 2, 3, i);
 

	
 
		DoCommandP(tile, p1, 0, CcPlaySound1E,
 
			CMD_BUILD_SIGNALS | CMD_AUTO | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE));
 
	} else {
 
		DoCommandP(tile, i, 0, CcPlaySound1E,
 
			CMD_REMOVE_SIGNALS | CMD_AUTO | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM));
 
	}
 
}
 
@@ -364,32 +363,30 @@ static void HandleAutodirPlacement(void)
 
}
 

	
 
static void HandleAutoSignalPlacement(void)
 
{
 
	TileHighlightData *thd = &_thd;
 
	byte trackstat = thd->drawstyle & 0xF; // 0..5
 
	byte semaphore = _ctrl_pressed ? 1 : 0;
 

	
 
	if (thd->drawstyle == HT_RECT) { // one tile case
 
		GenericPlaceSignals(TileVirtXY(thd->selend.x, thd->selend.y));
 
		return;
 
	}
 

	
 
	TileIndex start_tile = TileVirtXY(thd->selstart.x, thd->selstart.y);
 
	if (IsTileType(start_tile, MP_RAILWAY) && !HasSignals(start_tile) && _cur_year < _patches.semaphore_build_before) {
 
		/* Reverse the logic, so semaphores are normally built, and light
 
		 * signals can be built with ctrl held down. */
 
		semaphore = _ctrl_pressed ? 0 : 1;
 
	}
 
	int p2 = 0;
 
	SB(p2,  0, 1, _ctrl_pressed);
 
	SB(p2,  1, 1, _ctrl_pressed ^ (_cur_year < _patches.semaphore_build_before));
 
	SB(p2,  2, 3, trackstat);
 
	SB(p2, 24, 8, _patches.drag_signals_density);
 

	
 
	// _patches.drag_signals_density is given as a parameter such that each user in a network
 
	// game can specify his/her own signal density
 
	/* _patches.drag_signals_density is given as a parameter such that each user
 
	 * in a network game can specify his/her own signal density */
 
	DoCommandP(
 
		start_tile,
 
		TileVirtXY(thd->selstart.x, thd->selstart.y),
 
		TileVirtXY(thd->selend.x, thd->selend.y),
 
		(semaphore << 3) | (trackstat << 4) | (_patches.drag_signals_density << 24),
 
		p2,
 
		CcPlaySound1E,
 
		_remove_button_clicked ?
 
			CMD_REMOVE_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
 
			CMD_BUILD_SIGNAL_TRACK  | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE)
 
	);
 
}
0 comments (0 inline, 0 general)