diff --git a/src/macros.h b/src/macros.h index 8d97592356..1982e939eb 100644 --- a/src/macros.h +++ b/src/macros.h @@ -354,7 +354,7 @@ template static inline T TOGGLEBIT(T& x, const uint8 y) */ #define IS_CUSTOM_SPRITE(sprite) ((sprite) >= SPR_SIGNALS_BASE) -extern const byte _ffb_64[128]; +extern const byte _ffb_64[64]; /** * Returns the first occure of a bit in a 6-bit value (from right). @@ -368,17 +368,6 @@ extern const byte _ffb_64[128]; */ #define FIND_FIRST_BIT(x) _ffb_64[(x)] -/** - * Returns a value with the first occured of a bit set to zero. - * - * Returns x with the first bit from LSB that is not zero set - * to zero. So, 110100 returns 110000, 000001 returns 000000, etc. - * - * @param x The value to returned a new value - * @return The value which the first bit is set to zero - */ -#define KILL_FIRST_BIT(x) _ffb_64[(x) + 64] - /** * Finds the position of the first bit in an integer. * @@ -416,14 +405,15 @@ Faster ( or at least cleaner ) implementation below? * Clear the first bit in an integer. * * This function returns a value where the first bit (from LSB) - * is cleared. This function checks only the bits of 0x3F3F! + * is cleared. + * So, 110100 returns 110000, 000001 returns 000000, etc. * * @param value The value to clear the first bit * @return The new value with the first bit cleared */ -static inline uint KillFirstBit2x64(uint value) +template static inline T KillFirstBit(T value) { - return value &= (uint)(value - 1) | 0x3FFFC0C0; + return value &= (T)(value - 1); } /** diff --git a/src/pathfind.cpp b/src/pathfind.cpp index fde5f85b01..fb0fc98bd7 100644 --- a/src/pathfind.cpp +++ b/src/pathfind.cpp @@ -234,7 +234,7 @@ static uint SkipToEndOfTunnel(TrackPathFinder* tpf, TileIndex tile, DiagDirectio return flotr.tile; } -const byte _ffb_64[128] = { +const byte _ffb_64[64] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, @@ -243,15 +243,6 @@ const byte _ffb_64[128] = { 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - - 0, 0, 0, 2, 0, 4, 4, 6, - 0, 8, 8, 10, 8, 12, 12, 14, - 0, 16, 16, 18, 16, 20, 20, 22, -16, 24, 24, 26, 24, 28, 28, 30, - 0, 32, 32, 34, 32, 36, 36, 38, -32, 40, 40, 42, 40, 44, 44, 46, -32, 48, 48, 50, 48, 52, 52, 54, -48, 56, 56, 58, 56, 60, 60, 62, }; static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction); @@ -307,10 +298,10 @@ static inline void TPFMode1_NormalCase(TrackPathFinder* tpf, TileIndex tile, Til bits &= 0xBF; if (bits != 0) { - if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KILL_FIRST_BIT(bits) == 0 || ++tpf->rd.depth <= 7))) { + if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KillFirstBit(bits) == 0 || ++tpf->rd.depth <= 7))) { do { int i = FIND_FIRST_BIT(bits); - bits = KILL_FIRST_BIT(bits); + bits = KillFirstBit(bits); tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i); RememberData rd = tpf->rd; @@ -391,7 +382,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi do { uint i = FIND_FIRST_BIT(bits); - bits = KILL_FIRST_BIT(bits); + bits = KillFirstBit(bits); tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i); RememberData rd = tpf->rd; @@ -803,7 +794,7 @@ start_at: bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK)); /* Check that the tile contains exactly one track */ - if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break; + if (bits == 0 || KillFirstBit(bits) != 0) break; if (!HASBIT(tpf->railtypes, GetRailType(tile))) { bits = TRACK_BIT_NONE; diff --git a/src/rail.h b/src/rail.h index de1d1d82dd..00adf6183c 100644 --- a/src/rail.h +++ b/src/rail.h @@ -370,7 +370,7 @@ static inline Track FindFirstTrack(TrackBits tracks) */ static inline Track TrackBitsToTrack(TrackBits tracks) { - assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KILL_FIRST_BIT(tracks & TRACK_BIT_MASK) == 0)); + 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; } @@ -785,7 +785,7 @@ static inline bool HasPowerOnRail(RailType enginetype, RailType tiletype) static inline bool TracksOverlap(TrackBits bits) { /* With no, or only one track, there is no overlap */ - if (bits == 0 || KILL_FIRST_BIT(bits) == 0) return false; + if (bits == TRACK_BIT_NONE || KillFirstBit(bits) == TRACK_BIT_NONE) return false; /* We know that there are at least two tracks present. When there are more * than 2 tracks, they will surely overlap. When there are two, they will * always overlap unless they are lower & upper or right & left. */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index ebb15f9c9b..f0e16edf56 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -802,7 +802,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 { /* See if this is a valid track combination for signals, (ie, no overlap) */ TrackBits trackbits = GetTrackBits(tile); - if (KILL_FIRST_BIT(trackbits) != 0 && /* More than one track present */ + if (KillFirstBit(trackbits) != TRACK_BIT_NONE && /* More than one track present */ trackbits != TRACK_BIT_HORZ && trackbits != TRACK_BIT_VERT) { return CMD_ERROR; diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 67f592c062..e871276118 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1211,7 +1211,7 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent } /* Only one track to choose between? */ - if (!(KillFirstBit2x64(trackdirs))) { + if (KillFirstBit(trackdirs) != TRACKDIR_BIT_NONE) { return_track(FindFirstBit2x64(trackdirs)); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 71dbebb0cb..ffd7bc85a2 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2188,10 +2188,10 @@ static Track ChooseTrainTrack(Vehicle* v, TileIndex tile, DiagDirection enterdir TIC() #endif - assert((tracks & ~0x3F) == 0); + assert((tracks & ~TRACK_BIT_MASK) == 0); /* quick return in case only one possible track is available */ - if (KILL_FIRST_BIT(tracks) == 0) return FindFirstTrack(tracks); + if (KillFirstBit(tracks) == TRACK_BIT_NONE) return FindFirstTrack(tracks); if (_patches.yapf.rail_use_yapf) { Trackdir trackdir = YapfChooseRailTrack(v, tile, enterdir, tracks, &path_not_found); diff --git a/src/yapf/yapf_base.hpp b/src/yapf/yapf_base.hpp index 43dd1793b9..c3ab93c723 100644 --- a/src/yapf/yapf_base.hpp +++ b/src/yapf/yapf_base.hpp @@ -192,8 +192,8 @@ public: /** add multiple nodes - direct children of the given node */ FORCEINLINE void AddMultipleNodes(Node* parent, const TrackFollower &tf) { - bool is_choice = (KillFirstBit2x64(tf.m_new_td_bits) != 0); - for (TrackdirBits rtds = tf.m_new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = (TrackdirBits)KillFirstBit2x64(rtds)) { + 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); Node& n = Yapf().CreateNewNode(); n.Set(parent, tf.m_new_tile, td, is_choice); diff --git a/src/yapf/yapf_common.hpp b/src/yapf/yapf_common.hpp index 8c5257e943..b507ceb9e3 100644 --- a/src/yapf/yapf_common.hpp +++ b/src/yapf/yapf_common.hpp @@ -32,8 +32,8 @@ public: /// Called when YAPF needs to place origin nodes into open list void PfSetStartupNodes() { - bool is_choice = (KillFirstBit2x64(m_orgTrackdirs) != 0); - for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = (TrackdirBits)KillFirstBit2x64(tdb)) { + 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); Node& n1 = Yapf().CreateNewNode(); n1.Set(NULL, m_orgTile, td, is_choice); diff --git a/src/yapf/yapf_costrail.hpp b/src/yapf/yapf_costrail.hpp index 3b57fe3284..5756f04672 100644 --- a/src/yapf/yapf_costrail.hpp +++ b/src/yapf/yapf_costrail.hpp @@ -387,7 +387,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th } /* Check if the next tile is not a choice. */ - if (KillFirstBit2x64(tf_local.m_new_td_bits) != 0) { + if (KillFirstBit(tf_local.m_new_td_bits) != TRACKDIR_BIT_NONE) { /* More than one segment will follow. Close this one. */ end_segment_reason |= ESRB_CHOICE_FOLLOWS; break; diff --git a/src/yapf/yapf_road.cpp b/src/yapf/yapf_road.cpp index 99bde7fdba..e07b48d609 100644 --- a/src/yapf/yapf_road.cpp +++ b/src/yapf/yapf_road.cpp @@ -97,7 +97,7 @@ public: if (!F.Follow(tile, trackdir)) break; // if there are more trackdirs available & reachable, we are at the end of segment - if (KillFirstBit2x64(F.m_new_td_bits) != 0) break; + if (KillFirstBit(F.m_new_td_bits) != TRACKDIR_BIT_NONE) break; Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits);