From ef098db7c8aeded7d557512e89090ce8093780f1 Mon Sep 17 00:00:00 2001 From: Stan Date: Thu, 25 Apr 2019 22:37:15 +0000 Subject: [PATCH] Seed unit sounds so that their pitch and their gain are always the same for the same unit. Fixes #3578 Reviewed by: @vladislavbelov Differential Revision: https://code.wildfiregames.com/D1584 This was SVN commit r22231. --- source/soundmanager/scripting/SoundGroup.cpp | 28 ++++++++++++++------ source/soundmanager/scripting/SoundGroup.h | 7 ++++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/source/soundmanager/scripting/SoundGroup.cpp b/source/soundmanager/scripting/SoundGroup.cpp index 895990ef91..c0a7f20b2a 100644 --- a/source/soundmanager/scripting/SoundGroup.cpp +++ b/source/soundmanager/scripting/SoundGroup.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,12 +21,14 @@ #include "graphics/Camera.h" #include "graphics/GameView.h" #include "lib/rand.h" -#include "ps/Game.h" #include "ps/CLogger.h" #include "ps/CStr.h" #include "ps/Filesystem.h" +#include "ps/Game.h" #include "ps/Util.h" #include "ps/XML/Xeromyces.h" +#include "simulation2/components/ICmpVisual.h" +#include "simulation2/system/Component.h" #include "soundmanager/items/ISoundItem.h" #include "soundmanager/SoundManager.h" @@ -35,9 +37,17 @@ extern CGame *g_Game; #if CONFIG2_AUDIO -static float RandFloat(float min, float max) +inline u32 CSoundGroup::FastRand() { - return rand(min * 100.f, max * 100.f) / 100.f; + // This is a mixed linear congruential random number generator. + // The magic numbers are chosen so that they generate pseudo random numbers over a big enough period (0xFFFF). + m_Seed = 214013 * m_Seed + 2531011; + return (m_Seed >> 16) & 0xFFFF; +} + +float CSoundGroup::RandFloat(float min, float max) +{ + return (static_cast(FastRand()) / (0xFFFF)) * (max - min) + min; } #endif @@ -62,6 +72,7 @@ void CSoundGroup::SetDefaultValues() m_ConeInnerAngle = 360.f; m_ConeOuterAngle = 360.f; m_Decay = 3.f; + m_Seed = 0; m_IntensityThreshold = 3.f; } @@ -179,10 +190,11 @@ void CSoundGroup::UploadPropertiesAndPlay(size_t index, const CVector3D& positio hSound->SetRollOff(itemRollOff); } - if (TestFlag(eRandPitch)) - hSound->SetPitch(RandFloat(m_PitchLower, m_PitchUpper)); - else - hSound->SetPitch(m_Pitch); + CmpPtr cmpVisual(*g_Game->GetSimulation2(), source); + if (cmpVisual) + m_Seed = cmpVisual->GetActorSeed(); + + hSound->SetPitch(TestFlag(eRandPitch) ? RandFloat(m_PitchLower, m_PitchUpper) : m_Pitch); if (TestFlag(eRandGain)) m_Gain = RandFloat(m_GainLower, m_GainUpper); diff --git a/source/soundmanager/scripting/SoundGroup.h b/source/soundmanager/scripting/SoundGroup.h index d60bc6ecbb..e04a1fc741 100644 --- a/source/soundmanager/scripting/SoundGroup.h +++ b/source/soundmanager/scripting/SoundGroup.h @@ -20,6 +20,7 @@ #include "lib/config2.h" #include "lib/file/vfs/vfs_path.h" +#include "lib/types.h" #include "simulation2/system/Entity.h" #include "soundmanager/data/SoundData.h" @@ -80,6 +81,10 @@ private: void SetDefaultValues(); #if CONFIG2_AUDIO + inline u32 FastRand(); + // Contains the current sound seed for the generator + u32 m_Seed; + float RandFloat(float min, float max); // We store the handles so we can load now and play later std::vector m_SoundGroups; #endif @@ -104,7 +109,7 @@ private: float m_PitchUpper; float m_Priority; // Up to eight individual parameters, use with eSndGrpFlags. - uint8_t m_Flags; + u8 m_Flags; }; #endif //#ifndef INCLUDED_SOUNDGROUP_H