diff options
-rw-r--r-- | docs/landscape.html | 6 | ||||
-rw-r--r-- | docs/landscape_grid.html | 4 | ||||
-rw-r--r-- | src/lang/english.txt | 6 | ||||
-rw-r--r-- | src/npf.cpp | 2 | ||||
-rw-r--r-- | src/openttd.cpp | 16 | ||||
-rw-r--r-- | src/rail_cmd.cpp | 98 | ||||
-rw-r--r-- | src/rail_map.h | 37 | ||||
-rw-r--r-- | src/saveload.cpp | 2 | ||||
-rw-r--r-- | src/yapf/yapf_costrail.hpp | 2 |
9 files changed, 110 insertions, 63 deletions
diff --git a/docs/landscape.html b/docs/landscape.html index b876bb31b..670539d09 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -355,9 +355,9 @@ </li> <li>m5 bit 6 set = with signals: <ul> - <li>m2 bits 7..4: bit clear = signal shows red; same bits as in m3</li> - <li>m2 bit 2: set = semaphore signals, clear = light signals </li> - <li>m2 bits 1..0 : type of signal + <li>m4 bits 7..4: bit clear = signal shows red; same bits as in m3</li> + <li>m2 bit 2 <i>(6)</i>: set = semaphore signals, clear = light signals <i>(lower and right tracks)</i></li> + <li>m2 bits 1..0 <i>(5..4)</i>: type of signal <i>(lower and right tracks)</i> <table> <tr> <td nowrap="nowrap" valign="top"><tt>00</tt>: </td> diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index 01a0ef1e2..06351e2aa 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -88,9 +88,9 @@ the array so you can quickly see what is used and what is not. <td class="caption">rail</td> <td class="bits">XXXX XXXX</td> <td class="bits">XXXX XXXX</td> - <td class="bits"><span class="free">OOOO OOOO</span> XXXX XXXX</td> + <td class="bits"><span class="free">OOOO OOOO O</span>XXX <span class="free">O</span>XXX</td> + <td class="bits">XXXX XXXX</td> <td class="bits">XXXX XXXX</td> - <td class="bits"><span class="free">OOOO O</span>XXX</td> <td class="bits">XXXX XXXX</td> <td class="bits">XX<span class="free">OO OO</span>XX</td> <td class="bits"><span class="free">OOOO OOOO</span></td> diff --git a/src/lang/english.txt b/src/lang/english.txt index 9a2d69353..101ff2cb9 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1590,6 +1590,12 @@ STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS :Railway track w STR_RAILROAD_TRACK_WITH_PRESIGNALS :Railway track with pre-signals STR_RAILROAD_TRACK_WITH_EXITSIGNALS :Railway track with exit-signals STR_RAILROAD_TRACK_WITH_COMBOSIGNALS :Railway track with combo-signals +STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS :Railway track with normal and pre-signals +STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS :Railway track with normal and exit-signals +STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS :Railway track with normal and combo-signals +STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS :Railway track with pre- and exit-signals +STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS :Railway track with pre- and combo-signals +STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS :Railway track with exit- and combo-signals STR_MUST_REMOVE_RAILWAY_STATION_FIRST :{WHITE}Must remove railway station first diff --git a/src/npf.cpp b/src/npf.cpp index a5f7ec157..10e4b6171 100644 --- a/src/npf.cpp +++ b/src/npf.cpp @@ -357,7 +357,7 @@ static int32 NPFRailPathCost(AyStar* as, AyStarNode* current, OpenListNode* pare * encounter, if it is red */ /* Is this a presignal exit or combo? */ - SignalType sigtype = GetSignalType(tile); + SignalType sigtype = GetSignalType(tile, TrackdirToTrack(trackdir)); if (sigtype == SIGTYPE_EXIT || sigtype == SIGTYPE_COMBO) { /* Penalise exit and combo signals differently (heavier) */ cost += _patches.npf_rail_firstred_exit_penalty; diff --git a/src/openttd.cpp b/src/openttd.cpp index 062d2185b..2e20074a7 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1664,10 +1664,10 @@ bool AfterLoadGame() case MP_RAILWAY: if (HasSignals(t)) { /* convert PBS signals to combo-signals */ - if (HASBIT(_m[t].m2, 2)) SetSignalType(t, SIGTYPE_COMBO); + if (HASBIT(_m[t].m2, 2)) SetSignalType(t, TRACK_X, SIGTYPE_COMBO); /* move the signal variant back */ - SetSignalVariant(t, HASBIT(_m[t].m2, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC); + SetSignalVariant(t, TRACK_X, HASBIT(_m[t].m2, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC); CLRBIT(_m[t].m2, 3); } @@ -2001,6 +2001,18 @@ bool AfterLoadGame() _opt.diff.number_towns++; } + if (CheckSavegameVersion(64)) { + /* copy the signal type/variant and move signal states bits */ + for (TileIndex t = 0; t < map_size; t++) { + if (IsTileType(t, MP_RAILWAY) && HasSignals(t)) { + SetSignalStates(t, GB(_m[t].m2, 4, 4)); + SetSignalVariant(t, INVALID_TRACK, GetSignalVariant(t, TRACK_X)); + SetSignalType(t, INVALID_TRACK, GetSignalType(t, TRACK_X)); + CLRBIT(_m[t].m2, 7); + } + } + } + /* Recalculate */ Group *g; FOR_ALL_GROUPS(g) { diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 7ffdc4a63..66036ab36 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -692,7 +692,7 @@ int32 CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) /* build new signals */ cost = _price.build_signals; } else { - if (p2 != 0 && sigvar != GetSignalVariant(tile)) { + if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) { /* convert signals <-> semaphores */ cost = _price.build_signals + _price.remove_signals; } else { @@ -707,20 +707,22 @@ int32 CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) SetHasSignals(tile, true); SetSignalStates(tile, 0xF); // all signals are on SetPresentSignals(tile, 0); // no signals built by default - SetSignalType(tile, SIGTYPE_NORMAL); - SetSignalVariant(tile, sigvar); + SetSignalType(tile, track, SIGTYPE_NORMAL); + SetSignalVariant(tile, track, sigvar); } if (p2 == 0) { if (!HasSignalOnTrack(tile, track)) { /* build new signals */ SetPresentSignals(tile, GetPresentSignals(tile) | SignalOnTrack(track)); + SetSignalType(tile, track, SIGTYPE_NORMAL); + SetSignalVariant(tile, track, sigvar); } else { if (pre_signal) { /* cycle between normal -> pre -> exit -> combo -> ... */ - SignalType type = GetSignalType(tile); + SignalType type = GetSignalType(tile, track); - SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1)); + SetSignalType(tile, track, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : (SignalType)(type + 1)); } else { CycleSignalSide(tile, track); } @@ -729,7 +731,7 @@ int32 CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) /* If CmdBuildManySignals is called with copying signals, just copy the * direction of the first signal given as parameter by CmdBuildManySignals */ SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track))); - SetSignalVariant(tile, sigvar); + SetSignalVariant(tile, track, sigvar); } MarkTileDirtyByTile(tile); @@ -787,7 +789,7 @@ static int32 CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint3 if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */ /* copy signal/semaphores style (independent of CTRL) */ - semaphores = GetSignalVariant(tile) != SIG_ELECTRIC; + semaphores = GetSignalVariant(tile, track) != SIG_ELECTRIC; } else { // no signals exist, drag a two-way signal stretch signals = SignalOnTrack(track); } @@ -879,7 +881,7 @@ int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) if (GetPresentSignals(tile) == 0) { SetSignalStates(tile, 0); SetHasSignals(tile, false); - SetSignalVariant(tile, SIG_ELECTRIC); // remove any possible semaphores + SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores } SetSignalsOnBothDir(tile, track); @@ -1090,7 +1092,7 @@ static int32 ClearTile_Track(TileIndex tile, byte flags) #include "table/track_land.h" -static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos) +static void DrawSingleSignal(TileIndex tile, Track track, byte condition, uint image, uint pos) { bool side = (_opt.road_side != 0) && _patches.signal_side; static const Point SignalPositions[2][12] = { @@ -1127,10 +1129,10 @@ static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint po /* _signal_base is set by our NewGRF Action 5 loader. If it is 0 then we * just draw the standard signals, else we get the offset from _signal_base * and draw that sprite. All the signal sprites are loaded sequentially. */ - if (_signal_base == 0 || (GetSignalType(tile) == 0 && GetSignalVariant(tile) == SIG_ELECTRIC)) { - sprite = SignalBase[side][GetSignalVariant(tile)][GetSignalType(tile)] + image + condition; + if (_signal_base == 0 || (GetSignalType(tile, track) == SIGTYPE_NORMAL && GetSignalVariant(tile, track) == SIG_ELECTRIC)) { + sprite = SignalBase[side][GetSignalVariant(tile, track)][GetSignalType(tile, track)] + image + condition; } else { - sprite = _signal_base + (GetSignalType(tile) - 1) * 16 + GetSignalVariant(tile) * 64 + image + condition; + sprite = _signal_base + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition; } AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, 10, GetSlopeZ(x,y)); @@ -1300,33 +1302,33 @@ static void DrawTrackBits(TileInfo* ti, TrackBits track) static void DrawSignals(TileIndex tile, TrackBits rails) { -#define MAYBE_DRAW_SIGNAL(x,y,z) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, GetSingleSignalState(tile, x), y - 0x4FB, z) +#define MAYBE_DRAW_SIGNAL(x,y,z,t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, t, GetSingleSignalState(tile, x), y - 0x4FB, z) if (!(rails & TRACK_BIT_Y)) { if (!(rails & TRACK_BIT_X)) { if (rails & TRACK_BIT_LEFT) { - MAYBE_DRAW_SIGNAL(2, 0x509, 0); - MAYBE_DRAW_SIGNAL(3, 0x507, 1); + MAYBE_DRAW_SIGNAL(2, 0x509, 0, TRACK_LEFT); + MAYBE_DRAW_SIGNAL(3, 0x507, 1, TRACK_LEFT); } if (rails & TRACK_BIT_RIGHT) { - MAYBE_DRAW_SIGNAL(0, 0x509, 2); - MAYBE_DRAW_SIGNAL(1, 0x507, 3); + MAYBE_DRAW_SIGNAL(0, 0x509, 2, TRACK_RIGHT); + MAYBE_DRAW_SIGNAL(1, 0x507, 3, TRACK_RIGHT); } if (rails & TRACK_BIT_UPPER) { - MAYBE_DRAW_SIGNAL(3, 0x505, 4); - MAYBE_DRAW_SIGNAL(2, 0x503, 5); + MAYBE_DRAW_SIGNAL(3, 0x505, 4, TRACK_UPPER); + MAYBE_DRAW_SIGNAL(2, 0x503, 5, TRACK_UPPER); } if (rails & TRACK_BIT_LOWER) { - MAYBE_DRAW_SIGNAL(1, 0x505, 6); - MAYBE_DRAW_SIGNAL(0, 0x503, 7); + MAYBE_DRAW_SIGNAL(1, 0x505, 6, TRACK_LOWER); + MAYBE_DRAW_SIGNAL(0, 0x503, 7, TRACK_LOWER); } } else { - MAYBE_DRAW_SIGNAL(3, 0x4FB, 8); - MAYBE_DRAW_SIGNAL(2, 0x4FD, 9); + MAYBE_DRAW_SIGNAL(3, 0x4FB, 8, TRACK_X); + MAYBE_DRAW_SIGNAL(2, 0x4FD, 9, TRACK_X); } } else { - MAYBE_DRAW_SIGNAL(3, 0x4FF, 10); - MAYBE_DRAW_SIGNAL(2, 0x501, 11); + MAYBE_DRAW_SIGNAL(3, 0x4FF, 10, TRACK_Y); + MAYBE_DRAW_SIGNAL(2, 0x501, 11, TRACK_Y); } } @@ -1510,11 +1512,12 @@ struct SetSignalsData { static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) { SetSignalsData* ssd = (SetSignalsData*)data; + Track track = TrackdirToTrack(trackdir); if (!IsTileType(tile, MP_RAILWAY)) return false; /* the tile has signals? */ - if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) { + if (HasSignalOnTrack(tile, track)) { if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) { /* yes, add the signal to the list of signals */ if (ssd->cur != NUM_SSD_ENTRY) { @@ -1524,10 +1527,10 @@ static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, ui } /* remember if this block has a presignal. */ - ssd->has_presignal |= IsPresignalEntry(tile); + ssd->has_presignal |= IsPresignalEntry(tile, track); } - if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) { + if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile, track)) { /* this is an exit signal that points out from the segment */ ssd->presignal_exits++; if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED) @@ -1666,13 +1669,14 @@ static void ChangeSignalStates(SetSignalsData *ssd) TileIndex tile = ssd->tile[i]; byte bit = SignalAgainstTrackdir(ssd->bit[i]); uint signals = GetSignalStates(tile); + Track track = TrackdirToTrack(ssd->bit[i]); /* presignals don't turn green if there is at least one presignal exit and none are free */ - if (IsPresignalEntry(tile)) { + if (IsPresignalEntry(tile, track)) { int ex = ssd->presignal_exits, exfree = ssd->presignal_exits_free; /* subtract for dual combo signals so they don't count themselves */ - if (IsPresignalExit(tile) && HasSignalOnTrackdir(tile, ssd->bit[i])) { + if (IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, ssd->bit[i])) { ex--; if (GetSignalStateByTrackdir(tile, ssd->bit[i]) != SIGNAL_STATE_RED) exfree--; } @@ -1692,7 +1696,7 @@ make_red: } /* Update signals on the other side of this exit-combo signal; it changed. */ - if (IsPresignalExit(tile)) { + if (IsPresignalExit(tile, track)) { if (ssd->cur_stack != NUM_SSD_STACK) { ssd->next_tile[ssd->cur_stack] = tile; ssd->next_dir[ssd->cur_stack] = _dir_from_track[ssd->bit[i]]; @@ -1970,14 +1974,34 @@ static void GetTileDesc_Track(TileIndex tile, TileDesc *td) break; case RAIL_TILE_SIGNALS: { - const StringID signal_type[] = { - STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS, - STR_RAILROAD_TRACK_WITH_PRESIGNALS, - STR_RAILROAD_TRACK_WITH_EXITSIGNALS, - STR_RAILROAD_TRACK_WITH_COMBOSIGNALS + const StringID signal_type[4][4] = { + { + STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS, + STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS, + STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS, + STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS + }, + { + STR_RAILROAD_TRACK_WITH_NORMAL_PRESIGNALS, + STR_RAILROAD_TRACK_WITH_PRESIGNALS, + STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS, + STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS + }, + { + STR_RAILROAD_TRACK_WITH_NORMAL_EXITSIGNALS, + STR_RAILROAD_TRACK_WITH_PRE_EXITSIGNALS, + STR_RAILROAD_TRACK_WITH_EXITSIGNALS, + STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS + }, + { + STR_RAILROAD_TRACK_WITH_NORMAL_COMBOSIGNALS, + STR_RAILROAD_TRACK_WITH_PRE_COMBOSIGNALS, + STR_RAILROAD_TRACK_WITH_EXIT_COMBOSIGNALS, + STR_RAILROAD_TRACK_WITH_COMBOSIGNALS + } }; - td->str = signal_type[GetSignalType(tile)]; + td->str = signal_type[GetSignalType(tile, TRACK_UPPER)][GetSignalType(tile, TRACK_LOWER)]; break; } diff --git a/src/rail_map.h b/src/rail_map.h index 1d22fe332..ff938d846 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -207,33 +207,35 @@ enum SignalType { SIGTYPE_COMBO = 3 ///< presignal inter-block }; -static inline SignalType GetSignalType(TileIndex t) +static inline SignalType GetSignalType(TileIndex t, Track track) { assert(GetRailTileType(t) == RAIL_TILE_SIGNALS); - return (SignalType)GB(_m[t].m2, 0, 2); + byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 4 : 0; + return (SignalType)GB(_m[t].m2, pos, 2); } -static inline void SetSignalType(TileIndex t, SignalType s) +static inline void SetSignalType(TileIndex t, Track track, SignalType s) { assert(GetRailTileType(t) == RAIL_TILE_SIGNALS); - SB(_m[t].m2, 0, 2, s); + byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 4 : 0; + SB(_m[t].m2, pos, 2, s); + if (track == INVALID_TRACK) SB(_m[t].m2, 4, 2, s); } -static inline bool IsPresignalEntry(TileIndex t) +static inline bool IsPresignalEntry(TileIndex t, Track track) { - return GetSignalType(t) == SIGTYPE_ENTRY || GetSignalType(t) == SIGTYPE_COMBO; + return GetSignalType(t, track) == SIGTYPE_ENTRY || GetSignalType(t, track) == SIGTYPE_COMBO; } -static inline bool IsPresignalExit(TileIndex t) +static inline bool IsPresignalExit(TileIndex t, Track track) { - return GetSignalType(t) == SIGTYPE_EXIT || GetSignalType(t) == SIGTYPE_COMBO; + return GetSignalType(t, track) == SIGTYPE_EXIT || GetSignalType(t, track) == SIGTYPE_COMBO; } static inline void CycleSignalSide(TileIndex t, Track track) { byte sig; - byte pos = 6; - if (track == TRACK_LOWER || track == TRACK_RIGHT) pos = 4; + byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 4 : 6; sig = GB(_m[t].m3, pos, 2); if (--sig == 0) sig = 3; @@ -246,14 +248,17 @@ enum SignalVariant { SIG_SEMAPHORE = 1 ///< Old-fashioned semaphore signal }; -static inline SignalVariant GetSignalVariant(TileIndex t) +static inline SignalVariant GetSignalVariant(TileIndex t, Track track) { - return (SignalVariant)GB(_m[t].m2, 2, 1); + byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 6 : 2; + return (SignalVariant)GB(_m[t].m2, pos, 1); } -static inline void SetSignalVariant(TileIndex t, SignalVariant v) +static inline void SetSignalVariant(TileIndex t, Track track, SignalVariant v) { - SB(_m[t].m2, 2, 1, v); + byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 6 : 2; + SB(_m[t].m2, pos, 1, v); + if (track == INVALID_TRACK) SB(_m[t].m2, 6, 1, v); } /** These are states in which a signal can be. Currently these are only two, so @@ -272,7 +277,7 @@ enum SignalState { */ static inline void SetSignalStates(TileIndex tile, uint state) { - SB(_m[tile].m2, 4, 4, state); + SB(_m[tile].m4, 4, 4, state); } /** @@ -282,7 +287,7 @@ static inline void SetSignalStates(TileIndex tile, uint state) */ static inline uint GetSignalStates(TileIndex tile) { - return GB(_m[tile].m2, 4, 4); + return GB(_m[tile].m4, 4, 4); } /** diff --git a/src/saveload.cpp b/src/saveload.cpp index 9eb15a3f9..420e5e98a 100644 --- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -29,7 +29,7 @@ #include <setjmp.h> #include <list> -extern const uint16 SAVEGAME_VERSION = 63; +extern const uint16 SAVEGAME_VERSION = 64; uint16 _sl_version; ///< the major savegame version identifier byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! diff --git a/src/yapf/yapf_costrail.hpp b/src/yapf/yapf_costrail.hpp index 8efda0c27..ffde3703b 100644 --- a/src/yapf/yapf_costrail.hpp +++ b/src/yapf/yapf_costrail.hpp @@ -121,7 +121,7 @@ public: Yapf().m_stopped_on_first_two_way_signal = true; return -1; } - SignalType sig_type = GetSignalType(tile); + SignalType sig_type = GetSignalType(tile, TrackdirToTrack(trackdir)); n.m_last_red_signal_type = sig_type; n.flags_u.flags_s.m_last_signal_was_red = true; |