Changeset - r28518:ca5098bf21c9
[Not reviewed]
master
1 12 0
Rubidium - 11 months ago 2024-01-18 18:40:49
rubidium@openttd.org
Codechange: replace FIND_FIRST_BIT/FindFirstBit2x64 with FindFirstBit
13 files changed with 21 insertions and 81 deletions:
0 comments (0 inline, 0 general)
src/core/CMakeLists.txt
Show inline comments
 
add_files(
 
    alloc_func.cpp
 
    alloc_func.hpp
 
    alloc_type.hpp
 
    backup_type.hpp
 
    bitmath_func.cpp
 
    bitmath_func.hpp
 
    endian_func.hpp
 
    endian_type.hpp
 
    enum_type.hpp
 
    format.hpp
 
    geometry_func.cpp
src/core/bitmath_func.cpp
Show inline comments
 
deleted file
src/core/bitmath_func.hpp
Show inline comments
 
@@ -180,64 +180,29 @@ inline T ClrBit(T &x, const uint8_t y)
 
template <typename T>
 
inline T ToggleBit(T &x, const uint8_t y)
 
{
 
	return x = (T)(x ^ ((T)1U << y));
 
}
 

	
 

	
 
/** Lookup table to check which bit is set in a 6 bit variable */
 
extern const uint8_t _ffb_64[64];
 

	
 
/**
 
 * Returns the first non-zero bit in a 6-bit value (from right).
 
 *
 
 * Returns the position of the first bit that is not zero, counted from the
 
 * LSB. Ie, 110100 returns 2, 000001 returns 0, etc. When x == 0 returns
 
 * 0.
 
 *
 
 * @param x The 6-bit value to check the first zero-bit
 
 * @return The first position of a bit started from the LSB or 0 if x is 0.
 
 */
 
#define FIND_FIRST_BIT(x) _ffb_64[(x)]
 

	
 
/**
 
 * Finds the position of the first non-zero bit in an integer.
 
 *
 
 * This function returns the position of the first bit set in the
 
 * integer. It does only check the bits of the bitmask
 
 * 0x3F3F (0011111100111111) and checks only the
 
 * bits of the bitmask 0x3F00 if and only if the
 
 * lower part 0x00FF is 0. This results the bits at 0x00C0 must
 
 * be also zero to check the bits at 0x3F00.
 
 *
 
 * @param value The value to check the first bits
 
 * @return The position of the first bit which is set
 
 * @see FIND_FIRST_BIT
 
 */
 
inline uint8_t FindFirstBit2x64(const int value)
 
{
 
	if ((value & 0xFF) == 0) {
 
		return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8;
 
	} else {
 
		return FIND_FIRST_BIT(value & 0x3F);
 
	}
 
}
 

	
 
/**
 
 * Search the first set bit in a value.
 
 * When no bit is set, it returns 0.
 
 *
 
 * @param x The value to search.
 
 * @return The position of the first bit set.
 
 */
 
template <typename T>
 
constexpr uint8_t FindFirstBit(T x)
 
{
 
	if (x == 0) return 0;
 

	
 
	return std::countr_zero(x);
 
	if constexpr (std::is_enum_v<T>) {
 
		return std::countr_zero<std::underlying_type_t<T>>(x);
 
	} else {
 
		return std::countr_zero(x);
 
	}
 
}
 

	
 
/**
 
 * Search the last set bit in a value.
 
 * When no bit is set, it returns 0.
 
 *
src/pathfinder/npf/npf.cpp
Show inline comments
 
@@ -1222,17 +1222,17 @@ bool NPFShipCheckReverse(const Ship *v, 
 
	assert(trackdir_rev != INVALID_TRACKDIR);
 

	
 
	AyStarUserData user = { v->owner, TRANSPORT_WATER, RAILTYPES_NONE, ROADTYPES_NONE, 0 };
 
	if (best_td != nullptr) {
 
		DiagDirection entry = ReverseDiagDir(VehicleExitDir(v->direction, v->state));
 
		TrackdirBits rtds = DiagdirReachesTrackdirs(entry) & TrackStatusToTrackdirBits(GetTileTrackStatus(v->tile, TRANSPORT_WATER, 0, entry));
 
		Trackdir best = (Trackdir)FindFirstBit2x64(rtds);
 
		Trackdir best = (Trackdir)FindFirstBit(rtds);
 
		rtds = KillFirstBit(rtds);
 
		if (rtds == TRACKDIR_BIT_NONE) return false; /* At most one choice. */
 
		for (; rtds != TRACKDIR_BIT_NONE; rtds = KillFirstBit(rtds)) {
 
			Trackdir td = (Trackdir)FindFirstBit2x64(rtds);
 
			Trackdir td = (Trackdir)FindFirstBit(rtds);
 
			ftd = NPFRouteToStationOrTileTwoWay(v->tile, best, false, v->tile, td, false, &fstd, &user);
 
			if (ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) best = td;
 
		}
 
		if (ftd.best_bird_dist == 0) {
 
			*best_td = best;
 
			return true;
src/pathfinder/yapf/yapf_base.hpp
Show inline comments
 
@@ -189,13 +189,13 @@ public:
 

	
 
	/** add multiple nodes - direct children of the given node */
 
	inline void AddMultipleNodes(Node *parent, const TrackFollower &tf)
 
	{
 
		bool is_choice = (KillFirstBit(tf.m_new_td_bits) != TRACKDIR_BIT_NONE);
 
		for (TrackdirBits rtds = tf.m_new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = KillFirstBit(rtds)) {
 
			Trackdir td = (Trackdir)FindFirstBit2x64(rtds);
 
			Trackdir td = (Trackdir)FindFirstBit(rtds);
 
			Node &n = Yapf().CreateNewNode();
 
			n.Set(parent, tf.m_new_tile, td, is_choice);
 
			Yapf().AddNewNode(n, tf);
 
		}
 
	}
 

	
src/pathfinder/yapf/yapf_common.hpp
Show inline comments
 
@@ -39,13 +39,13 @@ public:
 

	
 
	/** Called when YAPF needs to place origin nodes into open list */
 
	void PfSetStartupNodes()
 
	{
 
		bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE);
 
		for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
 
			Trackdir td = (Trackdir)FindFirstBit2x64(tdb);
 
			Trackdir td = (Trackdir)FindFirstBit(tdb);
 
			Node &n1 = Yapf().CreateNewNode();
 
			n1.Set(nullptr, m_orgTile, td, is_choice);
 
			Yapf().AddStartupNode(n1);
 
		}
 
	}
 
};
src/pathfinder/yapf/yapf_costrail.hpp
Show inline comments
 
@@ -501,13 +501,13 @@ no_entry_cost: // jump here at the begin
 
				/* More than one segment will follow. Close this one. */
 
				end_segment_reason |= ESRB_CHOICE_FOLLOWS;
 
				break;
 
			}
 

	
 
			/* Gather the next tile/trackdir/tile_type/rail_type. */
 
			TILE next(tf_local.m_new_tile, (Trackdir)FindFirstBit2x64(tf_local.m_new_td_bits));
 
			TILE next(tf_local.m_new_tile, (Trackdir)FindFirstBit(tf_local.m_new_td_bits));
 

	
 
			if (TrackFollower::DoTrackMasking() && IsTileType(next.tile, MP_RAILWAY)) {
 
				if (HasSignalOnTrackdir(next.tile, next.td) && IsPbsSignal(GetSignalType(next.tile, TrackdirToTrack(next.td)))) {
 
					/* Possible safe tile. */
 
					end_segment_reason |= ESRB_SAFE_TILE;
 
				} else if (HasSignalOnTrackdir(next.tile, ReverseTrackdir(next.td)) && GetSignalType(next.tile, TrackdirToTrack(next.td)) == SIGTYPE_PBS_ONEWAY) {
src/pathfinder/yapf/yapf_road.cpp
Show inline comments
 
@@ -142,13 +142,13 @@ public:
 
			TrackFollower F(Yapf().GetVehicle());
 
			if (!F.Follow(tile, trackdir)) break;
 

	
 
			/* if there are more trackdirs available & reachable, we are at the end of segment */
 
			if (KillFirstBit(F.m_new_td_bits) != TRACKDIR_BIT_NONE) break;
 

	
 
			Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits);
 
			Trackdir new_td = (Trackdir)FindFirstBit(F.m_new_td_bits);
 

	
 
			/* stop if RV is on simple loop with no junctions */
 
			if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false;
 

	
 
			/* if we skipped some tunnel tiles, add their cost */
 
			segment_cost += F.m_tiles_skipped * YAPF_TILE_LENGTH;
 
@@ -532,13 +532,13 @@ Trackdir YapfRoadVehicleChooseTrack(cons
 
	/* check if non-default YAPF type should be used */
 
	if (_settings_game.pf.yapf.disable_node_optimization) {
 
		pfnChooseRoadTrack = &CYapfRoad1::stChooseRoadTrack; // Trackdir
 
	}
 

	
 
	Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
 
	return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit2x64(trackdirs);
 
	return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit(trackdirs);
 
}
 

	
 
FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_distance)
 
{
 
	TileIndex tile = v->tile;
 
	Trackdir trackdir = v->GetVehicleTrackdir();
src/pathfinder/yapf/yapf_ship.cpp
Show inline comments
 
@@ -203,13 +203,13 @@ public:
 
			TrackdirBits trackdirs = TrackBitsToTrackdirBits(tracks);
 
			/* Limit to trackdirs reachable from enterdir. */
 
			trackdirs &= DiagdirReachesTrackdirs(enterdir);
 

	
 
			/* use vehicle's current direction if that's possible, otherwise use first usable one. */
 
			Trackdir veh_dir = v->GetVehicleTrackdir();
 
			return (HasTrackdir(trackdirs, veh_dir)) ? veh_dir : (Trackdir)FindFirstBit2x64(trackdirs);
 
			return (HasTrackdir(trackdirs, veh_dir)) ? veh_dir : (Trackdir)FindFirstBit(trackdirs);
 
		}
 

	
 
		/* Move back to the old tile/trackdir (where ship is coming from). */
 
		TileIndex src_tile = TileAddByDiagDir(tile, ReverseDiagDir(enterdir));
 
		Trackdir trackdir = v->GetVehicleTrackdir();
 
		assert(IsValidTrackdir(trackdir));
src/roadveh_cmd.cpp
Show inline comments
 
@@ -957,13 +957,13 @@ static Trackdir RoadFindPathToDest(RoadV
 
	/* Only one track to choose between? */
 
	if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) {
 
		if (!v->path.empty() && v->path.tile.front() == tile) {
 
			/* Vehicle expected a choice here, invalidate its path. */
 
			v->path.clear();
 
		}
 
		return_track(FindFirstBit2x64(trackdirs));
 
		return_track(FindFirstBit(trackdirs));
 
	}
 

	
 
	/* Attempt to follow cached path. */
 
	if (!v->path.empty()) {
 
		if (v->path.tile.front() != tile) {
 
			/* Vehicle didn't expect a choice here, invalidate its path. */
src/spritecache.cpp
Show inline comments
 
@@ -371,13 +371,13 @@ static bool PadSprites(SpriteLoader::Spr
 
	return true;
 
}
 

	
 
static bool ResizeSprites(SpriteLoader::SpriteCollection &sprite, uint8_t sprite_avail, SpriteEncoder *encoder)
 
{
 
	/* Create a fully zoomed image if it does not exist */
 
	ZoomLevel first_avail = static_cast<ZoomLevel>(FIND_FIRST_BIT(sprite_avail));
 
	ZoomLevel first_avail = static_cast<ZoomLevel>(FindFirstBit(sprite_avail));
 
	if (first_avail != ZOOM_LVL_NORMAL) {
 
		if (!ResizeSpriteIn(sprite, first_avail, ZOOM_LVL_NORMAL)) return false;
 
		SetBit(sprite_avail, ZOOM_LVL_NORMAL);
 
	}
 

	
 
	/* Pad sprites to make sizes match. */
src/track_func.h
Show inline comments
 
@@ -129,13 +129,13 @@ inline TrackdirBits TrackdirToTrackdirBi
 
 * @see FindFirstTrack
 
 */
 
inline Track RemoveFirstTrack(TrackBits *tracks)
 
{
 
	if (*tracks != TRACK_BIT_NONE && *tracks != INVALID_TRACK_BIT) {
 
		assert((*tracks & ~TRACK_BIT_MASK) == TRACK_BIT_NONE);
 
		Track first = (Track)FIND_FIRST_BIT(*tracks);
 
		Track first = (Track)FindFirstBit(*tracks);
 
		ClrBit(*tracks, first);
 
		return first;
 
	}
 
	return INVALID_TRACK;
 
}
 

	
 
@@ -154,13 +154,13 @@ inline Track RemoveFirstTrack(TrackBits 
 
 * @see FindFirstTrackdir
 
 */
 
inline Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
 
{
 
	if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) {
 
		assert((*trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
 
		Trackdir first = (Trackdir)FindFirstBit2x64(*trackdirs);
 
		Trackdir first = (Trackdir)FindFirstBit(*trackdirs);
 
		ClrBit(*trackdirs, first);
 
		return first;
 
	}
 
	return INVALID_TRACKDIR;
 
}
 

	
 
@@ -173,13 +173,13 @@ inline Trackdir RemoveFirstTrackdir(Trac
 
 * @param tracks The TrackBits value
 
 * @return The first Track found or INVALID_TRACK
 
 * @see RemoveFirstTrack
 
 */
 
inline Track FindFirstTrack(TrackBits tracks)
 
{
 
	return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK;
 
	return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FindFirstBit(tracks) : INVALID_TRACK;
 
}
 

	
 
/**
 
 * Converts TrackBits to Track.
 
 *
 
 * This function converts a TrackBits value to a Track value. As it
 
@@ -190,13 +190,13 @@ inline Track FindFirstTrack(TrackBits tr
 
 * @return The Track from the value or INVALID_TRACK
 
 * @pre tracks must contains only one Track or be INVALID_TRACK_BIT
 
 */
 
inline Track TrackBitsToTrack(TrackBits tracks)
 
{
 
	assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KillFirstBit(tracks & TRACK_BIT_MASK) == TRACK_BIT_NONE));
 
	return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK;
 
	return tracks != INVALID_TRACK_BIT ? (Track)FindFirstBit(tracks & TRACK_BIT_MASK) : INVALID_TRACK;
 
}
 

	
 
/**
 
 * Returns first Trackdir from TrackdirBits or INVALID_TRACKDIR
 
 *
 
 * This function returns the first Trackdir in the given TrackdirBits value or
 
@@ -208,13 +208,13 @@ inline Track TrackBitsToTrack(TrackBits 
 
 * @pre trackdirs must not be INVALID_TRACKDIR_BIT
 
 * @see RemoveFirstTrackdir
 
 */
 
inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
 
{
 
	assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
 
	return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR;
 
	return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit(trackdirs) : INVALID_TRACKDIR;
 
}
 

	
 
/*
 
 * Functions describing logical relations between Tracks, TrackBits, Trackdirs
 
 * TrackdirBits, Direction and DiagDirections.
 
 */
src/train_cmd.cpp
Show inline comments
 
@@ -3425,13 +3425,13 @@ bool TrainController(Train *v, Vehicle *
 
				assert(
 
						chosen_track == TRACK_BIT_X     || chosen_track == TRACK_BIT_Y ||
 
						chosen_track == TRACK_BIT_UPPER || chosen_track == TRACK_BIT_LOWER ||
 
						chosen_track == TRACK_BIT_LEFT  || chosen_track == TRACK_BIT_RIGHT);
 

	
 
				/* Update XY to reflect the entrance to the new tile, and select the direction to use */
 
				const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir];
 
				const byte *b = _initial_tile_subcoord[FindFirstBit(chosen_track)][enterdir];
 
				gp.x = (gp.x & ~0xF) | b[0];
 
				gp.y = (gp.y & ~0xF) | b[1];
 
				Direction chosen_dir = (Direction)b[2];
 

	
 
				/* Call the landscape function and tell it that the vehicle entered the tile */
 
				uint32_t r = VehicleEnterTile(v, gp.new_tile, gp.x, gp.y);
0 comments (0 inline, 0 general)