(svn r7736) [cbh] - Codechange: removed one goto by messing with if/else blocks. Also suppresses gcc warning that 'dir' can be used uninitialized. custombridgeheads
authorKUDr
Mon, 01 Jan 2007 23:43:24 +0000
branchcustombridgeheads
changeset 5630 abc40525bd50
parent 5629 7cb2c58f4a7c
child 5631 932c1a268feb
(svn r7736) [cbh] - Codechange: removed one goto by messing with if/else blocks. Also suppresses gcc warning that 'dir' can be used uninitialized.
train_cmd.c
--- a/train_cmd.c	Mon Jan 01 23:37:39 2007 +0000
+++ b/train_cmd.c	Mon Jan 01 23:43:24 2007 +0000
@@ -3029,11 +3029,42 @@
 
 	/* For every vehicle after and including the given vehicle */
 	for (prev = GetPrevVehicleInChain(v); v != NULL; prev = v, v = v->next) {
+
+		bool in_tunnel_or_bridge = (v->u.rail.track == 0x40);
+		bool entering_new_tile;
+
 		BeginVehicleMove(v);
 
-		if (v->u.rail.track != 0x40) {
+		entering_new_tile = !GetNewVehiclePos(v, &gp);
+
+		if (in_tunnel_or_bridge) {
+			uint32 res;
+			/* in tunnel or on a bridge */
+
+			SetSpeedLimitOnBridge(v);
+
+			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !((res = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)) & 0x4)) {
+				/* stay in tunnel/bridge wormhole */
+				v->x_pos = gp.x;
+				v->y_pos = gp.y;
+				VehiclePositionChanged(v);
+				if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
+				continue;
+			}
+			/* left tunnel/bridge wormhole */
+			dir = v->direction;
+			enterdir = INVALID_DIAGDIR;
+			if (IsBridgeTile(gp.new_tile) && res & 0x4) {
+				/* ok we have just left the bridge (because the status was "onbridge" before and we got
+				a return value of 4 from VehicleEnterTile. we know the enterdir from the bridge ramp
+				direction, and act as if we entered the tile normally (hence the goto) */
+				dir = v->direction;
+				enterdir = ReverseDiagDir(GetBridgeRampDirection(gp.new_tile));
+				in_tunnel_or_bridge = false;
+			}
+		} else {
 			/* Not inside tunnel */
-			if (GetNewVehiclePos(v, &gp)) {
+			if (!entering_new_tile) {
 				/* Staying in the old tile */
 				if (v->u.rail.track == 0x80) {
 					/* inside depot */
@@ -3061,126 +3092,105 @@
 					}
 				}
 			} else {
-				/* A new tile is about to be entered. */
-
-				byte bits;
+				/* A new tile is about to be entered normally (not from bridge wormhole to ramp) */
 				/* Determine what direction we're entering the new tile from */
 				dir = GetNewVehicleDirectionByTile(gp.new_tile, gp.old_tile);
 				enterdir = DirToDiagDir(dir);
 				assert(enterdir==0 || enterdir==1 || enterdir==2 || enterdir==3);
-new_tile:
-
-				/* Get the status of the tracks in the new tile and mask
-				 * away the bits that aren't reachable. */
-				ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
-
-				/* Combine the from & to directions.
-				 * Now, the lower byte contains the track status, and the byte at bit 16 contains
-				 * the signal status. */
-				tracks = ts | (ts >> 8);
-				bits = tracks & 0xFF;
-				if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) {
-					/* We allow wagons to make 90 deg turns, because forbid_90_deg
-					 * can be switched on halfway a turn */
-					bits &= ~TrackCrossesTracks(FIND_FIRST_BIT(v->u.rail.track));
-				}
-
-				if (bits == 0) {
-					DEBUG(misc, 2, "%x == 0", bits);
-					goto invalid_rail;
-				}
-
-				/* Check if the new tile contrains tracks that are compatible
-				 * with the current train, if not, bail out. */
-				if (!CheckCompatibleRail(v, gp.new_tile)) {
-					DEBUG(misc, 2, "!CheckCompatibleRail(%p, %x)", v, gp.new_tile);
-					goto invalid_rail;
-				}
-
-				if (prev == NULL) {
-					/* Currently the locomotive is active. Determine which one of the
-					 * available tracks to choose */
-					chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
-					assert(chosen_track & tracks);
-
-					/* Check if it's a red signal and that force proceed is not clicked. */
-					if ( (tracks>>16)&chosen_track && v->u.rail.force_proceed == 0) goto red_light;
-				} else {
-					static byte _matching_tracks[8] = {0x30, 1, 0xC, 2, 0x30, 1, 0xC, 2};
-
-					/* The wagon is active, simply follow the prev vehicle. */
-					chosen_track = (byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
-				}
-
-				/* make sure chosen track is a valid track */
-				assert(chosen_track==1 || chosen_track==2 || chosen_track==4 || chosen_track==8 || chosen_track==16 || chosen_track==32);
-
-				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
-				{
-					const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
-					gp.x = (gp.x & ~0xF) | b[0];
-					gp.y = (gp.y & ~0xF) | b[1];
-					chosen_dir = b[2];
+			}
+		}
+		if (entering_new_tile && !in_tunnel_or_bridge) {
+			/* A new tile is about to be entered. */
+			byte bits;
+
+			/* Get the status of the tracks in the new tile and mask
+			 * away the bits that aren't reachable. */
+			ts = GetTileTrackStatus(gp.new_tile, TRANSPORT_RAIL) & _reachable_tracks[enterdir];
+
+			/* Combine the from & to directions.
+			 * Now, the lower byte contains the track status, and the byte at bit 16 contains
+			 * the signal status. */
+			tracks = ts | (ts >> 8);
+			bits = tracks & 0xFF;
+			if ((_patches.new_pathfinding_all || _patches.yapf.rail_use_yapf) && _patches.forbid_90_deg && prev == NULL) {
+				/* We allow wagons to make 90 deg turns, because forbid_90_deg
+				 * can be switched on halfway a turn */
+				bits &= ~TrackCrossesTracks(FIND_FIRST_BIT(v->u.rail.track));
+			}
+
+			if (bits == 0) {
+				DEBUG(misc, 2, "%x == 0", bits);
+				goto invalid_rail;
+			}
+
+			/* Check if the new tile contrains tracks that are compatible
+			 * with the current train, if not, bail out. */
+			if (!CheckCompatibleRail(v, gp.new_tile)) {
+				DEBUG(misc, 2, "!CheckCompatibleRail(%p, %x)", v, gp.new_tile);
+				goto invalid_rail;
+			}
+
+			if (prev == NULL) {
+				/* Currently the locomotive is active. Determine which one of the
+				 * available tracks to choose */
+				chosen_track = 1 << ChooseTrainTrack(v, gp.new_tile, enterdir, bits);
+				assert(chosen_track & tracks);
+
+				/* Check if it's a red signal and that force proceed is not clicked. */
+				if ( (tracks>>16)&chosen_track && v->u.rail.force_proceed == 0) goto red_light;
+			} else {
+				static byte _matching_tracks[8] = {0x30, 1, 0xC, 2, 0x30, 1, 0xC, 2};
+
+				/* The wagon is active, simply follow the prev vehicle. */
+				chosen_track = (byte)(_matching_tracks[GetDirectionToVehicle(prev, gp.x, gp.y)] & bits);
+			}
+
+			/* make sure chosen track is a valid track */
+			assert(chosen_track==1 || chosen_track==2 || chosen_track==4 || chosen_track==8 || chosen_track==16 || chosen_track==32);
+
+			/* Update XY to reflect the entrance to the new tile, and select the direction to use */
+			{
+				const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
+				gp.x = (gp.x & ~0xF) | b[0];
+				gp.y = (gp.y & ~0xF) | b[1];
+				chosen_dir = b[2];
+			}
+
+			/* Call the landscape function and tell it that the vehicle entered the tile */
+			r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
+			if (r & 0x8) {
+				DEBUG(misc, 2, "%x & 0x8 (new tile)", r);
+				goto invalid_rail;
+			}
+
+			if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
+				UnbarCrossing(v->tile);
+				MarkTileDirtyByTile(v->tile);
+			}
+
+			if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
+
+			if (!(r&0x4)) {
+				v->tile = gp.new_tile;
+
+				if (GetTileRailType(gp.new_tile, chosen_track) != GetTileRailType(gp.old_tile, v->u.rail.track)) {
+					TrainPowerChanged(GetFirstVehicleInChain(v));
 				}
 
-				/* Call the landscape function and tell it that the vehicle entered the tile */
-				r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
-				if (r & 0x8) {
-					DEBUG(misc, 2, "%x & 0x8 (new tile)", r);
-					goto invalid_rail;
-				}
-
-				if (IsLevelCrossingTile(v->tile) && v->next == NULL) {
-					UnbarCrossing(v->tile);
-					MarkTileDirtyByTile(v->tile);
-				}
-
-				if (IsFrontEngine(v)) v->load_unload_time_rem = 0;
-
-				if (!(r&0x4)) {
-					v->tile = gp.new_tile;
-
-					if (GetTileRailType(gp.new_tile, chosen_track) != GetTileRailType(gp.old_tile, v->u.rail.track)) {
-						TrainPowerChanged(GetFirstVehicleInChain(v));
-					}
-
-					v->u.rail.track = chosen_track;
-					assert(v->u.rail.track);
-				}
-
-				if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
-
-				/* Signals can only change when the first
-				 * (above) or the last vehicle moves. */
-				if (v->next == NULL)
-					TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
-
-				if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
-
-				v->direction = chosen_dir;
+				v->u.rail.track = chosen_track;
+				assert(v->u.rail.track);
 			}
-		} else {
-			uint32 res;
-			/* in tunnel on on a bridge */
-			GetNewVehiclePos(v, &gp);
-
-			SetSpeedLimitOnBridge(v);
-
-			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !((res = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)) & 0x4)) {
-				v->x_pos = gp.x;
-				v->y_pos = gp.y;
-				VehiclePositionChanged(v);
-				if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
-				continue;
-			}
-
-			if (IsBridgeTile(gp.new_tile) && res & 0x4) {
-				/* ok we have just left the bridge (because the status was "onbridge" before and we got
-				   a return value of 4 from VehicleEnterTile. we know the enterdir from the bridge ramp
-				   direction, and act as if we entered the tile normally (hence the goto) */
-				enterdir = ReverseDiagDir(GetBridgeRampDirection(gp.new_tile));
-				goto new_tile;
-			}
+
+			if (IsFrontEngine(v)) TrainMovedChangeSignals(gp.new_tile, enterdir);
+
+			/* Signals can only change when the first
+			 * (above) or the last vehicle moves. */
+			if (v->next == NULL)
+				TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir));
+
+			if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir);
+
+			v->direction = chosen_dir;
 		}
 
 		/* update image of train, as well as delta XY */