elrail.c
changeset 3451 86ff1ac451d8
parent 3449 677afbebac23
child 3452 c3ee991eaba1
equal deleted inserted replaced
3450:3b067aa1c08c 3451:86ff1ac451d8
   113 		default:
   113 		default:
   114 			return 0;
   114 			return 0;
   115 	}
   115 	}
   116 }
   116 }
   117 
   117 
       
   118 /** Corrects the tileh for certain tile types. Returns an effective tileh for the track on the tile.
       
   119   * @param tile The tile to analyse
       
   120   * @param *tileh the tileh
       
   121   */
       
   122 static void AdjustTileh(TileIndex tile, uint *tileh)
       
   123 {
       
   124 	if (IsTunnelTile(tile)) *tileh = 0;
       
   125 	if (IsBridgeTile(tile) && IsBridgeRamp(tile)) {
       
   126 		if (*tileh != 0) {
       
   127 			*tileh = 0;
       
   128 		} else {
       
   129 			switch (GetBridgeRampDirection(tile)) {
       
   130 				case DIAGDIR_NE: *tileh = 12; break;
       
   131 				case DIAGDIR_SE: *tileh =  6; break;
       
   132 				case DIAGDIR_SW: *tileh =  3; break;
       
   133 				case DIAGDIR_NW: *tileh =  9; break;
       
   134 				default: break;
       
   135 			}
       
   136 		}
       
   137 	}
       
   138 }
       
   139 
   118 /** Draws wires and, if required, pylons on a given tile
   140 /** Draws wires and, if required, pylons on a given tile
   119   * @param ti The Tileinfo to draw the tile for
   141   * @param ti The Tileinfo to draw the tile for
   120   * @todo Currently, each pylon is drawn twice (once for each neighbouring tiles use OwnedPPPonPCP for this)
       
   121   */
   142   */
   122 static void DrawCatenaryRailway(const TileInfo *ti)
   143 static void DrawCatenaryRailway(const TileInfo *ti)
   123 {
   144 {
   124 	/* Pylons are placed on a tile edge, so we need to take into account
   145 	/* Pylons are placed on a tile edge, so we need to take into account
   125 	   the track configuration of 2 adjacent tiles. trackconfig[0] stores the
   146 	   the track configuration of 2 adjacent tiles. trackconfig[0] stores the
   126 	   current tile (home tile) while [1] holds the neighbour */
   147 	   current tile (home tile) while [1] holds the neighbour */
   127 	TrackBits trackconfig[TS_END];
   148 	TrackBits trackconfig[TS_END];
   128 	bool isflat[TS_END];
   149 	bool isflat[TS_END];
   129 	/* Note that ti->tileh has already been adjusted for Foundations */
   150 	/* Note that ti->tileh has already been adjusted for Foundations */
   130 	uint tileh[TS_END];
   151 	uint tileh[TS_END] = {ti->tileh, 0};
   131 
   152 
   132 	TLG tlg = GetTLG(ti->tile);
   153 	TLG tlg = GetTLG(ti->tile);
   133 	byte PCPstatus = 0;
   154 	byte PCPstatus = 0;
   134 	byte OverridePCP = 0;
   155 	byte OverridePCP = 0;
   135 	byte PPPpreferred[DIAGDIR_END];
   156 	byte PPPpreferred[DIAGDIR_END];
   136 	byte PPPallowed[DIAGDIR_END];
   157 	byte PPPallowed[DIAGDIR_END];
   137 	byte PPPbuffer[DIAGDIR_END];
       
   138 	DiagDirection i;
   158 	DiagDirection i;
   139 	Track t;
   159 	Track t;
   140 
       
   141 	tileh[0] = ti->tileh;
       
   142 	tileh[1] = 0;
       
   143 
       
   144 	PPPpreferred[0] = PPPpreferred[1] = PPPpreferred[2] = PPPpreferred[3] = 0xFF;
       
   145 	PPPallowed[0] = AllowedPPPonPCP[0];
       
   146 	PPPallowed[1] = AllowedPPPonPCP[1];
       
   147 	PPPallowed[2] = AllowedPPPonPCP[2];
       
   148 	PPPallowed[3] = AllowedPPPonPCP[3];
       
   149 
   160 
   150 	/* Find which rail bits are present, and select the override points.
   161 	/* Find which rail bits are present, and select the override points.
   151 	   We don't draw a pylon:
   162 	   We don't draw a pylon:
   152 	   1) INSIDE a tunnel (we wouldn't see it anyway)
   163 	   1) INSIDE a tunnel (we wouldn't see it anyway)
   153 	   2) on the "far" end of a bridge head (the one that connects to bridge middle),
   164 	   2) on the "far" end of a bridge head (the one that connects to bridge middle),
   155 	      which have no middle tiles */
   166 	      which have no middle tiles */
   156 	trackconfig[TS_HOME] = GetRailTrackBitsUniversal(ti->tile, &OverridePCP);
   167 	trackconfig[TS_HOME] = GetRailTrackBitsUniversal(ti->tile, &OverridePCP);
   157 	/* If a track bit is present that is not in the main direction, the track is level */
   168 	/* If a track bit is present that is not in the main direction, the track is level */
   158 	isflat[TS_HOME] = trackconfig[TS_HOME] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT);
   169 	isflat[TS_HOME] = trackconfig[TS_HOME] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT);
   159 
   170 
   160 	if (IsTunnelTile(ti->tile)) tileh[TS_HOME] = 0;
   171 	AdjustTileh(ti->tile, &tileh[TS_HOME]);
   161 	if (IsBridgeTile(ti->tile) && IsBridgeRamp(ti->tile)) {
       
   162 		if (tileh[TS_HOME] != 0) {
       
   163 			tileh[TS_HOME] = 0;
       
   164 		} else {
       
   165 			switch (GetBridgeRampDirection(ti->tile)) {
       
   166 				case DIAGDIR_NE: tileh[TS_HOME] = 12; break;
       
   167 				case DIAGDIR_SE: tileh[TS_HOME] =  6; break;
       
   168 				case DIAGDIR_SW: tileh[TS_HOME] =  3; break;
       
   169 				case DIAGDIR_NW: tileh[TS_HOME] =  9; break;
       
   170 				default: break;
       
   171 			}
       
   172 		}
       
   173 	}
       
   174 
   172 
   175 	for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
   173 	for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
   176 		TileIndex neighbour = ti->tile + TileOffsByDir(i);
   174 		TileIndex neighbour = ti->tile + TileOffsByDir(i);
   177 		uint foundation = 0;
   175 		uint foundation = 0;
   178 		int k;
   176 		int k;
   181 		   existing foundataions, so we do have to do that manually later on.*/
   179 		   existing foundataions, so we do have to do that manually later on.*/
   182 		tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
   180 		tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
   183 		trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
   181 		trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
   184 		isflat[TS_NEIGHBOUR] = trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT);
   182 		isflat[TS_NEIGHBOUR] = trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_UPPER | TRACK_BIT_LOWER | TRACK_BIT_LEFT | TRACK_BIT_RIGHT);
   185 
   183 
       
   184 		PPPpreferred[i] = 0xFF; /* We start with preferring everything (end-of-line in any direction) */
       
   185 		PPPallowed[i] = AllowedPPPonPCP[i];
       
   186 
   186 		/* We cycle through all the existing tracks at a PCP and see what
   187 		/* We cycle through all the existing tracks at a PCP and see what
   187 		   PPPs we want to have, or may not have at all */
   188 		   PPPs we want to have, or may not have at all */
   188 		for (k = 0; k < TRACKS_AT_PCP; k++) {
   189 		for (k = 0; k < NUM_TRACKS_AT_PCP; k++) {
   189 			/* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
   190 			/* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
   190 			if (
   191 			if (TrackSourceTile[i][k] == TS_NEIGHBOUR &&
   191 					trackorigin[i][k] == TS_NEIGHBOUR &&
   192 			    IsBridgeTile(neighbour) && IsBridgeRamp(neighbour) &&
   192 					IsBridgeTile(neighbour) && IsBridgeRamp(neighbour) &&
   193 			    GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)
   193 					GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)
       
   194 			   ) continue;
   194 			   ) continue;
   195 
   195 
   196 			if (HASBIT(trackconfig[trackorigin[i][k]], PPPtracks[i][k])) {
   196 			/* We check whether the track in question (k) is present in the tile
   197 				DiagDirection PCPpos = (trackorigin[i][k] == 0) ? i : ReverseDiagDir(i);
   197 			   (TrackSourceTile) */
   198 				PCPstatus |= 1 << i; /* This PCP is in use */
   198 			if (HASBIT(trackconfig[TrackSourceTile[i][k]], TracksAtPCP[i][k])) {
   199 				PPPpreferred[i] &= PreferredPPPofTrackBitAtPCP[PPPtracks[i][k]][PCPpos];
   199 				/* track found, if track is in the neighbour tile, adjust the number
   200 				PPPallowed[i] &= ~DisallowedPPPofTrackBitAtPCP[PPPtracks[i][k]][PCPpos];
   200 				   of the PCP for preferred/allowed determination*/
       
   201 				DiagDirection PCPpos = (TrackSourceTile[i][k] == TS_HOME) ? i : ReverseDiagDir(i);
       
   202 				SETBIT(PCPstatus, i); /* This PCP is in use */
       
   203 
       
   204 				PPPpreferred[i] &= PreferredPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
       
   205 				PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
   201 			}
   206 			}
   202 		}
   207 		}
   203 
   208 
   204 		/* Deactivate all PPPs if PCP is not used */
   209 		/* Deactivate all PPPs if PCP is not used */
   205 		PPPpreferred[i] *= HASBIT(PCPstatus, i);
   210 		PPPpreferred[i] *= HASBIT(PCPstatus, i);
   220 			} else {
   225 			} else {
   221 				tileh[TS_NEIGHBOUR] = _inclined_tileh[foundation - 15];
   226 				tileh[TS_NEIGHBOUR] = _inclined_tileh[foundation - 15];
   222 			}
   227 			}
   223 		}
   228 		}
   224 
   229 
   225 		/* Convert the real tileh into a pseudo-tileh for the track */
   230 		AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
   226 		if (IsTunnelTile(neighbour)) tileh[TS_NEIGHBOUR] = 0;
       
   227 		if (IsBridgeTile(neighbour) && IsBridgeRamp(neighbour)) {
       
   228 			if (tileh[TS_NEIGHBOUR] != 0) {
       
   229 				tileh[TS_NEIGHBOUR] = 0;
       
   230 			} else {
       
   231 				switch (GetBridgeRampDirection(neighbour)) {
       
   232 					case DIAGDIR_NE: tileh[TS_NEIGHBOUR] = 12; break;
       
   233 					case DIAGDIR_SE: tileh[TS_NEIGHBOUR] =  6; break;
       
   234 					case DIAGDIR_SW: tileh[TS_NEIGHBOUR] =  3; break;
       
   235 					case DIAGDIR_NW: tileh[TS_NEIGHBOUR] =  9; break;
       
   236 					default: break;
       
   237 				}
       
   238 			}
       
   239 		}
       
   240 
   231 
   241 		/* If we have a straight (and level) track, we want a pylon only every 2 tiles
   232 		/* If we have a straight (and level) track, we want a pylon only every 2 tiles
   242 		   Delete the PCP if this is the case. */
   233 		   Delete the PCP if this is the case. */
   243 		/* Level means that the slope is the same, or the track is flat */
   234 		/* Level means that the slope is the same, or the track is flat */
   244 		if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
   235 		if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
   245 			for (k = 0; k < NUM_IGNORE_GROUPS; k++)
   236 			for (k = 0; k < NUM_IGNORE_GROUPS; k++)
   246 				if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) PCPstatus &= ~(1 << i);
   237 				if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) CLRBIT(PCPstatus, i);
   247 		}
   238 		}
   248 
   239 
   249 		/* Now decide where we draw our tiles. First try the preferred PPPs, but they may not exist.
   240 		/* Now decide where we draw our pylons. First try the preferred PPPs, but they may not exist.
   250 		   In that case, we try the any of the allowed ones. if they don't exist either, don't draw
   241 		   In that case, we try the any of the allowed ones. if they don't exist either, don't draw
   251 		   anything */
   242 		   anything. Note that the preferred PPPs still contain the end-of-line markers.
   252 		if (PPPpreferred[i] != 0) {
   243 		   Remove those (simply by ANDing with allowed, since these markers are never allowed) */
   253 			/* Some of the preferred PPPs (the ones in direct extension of the track bit)
   244 		if ( (PPPallowed[i] & PPPpreferred[i]) != 0) PPPallowed[i] &= PPPpreferred[i];
   254 			   have been used as an "end of line" marker. As these are not ALLOWED, this operation
   245 
   255 			   cancles them out */
   246 		if (PPPallowed[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) {
   256 			PPPbuffer[i] = PPPpreferred[i] & PPPallowed[i];
       
   257 			/* We haven't any buffer yet, so try something else. Fixes 90° curves */
       
   258 			if (PPPbuffer[i] == 0) PPPbuffer[i] = PPPallowed[i];
       
   259 		} else {
       
   260 			PPPbuffer[i] = PPPallowed[i];
       
   261 		}
       
   262 
       
   263 		if (PPPbuffer[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) {
       
   264 			for (k = 0; k < DIR_END; k++) {
   247 			for (k = 0; k < DIR_END; k++) {
   265 				byte temp = PPPorder[i][GetTLG(ti->tile)][k];
   248 				byte temp = PPPorder[i][GetTLG(ti->tile)][k];
   266 				if (HASBIT(PPPbuffer[i], temp)) {
   249 				if (HASBIT(PPPallowed[i], temp)) {
   267 					uint x  = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
   250 					uint x  = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
   268 					uint y  = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
   251 					uint y  = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
   269 
   252 
   270 					/* Don't build the pylon if it would be outside the tile */
   253 					/* Don't build the pylon if it would be outside the tile */
   271 					if (!HASBIT(OwnedPPPonPCP[i], temp)) {
   254 					if (!HASBIT(OwnedPPPonPCP[i], temp)) {