755 if (!HasSignalOnTrack(tile, track)) { |
757 if (!HasSignalOnTrack(tile, track)) { |
756 // build new signals |
758 // build new signals |
757 _map3_lo[tile] |= SignalOnTrack(track); |
759 _map3_lo[tile] |= SignalOnTrack(track); |
758 } else { |
760 } else { |
759 if (pre_signal) { |
761 if (pre_signal) { |
760 // cycle between normal -> pre -> exit -> combo -> ... |
762 // cycle between normal -> pre -> exit -> combo -> pbs ->... |
761 byte type = (GetSignalType(tile, track) + 1) & 0x03; |
763 byte type = ((GetSignalType(tile, track) + 1) % 5); |
762 _map3_hi[tile] &= ~0x03; |
764 _map3_hi[tile] &= ~0x07; |
763 _map3_hi[tile] |= type; |
765 _map3_hi[tile] |= type ; |
764 } else { |
766 } else { |
765 // cycle between two-way -> one-way -> one-way -> ... |
767 // cycle between two-way -> one-way -> one-way -> ... |
766 /* TODO: Rewrite switch into something more general */ |
768 /* TODO: Rewrite switch into something more general */ |
767 switch (track) { |
769 switch (track) { |
768 case TRACK_LOWER: |
770 case TRACK_LOWER: |
1121 0x4FB, |
1123 0x4FB, |
1122 0x1323, |
1124 0x1323, |
1123 0x1333, |
1125 0x1333, |
1124 0x1343, |
1126 0x1343, |
1125 |
1127 |
1126 0x0, //PBS place, light signal |
1128 // pbs signals |
1127 0x0, //reserved for future use |
1129 0x1393, |
1128 0x0, //reserved for future use |
1130 0x13A3, // not used (yet?) |
1129 0x0, //reserved for future use |
1131 0x13B3, // not used (yet?) |
1130 |
1132 0x13C3, // not used (yet?) |
1131 // use semaphores instead of signals? |
1133 |
|
1134 // semaphores |
1132 0x1353, |
1135 0x1353, |
1133 0x1363, |
1136 0x1363, |
1134 0x1373, |
1137 0x1373, |
1135 0x1383, |
1138 0x1383, |
1136 |
1139 |
1137 0x0, //PBS place, semaphore |
1140 // pbs semaphores |
1138 0x0, //reserved for future use |
1141 0x13D3, |
1139 0x0, //reserved for future use |
1142 0x13E3, // not used (yet?) |
1140 0x0, //reserved for future use |
1143 0x13F3, // not used (yet?) |
|
1144 0x1403, // not used (yet?) |
|
1145 |
1141 |
1146 |
1142 // mirrored versions |
1147 // mirrored versions |
1143 0x4FB, |
1148 0x4FB, |
1144 0x1323, |
1149 0x1323, |
1145 0x1333, |
1150 0x1333, |
1146 0x1343, |
1151 0x1343, |
1147 |
1152 |
1148 0x0, //PBS place, semaphore |
1153 // pbs signals |
1149 0x0, //reserved for future use |
1154 0x1393, |
1150 0x0, //reserved for future use |
1155 0x13A3, // not used (yet?) |
1151 0x0, //reserved for future use |
1156 0x13B3, // not used (yet?) |
1152 |
1157 0x13C3, // not used (yet?) |
1153 0x13C6, |
1158 |
1154 0x13D6, |
1159 // semaphores |
1155 0x13E6, |
1160 0x1446, |
1156 0x13F6, |
1161 0x1456, |
1157 |
1162 0x1466, |
1158 0x0, //PBS place, semaphore |
1163 0x1476, |
1159 0x0, //reserved for future use |
1164 |
1160 0x0, //reserved for future use |
1165 // pbs semaphores |
1161 0x0, //reserved for future use |
1166 0x14C6, |
|
1167 0x14D6, // not used (yet?) |
|
1168 0x14E6, // not used (yet?) |
|
1169 0x14F6, // not used (yet?) |
1162 }; |
1170 }; |
1163 |
1171 |
1164 // used to determine the side of the road for the signal |
1172 // used to determine the side of the road for the signal |
1165 static const byte _signal_position[24] = { |
1173 static const byte _signal_position[24] = { |
1166 /* original: left side position */ |
1174 /* original: left side position */ |
1464 if (m5 & TRACK_BIT_LOWER) DrawGroundSprite(TrackSet[SINGLE_SOUTH]); |
1472 if (m5 & TRACK_BIT_LOWER) DrawGroundSprite(TrackSet[SINGLE_SOUTH]); |
1465 if (m5 & TRACK_BIT_LEFT) DrawGroundSprite(TrackSet[SINGLE_WEST]); |
1473 if (m5 & TRACK_BIT_LEFT) DrawGroundSprite(TrackSet[SINGLE_WEST]); |
1466 if (m5 & TRACK_BIT_RIGHT) DrawGroundSprite(TrackSet[SINGLE_EAST]); |
1474 if (m5 & TRACK_BIT_RIGHT) DrawGroundSprite(TrackSet[SINGLE_EAST]); |
1467 } |
1475 } |
1468 |
1476 |
|
1477 if (_debug_pbs_level >= 1) { |
|
1478 byte pbs = PBSTileReserved(ti->tile); |
|
1479 if (pbs & TRACK_BIT_DIAG1) DrawGroundSprite(TrackSet[SINGLE_Y] | PALETTE_CRASH); |
|
1480 if (pbs & TRACK_BIT_DIAG2) DrawGroundSprite(TrackSet[SINGLE_X] | PALETTE_CRASH); |
|
1481 if (pbs & TRACK_BIT_UPPER) DrawGroundSprite(TrackSet[SINGLE_NORTH] | PALETTE_CRASH); |
|
1482 if (pbs & TRACK_BIT_LOWER) DrawGroundSprite(TrackSet[SINGLE_SOUTH] | PALETTE_CRASH); |
|
1483 if (pbs & TRACK_BIT_LEFT) DrawGroundSprite(TrackSet[SINGLE_WEST] | PALETTE_CRASH); |
|
1484 if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite(TrackSet[SINGLE_EAST] | PALETTE_CRASH); |
|
1485 } |
|
1486 |
1469 if (_display_opt & DO_FULL_DETAIL) { |
1487 if (_display_opt & DO_FULL_DETAIL) { |
1470 _detailed_track_proc[_map2[ti->tile] & RAIL_MAP2LO_GROUND_MASK](ti); |
1488 _detailed_track_proc[_map2[ti->tile] & RAIL_MAP2LO_GROUND_MASK](ti); |
1471 } |
1489 } |
1472 |
1490 |
1473 /* draw signals also? */ |
1491 /* draw signals also? */ |
1573 image = 4550; // flat ground |
1591 image = 4550; // flat ground |
1574 } |
1592 } |
1575 |
1593 |
1576 DrawGroundSprite(image); |
1594 DrawGroundSprite(image); |
1577 |
1595 |
|
1596 if (_debug_pbs_level >= 1) { |
|
1597 byte pbs = PBSTileReserved(ti->tile); |
|
1598 if (pbs & TRACK_BIT_DIAG1) DrawGroundSprite((0x3ED + tracktype_offs) | PALETTE_CRASH); |
|
1599 if (pbs & TRACK_BIT_DIAG2) DrawGroundSprite((0x3EE + tracktype_offs) | PALETTE_CRASH); |
|
1600 if (pbs & TRACK_BIT_UPPER) DrawGroundSprite((0x3EF + tracktype_offs) | PALETTE_CRASH); |
|
1601 if (pbs & TRACK_BIT_LOWER) DrawGroundSprite((0x3F0 + tracktype_offs) | PALETTE_CRASH); |
|
1602 if (pbs & TRACK_BIT_LEFT) DrawGroundSprite((0x3F2 + tracktype_offs) | PALETTE_CRASH); |
|
1603 if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite((0x3F1 + tracktype_offs) | PALETTE_CRASH); |
|
1604 } |
|
1605 |
1578 while ((image=drss->image) != 0) { |
1606 while ((image=drss->image) != 0) { |
1579 DrawSpecialBuilding(image, type < 4 ? tracktype_offs : 0, ti, |
1607 DrawSpecialBuilding(image, type < 4 ? tracktype_offs : 0, ti, |
1580 drss->subcoord_x, drss->subcoord_y, 0, |
1608 drss->subcoord_x, drss->subcoord_y, 0, |
1581 drss->width, drss->height, 0x17); |
1609 drss->width, drss->height, 0x17); |
1582 drss++; |
1610 drss++; |
1609 if (image & 0x8000) image |= ormod; |
1637 if (image & 0x8000) image |= ormod; |
1610 DrawSprite(image + railtype, x + pt.x, y + pt.y); |
1638 DrawSprite(image + railtype, x + pt.x, y + pt.y); |
1611 } |
1639 } |
1612 } |
1640 } |
1613 |
1641 |
1614 #define NUM_SSD_ENTRY 256 |
|
1615 #define NUM_SSD_STACK 32 |
|
1616 |
|
1617 typedef struct SetSignalsData { |
1642 typedef struct SetSignalsData { |
1618 int cur; |
1643 int cur; |
1619 int cur_stack; |
1644 int cur_stack; |
1620 bool stop; |
1645 bool stop; |
1621 bool has_presignal; |
1646 bool has_presignal; |
1622 |
1647 |
|
1648 bool has_pbssignal; |
|
1649 // lowest 2 bits = amount of pbs signals in the block, clamped at 2 |
|
1650 // bit 2 = there is a pbs entry signal in this block |
|
1651 // bit 3 = there is a pbs exit signal in this block |
|
1652 |
1623 // presignal info |
1653 // presignal info |
1624 int presignal_exits; |
1654 int presignal_exits; |
1625 int presignal_exits_free; |
1655 int presignal_exits_free; |
1626 |
1656 |
1627 // these are used to keep track of the signals that change. |
1657 // these are used to keep track of the signals that change. |
1628 byte bit[NUM_SSD_ENTRY]; |
1658 byte bit[NUM_SSD_ENTRY]; |
1629 TileIndex tile[NUM_SSD_ENTRY]; |
1659 TileIndex tile[NUM_SSD_ENTRY]; |
|
1660 |
|
1661 int pbs_cur; |
|
1662 // these are used to keep track of all signals in the block |
|
1663 TileIndex pbs_tile[NUM_SSD_ENTRY]; |
1630 |
1664 |
1631 // these are used to keep track of the stack that modifies presignals recursively |
1665 // these are used to keep track of the stack that modifies presignals recursively |
1632 TileIndex next_tile[NUM_SSD_STACK]; |
1666 TileIndex next_tile[NUM_SSD_STACK]; |
1633 byte next_dir[NUM_SSD_STACK]; |
1667 byte next_dir[NUM_SSD_STACK]; |
1634 |
1668 |
1645 ssd->tile[ssd->cur] = tile; // remember the tile index |
1679 ssd->tile[ssd->cur] = tile; // remember the tile index |
1646 ssd->bit[ssd->cur] = track; // and the controlling bit number |
1680 ssd->bit[ssd->cur] = track; // and the controlling bit number |
1647 ssd->cur++; |
1681 ssd->cur++; |
1648 } |
1682 } |
1649 |
1683 |
|
1684 if (PBSIsPbsSignal(tile, ReverseTrackdir(track))) |
|
1685 SETBIT(ssd->has_pbssignal, 2); |
|
1686 |
1650 // remember if this block has a presignal. |
1687 // remember if this block has a presignal. |
1651 ssd->has_presignal |= (_map3_hi[tile]&1); |
1688 ssd->has_presignal |= (_map3_hi[tile]&1); |
1652 } |
1689 } |
1653 |
1690 |
1654 // is this an exit signal that points out from the segment? |
1691 if (PBSIsPbsSignal(tile, ReverseTrackdir(track)) || PBSIsPbsSignal(tile, track)) { |
1655 if ((_map3_hi[tile]&2) && _map3_lo[tile]&_signals_table_other[track]) { |
1692 byte num = ssd->has_pbssignal & 3; |
1656 ssd->presignal_exits++; |
1693 num = clamp(num + 1, 0, 2); |
1657 if ((_map2[tile]&_signals_table_other[track]) != 0) |
1694 ssd->has_pbssignal &= ~3; |
1658 ssd->presignal_exits_free++; |
1695 ssd->has_pbssignal |= num; |
|
1696 } |
|
1697 |
|
1698 if ((_map3_lo[tile] & _signals_table_both[track]) != 0) { |
|
1699 ssd->pbs_tile[ssd->pbs_cur] = tile; // remember the tile index |
|
1700 ssd->pbs_cur++; |
|
1701 } |
|
1702 |
|
1703 if (_map3_lo[tile]&_signals_table_other[track]) { |
|
1704 if (_map3_hi[tile]&2) { |
|
1705 // this is an exit signal that points out from the segment |
|
1706 ssd->presignal_exits++; |
|
1707 if ((_map2[tile]&_signals_table_other[track]) != 0) |
|
1708 ssd->presignal_exits_free++; |
|
1709 } |
|
1710 if (PBSIsPbsSignal(tile, track)) |
|
1711 SETBIT(ssd->has_pbssignal, 3); |
1659 } |
1712 } |
1660 |
1713 |
1661 return true; |
1714 return true; |
1662 } else if (IsTileDepotType(tile, TRANSPORT_RAIL)) |
1715 } else if (IsTileDepotType(tile, TRANSPORT_RAIL)) |
1663 return true; // don't look further if the tile is a depot |
1716 return true; // don't look further if the tile is a depot |
1790 // the presignal is green if, |
1843 // the presignal is green if, |
1791 // if no train is in the segment AND |
1844 // if no train is in the segment AND |
1792 // there is at least one green exit signal OR |
1845 // there is at least one green exit signal OR |
1793 // there are no exit signals in the segment |
1846 // there are no exit signals in the segment |
1794 |
1847 |
|
1848 // convert the block to pbs, if needed |
|
1849 if (_patches.auto_pbs_placement && !(ssd->stop) && (ssd->has_pbssignal == 0xE) && !ssd->has_presignal && (ssd->presignal_exits == 0)) // 0xE means at least 2 pbs signals, and at least 1 entry and 1 exit, see comments ssd->has_pbssignal |
|
1850 for(i=0; i!=ssd->pbs_cur; i++) { |
|
1851 TileIndex tile = ssd->pbs_tile[i]; |
|
1852 _map3_hi[tile] &= ~0x07; |
|
1853 _map3_hi[tile] |= 0x04; |
|
1854 MarkTileDirtyByTile(tile); |
|
1855 }; |
|
1856 |
1795 // then mark the signals in the segment accordingly |
1857 // then mark the signals in the segment accordingly |
1796 for(i=0; i!=ssd->cur; i++) { |
1858 for(i=0; i!=ssd->cur; i++) { |
1797 TileIndex tile = ssd->tile[i]; |
1859 TileIndex tile = ssd->tile[i]; |
1798 byte bit = _signals_table[ssd->bit[i]]; |
1860 byte bit = _signals_table[ssd->bit[i]]; |
1799 uint16 m2 = _map2[tile]; |
1861 uint16 m2 = _map2[tile]; |
1850 ssd.cur_stack = 0; |
1912 ssd.cur_stack = 0; |
1851 direction>>=1; |
1913 direction>>=1; |
1852 |
1914 |
1853 for(;;) { |
1915 for(;;) { |
1854 // go through one segment and update all signals pointing into that segment. |
1916 // go through one segment and update all signals pointing into that segment. |
1855 ssd.cur = ssd.presignal_exits = ssd.presignal_exits_free = 0; |
1917 ssd.cur = ssd.pbs_cur = ssd.presignal_exits = ssd.presignal_exits_free = 0; |
1856 ssd.has_presignal = false; |
1918 ssd.has_presignal = false; |
|
1919 ssd.has_pbssignal = false; |
1857 |
1920 |
1858 FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, (TPFEnumProc*)SetSignalsEnumProc, SetSignalsAfterProc, &ssd); |
1921 FollowTrack(tile, 0xC000 | TRANSPORT_RAIL, direction, (TPFEnumProc*)SetSignalsEnumProc, SetSignalsAfterProc, &ssd); |
1859 ChangeSignalStates(&ssd); |
1922 ChangeSignalStates(&ssd); |
1860 |
1923 |
1861 // remember the result only for the first iteration. |
1924 // remember the result only for the first iteration. |
2160 /* make sure a train is not entering the tile from behind */ |
2223 /* make sure a train is not entering the tile from behind */ |
2161 return 8; |
2224 return 8; |
2162 } else if (_fractcoords_enter[dir] == fract_coord) { |
2225 } else if (_fractcoords_enter[dir] == fract_coord) { |
2163 if (_enter_directions[dir] == v->direction) { |
2226 if (_enter_directions[dir] == v->direction) { |
2164 /* enter the depot */ |
2227 /* enter the depot */ |
|
2228 if (v->next == NULL) |
|
2229 PBSClearTrack(v->tile, FIND_FIRST_BIT(v->u.rail.track)); |
2165 v->u.rail.track = 0x80, |
2230 v->u.rail.track = 0x80, |
2166 v->vehstatus |= VS_HIDDEN; /* hide it */ |
2231 v->vehstatus |= VS_HIDDEN; /* hide it */ |
2167 v->direction ^= 4; |
2232 v->direction ^= 4; |
2168 if (v->next == NULL) |
2233 if (v->next == NULL) |
2169 TrainEnterDepot(v, tile); |
2234 TrainEnterDepot(v, tile); |