src/pathfind.cpp
branchNewGRF_ports
changeset 6871 5a9dc001e1ad
parent 6720 35756db7e577
child 6872 1c4a4a609f85
equal deleted inserted replaced
6870:ca3fd1fbe311 6871:5a9dc001e1ad
   138 };
   138 };
   139 
   139 
   140 static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
   140 static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
   141 {
   141 {
   142 	uint bits;
   142 	uint bits;
   143 	int i;
       
   144 	RememberData rd;
   143 	RememberData rd;
   145 
   144 
   146 	assert(tpf->tracktype == TRANSPORT_WATER);
   145 	assert(tpf->tracktype == TRANSPORT_WATER);
   147 
   146 
   148 	/* This addition will sometimes overflow by a single tile.
   147 	/* This addition will sometimes overflow by a single tile.
   158 	if (bits == 0)
   157 	if (bits == 0)
   159 		return;
   158 		return;
   160 
   159 
   161 	assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY());
   160 	assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY());
   162 
   161 
   163 	if ( (bits & (bits - 1)) == 0 ) {
   162 	uint i = 0;
   164 		/* only one direction */
   163 	/* only one direction */
   165 		i = 0;
   164 	if (KillFirstBit(bits) == 0) {
   166 		while (!(bits & 1))
   165 		i = FindFirstBit(bits);
   167 			i++, bits >>= 1;
       
   168 
       
   169 		rd = tpf->rd;
   166 		rd = tpf->rd;
   170 		goto continue_here;
   167 		goto continue_here;
   171 	}
   168 	}
   172 	/* several directions */
   169 	/* several directions */
   173 	i=0;
       
   174 	do {
   170 	do {
   175 		if (!(bits & 1)) continue;
   171 		i = FindFirstBit(bits);
   176 		rd = tpf->rd;
   172 		rd = tpf->rd;
   177 
   173 
   178 		/* Change direction 4 times only */
   174 		/* Change direction 4 times only */
   179 		if ((byte)i != tpf->rd.pft_var6) {
   175 		if ((byte)i != tpf->rd.pft_var6) {
   180 			if (++tpf->rd.depth > 4) {
   176 			if (++tpf->rd.depth > 4) {
   182 				return;
   178 				return;
   183 			}
   179 			}
   184 			tpf->rd.pft_var6 = (byte)i;
   180 			tpf->rd.pft_var6 = (byte)i;
   185 		}
   181 		}
   186 
   182 
   187 continue_here:;
   183 continue_here:
   188 		tpf->the_dir = (Trackdir)(i + (HASBIT(_otherdir_mask[direction], i) ? 8 : 0));
   184 		tpf->the_dir = (Trackdir)(i + (HasBit(_otherdir_mask[direction], i) ? 8 : 0));
   189 
   185 
   190 		if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, NULL)) {
   186 		if (!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, NULL)) {
   191 			TPFMode2(tpf, tile, _tpf_new_direction[tpf->the_dir]);
   187 			TPFMode2(tpf, tile, _tpf_new_direction[tpf->the_dir]);
   192 		}
   188 		}
   193 
   189 
   194 		tpf->rd = rd;
   190 		tpf->rd = rd;
   195 	} while (++i, bits >>= 1);
   191 	} while (ClrBit(bits, i) != 0);
   196 
   192 
   197 }
   193 }
   198 
   194 
   199 
   195 
   200 /* Returns the end tile and the length of a tunnel. The length does not
   196 /* Returns the end tile and the length of a tunnel. The length does not
   232 	tpf->rd.cur_length += flotr.length;
   228 	tpf->rd.cur_length += flotr.length;
   233 	TPFSetTileBit(tpf, flotr.tile, 14);
   229 	TPFSetTileBit(tpf, flotr.tile, 14);
   234 	return flotr.tile;
   230 	return flotr.tile;
   235 }
   231 }
   236 
   232 
   237 const byte _ffb_64[128] = {
       
   238  0,  0,  1,  0,  2,  0,  1,  0,
       
   239  3,  0,  1,  0,  2,  0,  1,  0,
       
   240  4,  0,  1,  0,  2,  0,  1,  0,
       
   241  3,  0,  1,  0,  2,  0,  1,  0,
       
   242  5,  0,  1,  0,  2,  0,  1,  0,
       
   243  3,  0,  1,  0,  2,  0,  1,  0,
       
   244  4,  0,  1,  0,  2,  0,  1,  0,
       
   245  3,  0,  1,  0,  2,  0,  1,  0,
       
   246 
       
   247  0,  0,  0,  2,  0,  4,  4,  6,
       
   248  0,  8,  8, 10,  8, 12, 12, 14,
       
   249  0, 16, 16, 18, 16, 20, 20, 22,
       
   250 16, 24, 24, 26, 24, 28, 28, 30,
       
   251  0, 32, 32, 34, 32, 36, 36, 38,
       
   252 32, 40, 40, 42, 40, 44, 44, 46,
       
   253 32, 48, 48, 50, 48, 52, 52, 54,
       
   254 48, 56, 56, 58, 56, 60, 60, 62,
       
   255 };
       
   256 
       
   257 static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction);
   233 static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction);
   258 
   234 
   259 /** Most code of the "Normal" case of TPF Mode 1; for signals special tricks
   235 /** Most code of the "Normal" case of TPF Mode 1; for signals special tricks
   260  * have to be done, but those happen in TPFMode1; this is just to prevent
   236  * have to be done, but those happen in TPFMode1; this is just to prevent
   261  * gotos ;). */
   237  * gotos ;). */
   300 
   276 
   301 	uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
   277 	uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
   302 
   278 
   303 	if ((byte)bits != tpf->var2) {
   279 	if ((byte)bits != tpf->var2) {
   304 		bits &= _tpfmode1_and[direction];
   280 		bits &= _tpfmode1_and[direction];
   305 		bits = bits | (bits >> 8);
   281 		bits |= bits >> 8;
   306 	}
   282 	}
   307 	bits &= 0xBF;
   283 	bits &= 0xBF;
   308 
   284 
   309 	if (bits != 0) {
   285 	if (bits != 0) {
   310 		if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KILL_FIRST_BIT(bits) == 0 || ++tpf->rd.depth <= 7))) {
   286 		if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KillFirstBit(bits) == 0 || ++tpf->rd.depth <= 7))) {
   311 			do {
   287 			do {
   312 				int i = FIND_FIRST_BIT(bits);
   288 				int i = FIND_FIRST_BIT(bits);
   313 				bits = KILL_FIRST_BIT(bits);
   289 				bits = KillFirstBit(bits);
   314 
   290 
   315 				tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
   291 				tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
   316 				RememberData rd = tpf->rd;
   292 				RememberData rd = tpf->rd;
   317 
   293 
   318 				if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
   294 				if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
   389 	if (bits == 0)
   365 	if (bits == 0)
   390 		return;
   366 		return;
   391 
   367 
   392 	do {
   368 	do {
   393 		uint i = FIND_FIRST_BIT(bits);
   369 		uint i = FIND_FIRST_BIT(bits);
   394 		bits = KILL_FIRST_BIT(bits);
   370 		bits = KillFirstBit(bits);
   395 
   371 
   396 		tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
   372 		tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
   397 		RememberData rd = tpf->rd;
   373 		RememberData rd = tpf->rd;
   398 		if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
   374 		if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
   399 				!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
   375 				!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
   417 
   393 
   418 	tpf.rd.cur_length = 0;
   394 	tpf.rd.cur_length = 0;
   419 	tpf.rd.depth = 0;
   395 	tpf.rd.depth = 0;
   420 	tpf.rd.pft_var6 = 0;
   396 	tpf.rd.pft_var6 = 0;
   421 
   397 
   422 	tpf.var2 = HASBIT(flags, 15) ? 0x43 : 0xFF; // 0x8000
   398 	tpf.var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000
   423 
   399 
   424 	tpf.disable_tile_hash = HASBIT(flags, 12);  // 0x1000
   400 	tpf.disable_tile_hash = HasBit(flags, 12);  // 0x1000
   425 	tpf.hasbit_13         = HASBIT(flags, 13);  // 0x2000
   401 	tpf.hasbit_13         = HasBit(flags, 13);  // 0x2000
   426 
   402 
   427 
   403 
   428 	tpf.tracktype = (TransportType)(flags & 0xFF);
   404 	tpf.tracktype = (TransportType)(flags & 0xFF);
   429 	tpf.sub_type = sub_type;
   405 	tpf.sub_type = sub_type;
   430 
   406 
   431 	if (HASBIT(flags, 11)) {
   407 	if (HasBit(flags, 11)) {
   432 		tpf.rd.pft_var6 = 0xFF;
   408 		tpf.rd.pft_var6 = 0xFF;
   433 		tpf.enum_proc(tile, data, INVALID_TRACKDIR, 0, 0);
   409 		tpf.enum_proc(tile, data, INVALID_TRACKDIR, 0, 0);
   434 		TPFMode2(&tpf, tile, direction);
   410 		TPFMode2(&tpf, tile, direction);
   435 	} else {
   411 	} else {
   436 		/* clear the hash_heads */
   412 		/* clear the hash_heads */
   674 	0,                                           ///< 14
   650 	0,                                           ///< 14
   675 };
   651 };
   676 
   652 
   677 static uint DistanceMoo(TileIndex t0, TileIndex t1)
   653 static uint DistanceMoo(TileIndex t0, TileIndex t1)
   678 {
   654 {
   679 	const uint dx = delta(TileX(t0), TileX(t1));
   655 	const uint dx = Delta(TileX(t0), TileX(t1));
   680 	const uint dy = delta(TileY(t0), TileY(t1));
   656 	const uint dy = Delta(TileY(t0), TileY(t1));
   681 
   657 
   682 	const uint straightTracks = 2 * min(dx, dy); // The number of straight (not full length) tracks
   658 	const uint straightTracks = 2 * min(dx, dy); // The number of straight (not full length) tracks
   683 	/* OPTIMISATION:
   659 	/* OPTIMISATION:
   684 	 * Original: diagTracks = max(dx, dy) - min(dx,dy);
   660 	 * Original: diagTracks = max(dx, dy) - min(dx,dy);
   685 	 * Proof:
   661 	 * Proof:
   753 					if (GetTunnelDirection(tile) != direction ||
   729 					if (GetTunnelDirection(tile) != direction ||
   754 							GetTunnelTransportType(tile) != tpf->tracktype) {
   730 							GetTunnelTransportType(tile) != tpf->tracktype) {
   755 						/* We are not driving into the tunnel, or it is an invalid tunnel */
   731 						/* We are not driving into the tunnel, or it is an invalid tunnel */
   756 						continue;
   732 						continue;
   757 					}
   733 					}
   758 					if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
   734 					if (!HasBit(tpf->railtypes, GetRailType(tile))) {
   759 						bits = TRACK_BIT_NONE;
   735 						bits = TRACK_BIT_NONE;
   760 						break;
   736 						break;
   761 					}
   737 					}
   762 					flotr = FindLengthOfTunnel(tile, direction);
   738 					flotr = FindLengthOfTunnel(tile, direction);
   763 					si.cur_length += flotr.length * DIAG_FACTOR;
   739 					si.cur_length += flotr.length * DIAG_FACTOR;
   801 				 * Determine which tracks that exist on this tile. */
   777 				 * Determine which tracks that exist on this tile. */
   802 				uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _tpfmode1_and[direction];
   778 				uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & _tpfmode1_and[direction];
   803 				bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK));
   779 				bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK));
   804 
   780 
   805 				/* Check that the tile contains exactly one track */
   781 				/* Check that the tile contains exactly one track */
   806 				if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break;
   782 				if (bits == 0 || KillFirstBit(bits) != 0) break;
   807 
   783 
   808 				if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
   784 				if (!HasBit(tpf->railtypes, GetRailType(tile))) {
   809 					bits = TRACK_BIT_NONE;
   785 					bits = TRACK_BIT_NONE;
   810 					break;
   786 					break;
   811 				}
   787 				}
   812 
   788 
   813 				/*******************
   789 				/*******************
   829 			/* The tile has no reachable tracks => End of rail segment
   805 			/* The tile has no reachable tracks => End of rail segment
   830 			 * or Intersection => End of rail segment. We check this agains all the
   806 			 * or Intersection => End of rail segment. We check this agains all the
   831 			 * bits, not just reachable ones, to prevent infinite loops. */
   807 			 * bits, not just reachable ones, to prevent infinite loops. */
   832 			if (bits == TRACK_BIT_NONE || TracksOverlap(allbits)) break;
   808 			if (bits == TRACK_BIT_NONE || TracksOverlap(allbits)) break;
   833 
   809 
   834 			if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
   810 			if (!HasBit(tpf->railtypes, GetRailType(tile))) {
   835 				bits = TRACK_BIT_NONE;
   811 				bits = TRACK_BIT_NONE;
   836 				break;
   812 				break;
   837 			}
   813 			}
   838 
   814 
   839 			/* If we reach here, the tile has exactly one track, and this
   815 			/* If we reach here, the tile has exactly one track, and this