mirror of https://github.com/OpenTTD/OpenTTD
(svn r2059) -Codechange: rewrote SetSignalsAfterProc so now the tiles from the PF
are checked against the vehicle-position-hash, instead all vehicles to the PF-position-hash. Big speed increase (function usages drops from 9% to 0.5%!) for maps with a lot of trains.release/0.4.5
parent
1eab014524
commit
6d75cce924
89
rail_cmd.c
89
rail_cmd.c
|
@ -1554,47 +1554,80 @@ static bool SetSignalsEnumProc(uint tile, SetSignalsData *ssd, int track, uint l
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Struct to parse data from VehicleFromPos to SignalVehicleCheckProc */
|
||||||
|
typedef struct SignalVehicleCheckStruct {
|
||||||
|
TileIndex tile;
|
||||||
|
uint track;
|
||||||
|
} SignalVehicleCheckStruct;
|
||||||
|
|
||||||
|
static void *SignalVehicleCheckProc(Vehicle *v, void *data)
|
||||||
|
{
|
||||||
|
SignalVehicleCheckStruct *dest = data;
|
||||||
|
TileIndex tile;
|
||||||
|
|
||||||
|
/* Find the tile outside the tunnel, for signalling */
|
||||||
|
if (v->u.rail.track == 0x40) {
|
||||||
|
tile = GetVehicleOutOfTunnelTile(v);
|
||||||
|
} else {
|
||||||
|
tile = v->tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrong tile, or no train? Not a match */
|
||||||
|
if (tile != dest->tile || v->type != VEH_Train)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Are we on the same piece of track? */
|
||||||
|
if (dest->track & (v->u.rail.track + (v->u.rail.track<<8)))
|
||||||
|
return v;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special check for SetSignalsAfterProc, to see if there is a vehicle on this tile */
|
||||||
|
bool SignalVehicleCheck(TileIndex tile, uint track)
|
||||||
|
{
|
||||||
|
SignalVehicleCheckStruct dest;
|
||||||
|
|
||||||
|
dest.tile = tile;
|
||||||
|
dest.track = track;
|
||||||
|
|
||||||
|
return VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void SetSignalsAfterProc(TrackPathFinder *tpf)
|
static void SetSignalsAfterProc(TrackPathFinder *tpf)
|
||||||
{
|
{
|
||||||
SetSignalsData *ssd = tpf->userdata;
|
SetSignalsData *ssd = tpf->userdata;
|
||||||
Vehicle *v;
|
|
||||||
uint tile, hash, val, offs;
|
|
||||||
TrackPathFinderLink *link;
|
TrackPathFinderLink *link;
|
||||||
|
uint offs;
|
||||||
|
uint i;
|
||||||
|
|
||||||
ssd->stop = false;
|
ssd->stop = false;
|
||||||
|
|
||||||
// for each train, check if it is in the segment.
|
/* Go through all the PF tiles */
|
||||||
// then we know that the signal should be red.
|
for (i = 0; i < lengthof(tpf->hash_head); i++) {
|
||||||
FOR_ALL_VEHICLES(v) {
|
/* Empty hash item */
|
||||||
if (v->type != VEH_Train)
|
if (tpf->hash_head[i] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tile = v->tile;
|
/* If 0x8000 is not set, there is only 1 item */
|
||||||
if (v->u.rail.track == 0x40) { tile = GetVehicleOutOfTunnelTile(v); }
|
if (!(tpf->hash_head[i] & 0x8000)) {
|
||||||
|
/* Check if there is a vehicle on this tile */
|
||||||
hash = PATHFIND_HASH_TILE(tile);
|
if (SignalVehicleCheck(tpf->hash_tile[i], tpf->hash_head[i])) {
|
||||||
|
ssd->stop = true;
|
||||||
val = tpf->hash_head[hash];
|
return;
|
||||||
if (val == 0)
|
}
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(val & 0x8000)) {
|
|
||||||
if ((TileIndex)tile == tpf->hash_tile[hash])
|
|
||||||
goto check_val;
|
|
||||||
} else {
|
} else {
|
||||||
offs = tpf->hash_tile[hash];
|
/* There are multiple items, where hash_tile points to the first item in the list */
|
||||||
|
offs = tpf->hash_tile[i];
|
||||||
do {
|
do {
|
||||||
|
/* Find the next item */
|
||||||
link = PATHFIND_GET_LINK_PTR(tpf, offs);
|
link = PATHFIND_GET_LINK_PTR(tpf, offs);
|
||||||
if ( (TileIndex)tile == link->tile) {
|
/* Check if there is a vehicle on this tile */
|
||||||
val = link->flags;
|
if (SignalVehicleCheck(link->tile, link->flags)) {
|
||||||
check_val:;
|
ssd->stop = true;
|
||||||
// the train is on the track, in either direction?
|
return;
|
||||||
if (val & (v->u.rail.track + (v->u.rail.track<<8))) {
|
|
||||||
ssd->stop = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
/* Goto the next item */
|
||||||
} while ((offs=link->next) != 0xFFFF);
|
} while ((offs=link->next) != 0xFFFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue