mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r11383) -Codechange: fixed all the mess around KillFirstBit (tnx to Rubidium and skidd13)
This commit is contained in:
parent
69b1d97c03
commit
4b8aaa994c
20
src/macros.h
20
src/macros.h
|
@ -354,7 +354,7 @@ template<typename T> 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<typename T> static inline T KillFirstBit(T value)
|
||||
{
|
||||
return value &= (uint)(value - 1) | 0x3FFFC0C0;
|
||||
return value &= (T)(value - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue