Add signal style flag for drawing on the opposite side

This commit is contained in:
Jonathan G Rennison
2022-06-22 23:45:44 +01:00
parent ff064e06b8
commit fcae909839
12 changed files with 96 additions and 33 deletions

View File

@@ -512,6 +512,11 @@ item (FEAT_GLOBALVARS) {
The value is clamped to be less than or equal to the value set in the <span class="code">extra_aspects</span> property. The value is clamped to be less than or equal to the value set in the <span class="code">extra_aspects</span> property.
</td> </td>
</tr> </tr>
<tr><td>style_opposite_side</td><td>0 or 1</td>
<td>
Set whether signals should be drawn on the opposite side of the track for the most recently defined style (defined using the <span class="code">define_style</span> property).
</td>
</tr>
<tr><td>no_default_style</td><td>0 or 1</td> <tr><td>no_default_style</td><td>0 or 1</td>
<td> <td>
When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style

View File

@@ -480,6 +480,13 @@
The Action 0 Id field is not used, the value is ignored. The Action 0 Id field is not used, the value is ignored.
</p> </p>
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p> <p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p>
<h4 id="signals_style_opposite_side">Set custom signal style signal drawn on opposite side (mappable property: signals_style_opposite_side)</h4>
<p>This applies to the most recent custom signal style defined using the <a href="#signals_define_style">signals_define_style</a> property.<br />
When enabled, signals using this style are drawn on the opposite side of the track.</p>
<p>The property length is 1 byte. 0 is disabled (default). 1 is enabled.<br />
The Action 0 Id field is not used, the value is ignored.
</p>
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p>
<h4 id="signals_no_default_style">Set whether custom signal sprites should not be used for the default signal style (mappable property: signals_no_default_style)</h4> <h4 id="signals_no_default_style">Set whether custom signal sprites should not be used for the default signal style (mappable property: signals_no_default_style)</h4>
<p>This applies to <a href="#a3signals_custom_signal_sprites">Action 2/3 Signals (Feature 0E) custom signal sprites</a> for this GRF.<br /> <p>This applies to <a href="#a3signals_custom_signal_sprites">Action 2/3 Signals (Feature 0E) custom signal sprites</a> for this GRF.<br />
When enabled, this GRF is not used for the default signal style, it is only used for custom signal styles defined with <a href="#signals_define_style">signals_define_style</a>.</p> When enabled, this GRF is not used for the default signal style, it is only used for custom signal styles defined with <a href="#signals_define_style">signals_define_style</a>.</p>

View File

@@ -4271,6 +4271,15 @@ static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const
break; break;
} }
case A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE: {
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
uint8 value = buf->ReadByte();
if (_cur.grffile->current_new_signal_style != nullptr) {
SB(_cur.grffile->current_new_signal_style->style_flags, NSSF_OPPOSITE_SIDE, 1, (value != 0 ? 1 : 0));
}
break;
}
default: default:
ret = HandleAction0PropertyDefault(buf, prop); ret = HandleAction0PropertyDefault(buf, prop);
break; break;

View File

@@ -99,6 +99,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = {
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS, "signals_style_lookahead_extra_aspects"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS, "signals_style_lookahead_extra_aspects"),
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED, "signals_style_semaphore_enabled"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED, "signals_style_semaphore_enabled"),
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, "signals_style_electric_enabled"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, "signals_style_electric_enabled"),
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE, "signals_style_opposite_side"),
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_USE_LAND_GROUND, "object_use_land_ground"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_USE_LAND_GROUND, "object_use_land_ground"),
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"),
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"),

View File

@@ -43,6 +43,7 @@ enum Action0RemapPropertyIds {
A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS, A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS,
A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED, A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED,
A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED,
A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE,
A0RPI_OBJECT_USE_LAND_GROUND, A0RPI_OBJECT_USE_LAND_GROUND,
A0RPI_OBJECT_EDGE_FOUNDATION_MODE, A0RPI_OBJECT_EDGE_FOUNDATION_MODE,
A0RPI_OBJECT_FLOOD_RESISTANT, A0RPI_OBJECT_FLOOD_RESISTANT,

View File

@@ -28,6 +28,7 @@ enum NewSignalStyleFlags {
NSSF_NO_ASPECT_INC = 0, NSSF_NO_ASPECT_INC = 0,
NSSF_ALWAYS_RESERVE_THROUGH = 1, NSSF_ALWAYS_RESERVE_THROUGH = 1,
NSSF_LOOKAHEAD_ASPECTS_SET = 2, NSSF_LOOKAHEAD_ASPECTS_SET = 2,
NSSF_OPPOSITE_SIDE = 3,
}; };
struct NewSignalStyle { struct NewSignalStyle {

View File

@@ -479,7 +479,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 MarkSingleSignalDirtyAtZ(TileIndex tile, Trackdir td, bool opposite_side, 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);

View File

@@ -2763,7 +2763,7 @@ static uint GetSaveSlopeZ(uint x, uint y, Track track)
return GetSlopePixelZ(x, y); return GetSlopePixelZ(x, y);
} }
static void GetSignalXY(TileIndex tile, uint pos, uint &x, uint &y) static void GetSignalXY(TileIndex tile, uint pos, bool opposite, uint &x, uint &y)
{ {
bool side; bool side;
switch (_settings_game.construction.train_signal_side) { switch (_settings_game.construction.train_signal_side) {
@@ -2771,6 +2771,7 @@ static void GetSignalXY(TileIndex tile, uint pos, uint &x, uint &y)
case 2: side = true; break; // right case 2: side = true; break; // right
default: side = _settings_game.vehicle.road_side != 0; break; // driving side default: side = _settings_game.vehicle.road_side != 0; break; // driving side
} }
side ^= opposite;
static const Point SignalPositions[2][12] = { static const Point SignalPositions[2][12] = {
{ // Signals on the left side { // Signals on the left side
/* LEFT LEFT RIGHT RIGHT UPPER UPPER */ /* LEFT LEFT RIGHT RIGHT UPPER UPPER */
@@ -2796,8 +2797,25 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign
if (type == SIGTYPE_NO_ENTRY) pos ^= 1; if (type == SIGTYPE_NO_ENTRY) pos ^= 1;
uint8 style = 0;
if (_num_new_signal_styles > 0) {
switch (context) {
case CSSC_TRACK:
style = GetSignalStyle(tile, track);
break;
case CSSC_TUNNEL_BRIDGE_ENTRANCE:
case CSSC_TUNNEL_BRIDGE_EXIT:
style = GetTunnelBridgeSignalStyle(tile);
break;
default:
break;
}
}
uint x, y; uint x, y;
GetSignalXY(tile, pos, x, y); GetSignalXY(tile, pos, HasBit(_signal_opposite_side_style_mask, style), x, y);
uint8 aspect; uint8 aspect;
if (condition == SIGNAL_STATE_GREEN) { if (condition == SIGNAL_STATE_GREEN) {
@@ -2824,23 +2842,6 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign
aspect = 0; aspect = 0;
} }
uint8 style = 0;
if (_num_new_signal_styles > 0) {
switch (context) {
case CSSC_TRACK:
style = GetSignalStyle(tile, track);
break;
case CSSC_TUNNEL_BRIDGE_ENTRANCE:
case CSSC_TUNNEL_BRIDGE_EXIT:
style = GetTunnelBridgeSignalStyle(tile);
break;
default:
break;
}
}
const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, tile, type, variant, aspect, context, style, prog); const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, tile, type, variant, aspect, context, style, prog);
SpriteID sprite = result.sprite.sprite; SpriteID sprite = result.sprite.sprite;
PaletteID pal = PAL_NONE; PaletteID pal = PAL_NONE;
@@ -2926,7 +2927,7 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac
} }
template <typename F> template <typename F>
void MarkSingleSignalDirtyIntl(TileIndex tile, Trackdir td, F get_z) void MarkSingleSignalDirtyIntl(TileIndex tile, Trackdir td, bool opposite, F get_z)
{ {
static const uint8 trackdir_to_pos[TRACKDIR_END] = { static const uint8 trackdir_to_pos[TRACKDIR_END] = {
8, // TRACKDIR_X_NE 8, // TRACKDIR_X_NE
@@ -2948,7 +2949,7 @@ void MarkSingleSignalDirtyIntl(TileIndex tile, Trackdir td, F get_z)
}; };
uint x, y; uint x, y;
GetSignalXY(tile, trackdir_to_pos[td], x, y); GetSignalXY(tile, trackdir_to_pos[td], opposite, x, y);
Point pt = RemapCoords(x, y, get_z(x, y)); Point pt = RemapCoords(x, y, get_z(x, y));
MarkAllViewportsDirty( MarkAllViewportsDirty(
pt.x - SIGNAL_DIRTY_LEFT, pt.x - SIGNAL_DIRTY_LEFT,
@@ -2965,15 +2966,18 @@ void MarkSingleSignalDirty(TileIndex tile, Trackdir td)
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE); MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
return; return;
} }
bool opposite = false;
MarkSingleSignalDirtyIntl(tile, td, [td](uint x, uint y) -> uint { if (_signal_opposite_side_style_mask != 0) {
opposite = HasBit(_signal_opposite_side_style_mask, GetSignalStyleGeneric(tile, TrackdirToTrack(td)));
}
MarkSingleSignalDirtyIntl(tile, td, opposite, [td](uint x, uint y) -> uint {
return GetSaveSlopeZ(x, y, TrackdirToTrack(td)); return GetSaveSlopeZ(x, y, TrackdirToTrack(td));
}); });
} }
void MarkSingleSignalDirtyAtZ(TileIndex tile, Trackdir td, uint z) void MarkSingleSignalDirtyAtZ(TileIndex tile, Trackdir td, bool opposite_side, uint z)
{ {
MarkSingleSignalDirtyIntl(tile, td, [z](uint x, uint y) -> uint { MarkSingleSignalDirtyIntl(tile, td, opposite_side, [z](uint x, uint y) -> uint {
return z; return z;
}); });
} }

View File

@@ -409,6 +409,18 @@ static inline uint8 GetSignalStyle(TileIndex t, Track track)
return GB(_me[t].m6, pos, 4); return GB(_me[t].m6, pos, 4);
} }
static inline uint8 GetSignalStyleGeneric(TileIndex t, Track track)
{
switch (GetTileType(t)) {
case MP_RAILWAY:
return GetSignalStyle(t, track);
case MP_TUNNELBRIDGE:
return GetTunnelBridgeSignalStyle(t);
default:
return 0;
}
}
static inline void SetSignalStyle(TileIndex t, Track track, uint8 style) static inline void SetSignalStyle(TileIndex t, Track track, uint8 style)
{ {
assert_tile(GetRailTileType(t) == RAIL_TILE_SIGNALS, t); assert_tile(GetRailTileType(t) == RAIL_TILE_SIGNALS, t);

View File

@@ -33,6 +33,7 @@ uint64 _aspect_cfg_hash = 0;
uint16 _non_aspect_inc_style_mask = 0; uint16 _non_aspect_inc_style_mask = 0;
uint16 _always_reserve_through_style_mask = 0; uint16 _always_reserve_through_style_mask = 0;
uint16 _no_tunnel_bridge_style_mask = 0; uint16 _no_tunnel_bridge_style_mask = 0;
uint16 _signal_opposite_side_style_mask = 0;
bool _signal_sprite_oversized = false; bool _signal_sprite_oversized = false;
/// List of signals dependent upon this one /// List of signals dependent upon this one
@@ -1513,6 +1514,7 @@ static bool DetermineExtraAspectsVariable()
_non_aspect_inc_style_mask = 0; _non_aspect_inc_style_mask = 0;
_no_tunnel_bridge_style_mask = 0; _no_tunnel_bridge_style_mask = 0;
_always_reserve_through_style_mask = 0; _always_reserve_through_style_mask = 0;
_signal_opposite_side_style_mask = 0;
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) {
for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
@@ -1536,6 +1538,9 @@ static bool DetermineExtraAspectsVariable()
} else { } else {
_new_signal_styles[i].lookahead_extra_aspects = _new_signal_styles[i].grffile->new_signal_extra_aspects; _new_signal_styles[i].lookahead_extra_aspects = _new_signal_styles[i].grffile->new_signal_extra_aspects;
} }
if (HasBit(_new_signal_styles[i].style_flags, NSSF_OPPOSITE_SIDE)) {
SetBit(_signal_opposite_side_style_mask, i + 1);
}
} }
for (uint i = _num_new_signal_styles; i < MAX_NEW_SIGNAL_STYLES; i++) { for (uint i = _num_new_signal_styles; i < MAX_NEW_SIGNAL_STYLES; i++) {
_new_signal_styles[i].lookahead_extra_aspects = new_extra_aspects; _new_signal_styles[i].lookahead_extra_aspects = new_extra_aspects;

View File

@@ -24,6 +24,7 @@ extern uint64 _aspect_cfg_hash;
extern uint16 _non_aspect_inc_style_mask; extern uint16 _non_aspect_inc_style_mask;
extern uint16 _always_reserve_through_style_mask; extern uint16 _always_reserve_through_style_mask;
extern uint16 _no_tunnel_bridge_style_mask; extern uint16 _no_tunnel_bridge_style_mask;
extern uint16 _signal_opposite_side_style_mask;
extern bool _signal_sprite_oversized; extern bool _signal_sprite_oversized;
/** /**

View File

@@ -1729,9 +1729,12 @@ static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int off
static void DrawTunnelBridgeRampSingleSignal(const TileInfo *ti, bool is_green, uint position, SignalType type, bool show_exit) static void DrawTunnelBridgeRampSingleSignal(const TileInfo *ti, bool is_green, uint position, SignalType type, bool show_exit)
{ {
bool side = (_settings_game.vehicle.road_side != 0) &&_settings_game.construction.train_signal_side; bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side;
DiagDirection dir = GetTunnelBridgeDirection(ti->tile); DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
uint8 style = GetTunnelBridgeSignalStyle(ti->tile);
side ^= HasBit(_signal_opposite_side_style_mask, style);
static const Point SignalPositions[2][4] = { static const Point SignalPositions[2][4] = {
{ /* X X Y Y Signals on the left side */ { /* X X Y Y Signals on the left side */
{13, 3}, { 2, 13}, { 3, 4}, {13, 14} {13, 3}, { 2, 13}, { 3, 4}, {13, 14}
@@ -1761,7 +1764,7 @@ static void DrawTunnelBridgeRampSingleSignal(const TileInfo *ti, bool is_green,
} }
bool show_restricted = IsTunnelBridgeRestrictedSignal(ti->tile); bool show_restricted = IsTunnelBridgeRestrictedSignal(ti->tile);
const TraceRestrictProgram *prog = show_restricted ? GetExistingTraceRestrictProgram(ti->tile, FindFirstTrack(GetAcrossTunnelBridgeTrackBits(ti->tile))) : nullptr; const TraceRestrictProgram *prog = show_restricted ? GetExistingTraceRestrictProgram(ti->tile, FindFirstTrack(GetAcrossTunnelBridgeTrackBits(ti->tile))) : nullptr;
const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, ti->tile, type, variant, aspect, show_exit ? CSSC_TUNNEL_BRIDGE_EXIT : CSSC_TUNNEL_BRIDGE_ENTRANCE, GetTunnelBridgeSignalStyle(ti->tile), prog); const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, ti->tile, type, variant, aspect, show_exit ? CSSC_TUNNEL_BRIDGE_EXIT : CSSC_TUNNEL_BRIDGE_ENTRANCE, style, prog);
PalSpriteID sprite = result.sprite; PalSpriteID sprite = result.sprite;
bool is_custom_sprite = (sprite.sprite != 0); bool is_custom_sprite = (sprite.sprite != 0);
@@ -1827,9 +1830,10 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
} }
} }
static void GetBridgeSignalXY(TileIndex tile, DiagDirection bridge_direction, uint &position, uint &x, uint &y) static void GetBridgeSignalXY(TileIndex tile, DiagDirection bridge_direction, bool opposite_side, uint &position, uint &x, uint &y)
{ {
bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side; bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side;
side ^= opposite_side;
static const Point SignalPositions[2][4] = { static const Point SignalPositions[2][4] = {
{ /* X X Y Y Signals on the left side */ { /* X X Y Y Signals on the left side */
@@ -1863,9 +1867,10 @@ static void DrawBridgeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_st
while (bridge_signal_position <= bridge_section) { while (bridge_signal_position <= bridge_section) {
bridge_signal_position += simulated_wormhole_signals; bridge_signal_position += simulated_wormhole_signals;
if (bridge_signal_position == bridge_section) { if (bridge_signal_position == bridge_section) {
uint8 style = GetBridgeSignalStyle(bridge_start_tile);
uint position, x, y; uint position, x, y;
GetBridgeSignalXY(ti->tile, GetTunnelBridgeDirection(bridge_start_tile), position, x, y); GetBridgeSignalXY(ti->tile, GetTunnelBridgeDirection(bridge_start_tile), HasBit(_signal_opposite_side_style_mask, style), position, x, y);
SignalVariant variant = IsTunnelBridgeSemaphore(bridge_start_tile) ? SIG_SEMAPHORE : SIG_ELECTRIC; SignalVariant variant = IsTunnelBridgeSemaphore(bridge_start_tile) ? SIG_SEMAPHORE : SIG_ELECTRIC;
SignalState state = GetBridgeEntranceSimulatedSignalState(bridge_start_tile, m2_position); SignalState state = GetBridgeEntranceSimulatedSignalState(bridge_start_tile, m2_position);
@@ -1889,7 +1894,7 @@ static void DrawBridgeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_st
} }
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(bridge_start_tile)); const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(bridge_start_tile));
PalSpriteID sprite = GetCustomSignalSprite(rti, bridge_start_tile, SIGTYPE_NORMAL, variant, aspect, CSSC_BRIDGE_MIDDLE, GetBridgeSignalStyle(bridge_start_tile)).sprite; PalSpriteID sprite = GetCustomSignalSprite(rti, bridge_start_tile, SIGTYPE_NORMAL, variant, aspect, CSSC_BRIDGE_MIDDLE, style).sprite;
if (sprite.sprite != 0) { if (sprite.sprite != 0) {
sprite.sprite += position; sprite.sprite += position;
@@ -1920,8 +1925,13 @@ void MarkSingleBridgeSignalDirty(TileIndex tile, TileIndex bridge_start_tile)
return; return;
} }
bool opposite_side = false;
if (_signal_opposite_side_style_mask != 0) {
opposite_side = HasBit(_signal_opposite_side_style_mask, GetTunnelBridgeSignalStyle(bridge_start_tile));
}
uint position, x, y; uint position, x, y;
GetBridgeSignalXY(tile, GetTunnelBridgeDirection(bridge_start_tile), position, x, y); GetBridgeSignalXY(tile, GetTunnelBridgeDirection(bridge_start_tile), opposite_side, position, x, y);
Point pt = RemapCoords(x, y, GetBridgePixelHeight(bridge_start_tile) + 5 - BRIDGE_Z_START); Point pt = RemapCoords(x, y, GetBridgePixelHeight(bridge_start_tile) + 5 - BRIDGE_Z_START);
MarkAllViewportsDirty( MarkAllViewportsDirty(
pt.x - SIGNAL_DIRTY_LEFT, pt.x - SIGNAL_DIRTY_LEFT,
@@ -1939,15 +1949,22 @@ void MarkTunnelBridgeSignalDirty(TileIndex tile, bool exit)
return; return;
} }
bool opposite_side = false;
if (_signal_opposite_side_style_mask != 0) {
opposite_side = HasBit(_signal_opposite_side_style_mask, GetTunnelBridgeSignalStyle(tile));
}
if (IsRailCustomBridgeHeadTile(tile)) { if (IsRailCustomBridgeHeadTile(tile)) {
Trackdir td = exit ? GetTunnelBridgeExitTrackdir(tile) : GetTunnelBridgeEntranceTrackdir(tile); Trackdir td = exit ? GetTunnelBridgeExitTrackdir(tile) : GetTunnelBridgeEntranceTrackdir(tile);
MarkSingleSignalDirtyAtZ(tile, td, GetTileMaxPixelZ(tile)); MarkSingleSignalDirtyAtZ(tile, td, opposite_side, GetTileMaxPixelZ(tile));
return; return;
} }
bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side; bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side;
DiagDirection dir = GetTunnelBridgeDirection(tile); DiagDirection dir = GetTunnelBridgeDirection(tile);
side ^= opposite_side;
uint position; uint position;
switch (dir) { switch (dir) {
default: NOT_REACHED(); default: NOT_REACHED();