Skip to content

Commit

Permalink
Refactor PlayedSounds class to support different types of sounds
Browse files Browse the repository at this point in the history
  • Loading branch information
danielkrupinski committed Oct 30, 2023
1 parent 49d7a61 commit b12119a
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 47 deletions.
84 changes: 59 additions & 25 deletions Source/FeatureHelpers/PlayedSounds.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,59 @@
#include <MemoryPatterns/FileSystemPatterns.h>
#include <MemoryPatterns/SoundSystemPatterns.h>
#include "PlayedSound.h"
#include "Sound/WatchedSounds.h"
#include "Sound/WatchedSoundType.h"
#include <Utils/BitFlags.h>
#include <Utils/DynamicArray.h>

class PlayedSounds {
public:
void removeExpiredSounds(float curtime, float lifetime) noexcept
static constexpr auto kFootstepLifespan = 2.0f;

template <WatchedSoundType soundType>
void startWatching() noexcept
{
assert(!watchedSounds.has<soundType>());
watchedSounds.set<soundType>();
}

template <WatchedSoundType soundType>
void stopWatching() noexcept
{
for (std::size_t i = 0; i < sounds.getSize();) {
auto& sound = sounds[i];
if (!sound.isAlive(curtime, lifetime))
removeSound(sound);
else
++i;
assert(watchedSounds.has<soundType>());
watchedSounds.unset<soundType>();
}

void update(float curtime) noexcept
{
if (watchedSounds.has<WatchedSoundType::Footsteps>()) {
getSounds<WatchedSoundType::Footsteps>().removeExpiredSounds(curtime, kFootstepLifespan);
collectSounds(curtime);
}
}

template <typename Predicate>
void collectSounds(float curtime, Predicate&& predicate) noexcept
template <typename F>
void forEach(F&& f) const noexcept
{
footsteps.forEach(std::forward<F>(f));
}

private:
template <WatchedSoundType soundType>
[[nodiscard]] WatchedSounds& getSounds() noexcept
{
if constexpr (soundType == WatchedSoundType::Footsteps) {
return footsteps;
} else {
static_assert(soundType != soundType, "Unknown sound type!");
}
}

void collectSounds(float curtime) noexcept
{
if (!watchedSounds)
return;

if (!soundChannels || !*soundChannels)
return;

Expand All @@ -51,30 +86,29 @@ class PlayedSounds {
fileNames.getString(channel.sfx->fileNameHandle, buffer);
buffer.back() = '\0';

if (!predicate(std::string_view{buffer.data()}))
continue;
if (watchedSounds.has<WatchedSoundType::Footsteps>()) {
if (!isFootstepSound(std::string_view{buffer.data()}))
continue;

if (std::ranges::find(sounds, channel.guid, &PlayedSound::guid) != sounds.end())
continue;
if (footsteps.hasSound(channel.guid))
continue;

sounds.pushBack(PlayedSound{ .guid = channel.guid, .spawnTime = curtime, .origin = channelInfo2.memory[i].origin });
footsteps.addSound(PlayedSound{ .guid = channel.guid, .spawnTime = curtime, .origin = channelInfo2.memory[i].origin });
}
}
}

template <typename F>
void forEach(F&& f) const noexcept
{
std::ranges::for_each(sounds, std::forward<F>(f));
}

private:
void removeSound(PlayedSound& sound) noexcept
[[nodiscard]] static bool isFootstepSound(std::string_view soundName) noexcept
{
sound = sounds.back();
sounds.popBack();
if (soundName.starts_with(cs2::kPlayerFootstepSoundsPath)) {
return !std::string_view{ soundName.data() + cs2::kPlayerFootstepSoundsPath.length(), soundName.length() - cs2::kPlayerFootstepSoundsPath.length() }.starts_with(cs2::kPlayerSuitSoundPrefix);
}
return false;
}

cs2::SoundChannels** soundChannels{ SoundSystemPatterns::soundChannels() };
cs2::CBaseFileSystem** fileSystem{ FileSystemPatterns::fileSystem() };
DynamicArray<PlayedSound> sounds;

BitFlags<WatchedSoundType, std::uint8_t> watchedSounds;
WatchedSounds footsteps;
};
5 changes: 5 additions & 0 deletions Source/FeatureHelpers/Sound/WatchedSoundType.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

enum class WatchedSoundType {
Footsteps
};
45 changes: 45 additions & 0 deletions Source/FeatureHelpers/Sound/WatchedSounds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include <algorithm>

#include <FeatureHelpers/PlayedSound.h>
#include <Utils/DynamicArray.h>

class WatchedSounds {
public:
bool addSound(const PlayedSound& sound) noexcept
{
return sounds.pushBack(sound);
}

[[nodiscard]] bool hasSound(int guid) noexcept
{
return std::ranges::find(sounds, guid, &PlayedSound::guid) != sounds.end();
}

void removeExpiredSounds(float curtime, float lifespan) noexcept
{
for (std::size_t i = 0; i < sounds.getSize();) {
auto& sound = sounds[i];
if (!sound.isAlive(curtime, lifespan))
removeSound(sound);
else
++i;
}
}

template <typename F>
void forEach(F&& f) const noexcept
{
std::ranges::for_each(sounds, std::forward<F>(f));
}

private:
void removeSound(PlayedSound& sound) noexcept
{
sound = sounds.back();
sounds.popBack();
}

DynamicArray<PlayedSound> sounds;
};
29 changes: 7 additions & 22 deletions Source/Features/Sound/FootstepVisualizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ class FootstepVisualizer : public TogglableFeature<FootstepVisualizer> {
return;

createFootstepPanels();
removeOldFootsteps(*globalVarsProvider.getGlobalVars());
collectFootsteps(*globalVarsProvider.getGlobalVars());
footsteps.update(globalVarsProvider.getGlobalVars()->curtime);

std::size_t currentIndex = 0;
footsteps.forEach([this, &currentIndex] (const PlayedSound& sound) {
Expand All @@ -60,8 +59,8 @@ class FootstepVisualizer : public TogglableFeature<FootstepVisualizer> {
return;

const auto timeAlive = sound.getTimeAlive(globalVarsProvider.getGlobalVars()->curtime);
if (timeAlive >= kFootstepLifespan - kFootstepFadeAwayDuration) {
style.setOpacity((kFootstepLifespan - timeAlive) / kFootstepFadeAwayDuration);
if (timeAlive >= PlayedSounds::kFootstepLifespan - kFootstepFadeAwayDuration) {
style.setOpacity((PlayedSounds::kFootstepLifespan - timeAlive) / kFootstepFadeAwayDuration);
} else {
style.setOpacity(1.0f);
}
Expand Down Expand Up @@ -90,14 +89,16 @@ class FootstepVisualizer : public TogglableFeature<FootstepVisualizer> {
private:
friend TogglableFeature;

void onEnable() const noexcept
void onEnable() noexcept
{
viewRenderHook.incrementReferenceCount();
footsteps.startWatching<WatchedSoundType::Footsteps>();
}

void onDisable() const noexcept
void onDisable() noexcept
{
viewRenderHook.decrementReferenceCount();
footsteps.stopWatching<WatchedSoundType::Footsteps>();
hidePanels(0);
}

Expand Down Expand Up @@ -134,21 +135,6 @@ var footstepPanel = $.CreatePanel('Panel', $.GetContextPanel().FindChildInLayout
}
}

void removeOldFootsteps(const cs2::GlobalVars& globalVars) noexcept
{
footsteps.removeExpiredSounds(globalVars.curtime, kFootstepLifespan);
}

void collectFootsteps(const cs2::GlobalVars& globalVars) noexcept
{
footsteps.collectSounds(globalVars.curtime, [](std::string_view soundName) {
if (soundName.starts_with(cs2::kPlayerFootstepSoundsPath)) {
return !std::string_view{ soundName.data() + cs2::kPlayerFootstepSoundsPath.length(), soundName.length() - cs2::kPlayerFootstepSoundsPath.length() }.starts_with(cs2::kPlayerSuitSoundPrefix);
}
return false;
});
}

[[nodiscard]] PanoramaUiPanel getFootstepPanel(std::size_t index) const noexcept
{
const auto footstepContainerPanel = footstepContainerPanelPointer.get();
Expand Down Expand Up @@ -184,6 +170,5 @@ var footstepPanel = $.CreatePanel('Panel', $.GetContextPanel().FindChildInLayout
PlayedSounds footsteps;

static constexpr auto kMaxNumberOfFootstepsToDraw = 100;
static constexpr auto kFootstepLifespan = 2.0f;
static constexpr auto kFootstepFadeAwayDuration = 0.4f;
};
2 changes: 2 additions & 0 deletions Source/Osiris.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
<ClInclude Include="FeatureHelpers\NormalizedDeviceCoordinates.h" />
<ClInclude Include="FeatureHelpers\PlayedSound.h" />
<ClInclude Include="FeatureHelpers\PlayedSounds.h" />
<ClInclude Include="FeatureHelpers\Sound\WatchedSounds.h" />
<ClInclude Include="FeatureHelpers\Sound\WatchedSoundType.h" />
<ClInclude Include="FeatureHelpers\TogglableFeature.h" />
<ClInclude Include="FeatureHelpers\WorldToClipSpaceConverter.h" />
<ClInclude Include="Features\Features.h" />
Expand Down
9 changes: 9 additions & 0 deletions Source/Osiris.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@
<Filter Include="Features\Sound">
<UniqueIdentifier>{432df53f-506f-470e-af2c-7155e3d4f03c}</UniqueIdentifier>
</Filter>
<Filter Include="FeatureHelpers\Sound">
<UniqueIdentifier>{19a86d00-8a7b-4184-9119-96ec0b26c501}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CS2\Classes\C_CSGameRules.h">
Expand Down Expand Up @@ -627,6 +630,12 @@
<ClInclude Include="Utils\BitFlags.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="FeatureHelpers\Sound\WatchedSounds.h">
<Filter>FeatureHelpers\Sound</Filter>
</ClInclude>
<ClInclude Include="FeatureHelpers\Sound\WatchedSoundType.h">
<Filter>FeatureHelpers\Sound</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="UI\Panorama\CreateGUI.js">
Expand Down

0 comments on commit b12119a

Please sign in to comment.