src/elrail.cpp
changeset 9035 7e8b8f37259a
parent 9034 506e4aef33b6
child 9070 dd0121143eba
equal deleted inserted replaced
9034:506e4aef33b6 9035:7e8b8f37259a
   215 	TLG tlg = GetTLG(ti->tile);
   215 	TLG tlg = GetTLG(ti->tile);
   216 	byte PCPstatus = 0;
   216 	byte PCPstatus = 0;
   217 	byte OverridePCP = 0;
   217 	byte OverridePCP = 0;
   218 	byte PPPpreferred[DIAGDIR_END];
   218 	byte PPPpreferred[DIAGDIR_END];
   219 	byte PPPallowed[DIAGDIR_END];
   219 	byte PPPallowed[DIAGDIR_END];
   220 	DiagDirection i;
       
   221 	Track t;
       
   222 
   220 
   223 	/* Find which rail bits are present, and select the override points.
   221 	/* Find which rail bits are present, and select the override points.
   224 	 * We don't draw a pylon:
   222 	 * We don't draw a pylon:
   225 	 * 1) INSIDE a tunnel (we wouldn't see it anyway)
   223 	 * 1) INSIDE a tunnel (we wouldn't see it anyway)
   226 	 * 2) on the "far" end of a bridge head (the one that connects to bridge middle),
   224 	 * 2) on the "far" end of a bridge head (the one that connects to bridge middle),
   230 	/* If a track bit is present that is not in the main direction, the track is level */
   228 	/* If a track bit is present that is not in the main direction, the track is level */
   231 	isflat[TS_HOME] = ((trackconfig[TS_HOME] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0);
   229 	isflat[TS_HOME] = ((trackconfig[TS_HOME] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0);
   232 
   230 
   233 	AdjustTileh(ti->tile, &tileh[TS_HOME]);
   231 	AdjustTileh(ti->tile, &tileh[TS_HOME]);
   234 
   232 
   235 	for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
   233 	for (DiagDirection i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
   236 		TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
   234 		TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
   237 		Foundation foundation = FOUNDATION_NONE;
   235 		Foundation foundation = FOUNDATION_NONE;
   238 		int k;
   236 		byte elevation = GetPCPElevation(ti->tile, i);
   239 
   237 
   240 		/* Here's one of the main headaches. GetTileSlope does not correct for possibly
   238 		/* Here's one of the main headaches. GetTileSlope does not correct for possibly
   241 		 * existing foundataions, so we do have to do that manually later on.*/
   239 		 * existing foundataions, so we do have to do that manually later on.*/
   242 		tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
   240 		tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
   243 		trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
   241 		trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
   244 		if (IsTunnelTile(neighbour) && i != GetTunnelBridgeDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
   242 		if (IsTunnelTile(neighbour) && i != GetTunnelBridgeDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
   245 
   243 
   246 		/* If the neighboured tile does not smoothly connect to the current tile (because of a foundation),
   244 		/* If the neighboured tile does not smoothly connect to the current tile (because of a foundation),
   247 		 * we have to draw all pillars on the current tile. */
   245 		 * we have to draw all pillars on the current tile. */
   248 		if (GetPCPElevation(ti->tile, i) != GetPCPElevation(neighbour, ReverseDiagDir(i))) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
   246 		if (elevation != GetPCPElevation(neighbour, ReverseDiagDir(i))) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
   249 
   247 
   250 		isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0);
   248 		isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0);
   251 
   249 
   252 		PPPpreferred[i] = 0xFF; // We start with preferring everything (end-of-line in any direction)
   250 		PPPpreferred[i] = 0xFF; // We start with preferring everything (end-of-line in any direction)
   253 		PPPallowed[i] = AllowedPPPonPCP[i];
   251 		PPPallowed[i] = AllowedPPPonPCP[i];
   254 
   252 
   255 		/* We cycle through all the existing tracks at a PCP and see what
   253 		/* We cycle through all the existing tracks at a PCP and see what
   256 		 * PPPs we want to have, or may not have at all */
   254 		 * PPPs we want to have, or may not have at all */
   257 		for (k = 0; k < NUM_TRACKS_AT_PCP; k++) {
   255 		for (uint k = 0; k < NUM_TRACKS_AT_PCP; k++) {
   258 			/* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
   256 			/* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
   259 			if (TrackSourceTile[i][k] == TS_NEIGHBOUR &&
   257 			if (TrackSourceTile[i][k] == TS_NEIGHBOUR &&
   260 			    IsBridgeTile(neighbour) &&
   258 			    IsBridgeTile(neighbour) &&
   261 			    GetTunnelBridgeDirection(neighbour) == ReverseDiagDir(i)) {
   259 			    GetTunnelBridgeDirection(neighbour) == ReverseDiagDir(i)) {
   262 				continue;
   260 				continue;
   274 				PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
   272 				PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
   275 			}
   273 			}
   276 		}
   274 		}
   277 
   275 
   278 		/* Deactivate all PPPs if PCP is not used */
   276 		/* Deactivate all PPPs if PCP is not used */
   279 		PPPpreferred[i] *= HasBit(PCPstatus, i);
   277 		if (!HasBit(PCPstatus, i)) {
   280 		PPPallowed[i] *= HasBit(PCPstatus, i);
   278 			PPPpreferred[i] = 0;
       
   279 			PPPallowed[i] = 0;
       
   280 		}
   281 
   281 
   282 		/* A station is always "flat", so adjust the tileh accordingly */
   282 		/* A station is always "flat", so adjust the tileh accordingly */
   283 		if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
   283 		if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
   284 
   284 
   285 		/* Read the foundataions if they are present, and adjust the tileh */
   285 		/* Read the foundataions if they are present, and adjust the tileh */
   288 			foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetTunnelBridgeDirection(neighbour)));
   288 			foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetTunnelBridgeDirection(neighbour)));
   289 		}
   289 		}
   290 
   290 
   291 		ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
   291 		ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
   292 
   292 
   293 	/* Half tile slopes coincide only with horizontal/vertical track.
   293 		/* Half tile slopes coincide only with horizontal/vertical track.
   294 	 * Faking a flat slope results in the correct sprites on positions. */
   294 		 * Faking a flat slope results in the correct sprites on positions. */
   295 		if (IsHalftileSlope(tileh[TS_NEIGHBOUR])) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
   295 		if (IsHalftileSlope(tileh[TS_NEIGHBOUR])) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
   296 
   296 
   297 		AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
   297 		AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
   298 
   298 
   299 		/* If we have a straight (and level) track, we want a pylon only every 2 tiles
   299 		/* If we have a straight (and level) track, we want a pylon only every 2 tiles
   300 		 * Delete the PCP if this is the case. */
   300 		 * Delete the PCP if this is the case. */
   301 		/* Level means that the slope is the same, or the track is flat */
   301 		/* Level means that the slope is the same, or the track is flat */
   302 		if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
   302 		if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
   303 			for (k = 0; k < NUM_IGNORE_GROUPS; k++)
   303 			for (uint k = 0; k < NUM_IGNORE_GROUPS; k++) {
   304 				if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) ClrBit(PCPstatus, i);
   304 				if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) ClrBit(PCPstatus, i);
       
   305 			}
   305 		}
   306 		}
   306 
   307 
   307 		/* Now decide where we draw our pylons. First try the preferred PPPs, but they may not exist.
   308 		/* Now decide where we draw our pylons. First try the preferred PPPs, but they may not exist.
   308 		 * In that case, we try the any of the allowed ones. if they don't exist either, don't draw
   309 		 * In that case, we try the any of the allowed ones. if they don't exist either, don't draw
   309 		 * anything. Note that the preferred PPPs still contain the end-of-line markers.
   310 		 * anything. Note that the preferred PPPs still contain the end-of-line markers.
   319 				SetBit(OverridePCP, i);
   320 				SetBit(OverridePCP, i);
   320 			}
   321 			}
   321 		}
   322 		}
   322 
   323 
   323 		if (PPPallowed[i] != 0 && HasBit(PCPstatus, i) && !HasBit(OverridePCP, i)) {
   324 		if (PPPallowed[i] != 0 && HasBit(PCPstatus, i) && !HasBit(OverridePCP, i)) {
   324 			for (k = 0; k < DIR_END; k++) {
   325 			for (Direction k = DIR_BEGIN; k < DIR_END; k++) {
   325 				byte temp = PPPorder[i][GetTLG(ti->tile)][k];
   326 				byte temp = PPPorder[i][GetTLG(ti->tile)][k];
   326 
   327 
   327 				if (HasBit(PPPallowed[i], temp)) {
   328 				if (HasBit(PPPallowed[i], temp)) {
   328 					uint x  = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
   329 					uint x  = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
   329 					uint y  = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
   330 					uint y  = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
   334 						if (trackconfig[TS_NEIGHBOUR] != 0) break;
   335 						if (trackconfig[TS_NEIGHBOUR] != 0) break;
   335 						continue; /* No neighbour, go looking for a better position */
   336 						continue; /* No neighbour, go looking for a better position */
   336 					}
   337 					}
   337 
   338 
   338 					AddSortableSpriteToDraw(pylon_sprites[temp], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE,
   339 					AddSortableSpriteToDraw(pylon_sprites[temp], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE,
   339 							GetPCPElevation(ti->tile, i),
   340 						elevation, IsTransparencySet(TO_CATENARY), -1, -1);
   340 							IsTransparencySet(TO_CATENARY), -1, -1);
   341 
   341 					break; /* We already have drawn a pylon, bail out */
   342 					break; /* We already have drawn a pylon, bail out */
   342 				}
   343 				}
   343 			}
   344 			}
   344 		}
   345 		}
   345 	}
   346 	}
   350 
   351 
   351 		if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return;
   352 		if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return;
   352 	}
   353 	}
   353 
   354 
   354 	/* Drawing of pylons is finished, now draw the wires */
   355 	/* Drawing of pylons is finished, now draw the wires */
   355 	for (t = TRACK_BEGIN; t < TRACK_END; t++) {
   356 	for (Track t = TRACK_BEGIN; t < TRACK_END; t++) {
   356 		if (HasBit(trackconfig[TS_HOME], t)) {
   357 		if (HasBit(trackconfig[TS_HOME], t)) {
   357 			if (IsTunnelTile(ti->tile)) break; // drawn together with tunnel-roof (see DrawCatenaryOnTunnel())
   358 			if (IsTunnelTile(ti->tile)) break; // drawn together with tunnel-roof (see DrawCatenaryOnTunnel())
   358 			byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) +
   359 			byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) +
   359 				(HasBit(PCPstatus, PCPpositions[t][1]) << 1);
   360 				(HasBit(PCPstatus, PCPpositions[t][1]) << 1);
   360 
   361