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)) { |