OpenTTD Source: src/signal.cpp Source File

OpenTTD Source 15.0-beta1

signal.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "debug.h"
12#include "station_map.h"
13#include "tunnelbridge_map.h"
14#include "vehicle_func.h"
15#include "viewport_func.h"
16#include "train.h"
17#include "company_base.h"
18#include "pbs.h"
19
20#include "safeguards.h"
21
22
24 static const uint SIG_TBU_SIZE = 64;
25 static const uint SIG_TBD_SIZE = 256;
26 static const uint SIG_GLOB_SIZE = 128;
27 static const uint SIG_GLOB_UPDATE = 64;
28
29static_assert(SIG_GLOB_UPDATE <= SIG_GLOB_SIZE);
30
32 static const TrackBits _enterdir_to_trackbits[DIAGDIR_END] = {
33 TRACK_BIT_3WAY_NE,
34 TRACK_BIT_3WAY_SE,
35 TRACK_BIT_3WAY_SW,
36 TRACK_BIT_3WAY_NW
37};
38
40 static const TrackdirBits _enterdir_to_trackdirbits[DIAGDIR_END] = {
41 TRACKDIR_BIT_X_SW | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_RIGHT_S,
42 TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_RIGHT_N,
43 TRACKDIR_BIT_X_NE | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_LEFT_N,
44 TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_LEFT_S
45};
46
52template <typename Tdir, uint items>
53 struct SmallSet {
54private:
55 uint n; // actual number of units
56 bool overflowed; // did we try to overflow the set?
57 const char *name; // name, used for debugging purposes...
58
60 struct SSdata {
61 TileIndex tile;
62 Tdir dir;
63 } data[items];
64
65public:
67 SmallSet(const char *name) : n(0), overflowed(false), name(name) { }
68
70 void Reset()
71 {
72 this->n = 0;
73 this->overflowed = false;
74 }
75
80 bool Overflowed()
81 {
82 return this->overflowed;
83 }
84
89 bool IsEmpty()
90 {
91 return this->n == 0;
92 }
93
98 bool IsFull()
99 {
100 return this->n == lengthof(data);
101 }
102
107 uint Items()
108 {
109 return this->n;
110 }
111
112
119 bool Remove(TileIndex tile, Tdir dir)
120 {
121 for (uint i = 0; i < this->n; i++) {
122 if (this->data[i].tile == tile && this->data[i].dir == dir) {
123 this->data[i] = this->data[--this->n];
124 return true;
125 }
126 }
127
128 return false;
129 }
130
137 bool IsIn(TileIndex tile, Tdir dir)
138 {
139 for (uint i = 0; i < this->n; i++) {
140 if (this->data[i].tile == tile && this->data[i].dir == dir) return true;
141 }
142
143 return false;
144 }
145
153 bool Add(TileIndex tile, Tdir dir)
154 {
155 if (this->IsFull()) {
156 overflowed = true;
157 Debug(misc, 0, "SignalSegment too complex. Set {} is full (maximum {})", name, items);
158 return false; // set is full
159 }
160
161 this->data[this->n].tile = tile;
162 this->data[this->n].dir = dir;
163 this->n++;
164
165 return true;
166 }
167
174 bool Get(TileIndex *tile, Tdir *dir)
175 {
176 if (this->n == 0) return false;
177
178 this->n--;
179 *tile = this->data[this->n].tile;
180 *dir = this->data[this->n].dir;
181
182 return true;
183 }
184};
185
186 static SmallSet<Trackdir, SIG_TBU_SIZE> _tbuset("_tbuset");
187 static SmallSet<DiagDirection, SIG_TBD_SIZE> _tbdset("_tbdset");
188 static SmallSet<DiagDirection, SIG_GLOB_SIZE> _globset("_globset");
189
190
192 static Vehicle *TrainOnTileEnum(Vehicle *v, void *)
193{
194 if (v->type != VEH_TRAIN || Train::From(v)->track == TRACK_BIT_DEPOT) return nullptr;
195
196 return v;
197}
198
199
213 static inline bool CheckAddToTodoSet(TileIndex t1, DiagDirection d1, TileIndex t2, DiagDirection d2)
214{
215 _globset.Remove(t1, d1); // it can be in Global but not in Todo
216 _globset.Remove(t2, d2); // remove in all cases
217
218 assert(!_tbdset.IsIn(t1, d1)); // it really shouldn't be there already
219
220 return !_tbdset.Remove(t2, d2);
221}
222
223
237 static inline bool MaybeAddToTodoSet(TileIndex t1, DiagDirection d1, TileIndex t2, DiagDirection d2)
238{
239 if (!CheckAddToTodoSet(t1, d1, t2, d2)) return true;
240
241 return _tbdset.Add(t1, d1);
242}
243
244
246 enum SigFlags {
247 SF_NONE = 0,
248 SF_TRAIN = 1 << 0,
249 SF_EXIT = 1 << 1,
250 SF_EXIT2 = 1 << 2,
251 SF_GREEN = 1 << 3,
252 SF_GREEN2 = 1 << 4,
253 SF_FULL = 1 << 5,
254 SF_PBS = 1 << 6,
255 SF_SPLIT = 1 << 7,
256 SF_ENTER = 1 << 8,
257 SF_ENTER2 = 1 << 9,
258};
259
260 DECLARE_ENUM_AS_BIT_SET(SigFlags)
261
262
263
269static SigFlags ExploreSegment(Owner owner)
270{
271 SigFlags flags = SF_NONE;
272
273 TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280).
274 DiagDirection enterdir = INVALID_DIAGDIR;
275
276 while (_tbdset.Get(&tile, &enterdir)) { // tile and enterdir are initialized here, unless I'm mistaken.
277 TileIndex oldtile = tile; // tile we are leaving
278 DiagDirection exitdir = enterdir == INVALID_DIAGDIR ? INVALID_DIAGDIR : ReverseDiagDir(enterdir); // expected new exit direction (for straight line)
279
280 switch (GetTileType(tile)) {
281 case MP_RAILWAY: {
282 if (GetTileOwner(tile) != owner) continue; // do not propagate signals on others' tiles (remove for tracksharing)
283
284 if (IsRailDepot(tile)) {
285 if (enterdir == INVALID_DIAGDIR) { // from 'inside' - train just entered or left the depot
286 if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN;
287 exitdir = GetRailDepotDirection(tile);
288 tile += TileOffsByDiagDir(exitdir);
289 enterdir = ReverseDiagDir(exitdir);
290 break;
291 } else if (enterdir == GetRailDepotDirection(tile)) { // entered a depot
292 if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN;
293 continue;
294 } else {
295 continue;
296 }
297 }
298
299 assert(IsValidDiagDirection(enterdir));
300 TrackBits tracks = GetTrackBits(tile); // trackbits of tile
301 TrackBits tracks_masked = (TrackBits)(tracks & _enterdir_to_trackbits[enterdir]); // only incidating trackbits
302
303 if (tracks == TRACK_BIT_HORZ || tracks == TRACK_BIT_VERT) { // there is exactly one incidating track, no need to check
304 tracks = tracks_masked;
305 /* If no train detected yet, and there is not no train -> there is a train -> set the flag */
306 if (!(flags & SF_TRAIN) && EnsureNoTrainOnTrackBits(tile, tracks).Failed()) flags |= SF_TRAIN;
307 } else {
308 if (tracks_masked == TRACK_BIT_NONE) continue; // no incidating track
309 if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN;
310 }
311
312 /* Is this a track merge or split? */
313 if (!HasAtMostOneBit(tracks)) flags |= SF_SPLIT;
314
315 if (HasSignals(tile)) { // there is exactly one track - not zero, because there is exit from this tile
316 Track track = TrackBitsToTrack(tracks_masked); // mask TRACK_BIT_X and Y too
317 if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir
318 SignalType sig = GetSignalType(tile, track);
319 Trackdir trackdir = (Trackdir)FindFirstBit((tracks * 0x101U) & _enterdir_to_trackdirbits[enterdir]);
320 Trackdir reversedir = ReverseTrackdir(trackdir);
321 /* add (tile, reversetrackdir) to 'to-be-updated' set when there is
322 * ANY conventional signal in REVERSE direction
323 * (if it is a presignal EXIT and it changes, it will be added to 'to-be-done' set later) */
324 if (HasSignalOnTrackdir(tile, reversedir)) {
325 if (IsPbsSignal(sig)) flags |= SF_PBS;
326 if (flags & SF_ENTER) flags |= SF_ENTER2;
327 flags |= SF_ENTER;
328
329 if (!_tbuset.Add(tile, reversedir)) return flags | SF_FULL;
330 }
331 if (HasSignalOnTrackdir(tile, trackdir) && !IsOnewaySignal(tile, track)) flags |= SF_PBS;
332
333 /* if it is a presignal EXIT in OUR direction and we haven't found 2 green exits yes, do special check */
334 if (!(flags & SF_GREEN2) && IsPresignalExit(tile, track) && HasSignalOnTrackdir(tile, trackdir)) { // found presignal exit
335 if (flags & SF_EXIT) flags |= SF_EXIT2; // found two (or more) exits
336 flags |= SF_EXIT; // found at least one exit - allow for compiler optimizations
337 if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN) { // found green presignal exit
338 if (flags & SF_GREEN) flags |= SF_GREEN2;
339 flags |= SF_GREEN;
340 }
341 }
342
343 continue;
344 }
345 }
346
347 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { // test all possible exit directions
348 if (dir != enterdir && (tracks & _enterdir_to_trackbits[dir])) { // any track incidating?
349 TileIndex newtile = tile + TileOffsByDiagDir(dir); // new tile to check
350 DiagDirection newdir = ReverseDiagDir(dir); // direction we are entering from
351 if (!MaybeAddToTodoSet(newtile, newdir, tile, dir)) return flags | SF_FULL;
352 }
353 }
354
355 continue; // continue the while() loop
356 }
357
358 case MP_STATION:
359 if (!HasStationRail(tile)) continue;
360 if (GetTileOwner(tile) != owner) continue;
361 if (DiagDirToAxis(enterdir) != GetRailStationAxis(tile)) continue; // different axis
362 if (IsStationTileBlocked(tile)) continue; // 'eye-candy' station tile
363
364 if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN;
365 tile += TileOffsByDiagDir(exitdir);
366 break;
367
368 case MP_ROAD:
369 if (!IsLevelCrossing(tile)) continue;
370 if (GetTileOwner(tile) != owner) continue;
371 if (DiagDirToAxis(enterdir) == GetCrossingRoadAxis(tile)) continue; // different axis
372
373 if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN;
374 tile += TileOffsByDiagDir(exitdir);
375 break;
376
377 case MP_TUNNELBRIDGE: {
378 if (GetTileOwner(tile) != owner) continue;
379 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
380 DiagDirection dir = GetTunnelBridgeDirection(tile);
381
382 if (enterdir == INVALID_DIAGDIR) { // incoming from the wormhole
383 if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN;
384 enterdir = dir;
385 exitdir = ReverseDiagDir(dir);
386 tile += TileOffsByDiagDir(exitdir); // just skip to next tile
387 } else { // NOT incoming from the wormhole!
388 if (ReverseDiagDir(enterdir) != dir) continue;
389 if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN;
390 tile = GetOtherTunnelBridgeEnd(tile); // just skip to exit tile
391 enterdir = INVALID_DIAGDIR;
392 exitdir = INVALID_DIAGDIR;
393 }
394 }
395 break;
396
397 default:
398 continue; // continue the while() loop
399 }
400
401 if (!MaybeAddToTodoSet(tile, enterdir, oldtile, exitdir)) return flags | SF_FULL;
402 }
403
404 return flags;
405}
406
407
413 static void UpdateSignalsAroundSegment(SigFlags flags)
414{
415 TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280).
416 Trackdir trackdir = INVALID_TRACKDIR;
417
418 while (_tbuset.Get(&tile, &trackdir)) {
419 assert(HasSignalOnTrackdir(tile, trackdir));
420
421 Track track = TrackdirToTrack(trackdir);
422 SignalType sig = GetSignalType(tile, track);
423 SignalState newstate = SIGNAL_STATE_GREEN;
424
425 /* Signal state of reserved path signals is handled by the reserve/unreserve process. */
426 if (IsPbsSignal(sig) && (GetRailReservationTrackBits(tile) & TrackToTrackBits(track)) != TRACK_BIT_NONE) continue;
427
428 /* determine whether the new state is red */
429 if (flags & SF_TRAIN) {
430 /* train in the segment */
431 newstate = SIGNAL_STATE_RED;
432 } else if (IsPbsSignal(sig) && (flags & (SF_SPLIT | SF_ENTER2))) {
433 /* Turn path signals red if the segment has a junction or more than one way in. */
434 newstate = SIGNAL_STATE_RED;
435 } else {
436 /* is it a bidir combo? - then do not count its other signal direction as exit */
437 if (sig == SIGTYPE_COMBO && HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) {
438 /* at least one more exit */
439 if ((flags & SF_EXIT2) &&
440 /* no green exit */
441 (!(flags & SF_GREEN) ||
442 /* only one green exit, and it is this one - so all other exits are red */
443 (!(flags & SF_GREEN2) && GetSignalStateByTrackdir(tile, ReverseTrackdir(trackdir)) == SIGNAL_STATE_GREEN))) {
444 newstate = SIGNAL_STATE_RED;
445 }
446 } else { // entry, at least one exit, no green exit
447 if (IsPresignalEntry(tile, TrackdirToTrack(trackdir)) && (flags & SF_EXIT) && !(flags & SF_GREEN)) newstate = SIGNAL_STATE_RED;
448 }
449 }
450
451 /* only when the state changes */
452 if (newstate != GetSignalStateByTrackdir(tile, trackdir)) {
453 if (IsPresignalExit(tile, TrackdirToTrack(trackdir))) {
454 /* for pre-signal exits, add block to the global set */
455 DiagDirection exitdir = TrackdirToExitdir(ReverseTrackdir(trackdir));
456 _globset.Add(tile, exitdir); // do not check for full global set, first update all signals
457 }
458 SetSignalStateByTrackdir(tile, trackdir, newstate);
459 MarkTileDirtyByTile(tile);
460 }
461 }
462
463}
464
465
467 static inline void ResetSets()
468{
469 _tbuset.Reset();
470 _tbdset.Reset();
471 _globset.Reset();
472}
473
474
482 static SigSegState UpdateSignalsInBuffer(Owner owner)
483{
484 assert(Company::IsValidID(owner));
485
486 bool first = true; // first block?
487 SigSegState state = SIGSEG_FREE; // value to return
488
489 TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280).
490 DiagDirection dir = INVALID_DIAGDIR;
491
492 while (_globset.Get(&tile, &dir)) {
493 assert(_tbuset.IsEmpty());
494 assert(_tbdset.IsEmpty());
495
496 /* After updating signal, data stored are always MP_RAILWAY with signals.
497 * Other situations happen when data are from outside functions -
498 * modification of railbits (including both rail building and removal),
499 * train entering/leaving block, train leaving depot...
500 */
501 switch (GetTileType(tile)) {
502 case MP_TUNNELBRIDGE:
503 /* 'optimization assert' - do not try to update signals when it is not needed */
504 assert(GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL);
505 assert(dir == INVALID_DIAGDIR || dir == ReverseDiagDir(GetTunnelBridgeDirection(tile)));
506 _tbdset.Add(tile, INVALID_DIAGDIR); // we can safely start from wormhole centre
507 _tbdset.Add(GetOtherTunnelBridgeEnd(tile), INVALID_DIAGDIR);
508 break;
509
510 case MP_RAILWAY:
511 if (IsRailDepot(tile)) {
512 /* 'optimization assert' do not try to update signals in other cases */
513 assert(dir == INVALID_DIAGDIR || dir == GetRailDepotDirection(tile));
514 _tbdset.Add(tile, INVALID_DIAGDIR); // start from depot inside
515 break;
516 }
517 [[fallthrough]];
518
519 case MP_STATION:
520 case MP_ROAD:
521 if ((TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0)) & _enterdir_to_trackbits[dir]) != TRACK_BIT_NONE) {
522 /* only add to set when there is some 'interesting' track */
523 _tbdset.Add(tile, dir);
524 _tbdset.Add(tile + TileOffsByDiagDir(dir), ReverseDiagDir(dir));
525 break;
526 }
527 [[fallthrough]];
528
529 default:
530 /* jump to next tile */
531 tile = tile + TileOffsByDiagDir(dir);
532 dir = ReverseDiagDir(dir);
533 if ((TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0)) & _enterdir_to_trackbits[dir]) != TRACK_BIT_NONE) {
534 _tbdset.Add(tile, dir);
535 break;
536 }
537 /* happens when removing a rail that wasn't connected at one or both sides */
538 continue; // continue the while() loop
539 }
540
541 assert(!_tbdset.Overflowed()); // it really shouldn't overflow by these one or two items
542 assert(!_tbdset.IsEmpty()); // it wouldn't hurt anyone, but shouldn't happen too
543
544 SigFlags flags = ExploreSegment(owner);
545
546 if (first) {
547 first = false;
548 /* SIGSEG_FREE is set by default */
549 if (flags & SF_PBS) {
550 state = SIGSEG_PBS;
551 } else if ((flags & SF_TRAIN) || ((flags & SF_EXIT) && !(flags & SF_GREEN)) || (flags & SF_FULL)) {
552 state = SIGSEG_FULL;
553 }
554 }
555
556 /* do not do anything when some buffer was full */
557 if (flags & SF_FULL) {
558 ResetSets(); // free all sets
559 break;
560 }
561
562 UpdateSignalsAroundSegment(flags);
563 }
564
565 return state;
566}
567
568
569 static Owner _last_owner = INVALID_OWNER;
570
571
576 void UpdateSignalsInBuffer()
577{
578 if (!_globset.IsEmpty()) {
579 UpdateSignalsInBuffer(_last_owner);
580 _last_owner = INVALID_OWNER; // invalidate
581 }
582}
583
584
592 void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
593{
594 static const DiagDirection _search_dir_1[] = {
595 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
596 };
597 static const DiagDirection _search_dir_2[] = {
598 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
599 };
600
601 /* do not allow signal updates for two companies in one run */
602 assert(_globset.IsEmpty() || owner == _last_owner);
603
604 _last_owner = owner;
605
606 _globset.Add(tile, _search_dir_1[track]);
607 _globset.Add(tile, _search_dir_2[track]);
608
609 if (_globset.Items() >= SIG_GLOB_UPDATE) {
610 /* too many items, force update */
611 UpdateSignalsInBuffer(_last_owner);
612 _last_owner = INVALID_OWNER;
613 }
614}
615
616
624 void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
625{
626 /* do not allow signal updates for two companies in one run */
627 assert(_globset.IsEmpty() || owner == _last_owner);
628
629 _last_owner = owner;
630
631 _globset.Add(tile, side);
632
633 if (_globset.Items() >= SIG_GLOB_UPDATE) {
634 /* too many items, force update */
635 UpdateSignalsInBuffer(_last_owner);
636 _last_owner = INVALID_OWNER;
637 }
638}
639
650 SigSegState UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner)
651{
652 assert(_globset.IsEmpty());
653 _globset.Add(tile, side);
654
655 return UpdateSignalsInBuffer(owner);
656}
657
658
668 void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
669{
670 assert(_globset.IsEmpty());
671
672 AddTrackToSignalBuffer(tile, track, owner);
673 UpdateSignalsInBuffer(owner);
674}
FindFirstBit
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
Definition bitmath_func.hpp:213
HasAtMostOneBit
constexpr bool HasAtMostOneBit(T value)
Test whether value has at most 1 bit set.
Definition bitmath_func.hpp:290
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:171
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
Owner
Owner
Enum for all companies/owners.
Definition company_type.h:18
INVALID_OWNER
@ INVALID_OWNER
An invalid owner.
Definition company_type.h:29
debug.h
Functions related to debugging.
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition debug.h:37
ReverseDiagDir
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition direction_func.h:118
IsValidDiagDirection
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
Definition direction_func.h:21
DiagDirToAxis
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Definition direction_func.h:214
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition direction_type.h:73
DIAGDIR_NE
@ DIAGDIR_NE
Northeast, upper right on your monitor.
Definition direction_type.h:75
DIAGDIR_NW
@ DIAGDIR_NW
Northwest.
Definition direction_type.h:78
DIAGDIR_SE
@ DIAGDIR_SE
Southeast.
Definition direction_type.h:76
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition direction_type.h:79
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition direction_type.h:74
INVALID_DIAGDIR
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition direction_type.h:80
DIAGDIR_SW
@ DIAGDIR_SW
Southwest.
Definition direction_type.h:77
DECLARE_ENUM_AS_BIT_SET
#define DECLARE_ENUM_AS_BIT_SET(enum_type)
Operators to allow to work with enum as with type safe bit set in C++.
Definition enum_type.hpp:35
MarkTileDirtyByTile
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition viewport.cpp:2057
GetTileTrackStatus
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition landscape.cpp:554
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:567
pbs.h
PBS support routines.
HasSignalOnTrackdir
bool HasSignalOnTrackdir(Tile tile, Trackdir trackdir)
Checks for the presence of signals along the given trackdir on the given rail tile.
Definition rail_map.h:426
GetTrackBits
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
GetRailDepotDirection
DiagDirection GetRailDepotDirection(Tile t)
Returns the direction the depot is facing to.
Definition rail_map.h:171
SetSignalStateByTrackdir
void SetSignalStateByTrackdir(Tile tile, Trackdir trackdir, SignalState state)
Sets the state of the signal along the given trackdir.
Definition rail_map.h:449
HasSignalOnTrack
bool HasSignalOnTrack(Tile tile, Track track)
Checks for the presence of signals (either way) on the given track on the given rail tile.
Definition rail_map.h:413
IsOnewaySignal
bool IsOnewaySignal(Tile t, Track track)
One-way signals can't be passed the 'wrong' way.
Definition rail_map.h:319
IsRailDepot
static debug_inline bool IsRailDepot(Tile t)
Is this rail tile a rail depot?
Definition rail_map.h:95
GetRailReservationTrackBits
TrackBits GetRailReservationTrackBits(Tile t)
Returns the reserved track bits of the tile.
Definition rail_map.h:194
HasSignals
bool HasSignals(Tile t)
Checks if a rail tile has signals.
Definition rail_map.h:72
GetSignalStateByTrackdir
SignalState GetSignalStateByTrackdir(Tile tile, Trackdir trackdir)
Gets the state of the signal along the given trackdir.
Definition rail_map.h:438
GetCrossingRoadAxis
Axis GetCrossingRoadAxis(Tile t)
Get the road axis of a level crossing.
Definition road_map.h:325
IsLevelCrossing
bool IsLevelCrossing(Tile t)
Return whether a tile is a level crossing.
Definition road_map.h:85
safeguards.h
A number of safeguards to prevent using unsafe methods.
_last_owner
static Owner _last_owner
last owner whose track was put into _globset
Definition signal.cpp:569
MaybeAddToTodoSet
static bool MaybeAddToTodoSet(TileIndex t1, DiagDirection d1, TileIndex t2, DiagDirection d2)
Perform some operations before adding data into Todo set The new and reverse direction is removed fro...
Definition signal.cpp:237
_enterdir_to_trackdirbits
static const TrackdirBits _enterdir_to_trackdirbits[DIAGDIR_END]
incidating trackdirbits with given enterdir
Definition signal.cpp:40
_tbuset
static SmallSet< Trackdir, SIG_TBU_SIZE > _tbuset("_tbuset")
set of signals that will be updated
_globset
static SmallSet< DiagDirection, SIG_GLOB_SIZE > _globset("_globset")
set of places to be updated in following runs
AddTrackToSignalBuffer
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
Add track to signal update buffer.
Definition signal.cpp:592
UpdateSignalsOnSegment
SigSegState UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner)
Update signals, starting at one side of a tile Will check tile next to this at opposite side too.
Definition signal.cpp:650
UpdateSignalsInBuffer
void UpdateSignalsInBuffer()
Update signals in buffer Called from 'outside'.
Definition signal.cpp:576
SIG_TBD_SIZE
static const uint SIG_TBD_SIZE
number of intersections - open nodes in current block
Definition signal.cpp:25
AddSideToSignalBuffer
void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
Add side of tile to signal update buffer.
Definition signal.cpp:624
SIG_GLOB_SIZE
static const uint SIG_GLOB_SIZE
number of open blocks (block can be opened more times until detected)
Definition signal.cpp:26
ResetSets
static void ResetSets()
Reset all sets after one set overflowed.
Definition signal.cpp:467
_tbdset
static SmallSet< DiagDirection, SIG_TBD_SIZE > _tbdset("_tbdset")
set of open nodes in current signal block
SIG_TBU_SIZE
static const uint SIG_TBU_SIZE
these are the maximums used for updating signal blocks
Definition signal.cpp:24
UpdateSignalsAroundSegment
static void UpdateSignalsAroundSegment(SigFlags flags)
Update signals around segment in _tbuset.
Definition signal.cpp:413
SetSignalsOnBothDir
void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
Update signals at segments that are at both ends of given (existent or non-existent) track.
Definition signal.cpp:668
SigFlags
SigFlags
Current signal block state flags.
Definition signal.cpp:246
SF_SPLIT
@ SF_SPLIT
track merge/split found
Definition signal.cpp:255
SF_GREEN2
@ SF_GREEN2
two or more green exits found
Definition signal.cpp:252
SF_EXIT2
@ SF_EXIT2
two or more exits found
Definition signal.cpp:250
SF_ENTER2
@ SF_ENTER2
two or more signals entering the block found
Definition signal.cpp:257
SF_PBS
@ SF_PBS
pbs signal found
Definition signal.cpp:254
SF_GREEN
@ SF_GREEN
green exitsignal found
Definition signal.cpp:251
SF_ENTER
@ SF_ENTER
signal entering the block found
Definition signal.cpp:256
SF_EXIT
@ SF_EXIT
exitsignal found
Definition signal.cpp:249
SF_FULL
@ SF_FULL
some of buffers was full, do not continue
Definition signal.cpp:253
SF_TRAIN
@ SF_TRAIN
train found in segment
Definition signal.cpp:248
TrainOnTileEnum
static Vehicle * TrainOnTileEnum(Vehicle *v, void *)
Check whether there is a train on rail, not in a depot.
Definition signal.cpp:192
SIG_GLOB_UPDATE
static const uint SIG_GLOB_UPDATE
how many items need to be in _globset to force update
Definition signal.cpp:27
CheckAddToTodoSet
static bool CheckAddToTodoSet(TileIndex t1, DiagDirection d1, TileIndex t2, DiagDirection d2)
Perform some operations before adding data into Todo set The new and reverse direction is removed fro...
Definition signal.cpp:213
_enterdir_to_trackbits
static const TrackBits _enterdir_to_trackbits[DIAGDIR_END]
incidating trackbits with given enterdir
Definition signal.cpp:32
ExploreSegment
static SigFlags ExploreSegment(Owner owner)
Search signal block.
Definition signal.cpp:269
SigSegState
SigSegState
State of the signal segment.
Definition signal_func.h:49
SIGSEG_PBS
@ SIGSEG_PBS
Segment is a PBS segment.
Definition signal_func.h:52
SIGSEG_FREE
@ SIGSEG_FREE
Free and has no pre-signal exits or at least one green exit.
Definition signal_func.h:50
SIGSEG_FULL
@ SIGSEG_FULL
Occupied by a train.
Definition signal_func.h:51
SignalType
SignalType
Type of signal, i.e.
Definition signal_type.h:23
SIGTYPE_COMBO
@ SIGTYPE_COMBO
presignal inter-block
Definition signal_type.h:27
SignalState
SignalState
These are states in which a signal can be.
Definition signal_type.h:42
SIGNAL_STATE_RED
@ SIGNAL_STATE_RED
The signal is red.
Definition signal_type.h:43
SIGNAL_STATE_GREEN
@ SIGNAL_STATE_GREEN
The signal is green.
Definition signal_type.h:44
station_map.h
Maps accessors for stations.
GetRailStationAxis
Axis GetRailStationAxis(Tile t)
Get the rail direction of a rail station.
Definition station_map.h:503
IsStationTileBlocked
bool IsStationTileBlocked(Tile t)
Is tile t a blocked tile?
Definition station_map.h:431
HasStationRail
bool HasStationRail(Tile t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint?
Definition station_map.h:135
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
lengthof
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:280
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition vehicle_type.h:51
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition pool_type.hpp:328
SmallSet::SSdata
Element of set.
Definition signal.cpp:60
SmallSet
Set containing 'items' items of 'tile and Tdir' No tree structure is used because it would cause slow...
Definition signal.cpp:53
SmallSet::Add
bool Add(TileIndex tile, Tdir dir)
Adds tile & dir into the set, checks for full set Sets the 'overflowed' flag if the set was full.
Definition signal.cpp:153
SmallSet::Overflowed
bool Overflowed()
Returns value of 'overflowed'.
Definition signal.cpp:80
SmallSet::Remove
bool Remove(TileIndex tile, Tdir dir)
Tries to remove first instance of given tile and dir.
Definition signal.cpp:119
SmallSet::SmallSet
SmallSet(const char *name)
Constructor - just set default values and 'name'.
Definition signal.cpp:67
SmallSet::Get
bool Get(TileIndex *tile, Tdir *dir)
Reads the last added element into the set.
Definition signal.cpp:174
SmallSet::Reset
void Reset()
Reset variables to default values.
Definition signal.cpp:70
SmallSet::Items
uint Items()
Reads the number of items.
Definition signal.cpp:107
SmallSet::IsIn
bool IsIn(TileIndex tile, Tdir dir)
Tries to find given tile and dir in the set.
Definition signal.cpp:137
SmallSet::IsEmpty
bool IsEmpty()
Checks for empty set.
Definition signal.cpp:89
SmallSet::IsFull
bool IsFull()
Checks for full set.
Definition signal.cpp:98
SpecializedVehicle::From
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition vehicle_base.h:1215
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
Vehicle
Vehicle data structure.
Definition vehicle_base.h:244
GetTileOwner
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
GetTileType
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
MP_ROAD
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
MP_RAILWAY
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
TrackdirToTrack
Track TrackdirToTrack(Trackdir trackdir)
Returns the Track that a given Trackdir represents.
Definition track_func.h:262
TrackToTrackBits
TrackBits TrackToTrackBits(Track track)
Maps a Track to the corresponding TrackBits value.
Definition track_func.h:77
TrackBitsToTrack
Track TrackBitsToTrack(TrackBits tracks)
Converts TrackBits to Track.
Definition track_func.h:193
ReverseTrackdir
Trackdir ReverseTrackdir(Trackdir trackdir)
Maps a trackdir to the reverse trackdir.
Definition track_func.h:247
TrackStatusToTrackBits
TrackBits TrackStatusToTrackBits(TrackStatus ts)
Returns the present-track-information of a TrackStatus.
Definition track_func.h:363
TrackdirToExitdir
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition track_func.h:439
TrackBits
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
TRACK_BIT_DEPOT
@ TRACK_BIT_DEPOT
Bitflag for a depot.
Definition track_type.h:53
TRACK_BIT_HORZ
@ TRACK_BIT_HORZ
Upper and lower track.
Definition track_type.h:44
TRACK_BIT_NONE
@ TRACK_BIT_NONE
No track.
Definition track_type.h:36
TRACK_BIT_3WAY_NW
@ TRACK_BIT_3WAY_NW
"Arrow" to the north-west
Definition track_type.h:49
TRACK_BIT_3WAY_NE
@ TRACK_BIT_3WAY_NE
"Arrow" to the north-east
Definition track_type.h:46
TRACK_BIT_3WAY_SW
@ TRACK_BIT_3WAY_SW
"Arrow" to the south-west
Definition track_type.h:48
TRACK_BIT_VERT
@ TRACK_BIT_VERT
Left and right track.
Definition track_type.h:45
TRACK_BIT_3WAY_SE
@ TRACK_BIT_3WAY_SE
"Arrow" to the south-east
Definition track_type.h:47
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition track_type.h:67
INVALID_TRACKDIR
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition track_type.h:86
TrackdirBits
TrackdirBits
Allow incrementing of Trackdir variables.
Definition track_type.h:98
TRACKDIR_BIT_LEFT_S
@ TRACKDIR_BIT_LEFT_S
Track left, direction south.
Definition track_type.h:104
TRACKDIR_BIT_Y_NW
@ TRACKDIR_BIT_Y_NW
Track y-axis, direction north-west.
Definition track_type.h:108
TRACKDIR_BIT_UPPER_E
@ TRACKDIR_BIT_UPPER_E
Track upper, direction east.
Definition track_type.h:102
TRACKDIR_BIT_X_NE
@ TRACKDIR_BIT_X_NE
Track x-axis, direction north-east.
Definition track_type.h:100
TRACKDIR_BIT_LOWER_E
@ TRACKDIR_BIT_LOWER_E
Track lower, direction east.
Definition track_type.h:103
TRACKDIR_BIT_LEFT_N
@ TRACKDIR_BIT_LEFT_N
Track left, direction north.
Definition track_type.h:111
TRACKDIR_BIT_RIGHT_S
@ TRACKDIR_BIT_RIGHT_S
Track right, direction south.
Definition track_type.h:105
TRACKDIR_BIT_Y_SE
@ TRACKDIR_BIT_Y_SE
Track y-axis, direction south-east.
Definition track_type.h:101
TRACKDIR_BIT_RIGHT_N
@ TRACKDIR_BIT_RIGHT_N
Track right, direction north.
Definition track_type.h:112
TRACKDIR_BIT_UPPER_W
@ TRACKDIR_BIT_UPPER_W
Track upper, direction west.
Definition track_type.h:109
TRACKDIR_BIT_LOWER_W
@ TRACKDIR_BIT_LOWER_W
Track lower, direction west.
Definition track_type.h:110
TRACKDIR_BIT_X_SW
@ TRACKDIR_BIT_X_SW
Track x-axis, direction south-west.
Definition track_type.h:107
Track
Track
These are used to specify a single track.
Definition track_type.h:19
train.h
Base for the train class.
TRANSPORT_RAIL
@ TRANSPORT_RAIL
Transport by train.
Definition transport_type.h:27
tunnelbridge_map.h
Functions that have tunnels and bridges in common.
GetTunnelBridgeDirection
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
Definition tunnelbridge_map.h:26
GetTunnelBridgeTransportType
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
Definition tunnelbridge_map.h:39
GetOtherTunnelBridgeEnd
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
Definition tunnelbridge_map.h:78
EnsureNoTrainOnTrackBits
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
Tests if a vehicle interacts with the specified track bits.
Definition vehicle.cpp:608
HasVehicleOnPos
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition vehicle.cpp:520
vehicle_func.h
Functions related to vehicles.
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:24
viewport_func.h
Functions related to (drawing on) viewports.