2024-01-07 19:47:58 +01:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
Copyright (C) 2024 the OpenMoHAA team
|
|
|
|
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
2024-08-09 20:30:35 +02:00
|
|
|
#include "snd_local.h"
|
|
|
|
#include "snd_openal_new.h"
|
|
|
|
#include "client.h"
|
|
|
|
#include "cl_ui.h"
|
2024-01-07 19:47:58 +01:00
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
vec3_t origin;
|
|
|
|
vec3_t velocity;
|
|
|
|
sfx_t *sfx;
|
|
|
|
int mergeFrame;
|
|
|
|
} loopSound_t;
|
|
|
|
|
|
|
|
qboolean s_bLastInitSound = qfalse;
|
|
|
|
qboolean s_bSoundStarted = qfalse;
|
|
|
|
qboolean s_bSoundPaused = qfalse;
|
|
|
|
qboolean s_bTryUnpause = qfalse;
|
|
|
|
int s_iListenerNumber = 0;
|
|
|
|
float s_fAmbientVolume = 1.f;
|
|
|
|
|
|
|
|
int number_of_sfx_infos = 0;
|
|
|
|
|
|
|
|
cvar_t *s_volume;
|
|
|
|
cvar_t *s_loadas8bit;
|
|
|
|
cvar_t *s_khz;
|
|
|
|
cvar_t *s_show;
|
|
|
|
cvar_t *s_testsound;
|
|
|
|
cvar_t *s_separation;
|
|
|
|
cvar_t *s_musicVolume;
|
|
|
|
cvar_t *s_ambientVolume;
|
|
|
|
|
|
|
|
sfx_info_t sfx_infos[MAX_SFX_INFOS];
|
|
|
|
|
|
|
|
sfx_t s_knownSfx[MAX_SFX];
|
|
|
|
int s_numSfx;
|
|
|
|
|
|
|
|
s_entity_t s_entity[MAX_GENTITIES];
|
|
|
|
|
|
|
|
static int s_registrationSequence;
|
|
|
|
static qboolean s_inRegistration;
|
|
|
|
|
|
|
|
cvar_t *s_mixPreStep;
|
|
|
|
cvar_t *s_dialogscale;
|
|
|
|
|
|
|
|
int numLoopSounds;
|
|
|
|
loopSound_t loopSounds[MAX_LOOP_SOUNDS];
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_SoundInfo_f
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_SoundInfo_f()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
S_PrintInfo();
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_SoundDump_f
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_SoundDump_f()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
S_DumpInfo();
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_Init
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_Init(qboolean full_startup)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
int iStart, iEnd;
|
|
|
|
cvar_t *cv;
|
|
|
|
|
|
|
|
Com_Printf("------- Sound Initialization (%s) -------\n", full_startup ? "full" : "partial");
|
|
|
|
|
|
|
|
iStart = Sys_Milliseconds();
|
|
|
|
|
|
|
|
s_volume = Cvar_Get("s_volume", "0.9", CVAR_ARCHIVE);
|
|
|
|
s_musicVolume = Cvar_Get("s_musicvolume", "0.9", CVAR_ARCHIVE);
|
|
|
|
s_ambientVolume = Cvar_Get("s_ambientvolume", "1.00", CVAR_ARCHIVE);
|
|
|
|
s_separation = Cvar_Get("s_separation", "0.5", CVAR_ARCHIVE);
|
|
|
|
s_khz = Cvar_Get("s_khz", "11", CVAR_ARCHIVE | CVAR_SOUND_LATCH);
|
|
|
|
s_loadas8bit = Cvar_Get("s_loadas8bit", "0", CVAR_ARCHIVE | CVAR_LATCH);
|
|
|
|
s_mixPreStep = Cvar_Get("s_mixPreStep", "0.05", CVAR_ARCHIVE);
|
|
|
|
s_show = Cvar_Get("s_show", "0", CVAR_CHEAT);
|
|
|
|
s_testsound = Cvar_Get("s_testsound", "0", CVAR_CHEAT);
|
|
|
|
s_dialogscale = Cvar_Get("s_dialogscale", "1", CVAR_ARCHIVE);
|
|
|
|
s_bLastInitSound = false;
|
|
|
|
|
|
|
|
cv = Cvar_Get("s_initsound", "1", 0);
|
|
|
|
|
|
|
|
if (cv->integer) {
|
|
|
|
Cmd_AddCommand("play", S_Play);
|
|
|
|
Cmd_AddCommand("soundlist", S_SoundList);
|
|
|
|
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
|
|
|
|
Cmd_AddCommand("sounddump", S_SoundDump_f);
|
|
|
|
|
|
|
|
if (S_Driver_Init()) {
|
|
|
|
s_bLastInitSound = true;
|
|
|
|
s_bSoundStarted = true;
|
|
|
|
|
|
|
|
if (full_startup) {
|
|
|
|
s_numSfx = 0;
|
|
|
|
S_StopAllSounds(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
S_FindName("***DEFAULT***", -1);
|
|
|
|
S_SoundInfo_f();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Com_Printf("Sound Not Initializing.\n");
|
|
|
|
s_bSoundStarted = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
iEnd = Sys_Milliseconds();
|
|
|
|
Com_Printf("------- Sound Initialization Complete ------- %i ms\n", iEnd - iStart);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_Shutdown
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_Shutdown(qboolean full_shutdown)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
int i;
|
|
|
|
sfx_t *sfx;
|
|
|
|
|
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Printf("------- Sound Shutdown (%s) -------\n", full_shutdown ? "full" : "partial");
|
|
|
|
|
|
|
|
S_Driver_Shutdown();
|
|
|
|
s_bSoundStarted = false;
|
|
|
|
|
|
|
|
Cmd_RemoveCommand("play");
|
|
|
|
Cmd_RemoveCommand("music");
|
|
|
|
Cmd_RemoveCommand("stopsound");
|
|
|
|
Cmd_RemoveCommand("soundlist");
|
|
|
|
Cmd_RemoveCommand("soundinfo");
|
|
|
|
|
|
|
|
if (full_shutdown) {
|
|
|
|
for (i = 0; i < s_numSfx; i++) {
|
|
|
|
sfx = &s_knownSfx[i];
|
|
|
|
|
|
|
|
if (sfx->name[0]) {
|
|
|
|
if (sfx->data) {
|
|
|
|
Z_Free(sfx->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
*sfx = {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s_numSfx = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Printf("------- Sound Shutdown Complete -------\n");
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_NameExists
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
qboolean S_NameExists(const char *name)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (strlen(name) >= MAX_RES_NAME) {
|
|
|
|
Com_DPrintf("Sound name too long: %s", name);
|
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < s_numSfx; i++) {
|
|
|
|
if (!strcmp(s_knownSfx[i].name, name)) {
|
|
|
|
return qtrue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-07 19:47:58 +01:00
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_FindName
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
sfx_t *S_FindName(const char *name, int sequenceNumber)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
int i;
|
|
|
|
sfx_t *sfx;
|
|
|
|
|
|
|
|
if (!name) {
|
|
|
|
Com_DPrintf("S_FindName: NULL\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!name[0]) {
|
|
|
|
Com_DPrintf("S_FindName: empty name\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strlen(name) >= MAX_RES_NAME) {
|
|
|
|
Com_DPrintf("Sound name too long: %s", name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < s_numSfx; i++) {
|
|
|
|
sfx = &s_knownSfx[i];
|
|
|
|
|
|
|
|
if (!strcmp(sfx->name, name)) {
|
|
|
|
if (sfx->registration_sequence != -1) {
|
|
|
|
sfx->registration_sequence = sequenceNumber;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sfx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sfx = &s_knownSfx[0];
|
|
|
|
|
|
|
|
for (i = 0; i < s_numSfx; i++) {
|
|
|
|
sfx = &s_knownSfx[i];
|
|
|
|
if (!sfx->name[0]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == s_numSfx) {
|
|
|
|
if (i == MAX_SFX) {
|
|
|
|
Com_Error(ERR_FATAL, "S_FindName: out of sfx_t");
|
|
|
|
}
|
|
|
|
|
2024-01-21 23:50:15 +01:00
|
|
|
sfx = &s_knownSfx[s_numSfx];
|
2024-01-08 20:07:26 +01:00
|
|
|
s_numSfx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*sfx = {};
|
|
|
|
// Fixed in OPM
|
|
|
|
// strcpy was used before
|
|
|
|
//strcpy(sfx->name, name);
|
|
|
|
Q_strncpyz(sfx->name, name, sizeof(sfx->name));
|
|
|
|
sfx->registration_sequence = sequenceNumber;
|
|
|
|
|
|
|
|
return sfx;
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_BeginRegistration
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_BeginRegistration()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
Com_Printf("------- Sound Begin Registration -------\n");
|
|
|
|
|
|
|
|
S_StopAllSounds(true);
|
|
|
|
|
|
|
|
++s_registrationSequence;
|
|
|
|
s_inRegistration = true;
|
|
|
|
s_knownSfx[0].registration_sequence = s_registrationSequence;
|
|
|
|
|
|
|
|
Com_Printf("------- Sound Begin Registration Complete -------\n");
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_DefaultSound
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_DefaultSound(sfx_t *sfx)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
sfx->data = NULL;
|
|
|
|
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_IsSoundRegistered
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
qboolean S_IsSoundRegistered(const char *name)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
char szCacheName[MAX_QPATH];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; name[i] && i < MAX_QPATH; i++) {
|
|
|
|
szCacheName[i] = tolower(name[i]);
|
|
|
|
}
|
|
|
|
szCacheName[i] = 0;
|
|
|
|
|
|
|
|
if (i >= MAX_QPATH) {
|
|
|
|
Com_Printf("Sound name exceeds MAX_QPATH\n");
|
|
|
|
return qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_NameExists(szCacheName);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_RegisterSound
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
sfxHandle_t S_RegisterSound(const char *name, int streamed, qboolean force_load)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
char szCacheName[MAX_QPATH];
|
|
|
|
sfx_t *sfx;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
Com_Printf("ERROR: Trying to register sound %s when soundsystem hasn't started.\n", name);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!name) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; name[i] && i < MAX_QPATH; i++) {
|
|
|
|
szCacheName[i] = tolower(name[i]);
|
|
|
|
}
|
|
|
|
szCacheName[i] = 0;
|
|
|
|
|
|
|
|
if (i >= MAX_QPATH) {
|
|
|
|
Com_Printf("Sound name exceeds MAX_QPATH\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
sfx = S_FindName(szCacheName, s_registrationSequence);
|
|
|
|
if (!sfx) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sfx->data) {
|
|
|
|
if (!S_LoadSound(sfx->name, sfx, streamed, force_load)) {
|
|
|
|
Com_DPrintf("Couldn't load sound: %s\n", sfx->name);
|
|
|
|
if (!S_LoadSound("sound/default.wav", sfx, streamed, 0)) {
|
|
|
|
Com_DPrintf("Couldn't load sound: sound/default.wav\n");
|
|
|
|
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sfx->iFlags &= ~SFX_FLAG_DEFAULT_SOUND;
|
|
|
|
sfx->sfx_info_index = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < number_of_sfx_infos; i++) {
|
|
|
|
if (!Q_stricmp(sfx->name, sfx_infos[i].name)) {
|
|
|
|
sfx->sfx_info_index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return sfx - s_knownSfx;
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_GetSoundTime
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
float S_GetSoundTime(sfxHandle_t handle)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
return s_knownSfx[handle].time_length;
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_EndRegistration
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_EndRegistration()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
int i;
|
|
|
|
sfx_t *sfx;
|
|
|
|
|
|
|
|
Com_Printf("------- Sound End Registration -------\n");
|
|
|
|
s_inRegistration = qfalse;
|
|
|
|
|
|
|
|
for (i = 0; i < s_numSfx; i++) {
|
|
|
|
sfx = &s_knownSfx[i];
|
|
|
|
|
|
|
|
if (!sfx->name[0]) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sfx->registration_sequence && sfx->registration_sequence != s_registrationSequence) {
|
|
|
|
if (sfx->data) {
|
|
|
|
Z_Free(sfx->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
*sfx = {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Printf("------- Sound End Registration Complete -------\n");
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_UpdateEntity
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (entityNum > MAX_GENTITIES) {
|
|
|
|
Com_Error(ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
VectorCopy(origin, s_entity[entityNum].position);
|
|
|
|
VectorCopy(vel, s_entity[entityNum].velocity);
|
|
|
|
s_entity[entityNum].use_listener = use_listener;
|
|
|
|
s_entity[entityNum].time = cl.serverTime;
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_SetGlobalAmbientVolumeLevel
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_SetGlobalAmbientVolumeLevel(float volume)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
s_fAmbientVolume = volume;
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_StartSound
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_StartSound(
|
|
|
|
const vec3_t origin,
|
|
|
|
int entnum,
|
|
|
|
int entchannel,
|
|
|
|
sfxHandle_t sfxHandle,
|
|
|
|
float volume,
|
|
|
|
float min_dist,
|
|
|
|
float pitch,
|
|
|
|
float maxDist,
|
|
|
|
int streamed
|
|
|
|
)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (s_show_sounds->integer > 0 && sfxHandle > 0 && sfxHandle < s_numSfx) {
|
|
|
|
Com_DPrintf("S_StartSound: %s\n", s_knownSfx[sfxHandle].name);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
if (s_show_sounds->integer > 0) {
|
|
|
|
Com_DPrintf("^~^~^ sound system not yet started\n");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (server_loading) {
|
|
|
|
if (s_show_sounds->integer > 0) {
|
|
|
|
Com_DPrintf("^~^~^ cannot start sounds while loading a server\n");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
|
|
|
|
Com_Error(ERR_DROP, "S_StartSound: handle %i out of range", sfxHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sfxHandle) {
|
|
|
|
if (s_show_sounds->integer > 0) {
|
|
|
|
Com_DPrintf("^~^~^ null handle\n");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entnum && (entchannel == CHAN_DIALOG || entchannel == CHAN_DIALOG_SECONDARY) && s_dialogscale->value > 0) {
|
|
|
|
volume *= s_dialogscale->value;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_Driver_StartSound(origin, entnum, entchannel, sfxHandle, volume, min_dist, pitch, maxDist, streamed);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_StartLocalSound
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_StartLocalSound(const char *sound_name, qboolean force_load)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
sfxHandle_t sfxHandle;
|
|
|
|
const char *name;
|
2024-01-16 20:27:56 +01:00
|
|
|
AliasListNode_t *pSoundAlias = NULL;
|
2024-01-08 20:07:26 +01:00
|
|
|
|
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sound_name) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
name = Alias_FindRandom(sound_name, &pSoundAlias);
|
|
|
|
if (!name) {
|
|
|
|
name = sound_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
|
|
|
|
|
|
|
|
if (!pSoundAlias) {
|
|
|
|
S_StartSound(NULL, s_iListenerNumber, CHAN_MENU, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_StartSound(
|
|
|
|
0,
|
|
|
|
s_iListenerNumber,
|
|
|
|
CHAN_MENU,
|
|
|
|
sfxHandle,
|
|
|
|
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
|
|
|
|
-1.0,
|
|
|
|
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
|
|
|
|
pSoundAlias->maxDist,
|
|
|
|
pSoundAlias->streamed
|
|
|
|
);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_StartLocalSoundChannel
|
|
|
|
|
|
|
|
Added in 2.0
|
|
|
|
Starts a local sound, with the specified channel
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_StartLocalSoundChannel(const char *sound_name, qboolean force_load, soundChannel_t channel)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
sfxHandle_t sfxHandle;
|
|
|
|
const char *name;
|
2024-03-03 18:53:22 +01:00
|
|
|
AliasListNode_t *pSoundAlias = NULL;
|
2024-01-08 20:07:26 +01:00
|
|
|
|
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sound_name) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
name = Alias_FindRandom(sound_name, &pSoundAlias);
|
|
|
|
if (!name) {
|
|
|
|
name = sound_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
|
|
|
|
|
|
|
|
if (!pSoundAlias) {
|
|
|
|
S_StartSound(NULL, s_iListenerNumber, channel, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_StartSound(
|
|
|
|
0,
|
|
|
|
s_iListenerNumber,
|
|
|
|
channel,
|
|
|
|
sfxHandle,
|
|
|
|
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
|
|
|
|
-1.0,
|
|
|
|
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
|
|
|
|
pSoundAlias->maxDist,
|
|
|
|
pSoundAlias->streamed
|
|
|
|
);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_StopAllSounds
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_StopAllSounds(qboolean stop_music)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Printf("------- S_StopAllSounds (%s) -------\n", stop_music ? "stop music" : "don't stop music");
|
|
|
|
|
|
|
|
// Tell the driver to stop all sounds
|
|
|
|
S_Driver_StopAllSounds(stop_music);
|
|
|
|
|
|
|
|
Com_Printf("------- S_StopAllSounds Complete-------\n");
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_ClearLoopingSounds
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_ClearLoopingSounds()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_Driver_ClearLoopingSounds();
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_AddLoopingSound
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_AddLoopingSound(
|
|
|
|
const vec3_t origin,
|
|
|
|
const vec3_t velocity,
|
|
|
|
sfxHandle_t sfxHandle,
|
|
|
|
float volume,
|
|
|
|
float min_dist,
|
|
|
|
float max_dist,
|
|
|
|
float pitch,
|
|
|
|
int flags
|
|
|
|
)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
|
|
|
|
Com_Error(ERR_DROP, "S_AddLoopingSound: handle %i out of range", sfxHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!sfxHandle) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_Driver_AddLoopingSound(origin, velocity, sfxHandle, volume, min_dist, max_dist, pitch, flags);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_Respatialize
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3])
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_Driver_Respatialize(entityNum, head, axis);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_Update
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_Update()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (server_loading) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_Driver_Update();
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_StopSound
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_StopSound(int entnum, int channel)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (channel == CHAN_AUTO) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_Driver_StopSound(entnum, channel);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_SetReverb
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_SetReverb(int reverb_type, float reverb_level)
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
if (!s_bSoundStarted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
S_Driver_SetReverb(reverb_type, reverb_level);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_Play
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_Play()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
int i;
|
|
|
|
char name[MAX_QPATH];
|
|
|
|
|
|
|
|
for (i = 1; i < Cmd_Argc(); i++) {
|
|
|
|
if (strrchr(Cmd_Argv(i), '.')) {
|
|
|
|
Q_strncpyz(name, Cmd_Argv(i), sizeof(name));
|
|
|
|
} else {
|
|
|
|
Com_sprintf(name, sizeof(name), "%s.wav", Cmd_Argv(1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
S_StartLocalSound(name, qfalse);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_SoundList
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_SoundList()
|
|
|
|
{
|
2024-01-08 20:07:26 +01:00
|
|
|
int i;
|
|
|
|
sfx_t *sfx;
|
|
|
|
int size;
|
|
|
|
int total = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < s_numSfx; i++) {
|
|
|
|
sfx = &s_knownSfx[i];
|
|
|
|
|
|
|
|
if (sfx->registration_sequence) {
|
|
|
|
size = sfx->length * sfx->width;
|
|
|
|
total += size;
|
|
|
|
Com_Printf("(%2db) %6i : %s\n", sfx->width * 8, size, sfx->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Printf("Total resident: %i\n", total);
|
2024-01-07 19:47:58 +01:00
|
|
|
}
|
|
|
|
|
2024-01-08 20:07:26 +01:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_ClearSoundBuffer
|
|
|
|
==============
|
|
|
|
*/
|
2024-01-07 19:47:58 +01:00
|
|
|
void S_ClearSoundBuffer()
|
|
|
|
{
|
|
|
|
// TODO: Remove once AL is fully implemented
|
|
|
|
}
|
|
|
|
|
2024-07-22 20:07:32 +02:00
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_GetMusicFilename
|
|
|
|
==============
|
|
|
|
*/
|
|
|
|
const char* S_GetMusicFilename()
|
|
|
|
{
|
|
|
|
return S_Driver_GetMusicFilename();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_GetMusicLoopCount
|
|
|
|
==============
|
|
|
|
*/
|
|
|
|
int S_GetMusicLoopCount()
|
|
|
|
{
|
|
|
|
return S_Driver_GetMusicLoopCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
==============
|
|
|
|
S_GetMusicOffset
|
|
|
|
==============
|
|
|
|
*/
|
|
|
|
unsigned int S_GetMusicOffset()
|
|
|
|
{
|
|
|
|
return S_Driver_GetMusicOffset();
|
|
|
|
}
|