diff --git a/src/include/sound.h b/src/include/sound.h index 26c09a8002..940b76e3af 100644 --- a/src/include/sound.h +++ b/src/include/sound.h @@ -54,7 +54,6 @@ class LuaActionListener; ----------------------------------------------------------------------------*/ #define MaxSampleVolume 255 /// Maximum sample volume -#define NO_SOUND 0 /// No valid sound ID /** ** Voice groups for a unit @@ -163,8 +162,17 @@ extern int DistanceSilent; -- Functions ----------------------------------------------------------------------------*/ -/// Calculates volume level -extern unsigned char CalculateVolume(bool isVolume, int power, unsigned char range); +/** +** Compute a suitable volume for something taking place at a given +** distance from the current view point. +** +** @param d distance +** @param range range +** +** @return volume for given distance (0..??) +*/ +unsigned char VolumeForDistance(unsigned short d, unsigned char range); + /// Play a unit sound extern void PlayUnitSound(const CUnit &, EUnitVoice, bool sampleUnique = false); /// Play a unit sound @@ -177,9 +185,6 @@ extern void PlayGameSound(CSound *sound, unsigned char volume, bool always = fal /// Play a sound file extern int PlayFile(const std::string &name, LuaActionListener *listener = nullptr); -/// Modify the range of a given sound. -extern void SetSoundRange(CSound *sound, unsigned char range); - /// Register a sound (can be a simple sound or a group) extern CSound *RegisterSound(const std::vector &files); @@ -209,7 +214,7 @@ extern void CallbackMusicTrigger(); /// Map sound to identifier extern void MapSound(const std::string &sound_name, CSound *id); /// Get the sound id bound to an identifier -extern CSound *SoundForName(const std::string &sound_name); +extern CSound *SoundForName(const std::string_view &sound_name); /// Make a sound bound to identifier extern CSound *MakeSound(const std::string &sound_name, const std::vector &files); /// Make a sound group bound to identifier diff --git a/src/include/sound_server.h b/src/include/sound_server.h index 39c8665963..64088a3843 100644 --- a/src/include/sound_server.h +++ b/src/include/sound_server.h @@ -43,7 +43,6 @@ -- Definitons ----------------------------------------------------------------------------*/ -#define MaxVolume 255 #define SOUND_BUFFER_SIZE 65536 /*---------------------------------------------------------------------------- diff --git a/src/sound/script_sound.cpp b/src/sound/script_sound.cpp index 264bf96226..c26a32b992 100644 --- a/src/sound/script_sound.cpp +++ b/src/sound/script_sound.cpp @@ -76,16 +76,13 @@ static int CclSoundForName(lua_State *l) */ static CSound *CclGetSound(lua_State *l) { - LuaUserData *data; - int pop; - - pop = 0; + bool pop = false; if (lua_isstring(l, -1)) { CclSoundForName(l); - pop = 1; + pop = true; } if (lua_isuserdata(l, -1)) { - data = (LuaUserData *)lua_touserdata(l, -1); + LuaUserData *data = (LuaUserData *)lua_touserdata(l, -1); if (data->Type == LuaSoundType) { if (pop) { lua_pop(l, 1); @@ -114,7 +111,7 @@ static int CclMakeSound(lua_State *l) std::string c_name = std::string{LuaToString(l, 1)}; std::vector files; - CSound *id; + CSound *id = nullptr; if (lua_isstring(l, 2)) { // only one file files.push_back(std::string{LuaToString(l, 2)}); @@ -147,22 +144,16 @@ static int CclMakeSound(lua_State *l) */ static int CclMakeSoundGroup(lua_State *l) { - CSound *id; - std::string c_name; - CSound *first; - CSound *second; - LuaUserData *data; - LuaCheckArgs(l, 3); - c_name = LuaToString(l, 1); + std::string c_name{LuaToString(l, 1)}; lua_pushvalue(l, 2); - first = CclGetSound(l); + CSound *first = CclGetSound(l); lua_pop(l, 1); - second = CclGetSound(l); - id = MakeSoundGroup(c_name, first, second); - data = (LuaUserData *)lua_newuserdata(l, sizeof(LuaUserData)); + CSound *second = CclGetSound(l); + CSound *id = MakeSoundGroup(c_name, first, second); + LuaUserData *data = (LuaUserData *)lua_newuserdata(l, sizeof(LuaUserData)); data->Type = LuaSoundType; data->Data = id; return 1; @@ -206,10 +197,7 @@ static int CclPlaySound(lua_State *l) lua_pushvalue(l, 1); CSound *id = CclGetSound(l); lua_pop(l, 1); - bool always = false; - if (args == 2) { - always = LuaToBoolean(l, 2); - } + const bool always = args == 2 && LuaToBoolean(l, 2); PlayGameSound(id, MaxSampleVolume, always); return 0; } @@ -339,17 +327,17 @@ static int CclSetGlobalSoundRange(lua_State *l) */ static int CclSetSoundRange(lua_State *l) { - LuaCheckArgs(l, 2); - int tmp = LuaToNumber(l, 2); - clamp(&tmp, 0, 255); - const unsigned char theRange = static_cast(tmp); + int range = LuaToNumber(l, 2); + clamp(&range, 0, 255); + const unsigned char theRange = static_cast(range); lua_pushvalue(l, 1); - CSound *id = CclGetSound(l); - SetSoundRange(id, theRange); - return 1; + if (CSound* id = CclGetSound(l)) { + id->Range = theRange; + } + return 0; } /** diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp index cf7d770dce..98c2463010 100644 --- a/src/sound/sound.cpp +++ b/src/sound/sound.cpp @@ -51,6 +51,8 @@ -- Variables ----------------------------------------------------------------------------*/ +static constexpr unsigned char MaxVolume = 255; + /** ** Various sounds used in game. */ @@ -65,9 +67,6 @@ struct SelectionHandling { unsigned char HowMany; /// number of sound played in this group }; -/// FIXME: docu -SelectionHandling SelectionHandler; - static int ViewPointOffset; /// Distance to Volume Mapping int DistanceSilent; /// silent distance @@ -92,23 +91,24 @@ static Mix_Chunk *SimpleChooseSample(const CSound &sound) /** ** Choose the sample to play */ -static Mix_Chunk *ChooseSample(CSound *sound, bool selection, Origin &source) +static Mix_Chunk *ChooseSample(CSound &sound, bool selection, Origin &source) { - Mix_Chunk *result = nullptr; - - if (!sound || !SoundEnabled()) { + if (!SoundEnabled()) { return nullptr; } - if (sound->Number == TWO_GROUPS) { + Mix_Chunk *result = nullptr; + static SelectionHandling SelectionHandler{}; + + if (sound.Number == TWO_GROUPS) { // handle a special sound (selection) if (SelectionHandler.Sound != nullptr && (SelectionHandler.Source.Base == source.Base && SelectionHandler.Source.Id == source.Id)) { - if (SelectionHandler.Sound == sound->Sound.TwoGroups.First) { + if (SelectionHandler.Sound == sound.Sound.TwoGroups.First) { result = SimpleChooseSample(*SelectionHandler.Sound); SelectionHandler.HowMany++; if (SelectionHandler.HowMany >= 3) { SelectionHandler.HowMany = 0; - SelectionHandler.Sound = sound->Sound.TwoGroups.Second; + SelectionHandler.Sound = sound.Sound.TwoGroups.Second; } } else { //FIXME: checks for error @@ -118,23 +118,23 @@ static Mix_Chunk *ChooseSample(CSound *sound, bool selection, Origin &source) SelectionHandler.HowMany++; if (SelectionHandler.HowMany >= SelectionHandler.Sound->Number) { SelectionHandler.HowMany = 0; - SelectionHandler.Sound = sound->Sound.TwoGroups.First; + SelectionHandler.Sound = sound.Sound.TwoGroups.First; } } else { result = SelectionHandler.Sound->Sound.OneSound; SelectionHandler.HowMany = 0; - SelectionHandler.Sound = sound->Sound.TwoGroups.First; + SelectionHandler.Sound = sound.Sound.TwoGroups.First; } } } else { SelectionHandler.Source = source; - SelectionHandler.Sound = sound->Sound.TwoGroups.First; + SelectionHandler.Sound = sound.Sound.TwoGroups.First; result = SimpleChooseSample(*SelectionHandler.Sound); SelectionHandler.HowMany = 1; } } else { // normal sound/sound group handling - result = SimpleChooseSample(*sound); + result = SimpleChooseSample(sound); if (SelectionHandler.Source.Base == source.Base && SelectionHandler.Source.Id == source.Id) { SelectionHandler.HowMany = 0; SelectionHandler.Sound = nullptr; @@ -225,20 +225,6 @@ unsigned char VolumeForDistance(unsigned short d, unsigned char range) } } -/** -** Calculate the volume associated with a request, either by clipping the -** range parameter of this request, or by mapping this range to a volume. -*/ -unsigned char CalculateVolume(bool isVolume, int power, unsigned char range) -{ - if (isVolume) { - return std::min(MaxVolume, power); - } else { - // map distance to volume - return VolumeForDistance(power, range); - } -} - /** ** Calculate the stereo value for a unit */ @@ -273,7 +259,7 @@ void PlayUnitSound(const CUnit &unit, EUnitVoice voice, bool sampleUnique) return; } - Mix_Chunk *sample = ChooseSample(sound, selection, source); + Mix_Chunk *sample = ChooseSample(*sound, selection, source); if (sampleUnique && SampleIsPlaying(sample)) { return; @@ -283,7 +269,7 @@ void PlayUnitSound(const CUnit &unit, EUnitVoice voice, bool sampleUnique) if (channel == -1) { return; } - SetChannelVolume(channel, CalculateVolume(false, ViewPointDistanceToUnit(unit), sound->Range)); + SetChannelVolume(channel, VolumeForDistance(ViewPointDistanceToUnit(unit), sound->Range)); SetChannelStereo(channel, CalculateStereo(unit)); #ifdef USE_MNG const CUnitType &type = *unit.Type; @@ -309,12 +295,12 @@ void PlayUnitSound(const CUnit &unit, CSound *sound) return; } Origin source = {&unit, unsigned(UnitNumber(unit))}; - unsigned char volume = CalculateVolume(false, ViewPointDistanceToUnit(unit), sound->Range); + const unsigned char volume = VolumeForDistance(ViewPointDistanceToUnit(unit), sound->Range); if (volume == 0) { return; } - int channel = PlaySample(ChooseSample(sound, false, source)); + int channel = PlaySample(ChooseSample(*sound, false, source)); if (channel == -1) { return; } @@ -339,12 +325,13 @@ void PlayMissileSound(const Missile &missile, CSound *sound) clamp(&stereo, -128, 127); Origin source = {nullptr, 0}; - unsigned char volume = CalculateVolume(false, ViewPointDistanceToMissile(missile), sound->Range); + const unsigned char volume = + VolumeForDistance(ViewPointDistanceToMissile(missile), sound->Range); if (volume == 0) { return; } - int channel = PlaySample(ChooseSample(sound, false, source)); + int channel = PlaySample(ChooseSample(*sound, false, source)); if (channel == -1) { return; } @@ -365,7 +352,7 @@ void PlayGameSound(CSound *sound, unsigned char volume, bool always) } Origin source = {nullptr, 0}; - Mix_Chunk *sample = ChooseSample(sound, false, source); + Mix_Chunk *sample = ChooseSample(*sound, false, source); if (!sample || (!always && SampleIsPlaying(sample))) { return; @@ -375,7 +362,7 @@ void PlayGameSound(CSound *sound, unsigned char volume, bool always) if (channel == -1) { return; } - SetChannelVolume(channel, CalculateVolume(true, volume, sound->Range)); + SetChannelVolume(channel, std::min(MaxVolume, volume)); } static std::map ChannelMap; @@ -425,19 +412,6 @@ int PlayFile(const std::string &name, LuaActionListener *listener) return channel; } -/** -** Ask the sound server to change the range of a sound. -** -** @param sound the id of the sound to modify. -** @param range the new range for this sound. -*/ -void SetSoundRange(CSound *sound, unsigned char range) -{ - if (sound != NO_SOUND) { - sound->Range = range; - } -} - /** ** Ask the sound server to register a sound (and currently to load it) ** and to return an unique identifier for it. The unique identifier is @@ -464,14 +438,14 @@ CSound *RegisterSound(const std::vector &files) if (!id->Sound.OneGroup[i]) { //delete[] id->Sound.OneGroup; delete id; - return NO_SOUND; + return nullptr; } } } else { // load a unique sound id->Sound.OneSound = LoadSample(files[0]); if (!id->Sound.OneSound) { delete id; - return NO_SOUND; + return nullptr; } id->Number = ONE_SOUND; } @@ -489,8 +463,8 @@ CSound *RegisterSound(const std::vector &files) */ CSound *RegisterTwoGroups(CSound *first, CSound *second) { - if (first == NO_SOUND || second == NO_SOUND) { - return NO_SOUND; + if (first == nullptr || second == nullptr) { + return nullptr; } CSound *id = new CSound; id->Number = TWO_GROUPS; diff --git a/src/sound/sound_id.cpp b/src/sound/sound_id.cpp index 8b74c8722e..46a4d2b9e2 100644 --- a/src/sound/sound_id.cpp +++ b/src/sound/sound_id.cpp @@ -46,13 +46,13 @@ -- Variables ----------------------------------------------------------------------------*/ -static std::map SoundMap; +static std::map> SoundMap; /*---------------------------------------------------------------------------- -- Functions ----------------------------------------------------------------------------*/ -static CSound *FindSound(const std::string &name) +static CSound *FindSound(const std::string_view &name) { std::map::iterator ret = SoundMap.find(name); if (ret != SoundMap.end()) { @@ -65,7 +65,7 @@ static CSound *FindSound(const std::string &name) ** Add a new mapping (sound name to sound id) in the hash table ** Create a new mapping between a name and an already valid sound id. ** -** @param name Name of the sound (now freed by caller!). +** @param name Name of the sound. ** @param id Sound identifier. */ void MapSound(const std::string &name, CSound *id) @@ -85,14 +85,14 @@ void MapSound(const std::string &name, CSound *id) ** ** @return Sound identifier for this name. */ -CSound *SoundForName(const std::string &name) +CSound *SoundForName(const std::string_view &name) { Assert(!name.empty()); CSound *sound = FindSound(name); if (sound) { return sound; } - DebugPrint("Can't find sound '%s' in sound table\n", name.c_str()); + DebugPrint("Can't find sound '%s' in sound table\n", name.data()); return nullptr; } @@ -118,7 +118,7 @@ CSound *MakeSound(const std::string &name, const std::vector &files } sound = RegisterSound(files); - if (sound != NO_SOUND) { + if (sound != nullptr) { MapSound(name, sound); } return sound; @@ -147,7 +147,7 @@ CSound *MakeSoundGroup(const std::string &name, CSound *first, CSound *second) } sound = RegisterTwoGroups(first, second); - if (sound != NO_SOUND) { + if (sound != nullptr) { MapSound(name, sound); } return sound; diff --git a/src/sound/unitsound.cpp b/src/sound/unitsound.cpp index 9729a57815..0cac23ed4a 100644 --- a/src/sound/unitsound.cpp +++ b/src/sound/unitsound.cpp @@ -70,7 +70,7 @@ bool SoundConfig::MapSound() void SoundConfig::SetSoundRange(unsigned char range) { if (this->Sound) { - ::SetSoundRange(this->Sound, range); + this->Sound->Range = range; } } diff --git a/src/spell/spells.cpp b/src/spell/spells.cpp index b55a2c4bf2..fa02f07632 100644 --- a/src/spell/spells.cpp +++ b/src/spell/spells.cpp @@ -508,7 +508,10 @@ int SpellCast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i if (spell.Target == ETarget::Self) { PlayUnitSound(caster, spell.SoundWhenCast.Sound); } else { - PlayGameSound(spell.SoundWhenCast.Sound, CalculateVolume(false, ViewPointDistance(target ? target->tilePos : goalPos), spell.SoundWhenCast.Sound->Range)); + PlayGameSound( + spell.SoundWhenCast.Sound, + VolumeForDistance(ViewPointDistance(target ? target->tilePos : goalPos), + spell.SoundWhenCast.Sound->Range)); } } for (auto& act : spell.Action) {