1 // hardcoded sounds, defined in sounds.cfg 2 3 4 enum 5 { // To avoid a lot of work, possible bugs and allow backward compatibility for players own custom 6 // cfg files, it's best not to change the listed sound order, instead, just add to it. 7 S_JUMP = 0, 8 S_SOFTLAND, S_HARDLAND, 9 S_BULLETAIR1, S_BULLETAIR2, S_BULLETHIT, S_BULLETWATERHIT, 10 S_KNIFE, 11 S_PISTOL, S_RPISTOL, 12 S_CARBINE, S_RCARBINE, 13 S_SHOTGUN, S_RSHOTGUN, 14 S_SUBGUN, S_RSUBGUN, 15 S_SNIPER, S_RSNIPER, 16 S_ASSAULT, S_RASSAULT, 17 S_ITEMAMMO, S_ITEMHEALTH, 18 S_ITEMARMOUR, S_ITEMAKIMBO, 19 S_NOAMMO, S_AKIMBOOUT, 20 S_PAIN1, S_PAIN2, S_PAIN3, S_PAIN4, S_PAIN5, S_PAIN6, 21 S_DIE1, S_DIE2, 22 S_FEXPLODE, 23 S_SPLASH1, S_SPLASH2, 24 S_FLAGDROP, S_FLAGPICKUP, S_FLAGRETURN, S_FLAGSCORE, 25 S_GRENADEPULL, S_GRENADETHROW, S_GRENADEBOUNCE1, S_GRENADEBOUNCE2, S_RAKIMBO, 26 S_GUNCHANGE, 27 S_HITSOUND, 28 S_GIB, S_HEADSHOT, 29 S_CALLVOTE, S_VOTEPASS, S_VOTEFAIL, 30 S_FOOTSTEPS, S_FOOTSTEPSCROUCH, S_WATERFOOTSTEPS, S_WATERFOOTSTEPSCROUCH, 31 S_CROUCH, S_UNCROUCH, 32 S_MENUSELECT, S_MENUENTER, 33 S_UNDERWATER, 34 S_TINNITUS, 35 // begin: voicecoms 36 S_AFFIRMATIVE, 37 S_ALLRIGHTSIR, 38 S_COMEONMOVE, 39 S_COMINGINWITHTHEFLAG, 40 S_COVERME, 41 S_DEFENDTHEFLAG, 42 S_ENEMYDOWN, 43 S_GOGETEMBOYS, 44 S_GOODJOBTEAM, 45 S_IGOTONE, 46 S_IMADECONTACT, 47 S_IMATTACKING, 48 S_IMONDEFENSE, 49 S_IMONYOURTEAMMAN, 50 S_NEGATIVE, 51 S_NOCANDO, 52 S_RECOVERTHEFLAG, 53 S_SORRY, 54 S_SPREADOUT, 55 S_STAYHERE, 56 S_STAYTOGETHER, 57 S_THERESNOWAYSIR, 58 S_WEDIDIT, 59 S_YES, 60 S_ONTHEMOVE1, 61 S_ONTHEMOVE2, 62 S_GOTURBACK, 63 S_GOTUCOVERED, 64 S_INPOSITION1, 65 S_INPOSITION2, 66 S_REPORTIN, 67 S_NICESHOT, // begin: public 68 S_THANKS1, 69 S_THANKS2, 70 S_AWESOME1, 71 S_AWESOME2, 72 S_ITEMHELMET, // begin: Sounds for AssaultCube v1.1.0.4 onwards 73 S_HEARTBEAT, 74 S_KTFSCORE, 75 S_NULL 76 }; 77 78 // hardcoded music 79 80 enum 81 { 82 M_FLAGGRAB = 0, 83 M_LASTMINUTE1, 84 M_LASTMINUTE2 85 }; 86 87 // sound priorities 88 89 enum 90 { 91 SP_LOW = 0, 92 SP_NORMAL, 93 SP_HIGH, 94 SP_HIGHEST 95 }; 96 97 #ifndef STANDALONE 98 99 // owner of an OpenAL source, used as callback interface 100 101 class sourceowner 102 { 103 public: ~sourceowner()104 virtual ~sourceowner() {} 105 virtual void onsourcereassign(class source *s) = 0; 106 }; 107 108 // represents an OpenAL source, an audio emitter in the 3D world 109 110 class source 111 { 112 public: 113 ALuint id; 114 115 sourceowner *owner; 116 bool locked, valid; 117 int priority; 118 119 source(); 120 ~source(); 121 122 void lock(); 123 void unlock(); 124 void reset(); 125 void init(sourceowner *o); 126 void onreassign(); 127 128 bool generate(); 129 bool delete_(); 130 bool buffer(ALuint buf_id); 131 bool looping(bool enable); 132 bool queuebuffers(ALsizei n, const ALuint *buffer_ids); 133 bool unqueueallbuffers(); 134 bool gain(float g); 135 bool pitch(float p); 136 bool position(const vec &pos); 137 bool position(float x, float y, float z); 138 bool velocity(float x, float y, float z); 139 vec position(); 140 bool sourcerelative(bool enable); 141 int state(); 142 bool secoffset(float secs); 143 float secoffset(); 144 bool playing(); 145 bool play(); 146 bool stop(); 147 bool rewind(); 148 149 void printposition(); 150 }; 151 152 153 // represents an OpenAL sound buffer 154 155 class sbuffer 156 { 157 public: 158 ALuint id; 159 const char *name; 160 161 sbuffer(); 162 ~sbuffer(); 163 164 bool load(bool trydl = false); 165 void unload(); 166 }; 167 168 // buffer storage 169 170 class bufferhashtable : public hashtable<char *, sbuffer> 171 { 172 public: 173 virtual ~bufferhashtable(); 174 virtual sbuffer *find(char *name); 175 }; 176 177 // manages available sources, abstracts audio channels 178 // is a singleton 179 180 class sourcescheduler 181 { 182 int numsoundchannels; 183 static sourcescheduler *inst; 184 vector<source *> sources; 185 186 public: 187 sourcescheduler(); 188 static sourcescheduler &instance(); // singleton access 189 190 void init(int numsoundchannels); 191 void reset(); 192 source *newsource(int priority, const vec &o); 193 void releasesource(source *src); 194 }; 195 196 // audio streaming 197 198 class oggstream : sourceowner 199 { 200 public: 201 string name; 202 bool valid; 203 204 // file stream 205 OggVorbis_File oggfile; 206 bool isopen; 207 vorbis_info *info; 208 double totalseconds; 209 static const int BUFSIZE = 1024 * 512; // 512kb buffer 210 211 // OpenAL resources 212 ALuint bufferids[2]; 213 source *src; 214 ALenum format; 215 216 // settings 217 float volume, gain; 218 int startmillis, endmillis, startfademillis, endfademillis; 219 bool looping; 220 221 oggstream(); 222 ~oggstream(); 223 224 void reset(); 225 bool open(const char *f); 226 void onsourcereassign(source *s); 227 bool stream(ALuint bufid); 228 bool update(); 229 bool playing(); 230 void updategain(); 231 void setgain(float g); 232 void setvolume(float v); 233 void fadein(int startmillis, int fademillis); 234 void fadeout(int endmillis, int fademillis); 235 bool playback(bool looping = false); 236 void seek(double offset); 237 }; 238 239 240 struct soundconfig 241 { 242 sbuffer *buf; // sound data 243 int vol; // volume 244 int uses, maxuses; // track uses 245 bool loop; 246 bool muted; 247 int audibleradius; 248 249 enum distancemodel 250 { 251 DM_DEFAULT = 0, // use openal distance model 252 DM_LINEAR // custom linear model (used in conjunction with audibleradius) 253 }; 254 255 distancemodel model; 256 257 soundconfig(sbuffer *b, int vol, int maxuses, bool loop, int audibleradius); 258 void onattach(); 259 void ondetach(); 260 }; 261 262 263 class worldobjreference 264 { 265 public: 266 267 enum worldobjtype { WR_CAMERA, WR_PHYSENT, WR_ENTITY, WR_STATICPOS }; 268 int type; 269 worldobjreference(int t)270 worldobjreference(int t) : type(t) {} ~worldobjreference()271 virtual ~worldobjreference() {} 272 virtual worldobjreference *clone() const = 0; 273 virtual const vec ¤tposition() const = 0; 274 virtual bool nodistance() = 0; 275 virtual bool operator==(const worldobjreference &other) = 0; 276 virtual bool operator!=(const worldobjreference &other) { return !(*this==other); } attach()277 virtual void attach() {} detach()278 virtual void detach() {} 279 }; 280 281 282 class camerareference : public worldobjreference 283 { 284 public: 285 camerareference(); 286 287 worldobjreference *clone() const; 288 const vec ¤tposition() const; 289 bool nodistance(); 290 bool operator==(const worldobjreference &other); 291 }; 292 293 294 class physentreference : public worldobjreference 295 { 296 public: 297 class physent *phys; 298 299 physentreference(physent *ref); 300 worldobjreference *clone() const; 301 const vec ¤tposition() const; 302 bool nodistance(); 303 bool operator==(const worldobjreference &other); 304 }; 305 306 307 struct entityreference : public worldobjreference 308 { 309 public: 310 struct entity *ent; 311 312 entityreference(entity *ref); 313 worldobjreference *clone() const; 314 const vec ¤tposition() const; 315 bool nodistance(); 316 bool operator==(const worldobjreference &other); 317 }; 318 319 320 struct staticreference : public worldobjreference 321 { 322 public: 323 vec pos; 324 325 staticreference(const vec &ref); 326 worldobjreference *clone() const; 327 const vec ¤tposition() const; 328 bool nodistance(); 329 bool operator==(const worldobjreference &other); 330 }; 331 332 333 class location : sourceowner 334 { 335 public: 336 soundconfig *cfg; 337 source *src; 338 worldobjreference *ref; 339 340 bool stale; 341 int playmillis; 342 343 location(int sound, const worldobjreference &r, int priority = SP_NORMAL); 344 ~location(); 345 void attachworldobjreference(const worldobjreference &r); 346 void evaluateworldobjref(); 347 void onsourcereassign(source *s); 348 void updatepos(); 349 void update(); 350 void play(bool loop = false); 351 void pitch(float p); 352 bool setvolume(float v); 353 void offset(float secs); 354 float offset(); 355 void drop(); 356 }; 357 358 359 struct locvector : vector<location *> 360 { ~locvectorlocvector361 virtual ~locvector() {} 362 363 location *find(int sound, worldobjreference *ref/* = NULL*/, const vector<soundconfig> &soundcollection /* = gamesounds*/); 364 void delete_(int i); 365 void replaceworldobjreference(const worldobjreference &oldr, const worldobjreference &newr); 366 void updatelocations(); 367 void forcepitch(float pitch); 368 void deleteworldobjsounds(); 369 }; 370 371 372 // audio interface to the engine 373 374 class audiomanager 375 { 376 bool nosound; 377 float currentpitch; 378 vector<char *> musics; 379 ALCdevice *device; 380 ALCcontext *context; 381 382 bufferhashtable bufferpool; 383 oggstream *gamemusic; 384 385 public: 386 387 locvector locations; 388 389 audiomanager(); 390 391 // init & setup 392 void initsound(); 393 void preloadmapsound(entity &e, bool trydl = false); 394 void preloadmapsounds(bool trydl = false); 395 void applymapsoundchanges(); 396 397 // configuration 398 void setchannels(int num); 399 void setlistenervol(int vol); 400 int addsound(char *name, int vol, int maxuses, bool loop, vector<soundconfig> &sounds, bool load, int audibleradius); 401 void registermusic(char *name); 402 void mutesound(int n, int off); 403 void unmuteallsounds(); 404 int soundmuted(int n); 405 406 // cleanup 407 void soundcleanup(); 408 void clearworldsounds(bool fullclean = true); 409 void mapsoundreset(); 410 void stopsound(); 411 412 // music handling 413 void music(char *name, int millis, char *cmd); 414 void musicpreload(int id); 415 void musicsuggest(int id, int millis, bool rndofs); 416 void musicfadeout(int id); 417 void setmusicvol(int musicvol); 418 419 // sound handling 420 location *_playsound(int n, const worldobjreference &r, int priority, float offset = 0.0f, bool loop = false); 421 void playsound(int n, int priority = SP_NORMAL); 422 void playsound(int n, class physent *p, int priority = SP_NORMAL); 423 void playsound(int n, struct entity *e, int priority = SP_NORMAL); 424 void playsound(int n, const vec *v, int priority = SP_NORMAL); 425 void playsoundname(char *s, const vec *loc, int vol); 426 void playsoundc(int n, physent *p = NULL, int priority = SP_NORMAL); 427 void sound(int n); 428 int findsound(char *name, int vol, vector<soundconfig> &sounds); 429 void detachsounds(class playerent *owner); 430 431 // update 432 void updateplayerfootsteps(class playerent *p); 433 location *updateloopsound(int sound, bool active, float vol = 1.0f); 434 void updateaudio(); 435 436 // misc 437 void writesoundconfig(stream *f); 438 }; 439 440 void alclearerr(); 441 bool alerr(bool msg = true, int line = 0); 442 #define ALERR alerr(true, __LINE__) 443 444 extern vector<soundconfig> gamesounds, mapsounds; 445 extern ov_callbacks oggcallbacks; 446 extern int soundvol; 447 extern int audiodebug; 448 449 extern audiomanager audiomgr; 450 451 #endif //#ifndef STANDALONE 452