From f8f3bb242188fc433fba71550ce9fba5b7e18a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Thu, 17 Mar 2022 17:35:34 +0200 Subject: [PATCH] Use std::minstd_rand and split serialization from save/load --- apps/openmw/mwworld/worldimp.cpp | 9 +++---- components/misc/rng.cpp | 19 +++++++++++++++ components/misc/rng.hpp | 40 ++++---------------------------- 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index fb48707a8e..6517694f15 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -342,7 +342,7 @@ namespace MWWorld void World::write (ESM::ESMWriter& writer, Loading::Listener& progress) const { writer.startRecord(ESM::REC_RAND); - writer.writeHNT("RAND", mPrng.getSeed()); + writer.writeHNOString("RAND", Misc::Rng::serialize(mPrng)); writer.endRecord(ESM::REC_RAND); // Active cells could have a dirty fog of war, sync it to the CellStore first @@ -385,11 +385,8 @@ namespace MWWorld return; case ESM::REC_RAND: { - Misc::Rng::Generator::result_type seed{}; - reader.getHNT(seed, "RAND"); - Log(Debug::Info) << "---- World random state: " << seed << " ----"; - mPrng.seed(seed); - Misc::Rng::getGenerator().seed(seed); + auto data = reader.getHNOString("RAND"); + Misc::Rng::deserialize(data, mPrng); } break; case ESM::REC_PLAY: diff --git a/components/misc/rng.cpp b/components/misc/rng.cpp index b44c6c2785..01044040a0 100644 --- a/components/misc/rng.cpp +++ b/components/misc/rng.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -14,6 +15,23 @@ namespace Misc::Rng return sGenerator; } + std::string serialize(const Generator& prng) + { + std::stringstream ss; + ss << prng; + + return ss.str(); + } + + void deserialize(std::string_view data, Generator& prng) + { + std::stringstream ss; + ss << data; + + ss.seekg(0); + ss >> prng; + } + unsigned int generateDefaultSeed() { auto res = static_cast(std::chrono::high_resolution_clock::now().time_since_epoch().count()); @@ -65,4 +83,5 @@ namespace Misc::Rng { return std::uniform_real_distribution(mean - deviation, mean + deviation)(prng); } + } diff --git a/components/misc/rng.hpp b/components/misc/rng.hpp index 1b7831e3c6..d7ab7f3e7a 100644 --- a/components/misc/rng.hpp +++ b/components/misc/rng.hpp @@ -3,50 +3,20 @@ #include #include +#include /* Provides central implementation of the RNG logic */ namespace Misc::Rng { - class Generator - { - uint32_t mState{}; - - public: - using result_type = uint32_t; - - constexpr Generator() = default; - constexpr Generator(result_type seed) : mState{ seed } {} - constexpr result_type operator()() noexcept - { - mState = (214013 * mState + 2531011); - return (mState >> 16) & max(); - } - - static constexpr result_type min() noexcept - { - return 0u; - } - - static constexpr result_type max() noexcept - { - return 0x7FFFu; - } - - void seed(result_type val) noexcept - { - mState = val; - } - - uint32_t getSeed() const noexcept - { - return mState; - } - }; + using Generator = std::minstd_rand; Generator& getGenerator(); + std::string serialize(const Generator& prng); + void deserialize(std::string_view data, Generator& prng); + /// returns default seed for RNG unsigned int generateDefaultSeed();