Add signal style flag for drawing on the opposite side
This commit is contained in:
@@ -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.
|
||||
</td>
|
||||
</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>
|
||||
<td>
|
||||
When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style
|
||||
|
@@ -480,6 +480,13 @@
|
||||
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_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>
|
||||
<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>
|
||||
|
@@ -4271,6 +4271,15 @@ static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const
|
||||
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:
|
||||
ret = HandleAction0PropertyDefault(buf, prop);
|
||||
break;
|
||||
|
@@ -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_SEMAPHORE_ENABLED, "signals_style_semaphore_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_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"),
|
||||
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"),
|
||||
|
@@ -43,6 +43,7 @@ enum Action0RemapPropertyIds {
|
||||
A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS,
|
||||
A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED,
|
||||
A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED,
|
||||
A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE,
|
||||
A0RPI_OBJECT_USE_LAND_GROUND,
|
||||
A0RPI_OBJECT_EDGE_FOUNDATION_MODE,
|
||||
A0RPI_OBJECT_FLOOD_RESISTANT,
|
||||
|
@@ -28,6 +28,7 @@ enum NewSignalStyleFlags {
|
||||
NSSF_NO_ASPECT_INC = 0,
|
||||
NSSF_ALWAYS_RESERVE_THROUGH = 1,
|
||||
NSSF_LOOKAHEAD_ASPECTS_SET = 2,
|
||||
NSSF_OPPOSITE_SIDE = 3,
|
||||
};
|
||||
|
||||
struct NewSignalStyle {
|
||||
|
@@ -479,7 +479,7 @@ static inline Money SignalMaintenanceCost(uint32 num)
|
||||
}
|
||||
|
||||
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);
|
||||
int TicksToLeaveDepot(const Train *v);
|
||||
|
@@ -2763,7 +2763,7 @@ static uint GetSaveSlopeZ(uint x, uint y, Track track)
|
||||
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;
|
||||
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
|
||||
default: side = _settings_game.vehicle.road_side != 0; break; // driving side
|
||||
}
|
||||
side ^= opposite;
|
||||
static const Point SignalPositions[2][12] = {
|
||||
{ // Signals on the left side
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
GetSignalXY(tile, pos, x, y);
|
||||
GetSignalXY(tile, pos, HasBit(_signal_opposite_side_style_mask, style), x, y);
|
||||
|
||||
uint8 aspect;
|
||||
if (condition == SIGNAL_STATE_GREEN) {
|
||||
@@ -2824,23 +2842,6 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign
|
||||
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);
|
||||
SpriteID sprite = result.sprite.sprite;
|
||||
PaletteID pal = PAL_NONE;
|
||||
@@ -2926,7 +2927,7 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac
|
||||
}
|
||||
|
||||
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] = {
|
||||
8, // TRACKDIR_X_NE
|
||||
@@ -2948,7 +2949,7 @@ void MarkSingleSignalDirtyIntl(TileIndex tile, Trackdir td, F get_z)
|
||||
};
|
||||
|
||||
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));
|
||||
MarkAllViewportsDirty(
|
||||
pt.x - SIGNAL_DIRTY_LEFT,
|
||||
@@ -2965,15 +2966,18 @@ void MarkSingleSignalDirty(TileIndex tile, Trackdir td)
|
||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
||||
return;
|
||||
}
|
||||
|
||||
MarkSingleSignalDirtyIntl(tile, td, [td](uint x, uint y) -> uint {
|
||||
bool opposite = false;
|
||||
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));
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
@@ -409,6 +409,18 @@ static inline uint8 GetSignalStyle(TileIndex t, Track track)
|
||||
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)
|
||||
{
|
||||
assert_tile(GetRailTileType(t) == RAIL_TILE_SIGNALS, t);
|
||||
|
@@ -33,6 +33,7 @@ uint64 _aspect_cfg_hash = 0;
|
||||
uint16 _non_aspect_inc_style_mask = 0;
|
||||
uint16 _always_reserve_through_style_mask = 0;
|
||||
uint16 _no_tunnel_bridge_style_mask = 0;
|
||||
uint16 _signal_opposite_side_style_mask = 0;
|
||||
bool _signal_sprite_oversized = false;
|
||||
|
||||
/// List of signals dependent upon this one
|
||||
@@ -1513,6 +1514,7 @@ static bool DetermineExtraAspectsVariable()
|
||||
_non_aspect_inc_style_mask = 0;
|
||||
_no_tunnel_bridge_style_mask = 0;
|
||||
_always_reserve_through_style_mask = 0;
|
||||
_signal_opposite_side_style_mask = 0;
|
||||
|
||||
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) {
|
||||
for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
|
||||
@@ -1536,6 +1538,9 @@ static bool DetermineExtraAspectsVariable()
|
||||
} else {
|
||||
_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++) {
|
||||
_new_signal_styles[i].lookahead_extra_aspects = new_extra_aspects;
|
||||
|
@@ -24,6 +24,7 @@ extern uint64 _aspect_cfg_hash;
|
||||
extern uint16 _non_aspect_inc_style_mask;
|
||||
extern uint16 _always_reserve_through_style_mask;
|
||||
extern uint16 _no_tunnel_bridge_style_mask;
|
||||
extern uint16 _signal_opposite_side_style_mask;
|
||||
extern bool _signal_sprite_oversized;
|
||||
|
||||
/**
|
||||
|
@@ -1732,6 +1732,9 @@ static void DrawTunnelBridgeRampSingleSignal(const TileInfo *ti, bool is_green,
|
||||
bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side;
|
||||
DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
|
||||
|
||||
uint8 style = GetTunnelBridgeSignalStyle(ti->tile);
|
||||
side ^= HasBit(_signal_opposite_side_style_mask, style);
|
||||
|
||||
static const Point SignalPositions[2][4] = {
|
||||
{ /* X X Y Y Signals on the left side */
|
||||
{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);
|
||||
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;
|
||||
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;
|
||||
side ^= opposite_side;
|
||||
|
||||
static const Point SignalPositions[2][4] = {
|
||||
{ /* 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) {
|
||||
bridge_signal_position += simulated_wormhole_signals;
|
||||
if (bridge_signal_position == bridge_section) {
|
||||
uint8 style = GetBridgeSignalStyle(bridge_start_tile);
|
||||
|
||||
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;
|
||||
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));
|
||||
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) {
|
||||
sprite.sprite += position;
|
||||
@@ -1920,8 +1925,13 @@ void MarkSingleBridgeSignalDirty(TileIndex tile, TileIndex bridge_start_tile)
|
||||
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;
|
||||
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);
|
||||
MarkAllViewportsDirty(
|
||||
pt.x - SIGNAL_DIRTY_LEFT,
|
||||
@@ -1939,15 +1949,22 @@ void MarkTunnelBridgeSignalDirty(TileIndex tile, bool exit)
|
||||
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)) {
|
||||
Trackdir td = exit ? GetTunnelBridgeExitTrackdir(tile) : GetTunnelBridgeEntranceTrackdir(tile);
|
||||
MarkSingleSignalDirtyAtZ(tile, td, GetTileMaxPixelZ(tile));
|
||||
MarkSingleSignalDirtyAtZ(tile, td, opposite_side, GetTileMaxPixelZ(tile));
|
||||
return;
|
||||
}
|
||||
|
||||
bool side = (_settings_game.vehicle.road_side != 0) && _settings_game.construction.train_signal_side;
|
||||
DiagDirection dir = GetTunnelBridgeDirection(tile);
|
||||
|
||||
side ^= opposite_side;
|
||||
|
||||
uint position;
|
||||
switch (dir) {
|
||||
default: NOT_REACHED();
|
||||
|
Reference in New Issue
Block a user