Reduce viewport invalidation area of signal state changes
This commit is contained in:
@@ -84,6 +84,7 @@ bool TryReserveRailTrackdir(TileIndex tile, Trackdir td, bool trigger_stations)
|
||||
bool success = TryReserveRailTrack(tile, TrackdirToTrack(td), trigger_stations);
|
||||
if (success && HasPbsSignalOnTrackdir(tile, td)) {
|
||||
SetSignalStateByTrackdir(tile, td, SIGNAL_STATE_GREEN);
|
||||
MarkSingleSignalDirty(tile, td);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@@ -183,6 +184,7 @@ void UnreserveRailTrackdir(TileIndex tile, Trackdir td)
|
||||
{
|
||||
if (HasPbsSignalOnTrackdir(tile, td)) {
|
||||
SetSignalStateByTrackdir(tile, td, SIGNAL_STATE_RED);
|
||||
MarkSingleSignalDirty(tile, td);
|
||||
}
|
||||
UnreserveRailTrack(tile, TrackdirToTrack(td));
|
||||
}
|
||||
|
@@ -456,6 +456,8 @@ static inline Money SignalMaintenanceCost(uint32 num)
|
||||
return (_price[PR_INFRASTRUCTURE_RAIL] * 15 * num * (1 + IntSqrt(num))) >> 8; // 1 bit fraction for the multiplier and 7 bits scaling.
|
||||
}
|
||||
|
||||
void MarkSingleSignalDirty(TileIndex tile, Trackdir td);
|
||||
|
||||
void DrawTrainDepotSprite(int x, int y, int image, RailType railtype);
|
||||
int TicksToLeaveDepot(const Train *v);
|
||||
|
||||
|
@@ -2379,7 +2379,7 @@ static uint GetSaveSlopeZ(uint x, uint y, Track track)
|
||||
return GetSlopePixelZ(x, y);
|
||||
}
|
||||
|
||||
void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, SignalState condition, SignalOffsets image, uint pos, SignalType type, SignalVariant variant, bool show_restricted)
|
||||
static void GetSignalXY(TileIndex tile, uint pos, uint &x, uint &y)
|
||||
{
|
||||
bool side;
|
||||
switch (_settings_game.construction.train_signal_side) {
|
||||
@@ -2401,8 +2401,21 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign
|
||||
}
|
||||
};
|
||||
|
||||
uint x = TileX(tile) * TILE_SIZE + SignalPositions[side][pos].x;
|
||||
uint y = TileY(tile) * TILE_SIZE + SignalPositions[side][pos].y;
|
||||
x = TileX(tile) * TILE_SIZE + SignalPositions[side][pos].x;
|
||||
y = TileY(tile) * TILE_SIZE + SignalPositions[side][pos].y;
|
||||
}
|
||||
|
||||
static bool _signal_sprite_oversized = false;
|
||||
|
||||
static const int SIGNAL_DIRTY_LEFT = 7 * ZOOM_LVL_BASE;
|
||||
static const int SIGNAL_DIRTY_RIGHT = 7 * ZOOM_LVL_BASE;
|
||||
static const int SIGNAL_DIRTY_TOP = 30 * ZOOM_LVL_BASE;
|
||||
static const int SIGNAL_DIRTY_BOTTOM = 5 * ZOOM_LVL_BASE;
|
||||
|
||||
void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, SignalState condition, SignalOffsets image, uint pos, SignalType type, SignalVariant variant, bool show_restricted)
|
||||
{
|
||||
uint x, y;
|
||||
GetSignalXY(tile, pos, x, y);
|
||||
|
||||
SpriteID sprite;
|
||||
bool is_custom_sprite;
|
||||
@@ -2457,6 +2470,10 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign
|
||||
} else {
|
||||
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track));
|
||||
}
|
||||
const Sprite *sp = GetSprite(sprite, ST_NORMAL);
|
||||
if (sp->x_offs < -SIGNAL_DIRTY_LEFT || sp->x_offs + sp->width > SIGNAL_DIRTY_RIGHT || sp->y_offs < -SIGNAL_DIRTY_TOP || sp->y_offs + sp->height > SIGNAL_DIRTY_BOTTOM) {
|
||||
_signal_sprite_oversized = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, SignalState condition, SignalOffsets image, uint pos)
|
||||
@@ -2468,6 +2485,44 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac
|
||||
DrawSingleSignal(tile, rti, track, condition, image, pos, type, variant, show_restricted);
|
||||
}
|
||||
|
||||
void MarkSingleSignalDirty(TileIndex tile, Trackdir td)
|
||||
{
|
||||
if (_signal_sprite_oversized || td >= TRACKDIR_END) {
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
return;
|
||||
}
|
||||
|
||||
static const uint8 trackdir_to_pos[TRACKDIR_END] = {
|
||||
8, // TRACKDIR_X_NE
|
||||
10, // TRACKDIR_Y_SE
|
||||
4, // TRACKDIR_UPPER_E
|
||||
6, // TRACKDIR_LOWER_E
|
||||
0, // TRACKDIR_LEFT_S
|
||||
2, // TRACKDIR_RIGHT_S
|
||||
0, // TRACKDIR_RVREV_NE
|
||||
0, // TRACKDIR_RVREV_SE
|
||||
9, // TRACKDIR_X_SW
|
||||
11, // TRACKDIR_Y_NW
|
||||
5, // TRACKDIR_UPPER_W
|
||||
7, // TRACKDIR_LOWER_W
|
||||
1, // TRACKDIR_LEFT_N
|
||||
3, // TRACKDIR_RIGHT_N
|
||||
0, // TRACKDIR_RVREV_SW
|
||||
0, // TRACKDIR_RVREV_NW
|
||||
};
|
||||
|
||||
uint x, y;
|
||||
GetSignalXY(tile, trackdir_to_pos[td], x, y);
|
||||
Point pt = RemapCoords(x, y, GetSaveSlopeZ(x, y, TrackdirToTrack(td)));
|
||||
MarkAllViewportsDirty(
|
||||
pt.x - SIGNAL_DIRTY_LEFT,
|
||||
pt.y - SIGNAL_DIRTY_TOP,
|
||||
pt.x + SIGNAL_DIRTY_RIGHT,
|
||||
pt.y + SIGNAL_DIRTY_BOTTOM,
|
||||
ZOOM_LVL_DRAW_MAP
|
||||
);
|
||||
}
|
||||
|
||||
static uint32 _drawtile_track_palette;
|
||||
|
||||
|
||||
|
@@ -583,7 +583,7 @@ static void UpdateSignalsAroundSegment(SigInfo info)
|
||||
MarkDependencidesForUpdate(SignalReference(tile, track));
|
||||
}
|
||||
SetSignalStateByTrackdir(tile, trackdir, newstate);
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
MarkSingleSignalDirty(tile, trackdir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2822,7 +2822,7 @@ void FreeTrainTrackReservation(const Train *v, TileIndex origin, Trackdir orig_t
|
||||
} else {
|
||||
/* Turn the signal back to red. */
|
||||
SetSignalStateByTrackdir(tile, td, SIGNAL_STATE_RED);
|
||||
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
MarkSingleSignalDirty(tile, td);
|
||||
}
|
||||
} else if (HasSignalOnTrackdir(tile, ReverseTrackdir(td)) && IsOnewaySignal(tile, TrackdirToTrack(td))) {
|
||||
break;
|
||||
@@ -3105,7 +3105,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
{
|
||||
Track best_track = INVALID_TRACK;
|
||||
bool do_track_reservation = _settings_game.pf.reserve_paths || force_res;
|
||||
bool changed_signal = false;
|
||||
Trackdir changed_signal = INVALID_TRACKDIR;
|
||||
|
||||
assert((tracks & ~TRACK_BIT_MASK) == 0);
|
||||
|
||||
@@ -3138,8 +3138,8 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
ClrBit(v->flags, VRF_WAITING_RESTRICTION);
|
||||
|
||||
do_track_reservation = true;
|
||||
changed_signal = true;
|
||||
SetSignalStateByTrackdir(tile, TrackEnterdirToTrackdir(track, enterdir), SIGNAL_STATE_GREEN);
|
||||
changed_signal = TrackEnterdirToTrackdir(track, enterdir);
|
||||
SetSignalStateByTrackdir(tile, changed_signal, SIGNAL_STATE_GREEN);
|
||||
} else if (!do_track_reservation) {
|
||||
return track;
|
||||
}
|
||||
@@ -3154,7 +3154,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
if (res_dest.tile == INVALID_TILE) {
|
||||
/* Reservation failed? */
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
if (changed_signal) SetSignalStateByTrackdir(tile, TrackEnterdirToTrackdir(best_track, enterdir), SIGNAL_STATE_RED);
|
||||
if (changed_signal != INVALID_TRACKDIR) SetSignalStateByTrackdir(tile, changed_signal, SIGNAL_STATE_RED);
|
||||
return FindFirstTrack(tracks);
|
||||
}
|
||||
if (res_dest.okay) {
|
||||
@@ -3165,7 +3165,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
if (!HasLongReservePbsSignalOnTrackdir(v, ft.m_new_tile, new_td)) {
|
||||
/* Got a valid reservation that ends at a safe target, quick exit. */
|
||||
if (p_got_reservation != nullptr) *p_got_reservation = true;
|
||||
if (changed_signal) MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
if (changed_signal != INVALID_TRACKDIR) MarkSingleSignalDirty(tile, changed_signal);
|
||||
TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
|
||||
return best_track;
|
||||
}
|
||||
@@ -3227,7 +3227,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
best_track = FindFirstTrack(res);
|
||||
TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
|
||||
if (p_got_reservation != nullptr) *p_got_reservation = true;
|
||||
if (changed_signal) MarkTileDirtyByTile(tile);
|
||||
if (changed_signal != INVALID_TRACKDIR) MarkSingleSignalDirty(tile, changed_signal);
|
||||
} else {
|
||||
FreeTrainTrackReservation(v, origin.tile, origin.trackdir);
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
@@ -3259,7 +3259,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
FreeTrainTrackReservation(v, origin.tile, origin.trackdir);
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
got_reservation = false;
|
||||
changed_signal = false;
|
||||
changed_signal = INVALID_TRACKDIR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3268,7 +3268,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
FreeTrainTrackReservation(v, origin.tile, origin.trackdir);
|
||||
if (mark_stuck) MarkTrainAsStuck(v);
|
||||
got_reservation = false;
|
||||
changed_signal = false;
|
||||
changed_signal = INVALID_TRACKDIR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3287,7 +3287,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
|
||||
|
||||
TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
|
||||
|
||||
if (changed_signal) MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
|
||||
if (changed_signal != INVALID_TRACKDIR) MarkSingleSignalDirty(tile, changed_signal);
|
||||
if (p_got_reservation != nullptr) *p_got_reservation = got_reservation;
|
||||
|
||||
return best_track;
|
||||
@@ -4224,7 +4224,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
||||
Trackdir tdir = TrackDirectionToTrackdir(track, chosen_dir);
|
||||
if (v->IsFrontEngine() && HasPbsSignalOnTrackdir(gp.new_tile, tdir)) {
|
||||
SetSignalStateByTrackdir(gp.new_tile, tdir, SIGNAL_STATE_RED);
|
||||
MarkTileDirtyByTile(gp.new_tile);
|
||||
MarkSingleSignalDirty(gp.new_tile, tdir);
|
||||
}
|
||||
|
||||
/* Clear any track reservation when the last vehicle leaves the tile */
|
||||
|
Reference in New Issue
Block a user