From 8a59b960d47c29b5e2ce34c3800be62807c8d12c Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 18 Sep 2016 13:43:25 +0100 Subject: [PATCH 1/4] Fix missing include in parent commit. --- src/rail_cmd.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 662dc9a67b..51c8addaf0 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -39,6 +39,8 @@ #include "table/railtypes.h" #include "table/track_land.h" +#include + #include "safeguards.h" /** Helper type for lists/vectors of trains */ From 0d2e9f91bffd38a774cecd7f49ac5a0b45e8b5fb Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 18 Sep 2016 14:23:02 +0100 Subject: [PATCH 2/4] Adjust signal on bridge/tunnel map bits, rename accessors, add docs. Use same bit to store red/green state for entrances and exits. No longer re-use exit bit to store red/green state of entrance. Avoid modifying the M2 of tunnel entrances/exits. Rename and rationalise map accessor functions. Document bits used in landscape HTML docs. --- docs/landscape.html | 27 ++++++++- docs/landscape_grid.html | 10 ++-- src/pathfinder/npf/npf.cpp | 2 +- src/pathfinder/yapf/yapf_costrail.hpp | 2 +- src/pbs.cpp | 14 ++--- src/rail_cmd.cpp | 65 ++++++++++++---------- src/rail_map.h | 2 +- src/saveload/afterload.cpp | 17 +++++- src/saveload/extended_ver_sl.cpp | 2 +- src/signal.cpp | 20 +++---- src/train_cmd.cpp | 46 ++++++++-------- src/tunnelbridge_cmd.cpp | 20 +++---- src/tunnelbridge_map.h | 79 +++++++++++++-------------- 13 files changed, 175 insertions(+), 131 deletions(-) diff --git a/docs/landscape.html b/docs/landscape.html index f60e859fc3..525294d392 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -1446,7 +1446,7 @@
  • m3 bits 7..4: owner of tram
  • m3 bits 3..0: track type for railway
  • m5 bit 4: pbs reservation state for railway
  • -
  • m5 bits 7 clear: tunnel entrance/exit
  • +
  • m5 bit 7 clear: tunnel entrance/exit
  • m5 bit 7 set: bridge ramp
  • +
  • m5 bits 6..5: signal simulation (signals on bridge/tunnels patch) + + + + + + + + + + + + + + + +
    0 no signal simulation
    1 signal simulation entrance (bit 5 set)
    2 signal simulation exit (bit 6 set)
    + If signal simulation entrance or exit: +
      +
    • m6 bit 6: set = PBS signals, clear = block signals
    • +
    • m6 bit 1: set = semaphore signals, clear = light signals
    • +
    • m6 bit 0: set = signal shows green, clear = signal shows red
    • +
    • m2 bits 15..0: for bridges only: for signals 0..15 on bridge, signal is visually red if corresponding bit in 0..15 is set
    • +
    +
  • m5 bits 3..2: transport type diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index d34fe9840c..2db8e015fb 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -9,6 +9,7 @@ span.option{ font-family: "Courier New", Courier, mono; background-color: rgb(255,255, 30); } span.free { font-family: "Courier New", Courier, mono; background-color: rgb(30, 178, 54); } span.used { font-family: "Courier New", Courier, mono; } + span.used_p{ font-family: "Courier New", Courier, mono; background-color: cyan; } td.bits { white-space: nowrap; text-align: center; font-family: "Courier New", Courier, mono; } td.caption { white-space: nowrap; text-align: left; } td li { white-space: nowrap; text-align: left; } @@ -23,6 +24,7 @@ the array so you can quickly see what is used and what is not.
    • O - bit is free
    • X - bit is used
    • +
    • P - bit is used by patch feature
    •   - bit of attribute is abused for different purposes, i.e. other bits define the actual meaning.
    • ~ - bit is accessed, but does not really have a meaning (e.g. owner of clear land is always OWNER_NONE)
    @@ -334,8 +336,8 @@ the array so you can quickly see what is used and what is not. - - + + @@ -343,11 +345,11 @@ the array so you can quickly see what is used and what is not. + - - + diff --git a/src/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp index 496a9fdc53..41ec4b53f3 100644 --- a/src/pathfinder/npf/npf.cpp +++ b/src/pathfinder/npf/npf.cpp @@ -936,7 +936,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) break; } } - if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(dst_tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(dst_tile)) == dst_trackdir) { + if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(dst_tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(dst_tile)) == dst_trackdir) { /* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */ break; } diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp index 15da32d9f7..5b90f0b82e 100644 --- a/src/pathfinder/yapf/yapf_costrail.hpp +++ b/src/pathfinder/yapf/yapf_costrail.hpp @@ -244,7 +244,7 @@ public: } } } - if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == trackdir) { + if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == trackdir) { /* Entering a signalled bridge/tunnel from the wrong side, equivalent to encountering a one-way signal from the wrong side */ n.m_segment->m_end_segment_reason |= ESRB_DEAD_END; } diff --git a/src/pbs.cpp b/src/pbs.cpp index c0962557fb..ef81c8ed16 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -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 (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, true); + if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(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 (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, false); + if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED); MarkTileDirtyByTile(tile); } break; @@ -252,7 +252,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra if (IsRailDepotTile(tile)) break; /* Non-pbs signal? Reservation can't continue. */ if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) break; - if (IsTileType(tile, MP_TUNNELBRIDGE) && HasWormholeSignals(tile)) break; + if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeWithSignalSimulation(tile)) break; } return PBSTileInfo(tile, trackdir, false); @@ -281,7 +281,7 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data) /* Do not find trains inside signalled bridge/tunnels. * Trains on the ramp/entrance itself are found though. */ - if (IsTileType(info->res.tile, MP_TUNNELBRIDGE) && HasWormholeSignals(info->res.tile) && info->res.tile != TileVirtXY(t->x_pos, t->y_pos)) { + if (IsTileType(info->res.tile, MP_TUNNELBRIDGE) && IsTunnelBridgeWithSignalSimulation(info->res.tile) && info->res.tile != TileVirtXY(t->x_pos, t->y_pos)) { return NULL; } } @@ -329,7 +329,7 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res) if (ftoti.best != NULL) *train_on_res = ftoti.best->First(); } } - if (*train_on_res == NULL && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE) && !HasWormholeSignals(ftoti.res.tile)) { + if (*train_on_res == NULL && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE) && !IsTunnelBridgeWithSignalSimulation(ftoti.res.tile)) { /* The target tile is a bridge/tunnel, also check the other end tile. */ FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum); if (ftoti.best != NULL) *train_on_res = ftoti.best->First(); @@ -405,7 +405,7 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo } if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) { - if (IsTunnelBridgeEntrance(tile)) { + if (IsTunnelBridgeSignalSimulationEntrance(tile)) { return true; } } @@ -458,7 +458,7 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo /* Not reserved and depot or not a pbs signal -> free. */ if (IsRailDepotTile(tile)) return true; if (IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, trackdir) && !IsPbsSignal(GetSignalType(tile, track))) return true; - if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && IsTunnelBridgeEntrance(tile)) return true; + if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL && IsTunnelBridgeSignalSimulationEntrance(tile)) return true; /* Check the next tile, if it's a PBS signal, it has to be free as well. */ CFollowTrackRail ft(v, GetRailTypeInfo(v->railtype)->compatible_railtypes); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 51c8addaf0..f2c6e01c39 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1061,7 +1061,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, cost = CommandCost(); bool flip_variant = false; bool is_pbs = (sigtype == SIGTYPE_PBS) || (sigtype == SIGTYPE_PBS_ONEWAY); - if (!HasWormholeSignals(tile)) { // toggle signal zero costs. + if (!IsTunnelBridgeWithSignalSimulation(tile)) { // toggle signal zero costs. if (convert_signal) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS); if (p2 != 12) cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] * ((GetTunnelBridgeLength(tile, tile_exit) + 4) >> 2)); // minimal 1 } else { @@ -1074,7 +1074,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, } } if (flags & DC_EXEC) { - if (p2 == 0 && HasWormholeSignals(tile)) { // Toggle signal if already signals present. + if (p2 == 0 && IsTunnelBridgeWithSignalSimulation(tile)) { // Toggle signal if already signals present. if (convert_signal) { if (flip_variant) { SetTunnelBridgeSemaphore(tile, !IsTunnelBridgeSemaphore(tile)); @@ -1088,37 +1088,42 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, SetTunnelBridgePBS(tile, !IsTunnelBridgePBS(tile)); SetTunnelBridgePBS(tile_exit, IsTunnelBridgePBS(tile)); } else { - if (IsTunnelBridgeEntrance(tile)) { - ClrBitTunnelBridgeSignal(tile); - ClrBitTunnelBridgeExit(tile_exit); - SetBitTunnelBridgeExit(tile); - SetBitTunnelBridgeSignal(tile_exit); + if (IsTunnelBridgeSignalSimulationEntrance(tile)) { + ClrTunnelBridgeSignalSimulationEntrance(tile); + ClrTunnelBridgeSignalSimulationExit(tile_exit); + SetTunnelBridgeSignalSimulationExit(tile); + SetTunnelBridgeSignalSimulationEntrance(tile_exit); + SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_GREEN); } else { - ClrBitTunnelBridgeSignal(tile_exit); - ClrBitTunnelBridgeExit(tile); - SetBitTunnelBridgeExit(tile_exit); - SetBitTunnelBridgeSignal(tile); + ClrTunnelBridgeSignalSimulationEntrance(tile_exit); + ClrTunnelBridgeSignalSimulationExit(tile); + SetTunnelBridgeSignalSimulationExit(tile_exit); + SetTunnelBridgeSignalSimulationEntrance(tile); + SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); } } } else { /* Create one direction tunnel/bridge if required. */ if (p2 == 0) { - SetBitTunnelBridgeSignal(tile); - SetBitTunnelBridgeExit(tile_exit); + SetTunnelBridgeSignalSimulationEntrance(tile); + SetTunnelBridgeSignalSimulationExit(tile_exit); + SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); } else if (p2 == 4 || p2 == 8) { DiagDirection tbdir = GetTunnelBridgeDirection(tile); /* If signal only on one side build accoringly one-way tunnel/bridge. */ if ((p2 == 8 && (tbdir == DIAGDIR_NE || tbdir == DIAGDIR_SE)) || (p2 == 4 && (tbdir == DIAGDIR_SW || tbdir == DIAGDIR_NW))) { - ClrBitTunnelBridgeExit(tile); - ClrBitTunnelBridgeSignal(tile_exit); - SetBitTunnelBridgeSignal(tile); - SetBitTunnelBridgeExit(tile_exit); + ClrTunnelBridgeSignalSimulationExit(tile); + ClrTunnelBridgeSignalSimulationEntrance(tile_exit); + SetTunnelBridgeSignalSimulationEntrance(tile); + SetTunnelBridgeSignalSimulationExit(tile_exit); + SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); } else { - ClrBitTunnelBridgeSignal(tile); - ClrBitTunnelBridgeExit(tile_exit); - SetBitTunnelBridgeSignal(tile_exit); - SetBitTunnelBridgeExit(tile); + ClrTunnelBridgeSignalSimulationEntrance(tile); + ClrTunnelBridgeSignalSimulationExit(tile_exit); + SetTunnelBridgeSignalSimulationEntrance(tile_exit); + SetTunnelBridgeSignalSimulationExit(tile); + SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_GREEN); } } if (p2 == 0 || p2 == 4 || p2 == 8) { @@ -1128,8 +1133,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, SetTunnelBridgePBS(tile_exit, is_pbs); } } - if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile) && !HasTunnelBridgeReservation(tile)) SetTunnelBridgeExitGreen(tile, false); - if (IsTunnelBridgeExit(tile_exit) && IsTunnelBridgePBS(tile_exit) && !HasTunnelBridgeReservation(tile_exit)) SetTunnelBridgeExitGreen(tile_exit, false); + 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); MarkBridgeOrTunnelDirty(tile); AddSideToSignalBuffer(tile, INVALID_DIAGDIR, GetTileOwner(tile)); AddSideToSignalBuffer(tile_exit, INVALID_DIAGDIR, GetTileOwner(tile)); @@ -1305,7 +1310,7 @@ static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal return true; case MP_TUNNELBRIDGE: { - if (!remove && HasWormholeSignals(tile)) return false; + if (!remove && IsTunnelBridgeWithSignalSimulation(tile)) return false; TileIndex orig_tile = tile; // backup old value if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false; @@ -1556,7 +1561,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 if (IsTileType(tile, MP_TUNNELBRIDGE)) { TileIndex end = GetOtherTunnelBridgeEnd(tile); if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); - if (!HasWormholeSignals(tile)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS); + if (!IsTunnelBridgeWithSignalSimulation(tile)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS); cost *= ((GetTunnelBridgeLength(tile, end) + 4) >> 2); @@ -1584,12 +1589,12 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 /* Do it? */ if (flags & DC_EXEC) { - if (HasWormholeSignals(tile)) { // handle tunnel/bridge signals. + if (IsTunnelBridgeWithSignalSimulation(tile)) { // handle tunnel/bridge signals. TileIndex end = GetOtherTunnelBridgeEnd(tile); - ClrBitTunnelBridgeExit(tile); - ClrBitTunnelBridgeExit(end); - ClrBitTunnelBridgeSignal(tile); - ClrBitTunnelBridgeSignal(end); + ClrTunnelBridgeSignalSimulationExit(tile); + ClrTunnelBridgeSignalSimulationExit(end); + ClrTunnelBridgeSignalSimulationEntrance(tile); + ClrTunnelBridgeSignalSimulationEntrance(end); _m[tile].m2 = 0; _m[end].m2 = 0; MarkBridgeOrTunnelDirty(tile); diff --git a/src/rail_map.h b/src/rail_map.h index d2befc4686..05faec9018 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -480,7 +480,7 @@ static inline bool HasOnewaySignalBlockingTrackdir(TileIndex tile, Trackdir td) !HasSignalOnTrackdir(tile, td) && IsOnewaySignal(tile, TrackdirToTrack(td))) { return true; } - if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && + if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && DiagDirToDiagTrackdir(GetTunnelBridgeDirection(tile)) == td) { return true; } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index a187cad8f7..76f0d2ec6e 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2972,13 +2972,28 @@ bool AfterLoadGame() /* set the semaphore bit to match what it would have been in v1 */ /* clear the PBS bit, update the end signal state */ for (TileIndex t = 0; t < map_size; t++) { - if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && HasWormholeSignals(t)) { + if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeWithSignalSimulation(t)) { SetTunnelBridgeSemaphore(t, _cur_year < _settings_client.gui.semaphore_build_before); SetTunnelBridgePBS(t, false); UpdateSignalsOnSegment(t, INVALID_DIAGDIR, GetTileOwner(t)); } } } + if (SlXvIsFeaturePresent(XSLFI_SIG_TUNNEL_BRIDGE, 1, 2)) { + /* red/green signal state bit for tunnel entrances moved + * to no longer re-use signalled tunnel exit bit + */ + for (TileIndex t = 0; t < map_size; t++) { + if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL && IsTunnelBridgeWithSignalSimulation(t)) { + if (HasBit(_m[t].m5, 5)) { + /* signalled tunnel entrance */ + SignalState state = HasBit(_m[t].m5, 6) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN; + ClrBit(_m[t].m5, 6); + SetTunnelBridgeSignalState(t, state); + } + } + } + } /* Station acceptance is some kind of cache */ if (IsSavegameVersionBefore(127)) { diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 67e1cc195c..f62dec524b 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -45,7 +45,7 @@ std::vector _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, 2, 2, "signal_tunnel_bridge", NULL, NULL, NULL }, + { XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 3, 3, "signal_tunnel_bridge", NULL, NULL, NULL }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/signal.cpp b/src/signal.cpp index 4639def78f..57eabb5a84 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -384,13 +384,13 @@ static SigFlags ExploreSegment(Owner owner) if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue; DiagDirection dir = GetTunnelBridgeDirection(tile); - if (HasWormholeSignals(tile)) { + if (IsTunnelBridgeWithSignalSimulation(tile)) { if (enterdir == INVALID_DIAGDIR) { // incoming from the wormhole - if (!(flags & SF_TRAIN) && IsTunnelBridgeExit(tile)) { // tunnel entrence is ignored + if (!(flags & SF_TRAIN) && IsTunnelBridgeSignalSimulationExit(tile)) { // tunnel entrence is ignored if (HasVehicleOnPos(GetOtherTunnelBridgeEnd(tile), &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN; if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN; } - if (IsTunnelBridgeExit(tile) && !_tbuset.Add(tile, INVALID_TRACKDIR)) { + if (IsTunnelBridgeSignalSimulationExit(tile) && !_tbuset.Add(tile, INVALID_TRACKDIR)) { return flags | SF_FULL; } enterdir = dir; @@ -398,7 +398,7 @@ static SigFlags ExploreSegment(Owner owner) tile += TileOffsByDiagDir(exitdir); // just skip to next tile } else { // NOT incoming from the wormhole! if (ReverseDiagDir(enterdir) != dir) continue; - if (IsTunnelBridgeExit(tile)) { + if (IsTunnelBridgeSignalSimulationExit(tile)) { if (IsTunnelBridgePBS(tile)) { flags |= SF_PBS; } else if (!_tbuset.Add(tile, INVALID_TRACKDIR)) { @@ -407,7 +407,7 @@ static SigFlags ExploreSegment(Owner owner) } if (!(flags & SF_TRAIN)) { if (HasVehicleOnPos(tile, &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN; - if (!(flags & SF_TRAIN) && IsTunnelBridgeExit(tile)) { + if (!(flags & SF_TRAIN) && IsTunnelBridgeSignalSimulationExit(tile)) { if (HasVehicleOnPos(GetOtherTunnelBridgeEnd(tile), &tile, &TrainInWormholeTileEnum)) flags |= SF_TRAIN; } } @@ -453,12 +453,12 @@ static void UpdateSignalsAroundSegment(SigFlags flags) Trackdir trackdir; while (_tbuset.Get(&tile, &trackdir)) { - if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile)) { + if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile)) { if (IsTunnelBridgePBS(tile)) continue; - bool old_state = IsTunnelBridgeExitGreen(tile); - bool new_state = !(flags & SF_TRAIN); + SignalState old_state = GetTunnelBridgeSignalState(tile); + SignalState new_state = (flags & SF_TRAIN) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN; if (old_state != new_state) { - SetTunnelBridgeExitGreen(tile, new_state); + SetTunnelBridgeSignalState(tile, new_state); MarkTileDirtyByTile(tile); } continue; @@ -545,7 +545,7 @@ static SigSegState UpdateSignalsInBuffer(Owner owner) assert(GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL); assert(dir == INVALID_DIAGDIR || dir == ReverseDiagDir(GetTunnelBridgeDirection(tile))); _tbdset.Add(tile, INVALID_DIAGDIR); // we can safely start from wormhole centre - if (!HasWormholeSignals(tile)) { // Don't worry with other side of tunnel. + if (!IsTunnelBridgeWithSignalSimulation(tile)) { // Don't worry with other side of tunnel. _tbdset.Add(GetOtherTunnelBridgeEnd(tile), INVALID_DIAGDIR); } break; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index f914283a7d..9c1af7bb12 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1864,9 +1864,9 @@ void ReverseTrainDirection(Train *v) } /* We are inside tunnel/bidge with signals, reversing will close the entrance. */ - if (HasWormholeSignals(v->tile)) { + if (IsTunnelBridgeWithSignalSimulation(v->tile)) { /* Flip signal on tunnel entrance tile red. */ - SetBitTunnelBridgeExit(v->tile); + SetTunnelBridgeSignalState(v->tile, SIGNAL_STATE_RED); MarkTileDirtyByTile(v->tile); /* Clear counters. */ v->wait_counter = 0; @@ -2233,14 +2233,16 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir } if (free) { /* Open up the wormhole and clear m2. */ - _m[tile].m2 = 0; - _m[end].m2 = 0; + if (IsBridge(end)) { + _m[tile].m2 = 0; + _m[end].m2 = 0; + } - if (IsTunnelBridgeWithSignRed(end)) { - ClrBitTunnelBridgeExit(end); + if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeSignalState(end) == SIGNAL_STATE_RED) { + SetTunnelBridgeSignalState(end, SIGNAL_STATE_GREEN); if (!_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(end); - } else if (IsTunnelBridgeWithSignRed(tile)) { - ClrBitTunnelBridgeExit(tile); + } else if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) { + SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); if (!_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(tile); } } @@ -2249,7 +2251,7 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir static void UnreserveBridgeTunnelTile(TileIndex tile) { SetTunnelBridgeReservation(tile, false); - if (IsTunnelBridgeExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeExitGreen(tile, false); + if (IsTunnelBridgeSignalSimulationExit(tile) && IsTunnelBridgePBS(tile)) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_RED); } /** @@ -2268,7 +2270,7 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_ TileIndex end = GetOtherTunnelBridgeEnd(tile); bool free = TunnelBridgeIsFree(tile, end, v).Succeeded(); - if (HasWormholeSignals(tile)) { + if (IsTunnelBridgeWithSignalSimulation(tile)) { UnreserveBridgeTunnelTile(tile); HandleLastTunnelBridgeSignals(tile, end, dir, free); if (_settings_client.gui.show_track_reservation) { @@ -2288,7 +2290,7 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_ } } } - } else if (GetTunnelBridgeDirection(tile) == dir && HasWormholeSignals(tile)) { + } else if (GetTunnelBridgeDirection(tile) == dir && IsTunnelBridgeWithSignalSimulation(tile)) { /* cancelling reservation of entry ramp, due to reverse */ UnreserveBridgeTunnelTile(tile); if (_settings_client.gui.show_track_reservation) { @@ -2769,7 +2771,7 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay) } } - if (IsTileType(v->tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(v->tile) && + if (IsTileType(v->tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(v->tile) && DiagDirToDiagTrackBits(GetTunnelBridgeDirection(v->tile)) == v->track) { // prevent any attempt to reserve the wrong way onto a tunnel/bridge exit return false; @@ -2980,7 +2982,7 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir) if (!IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return true; } } - if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) { + if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) { if (UpdateSignalsOnSegment(tile, dir, GetTileOwner(tile)) == SIGSEG_PBS) { return true; } @@ -3247,7 +3249,7 @@ static bool CheckTrainStayInWormHole(Train *t, TileIndex tile) if (t->force_proceed != 0) return false; /* When not exit reverse train. */ - if (!IsTunnelBridgeExit(tile)) { + if (!IsTunnelBridgeSignalSimulationExit(tile)) { t->cur_speed = 0; ToggleBit(t->flags, VRF_REVERSING); return true; @@ -3287,8 +3289,8 @@ static void HandleSignalBehindTrain(Train *v, uint signal_number) if(tile == v->tile) { /* Flip signal on ramp. */ - if (IsTunnelBridgeWithSignRed(tile)) { - ClrBitTunnelBridgeExit(tile); + if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) { + SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); MarkTileDirtyByTile(tile); } } else if (IsBridge(v->tile) && signal_number <= 16) { @@ -3482,20 +3484,20 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) goto invalid_rail; } - if (HasWormholeSignals(gp.new_tile)) { + if (IsTunnelBridgeWithSignalSimulation(gp.new_tile)) { /* If red signal stop. */ if (v->IsFrontEngine() && v->force_proceed == 0) { - if (IsTunnelBridgeWithSignRed(gp.new_tile)) { + if (IsTunnelBridgeSignalSimulationEntrance(gp.new_tile) && GetTunnelBridgeSignalState(gp.new_tile) == SIGNAL_STATE_RED) { v->cur_speed = 0; v->vehstatus |= VS_TRAIN_SLOWING; return false; } - if (IsTunnelBridgeExit(gp.new_tile)) { + if (IsTunnelBridgeSignalSimulationExit(gp.new_tile)) { v->cur_speed = 0; goto invalid_rail; } /* Flip signal on tunnel entrance tile red. */ - SetBitTunnelBridgeExit(gp.new_tile); + SetTunnelBridgeSignalState(gp.new_tile, SIGNAL_STATE_RED); MarkTileDirtyByTile(gp.new_tile); } } @@ -3554,9 +3556,9 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) } else { /* Handle signal simulation on tunnel/bridge. */ TileIndex old_tile = TileVirtXY(v->x_pos, v->y_pos); - if (old_tile != gp.new_tile && HasWormholeSignals(v->tile) && (v->IsFrontEngine() || v->Next() == NULL)) { + if (old_tile != gp.new_tile && IsTunnelBridgeWithSignalSimulation(v->tile) && (v->IsFrontEngine() || v->Next() == NULL)) { if (old_tile == v->tile) { - if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeExit(v->tile)) goto invalid_rail; + if (v->IsFrontEngine() && v->force_proceed == 0 && IsTunnelBridgeSignalSimulationExit(v->tile)) goto invalid_rail; /* Entered wormhole set counters. */ v->wait_counter = (TILE_SIZE * _settings_game.construction.simulated_wormhole_signals) - TILE_SIZE; v->load_unload_ticks = 0; diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 64bd366b15..6746de1da4 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1166,15 +1166,13 @@ static void DrawTunnelBridgeRampSignal(const TileInfo *ti) SignalType type = SIGTYPE_NORMAL; - bool is_green; + bool is_green = (GetTunnelBridgeSignalState(ti->tile) == SIGNAL_STATE_GREEN); bool show_exit; - if (IsTunnelBridgeExit(ti->tile)) { - is_green = IsTunnelBridgeExitGreen(ti->tile); + if (IsTunnelBridgeSignalSimulationExit(ti->tile)) { show_exit = true; position ^= 1; if (IsTunnelBridgePBS(ti->tile)) type = SIGTYPE_PBS_ONEWAY; } else { - is_green = IsTunnelBridgeWithSignGreen(ti->tile); show_exit = false; } @@ -1369,7 +1367,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, ti->x + BB_data[4], ti->y + BB_data[5], BB_data[6], BB_data[7], TILE_HEIGHT, ti->z); /* Draw signals for tunnel. */ - if (HasWormholeSignals(ti->tile)) DrawTunnelBridgeRampSignal(ti); + if (IsTunnelBridgeWithSignalSimulation(ti->tile)) DrawTunnelBridgeRampSignal(ti); DrawBridgeMiddle(ti); } else { // IsBridge(ti->tile) @@ -1479,7 +1477,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) } /* Draw signals for bridge. */ - if (HasWormholeSignals(ti->tile)) DrawTunnelBridgeRampSignal(ti); + if (IsTunnelBridgeWithSignalSimulation(ti->tile)) DrawTunnelBridgeRampSignal(ti); DrawBridgeMiddle(ti); } @@ -1616,7 +1614,7 @@ void DrawBridgeMiddle(const TileInfo *ti) } if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && !IsInvisibilitySet(TO_BRIDGES) && HasTunnelBridgeReservation(rampnorth) - && !HasWormholeSignals(rampnorth)) { + && !IsTunnelBridgeWithSignalSimulation(rampnorth)) { if (rti->UsesOverlay()) { SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY); AddSortableSpriteToDraw(overlay + RTO_X + axis, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES)); @@ -1630,8 +1628,8 @@ void DrawBridgeMiddle(const TileInfo *ti) if (HasCatenaryDrawn(GetRailType(rampsouth))) { DrawCatenaryOnBridge(ti); } - if (HasWormholeSignals(rampsouth)) { - IsTunnelBridgeExit(rampsouth) ? DrawBrigeSignalOnMiddlePart(ti, rampnorth, z): DrawBrigeSignalOnMiddlePart(ti, rampsouth, z); + if (IsTunnelBridgeWithSignalSimulation(rampsouth)) { + IsTunnelBridgeSignalSimulationExit(rampsouth) ? DrawBrigeSignalOnMiddlePart(ti, rampnorth, z): DrawBrigeSignalOnMiddlePart(ti, rampsouth, z); } } @@ -1721,9 +1719,9 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) TransportType tt = GetTunnelBridgeTransportType(tile); if (IsTunnel(tile)) { - td->str = (tt == TRANSPORT_RAIL) ? HasWormholeSignals(tile) ? STR_LAI_TUNNEL_DESCRIPTION_RAILROAD_SIGNAL : STR_LAI_TUNNEL_DESCRIPTION_RAILROAD : STR_LAI_TUNNEL_DESCRIPTION_ROAD; + td->str = (tt == TRANSPORT_RAIL) ? IsTunnelBridgeWithSignalSimulation(tile) ? STR_LAI_TUNNEL_DESCRIPTION_RAILROAD_SIGNAL : STR_LAI_TUNNEL_DESCRIPTION_RAILROAD : STR_LAI_TUNNEL_DESCRIPTION_ROAD; } else { // IsBridge(tile) - td->str = (tt == TRANSPORT_WATER) ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : HasWormholeSignals(tile) ? STR_LAI_BRIDGE_DESCRIPTION_RAILROAD_SIGNAL : GetBridgeSpec(GetBridgeType(tile))->transport_name[tt]; + td->str = (tt == TRANSPORT_WATER) ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : IsTunnelBridgeWithSignalSimulation(tile) ? STR_LAI_BRIDGE_DESCRIPTION_RAILROAD_SIGNAL : GetBridgeSpec(GetBridgeType(tile))->transport_name[tt]; } td->owner[0] = GetTileOwner(tile); diff --git a/src/tunnelbridge_map.h b/src/tunnelbridge_map.h index 2196f794f1..499aad99b7 100644 --- a/src/tunnelbridge_map.h +++ b/src/tunnelbridge_map.h @@ -14,6 +14,7 @@ #include "bridge_map.h" #include "tunnel_map.h" +#include "signal_type.h" /** @@ -122,40 +123,40 @@ static inline TrackBits GetTunnelBridgeReservationTrackBits(TileIndex t) } /** - * Declare tunnel/bridge with signal simulation. + * Declare tunnel/bridge entrance with signal simulation. * @param t the tunnel/bridge tile. */ -static inline void SetBitTunnelBridgeSignal(TileIndex t) +static inline void SetTunnelBridgeSignalSimulationEntrance(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); SetBit(_m[t].m5, 5); } /** - * Remove tunnel/bridge with signal simulation. + * Remove tunnel/bridge entrance with signal simulation. * @param t the tunnel/bridge tile. */ -static inline void ClrBitTunnelBridgeSignal(TileIndex t) +static inline void ClrTunnelBridgeSignalSimulationEntrance(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); ClrBit(_m[t].m5, 5); } /** - * Declare tunnel/bridge exit. + * Declare tunnel/bridge exit with signal simulation. * @param t the tunnel/bridge tile. */ -static inline void SetBitTunnelBridgeExit(TileIndex t) +static inline void SetTunnelBridgeSignalSimulationExit(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); SetBit(_m[t].m5, 6); } /** - * Remove tunnel/bridge exit declaration. + * Remove tunnel/bridge exit with signal simulation. * @param t the tunnel/bridge tile. */ -static inline void ClrBitTunnelBridgeExit(TileIndex t) +static inline void ClrTunnelBridgeSignalSimulationExit(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); ClrBit(_m[t].m5, 6); @@ -167,85 +168,81 @@ static inline void ClrBitTunnelBridgeExit(TileIndex t) * @param t the tile that might be a tunnel/bridge. * @return true if and only if this tile is a tunnel/bridge with signal simulation. */ -static inline bool HasWormholeSignals(TileIndex t) +static inline bool IsTunnelBridgeWithSignalSimulation(TileIndex t) { - return IsTileType(t, MP_TUNNELBRIDGE) && (HasBit(_m[t].m5, 5) || HasBit(_m[t].m5, 6)) ; -} - -/** - * Is this a tunnel/bridge with sign on green? - * @param t the tile that might be a tunnel/bridge with sign set green. - * @pre IsTileType(t, MP_TUNNELBRIDGE) - * @return true if and only if this tile is a tunnel/bridge entrance. - */ -static inline bool IsTunnelBridgeWithSignGreen(TileIndex t) -{ - assert(IsTileType(t, MP_TUNNELBRIDGE)); - return HasBit(_m[t].m5, 5) && !HasBit(_m[t].m5, 6); -} - -static inline bool IsTunnelBridgeWithSignRed(TileIndex t) -{ - assert(IsTileType(t, MP_TUNNELBRIDGE)); - return HasBit(_m[t].m5, 5) && HasBit(_m[t].m5, 6); + return IsTileType(t, MP_TUNNELBRIDGE) && (HasBit(_m[t].m5, 5) || HasBit(_m[t].m5, 6)); } /** * Is this a tunnel/bridge entrance tile with signal? * Tunnel bridge signal simulation has allways bit 5 on at entrance. * @param t the tile that might be a tunnel/bridge. + * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return true if and only if this tile is a tunnel/bridge entrance. */ -static inline bool IsTunnelBridgeEntrance(TileIndex t) +static inline bool IsTunnelBridgeSignalSimulationEntrance(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - return HasBit(_m[t].m5, 5) ; + return HasBit(_m[t].m5, 5) && !HasBit(_m[t].m5, 6); } /** * Is this a tunnel/bridge exit? * @param t the tile that might be a tunnel/bridge. + * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return true if and only if this tile is a tunnel/bridge exit. */ -static inline bool IsTunnelBridgeExit(TileIndex t) +static inline bool IsTunnelBridgeSignalSimulationExit(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); return !HasBit(_m[t].m5, 5) && HasBit(_m[t].m5, 6); } -static inline bool IsTunnelBridgeExitGreen(TileIndex t) +/** + * Get 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) + * @return signal state + */ +static inline SignalState GetTunnelBridgeSignalState(TileIndex t) { - assert(IsTunnelBridgeExit(t)); - return HasBit(_me[t].m6, 0); + assert(IsTunnelBridgeWithSignalSimulation(t)); + return HasBit(_me[t].m6, 0) ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED; } -static inline void SetTunnelBridgeExitGreen(TileIndex t, bool green) +/** + * 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) { - assert(IsTunnelBridgeExit(t)); - SB(_me[t].m6, 0, 1, green ? 1 : 0); + assert(IsTunnelBridgeWithSignalSimulation(t)); + SB(_me[t].m6, 0, 1, (state == SIGNAL_STATE_GREEN) ? 1 : 0); } static inline bool IsTunnelBridgeSemaphore(TileIndex t) { - assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t)); + assert(IsTunnelBridgeWithSignalSimulation(t)); return HasBit(_me[t].m6, 1); } static inline void SetTunnelBridgeSemaphore(TileIndex t, bool is_semaphore) { - assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t)); + assert(IsTunnelBridgeWithSignalSimulation(t)); SB(_me[t].m6, 1, 1, is_semaphore ? 1 : 0); } static inline bool IsTunnelBridgePBS(TileIndex t) { - assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t)); + assert(IsTunnelBridgeWithSignalSimulation(t)); return HasBit(_me[t].m6, 6); } static inline void SetTunnelBridgePBS(TileIndex t, bool is_pbs) { - assert(IsTileType(t, MP_TUNNELBRIDGE) && HasWormholeSignals(t)); + assert(IsTunnelBridgeWithSignalSimulation(t)); SB(_me[t].m6, 6, 1, is_pbs ? 1 : 0); } From 61500b596eb7a20acc45b330ed23cdcf2a7fc124 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 18 Sep 2016 16:12:47 +0100 Subject: [PATCH 3/4] Fix tunnel/bridge entrance signal not being refreshed. When a train left a tunnel or a bridge with no intermediary signals, when setting the entrance signal to green, the display was not refreshed with show track reservations was enabled. --- src/train_cmd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 9c1af7bb12..7112186077 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2240,10 +2240,10 @@ static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDir if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeSignalState(end) == SIGNAL_STATE_RED) { SetTunnelBridgeSignalState(end, SIGNAL_STATE_GREEN); - if (!_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(end); + MarkTileDirtyByTile(end); } else if (IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeSignalState(tile) == SIGNAL_STATE_RED) { SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); - if (!_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(tile); + MarkTileDirtyByTile(tile); } } } From 556594f2f09994e861bcdda6d021c34e85e3c4d1 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 18 Sep 2016 19:48:52 +0100 Subject: [PATCH 4/4] Extend bridge signal simulation to support an unlimited no. of signals. This is instead of the previous limit of 16, all stored in M2. --- docs/landscape.html | 3 +- projects/openttd_vs100.vcxproj | 3 ++ projects/openttd_vs100.vcxproj.filters | 9 ++++ projects/openttd_vs140.vcxproj | 3 ++ projects/openttd_vs140.vcxproj.filters | 9 ++++ projects/openttd_vs80.vcproj | 12 +++++ projects/openttd_vs90.vcproj | 12 +++++ source.list | 2 + src/bridge_map.cpp | 55 +++++++++++++++++++ src/bridge_signal_map.h | 75 ++++++++++++++++++++++++++ src/misc.cpp | 2 + src/openttd.cpp | 2 + src/rail_cmd.cpp | 55 +++++++++---------- src/saveload/bridge_signal_sl.cpp | 58 ++++++++++++++++++++ src/saveload/extended_ver_sl.cpp | 2 +- src/saveload/saveload.cpp | 2 + src/train_cmd.cpp | 64 ++++++++++++++-------- src/tunnelbridge_cmd.cpp | 10 ++-- 18 files changed, 321 insertions(+), 57 deletions(-) create mode 100644 src/bridge_signal_map.h create mode 100644 src/saveload/bridge_signal_sl.cpp diff --git a/docs/landscape.html b/docs/landscape.html index 525294d392..50e53a9f3a 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -1560,7 +1560,8 @@
  • m6 bit 6: set = PBS signals, clear = block signals
  • m6 bit 1: set = semaphore signals, clear = light signals
  • m6 bit 0: set = signal shows green, clear = signal shows red
  • -
  • m2 bits 15..0: for bridges only: for signals 0..15 on bridge, signal is visually red if corresponding bit in 0..15 is set
  • +
  • m2 bit 15: for bridge entrances only: storage for visual red/green state of signals starting from 15 is allocated outside the map array
  • +
  • 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
  • m5 bits 3..2: transport type diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index 18a3cb23ba..4c608f35d3 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -667,6 +667,7 @@ + @@ -872,6 +873,7 @@ + @@ -1177,6 +1179,7 @@ + diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index 16848eb7b8..609f8a8663 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -1230,6 +1230,9 @@ Core Source Code + + Core Source Code + Core Source Code @@ -1845,6 +1848,9 @@ Save/Load handlers + + Save/Load handlers + Tables @@ -2760,6 +2766,9 @@ Map Accessors + + Map Accessors + Map Accessors diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index 5aa11e6f4a..e5582f8243 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -684,6 +684,7 @@ + @@ -889,6 +890,7 @@ + @@ -1194,6 +1196,7 @@ + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index 16848eb7b8..609f8a8663 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -1230,6 +1230,9 @@ Core Source Code + + Core Source Code + Core Source Code @@ -1845,6 +1848,9 @@ Save/Load handlers + + Save/Load handlers + Tables @@ -2760,6 +2766,9 @@ Map Accessors + + Map Accessors + Map Accessors diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index 9f4e2bbf3e..61ecd8d30d 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1946,6 +1946,10 @@ RelativePath=".\..\src\core\bitmath_func.hpp" > + + @@ -2782,6 +2786,10 @@ RelativePath=".\..\src\saveload\extended_ver_sl.cpp" > + + + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index 930522942c..69d120fdf8 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -1943,6 +1943,10 @@ RelativePath=".\..\src\core\bitmath_func.hpp" > + + @@ -2779,6 +2783,10 @@ RelativePath=".\..\src\saveload\extended_ver_sl.cpp" > + + + + diff --git a/source.list b/source.list index 2b177a0889..6608921d6b 100644 --- a/source.list +++ b/source.list @@ -637,6 +637,7 @@ saveload/vehicle_sl.cpp saveload/waypoint_sl.cpp saveload/extended_ver_sl.h saveload/extended_ver_sl.cpp +saveload/bridge_signal_sl.cpp # Tables table/airport_defaults.h @@ -981,6 +982,7 @@ newgrf_townname.cpp # Map Accessors bridge_map.cpp bridge_map.h +bridge_signal_map.h clear_map.h industry_map.h object_map.h diff --git a/src/bridge_map.cpp b/src/bridge_map.cpp index d1e0d6024a..7d155fed64 100644 --- a/src/bridge_map.cpp +++ b/src/bridge_map.cpp @@ -12,6 +12,8 @@ #include "stdafx.h" #include "landscape.h" #include "tunnelbridge_map.h" +#include "bridge_signal_map.h" +#include "debug.h" #include "safeguards.h" @@ -78,3 +80,56 @@ int GetBridgeHeight(TileIndex t) /* one height level extra for the ramp */ return h + 1 + ApplyFoundationToSlope(f, &tileh); } + +std::unordered_map _long_bridge_signal_sim_map; + +SignalState GetBridgeEntranceSimulatedSignalStateExtended(TileIndex t, uint16 signal) +{ + const auto it = _long_bridge_signal_sim_map.find(t); + if (it != _long_bridge_signal_sim_map.end()) { + const LongBridgeSignalStorage &lbss = it->second; + uint16 offset = signal - 15; + uint16 slot = offset >> 6; + uint16 bit = offset & 0x3F; + if (slot >= lbss.signal_red_bits.size()) return SIGNAL_STATE_GREEN; + return GB(lbss.signal_red_bits[slot], bit, 1) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN; + } else { + return SIGNAL_STATE_GREEN; + } +} + +void SetBridgeEntranceSimulatedSignalStateExtended(TileIndex t, uint16 signal, SignalState state) +{ + LongBridgeSignalStorage &lbss = _long_bridge_signal_sim_map[t]; + uint16 offset = signal - 15; + uint16 slot = offset >> 6; + uint16 bit = offset & 0x3F; + if (slot >= lbss.signal_red_bits.size()) lbss.signal_red_bits.resize(slot + 1); + SB(lbss.signal_red_bits[slot], bit, 1, (uint64) ((state == SIGNAL_STATE_RED) ? 1 : 0)); + _m[t].m2 |= 0x8000; +} + +void SetAllBridgeEntranceSimulatedSignalsGreenExtended(TileIndex t) +{ + auto it = _long_bridge_signal_sim_map.find(t); + if (it != _long_bridge_signal_sim_map.end()) { + LongBridgeSignalStorage &lbss = it->second; + for (auto &it : lbss.signal_red_bits) { + it = 0; + } + _m[t].m2 = 0x8000; + } else { + _m[t].m2 = 0; + } +} + +void ClearBridgeEntranceSimulatedSignalsExtended(TileIndex t) +{ + _long_bridge_signal_sim_map.erase(t); + _m[t].m2 = 0; +} + +void ClearBridgeSimulatedSignalMapping() +{ + _long_bridge_signal_sim_map.clear(); +} diff --git a/src/bridge_signal_map.h b/src/bridge_signal_map.h new file mode 100644 index 0000000000..3ab234cbe3 --- /dev/null +++ b/src/bridge_signal_map.h @@ -0,0 +1,75 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file bridge_signal_map.h Map accessor functions for bridge signal simulation. */ + +#ifndef BRIDGE_SIGNAL_MAP_H +#define BRIDGE_SIGNAL_MAP_H + +#include "tile_type.h" +#include "map_func.h" +#include "signal_type.h" +#include "core/bitmath_func.hpp" + +#include +#include + +struct LongBridgeSignalStorage { + std::vector signal_red_bits; +}; + +extern std::unordered_map _long_bridge_signal_sim_map; + +SignalState GetBridgeEntranceSimulatedSignalStateExtended(TileIndex t, uint16 signal); + +static inline SignalState GetBridgeEntranceSimulatedSignalState(TileIndex t, uint16 signal) +{ + if (signal < 15) { + return GB(_m[t].m2, signal, 1) ? SIGNAL_STATE_RED : SIGNAL_STATE_GREEN; + } else { + return GetBridgeEntranceSimulatedSignalStateExtended(t, signal); + } +} + +void SetBridgeEntranceSimulatedSignalStateExtended(TileIndex t, uint16 signal, SignalState state); + +static inline void SetBridgeEntranceSimulatedSignalState(TileIndex t, uint16 signal, SignalState state) +{ + if (signal < 15) { + SB(_m[t].m2, signal, 1, (state == SIGNAL_STATE_RED) ? 1 : 0); + } else { + SetBridgeEntranceSimulatedSignalStateExtended(t, signal, state); + } +} + +void SetAllBridgeEntranceSimulatedSignalsGreenExtended(TileIndex t); + +static inline void SetAllBridgeEntranceSimulatedSignalsGreen(TileIndex t) +{ + if (_m[t].m2 & 0x8000) { + SetAllBridgeEntranceSimulatedSignalsGreenExtended(t); + } else { + _m[t].m2 = 0; + } +} + +void ClearBridgeEntranceSimulatedSignalsExtended(TileIndex t); + +static inline void ClearBridgeEntranceSimulatedSignals(TileIndex t) +{ + if (_m[t].m2 & 0x8000) { + ClearBridgeEntranceSimulatedSignalsExtended(t); + } else { + _m[t].m2 = 0; + } +} + +void ClearBridgeSimulatedSignalMapping(); + +#endif /* BRIDGE_SIGNAL_MAP_H */ diff --git a/src/misc.cpp b/src/misc.cpp index d9d506993f..d9623244c1 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -28,6 +28,7 @@ #include "core/pool_type.hpp" #include "game/game.hpp" #include "linkgraph/linkgraphschedule.h" +#include "bridge_signal_map.h" #include "safeguards.h" @@ -72,6 +73,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin } LinkGraphSchedule::Clear(); + ClearBridgeSimulatedSignalMapping(); PoolBase::Clean(PT_NORMAL); ResetPersistentNewGRFData(); diff --git a/src/openttd.cpp b/src/openttd.cpp index 85b56adc85..3d78e51591 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -63,6 +63,7 @@ #include "subsidy_func.h" #include "gfx_layout.h" #include "viewport_sprite_sorter.h" +#include "bridge_signal_map.h" #include "linkgraph/linkgraphschedule.h" @@ -334,6 +335,7 @@ static void ShutdownGame() #endif LinkGraphSchedule::Clear(); + ClearBridgeSimulatedSignalMapping(); PoolBase::Clean(PT_ALL); /* No NewGRFs were loaded when it was still bootstrapping. */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index f2c6e01c39..e157000a00 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -21,6 +21,7 @@ #include "autoslope.h" #include "water.h" #include "tunnelbridge_map.h" +#include "bridge_signal_map.h" #include "vehicle_func.h" #include "sound_func.h" #include "tunnelbridge.h" @@ -1003,6 +1004,20 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, u return cost; } +static void ClearBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit) +{ + if (IsBridge(entrance)) ClearBridgeEntranceSimulatedSignals(entrance); + ClrTunnelBridgeSignalSimulationEntrance(entrance); + ClrTunnelBridgeSignalSimulationExit(exit); +} + +static void SetupBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit) +{ + SetTunnelBridgeSignalSimulationEntrance(entrance); + SetTunnelBridgeSignalState(entrance, SIGNAL_STATE_GREEN); + SetTunnelBridgeSignalSimulationExit(exit); +} + /** * Build signals, alternate between double/single, signal/semaphore, * pre/exit/combo-signals, and what-else not. If the rail piece does not @@ -1089,41 +1104,27 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, SetTunnelBridgePBS(tile_exit, IsTunnelBridgePBS(tile)); } else { if (IsTunnelBridgeSignalSimulationEntrance(tile)) { - ClrTunnelBridgeSignalSimulationEntrance(tile); - ClrTunnelBridgeSignalSimulationExit(tile_exit); - SetTunnelBridgeSignalSimulationExit(tile); - SetTunnelBridgeSignalSimulationEntrance(tile_exit); - SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_GREEN); + ClearBridgeTunnelSignalSimulation(tile, tile_exit); + SetupBridgeTunnelSignalSimulation(tile_exit, tile); } else { - ClrTunnelBridgeSignalSimulationEntrance(tile_exit); - ClrTunnelBridgeSignalSimulationExit(tile); - SetTunnelBridgeSignalSimulationExit(tile_exit); - SetTunnelBridgeSignalSimulationEntrance(tile); - SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); + ClearBridgeTunnelSignalSimulation(tile_exit, tile); + SetupBridgeTunnelSignalSimulation(tile, tile_exit); } } } else { /* Create one direction tunnel/bridge if required. */ if (p2 == 0) { - SetTunnelBridgeSignalSimulationEntrance(tile); - SetTunnelBridgeSignalSimulationExit(tile_exit); - SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); + SetupBridgeTunnelSignalSimulation(tile, tile_exit); } else if (p2 == 4 || p2 == 8) { DiagDirection tbdir = GetTunnelBridgeDirection(tile); /* If signal only on one side build accoringly one-way tunnel/bridge. */ if ((p2 == 8 && (tbdir == DIAGDIR_NE || tbdir == DIAGDIR_SE)) || (p2 == 4 && (tbdir == DIAGDIR_SW || tbdir == DIAGDIR_NW))) { - ClrTunnelBridgeSignalSimulationExit(tile); - ClrTunnelBridgeSignalSimulationEntrance(tile_exit); - SetTunnelBridgeSignalSimulationEntrance(tile); - SetTunnelBridgeSignalSimulationExit(tile_exit); - SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); + ClearBridgeTunnelSignalSimulation(tile_exit, tile); + SetupBridgeTunnelSignalSimulation(tile, tile_exit); } else { - ClrTunnelBridgeSignalSimulationEntrance(tile); - ClrTunnelBridgeSignalSimulationExit(tile_exit); - SetTunnelBridgeSignalSimulationEntrance(tile_exit); - SetTunnelBridgeSignalSimulationExit(tile); - SetTunnelBridgeSignalState(tile_exit, SIGNAL_STATE_GREEN); + ClearBridgeTunnelSignalSimulation(tile, tile_exit); + SetupBridgeTunnelSignalSimulation(tile_exit, tile); } } if (p2 == 0 || p2 == 4 || p2 == 8) { @@ -1591,12 +1592,8 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 if (IsTunnelBridgeWithSignalSimulation(tile)) { // handle tunnel/bridge signals. TileIndex end = GetOtherTunnelBridgeEnd(tile); - ClrTunnelBridgeSignalSimulationExit(tile); - ClrTunnelBridgeSignalSimulationExit(end); - ClrTunnelBridgeSignalSimulationEntrance(tile); - ClrTunnelBridgeSignalSimulationEntrance(end); - _m[tile].m2 = 0; - _m[end].m2 = 0; + ClearBridgeTunnelSignalSimulation(end, tile); + ClearBridgeTunnelSignalSimulation(tile, end); MarkBridgeOrTunnelDirty(tile); AddSideToSignalBuffer(tile, INVALID_DIAGDIR, GetTileOwner(tile)); AddSideToSignalBuffer(end, INVALID_DIAGDIR, GetTileOwner(tile)); diff --git a/src/saveload/bridge_signal_sl.cpp b/src/saveload/bridge_signal_sl.cpp new file mode 100644 index 0000000000..2af749a3fd --- /dev/null +++ b/src/saveload/bridge_signal_sl.cpp @@ -0,0 +1,58 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file bridge_signal_sl.cpp Code handling saving and loading of data for signal on bridges */ + +#include "../stdafx.h" +#include "../bridge_signal_map.h" +#include "saveload.h" +#include + +/** stub save header struct */ +struct LongBridgeSignalStorageStub { + uint32 length; +}; + +static const SaveLoad _long_bridge_signal_storage_stub_desc[] = { + SLE_VAR(LongBridgeSignalStorageStub, length, SLE_UINT32), + SLE_END() +}; + +static void Load_XBSS() +{ + int index; + LongBridgeSignalStorageStub stub; + while ((index = SlIterateArray()) != -1) { + LongBridgeSignalStorage &lbss = _long_bridge_signal_sim_map[index]; + SlObject(&stub, _long_bridge_signal_storage_stub_desc); + lbss.signal_red_bits.resize(stub.length); + SlArray(&(lbss.signal_red_bits[0]), stub.length, SLE_UINT64); + } +} + +static void RealSave_XBSS(const LongBridgeSignalStorage *lbss) +{ + LongBridgeSignalStorageStub stub; + stub.length = lbss->signal_red_bits.size(); + SlObject(&stub, _long_bridge_signal_storage_stub_desc); + SlArray(const_cast(&(lbss->signal_red_bits[0])), stub.length, SLE_UINT64); +} + +static void Save_XBSS() +{ + for (const auto &it : _long_bridge_signal_sim_map) { + const LongBridgeSignalStorage &lbss = it.second; + SlSetArrayIndex(it.first); + SlAutolength((AutolengthProc*) RealSave_XBSS, const_cast(&lbss)); + } +} + +extern const ChunkHandler _bridge_signal_chunk_handlers[] = { + { 'XBSS', Save_XBSS, Load_XBSS, NULL, NULL, CH_SPARSE_ARRAY | CH_LAST}, +}; diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index f62dec524b..6475840b42 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -45,7 +45,7 @@ std::vector _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, 3, 3, "signal_tunnel_bridge", NULL, NULL, NULL }, + { XSLFI_SIG_TUNNEL_BRIDGE, XSCF_NULL, 4, 4, "signal_tunnel_bridge", NULL, NULL, "XBSS" }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index f531944d63..651854671f 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -457,6 +457,7 @@ extern const ChunkHandler _linkgraph_chunk_handlers[]; extern const ChunkHandler _airport_chunk_handlers[]; extern const ChunkHandler _object_chunk_handlers[]; extern const ChunkHandler _persistent_storage_chunk_handlers[]; +extern const ChunkHandler _bridge_signal_chunk_handlers[]; /** Array of all chunks in a savegame, \c NULL terminated. */ static const ChunkHandler * const _chunk_handlers[] = { @@ -494,6 +495,7 @@ static const ChunkHandler * const _chunk_handlers[] = { _airport_chunk_handlers, _object_chunk_handlers, _persistent_storage_chunk_handlers, + _bridge_signal_chunk_handlers, NULL, }; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 7112186077..7d4d41d679 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -35,6 +35,7 @@ #include "order_backup.h" #include "zoom_func.h" #include "newgrf_debug.h" +#include "bridge_signal_map.h" #include "table/strings.h" #include "table/train_cmd.h" @@ -2210,32 +2211,49 @@ static bool CheckTrainStayInDepot(Train *v) return false; } +static int GetAndClearLastBridgeEntranceSetSignalIndex(TileIndex bridge_entrance) +{ + uint16 m = _m[bridge_entrance].m2; + if (m & 0x8000) { + auto it = _long_bridge_signal_sim_map.find(bridge_entrance); + if (it != _long_bridge_signal_sim_map.end()) { + LongBridgeSignalStorage &lbss = it->second; + size_t slot = lbss.signal_red_bits.size(); + while (slot > 0) { + slot--; + uint64 &slot_bits = lbss.signal_red_bits[slot]; + if (slot_bits) { + uint8 i = FindLastBit(slot_bits); + ClrBit(slot_bits, i); + return 1 + 15 + (64 * slot) + i; + } + } + } + } + if (m & 0x7FFF) { + uint8 i = FindLastBit(m & 0x7FFF); + ClrBit(_m[bridge_entrance].m2, i); + return 1 + i; + } + + return 0; +} + static void HandleLastTunnelBridgeSignals(TileIndex tile, TileIndex end, DiagDirection dir, bool free) { - if (IsBridge(end) && _m[end].m2 > 0){ + if (IsBridge(end) && _m[end].m2 != 0) { /* Clearing last bridge signal. */ - uint16 m = _m[end].m2; - byte i = 15; - while((m & 0x8000) == 0 && --i > 0) m <<= 1; - ClrBit(_m[end].m2, i); - - uint x = TileX(end)* TILE_SIZE; - uint y = TileY(end)* TILE_SIZE; - uint distance = (TILE_SIZE * _settings_game.construction.simulated_wormhole_signals) * ++i; - switch (dir) { - default: NOT_REACHED(); - case DIAGDIR_NE: MarkTileDirtyByTile(TileVirtXY(x - distance, y)); break; - case DIAGDIR_SE: MarkTileDirtyByTile(TileVirtXY(x, y + distance)); break; - case DIAGDIR_SW: MarkTileDirtyByTile(TileVirtXY(x + distance, y)); break; - case DIAGDIR_NW: MarkTileDirtyByTile(TileVirtXY(x, y - distance)); break; + int signal_offset = GetAndClearLastBridgeEntranceSetSignalIndex(end); + if (signal_offset) { + TileIndex last_signal_tile = end + (TileOffsByDiagDir(dir) * _settings_game.construction.simulated_wormhole_signals * signal_offset); + MarkTileDirtyByTile(last_signal_tile); } MarkTileDirtyByTile(tile); } if (free) { /* Open up the wormhole and clear m2. */ if (IsBridge(end)) { - _m[tile].m2 = 0; - _m[end].m2 = 0; + SetAllBridgeEntranceSimulatedSignalsGreen(end); } if (IsTunnelBridgeSignalSimulationEntrance(end) && GetTunnelBridgeSignalState(end) == SIGNAL_STATE_RED) { @@ -3276,7 +3294,7 @@ static bool CheckTrainStayInWormHole(Train *t, TileIndex tile) return false; } -static void HandleSignalBehindTrain(Train *v, uint signal_number) +static void HandleSignalBehindTrain(Train *v, int signal_number) { TileIndex tile; switch (v->direction) { @@ -3293,8 +3311,8 @@ static void HandleSignalBehindTrain(Train *v, uint signal_number) SetTunnelBridgeSignalState(tile, SIGNAL_STATE_GREEN); MarkTileDirtyByTile(tile); } - } else if (IsBridge(v->tile) && signal_number <= 16) { - ClrBit(_m[v->tile].m2, signal_number); + } else if (IsBridge(v->tile) && signal_number >= 0) { + SetBridgeEntranceSimulatedSignalState(v->tile, signal_number, SIGNAL_STATE_GREEN); MarkTileDirtyByTile(tile); } } @@ -3582,14 +3600,14 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) return false; } /* flip signal in front to red on bridges*/ - if (distance == 0 && v->load_unload_ticks <= 15 && IsBridge(v->tile)){ - SetBit(_m[v->tile].m2, v->load_unload_ticks); + if (distance == 0 && IsBridge(v->tile)) { + SetBridgeEntranceSimulatedSignalState(v->tile, v->load_unload_ticks, SIGNAL_STATE_RED); MarkTileDirtyByTile(gp.new_tile); } } } if (v->Next() == NULL) { - if (v->load_unload_ticks > 0 && v->load_unload_ticks <= 16 && distance == (TILE_SIZE * _settings_game.construction.simulated_wormhole_signals) - TILE_SIZE) HandleSignalBehindTrain(v, v->load_unload_ticks - 2); + if (v->load_unload_ticks > 0 && distance == (TILE_SIZE * _settings_game.construction.simulated_wormhole_signals) - TILE_SIZE) HandleSignalBehindTrain(v, v->load_unload_ticks - 2); if (old_tile == v->tile) { /* We left ramp into wormhole. */ v->x_pos = gp.x; diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 6746de1da4..4e24b215f2 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -26,6 +26,7 @@ #include "newgrf_sound.h" #include "autoslope.h" #include "tunnelbridge_map.h" +#include "bridge_signal_map.h" #include "strings_func.h" #include "date_func.h" #include "clear_func.h" @@ -954,6 +955,9 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) } DirtyCompanyInfrastructureWindows(owner); + if (IsTunnelBridgeSignalSimulationEntrance(tile)) ClearBridgeEntranceSimulatedSignals(tile); + if (IsTunnelBridgeSignalSimulationEntrance(endtile)) ClearBridgeEntranceSimulatedSignals(endtile); + DoClearSquare(tile); DoClearSquare(endtile); for (TileIndex c = tile + delta; c != endtile; c += delta) { @@ -1236,14 +1240,14 @@ static void DrawBrigeSignalOnMiddlePart(const TileInfo *ti, TileIndex bridge_sta SignalVariant variant = IsTunnelBridgeSemaphore(bridge_start_tile) ? SIG_SEMAPHORE : SIG_ELECTRIC; - SpriteID sprite; + SpriteID sprite = (GetBridgeEntranceSimulatedSignalState(bridge_start_tile, m2_position) == SIGNAL_STATE_GREEN); if (variant == SIG_ELECTRIC) { /* Normal electric signals are picked from original sprites. */ - sprite = SPR_ORIGINAL_SIGNALS_BASE + ((position << 1) + !HasBit(_m[bridge_start_tile].m2, m2_position)); + sprite += SPR_ORIGINAL_SIGNALS_BASE + (position << 1); } else { /* All other signals are picked from add on sprites. */ - sprite = SPR_SIGNALS_BASE + ((SIGTYPE_NORMAL - 1) * 16 + variant * 64 + (position << 1) + !HasBit(_m[bridge_start_tile].m2, m2_position)); + sprite += SPR_SIGNALS_BASE + (SIGTYPE_NORMAL - 1) * 16 + variant * 64 + (position << 1); } AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, TILE_HEIGHT, z, false, 0, 0, BB_Z_SEPARATOR);
  • OOOO OOOO OOOO OOOO XXXX XXXX OOOO OOOOXOOX XXXXOOOO OOOOXPPX XXXXOPOO OOPP XXXX XXXX
    -inherit- -inherit- -inherit-PPPP PPPP PPPP PPPP -inherit- -inherit- -inherit--inherit-OOXX XXOOOPXX XXPP -inherit-