Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

325 lines
8.2 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifndef SOUNDINFO_H
  7. #define SOUNDINFO_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "bitbuf.h"
  12. #include "const.h"
  13. #include "soundflags.h"
  14. #include "coordsize.h"
  15. #include "mathlib/vector.h"
  16. #include "netmessages.h"
  17. #define WRITE_DELTA_UINT( name, length ) \
  18. if ( name == delta->name ) \
  19. buffer.WriteOneBit(0); \
  20. else \
  21. { \
  22. buffer.WriteOneBit(1); \
  23. buffer.WriteUBitLong( name, length ); \
  24. }
  25. #define READ_DELTA_UINT( name, length ) \
  26. if ( buffer.ReadOneBit() != 0 ) \
  27. { name = buffer.ReadUBitLong( length ); }\
  28. else { name = delta->name; }
  29. #define WRITE_DELTA_SINT( name, length ) \
  30. if ( name == delta->name ) \
  31. buffer.WriteOneBit(0); \
  32. else \
  33. { \
  34. buffer.WriteOneBit(1); \
  35. buffer.WriteSBitLong( name, length ); \
  36. }
  37. #define WRITE_DELTA_SINT_SCALE( name, scale, length ) \
  38. if ( name == delta->name ) \
  39. buffer.WriteOneBit(0); \
  40. else \
  41. { \
  42. buffer.WriteOneBit(1); \
  43. buffer.WriteSBitLong( name / scale, length ); \
  44. }
  45. #define READ_DELTA_SINT( name, length ) \
  46. if ( buffer.ReadOneBit() != 0 ) \
  47. { name = buffer.ReadSBitLong( length ); } \
  48. else { name = delta->name; }
  49. #define READ_DELTA_SINT_SCALE( name, scale, length ) \
  50. if ( buffer.ReadOneBit() != 0 ) \
  51. { name = scale * buffer.ReadSBitLong( length ); } \
  52. else { name = delta->name; }
  53. #define SOUND_SEQNUMBER_BITS 10
  54. #define SOUND_SEQNUMBER_MASK ( (1<<SOUND_SEQNUMBER_BITS) - 1 )
  55. // offset sound delay encoding by 60ms since we encode negative sound delays with less precision
  56. // This means any negative sound delay greater than -100ms will get encoded at full precision
  57. #define SOUND_DELAY_OFFSET (0.100f)
  58. #pragma pack(4)
  59. // the full float time for now.
  60. #define SEND_SOUND_TIME 1
  61. //-----------------------------------------------------------------------------
  62. struct SoundInfo_t
  63. {
  64. Vector vOrigin;
  65. Vector vDirection;
  66. Vector vListenerOrigin;
  67. const char *pszName; // UNDONE: Make this a FilenameHandle_t to avoid bugs with arrays of these
  68. float fVolume;
  69. float fDelay;
  70. float fTickTime; // delay is encoded relative to this tick, fix up if packet is delayed
  71. int nSequenceNumber;
  72. int nEntityIndex;
  73. int nChannel;
  74. int nPitch;
  75. int nFlags;
  76. unsigned int nSoundNum;
  77. int nSpeakerEntity;
  78. int nRandomSeed;
  79. soundlevel_t Soundlevel;
  80. bool bIsSentence;
  81. bool bIsAmbient;
  82. bool bLooping;
  83. //---------------------------------
  84. enum SoundInfoInit_t
  85. {
  86. SOUNDINFO_SETDEFAULT,
  87. SOUNDINFO_NO_SETDEFAULT,
  88. };
  89. SoundInfo_t( SoundInfoInit_t Init = SOUNDINFO_SETDEFAULT )
  90. {
  91. if( Init == SOUNDINFO_SETDEFAULT )
  92. {
  93. SetDefault();
  94. }
  95. }
  96. void Set(int newEntity, int newChannel, const char *pszNewName, const Vector &newOrigin, const Vector& newDirection,
  97. float newVolume, soundlevel_t newSoundLevel, bool newLooping, int newPitch, const Vector &vecListenerOrigin, int speakerentity, int nSeed )
  98. {
  99. nEntityIndex = newEntity;
  100. nChannel = newChannel;
  101. pszName = pszNewName;
  102. vOrigin = newOrigin;
  103. vDirection = newDirection;
  104. fVolume = newVolume;
  105. Soundlevel = newSoundLevel;
  106. bLooping = newLooping;
  107. nPitch = newPitch;
  108. vListenerOrigin = vecListenerOrigin;
  109. nSpeakerEntity = speakerentity;
  110. nRandomSeed = nSeed;
  111. }
  112. void SetDefault()
  113. {
  114. fDelay = DEFAULT_SOUND_PACKET_DELAY;
  115. fTickTime = 0;
  116. fVolume = DEFAULT_SOUND_PACKET_VOLUME;
  117. Soundlevel = SNDLVL_NORM;
  118. nPitch = DEFAULT_SOUND_PACKET_PITCH;
  119. nEntityIndex = 0;
  120. nSpeakerEntity = -1;
  121. nChannel = CHAN_STATIC;
  122. nSoundNum = 0;
  123. nFlags = 0;
  124. nSequenceNumber = 0;
  125. nRandomSeed = 0;
  126. pszName = NULL;
  127. bLooping = false;
  128. bIsSentence = false;
  129. bIsAmbient = false;
  130. vOrigin.Init();
  131. vDirection.Init();
  132. vListenerOrigin.Init();
  133. }
  134. void ClearStopFields()
  135. {
  136. fVolume = 0;
  137. Soundlevel = SNDLVL_NONE;
  138. nPitch = PITCH_NORM;
  139. pszName = NULL;
  140. fDelay = 0.0f;
  141. nSequenceNumber = 0;
  142. vOrigin.Init();
  143. nSpeakerEntity = -1;
  144. }
  145. // this cries for Send/RecvTables:
  146. void WriteDelta( const SoundInfo_t *delta, CSVCMsg_Sounds& Msg, float finalTickTime )
  147. {
  148. #define WRITE_DELTA_FIELD( _name, _protobufname) \
  149. if( delta->_name != _name ) pSoundData->set_ ## _protobufname( _name );
  150. #define WRITE_DELTA_FIELD_SCALED( _name, _protobufname, _scaled_val ) \
  151. if( delta->_name != _name ) pSoundData->set_ ## _protobufname( _scaled_val );
  152. SoundInfo_t defaultSound( SOUNDINFO_NO_SETDEFAULT );
  153. CSVCMsg_Sounds::sounddata_t *pSoundData = Msg.add_sounds();
  154. if( !delta )
  155. {
  156. defaultSound.SetDefault();
  157. delta = &defaultSound;
  158. }
  159. WRITE_DELTA_FIELD( nEntityIndex, entity_index );
  160. WRITE_DELTA_FIELD( nFlags, flags );
  161. // Scriptable sounds are written as a hash, uses full 32 bits
  162. if( nFlags & SND_IS_SCRIPTHANDLE )
  163. {
  164. WRITE_DELTA_FIELD( nSoundNum, sound_num_handle );
  165. }
  166. else
  167. {
  168. WRITE_DELTA_FIELD( nSoundNum, sound_num );
  169. }
  170. WRITE_DELTA_FIELD( nChannel, channel );
  171. WRITE_DELTA_FIELD( bIsAmbient, is_ambient );
  172. WRITE_DELTA_FIELD( bIsSentence, is_sentence ); // NOTE: SND_STOP behavior is different depending on this flag
  173. if ( nFlags != SND_STOP )
  174. {
  175. WRITE_DELTA_FIELD_SCALED( nSequenceNumber, sequence_number, ( nSequenceNumber & SOUND_SEQNUMBER_MASK ) )
  176. WRITE_DELTA_FIELD_SCALED( fVolume, volume, ( int )( fVolume * 127.0f ) );
  177. WRITE_DELTA_FIELD( Soundlevel, sound_level );
  178. WRITE_DELTA_FIELD( nPitch, pitch );
  179. WRITE_DELTA_FIELD( nRandomSeed, random_seed );
  180. float delayValue = fDelay;
  181. if ( ( nFlags & SND_DELAY ) && ( fTickTime != finalTickTime ) )
  182. {
  183. delayValue += fTickTime - finalTickTime;
  184. }
  185. if ( delayValue != delta->fDelay )
  186. {
  187. pSoundData->set_delay_value( delayValue );
  188. }
  189. // don't transmit sounds with high precision
  190. WRITE_DELTA_FIELD_SCALED( vOrigin.x, origin_x, ( int )( vOrigin.x * ( 1.0f / 8.0f ) ) );
  191. WRITE_DELTA_FIELD_SCALED( vOrigin.y, origin_y, ( int )( vOrigin.y * ( 1.0f / 8.0f ) ) );
  192. WRITE_DELTA_FIELD_SCALED( vOrigin.z, origin_z, ( int )( vOrigin.z * ( 1.0f / 8.0f ) ) );
  193. WRITE_DELTA_FIELD( nSpeakerEntity, speaker_entity );
  194. }
  195. else
  196. {
  197. ClearStopFields();
  198. }
  199. #undef WRITE_DELTA_FIELD
  200. #undef WRITE_DELTA_FIELD_SCALED
  201. };
  202. void ReadDelta( const SoundInfo_t *delta, const CSVCMsg_Sounds::sounddata_t& SoundData)
  203. {
  204. #define READ_DELTA_FIELD( _name, _protobufname ) \
  205. _name = ( SoundData.has_ ## _protobufname() ) ? SoundData._protobufname() : delta->_name;
  206. #define READ_DELTA_FIELD_SCALED( _name, _protobufname, _scale ) \
  207. _name = ( SoundData.has_ ## _protobufname() ) ? ( SoundData._protobufname() * ( _scale ) ) : delta->_name;
  208. READ_DELTA_FIELD( nEntityIndex, entity_index );
  209. READ_DELTA_FIELD( nFlags, flags );
  210. // Scriptable sounds are written as a hash, uses full 32 bits
  211. if( nFlags & SND_IS_SCRIPTHANDLE )
  212. {
  213. READ_DELTA_FIELD( nSoundNum, sound_num_handle );
  214. }
  215. else
  216. {
  217. READ_DELTA_FIELD( nSoundNum, sound_num );
  218. }
  219. READ_DELTA_FIELD( nChannel, channel );
  220. READ_DELTA_FIELD( bIsAmbient, is_ambient );
  221. READ_DELTA_FIELD( bIsSentence, is_sentence ); // NOTE: SND_STOP behavior is different depending on this flag
  222. if ( nFlags != SND_STOP )
  223. {
  224. READ_DELTA_FIELD( nSequenceNumber, sequence_number );
  225. READ_DELTA_FIELD_SCALED( fVolume, volume, ( 1.0f / 127.0f ) );
  226. Soundlevel = ( soundlevel_t )( SoundData.has_sound_level() ? SoundData.sound_level() : delta->Soundlevel );
  227. READ_DELTA_FIELD( nPitch, pitch );
  228. READ_DELTA_FIELD( nRandomSeed, random_seed );
  229. READ_DELTA_FIELD( fDelay, delay_value );
  230. READ_DELTA_FIELD_SCALED( vOrigin.x, origin_x, 8.0f );
  231. READ_DELTA_FIELD_SCALED( vOrigin.y, origin_y, 8.0f );
  232. READ_DELTA_FIELD_SCALED( vOrigin.z, origin_z, 8.0f );
  233. READ_DELTA_FIELD( nSpeakerEntity, speaker_entity );
  234. }
  235. else
  236. {
  237. ClearStopFields();
  238. }
  239. #undef READ_DELTA_FIELD
  240. #undef READ_DELTA_FIELD_SCALED
  241. }
  242. };
  243. struct SpatializationInfo_t
  244. {
  245. typedef enum
  246. {
  247. SI_INCREATION = 0,
  248. SI_INSPATIALIZATION
  249. } SPATIALIZATIONTYPE;
  250. // Inputs
  251. SPATIALIZATIONTYPE type;
  252. // Info about the sound, channel, origin, direction, etc.
  253. SoundInfo_t info;
  254. // Requested Outputs ( NULL == not requested )
  255. Vector *pOrigin;
  256. QAngle *pAngles;
  257. float *pflRadius;
  258. CUtlVector< Vector > *m_pUtlVecMultiOrigins;
  259. CUtlVector< QAngle > *m_pUtlVecMultiAngles;
  260. };
  261. #pragma pack()
  262. #endif // SOUNDINFO_H