diff --git a/source/src/audiomanager.cpp b/source/src/audiomanager.cpp index 4be3e8f2..a309b8bb 100644 --- a/source/src/audiomanager.cpp +++ b/source/src/audiomanager.cpp @@ -96,8 +96,6 @@ void audiomanager::initsound() } } -cvector musics; - void audiomanager::music(char *name, char *millis, char *cmd) { if(nosound) return; @@ -164,15 +162,6 @@ void audiomanager::registermusic(char *name) musics.add(newstring(name)); } -int findsound(char *name, int vol, vector &sounds) -{ - loopv(sounds) - { - if(!strcmp(sounds[i].buf->name, name) && (!vol || sounds[i].vol==vol)) return i; - } - return -1; -} - int audiomanager::addsound(char *name, int vol, int maxuses, bool loop, vector &sounds, bool load) { if(nosound) return -1; @@ -191,6 +180,15 @@ int audiomanager::addsound(char *name, int vol, int maxuses, bool loop, vector &sounds) +{ + loopv(sounds) + { + if(!strcmp(sounds[i].buf->name, name) && (!vol || sounds[i].vol==vol)) return i; + } + return -1; +} + void audiomanager::preloadmapsound(entity &e) { if(e.type!=SOUND || !mapsounds.inrange(e.attr1)) return; @@ -333,12 +331,7 @@ location *audiomanager::updateloopsound(int sound, bool active, float vol) VARP(mapsoundrefresh, 0, 10, 1000); -void unmuteallsounds() -{ - loopv(gamesounds) gamesounds[i].muted = false; -} - -void mutesound(int n, int off) +void audiomanager::mutesound(int n, int off) { bool mute = (off == 0); if(!gamesounds.inrange(n)) @@ -349,15 +342,16 @@ void mutesound(int n, int off) gamesounds[n].muted = mute; } -int soundmuted(int n) +void audiomanager::unmuteallsounds() +{ + loopv(gamesounds) gamesounds[i].muted = false; +} + +int audiomanager::soundmuted(int n) { return gamesounds.inrange(n) && gamesounds[n].muted ? 1 : 0; } -COMMAND(unmuteallsounds, ARG_NONE); -COMMAND(mutesound, ARG_2INT); -COMMAND(soundmuted, ARG_1EXP); - void audiomanager::writesoundconfig(FILE *f) { loopv(gamesounds) if(gamesounds[i].muted) fprintf(f, "mutesound %d\n", i); @@ -372,7 +366,7 @@ void voicecom(char *sound, char *text) if(!last || lastmillis-last > 2000) { s_sprintfd(soundpath)("voicecom/%s", sound); - int s = findsound(soundpath, 0, gamesounds); + int s = audiomgr.findsound(soundpath, 0, gamesounds); if(s < 0 || s < S_AFFIRMATIVE || s > S_NICESHOT) return; audiomgr.playsound(s, SP_HIGH); if(s == S_NICESHOT) // public @@ -608,9 +602,6 @@ void audiomanager::updateaudio() alcProcessContext(context); } -audiomanager audiomgr; - - // binding of sounds to the 3D world // camera @@ -713,16 +704,37 @@ bool staticreference::operator==(const worldobjreference &other) return type==other.type && pos==((staticreference &)other).pos; } -// cli interface +// instance -void sound(int n) { audiomgr.playsound(n); } -COMMAND(sound, ARG_1INT); +audiomanager audiomgr; -void applymapsoundchanges() { audiomgr.applymapsoundchanges(); } -COMMANDN(applymapsoundchanges, applymapsoundchanges, ARG_NONE); +COMMANDF(sound, ARG_1INT, (int n) +{ + audiomgr.playsound(n); +}); -void mapsoundreset() { audiomgr.mapsoundreset(); } -COMMAND(mapsoundreset, ARG_NONE); +COMMANDF(applymapsoundchanges, ARG_NONE, (){ + audiomgr.applymapsoundchanges(); +}); + +COMMANDF(unmuteallsounds, ARG_NONE, () { + audiomgr.unmuteallsounds(); +}); + +COMMANDF(mutesound, ARG_2INT, (int n, int off) +{ + audiomgr.mutesound(n, off); +}); + +ICOMMANDF(soundmuted, ARG_1EXP, (int n) +{ + return audiomgr.soundmuted(n); +}); + +COMMANDF(mapsoundreset, ARG_NONE, () +{ + audiomgr.mapsoundreset(); +}); VARF(soundchannels, 4, 32, 1024, { if(!audiomgr.nosound) scheduler.init(); }); @@ -731,14 +743,23 @@ VARFP(soundvol, 0, 128, 255, if(!audiomgr.nosound) alListenerf(AL_GAIN, soundvol/255.0f); }); -void registersound(char *name, char *vol, char *loop) { audiomgr.addsound(name, atoi(vol), -1, atoi(loop) != 0, gamesounds, true); } -COMMAND(registersound, ARG_4STR); +COMMANDF(registersound, ARG_4STR, (char *name, char *vol, char *loop) +{ + audiomgr.addsound(name, atoi(vol), -1, atoi(loop) != 0, gamesounds, true); +}); -void mapsound(char *name, char *maxuses) { audiomgr.addsound(name, 255, atoi(maxuses), true, mapsounds, false); } -COMMAND(mapsound, ARG_3STR); +COMMANDF(mapsound, ARG_2STR, (char *name, char *maxuses) +{ + audiomgr.addsound(name, 255, atoi(maxuses), true, mapsounds, false); +}); -void registermusic(char *name) { audiomgr.registermusic(name); } -COMMAND(registermusic, ARG_1STR); +COMMANDF(registermusic, ARG_1STR, (char *name) +{ + audiomgr.registermusic(name); +}); + +COMMANDF(music, ARG_3STR, (char *name, char *millis, char *cmd) +{ + audiomgr.music(name, millis, cmd); +}); -void music(char *name, char *millis, char *cmd) { audiomgr.music(name, millis, cmd); } -COMMAND(music, ARG_3STR); \ No newline at end of file diff --git a/source/src/command.h b/source/src/command.h index 017e746c..e8ecdfc7 100644 --- a/source/src/command.h +++ b/source/src/command.h @@ -91,6 +91,8 @@ enum { IEXC_CORE = 0, IEXC_CFG, IEXC_PROMPT, IEXC_MAPCFG, IEXC_NUM }; // script // nasty macros for registering script functions, abuses globals to avoid excessive infrastructure #define COMMANDN(name, fun, nargs) static bool __dummy_##fun = addcommand(#name, (void (*)())fun, nargs) #define COMMAND(name, nargs) COMMANDN(name, name, nargs) +#define COMMANDF(name, nargs, inlinefunc) static void __dummy_##name ##inlinefunc ; COMMANDN(#name, __dummy_##name, nargs); +#define ICOMMANDF(name, nargs, inlinefunc) static int __dummy_##name ##inlinefunc ; COMMANDN(#name, __dummy_##name, nargs); #define VARP(name, min, cur, max) int name = variable(#name, min, cur, max, &name, NULL, true) #define VAR(name, min, cur, max) int name = variable(#name, min, cur, max, &name, NULL, false) diff --git a/source/src/oggstream.cpp b/source/src/oggstream.cpp index bd078bd3..3cd03ae0 100644 --- a/source/src/oggstream.cpp +++ b/source/src/oggstream.cpp @@ -20,7 +20,6 @@ ov_callbacks oggcallbacks = (long (*)(void *)) ftell }; - // ogg audio streaming oggstream::oggstream() : valid(false), isopen(false), src(NULL) diff --git a/source/src/sound.h b/source/src/sound.h index ebe8c087..df4606b0 100644 --- a/source/src/sound.h +++ b/source/src/sound.h @@ -1,4 +1,5 @@ // hardcoded sounds, defined in sounds.cfg + enum { S_JUMP = 0, @@ -56,7 +57,17 @@ enum S_NULL }; +// hardcoded music + +enum +{ + M_FLAGGRAB = 0, + M_LASTMINUTE1, + M_LASTMINUTE2 +}; + // sound priorities + enum { SP_LOW = 0, @@ -65,26 +76,20 @@ enum SP_HIGHEST }; -// hardcoded music -enum -{ - M_FLAGGRAB = 0, - M_LASTMINUTE1, - M_LASTMINUTE2 -}; - // owner of an OpenAL source, used as callback interface -struct sourceowner -{ - virtual ~sourceowner() {} - virtual void onsourcereassign(struct source *s) = 0; -}; +class sourceowner +{ +public: + virtual ~sourceowner() {} + virtual void onsourcereassign(class source *s) = 0; +}; // represents an OpenAL source, an audio emitter in the 3D world -struct source +class source { +public: ALuint id; sourceowner *owner; @@ -127,8 +132,9 @@ struct source // represents an OpenAL sound buffer -struct sbuffer +class sbuffer { +public: ALuint id; const char *name; @@ -141,16 +147,18 @@ struct sbuffer // buffer storage -struct bufferhashtable : hashtable +class bufferhashtable : public hashtable { +public: virtual ~bufferhashtable(); virtual sbuffer *find(char *name); }; -// manages audio channels +// manages sources -struct sourcescheduler +class sourcescheduler { +public: vector sources; sourcescheduler(); @@ -163,8 +171,9 @@ struct sourcescheduler // audio streaming -struct oggstream : sourceowner +class oggstream : sourceowner { +public: string name; bool valid; @@ -217,8 +226,10 @@ struct soundconfig }; -struct worldobjreference +class worldobjreference { +public: + enum worldobjtype { WR_CAMERA, WR_PHYSENT, WR_ENTITY, WR_STATICPOS }; int type; @@ -233,45 +244,51 @@ struct worldobjreference virtual void detach() {} }; -struct camerareference : worldobjreference + +class camerareference : public worldobjreference { - camerareference(); - worldobjreference *clone() const; - const vec ¤tposition() const; - bool nodistance(); - bool operator==(const worldobjreference &other); +public: + camerareference(); + + worldobjreference *clone() const; + const vec ¤tposition() const; + bool nodistance(); + bool operator==(const worldobjreference &other); }; -struct physentreference : worldobjreference + +class physentreference : public worldobjreference { +public: struct physent *phys; physentreference(physent *ref); - worldobjreference *clone() const; const vec ¤tposition() const; bool nodistance(); bool operator==(const worldobjreference &other); }; -struct entityreference : worldobjreference + +struct entityreference : public worldobjreference { +public: struct entity *ent; entityreference(entity *ref); - worldobjreference *clone() const; const vec ¤tposition() const; bool nodistance(); bool operator==(const worldobjreference &other); }; -struct staticreference : worldobjreference + +struct staticreference : public worldobjreference { +public: vec pos; staticreference(const vec &ref); - worldobjreference *clone() const; const vec ¤tposition() const; bool nodistance(); @@ -279,8 +296,9 @@ struct staticreference : worldobjreference }; -struct location : sourceowner +class location : sourceowner { +public: soundconfig *cfg; source *src; worldobjreference *ref; @@ -302,6 +320,7 @@ struct location : sourceowner void drop(); }; + struct locvector : vector { virtual ~locvector() {} @@ -314,12 +333,14 @@ struct locvector : vector void deleteworldobjsounds(); }; + // audio interface to the engine struct audiomanager { bool nosound; float currentpitch; + cvector musics; ALCdevice *device; ALCcontext *context; @@ -330,35 +351,48 @@ struct audiomanager audiomanager(); + // init + void initsound(); + void soundcleanup(); + void preloadmapsound(entity &e); + void preloadmapsounds(); + void applymapsoundchanges(); + + // setup + int addsound(char *name, int vol, int maxuses, bool loop, vector &sounds, bool load); + void registermusic(char *name); + + // cleanup + void detachsounds(struct playerent *owner); + void clearworldsounds(bool fullclean = true); + void mapsoundreset(); + void stopsound(); + + // music handling + void music(char *name, char *millis, char *cmd); + void musicsuggest(int id, int millis, bool rndofs); + void musicfadeout(int id); + + // sound handling location *_playsound(int n, const worldobjreference &r, int priority, float offset = 0.0f, bool loop = false); void playsound(int n, int priority = SP_NORMAL); void playsound(int n, struct physent *p, int priority = SP_NORMAL); void playsound(int n, struct entity *e, int priority = SP_NORMAL); void playsound(int n, const vec *v, int priority = SP_NORMAL); void playsoundname(char *s, const vec *loc, int vol); - void sound(int n); void playsoundc(int n, physent *p = NULL); - void stopsound(); - - void initsound(); - void soundcleanup(); - void mapsoundreset(); - void clearworldsounds(bool fullclean = true); - - void music(char *name, char *millis, char *cmd); - void musicsuggest(int id, int millis, bool rndofs); - void musicfadeout(int id); - void registermusic(char *name); - int addsound(char *name, int vol, int maxuses, bool loop, vector &sounds, bool load); + void sound(int n); + int findsound(char *name, int vol, vector &sounds); + void mutesound(int n, int off); + void unmuteallsounds(); + int soundmuted(int n); + // update void updateplayerfootsteps(struct playerent *p); location *updateloopsound(int sound, bool active, float vol = 1.0f); void updateaudio(); - void detachsounds(struct playerent *owner); - void preloadmapsound(entity &e); - void preloadmapsounds(); - void applymapsoundchanges(); + // misc void writesoundconfig(FILE *f); };