mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 13:23:45 -07:00
replace MT RNG with PCG (#4973)
replace boost hashing with FNV-1a removes boost as a dependency
This commit is contained in:
parent
081338b9f9
commit
4c547416cc
16 changed files with 63 additions and 466 deletions
12
.github/workflows/test-builds-on-distros.yml
vendored
12
.github/workflows/test-builds-on-distros.yml
vendored
|
@ -23,24 +23,24 @@ jobs:
|
||||||
if: ${{ matrix.image == 'archlinux:base' }}
|
if: ${{ matrix.image == 'archlinux:base' }}
|
||||||
run: |
|
run: |
|
||||||
echo arch
|
echo arch
|
||||||
echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
|
echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net
|
||||||
pacman -Syu --noconfirm
|
pacman -Syu --noconfirm
|
||||||
pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
|
pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net
|
||||||
- name: Install dependencies (dnf)
|
- name: Install dependencies (dnf)
|
||||||
if: ${{ matrix.image == 'fedora:39' }}
|
if: ${{ matrix.image == 'fedora:39' }}
|
||||||
run: |
|
run: |
|
||||||
echo fedora
|
echo fedora
|
||||||
echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} wget git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools tinyxml2-devel spdlog-devel boost-devel
|
echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} wget git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools tinyxml2-devel spdlog-devel
|
||||||
dnf -y upgrade
|
dnf -y upgrade
|
||||||
dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} wget git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools tinyxml2-devel spdlog-devel boost-devel
|
dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} wget git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools tinyxml2-devel spdlog-devel
|
||||||
- name: Install dependencies (apt)
|
- name: Install dependencies (apt)
|
||||||
if: ${{ matrix.image == 'ubuntu:mantic' || matrix.image == 'debian:bookworm' }}
|
if: ${{ matrix.image == 'ubuntu:mantic' || matrix.image == 'debian:bookworm' }}
|
||||||
run: |
|
run: |
|
||||||
echo debian based
|
echo debian based
|
||||||
echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
|
echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libopengl-dev
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get -y full-upgrade
|
apt-get -y full-upgrade
|
||||||
apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
|
apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libopengl-dev
|
||||||
- name: Install dependencies (zypper)
|
- name: Install dependencies (zypper)
|
||||||
if: ${{ matrix.image == 'opensuse/tumbleweed:latest' }}
|
if: ${{ matrix.image == 'opensuse/tumbleweed:latest' }}
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -90,26 +90,26 @@ C:\Program Files\CMake\bin\cmake.exe --build build-cmake --target ExtractAssetHe
|
||||||
#### Debian/Ubuntu
|
#### Debian/Ubuntu
|
||||||
```sh
|
```sh
|
||||||
# using gcc
|
# using gcc
|
||||||
apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
|
apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libopengl-dev
|
||||||
|
|
||||||
# or using clang
|
# or using clang
|
||||||
apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libboost-dev libopengl-dev
|
apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev libopengl-dev
|
||||||
```
|
```
|
||||||
#### Arch
|
#### Arch
|
||||||
```sh
|
```sh
|
||||||
# using gcc
|
# using gcc
|
||||||
pacman -S gcc git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
|
pacman -S gcc git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net
|
||||||
|
|
||||||
# or using clang
|
# or using clang
|
||||||
pacman -S clang git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net boost
|
pacman -S clang git cmake ninja lsb-release sdl2 libpng libzip nlohmann-json tinyxml2 spdlog sdl2_net
|
||||||
```
|
```
|
||||||
#### Fedora
|
#### Fedora
|
||||||
```sh
|
```sh
|
||||||
# using gcc
|
# using gcc
|
||||||
dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools nlohmann-json-devel tinyxml2-devel spdlog-devel boost-devel
|
dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools nlohmann-json-devel tinyxml2-devel spdlog-devel
|
||||||
|
|
||||||
# or using clang
|
# or using clang
|
||||||
dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools nlohmann-json-devel tinyxml2-devel spdlog-devel boost-devel
|
dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools nlohmann-json-devel tinyxml2-devel spdlog-devel
|
||||||
```
|
```
|
||||||
#### openSUSE
|
#### openSUSE
|
||||||
```sh
|
```sh
|
||||||
|
|
|
@ -276,32 +276,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||||
endif()
|
endif()
|
||||||
################################################################################
|
################################################################################
|
||||||
# Find/download Boost
|
|
||||||
################################################################################
|
|
||||||
include(FetchContent)
|
|
||||||
FetchContent_Declare(
|
|
||||||
Boost
|
|
||||||
URL https://archives.boost.io/release/1.81.0/source/boost_1_81_0.tar.gz
|
|
||||||
URL_HASH SHA256=205666dea9f6a7cfed87c7a6dfbeb52a2c1b9de55712c9c1a87735d7181452b6
|
|
||||||
SOURCE_SUBDIR "null" # Set to a nonexistent directory so boost is not built (we don't need to build it)
|
|
||||||
DOWNLOAD_EXTRACT_TIMESTAMP false # supress timestamp warning, not needed since the url wont change
|
|
||||||
)
|
|
||||||
|
|
||||||
set(Boost_NO_BOOST_CMAKE false)
|
|
||||||
set(BOOST_INCLUDEDIR ${FETCHCONTENT_BASE_DIR}/boost-src) # Location where FetchContent stores the source
|
|
||||||
message("Searching for Boost installation")
|
|
||||||
find_package(Boost)
|
|
||||||
|
|
||||||
if (NOT ${Boost_FOUND})
|
|
||||||
message("Boost not found. Downloading now...")
|
|
||||||
FetchContent_MakeAvailable(Boost)
|
|
||||||
message("Boost downloaded to " ${FETCHCONTENT_BASE_DIR}/boost-src)
|
|
||||||
set(BOOST-INCLUDE ${FETCHCONTENT_BASE_DIR}/boost-src)
|
|
||||||
else()
|
|
||||||
message("Boost found in " ${Boost_INCLUDE_DIRS})
|
|
||||||
set(BOOST-INCLUDE ${Boost_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
################################################################################
|
|
||||||
# Compile definitions
|
# Compile definitions
|
||||||
################################################################################
|
################################################################################
|
||||||
find_package(SDL2)
|
find_package(SDL2)
|
||||||
|
@ -349,7 +323,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type
|
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type
|
||||||
${SDL2-INCLUDE}
|
${SDL2-INCLUDE}
|
||||||
${SDL2-NET-INCLUDE}
|
${SDL2-NET-INCLUDE}
|
||||||
${BOOST-INCLUDE}
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/assets/
|
${CMAKE_CURRENT_SOURCE_DIR}/assets/
|
||||||
.
|
.
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
// 32 bit implementation based off of Boost hash
|
|
||||||
|
|
||||||
#ifndef BOOST_HASH_DETAIL_HASH_MIX_32_HPP
|
|
||||||
#define BOOST_HASH_DETAIL_HASH_MIX_32_HPP
|
|
||||||
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <climits>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
namespace hash_detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template<uint32_t Bits> struct hash_mix_impl_32;
|
|
||||||
|
|
||||||
// hash_mix for 32 bit
|
|
||||||
//
|
|
||||||
// We use the "best xmxmx" implementation from
|
|
||||||
// https://github.com/skeeto/hash-prospector/issues/19
|
|
||||||
|
|
||||||
template<> struct hash_mix_impl_32<32>
|
|
||||||
{
|
|
||||||
inline static boost::uint32_t fn( boost::uint32_t x )
|
|
||||||
{
|
|
||||||
boost::uint32_t const m1 = 0x21f0aaad;
|
|
||||||
boost::uint32_t const m2 = 0x735a2d97;
|
|
||||||
|
|
||||||
x ^= x >> 16;
|
|
||||||
x *= m1;
|
|
||||||
x ^= x >> 15;
|
|
||||||
x *= m2;
|
|
||||||
x ^= x >> 15;
|
|
||||||
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline uint32_t hash_mix_32( uint32_t v )
|
|
||||||
{
|
|
||||||
return hash_mix_impl_32<32>::fn( v );
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace hash_detail
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_HASH_DETAIL_HASH_MIX_32_HPP
|
|
|
@ -1,128 +0,0 @@
|
||||||
// 32 bit implementation based off of Boost hash
|
|
||||||
// Only implementing 32 bit version of char based ranges
|
|
||||||
|
|
||||||
#ifndef BOOST_HASH_DETAIL_HASH_RANGE_32_HPP
|
|
||||||
#define BOOST_HASH_DETAIL_HASH_RANGE_32_HPP
|
|
||||||
|
|
||||||
#include <boost_custom/container_hash/hash_fwd_32.hpp>
|
|
||||||
#include <boost_custom/container_hash/version.hpp>
|
|
||||||
|
|
||||||
#if BOOST_VERSION_HAS_HASH_RANGE
|
|
||||||
#include <boost/container_hash/detail/hash_range.hpp>
|
|
||||||
#else
|
|
||||||
#include <boost/type_traits/integral_constant.hpp>
|
|
||||||
#include <boost/type_traits/enable_if.hpp>
|
|
||||||
#include <boost/type_traits/is_same.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
#include <cstddef>
|
|
||||||
#include <climits>
|
|
||||||
#include <iterator>
|
|
||||||
#endif // #if BOOST_VERSION_HAS_HASH_RANGE
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
namespace hash_detail
|
|
||||||
{
|
|
||||||
|
|
||||||
#if !BOOST_VERSION_HAS_HASH_RANGE
|
|
||||||
|
|
||||||
template<class T> struct is_char_type: public boost::false_type {};
|
|
||||||
|
|
||||||
#if CHAR_BIT == 8
|
|
||||||
|
|
||||||
template<> struct is_char_type<char>: public boost::true_type {};
|
|
||||||
template<> struct is_char_type<signed char>: public boost::true_type {};
|
|
||||||
template<> struct is_char_type<unsigned char>: public boost::true_type {};
|
|
||||||
|
|
||||||
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
|
|
||||||
template<> struct is_char_type<char8_t>: public boost::true_type {};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
|
||||||
template<> struct is_char_type<std::byte>: public boost::true_type {};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #if !BOOST_VERSION_HAS_HASH_RANGE
|
|
||||||
|
|
||||||
#if BOOST_USE_STD_TYPES
|
|
||||||
#define BOOST_ENABLE_IF std::enable_if
|
|
||||||
#define BOOST_IS_SAME std::is_same
|
|
||||||
#else
|
|
||||||
#define BOOST_ENABLE_IF boost::enable_if_
|
|
||||||
#define BOOST_IS_SAME is_same
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<class It>
|
|
||||||
inline typename BOOST_ENABLE_IF<
|
|
||||||
is_char_type<typename std::iterator_traits<It>::value_type>::value &&
|
|
||||||
BOOST_IS_SAME<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value,
|
|
||||||
std::size_t>::type
|
|
||||||
hash_range_32( uint32_t seed, It first, It last )
|
|
||||||
{
|
|
||||||
std::size_t n = static_cast<std::size_t>( last - first );
|
|
||||||
|
|
||||||
for( ; n >= 4; first += 4, n -= 4 )
|
|
||||||
{
|
|
||||||
// clang 5+, gcc 5+ figure out this pattern and use a single mov on x86
|
|
||||||
// gcc on s390x and power BE even knows how to use load-reverse
|
|
||||||
|
|
||||||
boost::uint32_t w =
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) |
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[1] ) ) << 8 |
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[2] ) ) << 16 |
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[3] ) ) << 24;
|
|
||||||
|
|
||||||
hash_combine_32( seed, w );
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// add a trailing suffix byte of 0x01 because otherwise sequences of
|
|
||||||
// trailing zeroes are indistinguishable from end of string
|
|
||||||
|
|
||||||
boost::uint32_t w = 0x01u;
|
|
||||||
|
|
||||||
switch( n )
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
|
|
||||||
w =
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) |
|
|
||||||
0x0100u;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
|
|
||||||
w =
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) |
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[1] ) ) << 8 |
|
|
||||||
0x010000u;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
|
|
||||||
w =
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[0] ) ) |
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[1] ) ) << 8 |
|
|
||||||
static_cast<boost::uint32_t>( static_cast<unsigned char>( first[2] ) ) << 16 |
|
|
||||||
0x01000000u;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_combine_32( seed, w );
|
|
||||||
}
|
|
||||||
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace hash_detail
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#undef BOOST_ENABLE_IF
|
|
||||||
#undef BOOST_IS_SAME
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_HASH_DETAIL_HASH_RANGE_32_HPP
|
|
|
@ -1,188 +0,0 @@
|
||||||
// 32 bit implementation based off of Boost hash
|
|
||||||
// Only implementing 32 bit versions integral and string based hashes
|
|
||||||
|
|
||||||
#ifndef BOOST_FUNCTIONAL_HASH_HASH_32_HPP
|
|
||||||
#define BOOST_FUNCTIONAL_HASH_HASH_32_HPP
|
|
||||||
|
|
||||||
#include <boost/container_hash/hash.hpp>
|
|
||||||
#include <boost_custom/container_hash/hash_fwd_32.hpp>
|
|
||||||
#include <boost_custom/container_hash/detail/hash_mix_32.hpp>
|
|
||||||
#include <boost_custom/container_hash/detail/hash_range_32.hpp>
|
|
||||||
#include <boost_custom/container_hash/version.hpp>
|
|
||||||
|
|
||||||
#if !BOOST_VERSION_HAS_HASH_RANGE
|
|
||||||
#include <boost/type_traits/is_unsigned.hpp>
|
|
||||||
#include <boost/type_traits/make_unsigned.hpp>
|
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__GNUC__, < 3) \
|
|
||||||
&& !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
|
||||||
#define BOOST_HASH_CHAR_TRAITS string_char_traits
|
|
||||||
#else
|
|
||||||
#define BOOST_HASH_CHAR_TRAITS char_traits
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #if !BOOST_VERSION_HAS_HASH_RANGE
|
|
||||||
|
|
||||||
#if BOOST_USE_STD_TYPES
|
|
||||||
#define BOOST_ENABLE_IF std::enable_if
|
|
||||||
#define BOOST_IS_INTEGRAL hash_detail::is_integral
|
|
||||||
#define BOOST_IS_UNSIGNED is_unsigned
|
|
||||||
#define BOOST_MAKE_UNSIGNED make_unsigned
|
|
||||||
#else
|
|
||||||
#define BOOST_ENABLE_IF boost::enable_if_
|
|
||||||
#define BOOST_IS_INTEGRAL boost::is_integral
|
|
||||||
#define BOOST_IS_UNSIGNED boost::is_unsigned
|
|
||||||
#define BOOST_MAKE_UNSIGNED boost::make_unsigned
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
|
||||||
// boost::hash_value
|
|
||||||
//
|
|
||||||
|
|
||||||
// integral types
|
|
||||||
|
|
||||||
namespace hash_detail
|
|
||||||
{
|
|
||||||
template<class T,
|
|
||||||
bool bigger_than_size_t = (sizeof(T) > sizeof(uint32_t)),
|
|
||||||
bool is_unsigned = BOOST_IS_UNSIGNED<T>::value,
|
|
||||||
std::size_t size_t_bits = sizeof(uint32_t) * CHAR_BIT,
|
|
||||||
std::size_t type_bits = sizeof(T) * CHAR_BIT>
|
|
||||||
struct hash_integral_impl_32;
|
|
||||||
|
|
||||||
template<class T, bool is_unsigned, std::size_t size_t_bits, std::size_t type_bits> struct hash_integral_impl_32<T, false, is_unsigned, size_t_bits, type_bits>
|
|
||||||
{
|
|
||||||
static uint32_t fn( T v )
|
|
||||||
{
|
|
||||||
return static_cast<uint32_t>( v );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, std::size_t size_t_bits, std::size_t type_bits> struct hash_integral_impl_32<T, true, false, size_t_bits, type_bits>
|
|
||||||
{
|
|
||||||
static uint32_t fn( T v )
|
|
||||||
{
|
|
||||||
typedef typename BOOST_MAKE_UNSIGNED<T>::type U;
|
|
||||||
|
|
||||||
if( v >= 0 )
|
|
||||||
{
|
|
||||||
return hash_integral_impl_32<U>::fn( static_cast<U>( v ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ~hash_integral_impl_32<U>::fn( static_cast<U>( ~static_cast<U>( v ) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T> struct hash_integral_impl_32<T, true, true, 32, 64>
|
|
||||||
{
|
|
||||||
static uint32_t fn( T v )
|
|
||||||
{
|
|
||||||
uint32_t seed = 0;
|
|
||||||
|
|
||||||
seed = static_cast<uint32_t>( v >> 32 ) + hash_detail::hash_mix_32( seed );
|
|
||||||
seed = static_cast<uint32_t>( v ) + hash_detail::hash_mix_32( seed );
|
|
||||||
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T> struct hash_integral_impl_32<T, true, true, 32, 128>
|
|
||||||
{
|
|
||||||
static uint32_t fn( T v )
|
|
||||||
{
|
|
||||||
uint32_t seed = 0;
|
|
||||||
|
|
||||||
seed = static_cast<uint32_t>( v >> 96 ) + hash_detail::hash_mix_32( seed );
|
|
||||||
seed = static_cast<uint32_t>( v >> 64 ) + hash_detail::hash_mix_32( seed );
|
|
||||||
seed = static_cast<uint32_t>( v >> 32 ) + hash_detail::hash_mix_32( seed );
|
|
||||||
seed = static_cast<uint32_t>( v ) + hash_detail::hash_mix_32( seed );
|
|
||||||
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace hash_detail
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
typename BOOST_ENABLE_IF<BOOST_IS_INTEGRAL<T>::value, uint32_t>::type
|
|
||||||
hash_value_32( T v )
|
|
||||||
{
|
|
||||||
return hash_detail::hash_integral_impl_32<T>::fn( v );
|
|
||||||
}
|
|
||||||
|
|
||||||
// contiguous ranges (string, vector, array)
|
|
||||||
#if BOOST_VERSION_HAS_HASH_RANGE
|
|
||||||
template <typename T>
|
|
||||||
typename BOOST_ENABLE_IF<container_hash::is_contiguous_range<T>::value, uint32_t>::type
|
|
||||||
hash_value_32( T const& v )
|
|
||||||
{
|
|
||||||
return boost::hash_range_32( v.data(), v.data() + v.size() );
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template <class Ch, class A>
|
|
||||||
inline uint32_t hash_value_32(
|
|
||||||
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
|
|
||||||
{
|
|
||||||
return boost::hash_range_32( v.data(), v.data() + v.size() );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// boost::hash_combine
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline void hash_combine_32( uint32_t& seed, T const& v )
|
|
||||||
{
|
|
||||||
seed = boost::hash_detail::hash_mix_32( seed + 0x9e3779b9 + boost::hash_32<T>()( v ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// boost::hash_range
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class It>
|
|
||||||
inline void hash_range_32( uint32_t& seed, It first, It last )
|
|
||||||
{
|
|
||||||
seed = hash_detail::hash_range_32( seed, first, last );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class It>
|
|
||||||
inline uint32_t hash_range_32( It first, It last )
|
|
||||||
{
|
|
||||||
uint32_t seed = 0;
|
|
||||||
|
|
||||||
hash_range_32( seed, first, last );
|
|
||||||
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// boost::hash
|
|
||||||
//
|
|
||||||
|
|
||||||
template <class T> struct hash_32
|
|
||||||
{
|
|
||||||
typedef T argument_type;
|
|
||||||
typedef uint32_t result_type;
|
|
||||||
|
|
||||||
uint32_t operator()( T const& val ) const
|
|
||||||
{
|
|
||||||
return hash_value_32( val );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#undef BOOST_HASH_CHAR_TRAITS
|
|
||||||
#undef BOOST_ENABLE_IF
|
|
||||||
#undef BOOST_IS_INTEGRAL
|
|
||||||
#undef BOOST_IS_UNSIGNED
|
|
||||||
#undef BOOST_MAKE_UNSIGNED
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_32_HPP
|
|
|
@ -1,25 +0,0 @@
|
||||||
// 32 bit implementation based off of Boost hash
|
|
||||||
|
|
||||||
#ifndef BOOST_FUNCTIONAL_HASH_FWD_32_HPP
|
|
||||||
#define BOOST_FUNCTIONAL_HASH_FWD_32_HPP
|
|
||||||
|
|
||||||
#include <boost/container_hash/hash_fwd.hpp>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace container_hash
|
|
||||||
{
|
|
||||||
|
|
||||||
} // namespace container_hash
|
|
||||||
|
|
||||||
template<class T> struct hash_32;
|
|
||||||
|
|
||||||
template<class T> void hash_combine_32( uint32_t& seed, T const& v );
|
|
||||||
|
|
||||||
template<class It> void hash_range_32( uint32_t&, It, It );
|
|
||||||
template<class It> uint32_t hash_range_32( It, It );
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_32_HPP
|
|
|
@ -1,11 +0,0 @@
|
||||||
|
|
||||||
#ifndef BOOST_CONTAINER_HASH_VERSION_HPP
|
|
||||||
#define BOOST_CONTAINER_HASH_VERSION_HPP
|
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
|
|
||||||
#define BOOST_VERSION_HAS_HASH_RANGE ((BOOST_VERSION / 100 % 1000) >= 81)
|
|
||||||
|
|
||||||
#define BOOST_USE_STD_TYPES ((BOOST_VERSION / 100 % 1000) >= 84)
|
|
||||||
|
|
||||||
#endif // #ifndef BOOST_CONTAINER_HASH_VERSION_HPP
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "soh/Enhancements/debugger/performanceTimer.h"
|
#include "soh/Enhancements/debugger/performanceTimer.h"
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include "../../randomizer/randomizerTypes.h"
|
#include "../../randomizer/randomizerTypes.h"
|
||||||
#include <boost_custom/container_hash/hash_32.hpp>
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool seedChanged;
|
bool seedChanged;
|
||||||
|
@ -30,7 +29,7 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
|
||||||
srand(static_cast<uint32_t>(time(NULL)));
|
srand(static_cast<uint32_t>(time(NULL)));
|
||||||
// if a blank seed was entered, make a random one
|
// if a blank seed was entered, make a random one
|
||||||
if (seedInput.empty()) {
|
if (seedInput.empty()) {
|
||||||
seedInput = std::to_string(rand() % 0xFFFFFFFF);
|
seedInput = std::to_string(rand());
|
||||||
} else if (seedInput.rfind("seed_testing_count", 0) == 0 && seedInput.length() > 18) {
|
} else if (seedInput.rfind("seed_testing_count", 0) == 0 && seedInput.length() > 18) {
|
||||||
int count;
|
int count;
|
||||||
try {
|
try {
|
||||||
|
@ -43,8 +42,8 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->SetSeedString(seedInput);
|
ctx->SetSeedString(seedInput);
|
||||||
uint32_t seedHash = boost::hash_32<std::string>{}(ctx->GetSeedString());
|
uint32_t seedHash = SohUtils::Hash(ctx->GetSeedString());
|
||||||
ctx->SetSeed(seedHash & 0xFFFFFFFF);
|
ctx->SetSeed(seedHash);
|
||||||
|
|
||||||
ctx->ClearItemLocations();
|
ctx->ClearItemLocations();
|
||||||
int ret = Playthrough::Playthrough_Init(ctx->GetSeed(), excludedLocations, enabledTricks);
|
int ret = Playthrough::Playthrough_Init(ctx->GetSeed(), excludedLocations, enabledTricks);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "playthrough.hpp"
|
#include "playthrough.hpp"
|
||||||
|
|
||||||
#include <libultraship/libultraship.h>
|
#include <libultraship/libultraship.h>
|
||||||
#include <boost_custom/container_hash/hash_32.hpp>
|
|
||||||
#include "fill.hpp"
|
#include "fill.hpp"
|
||||||
#include "../location_access.h"
|
#include "../location_access.h"
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
|
@ -62,7 +61,7 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
|
||||||
settingsStr += (char*)gBuildVersion;
|
settingsStr += (char*)gBuildVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t finalHash = boost::hash_32<std::string>{}(std::to_string(ctx->GetSeed()) + settingsStr);
|
uint32_t finalHash = SohUtils::Hash(std::to_string(ctx->GetSeed()) + settingsStr);
|
||||||
Random_Init(finalHash);
|
Random_Init(finalHash);
|
||||||
ctx->SetHash(std::to_string(finalHash));
|
ctx->SetHash(std::to_string(finalHash));
|
||||||
|
|
||||||
|
@ -104,9 +103,9 @@ int Playthrough_Repeat(std::set<RandomizerCheck> excludedLocations, std::set<Ran
|
||||||
auto ctx = Rando::Context::GetInstance();
|
auto ctx = Rando::Context::GetInstance();
|
||||||
uint32_t repeatedSeed = 0;
|
uint32_t repeatedSeed = 0;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
ctx->SetSeedString(std::to_string(rand() % 0xFFFFFFFF));
|
ctx->SetSeedString(std::to_string(rand()));
|
||||||
repeatedSeed = boost::hash_32<std::string>{}(ctx->GetSeedString());
|
repeatedSeed = SohUtils::Hash(ctx->GetSeedString());
|
||||||
ctx->SetSeed(repeatedSeed % 0xFFFFFFFF);
|
ctx->SetSeed(repeatedSeed);
|
||||||
SPDLOG_DEBUG("testing seed: %d", repeatedSeed);
|
SPDLOG_DEBUG("testing seed: %d", repeatedSeed);
|
||||||
ClearProgress();
|
ClearProgress();
|
||||||
Playthrough_Init(ctx->GetSeed(), excludedLocations, enabledTricks);
|
Playthrough_Init(ctx->GetSeed(), excludedLocations, enabledTricks);
|
||||||
|
|
|
@ -1,40 +1,55 @@
|
||||||
#include "random.hpp"
|
#include "random.hpp"
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <boost/random/mersenne_twister.hpp>
|
#include <cassert>
|
||||||
#include <boost/random/uniform_int_distribution.hpp>
|
|
||||||
#include <boost/random/uniform_real_distribution.hpp>
|
|
||||||
|
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
static boost::random::mt19937 generator;
|
static uint64_t state = 0;
|
||||||
|
const uint64_t multiplier = 6364136223846793005ULL;
|
||||||
|
const uint64_t increment = 11634580027462260723ULL;
|
||||||
|
|
||||||
// Initialize with seed specified
|
// Initialize with seed specified
|
||||||
void Random_Init(uint32_t seed) {
|
void Random_Init(uint64_t seed) {
|
||||||
init = true;
|
init = true;
|
||||||
generator = boost::random::mt19937{ seed };
|
state = seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Random_InitSeed() {
|
uint32_t next32() {
|
||||||
if (!init) {
|
if (!init) {
|
||||||
// No seed given, get a random number from device to seed
|
// No seed given, get a random number from device to seed
|
||||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||||
const auto seed = static_cast<uint32_t>(std::random_device{}());
|
uint64_t seed = static_cast<uint64_t>(std::random_device{}());
|
||||||
#else
|
#else
|
||||||
uint32_t seed = static_cast<uint32_t>(std::hash<std::string>{}(std::to_string(rand())));
|
uint64_t seed = static_cast<uint64_t>(std::hash<std::string>{}(std::to_string(rand())));
|
||||||
#endif
|
#endif
|
||||||
Random_Init(seed);
|
Random_Init(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state = state * multiplier + increment;
|
||||||
|
uint32_t xorshifted = static_cast<uint32_t>(((state >> 18) ^ state) >> 27);
|
||||||
|
uint32_t rot = static_cast<int>(state >> 59);
|
||||||
|
return std::rotr(xorshifted, rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a random unsigned integer in range [min, max-1]
|
// Returns a random integer in range [min, max-1]
|
||||||
uint32_t Random(uint32_t min, uint32_t max) {
|
uint32_t Random(uint32_t min, uint32_t max) {
|
||||||
Random_InitSeed();
|
if (min == max) {
|
||||||
boost::random::uniform_int_distribution<uint32_t> distribution(min, max - 1);
|
return min;
|
||||||
return distribution(generator);
|
}
|
||||||
|
assert(max > min);
|
||||||
|
|
||||||
|
uint32_t n = max - min;
|
||||||
|
uint32_t cutoff = UINT32_MAX - UINT32_MAX % static_cast<uint32_t>(n);
|
||||||
|
for (;;) {
|
||||||
|
uint32_t r = next32();
|
||||||
|
if (r <= cutoff) {
|
||||||
|
return min + r % n;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a random floating point number in [0.0, 1.0)
|
// Returns a random floating point number in [0.0, 1.0)
|
||||||
double RandomDouble() {
|
double RandomDouble() {
|
||||||
boost::random::uniform_real_distribution<double> distribution(0.0, 1.0);
|
return ldexp(next32(), -32);
|
||||||
return distribution(generator);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
void Random_Init(uint32_t seed);
|
void Random_Init(uint64_t seed);
|
||||||
uint32_t Random(uint32_t min, uint32_t max);
|
uint32_t Random(uint32_t min, uint32_t max);
|
||||||
double RandomDouble();
|
double RandomDouble();
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include "soh/SohGui/UIWidgets.hpp"
|
#include "soh/SohGui/UIWidgets.hpp"
|
||||||
#include "static_data.h"
|
#include "static_data.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
#include <boost_custom/container_hash/hash_32.hpp>
|
|
||||||
#include "randomizer_settings_window.h"
|
#include "randomizer_settings_window.h"
|
||||||
#include "savefile.h"
|
#include "savefile.h"
|
||||||
#include "entrance.h"
|
#include "entrance.h"
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include "Enhancements/custom-message/CustomMessageManager.h"
|
#include "Enhancements/custom-message/CustomMessageManager.h"
|
||||||
#include "Enhancements/Presets/Presets.h"
|
#include "Enhancements/Presets/Presets.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <boost_custom/container_hash/hash_32.hpp>
|
|
||||||
|
|
||||||
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
||||||
#include "Extractor/Extract.h"
|
#include "Extractor/Extract.h"
|
||||||
|
@ -2640,7 +2639,7 @@ void SoH_ProcessDroppedFiles(std::string filePath) {
|
||||||
gui->SaveConsoleVariablesNextFrame();
|
gui->SaveConsoleVariablesNextFrame();
|
||||||
ShipInit::Init("*");
|
ShipInit::Init("*");
|
||||||
|
|
||||||
uint32_t finalHash = boost::hash_32<std::string>{}(configJson.dump());
|
uint32_t finalHash = SohUtils::Hash(configJson.dump());
|
||||||
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Configuration Loaded. Hash: %d", finalHash);
|
gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Configuration Loaded. Hash: %d", finalHash);
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
SPDLOG_ERROR("Failed to load config file: {}", e.what());
|
SPDLOG_ERROR("Failed to load config file: {}", e.what());
|
||||||
|
|
|
@ -398,3 +398,14 @@ bool SohUtils::IsStringEmpty(std::string str) {
|
||||||
// Check if the string is empty after stripping spaces
|
// Check if the string is empty after stripping spaces
|
||||||
return start == std::string::npos || end == std::string::npos;
|
return start == std::string::npos || end == std::string::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SohUtils::Hash(std::string str) {
|
||||||
|
// FNV-1a
|
||||||
|
const size_t len = str.size();
|
||||||
|
uint32_t hval = 0x811c9dc5;
|
||||||
|
for (size_t pos = 0; pos < len; pos++) {
|
||||||
|
hval ^= (uint32_t)str[pos];
|
||||||
|
hval *= 0x01000193;
|
||||||
|
}
|
||||||
|
return hval;
|
||||||
|
}
|
||||||
|
|
|
@ -22,4 +22,5 @@ std::string Sanitize(std::string stringValue);
|
||||||
size_t CopyStringToCharBuffer(char* buffer, const std::string& source, size_t maxBufferSize);
|
size_t CopyStringToCharBuffer(char* buffer, const std::string& source, size_t maxBufferSize);
|
||||||
|
|
||||||
bool IsStringEmpty(std::string str);
|
bool IsStringEmpty(std::string str);
|
||||||
|
uint32_t Hash(std::string str);
|
||||||
} // namespace SohUtils
|
} // namespace SohUtils
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue