|
@@ -110,48 +110,49 @@ static const byte _tpf_prev_direction[14
|
|
|
0,1,1,0,1,2, 0,0,
|
|
|
2,3,2,3,0,3,
|
|
|
};
|
|
|
|
|
|
|
|
|
static const byte _otherdir_mask[4] = {
|
|
|
0x10,
|
|
|
0,
|
|
|
0x5,
|
|
|
0x2A,
|
|
|
};
|
|
|
|
|
|
#ifdef DEBUG_TILE_PUSH
|
|
|
extern void dbg_push_tile(TileIndex tile, int track);
|
|
|
extern void dbg_pop_tile();
|
|
|
#endif
|
|
|
|
|
|
static void TPFMode2(TrackPathFinder *tpf, TileIndex tile, int direction)
|
|
|
{
|
|
|
uint bits;
|
|
|
int i;
|
|
|
RememberData rd;
|
|
|
int owner = -1;
|
|
|
|
|
|
/* XXX: Mode 2 is currently only used for ships, why is this code here? */
|
|
|
if (tpf->tracktype == TRANSPORT_RAIL) {
|
|
|
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE)) {
|
|
|
owner = GetTileOwner(tile);
|
|
|
/* Check if we are on the middle of a bridge (has no owner) */
|
|
|
if (IsTileType(tile, MP_TUNNELBRIDGE) && (_map5[tile] & 0xC0) == 0xC0)
|
|
|
owner = -1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// This addition will sometimes overflow by a single tile.
|
|
|
// The use of TILE_MASK here makes sure that we still point at a valid
|
|
|
// tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail.
|
|
|
tile = TILE_MASK(tile + TileOffsByDir(direction));
|
|
|
|
|
|
/* Check in case of rail if the owner is the same */
|
|
|
if (tpf->tracktype == TRANSPORT_RAIL) {
|
|
|
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
|
|
|
/* Check if we are on the middle of a bridge (has no owner) */
|
|
|
if (!IsTileType(tile, MP_TUNNELBRIDGE) || (_map5[tile] & 0xC0) != 0xC0)
|
|
|
if (owner != -1 && !IsTileOwner(tile, owner))
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (++tpf->rd.cur_length > 50)
|
|
@@ -319,48 +320,52 @@ static void TPFMode1(TrackPathFinder *tp
|
|
|
|
|
|
tpf->the_dir = (_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i;
|
|
|
rd = tpf->rd;
|
|
|
|
|
|
#ifdef DEBUG_TILE_PUSH
|
|
|
dbg_push_tile(tile, tpf->the_dir);
|
|
|
#endif
|
|
|
if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
|
|
|
!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
|
|
|
TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]);
|
|
|
}
|
|
|
#ifdef DEBUG_TILE_PUSH
|
|
|
dbg_pop_tile();
|
|
|
#endif
|
|
|
tpf->rd = rd;
|
|
|
} while (bits != 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* the next is only used when signals are checked.
|
|
|
* seems to go in 2 directions simultaneously */
|
|
|
|
|
|
/* if i can get rid of this, tail end recursion can be used to minimize
|
|
|
* stack space dramatically. */
|
|
|
|
|
|
/* If we are doing signal setting, we must reverse at evere tile, so we
|
|
|
* iterate all the tracks in a signal block, even when a normal train would
|
|
|
* not reach it (for example, when two lines merge */
|
|
|
if (tpf->hasbit_13)
|
|
|
return;
|
|
|
|
|
|
tile = tile_org;
|
|
|
direction ^= 2;
|
|
|
|
|
|
bits = GetTileTrackStatus(tile, tpf->tracktype);
|
|
|
bits |= (bits >> 8);
|
|
|
|
|
|
if ( (byte)bits != tpf->var2) {
|
|
|
bits &= _bits_mask[direction];
|
|
|
}
|
|
|
|
|
|
bits &= 0xBF;
|
|
|
if (bits == 0)
|
|
|
return;
|
|
|
|
|
|
do {
|
|
|
i = FIND_FIRST_BIT(bits);
|
|
|
bits = KILL_FIRST_BIT(bits);
|
|
|
|
|
|
tpf->the_dir = (_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i;
|
|
|
rd = tpf->rd;
|
|
|
if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
|