Mercurial > hg > openttd
comparison src/elrail.cpp @ 7534:cf1947f78acc draft
(svn r11054) -Fix [FS#944]: mismatch between TTDP's and OTTD's placement of catenary, creating graphical glitches when loading a catenary replacement. Patch by frosch.
author | rubidium <rubidium@openttd.org> |
---|---|
date | Fri, 07 Sep 2007 21:11:12 +0000 |
parents | 0731fbbbacb9 |
children | b5ee57f72673 |
comparison
equal
deleted
inserted
replaced
7533:4fc7abc511ae | 7534:cf1947f78acc |
---|---|
139 } | 139 } |
140 } | 140 } |
141 } | 141 } |
142 } | 142 } |
143 | 143 |
144 /** | |
145 * Returns the Z position of a Pylon Control Point. | |
146 * | |
147 * @param tile The tile the pylon should stand on. | |
148 * @param PCPpos The PCP of the tile. | |
149 * @return The Z position of the PCP. | |
150 */ | |
151 static byte GetPCPElevation(TileIndex tile, DiagDirection PCPpos) | |
152 { | |
153 /* The elevation of the "pylon"-sprite should be the elevation at the PCP. | |
154 * PCPs are always on a tile edge. | |
155 * | |
156 * This position can be outside of the tile, i.e. ?_pcp_offset == TILE_SIZE > TILE_SIZE - 1. | |
157 * So we have to move it inside the tile, because if the neighboured tile has a foundation, | |
158 * that does not smoothly connect to the current tile, we will get a wrong elevation from GetSlopeZ(). | |
159 * | |
160 * When we move the position inside the tile, we will get a wrong elevation if we have a slope. | |
161 * To catch all cases we round the Z position to the next (TILE_HEIGHT / 2). | |
162 * This will return the correct elevation for slopes and will also detect non-continuous elevation on edges. | |
163 * | |
164 * Also note that the result of GetSlopeZ() is very special on bridge-ramps. | |
165 */ | |
166 | |
167 byte z = GetSlopeZ(TileX(tile) * TILE_SIZE + min(x_pcp_offsets[PCPpos], TILE_SIZE - 1), TileY(tile) * TILE_SIZE + min(y_pcp_offsets[PCPpos], TILE_SIZE - 1)); | |
168 return (z + 2) & ~3; // this means z = (z + TILE_HEIGHT / 4) / (TILE_HEIGHT / 2) * (TILE_HEIGHT / 2); | |
169 } | |
170 | |
144 /** Draws wires and, if required, pylons on a given tile | 171 /** Draws wires and, if required, pylons on a given tile |
145 * @param ti The Tileinfo to draw the tile for | 172 * @param ti The Tileinfo to draw the tile for |
146 */ | 173 */ |
147 static void DrawCatenaryRailway(const TileInfo *ti) | 174 static void DrawCatenaryRailway(const TileInfo *ti) |
148 { | 175 { |
182 /* Here's one of the main headaches. GetTileSlope does not correct for possibly | 209 /* Here's one of the main headaches. GetTileSlope does not correct for possibly |
183 * existing foundataions, so we do have to do that manually later on.*/ | 210 * existing foundataions, so we do have to do that manually later on.*/ |
184 tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL); | 211 tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL); |
185 trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL); | 212 trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL); |
186 if (IsTunnelTile(neighbour) && i != GetTunnelDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE; | 213 if (IsTunnelTile(neighbour) && i != GetTunnelDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE; |
214 | |
215 /* If the neighboured tile does not smoothly connect to the current tile (because of a foundation), | |
216 * we have to draw all pillars on the current tile. */ | |
217 if (GetPCPElevation(ti->tile, i) != GetPCPElevation(neighbour, ReverseDiagDir(i))) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE; | |
218 | |
187 isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0); | 219 isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0); |
188 | 220 |
189 PPPpreferred[i] = 0xFF; // We start with preferring everything (end-of-line in any direction) | 221 PPPpreferred[i] = 0xFF; // We start with preferring everything (end-of-line in any direction) |
190 PPPallowed[i] = AllowedPPPonPCP[i]; | 222 PPPallowed[i] = AllowedPPPonPCP[i]; |
191 | 223 |
218 | 250 |
219 /* A station is always "flat", so adjust the tileh accordingly */ | 251 /* A station is always "flat", so adjust the tileh accordingly */ |
220 if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; | 252 if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT; |
221 | 253 |
222 /* Read the foundataions if they are present, and adjust the tileh */ | 254 /* Read the foundataions if they are present, and adjust the tileh */ |
223 if (IsTileType(neighbour, MP_RAILWAY) && GetRailType(neighbour) == RAILTYPE_ELECTRIC) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]); | 255 if (trackconfig[TS_NEIGHBOUR] != TRACK_BIT_NONE && IsTileType(neighbour, MP_RAILWAY) && GetRailType(neighbour) == RAILTYPE_ELECTRIC) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]); |
224 if (IsBridgeTile(neighbour)) { | 256 if (IsBridgeTile(neighbour)) { |
225 foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour))); | 257 foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour))); |
226 } | 258 } |
227 | 259 |
228 ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]); | 260 ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]); |
266 /* We have a neighour that will draw it, bail out */ | 298 /* We have a neighour that will draw it, bail out */ |
267 if (trackconfig[TS_NEIGHBOUR] != 0) break; | 299 if (trackconfig[TS_NEIGHBOUR] != 0) break; |
268 continue; /* No neighbour, go looking for a better position */ | 300 continue; /* No neighbour, go looking for a better position */ |
269 } | 301 } |
270 | 302 |
271 AddSortableSpriteToDraw(pylons_normal[temp], PAL_NONE, x, y, 1, 1, 10, | 303 AddSortableSpriteToDraw(pylon_sprites[temp], PAL_NONE, x, y, 1, 1, 10, |
272 GetSlopeZ(ti->x + x_pcp_offsets[i], ti->y + y_pcp_offsets[i]), | 304 GetPCPElevation(ti->tile, i), |
273 HASBIT(_transparent_opt, TO_BUILDINGS)); | 305 HASBIT(_transparent_opt, TO_BUILDINGS)); |
274 break; /* We already have drawn a pylon, bail out */ | 306 break; /* We already have drawn a pylon, bail out */ |
275 } | 307 } |
276 } | 308 } |
277 } | 309 } |
306 | 338 |
307 assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */ | 339 assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */ |
308 assert(!IsSteepSlope(tileh[TS_HOME])); | 340 assert(!IsSteepSlope(tileh[TS_HOME])); |
309 sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]]; | 341 sss = &CatenarySpriteData[Wires[tileh_selector][t][PCPconfig]]; |
310 | 342 |
343 /* | |
344 * The "wire"-sprite position is inside the tile, i.e. 0 <= sss->?_offset < TILE_SIZE. | |
345 * Therefore it is save to use GetSlopeZ() for the elevation. | |
346 * Also note, that the result of GetSlopeZ() is very special for bridge-ramps. | |
347 */ | |
311 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, | 348 AddSortableSpriteToDraw(sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
312 sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + min(sss->x_offset, TILE_SIZE - 1), ti->y + min(sss->y_offset, TILE_SIZE - 1)) + sss->z_offset, | 349 sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + sss->z_offset, |
313 HASBIT(_transparent_opt, TO_BUILDINGS)); | 350 HASBIT(_transparent_opt, TO_BUILDINGS)); |
314 } | 351 } |
315 } | 352 } |
316 } | 353 } |
317 | 354 |
347 ); | 384 ); |
348 | 385 |
349 /* Finished with wires, draw pylons */ | 386 /* Finished with wires, draw pylons */ |
350 /* every other tile needs a pylon on the northern end */ | 387 /* every other tile needs a pylon on the northern end */ |
351 if (num % 2) { | 388 if (num % 2) { |
352 if (axis == AXIS_X) { | 389 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_NE : DIAGDIR_NW); |
353 AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], PAL_NONE, ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); | 390 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
354 } else { | 391 if (HASBIT(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
355 AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], PAL_NONE, ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); | 392 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
356 } | 393 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
394 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); | |
357 } | 395 } |
358 | 396 |
359 /* need a pylon on the southern end of the bridge */ | 397 /* need a pylon on the southern end of the bridge */ |
360 if (DistanceMax(ti->tile, start) == length) { | 398 if (DistanceMax(ti->tile, start) == length) { |
361 if (axis == AXIS_X) { | 399 DiagDirection PCPpos = (axis == AXIS_X ? DIAGDIR_SW : DIAGDIR_SE); |
362 AddSortableSpriteToDraw(pylons_bridge[0 + HASBIT(tlg, 0)], PAL_NONE, ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); | 400 Direction PPPpos = (axis == AXIS_X ? DIR_NW : DIR_NE); |
363 } else { | 401 if (HASBIT(tlg, (axis == AXIS_X ? 0 : 1))) PPPpos = ReverseDir(PPPpos); |
364 AddSortableSpriteToDraw(pylons_bridge[2 + HASBIT(tlg, 1)], PAL_NONE, ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); | 402 uint x = ti->x + x_pcp_offsets[PCPpos] + x_ppp_offsets[PPPpos]; |
365 } | 403 uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos]; |
404 AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, 10, height, HASBIT(_transparent_opt, TO_BUILDINGS)); | |
366 } | 405 } |
367 } | 406 } |
368 | 407 |
369 void DrawCatenary(const TileInfo *ti) | 408 void DrawCatenary(const TileInfo *ti) |
370 { | 409 { |
381 switch (GetTileType(ti->tile)) { | 420 switch (GetTileType(ti->tile)) { |
382 case MP_RAILWAY: | 421 case MP_RAILWAY: |
383 if (IsRailDepot(ti->tile)) { | 422 if (IsRailDepot(ti->tile)) { |
384 const SortableSpriteStruct *sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)]; | 423 const SortableSpriteStruct *sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)]; |
385 | 424 |
425 /* This wire is not visible with the default depot sprites */ | |
386 AddSortableSpriteToDraw( | 426 AddSortableSpriteToDraw( |
387 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, | 427 sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, |
388 sss->x_size, sss->y_size, sss->z_size, | 428 sss->x_size, sss->y_size, sss->z_size, |
389 GetTileMaxZ(ti->tile) + sss->z_offset, | 429 GetTileMaxZ(ti->tile) + sss->z_offset, |
390 HASBIT(_transparent_opt, TO_BUILDINGS) | 430 HASBIT(_transparent_opt, TO_BUILDINGS) |