Collect warnings during load_world() and issue a warning at the end. Most, but not all warnings already printed a message - which usually scrolls out of the console quite fast. The collected value is also given back by the loadmap command, which allows batch editing scripts for maps stop at problematic maps. Mapsound errors are not detected, if soundvol is zero. Missing textures are not flagged, if notexture is set. The error code is ored together from those elements: 0x0000001 entity attribute overflow One or more map entities had attribute values, that are no longer supported with map format 10. Rework manually. 0x0000010 map decoder error Indicates a damaged map file. 0x0000100 world error -1 Map is completely solid. Very funny. 0x0000200 world error -2 Map border is not solid. Fix manually. 0x0001000 missing skymap texture files 0x0002000 missing world texture files (only if no notexture is set) 0x0004000 missing mapmodel files 0x0008000 missing mapsound files 0x0010000 bad mapsound command in map config 0x0020000 bad mapmodel command in map config 0x0040000 bad texture command in map config 0x0080000 bad loadnotexture command in map config 0x0100000 error during loading of mapmodels (see earlier console output) 0x1000000 out of range integer value in map config (for example, "fog 0") 0x2000000 out of range float value in map config 0x4000000 generic cubescript error in map config The command loadmap is now also available for non-debug builds. DOCREF loadmap
453 lines
10 KiB
C++
453 lines
10 KiB
C++
// hardcoded sounds, defined in sounds.cfg
|
|
|
|
|
|
enum
|
|
{ // To avoid a lot of work, possible bugs and allow backward compatibility for players own custom
|
|
// cfg files, it's best not to change the listed sound order, instead, just add to it.
|
|
S_JUMP = 0,
|
|
S_SOFTLAND, S_HARDLAND,
|
|
S_BULLETAIR1, S_BULLETAIR2, S_BULLETHIT, S_BULLETWATERHIT,
|
|
S_KNIFE,
|
|
S_PISTOL, S_RPISTOL,
|
|
S_CARBINE, S_RCARBINE,
|
|
S_SHOTGUN, S_RSHOTGUN,
|
|
S_SUBGUN, S_RSUBGUN,
|
|
S_SNIPER, S_RSNIPER,
|
|
S_ASSAULT, S_RASSAULT,
|
|
S_ITEMAMMO, S_ITEMHEALTH,
|
|
S_ITEMARMOUR, S_ITEMAKIMBO,
|
|
S_NOAMMO, S_AKIMBOOUT,
|
|
S_PAIN1, S_PAIN2, S_PAIN3, S_PAIN4, S_PAIN5, S_PAIN6,
|
|
S_DIE1, S_DIE2,
|
|
S_FEXPLODE,
|
|
S_SPLASH1, S_SPLASH2,
|
|
S_FLAGDROP, S_FLAGPICKUP, S_FLAGRETURN, S_FLAGSCORE,
|
|
S_GRENADEPULL, S_GRENADETHROW, S_GRENADEBOUNCE1, S_GRENADEBOUNCE2, S_RAKIMBO,
|
|
S_GUNCHANGE,
|
|
S_HITSOUND,
|
|
S_GIB, S_HEADSHOT,
|
|
S_CALLVOTE, S_VOTEPASS, S_VOTEFAIL,
|
|
S_FOOTSTEPS, S_FOOTSTEPSCROUCH, S_WATERFOOTSTEPS, S_WATERFOOTSTEPSCROUCH,
|
|
S_CROUCH, S_UNCROUCH,
|
|
S_MENUSELECT, S_MENUENTER,
|
|
S_UNDERWATER,
|
|
S_TINNITUS,
|
|
// begin: voicecoms
|
|
S_AFFIRMATIVE,
|
|
S_ALLRIGHTSIR,
|
|
S_COMEONMOVE,
|
|
S_COMINGINWITHTHEFLAG,
|
|
S_COVERME,
|
|
S_DEFENDTHEFLAG,
|
|
S_ENEMYDOWN,
|
|
S_GOGETEMBOYS,
|
|
S_GOODJOBTEAM,
|
|
S_IGOTONE,
|
|
S_IMADECONTACT,
|
|
S_IMATTACKING,
|
|
S_IMONDEFENSE,
|
|
S_IMONYOURTEAMMAN,
|
|
S_NEGATIVE,
|
|
S_NOCANDO,
|
|
S_RECOVERTHEFLAG,
|
|
S_SORRY,
|
|
S_SPREADOUT,
|
|
S_STAYHERE,
|
|
S_STAYTOGETHER,
|
|
S_THERESNOWAYSIR,
|
|
S_WEDIDIT,
|
|
S_YES,
|
|
S_ONTHEMOVE1,
|
|
S_ONTHEMOVE2,
|
|
S_GOTURBACK,
|
|
S_GOTUCOVERED,
|
|
S_INPOSITION1,
|
|
S_INPOSITION2,
|
|
S_REPORTIN,
|
|
S_NICESHOT, // begin: public
|
|
S_THANKS1,
|
|
S_THANKS2,
|
|
S_AWESOME1,
|
|
S_AWESOME2,
|
|
S_ITEMHELMET, // begin: Sounds for AssaultCube v1.1.0.4 onwards
|
|
S_HEARTBEAT,
|
|
S_KTFSCORE,
|
|
S_NULL
|
|
};
|
|
|
|
// hardcoded music
|
|
|
|
enum
|
|
{
|
|
M_FLAGGRAB = 0,
|
|
M_LASTMINUTE1,
|
|
M_LASTMINUTE2
|
|
};
|
|
|
|
// sound priorities
|
|
|
|
enum
|
|
{
|
|
SP_LOW = 0,
|
|
SP_NORMAL,
|
|
SP_HIGH,
|
|
SP_HIGHEST
|
|
};
|
|
|
|
#ifndef STANDALONE
|
|
|
|
// owner of an OpenAL source, used as callback interface
|
|
|
|
class sourceowner
|
|
{
|
|
public:
|
|
virtual ~sourceowner() {}
|
|
virtual void onsourcereassign(class source *s) = 0;
|
|
};
|
|
|
|
// represents an OpenAL source, an audio emitter in the 3D world
|
|
|
|
class source
|
|
{
|
|
public:
|
|
ALuint id;
|
|
|
|
sourceowner *owner;
|
|
bool locked, valid;
|
|
int priority;
|
|
|
|
source();
|
|
~source();
|
|
|
|
void lock();
|
|
void unlock();
|
|
void reset();
|
|
void init(sourceowner *o);
|
|
void onreassign();
|
|
|
|
bool generate();
|
|
bool delete_();
|
|
bool buffer(ALuint buf_id);
|
|
bool looping(bool enable);
|
|
bool queuebuffers(ALsizei n, const ALuint *buffer_ids);
|
|
bool unqueueallbuffers();
|
|
bool gain(float g);
|
|
bool pitch(float p);
|
|
bool position(const vec &pos);
|
|
bool position(float x, float y, float z);
|
|
bool velocity(float x, float y, float z);
|
|
vec position();
|
|
bool sourcerelative(bool enable);
|
|
int state();
|
|
bool secoffset(float secs);
|
|
float secoffset();
|
|
bool playing();
|
|
bool play();
|
|
bool stop();
|
|
bool rewind();
|
|
|
|
void printposition();
|
|
};
|
|
|
|
|
|
// represents an OpenAL sound buffer
|
|
|
|
class sbuffer
|
|
{
|
|
public:
|
|
ALuint id;
|
|
const char *name;
|
|
|
|
sbuffer();
|
|
~sbuffer();
|
|
|
|
bool load(bool trydl = false);
|
|
void unload();
|
|
};
|
|
|
|
// buffer storage
|
|
|
|
class bufferhashtable : public hashtable<char *, sbuffer>
|
|
{
|
|
public:
|
|
virtual ~bufferhashtable();
|
|
virtual sbuffer *find(char *name);
|
|
};
|
|
|
|
// manages available sources, abstracts audio channels
|
|
// is a singleton
|
|
|
|
class sourcescheduler
|
|
{
|
|
int numsoundchannels;
|
|
static sourcescheduler *inst;
|
|
vector<source *> sources;
|
|
|
|
public:
|
|
sourcescheduler();
|
|
static sourcescheduler &instance(); // singleton access
|
|
|
|
void init(int numsoundchannels);
|
|
void reset();
|
|
source *newsource(int priority, const vec &o);
|
|
void releasesource(source *src);
|
|
};
|
|
|
|
// audio streaming
|
|
|
|
class oggstream : sourceowner
|
|
{
|
|
public:
|
|
string name;
|
|
bool valid;
|
|
|
|
// file stream
|
|
OggVorbis_File oggfile;
|
|
bool isopen;
|
|
vorbis_info *info;
|
|
double totalseconds;
|
|
static const int BUFSIZE = 1024 * 512; // 512kb buffer
|
|
|
|
// OpenAL resources
|
|
ALuint bufferids[2];
|
|
source *src;
|
|
ALenum format;
|
|
|
|
// settings
|
|
float volume, gain;
|
|
int startmillis, endmillis, startfademillis, endfademillis;
|
|
bool looping;
|
|
|
|
oggstream();
|
|
~oggstream();
|
|
|
|
void reset();
|
|
bool open(const char *f);
|
|
void onsourcereassign(source *s);
|
|
bool stream(ALuint bufid);
|
|
bool update();
|
|
bool playing();
|
|
void updategain();
|
|
void setgain(float g);
|
|
void setvolume(float v);
|
|
void fadein(int startmillis, int fademillis);
|
|
void fadeout(int endmillis, int fademillis);
|
|
bool playback(bool looping = false);
|
|
void seek(double offset);
|
|
};
|
|
|
|
|
|
struct soundconfig
|
|
{
|
|
sbuffer *buf; // sound data
|
|
int vol; // volume
|
|
int uses, maxuses; // track uses
|
|
bool loop;
|
|
bool muted;
|
|
int audibleradius;
|
|
|
|
enum distancemodel
|
|
{
|
|
DM_DEFAULT = 0, // use openal distance model
|
|
DM_LINEAR // custom linear model (used in conjunction with audibleradius)
|
|
};
|
|
|
|
distancemodel model;
|
|
|
|
soundconfig(sbuffer *b, int vol, int maxuses, bool loop, int audibleradius);
|
|
void onattach();
|
|
void ondetach();
|
|
};
|
|
|
|
|
|
class worldobjreference
|
|
{
|
|
public:
|
|
|
|
enum worldobjtype { WR_CAMERA, WR_PHYSENT, WR_ENTITY, WR_STATICPOS };
|
|
int type;
|
|
|
|
worldobjreference(int t) : type(t) {}
|
|
virtual ~worldobjreference() {}
|
|
virtual worldobjreference *clone() const = 0;
|
|
virtual const vec ¤tposition() const = 0;
|
|
virtual bool nodistance() = 0;
|
|
virtual bool operator==(const worldobjreference &other) = 0;
|
|
virtual bool operator!=(const worldobjreference &other) { return !(*this==other); }
|
|
virtual void attach() {}
|
|
virtual void detach() {}
|
|
};
|
|
|
|
|
|
class camerareference : public worldobjreference
|
|
{
|
|
public:
|
|
camerareference();
|
|
|
|
worldobjreference *clone() const;
|
|
const vec ¤tposition() const;
|
|
bool nodistance();
|
|
bool operator==(const worldobjreference &other);
|
|
};
|
|
|
|
|
|
class physentreference : public worldobjreference
|
|
{
|
|
public:
|
|
class physent *phys;
|
|
|
|
physentreference(physent *ref);
|
|
worldobjreference *clone() const;
|
|
const vec ¤tposition() const;
|
|
bool nodistance();
|
|
bool operator==(const worldobjreference &other);
|
|
};
|
|
|
|
|
|
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 : public worldobjreference
|
|
{
|
|
public:
|
|
vec pos;
|
|
|
|
staticreference(const vec &ref);
|
|
worldobjreference *clone() const;
|
|
const vec ¤tposition() const;
|
|
bool nodistance();
|
|
bool operator==(const worldobjreference &other);
|
|
};
|
|
|
|
|
|
class location : sourceowner
|
|
{
|
|
public:
|
|
soundconfig *cfg;
|
|
source *src;
|
|
worldobjreference *ref;
|
|
|
|
bool stale;
|
|
int playmillis;
|
|
|
|
location(int sound, const worldobjreference &r, int priority = SP_NORMAL);
|
|
~location();
|
|
void attachworldobjreference(const worldobjreference &r);
|
|
void evaluateworldobjref();
|
|
void onsourcereassign(source *s);
|
|
void updatepos();
|
|
void update();
|
|
void play(bool loop = false);
|
|
void pitch(float p);
|
|
bool setvolume(float v);
|
|
void offset(float secs);
|
|
float offset();
|
|
void drop();
|
|
};
|
|
|
|
|
|
struct locvector : vector<location *>
|
|
{
|
|
virtual ~locvector() {}
|
|
|
|
location *find(int sound, worldobjreference *ref/* = NULL*/, const vector<soundconfig> &soundcollection /* = gamesounds*/);
|
|
void delete_(int i);
|
|
void replaceworldobjreference(const worldobjreference &oldr, const worldobjreference &newr);
|
|
void updatelocations();
|
|
void forcepitch(float pitch);
|
|
void deleteworldobjsounds();
|
|
};
|
|
|
|
|
|
// audio interface to the engine
|
|
|
|
class audiomanager
|
|
{
|
|
bool nosound;
|
|
float currentpitch;
|
|
vector<char *> musics;
|
|
ALCdevice *device;
|
|
ALCcontext *context;
|
|
|
|
bufferhashtable bufferpool;
|
|
oggstream *gamemusic;
|
|
|
|
public:
|
|
|
|
locvector locations;
|
|
|
|
audiomanager();
|
|
|
|
// init & setup
|
|
void initsound();
|
|
bool preloadmapsound(entity &e, bool trydl = false);
|
|
bool preloadmapsounds(bool trydl = false);
|
|
void applymapsoundchanges();
|
|
|
|
// configuration
|
|
void setchannels(int num);
|
|
void setlistenervol(int vol);
|
|
int addsound(char *name, int vol, int maxuses, bool loop, vector<soundconfig> &sounds, bool load, int audibleradius);
|
|
void registermusic(char *name);
|
|
void mutesound(int n, int off);
|
|
void unmuteallsounds();
|
|
int soundmuted(int n);
|
|
|
|
// cleanup
|
|
void soundcleanup();
|
|
void clearworldsounds(bool fullclean = true);
|
|
void mapsoundreset();
|
|
void stopsound();
|
|
|
|
// music handling
|
|
void music(char *name, int millis, char *cmd);
|
|
void musicpreload(int id);
|
|
void musicsuggest(int id, int millis, bool rndofs);
|
|
void musicfadeout(int id);
|
|
void setmusicvol(int musicvol);
|
|
|
|
// 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, class 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 playsoundc(int n, physent *p = NULL, int priority = SP_NORMAL);
|
|
void sound(int n);
|
|
int findsound(char *name, int vol, vector<soundconfig> &sounds);
|
|
void detachsounds(class playerent *owner);
|
|
|
|
// update
|
|
void updateplayerfootsteps(class playerent *p);
|
|
location *updateloopsound(int sound, bool active, float vol = 1.0f);
|
|
void updateaudio();
|
|
|
|
// misc
|
|
void writesoundconfig(stream *f);
|
|
};
|
|
|
|
void alclearerr();
|
|
bool alerr(bool msg = true, int line = 0, const char *s = NULL, ...) PRINTFARGS(3, 4);
|
|
#define ALERR alerr(true, __LINE__)
|
|
#define ALERRF(fmt, ...) alerr(true, __LINE__, fmt, __VA_ARGS__)
|
|
|
|
extern vector<soundconfig> gamesounds, mapsounds;
|
|
extern ov_callbacks oggcallbacks;
|
|
extern int soundvol;
|
|
extern int audiodebug;
|
|
|
|
extern audiomanager audiomgr;
|
|
|
|
#endif //#ifndef STANDALONE
|