mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Replace custom BitCount implementation with std::popcount (C++20)
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "../world/Entrance.h"
|
||||
#include "../world/Footpath.h"
|
||||
|
||||
#include <bit>
|
||||
#include <bitset>
|
||||
#include <cstring>
|
||||
|
||||
@@ -848,7 +849,7 @@ namespace OpenRCT2::PathFinding
|
||||
|
||||
searchResult = PathSearchResult::Thin;
|
||||
|
||||
uint8_t numEdges = BitCount(tileElement->AsPath()->GetEdges());
|
||||
uint8_t numEdges = std::popcount(tileElement->AsPath()->GetEdges());
|
||||
|
||||
if (numEdges < 2)
|
||||
{
|
||||
@@ -1371,7 +1372,7 @@ namespace OpenRCT2::PathFinding
|
||||
* edge that gives the best (i.e. smallest) value (best_score)
|
||||
* or for different edges with equal value, the edge with the
|
||||
* least steps (best_sub). */
|
||||
int32_t numEdges = BitCount(edges);
|
||||
int32_t numEdges = std::popcount(edges);
|
||||
for (int32_t testEdge = chosenEdge; testEdge != -1; testEdge = UtilBitScanForward(edges))
|
||||
{
|
||||
edges &= ~(1 << testEdge);
|
||||
@@ -1994,7 +1995,7 @@ namespace OpenRCT2::PathFinding
|
||||
if (peep.HasItem(ShopItem::Map))
|
||||
{
|
||||
// If at least 2 directions consult map
|
||||
if (BitCount(edges) >= 2)
|
||||
if (std::popcount(edges) >= 2)
|
||||
{
|
||||
uint16_t probability = 1638;
|
||||
if (peep.HeadingForRideOrParkExit())
|
||||
|
||||
@@ -172,56 +172,6 @@ bool AVX2Available()
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool BitCountPopcntAvailable()
|
||||
{
|
||||
#ifdef OPENRCT2_X86
|
||||
// POPCNT support is declared as the 23rd bit of ECX with CPUID(EAX = 1).
|
||||
uint32_t regs[4] = { 0 };
|
||||
if (CPUIDX86(regs, 1))
|
||||
{
|
||||
return (regs[2] & (1 << 23));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t BitCountPopcnt(uint32_t source)
|
||||
{
|
||||
// Use CPUID defines to figure out calling style
|
||||
#if defined(OpenRCT2_CPUID_GNUC_X86)
|
||||
// use asm directly in order to actually emit the instruction : using
|
||||
// __builtin_popcount results in an extra call to a library function.
|
||||
int32_t rv;
|
||||
asm volatile("popcnt %1,%0" : "=r"(rv) : "rm"(source) : "cc");
|
||||
return rv;
|
||||
#elif defined(OpenRCT2_CPUID_MSVC_X86)
|
||||
return _mm_popcnt_u32(source);
|
||||
#else
|
||||
Guard::Fail("bitcount_popcnt() called, without support compiled in");
|
||||
return INT_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int32_t BitCountLut(uint32_t source)
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html
|
||||
static constexpr uint8_t BitsSetTable256[256] = {
|
||||
#define B2(n) n, (n) + 1, (n) + 1, (n) + 2
|
||||
#define B4(n) B2(n), B2((n) + 1), B2((n) + 1), B2((n) + 2)
|
||||
#define B6(n) B4(n), B4((n) + 1), B4((n) + 1), B4((n) + 2)
|
||||
B6(0), B6(1), B6(1), B6(2)
|
||||
};
|
||||
return BitsSetTable256[source & 0xff] + BitsSetTable256[(source >> 8) & 0xff] + BitsSetTable256[(source >> 16) & 0xff]
|
||||
+ BitsSetTable256[source >> 24];
|
||||
}
|
||||
|
||||
static const auto BitCountFn = BitCountPopcntAvailable() ? BitCountPopcnt : BitCountLut;
|
||||
|
||||
int32_t BitCount(uint32_t source)
|
||||
{
|
||||
return BitCountFn(source);
|
||||
}
|
||||
|
||||
/* Case insensitive logical compare */
|
||||
// Example:
|
||||
// - Guest 10
|
||||
|
||||
@@ -29,7 +29,6 @@ bool AVX2Available();
|
||||
|
||||
int32_t UtilBitScanForward(int32_t source);
|
||||
int32_t UtilBitScanForward(int64_t source);
|
||||
int32_t BitCount(uint32_t source);
|
||||
int32_t StrLogicalCmp(char const* a, char const* b);
|
||||
char* SafeStrCpy(char* destination, const char* source, size_t num);
|
||||
char* SafeStrCat(char* destination, const char* source, size_t size);
|
||||
|
||||
@@ -45,9 +45,11 @@
|
||||
#include "Surface.h"
|
||||
#include "TileElement.h"
|
||||
|
||||
#include <bit>
|
||||
#include <iterator>
|
||||
|
||||
using namespace OpenRCT2::TrackMetaData;
|
||||
|
||||
void FootpathUpdateQueueEntranceBanner(const CoordsXY& footpathPos, TileElement* tileElement);
|
||||
|
||||
FootpathSelection gFootpathSelection;
|
||||
@@ -1134,8 +1136,8 @@ void FootpathChainRideQueue(
|
||||
{
|
||||
// Fix #2051: Stop queue paths that are already connected to two other tiles
|
||||
// from connecting to the tile we are coming from.
|
||||
int32_t edges = tileElement->AsPath()->GetEdges();
|
||||
int32_t numEdges = BitCount(edges);
|
||||
uint32_t edges = tileElement->AsPath()->GetEdges();
|
||||
uint32_t numEdges = std::popcount(edges);
|
||||
if (numEdges >= 2)
|
||||
{
|
||||
int32_t requiredEdgeMask = 1 << DirectionReverse(direction);
|
||||
|
||||
Reference in New Issue
Block a user