112 0x16, |
112 0x16, |
113 0x25, |
113 0x25, |
114 0x2A, |
114 0x2A, |
115 }; |
115 }; |
116 |
116 |
117 static const byte _tpf_new_direction[14] = { |
117 static const DiagDirection _tpf_new_direction[14] = { |
118 0, 1, 0, 1, 2, 1, |
118 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, |
119 0, 0, |
119 INVALID_DIAGDIR, INVALID_DIAGDIR, |
120 2, 3, 3, 2, 3, 0, |
120 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, |
121 }; |
121 }; |
122 |
122 |
123 static const byte _tpf_prev_direction[14] = { |
123 static const DiagDirection _tpf_prev_direction[14] = { |
124 0, 1, 1, 0, 1, 2, |
124 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, |
125 0, 0, |
125 INVALID_DIAGDIR, INVALID_DIAGDIR, |
126 2, 3, 2, 3, 0, 3, |
126 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, |
127 }; |
127 }; |
128 |
128 |
129 |
129 |
130 static const byte _otherdir_mask[4] = { |
130 static const byte _otherdir_mask[4] = { |
131 0x10, |
131 0x10, |
180 } |
180 } |
181 tpf->rd.pft_var6 = (byte)i; |
181 tpf->rd.pft_var6 = (byte)i; |
182 } |
182 } |
183 |
183 |
184 continue_here:; |
184 continue_here:; |
185 tpf->the_dir = i + (HASBIT(_otherdir_mask[direction], i) ? 8 : 0); |
185 tpf->the_dir = (Trackdir)(i + (HASBIT(_otherdir_mask[direction], i) ? 8 : 0)); |
186 |
186 |
187 if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, NULL)) { |
187 if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, NULL)) { |
188 TPFMode2(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
188 TPFMode2(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
189 } |
189 } |
190 |
190 |
331 if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KILL_FIRST_BIT(bits) == 0 || ++tpf->rd.depth <= 7))) { |
331 if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KILL_FIRST_BIT(bits) == 0 || ++tpf->rd.depth <= 7))) { |
332 do { |
332 do { |
333 i = FIND_FIRST_BIT(bits); |
333 i = FIND_FIRST_BIT(bits); |
334 bits = KILL_FIRST_BIT(bits); |
334 bits = KILL_FIRST_BIT(bits); |
335 |
335 |
336 tpf->the_dir = (_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i; |
336 tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i); |
337 rd = tpf->rd; |
337 rd = tpf->rd; |
338 |
338 |
339 if (TPFSetTileBit(tpf, tile, tpf->the_dir) && |
339 if (TPFSetTileBit(tpf, tile, tpf->the_dir) && |
340 !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) { |
340 !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) { |
341 TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
341 TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
373 |
373 |
374 do { |
374 do { |
375 i = FIND_FIRST_BIT(bits); |
375 i = FIND_FIRST_BIT(bits); |
376 bits = KILL_FIRST_BIT(bits); |
376 bits = KILL_FIRST_BIT(bits); |
377 |
377 |
378 tpf->the_dir = (_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i; |
378 tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i); |
379 rd = tpf->rd; |
379 rd = tpf->rd; |
380 if (TPFSetTileBit(tpf, tile, tpf->the_dir) && |
380 if (TPFSetTileBit(tpf, tile, tpf->the_dir) && |
381 !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) { |
381 !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) { |
382 TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
382 TPFMode1(tpf, tile, _tpf_new_direction[tpf->the_dir]); |
383 } |
383 } |
405 |
405 |
406 tpf.disable_tile_hash = HASBIT(flags, 12); /* 0x1000 */ |
406 tpf.disable_tile_hash = HASBIT(flags, 12); /* 0x1000 */ |
407 tpf.hasbit_13 = HASBIT(flags, 13); /* 0x2000 */ |
407 tpf.hasbit_13 = HASBIT(flags, 13); /* 0x2000 */ |
408 |
408 |
409 |
409 |
410 tpf.tracktype = (byte)flags; |
410 tpf.tracktype = (TransportType)(flags & 0xFF); |
411 |
411 |
412 if (HASBIT(flags, 11)) { |
412 if (HASBIT(flags, 11)) { |
413 tpf.rd.pft_var6 = 0xFF; |
413 tpf.rd.pft_var6 = 0xFF; |
414 tpf.enum_proc(tile, data, 0, 0, 0); |
414 tpf.enum_proc(tile, data, INVALID_TRACKDIR, 0, 0); |
415 TPFMode2(&tpf, tile, direction); |
415 TPFMode2(&tpf, tile, direction); |
416 } else { |
416 } else { |
417 /* clear the hash_heads */ |
417 /* clear the hash_heads */ |
418 memset(tpf.hash_head, 0, sizeof(tpf.hash_head)); |
418 memset(tpf.hash_head, 0, sizeof(tpf.hash_head)); |
419 TPFMode1(&tpf, tile, direction); |
419 TPFMode1(&tpf, tile, direction); |
425 |
425 |
426 typedef struct { |
426 typedef struct { |
427 TileIndex tile; |
427 TileIndex tile; |
428 uint16 cur_length; // This is the current length to this tile. |
428 uint16 cur_length; // This is the current length to this tile. |
429 uint16 priority; // This is the current length + estimated length to the goal. |
429 uint16 priority; // This is the current length + estimated length to the goal. |
430 byte track; |
430 TrackdirByte track; |
431 byte depth; |
431 byte depth; |
432 byte state; |
432 byte state; |
433 byte first_track; |
433 byte first_track; |
434 } StackedItem; |
434 } StackedItem; |
435 |
435 |
436 static const byte _new_track[6][4] = { |
436 static const Trackdir _new_trackdir[6][4] = { |
437 {0, 0xff, 8, 0xff,}, |
437 {TRACKDIR_X_NE, INVALID_TRACKDIR, TRACKDIR_X_SW, INVALID_TRACKDIR,}, |
438 {0xff, 1, 0xff, 9,}, |
438 {INVALID_TRACKDIR, TRACKDIR_Y_SE, INVALID_TRACKDIR, TRACKDIR_Y_NW,}, |
439 {0xff, 2, 10, 0xff,}, |
439 {INVALID_TRACKDIR, TRACKDIR_UPPER_E, TRACKDIR_UPPER_W, INVALID_TRACKDIR,}, |
440 {3, 0xff, 0xff, 11,}, |
440 {TRACKDIR_LOWER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LOWER_W,}, |
441 {12, 4, 0xff, 0xff,}, |
441 {TRACKDIR_LEFT_N, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR,}, |
442 {0xff, 0xff, 5, 13,}, |
442 {INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_RIGHT_S, TRACKDIR_RIGHT_N,}, |
443 }; |
443 }; |
444 |
444 |
445 typedef struct HashLink { |
445 typedef struct HashLink { |
446 TileIndex tile; |
446 TileIndex tile; |
447 uint16 typelength; |
447 uint16 typelength; |
572 // otherwise make a new link |
572 // otherwise make a new link |
573 |
573 |
574 uint offs = tpf->hash_tile[hash]; |
574 uint offs = tpf->hash_tile[hash]; |
575 do { |
575 do { |
576 link = NTP_GET_LINK_PTR(tpf, offs); |
576 link = NTP_GET_LINK_PTR(tpf, offs); |
577 if (tile == link->tile && (link->typelength & 0x3U) == dir) { |
577 if (tile == link->tile && (link->typelength & 0x3U) == (uint)dir) { |
578 if (length >= (uint)(link->typelength >> 2)) return false; |
578 if (length >= (uint)(link->typelength >> 2)) return false; |
579 link->typelength = dir | (length << 2); |
579 link->typelength = dir | (length << 2); |
580 return true; |
580 return true; |
581 } |
581 } |
582 } while ((offs = link->next) != 0xFFFF); |
582 } while ((offs = link->next) != 0xFFFF); |
655 0, //14 |
655 0, //14 |
656 }; |
656 }; |
657 |
657 |
658 static uint DistanceMoo(TileIndex t0, TileIndex t1) |
658 static uint DistanceMoo(TileIndex t0, TileIndex t1) |
659 { |
659 { |
660 const uint dx = abs(TileX(t0) - TileX(t1)); |
660 const uint dx = delta(TileX(t0), TileX(t1)); |
661 const uint dy = abs(TileY(t0) - TileY(t1)); |
661 const uint dy = delta(TileY(t0), TileY(t1)); |
662 |
662 |
663 const uint straightTracks = 2 * min(dx, dy); /* The number of straight (not full length) tracks */ |
663 const uint straightTracks = 2 * min(dx, dy); /* The number of straight (not full length) tracks */ |
664 /* OPTIMISATION: |
664 /* OPTIMISATION: |
665 * Original: diagTracks = max(dx, dy) - min(dx,dy); |
665 * Original: diagTracks = max(dx, dy) - min(dx,dy); |
666 * Proof: |
666 * Proof: |
735 GetTunnelTransportType(tile) != tpf->tracktype) { |
735 GetTunnelTransportType(tile) != tpf->tracktype) { |
736 // We are not driving into the tunnel, or it is an invalid tunnel |
736 // We are not driving into the tunnel, or it is an invalid tunnel |
737 continue; |
737 continue; |
738 } |
738 } |
739 if (!HASBIT(tpf->railtypes, GetRailType(tile))) { |
739 if (!HASBIT(tpf->railtypes, GetRailType(tile))) { |
740 bits = 0; |
740 bits = TRACK_BIT_NONE; |
741 break; |
741 break; |
742 } |
742 } |
743 flotr = FindLengthOfTunnel(tile, direction); |
743 flotr = FindLengthOfTunnel(tile, direction); |
744 si.cur_length += flotr.length * DIAG_FACTOR; |
744 si.cur_length += flotr.length * DIAG_FACTOR; |
745 tile = flotr.tile; |
745 tile = flotr.tile; |
769 tile += TileOffsByDiagDir(direction); |
769 tile += TileOffsByDiagDir(direction); |
770 |
770 |
771 // too long search length? bail out. |
771 // too long search length? bail out. |
772 if (si.cur_length >= tpf->maxlength) { |
772 if (si.cur_length >= tpf->maxlength) { |
773 DEBUG(ntp, 1, "Cur_length too big"); |
773 DEBUG(ntp, 1, "Cur_length too big"); |
774 bits = 0; |
774 bits = TRACK_BIT_NONE; |
775 break; |
775 break; |
776 } |
776 } |
777 |
777 |
778 // Not a regular rail tile? |
778 // Not a regular rail tile? |
779 // Then we can't use the code below, but revert to more general code. |
779 // Then we can't use the code below, but revert to more general code. |
780 if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) { |
780 if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) { |
781 // We found a tile which is not a normal railway tile. |
781 // We found a tile which is not a normal railway tile. |
782 // Determine which tracks that exist on this tile. |
782 // Determine which tracks that exist on this tile. |
783 bits = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction]; |
783 uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction]; |
784 bits = (bits | (bits >> 8)) & 0x3F; |
784 bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK)); |
785 |
785 |
786 // Check that the tile contains exactly one track |
786 // Check that the tile contains exactly one track |
787 if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break; |
787 if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break; |
788 |
788 |
789 if (!HASBIT(tpf->railtypes, IsTileType(tile, MP_STREET) ? GetRailTypeCrossing(tile) : GetRailType(tile))) { |
789 if (!HASBIT(tpf->railtypes, IsTileType(tile, MP_STREET) ? GetRailTypeCrossing(tile) : GetRailType(tile))) { |
790 bits = 0; |
790 bits = TRACK_BIT_NONE; |
791 break; |
791 break; |
792 } |
792 } |
793 |
793 |
794 /////////////////// |
794 /////////////////// |
795 // If we reach here, the tile has exactly one track. |
795 // If we reach here, the tile has exactly one track. |
796 // tile - index to a tile that is not rail tile, but still straight (with optional signals) |
796 // tile - index to a tile that is not rail tile, but still straight (with optional signals) |
797 // bits - bitmask of which track that exist on the tile (exactly one bit is set) |
797 // bits - bitmask of which track that exist on the tile (exactly one bit is set) |
798 // direction - which direction are we moving in? |
798 // direction - which direction are we moving in? |
799 /////////////////// |
799 /////////////////// |
800 si.track = _new_track[FIND_FIRST_BIT(bits)][direction]; |
800 si.track = _new_trackdir[FIND_FIRST_BIT(bits)][direction]; |
801 si.cur_length += _length_of_track[si.track]; |
801 si.cur_length += _length_of_track[si.track]; |
802 goto callback_and_continue; |
802 goto callback_and_continue; |
803 } |
803 } |
804 |
804 |
805 /* Regular rail tile, determine which tracks exist. */ |
805 /* Regular rail tile, determine which tracks exist. */ |
808 bits = allbits & DiagdirReachesTracks(direction); |
808 bits = allbits & DiagdirReachesTracks(direction); |
809 |
809 |
810 /* The tile has no reachable tracks => End of rail segment |
810 /* The tile has no reachable tracks => End of rail segment |
811 * or Intersection => End of rail segment. We check this agains all the |
811 * or Intersection => End of rail segment. We check this agains all the |
812 * bits, not just reachable ones, to prevent infinite loops. */ |
812 * bits, not just reachable ones, to prevent infinite loops. */ |
813 if (bits == 0 || TracksOverlap(allbits)) break; |
813 if (bits == TRACK_BIT_NONE || TracksOverlap(allbits)) break; |
814 |
814 |
815 if (!HASBIT(tpf->railtypes, GetRailType(tile))) { |
815 if (!HASBIT(tpf->railtypes, GetRailType(tile))) { |
816 bits = 0; |
816 bits = TRACK_BIT_NONE; |
817 break; |
817 break; |
818 } |
818 } |
819 |
819 |
820 /* If we reach here, the tile has exactly one track, and this |
820 /* If we reach here, the tile has exactly one track, and this |
821 track is reachable => Rail segment continues */ |
821 track is reachable => Rail segment continues */ |
822 |
822 |
823 track = _new_track[FIND_FIRST_BIT(bits)][direction]; |
823 track = _new_trackdir[FIND_FIRST_BIT(bits)][direction]; |
824 assert(track != 0xff); |
824 assert(track != INVALID_TRACKDIR); |
825 |
825 |
826 si.cur_length += _length_of_track[track]; |
826 si.cur_length += _length_of_track[track]; |
827 |
827 |
828 // Check if this rail is an upwards slope. If it is, then add a penalty. |
828 // Check if this rail is an upwards slope. If it is, then add a penalty. |
829 // Small optimization here.. if (track&7)>1 then it can't be a slope so we avoid calling GetTileSlope |
829 // Small optimization here.. if (track&7)>1 then it can't be a slope so we avoid calling GetTileSlope |
835 // railway tile with signals..? |
835 // railway tile with signals..? |
836 if (HasSignals(tile)) { |
836 if (HasSignals(tile)) { |
837 if (!HasSignalOnTrackdir(tile, track)) { |
837 if (!HasSignalOnTrackdir(tile, track)) { |
838 // if one way signal not pointing towards us, stop going in this direction => End of rail segment. |
838 // if one way signal not pointing towards us, stop going in this direction => End of rail segment. |
839 if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) { |
839 if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) { |
840 bits = 0; |
840 bits = TRACK_BIT_NONE; |
841 break; |
841 break; |
842 } |
842 } |
843 } else if (GetSignalStateByTrackdir(tile, track) == SIGNAL_STATE_GREEN) { |
843 } else if (GetSignalStateByTrackdir(tile, track) == SIGNAL_STATE_GREEN) { |
844 // green signal in our direction. either one way or two way. |
844 // green signal in our direction. either one way or two way. |
845 si.state |= 3; |
845 si.state |= 3; |
848 if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) { |
848 if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) { |
849 // two way red signal. unless we passed another green signal on the way, |
849 // two way red signal. unless we passed another green signal on the way, |
850 // stop going in this direction => End of rail segment. |
850 // stop going in this direction => End of rail segment. |
851 // this is to prevent us from going into a full platform. |
851 // this is to prevent us from going into a full platform. |
852 if (!(si.state&1)) { |
852 if (!(si.state&1)) { |
853 bits = 0; |
853 bits = TRACK_BIT_NONE; |
854 break; |
854 break; |
855 } |
855 } |
856 } |
856 } |
857 if (!(si.state & 2)) { |
857 if (!(si.state & 2)) { |
858 // Is this the first signal we see? And it's red... add penalty |
858 // Is this the first signal we see? And it's red... add penalty |
872 // continue with the next track |
872 // continue with the next track |
873 direction = _tpf_new_direction[track]; |
873 direction = _tpf_new_direction[track]; |
874 |
874 |
875 // safety check if we're running around chasing our tail... (infinite loop) |
875 // safety check if we're running around chasing our tail... (infinite loop) |
876 if (tile == tile_org) { |
876 if (tile == tile_org) { |
877 bits = 0; |
877 bits = TRACK_BIT_NONE; |
878 break; |
878 break; |
879 } |
879 } |
880 } |
880 } |
881 |
881 |
882 // There are no tracks to choose between. |
882 // There are no tracks to choose between. |
883 // Stop searching in this direction |
883 // Stop searching in this direction |
884 if (bits == 0) |
884 if (bits == TRACK_BIT_NONE) |
885 continue; |
885 continue; |
886 |
886 |
887 //////////////// |
887 //////////////// |
888 // We got multiple tracks to choose between (intersection). |
888 // We got multiple tracks to choose between (intersection). |
889 // Branch the search space into several branches. |
889 // Branch the search space into several branches. |
907 |
907 |
908 si.depth++; |
908 si.depth++; |
909 if (si.depth == 0) |
909 if (si.depth == 0) |
910 continue; /* We overflowed our depth. No more searching in this direction. */ |
910 continue; /* We overflowed our depth. No more searching in this direction. */ |
911 si.tile = tile; |
911 si.tile = tile; |
912 do { |
912 while (bits != TRACK_BIT_NONE) { |
913 si.track = _new_track[FIND_FIRST_BIT(bits)][direction]; |
913 Track track = RemoveFirstTrack(bits); |
|
914 si.track = _new_trackdir[track][direction]; |
914 assert(si.track != 0xFF); |
915 assert(si.track != 0xFF); |
915 si.priority = si.cur_length + estimation; |
916 si.priority = si.cur_length + estimation; |
916 |
917 |
917 // out of stack items, bail out? |
918 // out of stack items, bail out? |
918 if (tpf->nstack >= lengthof(tpf->stack)) { |
919 if (tpf->nstack >= lengthof(tpf->stack)) { |
920 break; |
921 break; |
921 } |
922 } |
922 |
923 |
923 tpf->stack[tpf->nstack] = si; |
924 tpf->stack[tpf->nstack] = si; |
924 HeapifyUp(tpf); |
925 HeapifyUp(tpf); |
925 } while ((bits = KILL_FIRST_BIT(bits)) != 0); |
926 }; |
926 |
927 |
927 // If this is the first intersection, we need to fill the first_track member. |
928 // If this is the first intersection, we need to fill the first_track member. |
928 // so the code outside knows which path is better. |
929 // so the code outside knows which path is better. |
929 // also randomize the order in which we search through them. |
930 // also randomize the order in which we search through them. |
930 if (si.depth == 1) { |
931 if (si.depth == 1) { |
931 assert(tpf->nstack == 1 || tpf->nstack == 2 || tpf->nstack == 3); |
932 assert(tpf->nstack == 1 || tpf->nstack == 2 || tpf->nstack == 3); |
932 if (tpf->nstack != 1) { |
933 if (tpf->nstack != 1) { |
933 uint32 r = Random(); |
934 uint32 r = Random(); |
934 if (r&1) swap_byte(&tpf->stack[0].track, &tpf->stack[1].track); |
935 if (r&1) SwapT(&tpf->stack[0].track, &tpf->stack[1].track); |
935 if (tpf->nstack != 2) { |
936 if (tpf->nstack != 2) { |
936 byte t = tpf->stack[2].track; |
937 TrackdirByte t = tpf->stack[2].track; |
937 if (r&2) swap_byte(&tpf->stack[0].track, &t); |
938 if (r&2) SwapT(&tpf->stack[0].track, &t); |
938 if (r&4) swap_byte(&tpf->stack[1].track, &t); |
939 if (r&4) SwapT(&tpf->stack[1].track, &t); |
939 tpf->stack[2].first_track = tpf->stack[2].track = t; |
940 tpf->stack[2].first_track = tpf->stack[2].track = t; |
940 } |
941 } |
941 tpf->stack[0].first_track = tpf->stack[0].track; |
942 tpf->stack[0].first_track = tpf->stack[0].track; |
942 tpf->stack[1].first_track = tpf->stack[1].track; |
943 tpf->stack[1].first_track = tpf->stack[1].track; |
943 } |
944 } |