diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/vphysics_sound.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/shared/vphysics_sound.h')
| -rw-r--r-- | game/shared/vphysics_sound.h | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/game/shared/vphysics_sound.h b/game/shared/vphysics_sound.h new file mode 100644 index 0000000..591a0db --- /dev/null +++ b/game/shared/vphysics_sound.h @@ -0,0 +1,177 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef VPHYSICS_SOUND_H +#define VPHYSICS_SOUND_H +#ifdef _WIN32 +#pragma once +#endif + +#include "SoundEmitterSystem/isoundemittersystembase.h" + +namespace physicssound +{ + struct impactsound_t + { + void *pGameData; + int entityIndex; + int soundChannel; + float volume; + float impactSpeed; + unsigned short surfaceProps; + unsigned short surfacePropsHit; + Vector origin; + }; + + // UNDONE: Use a sorted container and sort by volume/distance? + struct soundlist_t + { + CUtlVector<impactsound_t> elements; + impactsound_t &GetElement(int index) { return elements[index]; } + impactsound_t &AddElement() { return elements[elements.AddToTail()]; } + int Count() { return elements.Count(); } + void RemoveAll() { elements.RemoveAll(); } + }; + + void PlayImpactSounds( soundlist_t &list ) + { + for ( int i = list.Count()-1; i >= 0; --i ) + { + impactsound_t &sound = list.GetElement(i); + const surfacedata_t *psurf = physprops->GetSurfaceData( sound.surfaceProps ); + if ( psurf->sounds.impactHard ) + { + const surfacedata_t *pHit = physprops->GetSurfaceData( sound.surfacePropsHit ); + unsigned short soundName = psurf->sounds.impactHard; + if ( pHit && psurf->sounds.impactSoft ) + { + if ( pHit->audio.hardnessFactor < psurf->audio.hardThreshold || + (psurf->audio.hardVelocityThreshold > 0 && psurf->audio.hardVelocityThreshold > sound.impactSpeed) ) + { + soundName = psurf->sounds.impactSoft; + } + } + const char *pSound = physprops->GetString( soundName ); + + CSoundParameters params; + if ( !CBaseEntity::GetParametersForSound( pSound, params, NULL ) ) + break; + + if ( sound.volume > 1 ) + sound.volume = 1; + CPASAttenuationFilter filter( sound.origin, params.soundlevel ); + // JAY: If this entity gets deleted, the sound comes out at the world origin + // this sounds bad! Play on ent 0 for now. + EmitSound_t ep; + ep.m_nChannel = sound.soundChannel; + ep.m_pSoundName = params.soundname; + ep.m_flVolume = params.volume * sound.volume; + ep.m_SoundLevel = params.soundlevel; + ep.m_nPitch = params.pitch; + ep.m_pOrigin = &sound.origin; + + CBaseEntity::EmitSound( filter, 0 /*sound.entityIndex*/, ep ); + } + } + list.RemoveAll(); + } + void AddImpactSound( soundlist_t &list, void *pGameData, int entityIndex, int soundChannel, IPhysicsObject *pObject, int surfaceProps, int surfacePropsHit, float volume, float impactSpeed ) + { + impactSpeed += 1e-4; + for ( int i = list.Count()-1; i >= 0; --i ) + { + impactsound_t &sound = list.GetElement(i); + // UNDONE: Compare entity or channel somehow? + // UNDONE: Doing one slot per entity is too noisy. So now we use one slot per material + + // heuristic - after 4 impacts sounds in one frame, start merging everything + if ( surfaceProps == sound.surfaceProps || list.Count() > 4 ) + { + // UNDONE: Store instance volume separate from aggregate volume and compare that? + if ( volume > sound.volume ) + { + pObject->GetPosition( &sound.origin, NULL ); + sound.pGameData = pGameData; + sound.entityIndex = entityIndex; + sound.soundChannel = soundChannel; + sound.surfacePropsHit = surfacePropsHit; + } + sound.volume += volume; + sound.impactSpeed = MAX(impactSpeed,sound.impactSpeed); + return; + } + } + + impactsound_t &sound = list.AddElement(); + sound.pGameData = pGameData; + sound.entityIndex = entityIndex; + sound.soundChannel = soundChannel; + pObject->GetPosition( &sound.origin, NULL ); + sound.surfaceProps = surfaceProps; + sound.surfacePropsHit = surfacePropsHit; + sound.volume = volume; + sound.impactSpeed = impactSpeed; + } + + struct breaksound_t + { + Vector origin; + int surfacePropsBreak; + }; + + void AddBreakSound( CUtlVector<breaksound_t> &list, const Vector &origin, unsigned short surfaceProps ) + { + const surfacedata_t *psurf = physprops->GetSurfaceData( surfaceProps ); + if ( !psurf->sounds.breakSound ) + return; + + for ( int i = list.Count()-1; i >= 0; --i ) + { + breaksound_t &sound = list.Element(i); + // Allow 3 break sounds before you start merging anything. + if ( list.Count() > 2 && surfaceProps == sound.surfacePropsBreak ) + { + sound.origin = (sound.origin + origin) * 0.5f; + return; + } + } + breaksound_t sound; + sound.origin = origin; + sound.surfacePropsBreak = surfaceProps; + list.AddToTail(sound); + + } + + void PlayBreakSounds( CUtlVector<breaksound_t> &list ) + { + for ( int i = list.Count()-1; i >= 0; --i ) + { + breaksound_t &sound = list.Element(i); + + const surfacedata_t *psurf = physprops->GetSurfaceData( sound.surfacePropsBreak ); + const char *pSound = physprops->GetString( psurf->sounds.breakSound ); + CSoundParameters params; + if ( !CBaseEntity::GetParametersForSound( pSound, params, NULL ) ) + return; + + // Play from the world, because the entity is breaking, so it'll be destroyed soon + CPASAttenuationFilter filter( sound.origin, params.soundlevel ); + EmitSound_t ep; + ep.m_nChannel = CHAN_STATIC; + ep.m_pSoundName = params.soundname; + ep.m_flVolume = params.volume; + ep.m_SoundLevel = params.soundlevel; + ep.m_nPitch = params.pitch; + ep.m_pOrigin = &sound.origin; + CBaseEntity::EmitSound( filter, 0 /*sound.entityIndex*/, ep ); + } + list.RemoveAll(); + } +}; + + +#endif // VPHYSICS_SOUND_H |