]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - snd_main.c
README.md: various doc adjustments
[xonotic/darkplaces.git] / snd_main.c
index bcf5163c14e05af7d3c47aa70719e8c5b151b61c..03d7e33e76ae59c9892810a11809bb2532dac5b3 100644 (file)
@@ -164,96 +164,97 @@ typedef enum { SPATIAL_NONE, SPATIAL_LOG, SPATIAL_POW, SPATIAL_THRESH } spatialm
 spatialmethod_t spatialmethod;
 
 // Cvars declared in sound.h (part of the sound API)
-cvar_t bgmvolume = {CVAR_CLIENT | CVAR_SAVE, "bgmvolume", "1", "volume of background music (such as CD music or replacement files such as sound/cdtracks/track002.ogg)"};
-cvar_t mastervolume = {CVAR_CLIENT | CVAR_SAVE, "mastervolume", "0.7", "master volume"};
-cvar_t volume = {CVAR_CLIENT | CVAR_SAVE, "volume", "0.7", "volume of sound effects"};
-cvar_t snd_initialized = {CVAR_CLIENT | CVAR_READONLY, "snd_initialized", "0", "indicates the sound subsystem is active"};
-cvar_t snd_staticvolume = {CVAR_CLIENT | CVAR_SAVE, "snd_staticvolume", "1", "volume of ambient sound effects (such as swampy sounds at the start of e1m2)"};
-cvar_t snd_soundradius = {CVAR_CLIENT | CVAR_SAVE, "snd_soundradius", "1200", "radius of weapon sounds and other standard sound effects (monster idle noises are half this radius and flickering light noises are one third of this radius)"};
-cvar_t snd_attenuation_exponent = {CVAR_CLIENT | CVAR_SAVE, "snd_attenuation_exponent", "1", "Exponent of (1-radius) in sound attenuation formula"};
-cvar_t snd_attenuation_decibel = {CVAR_CLIENT | CVAR_SAVE, "snd_attenuation_decibel", "0", "Decibel sound attenuation per sound radius distance"};
-cvar_t snd_spatialization_min_radius = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_min_radius", "10000", "use minimum spatialization above to this radius"};
-cvar_t snd_spatialization_max_radius = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_max_radius", "100", "use maximum spatialization below this radius"};
-cvar_t snd_spatialization_min = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_min", "0.70", "minimum spatializazion of sounds"};
-cvar_t snd_spatialization_max = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_max", "0.95", "maximum spatialization of sounds"};
-cvar_t snd_spatialization_power = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_power", "0", "exponent of the spatialization falloff curve (0: logarithmic)"};
-cvar_t snd_spatialization_control = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_control", "0", "enable spatialization control (headphone friendly mode)"};
-cvar_t snd_spatialization_prologic = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_prologic", "0", "use dolby prologic (I, II or IIx) encoding (snd_channels must be 2)"};
-cvar_t snd_spatialization_prologic_frontangle = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_prologic_frontangle", "30", "the angle between the front speakers and the center speaker"};
-cvar_t snd_spatialization_occlusion = {CVAR_CLIENT | CVAR_SAVE, "snd_spatialization_occlusion", "1", "enable occlusion testing on spatialized sounds, which simply quiets sounds that are blocked by the world; 1 enables PVS method, 2 enables LineOfSight method, 3 enables both"};
+cvar_t bgmvolume = {CF_CLIENT | CF_ARCHIVE, "bgmvolume", "1", "volume of background music (such as CD music or replacement files such as sound/cdtracks/track002.ogg)"};
+cvar_t mastervolume = {CF_CLIENT | CF_ARCHIVE, "mastervolume", "0.7", "master volume"};
+cvar_t volume = {CF_CLIENT | CF_ARCHIVE, "volume", "0.7", "volume of sound effects"};
+cvar_t snd_initialized = {CF_CLIENT | CF_READONLY, "snd_initialized", "0", "indicates the sound subsystem is active"};
+cvar_t snd_staticvolume = {CF_CLIENT | CF_ARCHIVE, "snd_staticvolume", "1", "volume of ambient sound effects (such as swampy sounds at the start of e1m2)"};
+cvar_t snd_soundradius = {CF_CLIENT | CF_ARCHIVE, "snd_soundradius", "1200", "radius of weapon sounds and other standard sound effects (monster idle noises are half this radius and flickering light noises are one third of this radius)"};
+cvar_t snd_attenuation_exponent = {CF_CLIENT | CF_ARCHIVE, "snd_attenuation_exponent", "1", "Exponent of (1-radius) in sound attenuation formula"};
+cvar_t snd_attenuation_decibel = {CF_CLIENT | CF_ARCHIVE, "snd_attenuation_decibel", "0", "Decibel sound attenuation per sound radius distance"};
+cvar_t snd_spatialization_min_radius = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_min_radius", "10000", "use minimum spatialization above to this radius"};
+cvar_t snd_spatialization_max_radius = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_max_radius", "100", "use maximum spatialization below this radius"};
+cvar_t snd_spatialization_min = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_min", "0.70", "minimum spatializazion of sounds"};
+cvar_t snd_spatialization_max = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_max", "0.95", "maximum spatialization of sounds"};
+cvar_t snd_spatialization_power = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_power", "0", "exponent of the spatialization falloff curve (0: logarithmic)"};
+cvar_t snd_spatialization_control = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_control", "0", "enable spatialization control (headphone friendly mode)"};
+cvar_t snd_spatialization_prologic = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_prologic", "0", "use dolby prologic (I, II or IIx) encoding (snd_channels must be 2)"};
+cvar_t snd_spatialization_prologic_frontangle = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_prologic_frontangle", "30", "the angle between the front speakers and the center speaker"};
+cvar_t snd_spatialization_occlusion = {CF_CLIENT | CF_ARCHIVE, "snd_spatialization_occlusion", "1", "enable occlusion testing on spatialized sounds, which simply quiets sounds that are blocked by the world; 1 enables PVS method, 2 enables LineOfSight method, 3 enables both"};
 
 // Cvars declared in snd_main.h (shared with other snd_*.c files)
-cvar_t _snd_mixahead = {CVAR_CLIENT | CVAR_SAVE, "_snd_mixahead", "0.15", "how much sound to mix ahead of time"};
-cvar_t snd_streaming = {CVAR_CLIENT | CVAR_SAVE, "snd_streaming", "1", "enables keeping compressed ogg sound files compressed, decompressing them only as needed, otherwise they will be decompressed completely at load (may use a lot of memory); when set to 2, streaming is performed even if this would waste memory"};
-cvar_t snd_streaming_length = {CVAR_CLIENT | CVAR_SAVE, "snd_streaming_length", "1", "decompress sounds completely if they are less than this play time when snd_streaming is 1"};
-cvar_t snd_swapstereo = {CVAR_CLIENT | CVAR_SAVE, "snd_swapstereo", "0", "swaps left/right speakers for old ISA soundblaster cards"};
+cvar_t snd_waterfx = {CF_CLIENT | CF_ARCHIVE, "snd_waterfx", "1", "underwater sound filter strength"};
+cvar_t _snd_mixahead = {CF_CLIENT | CF_ARCHIVE, "_snd_mixahead", "0.15", "how much sound to mix ahead of time"};
+cvar_t snd_streaming = {CF_CLIENT | CF_ARCHIVE, "snd_streaming", "1", "enables keeping compressed ogg sound files compressed, decompressing them only as needed, otherwise they will be decompressed completely at load (may use a lot of memory); when set to 2, streaming is performed even if this would waste memory"};
+cvar_t snd_streaming_length = {CF_CLIENT | CF_ARCHIVE, "snd_streaming_length", "1", "decompress sounds completely if they are less than this play time when snd_streaming is 1"};
+cvar_t snd_swapstereo = {CF_CLIENT | CF_ARCHIVE, "snd_swapstereo", "0", "swaps left/right speakers for old ISA soundblaster cards"};
 extern cvar_t v_flipped;
-cvar_t snd_channellayout = {CVAR_CLIENT, "snd_channellayout", "0", "channel layout. Can be 0 (auto - snd_restart needed), 1 (standard layout), or 2 (ALSA layout)"};
-cvar_t snd_mutewhenidle = {CVAR_CLIENT | CVAR_SAVE, "snd_mutewhenidle", "1", "whether to disable sound output when game window is inactive"};
-cvar_t snd_maxchannelvolume = {CVAR_CLIENT | CVAR_SAVE, "snd_maxchannelvolume", "10", "maximum volume of a single sound"};
-cvar_t snd_softclip = {CVAR_CLIENT | CVAR_SAVE, "snd_softclip", "0", "Use soft-clipping. Soft-clipping can make the sound more smooth if very high volume levels are used. Enable this option if the dynamic range of the loudspeakers is very low. WARNING: This feature creates distortion and should be considered a last resort."};
-//cvar_t snd_softclip = {CVAR_CLIENT | CVAR_SAVE, "snd_softclip", "0", "Use soft-clipping (when set to 2, use it even if output is floating point). Soft-clipping can make the sound more smooth if very high volume levels are used. Enable this option if the dynamic range of the loudspeakers is very low. WARNING: This feature creates distortion and should be considered a last resort."};
-cvar_t snd_entchannel0volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel0volume", "1", "volume multiplier of the auto-allocate entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_entchannel1volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel1volume", "1", "volume multiplier of the 1st entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_entchannel2volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel2volume", "1", "volume multiplier of the 2nd entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_entchannel3volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel3volume", "1", "volume multiplier of the 3rd entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_entchannel4volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel4volume", "1", "volume multiplier of the 4th entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_entchannel5volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel5volume", "1", "volume multiplier of the 5th entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_entchannel6volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel6volume", "1", "volume multiplier of the 6th entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_entchannel7volume = {CVAR_CLIENT | CVAR_SAVE, "snd_entchannel7volume", "1", "volume multiplier of the 7th entity channel of regular entities (DEPRECATED)"};
-cvar_t snd_playerchannel0volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel0volume", "1", "volume multiplier of the auto-allocate entity channel of player entities (DEPRECATED)"};
-cvar_t snd_playerchannel1volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel1volume", "1", "volume multiplier of the 1st entity channel of player entities (DEPRECATED)"};
-cvar_t snd_playerchannel2volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel2volume", "1", "volume multiplier of the 2nd entity channel of player entities (DEPRECATED)"};
-cvar_t snd_playerchannel3volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel3volume", "1", "volume multiplier of the 3rd entity channel of player entities (DEPRECATED)"};
-cvar_t snd_playerchannel4volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel4volume", "1", "volume multiplier of the 4th entity channel of player entities (DEPRECATED)"};
-cvar_t snd_playerchannel5volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel5volume", "1", "volume multiplier of the 5th entity channel of player entities (DEPRECATED)"};
-cvar_t snd_playerchannel6volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel6volume", "1", "volume multiplier of the 6th entity channel of player entities (DEPRECATED)"};
-cvar_t snd_playerchannel7volume = {CVAR_CLIENT | CVAR_SAVE, "snd_playerchannel7volume", "1", "volume multiplier of the 7th entity channel of player entities (DEPRECATED)"};
-cvar_t snd_worldchannel0volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel0volume", "1", "volume multiplier of the auto-allocate entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_worldchannel1volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel1volume", "1", "volume multiplier of the 1st entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_worldchannel2volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel2volume", "1", "volume multiplier of the 2nd entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_worldchannel3volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel3volume", "1", "volume multiplier of the 3rd entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_worldchannel4volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel4volume", "1", "volume multiplier of the 4th entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_worldchannel5volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel5volume", "1", "volume multiplier of the 5th entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_worldchannel6volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel6volume", "1", "volume multiplier of the 6th entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_worldchannel7volume = {CVAR_CLIENT | CVAR_SAVE, "snd_worldchannel7volume", "1", "volume multiplier of the 7th entity channel of the world entity (DEPRECATED)"};
-cvar_t snd_csqcchannel0volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel0volume", "1", "volume multiplier of the auto-allocate entity channel CSQC entities (DEPRECATED)"};
-cvar_t snd_csqcchannel1volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel1volume", "1", "volume multiplier of the 1st entity channel of CSQC entities (DEPRECATED)"};
-cvar_t snd_csqcchannel2volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel2volume", "1", "volume multiplier of the 2nd entity channel of CSQC entities (DEPRECATED)"};
-cvar_t snd_csqcchannel3volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel3volume", "1", "volume multiplier of the 3rd entity channel of CSQC entities (DEPRECATED)"};
-cvar_t snd_csqcchannel4volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel4volume", "1", "volume multiplier of the 4th entity channel of CSQC entities (DEPRECATED)"};
-cvar_t snd_csqcchannel5volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel5volume", "1", "volume multiplier of the 5th entity channel of CSQC entities (DEPRECATED)"};
-cvar_t snd_csqcchannel6volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel6volume", "1", "volume multiplier of the 6th entity channel of CSQC entities (DEPRECATED)"};
-cvar_t snd_csqcchannel7volume = {CVAR_CLIENT | CVAR_SAVE, "snd_csqcchannel7volume", "1", "volume multiplier of the 7th entity channel of CSQC entities (DEPRECATED)"};
-cvar_t snd_channel0volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel0volume", "1", "volume multiplier of the auto-allocate entity channel"};
-cvar_t snd_channel1volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel1volume", "1", "volume multiplier of the 1st entity channel"};
-cvar_t snd_channel2volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel2volume", "1", "volume multiplier of the 2nd entity channel"};
-cvar_t snd_channel3volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel3volume", "1", "volume multiplier of the 3rd entity channel"};
-cvar_t snd_channel4volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel4volume", "1", "volume multiplier of the 4th entity channel"};
-cvar_t snd_channel5volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel5volume", "1", "volume multiplier of the 5th entity channel"};
-cvar_t snd_channel6volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel6volume", "1", "volume multiplier of the 6th entity channel"};
-cvar_t snd_channel7volume = {CVAR_CLIENT | CVAR_SAVE, "snd_channel7volume", "1", "volume multiplier of the 7th entity channel"};
+cvar_t snd_channellayout = {CF_CLIENT, "snd_channellayout", "0", "channel layout. Can be 0 (auto - snd_restart needed), 1 (standard layout), or 2 (ALSA layout)"};
+cvar_t snd_mutewhenidle = {CF_CLIENT | CF_ARCHIVE, "snd_mutewhenidle", "1", "whether to disable sound output when game window is inactive"};
+cvar_t snd_maxchannelvolume = {CF_CLIENT | CF_ARCHIVE, "snd_maxchannelvolume", "10", "maximum volume of a single sound"};
+cvar_t snd_softclip = {CF_CLIENT | CF_ARCHIVE, "snd_softclip", "0", "Use soft-clipping. Soft-clipping can make the sound more smooth if very high volume levels are used. Enable this option if the dynamic range of the loudspeakers is very low. WARNING: This feature creates distortion and should be considered a last resort."};
+//cvar_t snd_softclip = {CF_CLIENT | CF_ARCHIVE, "snd_softclip", "0", "Use soft-clipping (when set to 2, use it even if output is floating point). Soft-clipping can make the sound more smooth if very high volume levels are used. Enable this option if the dynamic range of the loudspeakers is very low. WARNING: This feature creates distortion and should be considered a last resort."};
+cvar_t snd_entchannel0volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel0volume", "1", "volume multiplier of the auto-allocate entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_entchannel1volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel1volume", "1", "volume multiplier of the 1st entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_entchannel2volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel2volume", "1", "volume multiplier of the 2nd entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_entchannel3volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel3volume", "1", "volume multiplier of the 3rd entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_entchannel4volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel4volume", "1", "volume multiplier of the 4th entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_entchannel5volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel5volume", "1", "volume multiplier of the 5th entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_entchannel6volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel6volume", "1", "volume multiplier of the 6th entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_entchannel7volume = {CF_CLIENT | CF_ARCHIVE, "snd_entchannel7volume", "1", "volume multiplier of the 7th entity channel of regular entities (DEPRECATED)"};
+cvar_t snd_playerchannel0volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel0volume", "1", "volume multiplier of the auto-allocate entity channel of player entities (DEPRECATED)"};
+cvar_t snd_playerchannel1volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel1volume", "1", "volume multiplier of the 1st entity channel of player entities (DEPRECATED)"};
+cvar_t snd_playerchannel2volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel2volume", "1", "volume multiplier of the 2nd entity channel of player entities (DEPRECATED)"};
+cvar_t snd_playerchannel3volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel3volume", "1", "volume multiplier of the 3rd entity channel of player entities (DEPRECATED)"};
+cvar_t snd_playerchannel4volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel4volume", "1", "volume multiplier of the 4th entity channel of player entities (DEPRECATED)"};
+cvar_t snd_playerchannel5volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel5volume", "1", "volume multiplier of the 5th entity channel of player entities (DEPRECATED)"};
+cvar_t snd_playerchannel6volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel6volume", "1", "volume multiplier of the 6th entity channel of player entities (DEPRECATED)"};
+cvar_t snd_playerchannel7volume = {CF_CLIENT | CF_ARCHIVE, "snd_playerchannel7volume", "1", "volume multiplier of the 7th entity channel of player entities (DEPRECATED)"};
+cvar_t snd_worldchannel0volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel0volume", "1", "volume multiplier of the auto-allocate entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_worldchannel1volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel1volume", "1", "volume multiplier of the 1st entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_worldchannel2volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel2volume", "1", "volume multiplier of the 2nd entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_worldchannel3volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel3volume", "1", "volume multiplier of the 3rd entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_worldchannel4volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel4volume", "1", "volume multiplier of the 4th entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_worldchannel5volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel5volume", "1", "volume multiplier of the 5th entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_worldchannel6volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel6volume", "1", "volume multiplier of the 6th entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_worldchannel7volume = {CF_CLIENT | CF_ARCHIVE, "snd_worldchannel7volume", "1", "volume multiplier of the 7th entity channel of the world entity (DEPRECATED)"};
+cvar_t snd_csqcchannel0volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel0volume", "1", "volume multiplier of the auto-allocate entity channel CSQC entities (DEPRECATED)"};
+cvar_t snd_csqcchannel1volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel1volume", "1", "volume multiplier of the 1st entity channel of CSQC entities (DEPRECATED)"};
+cvar_t snd_csqcchannel2volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel2volume", "1", "volume multiplier of the 2nd entity channel of CSQC entities (DEPRECATED)"};
+cvar_t snd_csqcchannel3volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel3volume", "1", "volume multiplier of the 3rd entity channel of CSQC entities (DEPRECATED)"};
+cvar_t snd_csqcchannel4volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel4volume", "1", "volume multiplier of the 4th entity channel of CSQC entities (DEPRECATED)"};
+cvar_t snd_csqcchannel5volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel5volume", "1", "volume multiplier of the 5th entity channel of CSQC entities (DEPRECATED)"};
+cvar_t snd_csqcchannel6volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel6volume", "1", "volume multiplier of the 6th entity channel of CSQC entities (DEPRECATED)"};
+cvar_t snd_csqcchannel7volume = {CF_CLIENT | CF_ARCHIVE, "snd_csqcchannel7volume", "1", "volume multiplier of the 7th entity channel of CSQC entities (DEPRECATED)"};
+cvar_t snd_channel0volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel0volume", "1", "volume multiplier of the auto-allocate entity channel"};
+cvar_t snd_channel1volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel1volume", "1", "volume multiplier of the 1st entity channel"};
+cvar_t snd_channel2volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel2volume", "1", "volume multiplier of the 2nd entity channel"};
+cvar_t snd_channel3volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel3volume", "1", "volume multiplier of the 3rd entity channel"};
+cvar_t snd_channel4volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel4volume", "1", "volume multiplier of the 4th entity channel"};
+cvar_t snd_channel5volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel5volume", "1", "volume multiplier of the 5th entity channel"};
+cvar_t snd_channel6volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel6volume", "1", "volume multiplier of the 6th entity channel"};
+cvar_t snd_channel7volume = {CF_CLIENT | CF_ARCHIVE, "snd_channel7volume", "1", "volume multiplier of the 7th entity channel"};
 
 // Local cvars
-static cvar_t nosound = {CVAR_CLIENT, "nosound", "0", "disables sound"};
-static cvar_t snd_precache = {CVAR_CLIENT, "snd_precache", "1", "loads sounds before they are used"};
-static cvar_t ambient_level = {CVAR_CLIENT, "ambient_level", "0.3", "volume of environment noises (water and wind)"};
-static cvar_t ambient_fade = {CVAR_CLIENT, "ambient_fade", "100", "rate of volume fading when moving from one environment to another"};
-static cvar_t snd_noextraupdate = {CVAR_CLIENT, "snd_noextraupdate", "0", "disables extra sound mixer calls that are meant to reduce the chance of sound breakup at very low framerates"};
-static cvar_t snd_show = {CVAR_CLIENT, "snd_show", "0", "shows some statistics about sound mixing"};
+static cvar_t nosound = {CF_CLIENT, "nosound", "0", "disables sound"};
+static cvar_t snd_precache = {CF_CLIENT, "snd_precache", "1", "loads sounds before they are used"};
+static cvar_t ambient_level = {CF_CLIENT, "ambient_level", "0.3", "volume of environment noises (water and wind)"};
+static cvar_t ambient_fade = {CF_CLIENT, "ambient_fade", "100", "rate of volume fading when moving from one environment to another"};
+static cvar_t snd_noextraupdate = {CF_CLIENT, "snd_noextraupdate", "0", "disables extra sound mixer calls that are meant to reduce the chance of sound breakup at very low framerates"};
+static cvar_t snd_show = {CF_CLIENT, "snd_show", "0", "shows some statistics about sound mixing"};
 
 // Default sound format is 48KHz, 32bit float, stereo
 // (48KHz because a lot of onboard sound cards sucks at any other speed)
-static cvar_t snd_speed = {CVAR_CLIENT | CVAR_SAVE, "snd_speed", "48000", "sound output frequency, in hertz"};
-static cvar_t snd_width = {CVAR_CLIENT | CVAR_SAVE, "snd_width", "4", "sound output precision, in bytes - 1 = 8bit, 2 = 16bit, 4 = 32bit float"};
-static cvar_t snd_channels = {CVAR_CLIENT | CVAR_SAVE, "snd_channels", "2", "number of channels for the sound output (2 for stereo; up to 8 supported for 3D sound)"};
+static cvar_t snd_speed = {CF_CLIENT | CF_ARCHIVE, "snd_speed", "48000", "sound output frequency, in hertz"};
+static cvar_t snd_width = {CF_CLIENT | CF_ARCHIVE, "snd_width", "4", "sound output precision, in bytes - 1 = 8bit, 2 = 16bit, 4 = 32bit float"};
+static cvar_t snd_channels = {CF_CLIENT | CF_ARCHIVE, "snd_channels", "2", "number of channels for the sound output (2 for stereo; up to 8 supported for 3D sound)"};
 
-static cvar_t snd_startloopingsounds = {CVAR_CLIENT, "snd_startloopingsounds", "1", "whether to start sounds that would loop (you want this to be 1); existing sounds are not affected"};
-static cvar_t snd_startnonloopingsounds = {CVAR_CLIENT, "snd_startnonloopingsounds", "1", "whether to start sounds that would not loop (you want this to be 1); existing sounds are not affected"};
+static cvar_t snd_startloopingsounds = {CF_CLIENT, "snd_startloopingsounds", "1", "whether to start sounds that would loop (you want this to be 1); existing sounds are not affected"};
+static cvar_t snd_startnonloopingsounds = {CF_CLIENT, "snd_startnonloopingsounds", "1", "whether to start sounds that would not loop (you want this to be 1); existing sounds are not affected"};
 
 // randomization
-static cvar_t snd_identicalsoundrandomization_time = {CVAR_CLIENT, "snd_identicalsoundrandomization_time", "0.1", "how much seconds to randomly skip (positive) or delay (negative) sounds when multiple identical sounds are started on the same frame"};
-static cvar_t snd_identicalsoundrandomization_tics = {CVAR_CLIENT, "snd_identicalsoundrandomization_tics", "0", "if nonzero, how many tics to limit sound randomization as defined by snd_identicalsoundrandomization_time"};
+static cvar_t snd_identicalsoundrandomization_time = {CF_CLIENT, "snd_identicalsoundrandomization_time", "0.1", "how much seconds to randomly skip (positive) or delay (negative) sounds when multiple identical sounds are started on the same frame"};
+static cvar_t snd_identicalsoundrandomization_tics = {CF_CLIENT, "snd_identicalsoundrandomization_tics", "0", "if nonzero, how many tics to limit sound randomization as defined by snd_identicalsoundrandomization_time"};
 
 // Ambient sounds
 static sfx_t* ambient_sfxs [2] = { NULL, NULL };
@@ -276,9 +277,9 @@ static void S_Play_Common (cmd_state_t *cmd, float fvol, float attenuation)
        while (i < Cmd_Argc (cmd))
        {
                // Get the name, and appends ".wav" as an extension if there's none
-               strlcpy (name, Cmd_Argv(cmd, i), sizeof (name));
+               dp_strlcpy (name, Cmd_Argv(cmd, i), sizeof (name));
                if (!strrchr (name, '.'))
-                       strlcat (name, ".wav", sizeof (name));
+                       dp_strlcat (name, ".wav", sizeof (name));
                i++;
 
                // If we need to get the volume from the command line
@@ -661,6 +662,8 @@ void S_Startup (void)
 #ifdef CONFIG_VIDEO_CAPTURE
        recording_sound = false;
 #endif
+
+       CDAudio_Startup();
 }
 
 void S_Shutdown(void)
@@ -668,6 +671,8 @@ void S_Shutdown(void)
        if (snd_renderbuffer == NULL)
                return;
 
+       CDAudio_Shutdown();
+
        oldpaintedtime = snd_renderbuffer->endframe;
 
        if (simsound)
@@ -778,8 +783,8 @@ void S_Init(void)
        if (Sys_CheckParm("-nosound"))
        {
                // dummy out Play and Play2 because mods stuffcmd that
-               Cmd_AddCommand(CMD_CLIENT, "play", Host_NoOperation_f, "does nothing because -nosound was specified");
-               Cmd_AddCommand(CMD_CLIENT, "play2", Host_NoOperation_f, "does nothing because -nosound was specified");
+               Cmd_AddCommand(CF_CLIENT, "play", Cmd_NoOperation_f, "does nothing because -nosound was specified");
+               Cmd_AddCommand(CF_CLIENT, "play2", Cmd_NoOperation_f, "does nothing because -nosound was specified");
                return;
        }
 
@@ -789,15 +794,15 @@ void S_Init(void)
        if (Sys_CheckParm("-simsound"))
                simsound = true;
 
-       Cmd_AddCommand(CMD_CLIENT, "play", S_Play_f, "play a sound at your current location (not heard by anyone else)");
-       Cmd_AddCommand(CMD_CLIENT, "play2", S_Play2_f, "play a sound globally throughout the level (not heard by anyone else)");
-       Cmd_AddCommand(CMD_CLIENT, "playvol", S_PlayVol_f, "play a sound at the specified volume level at your current location (not heard by anyone else)");
-       Cmd_AddCommand(CMD_CLIENT, "stopsound", S_StopAllSounds_f, "silence");
-       Cmd_AddCommand(CMD_CLIENT, "pausesound", S_PauseSound_f, "temporary silence");
-       Cmd_AddCommand(CMD_CLIENT, "soundlist", S_SoundList_f, "list loaded sounds");
-       Cmd_AddCommand(CMD_CLIENT, "soundinfo", S_SoundInfo_f, "print sound system information (such as channels and speed)");
-       Cmd_AddCommand(CMD_CLIENT, "snd_restart", S_Restart_f, "restart sound system");
-       Cmd_AddCommand(CMD_CLIENT, "snd_unloadallsounds", S_UnloadAllSounds_f, "unload all sound files");
+       Cmd_AddCommand(CF_CLIENT, "play", S_Play_f, "play a sound at your current location (not heard by anyone else)");
+       Cmd_AddCommand(CF_CLIENT, "play2", S_Play2_f, "play a sound globally throughout the level (not heard by anyone else)");
+       Cmd_AddCommand(CF_CLIENT, "playvol", S_PlayVol_f, "play a sound at the specified volume level at your current location (not heard by anyone else)");
+       Cmd_AddCommand(CF_CLIENT, "stopsound", S_StopAllSounds_f, "silence");
+       Cmd_AddCommand(CF_CLIENT, "pausesound", S_PauseSound_f, "temporary silence");
+       Cmd_AddCommand(CF_CLIENT, "soundlist", S_SoundList_f, "list loaded sounds");
+       Cmd_AddCommand(CF_CLIENT, "soundinfo", S_SoundInfo_f, "print sound system information (such as channels and speed)");
+       Cmd_AddCommand(CF_CLIENT, "snd_restart", S_Restart_f, "restart sound system");
+       Cmd_AddCommand(CF_CLIENT, "snd_unloadallsounds", S_UnloadAllSounds_f, "unload all sound files");
 
        Cvar_RegisterVariable(&nosound);
        Cvar_RegisterVariable(&snd_precache);
@@ -808,6 +813,7 @@ void S_Init(void)
        Cvar_RegisterVariable(&ambient_fade);
        Cvar_RegisterVariable(&snd_noextraupdate);
        Cvar_RegisterVariable(&snd_show);
+       Cvar_RegisterVariable(&snd_waterfx);
        Cvar_RegisterVariable(&_snd_mixahead);
        Cvar_RegisterVariable(&snd_swapstereo); // for people with backwards sound wiring
        Cvar_RegisterVariable(&snd_channellayout);
@@ -824,6 +830,8 @@ void S_Init(void)
 #ifdef USEXMP
        XMP_OpenLibrary ();
 #endif
+
+       CDAudio_Init();
 }
 
 
@@ -921,7 +929,7 @@ sfx_t *S_FindName (const char *name)
        // Add a sfx_t struct for this sound
        sfx = (sfx_t *)Mem_Alloc (snd_mempool, sizeof (*sfx));
        memset (sfx, 0, sizeof(*sfx));
-       strlcpy (sfx->name, name, sizeof (sfx->name));
+       dp_strlcpy (sfx->name, name, sizeof (sfx->name));
        sfx->memsize = sizeof(*sfx);
        sfx->next = known_sfx;
        known_sfx = sfx;
@@ -1220,13 +1228,13 @@ static void SND_Spatialize_WithSfx(channel_t *ch, qbool isstatic, sfx_t *sfx)
                {
                        //Con_Printf("-- entnum %i origin %f %f %f neworigin %f %f %f\n", ch->entnum, ch->origin[0], ch->origin[1], ch->origin[2], cl.entities[ch->entnum].state_current.origin[0], cl.entities[ch->entnum].state_current.origin[1], cl.entities[ch->entnum].state_current.origin[2]);
 
-                       if (ch->entnum > MAX_EDICTS)
+                       if (CLVM_prog->loaded && ch->entnum > MAX_EDICTS)
                                if (!CL_VM_GetEntitySoundOrigin(ch->entnum, ch->origin))
                                        ch->entnum = MAX_EDICTS; // entity was removed, disown sound
                }
                else if (cl.entities[ch->entnum].state_current.active)
                {
-                       dp_model_t *model;
+                       model_t *model;
                        //Con_Printf("-- entnum %i origin %f %f %f neworigin %f %f %f\n", ch->entnum, ch->origin[0], ch->origin[1], ch->origin[2], cl.entities[ch->entnum].state_current.origin[0], cl.entities[ch->entnum].state_current.origin[1], cl.entities[ch->entnum].state_current.origin[2]);
                        model = CL_GetModelByIndex(cl.entities[ch->entnum].state_current.modelindex);
                        if (model && model->soundfromcenter)
@@ -1234,7 +1242,7 @@ static void SND_Spatialize_WithSfx(channel_t *ch, qbool isstatic, sfx_t *sfx)
                        else
                                Matrix4x4_OriginFromMatrix(&cl.entities[ch->entnum].render.matrix, ch->origin);
                }
-               else if (cl.csqc_server2csqcentitynumber[ch->entnum])
+               else if (CLVM_prog->loaded && cl.csqc_server2csqcentitynumber[ch->entnum])
                {
                        //Con_Printf("-- entnum %i (client %i) origin %f %f %f neworigin %f %f %f\n", ch->entnum, cl.csqc_server2csqcentitynumber[ch->entnum], ch->origin[0], ch->origin[1], ch->origin[2], cl.entities[ch->entnum].state_current.origin[0], cl.entities[ch->entnum].state_current.origin[1], cl.entities[ch->entnum].state_current.origin[2]);
 
@@ -1844,7 +1852,6 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float fvol, float attenuation)
        S_PlaySfxOnChannel (sfx, target_chan, CHANNELFLAG_FORCELOOP, origin, fvol, attenuation, true, 0, 0, 0, 1.0f);
 }
 
-
 /*
 ===================
 S_UpdateAmbientSounds
@@ -1864,7 +1871,10 @@ static void S_UpdateAmbientSounds (void)
        if (cl.worldmodel && cl.worldmodel->brush.AmbientSoundLevelsForPoint)
                cl.worldmodel->brush.AmbientSoundLevelsForPoint(cl.worldmodel, listener_origin, ambientlevels, sizeof(ambientlevels));
 
+
        // Calc ambient sound levels
+       S_SetUnderwaterIntensity();
+
        for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)
        {
                chan = &channels[ambient_channel];
@@ -2240,7 +2250,7 @@ void S_ExtraUpdate (void)
        S_PaintAndSubmit();
 }
 
-qbool S_LocalSound (const char *sound)
+qbool S_LocalSoundEx (const char *sound, int chan, float fvol)
 {
        sfx_t   *sfx;
        int             ch_ind;
@@ -2261,10 +2271,15 @@ qbool S_LocalSound (const char *sound)
        // fun fact: in Quake 1, this used -1 "replace any entity channel",
        // which we no longer support anyway
        // changed by Black in r4297 "Changed S_LocalSound to play multiple sounds at a time."
-       ch_ind = S_StartSound (cl.viewentity, 0, sfx, vec3_origin, 1, 0);
+       ch_ind = S_StartSound (cl.viewentity, chan, sfx, vec3_origin, fvol, 0);
        if (ch_ind < 0)
                return false;
 
        channels[ch_ind].flags |= CHANNELFLAG_LOCALSOUND;
        return true;
 }
+
+qbool S_LocalSound (const char *sound)
+{
+       return S_LocalSoundEx(sound, 0, 1);
+}