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);