Reduce screen re-draw area for tunnel/bridge end signal updates
This commit is contained in:
@@ -478,6 +478,7 @@ static inline Money SignalMaintenanceCost(uint32 num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MarkSingleSignalDirty(TileIndex tile, Trackdir td);
|
void MarkSingleSignalDirty(TileIndex tile, Trackdir td);
|
||||||
|
void MarkSingleSignalDirtyAtZ(TileIndex tile, Trackdir td, uint z);
|
||||||
|
|
||||||
void DrawTrainDepotSprite(int x, int y, int image, RailType railtype);
|
void DrawTrainDepotSprite(int x, int y, int image, RailType railtype);
|
||||||
int TicksToLeaveDepot(const Train *v);
|
int TicksToLeaveDepot(const Train *v);
|
||||||
|
@@ -2766,13 +2766,9 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac
|
|||||||
DrawSingleSignal(tile, rti, track, condition, image, pos, type, variant, show_restricted);
|
DrawSingleSignal(tile, rti, track, condition, image, pos, type, variant, show_restricted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkSingleSignalDirty(TileIndex tile, Trackdir td)
|
template <typename F>
|
||||||
|
void MarkSingleSignalDirtyIntl(TileIndex tile, Trackdir td, F get_z)
|
||||||
{
|
{
|
||||||
if (_signal_sprite_oversized || td >= TRACKDIR_END) {
|
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint8 trackdir_to_pos[TRACKDIR_END] = {
|
static const uint8 trackdir_to_pos[TRACKDIR_END] = {
|
||||||
8, // TRACKDIR_X_NE
|
8, // TRACKDIR_X_NE
|
||||||
10, // TRACKDIR_Y_SE
|
10, // TRACKDIR_Y_SE
|
||||||
@@ -2794,7 +2790,7 @@ void MarkSingleSignalDirty(TileIndex tile, Trackdir td)
|
|||||||
|
|
||||||
uint x, y;
|
uint x, y;
|
||||||
GetSignalXY(tile, trackdir_to_pos[td], x, y);
|
GetSignalXY(tile, trackdir_to_pos[td], x, y);
|
||||||
Point pt = RemapCoords(x, y, GetSaveSlopeZ(x, y, TrackdirToTrack(td)));
|
Point pt = RemapCoords(x, y, get_z(x, y));
|
||||||
MarkAllViewportsDirty(
|
MarkAllViewportsDirty(
|
||||||
pt.x - SIGNAL_DIRTY_LEFT,
|
pt.x - SIGNAL_DIRTY_LEFT,
|
||||||
pt.y - SIGNAL_DIRTY_TOP,
|
pt.y - SIGNAL_DIRTY_TOP,
|
||||||
@@ -2804,6 +2800,25 @@ void MarkSingleSignalDirty(TileIndex tile, Trackdir td)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MarkSingleSignalDirty(TileIndex tile, Trackdir td)
|
||||||
|
{
|
||||||
|
if (_signal_sprite_oversized || td >= TRACKDIR_END) {
|
||||||
|
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MarkSingleSignalDirtyIntl(tile, td, [td](uint x, uint y) -> uint {
|
||||||
|
return GetSaveSlopeZ(x, y, TrackdirToTrack(td));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkSingleSignalDirtyAtZ(TileIndex tile, Trackdir td, uint z)
|
||||||
|
{
|
||||||
|
MarkSingleSignalDirtyIntl(tile, td, [z](uint x, uint y) -> uint {
|
||||||
|
return z;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static uint32 _drawtile_track_palette;
|
static uint32 _drawtile_track_palette;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -720,7 +720,7 @@ static void UpdateSignalsAroundSegment(SigInfo info)
|
|||||||
uint8 aspect = GetForwardAspectAndIncrement(info, tile, exit_td);
|
uint8 aspect = GetForwardAspectAndIncrement(info, tile, exit_td);
|
||||||
if (aspect != GetTunnelBridgeExitSignalAspect(tile)) {
|
if (aspect != GetTunnelBridgeExitSignalAspect(tile)) {
|
||||||
SetTunnelBridgeExitSignalAspect(tile, aspect);
|
SetTunnelBridgeExitSignalAspect(tile, aspect);
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
MarkTunnelBridgeSignalDirty(tile, true);
|
||||||
PropagateAspectChange(tile, exit_td, aspect);
|
PropagateAspectChange(tile, exit_td, aspect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -748,7 +748,7 @@ static void UpdateSignalsAroundSegment(SigInfo info)
|
|||||||
PropagateAspectChange(tile, exit_td, aspect);
|
PropagateAspectChange(tile, exit_td, aspect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (refresh) MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
if (refresh) MarkTunnelBridgeSignalDirty(tile, true);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -857,7 +857,7 @@ static void UpdateSignalsAroundSegment(SigInfo info)
|
|||||||
uint8 old_aspect = GetTunnelBridgeExitSignalAspect(tile);
|
uint8 old_aspect = GetTunnelBridgeExitSignalAspect(tile);
|
||||||
if (aspect != old_aspect) {
|
if (aspect != old_aspect) {
|
||||||
SetTunnelBridgeExitSignalAspect(tile, aspect);
|
SetTunnelBridgeExitSignalAspect(tile, aspect);
|
||||||
if (old_aspect != 0) MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
if (old_aspect != 0) MarkTunnelBridgeSignalDirty(tile, true);
|
||||||
PropagateAspectChange(tile, trackdir, aspect);
|
PropagateAspectChange(tile, trackdir, aspect);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1358,7 +1358,7 @@ void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect)
|
|||||||
if (!IsTunnelBridgeSignalSimulationExit(tile) || GetTunnelBridgeExitSignalState(tile) != SIGNAL_STATE_GREEN) return;
|
if (!IsTunnelBridgeSignalSimulationExit(tile) || GetTunnelBridgeExitSignalState(tile) != SIGNAL_STATE_GREEN) return;
|
||||||
if (GetTunnelBridgeExitSignalAspect(tile) == aspect) return;
|
if (GetTunnelBridgeExitSignalAspect(tile) == aspect) return;
|
||||||
SetTunnelBridgeExitSignalAspect(tile, aspect);
|
SetTunnelBridgeExitSignalAspect(tile, aspect);
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
MarkTunnelBridgeSignalDirty(tile, true);
|
||||||
if (IsBridge(tile)) RefreshBridgeOnExitAspectChange(other, tile);
|
if (IsBridge(tile)) RefreshBridgeOnExitAspectChange(other, tile);
|
||||||
aspect = std::min<uint>(GetSignalledTunnelBridgeEntranceForwardAspect(other, tile) + 1, _extra_aspects + 1);
|
aspect = std::min<uint>(GetSignalledTunnelBridgeEntranceForwardAspect(other, tile) + 1, _extra_aspects + 1);
|
||||||
}
|
}
|
||||||
@@ -1372,7 +1372,7 @@ void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect)
|
|||||||
if (!IsTunnelBridgeSignalSimulationEntrance(tile) || GetTunnelBridgeEntranceSignalState(tile) != SIGNAL_STATE_GREEN) return;
|
if (!IsTunnelBridgeSignalSimulationEntrance(tile) || GetTunnelBridgeEntranceSignalState(tile) != SIGNAL_STATE_GREEN) return;
|
||||||
if (GetTunnelBridgeEntranceSignalAspect(tile) == aspect) return;
|
if (GetTunnelBridgeEntranceSignalAspect(tile) == aspect) return;
|
||||||
SetTunnelBridgeEntranceSignalAspect(tile, aspect);
|
SetTunnelBridgeEntranceSignalAspect(tile, aspect);
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
MarkTunnelBridgeSignalDirty(tile, false);
|
||||||
aspect = std::min<uint>(aspect + 1, _extra_aspects + 1);
|
aspect = std::min<uint>(aspect + 1, _extra_aspects + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3365,7 +3365,7 @@ static void UpdateTunnelBridgeEntranceSignalAspect(TileIndex tile)
|
|||||||
uint8 old_aspect = GetTunnelBridgeEntranceSignalAspect(tile);
|
uint8 old_aspect = GetTunnelBridgeEntranceSignalAspect(tile);
|
||||||
if (aspect != old_aspect) {
|
if (aspect != old_aspect) {
|
||||||
SetTunnelBridgeEntranceSignalAspect(tile, aspect);
|
SetTunnelBridgeEntranceSignalAspect(tile, aspect);
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
MarkTunnelBridgeSignalDirty(tile, false);
|
||||||
PropagateAspectChange(tile, trackdir, aspect);
|
PropagateAspectChange(tile, trackdir, aspect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3374,7 +3374,7 @@ static void SetTunnelBridgeEntranceSignalGreen(TileIndex tile)
|
|||||||
{
|
{
|
||||||
if (GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
|
if (GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
|
||||||
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
|
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
MarkTunnelBridgeSignalDirty(tile, false);
|
||||||
if (_extra_aspects > 0) {
|
if (_extra_aspects > 0) {
|
||||||
SetTunnelBridgeEntranceSignalAspect(tile, 0);
|
SetTunnelBridgeEntranceSignalAspect(tile, 0);
|
||||||
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile));
|
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile));
|
||||||
|
@@ -17,6 +17,8 @@ uint GetTunnelBridgeSignalSimulationSpacingTarget(Owner owner);
|
|||||||
uint GetBestTunnelBridgeSignalSimulationSpacing(Owner owner, TileIndex begin, TileIndex end);
|
uint GetBestTunnelBridgeSignalSimulationSpacing(Owner owner, TileIndex begin, TileIndex end);
|
||||||
uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end);
|
uint GetTunnelBridgeSignalSimulationSignalCount(TileIndex begin, TileIndex end);
|
||||||
|
|
||||||
|
void MarkTunnelBridgeSignalDirty(TileIndex tile, bool exit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the length of a tunnel or a bridge (without end tiles)
|
* Calculates the length of a tunnel or a bridge (without end tiles)
|
||||||
* @param begin The begin of the tunnel or bridge.
|
* @param begin The begin of the tunnel or bridge.
|
||||||
|
@@ -1894,6 +1894,65 @@ void MarkSingleBridgeSignalDirty(TileIndex tile, TileIndex bridge_start_tile)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MarkTunnelBridgeSignalDirty(TileIndex tile, bool exit)
|
||||||
|
{
|
||||||
|
if (_signal_sprite_oversized) {
|
||||||
|
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsRailCustomBridgeHeadTile(tile)) {
|
||||||
|
Trackdir td = exit ? GetTunnelBridgeExitTrackdir(tile) : GetTunnelBridgeEntranceTrackdir(tile);
|
||||||
|
MarkSingleSignalDirtyAtZ(tile, td, GetTileMaxPixelZ(tile));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side;
|
||||||
|
DiagDirection dir = GetTunnelBridgeDirection(tile);
|
||||||
|
|
||||||
|
uint position;
|
||||||
|
switch (dir) {
|
||||||
|
default: NOT_REACHED();
|
||||||
|
case DIAGDIR_NE: position = 0; break;
|
||||||
|
case DIAGDIR_SE: position = 2; break;
|
||||||
|
case DIAGDIR_SW: position = 1; break;
|
||||||
|
case DIAGDIR_NW: position = 3; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Point SignalPositions[2][4] = {
|
||||||
|
{ /* X X Y Y Signals on the left side */
|
||||||
|
{13, 3}, { 2, 13}, { 3, 4}, {13, 14}
|
||||||
|
}, {/* X X Y Y Signals on the right side */
|
||||||
|
{14, 13}, { 3, 3}, {13, 2}, { 3, 13}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint x = TileX(tile) * TILE_SIZE + SignalPositions[side != exit][position].x;
|
||||||
|
uint y = TileY(tile) * TILE_SIZE + SignalPositions[side != exit][position].y;
|
||||||
|
|
||||||
|
int z;
|
||||||
|
if (IsTunnel(tile)) {
|
||||||
|
z = GetTileZ(tile) * TILE_HEIGHT;
|
||||||
|
} else {
|
||||||
|
Slope slope = GetTilePixelSlope(tile, &z);
|
||||||
|
if (slope == SLOPE_FLAT) {
|
||||||
|
if (side == exit && dir == DIAGDIR_SE) z += 2;
|
||||||
|
if (side != exit && dir == DIAGDIR_SW) z += 2;
|
||||||
|
} else {
|
||||||
|
z += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Point pt = RemapCoords(x, y, z);
|
||||||
|
MarkAllViewportsDirty(
|
||||||
|
pt.x - SIGNAL_DIRTY_LEFT,
|
||||||
|
pt.y - SIGNAL_DIRTY_TOP,
|
||||||
|
pt.x + SIGNAL_DIRTY_RIGHT,
|
||||||
|
pt.y + SIGNAL_DIRTY_BOTTOM,
|
||||||
|
VMDF_NOT_MAP_MODE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a tunnel of bridge tile.
|
* Draws a tunnel of bridge tile.
|
||||||
* For tunnels, this is rather simple, as you only need to draw the entrance.
|
* For tunnels, this is rather simple, as you only need to draw the entrance.
|
||||||
|
Reference in New Issue
Block a user