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)