Reduce viewport invalidation area of signal state changes

pull/132/head
Jonathan G Rennison 4 years ago
parent b9eaef9fe1
commit 5240b46d1d

@ -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 */

Loading…
Cancel
Save