Which Mod Looks The Best?

Caliber
Urban Terror
Survival 9mm
Weapons Factory
None of the above


News

- Current
- Archived
- Send News
Tutorials
- Coding
- Mapping
Interviews
- Caliber Mod
Mods
- Previews
:::Q3Fortress
- Reviews
Download
- Best Maps
- Best Models
- Tools
Community
- Forums
- Dev Screens
- Chat

Mod Database
- Sign-Up
- Add Mod
- Delete Mod
- View Mods
Hosted Sites
Mods

- Alien Culture
- Alive

- Anarchy
- Armed Service
- Battle Arena
- Caliber
- Chaotic Designs
- Classic Q3A
- Countdown to Dest.
- Critical Mass
- Crusade
- Darkgift
- DarkStar
- Decimal
- Defend The Flags
- Full Metal Jacket
- Front Lines
- Fury
- GatheringDarkness
- Guerilla Warfare
- Hunter
- Insanity
- Insanity Prod.
- Jagged Q3
- Nightrunner
- Occupation
- Oblivion Demise
- Omega
- QForces
- Railfest
- Resound
- Run Bob Run
- ShadowRun
- ShadowStar Conflict
- SiR
- Snipers
- Team Phatass
- Terrorism
- Toons of Evil
- Tritium
- Urban Terror
- Zoners

Editing
- Coded
- Rungy's Metropolis
- MD3Centre
- PikaMaps!
- Q3Empire
- RealGunz
- RocIDE
- Team Interact

 
 

Adding Sounds - By Asriel

Playing sounds in Quake 3 is really quite easy, but can seem confusing. So, today we will have a look at basic sound functionality, and the various options it presents to you.

Fundamentally, a sound is a temporary entity. Thus, you ‘create’ the sound by using G_TempEntity. The astute among you might have noticed a little function tucked away in g_utils.c called G_Sound. This is ‘wrapper’ for the functionality the engine exposes in G_TempEntity with the sound flags. We won’t use this though, we are going to write our own to make sure you understand sounds.

In Beryllium, I added a function that could play sounds to every client in the game, like an announcer. I’ve ripper that right out, and here it is…



void BroadCastSound() {
	char name[MAX_TOKEN_CHARS];
	gentity_t	*te;
	vec3_t origin;
	trap_Argv(1, name, sizeof(name));
	if(!strlen(name))
		return;
	origin[0] = origin[1] = origin[2] = 0;
	te = G_TempEntity(origin, EV_GLOBAL_SOUND);
	te->s.eventParm = G_SoundIndex(name);
	te->r.svFlags |= SVF_BROADCAST;
}
This function was designed to be called from the console, so it extracts the name of the sound from the first argument on the command. We don’t really want this though, so we are going to change it so it can be called from anywhere. We need to make changes so that we can call it with the path to the file we want to play. I’ve pasted an appropriate change below, but you might want to see if you can do it alone before ‘cheating’ :).



void BroadCastSound(char *path) {
	gentity_t	*te;
	vec3_t origin;
	if(!strlen(path))
		return;
	origin[0] = origin[1] = origin[2] = 0;
	te = G_TempEntity(origin, EV_GLOBAL_SOUND);
	te->s.eventParm = G_SoundIndex(name);
	te->r.svFlags |= SVF_BROADCAST;
}

Right, lets run through this. A temporary entity is still an entity, so at the top, we declare an entity type variable. Now, this is important - origin is the vector location where the sound will occur. This makes no difference to our sounds, as we will find out in a moment, but for yours, it does. You might want to have a sound eminate from a base when a flag it captured or something (I don’t know, be creative). This origin is the 3d co-ordinate of the source of your sound.

Next, we check to see we were actually given a path. Calling G_SoundIndex without an empty string seems to cause a Q3 bomb, so this is just a simple check to save crashing ourselves if we forget to put in a path.

Right, now we set our origin to 0, 0, 0. This is because we are going to have a sound have NO falloff, and play to everyone, so though it needs an origin, it makes no difference where it is. 0, 0, 0 is as good as any. Next, we create the entity, at the origin we specified. The type of this entity is EV_GLOBAL_SOUND, which means it plays to every connected client. We could have used EV_GENERAL_SOUND, which would play a ‘normal’ sound that only occurs in the area around our origin co-ordinate. If you specify this, you’ll want to give a useful origin, such as the current position of a player. We’ll discuss how to do this in a second.

Next up, we set the temp entities parameters to the index of the sound we want to play. Quake 3 incorporates a nice caching system, so it doesn’t have to reload the sound every time its used. This first time G_SoundIndex is called for a given sound path, it loads the sound, caches (‘stores’) the it in memory, and assigns it a unique index number. Then, if the same sound is called again, it returns that number, rather than having to reload the sound.

Lastly, we send our sound off to be played, by telling Quake 3 we are ready to broadcast this entity to all the clients. Next frame, the sound request will be sent over the network, and all the clients will hear it! Test this out in your code by prototyping the function in g_local.h. Just go to the bottom, and add...



void BroadCastSound(char *path);
Then call it from somewhere with the FULL path of the sound, something like...


BroadCastSound("sound/bob.wav");
bob.wav can be in a pk3, in a folder called sound, or if you're not running a pure server, create a folder called sound, and put them in their. The format of the sound matters. No stero, and 8 bit work best for me.

Right, just a couple of things to clear up. There are different ‘channels’ for sounds to play on, so they don’t override each other much. Have a look at the G_Sound definition in g_utils.c, and calls to this. Also, have a look at this function and how it has been called in the game code to see how to set sounds centred on an entity, rather than the world.

There we go, a (very) brief and simple run down on how to get sounds into your mod. Questions comments and rebukes for technical inaccuracies to adamw@archgrove.co.uk, or ICQ me on 65572335.

Adam "Asriel" Wright
Beryllium Q3