diff --git a/src/displayapp/screens/Dice.cpp b/src/displayapp/screens/Dice.cpp index 302c5f3fb2..1205d5fceb 100644 --- a/src/displayapp/screens/Dice.cpp +++ b/src/displayapp/screens/Dice.cpp @@ -43,11 +43,11 @@ Dice::Dice(Controllers::MotionController& motionController, Controllers::MotorController& motorController, Controllers::Settings& settingsController) : motorController {motorController}, motionController {motionController}, settingsController {settingsController} { - std::seed_seq sseq {static_cast(xTaskGetTickCount()), - static_cast(motionController.X()), - static_cast(motionController.Y()), - static_cast(motionController.Z())}; - gen.seed(sseq); + uint32_t seed = static_cast(xTaskGetTickCount()); + seed = seed * 31 + static_cast(motionController.X()); + seed = seed * 31 + static_cast(motionController.Y()); + seed = seed * 31 + static_cast(motionController.Z()); + gen.Seed(seed); lv_obj_t* nCounterLabel = MakeLabel(&jetbrains_mono_bold_20, LV_COLOR_WHITE, diff --git a/src/displayapp/screens/Dice.h b/src/displayapp/screens/Dice.h index d12848d3cf..3f15a32500 100644 --- a/src/displayapp/screens/Dice.h +++ b/src/displayapp/screens/Dice.h @@ -29,7 +29,38 @@ namespace Pinetime { lv_task_t* refreshTask; bool enableShakeForDice = false; - std::mt19937 gen; + // std::mt19937 keeps 624 words of state and needs roughly 2.5 KB of + // stack to seed from a seed_seq, on a display task that has 3.2 KB in + // total. A dice roll does not need that much generator. + class Rng { + public: + using result_type = uint32_t; + + static constexpr result_type min() { + return 1; + } + + static constexpr result_type max() { + return UINT32_MAX; + } + + void Seed(result_type value) { + // Zero is the one state xorshift cannot leave again. + state = (value != 0) ? value : 0x9e3779b9; + } + + result_type operator()() { + state ^= state << 13; + state ^= state >> 17; + state ^= state << 5; + return state; + } + + private: + result_type state = 0x9e3779b9; + }; + + Rng gen; std::array resultColors = {LV_COLOR_YELLOW, LV_COLOR_MAGENTA, LV_COLOR_AQUA}; uint8_t currentColorIndex;