Use separate bits for signals on bridge/tunnel entrance/exit red/green states

pull/59/head
Jonathan G Rennison 6 years ago
parent 0dd3ff23de
commit d03139b241

@ -1557,9 +1557,10 @@
</table>
If signal simulation entrance or exit:
<ul>
<li>m6 bit 7: set = exit signal shows green, clear = exit signal shows red</li>
<li>m6 bit 6: set = PBS signals, clear = block signals</li>
<li>m6 bit 1: set = semaphore signals, clear = light signals</li>
<li>m6 bit 0: set = signal shows green, clear = signal shows red</li>
<li>m6 bit 0: set = entrance signal shows green, clear = entrance signal shows red</li>
<li>m2 bit 15: for bridge entrances only: storage for visual red/green state of signals starting from 15 is allocated outside the map array</li>
<li>m2 bits 14..0: for bridge entrances only: for signals 0..14 on bridge, signal is visually red if corresponding bit in 0..14 is set</li>
</ul>

@ -337,7 +337,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">X<span class="used_p">PP</span>X XXXX</td>
<td class="bits"><span class="free">O</span><span class="used_p">P</span><span class="free">OO OO</span><span class="used_p">PP</span></td>
<td class="bits"><span class="used_p">PP</span><span class="free">OO OO</span><span class="used_p">PP</span></td>
<td class="bits">XXXX XXXX</td>
</tr>
<tr>

@ -125,7 +125,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
case MP_TUNNELBRIDGE:
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && !GetTunnelBridgeReservationTrackBits(tile)) {
SetTunnelBridgeReservation(tile, true);
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile);
return true;
}
@ -181,7 +181,7 @@ void UnreserveRailTrack(TileIndex tile, Track t)
case MP_TUNNELBRIDGE:
if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
SetTunnelBridgeReservation(tile, false);
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(tile);
}
break;

@ -1022,7 +1022,7 @@ static void ClearBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit
static void SetupBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit)
{
SetTunnelBridgeSignalSimulationEntrance(entrance);
SetTunnelBridgeSignalState(entrance, SIGNAL_STATE_GREEN);
SetTunnelBridgeEntranceSignalState(entrance, SIGNAL_STATE_GREEN);
SetTunnelBridgeSignalSimulationExit(exit);
}
@ -1144,8 +1144,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
SetTunnelBridgePBS(tile_exit, is_pbs);
}
}
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
if (IsTunnelBridgeSignalSimulationExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_RED);
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_RED);
if (IsTunnelBridgeSignalSimulationExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeExitSignalState(tile_exit, SIGNAL_STATE_RED);
MarkBridgeOrTunnelDirty(tile);
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, GetTileOwner(tile));
AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile));

@ -2989,7 +2989,7 @@ bool AfterLoadGame()
/* signalled tunnel entrance */
SignalState state = HasBit(_m[t].m5, 6) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN;
ClrBit(_m[t].m5, 6);
SetTunnelBridgeSignalState(t, state);
SetTunnelBridgeEntranceSignalState(t, state);
}
}
}
@ -3005,6 +3005,14 @@ bool AfterLoadGame()
}
}
}
if (SlXvIsFeaturePresent(XSLFI_SIG_TUNNEL_BRIDGE, 1, 5)) {
/* entrance and exit signal red/green states now have separate bits */
for (TileIndex t = 0; t < map_size; t++) {
if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeSignalSimulationExit(t)) {
SetTunnelBridgeExitSignalState(t, HasBit(_me[t].m6, 0) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED);
}
}
}
/* Station acceptance is some kind of cache */
if (IsSavegameVersionBefore(127)) {

@ -45,8 +45,7 @@ std::vector<uint32> _sl_xv_discardable_chunk_ids; ///< list of chunks
static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 5, 5, "signal_tunnel_bridge", NULL, NULL, "XBSS" },
{ XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker
{ XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 6, 6, "signal_tunnel_bridge", NULL, NULL, "XBSS" },
};
/**

@ -455,10 +455,10 @@ static void UpdateSignalsAroundSegment(SigFlags flags)
while (_tbuset.Get(&tile, &trackdir)) {
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile)) {
if (IsTunnelBridgePBS(tile)) continue;
SignalState old_state = GetTunnelBridgeSignalState(tile);
SignalState old_state = GetTunnelBridgeExitSignalState(tile);
SignalState new_state = (flags & SF_TRAIN) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN;
if (old_state != new_state) {
SetTunnelBridgeSignalState(tile, new_state);
SetTunnelBridgeExitSignalState(tile, new_state);
MarkTileDirtyByTile(tile);
}
continue;

@ -1874,10 +1874,10 @@ void ReverseTrainDirection(Train *v)
return;
}
/* We are inside tunnel/bidge with signals, reversing will close the entrance. */
/* We are inside tunnel/bridge with signals, reversing will close the entrance. */
if (IsTunnelBridgeWithSignalSimulation(v->tile)) {
/* Flip signal on tunnel entrance tile red. */
SetTunnelBridgeSignalState(v->tile, SIGNAL_STATE_RED);
SetTunnelBridgeEntranceSignalState(v->tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(v->tile);
/* Clear counters. */
v->wait_counter = 0;
@ -2266,11 +2266,11 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
SetAllBridgeEntranceSimulatedSignalsGreen(end);
}
if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeSignalState(end) == SIGNAL_STATE_RED) {
SetTunnelBridgeSignalState(end, SIGNAL_STATE_GREEN);
if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeEntranceSignalState(end) == SIGNAL_STATE_RED) {
SetTunnelBridgeEntranceSignalState(end, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(end);
} else if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
} else if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile);
}
}
@ -2279,7 +2279,7 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir
static void UnreserveBridgeTunnelTile(TileIndex tile)
{
SetTunnelBridgeReservation(tile, false);
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED);
if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_RED);
}
/**
@ -3269,7 +3269,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
}
bool ok = TryPathReserve(t);
t->tile = veh_orig;
if (ok && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
if (ok && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_GREEN);
return ok;
}
@ -3317,8 +3317,8 @@ static void HandleSignalBehindTrain(Train *v, int signal_number)
if(tile == v->tile) {
/* Flip signal on ramp. */
if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN);
if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
SetTunnelBridgeEntranceSignalState(tile, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(tile);
}
} else if (IsBridge(v->tile) && signal_number >= 0) {
@ -3515,7 +3515,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
if (IsTunnelBridgeWithSignalSimulation(gp.new_tile)) {
/* If red signal stop. */
if (v->IsFrontEngine() && v->force_proceed == 0) {
if (IsTunnelBridgeSignalSimulationEntrance(gp.new_tile) && GetTunnelBridgeSignalState(gp.new_tile) == SIGNAL_STATE_RED) {
if (IsTunnelBridgeSignalSimulationEntrance(gp.new_tile) && GetTunnelBridgeEntranceSignalState(gp.new_tile) == SIGNAL_STATE_RED) {
v->cur_speed = 0;
v->vehstatus |= VS_TRAIN_SLOWING;
return false;
@ -3525,7 +3525,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
goto invalid_rail;
}
/* Flip signal on tunnel entrance tile red. */
SetTunnelBridgeSignalState(gp.new_tile, SIGNAL_STATE_RED);
SetTunnelBridgeEntranceSignalState(gp.new_tile, SIGNAL_STATE_RED);
MarkTileDirtyByTile(gp.new_tile);
}
}
@ -3837,7 +3837,25 @@ static void DeleteLastWagon(Train *v)
if (IsLevelCrossingTile(tile)) UpdateLevelCrossing(tile);
/* Update signals */
if (IsTileType(tile, MP_TUNNELBRIDGE) || IsRailDepotTile(tile)) {
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, owner);
if (IsTunnelBridgeWithSignalSimulation(tile)) {
TileIndex end = GetOtherTunnelBridgeEnd(tile);
UpdateSignalsOnSegment(end, INVALID_DIAGDIR, owner);
bool is_entrance = IsTunnelBridgeSignalSimulationEntrance(tile);
TileIndex entrance = is_entrance ? tile : end;
if (TunnelBridgeIsFree(tile, end, nullptr).Succeeded()) {
if (IsBridge(entrance)) {
SetAllBridgeEntranceSimulatedSignalsGreen(entrance);
MarkBridgeDirty(entrance);
}
if (IsTunnelBridgeSignalSimulationEntrance(entrance) && GetTunnelBridgeEntranceSignalState(entrance) == SIGNAL_STATE_RED) {
SetTunnelBridgeEntranceSignalState(entrance, SIGNAL_STATE_GREEN);
MarkTileDirtyByTile(entrance);
}
}
}
} else if (IsRailDepotTile(tile)) {
UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, owner);
} else {
SetSignalsOnBothDir(tile, track, owner);
@ -4078,7 +4096,7 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse)
if (IsLevelCrossingTile(tile)) MaybeBarCrossingWithSound(tile);
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL &&
IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) {
IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_RED) {
return TrainApproachingLineEnd(v, true, reverse);
}

@ -1183,13 +1183,14 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
SignalType type = SIGTYPE_NORMAL;
bool is_green = (GetTunnelBridgeSignalState(ti->tile) == SIGNAL_STATE_GREEN);
bool show_exit;
bool is_green, show_exit;
if (IsTunnelBridgeSignalSimulationExit(ti->tile)) {
is_green = (GetTunnelBridgeExitSignalState(ti->tile) == SIGNAL_STATE_GREEN);
show_exit = true;
position ^= 1;
if (IsTunnelBridgePBS(ti->tile)) type = SIGTYPE_PBS_ONEWAY;
} else {
is_green = (GetTunnelBridgeEntranceSignalState(ti->tile) == SIGNAL_STATE_GREEN);
show_exit = false;
}
@ -1216,7 +1217,7 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti)
}
/* Draws a signal on tunnel / bridge entrance tile. */
static void DrawBrigeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_start_tile, uint z)
static void DrawBridgeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_start_tile, uint z)
{
uint bridge_signal_position = 0;

@ -199,29 +199,53 @@ static inline bool IsTunnelBridgeSignalSimulationExit(TileIndex t)
}
/**
* Get the signal state for a tunnel/bridge entrance or exit with signal simulation
* Get the signal state for a tunnel/bridge entrance with signal simulation
* @param t the tunnel/bridge entrance or exit tile with signal simulation
* @pre IsTunnelBridgeWithSignalSimulation(t)
* @return signal state
*/
static inline SignalState GetTunnelBridgeSignalState(TileIndex t)
static inline SignalState GetTunnelBridgeEntranceSignalState(TileIndex t)
{
assert(IsTunnelBridgeWithSignalSimulation(t));
assert(IsTunnelBridgeSignalSimulationEntrance(t));
return HasBit(_me[t].m6, 0) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED;
}
/**
* Get the signal state for a tunnel/bridge exit with signal simulation
* @param t the tunnel/bridge entrance or exit tile with signal simulation
* @pre IsTunnelBridgeWithSignalSimulation(t)
* @return signal state
*/
static inline SignalState GetTunnelBridgeExitSignalState(TileIndex t)
{
assert(IsTunnelBridgeSignalSimulationExit(t));
return HasBit(_me[t].m6, 7) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED;
}
/**
* Set the signal state for a tunnel/bridge entrance or exit with signal simulation
* @param t the tunnel/bridge entrance or exit tile with signal simulation
* @pre IsTunnelBridgeWithSignalSimulation(t)
* @param state signal state
*/
static inline void SetTunnelBridgeSignalState(TileIndex t, SignalState state)
static inline void SetTunnelBridgeEntranceSignalState(TileIndex t, SignalState state)
{
assert(IsTunnelBridgeWithSignalSimulation(t));
assert(IsTunnelBridgeSignalSimulationEntrance(t));
SB(_me[t].m6, 0, 1, (state == SIGNAL_STATE_GREEN) ? 1 : 0);
}
/**
* Set the signal state for a tunnel/bridge entrance or exit with signal simulation
* @param t the tunnel/bridge entrance or exit tile with signal simulation
* @pre IsTunnelBridgeWithSignalSimulation(t)
* @param state signal state
*/
static inline void SetTunnelBridgeExitSignalState(TileIndex t, SignalState state)
{
assert(IsTunnelBridgeSignalSimulationExit(t));
SB(_me[t].m6, 7, 1, (state == SIGNAL_STATE_GREEN) ? 1 : 0);
}
static inline bool IsTunnelBridgeSemaphore(TileIndex t)
{
assert(IsTunnelBridgeWithSignalSimulation(t));

Loading…
Cancel
Save