Custom ambient sounds using cvars

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Custom ambient sounds using cvars

Post by frag.machine »

Ok, this is a small tutorial from some code I am working ATM. This will add cvars to change (and even mute) the hardcoded default sounds Quake uses when there are visible water or sky brushes. As a bonus, you will be able to also set sounds for when lava or slime are visible. I am assuming FitzQuake 0.85 without any changes as the base code, but this can be converted to a number of other engines.

1) Open up snd_dma.c, and somewhere on the top of file let's declare our cvars:

Code: Select all

cvar_t sfx_water = {"sfx_water", "ambience/water1.wav"};
cvar_t sfx_wind = {"sfx_wind", "ambience/wind2.wav"};
cvar_t sfx_slime = {"sfx_slime","misc/null.wav"};
cvar_t sfx_lava = {"sfx_lava","misc/null.wav"};
2) Above S_Init (), let's declare our function to set those sounds with the values in our just created cvars:

Code: Select all

void S_UpdateContentSounds (void)
{
  S_StopAllSounds (true);
  if (sfx_water.string) {ambient_sfx[AMBIENT_WATER] = S_PrecacheSound (sfx_water.string);}
  if (sfx_wind.string) {ambient_sfx[AMBIENT_SKY] = S_PrecacheSound (sfx_wind.string);}
  if (sfx_slime.string) {ambient_sfx[AMBIENT_SLIME] = S_PrecacheSound (sfx_slime.string);}
  if (sfx_lava.string) {ambient_sfx[AMBIENT_LAVA] = S_PrecacheSound (sfx_lava.string);}
}
The ambient_sfx array holds references to the precached sounds that play when sky or water is visible to the player. The idea here is quite simple: every time this function is called, it stops any sound in execution, and redefines the ambient_sfx array with the sounds defined in the cvars (provided, of course, the corresponding cvar has any string value defined).

3) After this, find and comment these 2 lines in S_Init ():

Code: Select all

ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav");
ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav");
The code above originally initializes ambient_sfx. Note that only 2 sounds are being defined (water and sky): the array itself can support more 2 sounds (for slime and lava brushes), but they are left empty in vanilla Quake (and in FitzQuake, too). But not anymore. Note also that, for the sake of retrocompatibility, we will assume by default the null sound to be played when lava or slime is visible. Therefore, the game default behavior is preserved.

4) After the 2 lines we just commented out, let's place our call to S_UpdateContentSounds:

Code: Select all

  // ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav");
  // ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav");
  S_UpdateContentSounds ();
5) And finally, after the following line:

Code: Select all

Cvar_RegisterVariable(&_snd_mixahead, NULL);
Let's place our cvar registering code:

Code: Select all

  Cvar_RegisterVariable(&sfx_water, S_UpdateContentSounds);
  Cvar_RegisterVariable(&sfx_wind, S_UpdateContentSounds);
  Cvar_RegisterVariable(&sfx_slime, S_UpdateContentSounds);
  Cvar_RegisterVariable(&sfx_lava, S_UpdateContentSounds);
Note that we are passing the S_UpdateContentSounds() function to the cvar registering. This way, every time one of these 4 cvars is changed S_UpdateContentSounds() is executed, and the change reflects immediately. This is a interesting (although not standard) feature the FitzQuake engine has. If you're trying to port this to vanilla Quake I suggest to create a console command that encapsulates the function call instead. The final result will be the same, although with one more step.

And that's it. To test what we did, let's grab a looping sound for replacement (for example, the bubbling lava sound from Quake 2 will fit nicely) and copy it to the <your_quake_dir>id1/sound/ambience folder (create it if you dont have it yet). You'll need to precache the file, so you'll need to fiddle (a little bit) with QuakeC. Just open world.qc and find the line that says:

Code: Select all

W_Precache ();                              // get weapon precaches
And below this line add this:

Code: Select all

precache_sound ("ambience/lava1.wav");
I won't enter in more details about how to do the QuakeC stuff (not the subject of the tutorial). But is really easy, trust me. :)

Run your modified engine, start a new game, bring down the console and type:

sfx_lava "ambience/lava1.wav"

Now just get a bit close of the hard skill gate lava pit and hear the lava bubbling.

The ability of not only changing the existing sound effects for water and outdoor areas but also setting similar effects for lava and slime is a great resource for mappers and modders to set the environment mood. And it's easy enough to even the begginer engine coder to add.Well, that's it. Enjoy!
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Custom ambient sounds using cvars

Post by Baker »

fragmachine ++

In the middle of July, I was investigating what sounds and models were hardcoded into the engine (like "dland.wav" ... the fiend sound).

The environmental effects hardcoded into the engine. [So are the basic particle effects like bolt.mdl and so forth].
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Custom ambient sounds using cvars

Post by frag.machine »

Yeah, hardcoded stuff like menu sounds and models are a nuisance to mappers/modders and worth a bit of effort from engine coders to become easier to work. Besides the environment sounds I am working on "cvarizing" the remaining stuff (land and water splash sounds, which models should be drawn fullbright and models used by the beam-like entities such bolts and grappling hook). Once I am sure everything works and no bugs were inserted I'll put another tut.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Custom ambient sounds using cvars

Post by revelator »

could maybe be interresting to implement the sound shader system from doom3 ? :)
Productivity is a state of mind.
hogsy
Posts: 198
Joined: Wed Aug 03, 2011 3:44 pm
Location: UK
Contact:

Re: Custom ambient sounds using cvars

Post by hogsy »

That's certainly not a bad idea though I think using cvars is a tad bit cleaner way of doing it, especially considering that if you were to switch over to some script based system you would obviously need to provide them along with the client, and when it's simply just an engine modification it makes things seem a bit messy to me.
Post Reply