//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #ifndef SOUNDINFO_H #define SOUNDINFO_H #ifdef _WIN32 #pragma once #endif #include "bitbuf.h" #include "const.h" #include "soundflags.h" #include "coordsize.h" #include "mathlib/vector.h" #include "netmessages.h" #define WRITE_DELTA_UINT( name, length ) \ if ( name == delta->name ) \ buffer.WriteOneBit(0); \ else \ { \ buffer.WriteOneBit(1); \ buffer.WriteUBitLong( name, length ); \ } #define READ_DELTA_UINT( name, length ) \ if ( buffer.ReadOneBit() != 0 ) \ { name = buffer.ReadUBitLong( length ); }\ else { name = delta->name; } #define WRITE_DELTA_SINT( name, length ) \ if ( name == delta->name ) \ buffer.WriteOneBit(0); \ else \ { \ buffer.WriteOneBit(1); \ buffer.WriteSBitLong( name, length ); \ } #define WRITE_DELTA_SINT_SCALE( name, scale, length ) \ if ( name == delta->name ) \ buffer.WriteOneBit(0); \ else \ { \ buffer.WriteOneBit(1); \ buffer.WriteSBitLong( name / scale, length ); \ } #define READ_DELTA_SINT( name, length ) \ if ( buffer.ReadOneBit() != 0 ) \ { name = buffer.ReadSBitLong( length ); } \ else { name = delta->name; } #define READ_DELTA_SINT_SCALE( name, scale, length ) \ if ( buffer.ReadOneBit() != 0 ) \ { name = scale * buffer.ReadSBitLong( length ); } \ else { name = delta->name; } #define SOUND_SEQNUMBER_BITS 10 #define SOUND_SEQNUMBER_MASK ( (1<_name != _name ) pSoundData->set_ ## _protobufname( _name ); #define WRITE_DELTA_FIELD_SCALED( _name, _protobufname, _scaled_val ) \ if( delta->_name != _name ) pSoundData->set_ ## _protobufname( _scaled_val ); SoundInfo_t defaultSound( SOUNDINFO_NO_SETDEFAULT ); CSVCMsg_Sounds::sounddata_t *pSoundData = Msg.add_sounds(); if( !delta ) { defaultSound.SetDefault(); delta = &defaultSound; } WRITE_DELTA_FIELD( nEntityIndex, entity_index ); WRITE_DELTA_FIELD( nFlags, flags ); // Scriptable sounds are written as a hash, uses full 32 bits if( nFlags & SND_IS_SCRIPTHANDLE ) { WRITE_DELTA_FIELD( nSoundNum, sound_num_handle ); } else { WRITE_DELTA_FIELD( nSoundNum, sound_num ); } WRITE_DELTA_FIELD( nChannel, channel ); WRITE_DELTA_FIELD( bIsAmbient, is_ambient ); WRITE_DELTA_FIELD( bIsSentence, is_sentence ); // NOTE: SND_STOP behavior is different depending on this flag if ( nFlags != SND_STOP ) { WRITE_DELTA_FIELD_SCALED( nSequenceNumber, sequence_number, ( nSequenceNumber & SOUND_SEQNUMBER_MASK ) ) WRITE_DELTA_FIELD_SCALED( fVolume, volume, ( int )( fVolume * 127.0f ) ); WRITE_DELTA_FIELD( Soundlevel, sound_level ); WRITE_DELTA_FIELD( nPitch, pitch ); WRITE_DELTA_FIELD( nRandomSeed, random_seed ); float delayValue = fDelay; if ( ( nFlags & SND_DELAY ) && ( fTickTime != finalTickTime ) ) { delayValue += fTickTime - finalTickTime; } if ( delayValue != delta->fDelay ) { pSoundData->set_delay_value( delayValue ); } // don't transmit sounds with high precision WRITE_DELTA_FIELD_SCALED( vOrigin.x, origin_x, ( int )( vOrigin.x * ( 1.0f / 8.0f ) ) ); WRITE_DELTA_FIELD_SCALED( vOrigin.y, origin_y, ( int )( vOrigin.y * ( 1.0f / 8.0f ) ) ); WRITE_DELTA_FIELD_SCALED( vOrigin.z, origin_z, ( int )( vOrigin.z * ( 1.0f / 8.0f ) ) ); WRITE_DELTA_FIELD( nSpeakerEntity, speaker_entity ); } else { ClearStopFields(); } #undef WRITE_DELTA_FIELD #undef WRITE_DELTA_FIELD_SCALED }; void ReadDelta( const SoundInfo_t *delta, const CSVCMsg_Sounds::sounddata_t& SoundData) { #define READ_DELTA_FIELD( _name, _protobufname ) \ _name = ( SoundData.has_ ## _protobufname() ) ? SoundData._protobufname() : delta->_name; #define READ_DELTA_FIELD_SCALED( _name, _protobufname, _scale ) \ _name = ( SoundData.has_ ## _protobufname() ) ? ( SoundData._protobufname() * ( _scale ) ) : delta->_name; READ_DELTA_FIELD( nEntityIndex, entity_index ); READ_DELTA_FIELD( nFlags, flags ); // Scriptable sounds are written as a hash, uses full 32 bits if( nFlags & SND_IS_SCRIPTHANDLE ) { READ_DELTA_FIELD( nSoundNum, sound_num_handle ); } else { READ_DELTA_FIELD( nSoundNum, sound_num ); } READ_DELTA_FIELD( nChannel, channel ); READ_DELTA_FIELD( bIsAmbient, is_ambient ); READ_DELTA_FIELD( bIsSentence, is_sentence ); // NOTE: SND_STOP behavior is different depending on this flag if ( nFlags != SND_STOP ) { READ_DELTA_FIELD( nSequenceNumber, sequence_number ); READ_DELTA_FIELD_SCALED( fVolume, volume, ( 1.0f / 127.0f ) ); Soundlevel = ( soundlevel_t )( SoundData.has_sound_level() ? SoundData.sound_level() : delta->Soundlevel ); READ_DELTA_FIELD( nPitch, pitch ); READ_DELTA_FIELD( nRandomSeed, random_seed ); READ_DELTA_FIELD( fDelay, delay_value ); READ_DELTA_FIELD_SCALED( vOrigin.x, origin_x, 8.0f ); READ_DELTA_FIELD_SCALED( vOrigin.y, origin_y, 8.0f ); READ_DELTA_FIELD_SCALED( vOrigin.z, origin_z, 8.0f ); READ_DELTA_FIELD( nSpeakerEntity, speaker_entity ); } else { ClearStopFields(); } #undef READ_DELTA_FIELD #undef READ_DELTA_FIELD_SCALED } }; struct SpatializationInfo_t { typedef enum { SI_INCREATION = 0, SI_INSPATIALIZATION } SPATIALIZATIONTYPE; // Inputs SPATIALIZATIONTYPE type; // Info about the sound, channel, origin, direction, etc. SoundInfo_t info; // Requested Outputs ( NULL == not requested ) Vector *pOrigin; QAngle *pAngles; float *pflRadius; CUtlVector< Vector > *m_pUtlVecMultiOrigins; CUtlVector< QAngle > *m_pUtlVecMultiAngles; }; #pragma pack() #endif // SOUNDINFO_H