mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-03-25 20:32:14 +00:00
OpenAL support, from Q2Pro
Copied and adapted (hopefully) all relevant code from Q2Pro. Did some small refactorings when needed. Still TODO: * Adapt Makefile * OGG support when using OpenAL * A cvar that switches between OpenAL and DMA/SDL * Actually compiling and testing this stuff ;)
This commit is contained in:
parent
9ee0341d14
commit
7e0a44825e
10 changed files with 808 additions and 93 deletions
|
@ -37,6 +37,10 @@ typedef struct {
|
|||
int loopstart;
|
||||
int speed; /* not needed, because converted on load? */
|
||||
int width;
|
||||
#if USE_OPENAL
|
||||
int size;
|
||||
int bufnum;
|
||||
#endif
|
||||
int stereo;
|
||||
byte data[1]; /* variable sized */
|
||||
} sfxcache_t;
|
||||
|
@ -87,6 +91,10 @@ typedef struct {
|
|||
int master_vol; /* 0-255 master volume */
|
||||
qboolean fixed_origin; /* use origin instead of fetching entnum's origin */
|
||||
qboolean autosound; /* from an entity->sound, cleared each frame */
|
||||
#if USE_OPENAL
|
||||
int autoframe;
|
||||
int srcnum;
|
||||
#endif
|
||||
} channel_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -98,6 +106,13 @@ typedef struct {
|
|||
int dataofs; /* chunk starts this many bytes from file start */
|
||||
} wavinfo_t;
|
||||
|
||||
typedef enum {
|
||||
SS_NOT = 0, // soundsystem not started
|
||||
SS_DMA, // soundsystem started, using DMA/SDL
|
||||
SS_OAL // soundsystem started, using OpenAL
|
||||
} sndstarted_t;
|
||||
|
||||
extern sndstarted_t sound_started;
|
||||
|
||||
/* initializes cycling through a DMA
|
||||
buffer and returns information on it */
|
||||
|
@ -113,6 +128,7 @@ void SNDDMA_Submit(void);
|
|||
|
||||
#define MAX_CHANNELS 32
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
extern int s_numchannels;
|
||||
|
||||
extern int paintedtime;
|
||||
extern int s_rawend;
|
||||
|
@ -133,6 +149,7 @@ extern cvar_t *s_khz;
|
|||
extern cvar_t *s_show;
|
||||
extern cvar_t *s_mixahead;
|
||||
extern cvar_t *s_testsound;
|
||||
extern cvar_t *s_ambient;
|
||||
|
||||
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength);
|
||||
void S_InitScaletable (void);
|
||||
|
@ -146,5 +163,25 @@ channel_t *S_PickChannel(int entnum, int entchannel);
|
|||
/* spatializes a channel */
|
||||
void S_Spatialize(channel_t *ch);
|
||||
|
||||
void S_BuildSoundList( int *sounds );
|
||||
|
||||
#if USE_OPENAL
|
||||
// this stuff was taken from Q2Pro
|
||||
// only begin attenuating sound volumes when outside the FULLVOLUME range
|
||||
#define SOUND_FULLVOLUME 80
|
||||
#define SOUND_LOOPATTENUATE 0.003
|
||||
|
||||
// for snd_al.c - copied from Q2Pro and adapted
|
||||
void AL_SoundInfo( void );
|
||||
qboolean AL_Init( void );
|
||||
void AL_Shutdown( void );
|
||||
sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data );
|
||||
void AL_DeleteSfx( sfx_t *s );
|
||||
void AL_StopChannel( channel_t *ch );
|
||||
void AL_PlayChannel( channel_t *ch );
|
||||
void AL_StopAllChannels( void );
|
||||
void AL_Update( void );
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
107
src/client/sound/header/qal_api.h
Normal file
107
src/client/sound/header/qal_api.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
This Source File was taken from the Q2Pro Port.
|
||||
|
||||
Copyright (C) 2010 skuller.net
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#define AL_NO_PROTOTYPES
|
||||
#include <AL/al.h>
|
||||
|
||||
#define QAL_IMP \
|
||||
QAL( LPALENABLE, alEnable ); \
|
||||
QAL( LPALDISABLE, alDisable ); \
|
||||
QAL( LPALISENABLED, alIsEnabled ); \
|
||||
QAL( LPALGETSTRING, alGetString ); \
|
||||
QAL( LPALGETBOOLEANV, alGetBooleanv ); \
|
||||
QAL( LPALGETINTEGERV, alGetIntegerv ); \
|
||||
QAL( LPALGETFLOATV, alGetFloatv ); \
|
||||
QAL( LPALGETDOUBLEV, alGetDoublev ); \
|
||||
QAL( LPALGETBOOLEAN, alGetBoolean ); \
|
||||
QAL( LPALGETINTEGER, alGetInteger ); \
|
||||
QAL( LPALGETFLOAT, alGetFloat ); \
|
||||
QAL( LPALGETDOUBLE, alGetDouble ); \
|
||||
QAL( LPALGETERROR, alGetError ); \
|
||||
QAL( LPALISEXTENSIONPRESENT, alIsExtensionPresent ); \
|
||||
QAL( LPALGETPROCADDRESS, alGetProcAddress ); \
|
||||
QAL( LPALGETENUMVALUE, alGetEnumValue ); \
|
||||
QAL( LPALLISTENERF, alListenerf ); \
|
||||
QAL( LPALLISTENER3F, alListener3f ); \
|
||||
QAL( LPALLISTENERFV, alListenerfv ); \
|
||||
QAL( LPALLISTENERI, alListeneri ); \
|
||||
QAL( LPALLISTENER3I, alListener3i ); \
|
||||
QAL( LPALLISTENERIV, alListeneriv ); \
|
||||
QAL( LPALGETLISTENERF, alGetListenerf ); \
|
||||
QAL( LPALGETLISTENER3F, alGetListener3f ); \
|
||||
QAL( LPALGETLISTENERFV, alGetListenerfv ); \
|
||||
QAL( LPALGETLISTENERI, alGetListeneri ); \
|
||||
QAL( LPALGETLISTENER3I, alGetListener3i ); \
|
||||
QAL( LPALGETLISTENERIV, alGetListeneriv ); \
|
||||
QAL( LPALGENSOURCES, alGenSources ); \
|
||||
QAL( LPALDELETESOURCES, alDeleteSources ); \
|
||||
QAL( LPALISSOURCE, alIsSource ); \
|
||||
QAL( LPALSOURCEF, alSourcef ); \
|
||||
QAL( LPALSOURCE3F, alSource3f ); \
|
||||
QAL( LPALSOURCEFV, alSourcefv ); \
|
||||
QAL( LPALSOURCEI, alSourcei ); \
|
||||
QAL( LPALSOURCE3I, alSource3i ); \
|
||||
QAL( LPALSOURCEIV, alSourceiv ); \
|
||||
QAL( LPALGETSOURCEF, alGetSourcef ); \
|
||||
QAL( LPALGETSOURCE3F, alGetSource3f ); \
|
||||
QAL( LPALGETSOURCEFV, alGetSourcefv ); \
|
||||
QAL( LPALGETSOURCEI, alGetSourcei ); \
|
||||
QAL( LPALGETSOURCE3I, alGetSource3i ); \
|
||||
QAL( LPALGETSOURCEIV, alGetSourceiv ); \
|
||||
QAL( LPALSOURCEPLAYV, alSourcePlayv ); \
|
||||
QAL( LPALSOURCESTOPV, alSourceStopv ); \
|
||||
QAL( LPALSOURCEREWINDV, alSourceRewindv ); \
|
||||
QAL( LPALSOURCEPAUSEV, alSourcePausev ); \
|
||||
QAL( LPALSOURCEPLAY, alSourcePlay ); \
|
||||
QAL( LPALSOURCESTOP, alSourceStop ); \
|
||||
QAL( LPALSOURCEREWIND, alSourceRewind ); \
|
||||
QAL( LPALSOURCEPAUSE, alSourcePause ); \
|
||||
QAL( LPALSOURCEQUEUEBUFFERS, alSourceQueueBuffers ); \
|
||||
QAL( LPALSOURCEUNQUEUEBUFFERS, alSourceUnqueueBuffers ); \
|
||||
QAL( LPALGENBUFFERS, alGenBuffers ); \
|
||||
QAL( LPALDELETEBUFFERS, alDeleteBuffers ); \
|
||||
QAL( LPALISBUFFER, alIsBuffer ); \
|
||||
QAL( LPALBUFFERDATA, alBufferData ); \
|
||||
QAL( LPALBUFFERF, alBufferf ); \
|
||||
QAL( LPALBUFFER3F, alBuffer3f ); \
|
||||
QAL( LPALBUFFERFV, alBufferfv ); \
|
||||
QAL( LPALBUFFERI, alBufferi ); \
|
||||
QAL( LPALBUFFER3I, alBuffer3i ); \
|
||||
QAL( LPALBUFFERIV, alBufferiv ); \
|
||||
QAL( LPALGETBUFFERF, alGetBufferf ); \
|
||||
QAL( LPALGETBUFFER3F, alGetBuffer3f ); \
|
||||
QAL( LPALGETBUFFERFV, alGetBufferfv ); \
|
||||
QAL( LPALGETBUFFERI, alGetBufferi ); \
|
||||
QAL( LPALGETBUFFER3I, alGetBuffer3i ); \
|
||||
QAL( LPALGETBUFFERIV, alGetBufferiv ); \
|
||||
QAL( LPALDOPPLERFACTOR, alDopplerFactor ); \
|
||||
QAL( LPALDOPPLERVELOCITY, alDopplerVelocity ); \
|
||||
QAL( LPALSPEEDOFSOUND, alSpeedOfSound ); \
|
||||
QAL( LPALDISTANCEMODEL, alDistanceModel );
|
||||
|
||||
#define QAL(type,func) extern type q##func;
|
||||
QAL_IMP
|
||||
#undef QAL
|
||||
|
||||
qboolean QAL_Init( void );
|
||||
void QAL_Shutdown( void );
|
||||
|
131
src/client/sound/qal_api.c
Normal file
131
src/client/sound/qal_api.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
This Source File was taken from the Q2Pro Port.
|
||||
|
||||
Copyright (C) 2010 skuller.net
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "header/qal_api.h"
|
||||
#include <AL/alc.h>
|
||||
|
||||
#define QALC_IMP \
|
||||
QAL( LPALCCREATECONTEXT, alcCreateContext ); \
|
||||
QAL( LPALCMAKECONTEXTCURRENT, alcMakeContextCurrent ); \
|
||||
QAL( LPALCPROCESSCONTEXT, alcProcessContext ); \
|
||||
QAL( LPALCSUSPENDCONTEXT, alcSuspendContext ); \
|
||||
QAL( LPALCDESTROYCONTEXT, alcDestroyContext ); \
|
||||
QAL( LPALCGETCURRENTCONTEXT, alcGetCurrentContext ); \
|
||||
QAL( LPALCGETCONTEXTSDEVICE, alcGetContextsDevice ); \
|
||||
QAL( LPALCOPENDEVICE, alcOpenDevice ); \
|
||||
QAL( LPALCCLOSEDEVICE, alcCloseDevice ); \
|
||||
QAL( LPALCGETERROR, alcGetError ); \
|
||||
QAL( LPALCISEXTENSIONPRESENT, alcIsExtensionPresent ); \
|
||||
QAL( LPALCGETPROCADDRESS, alcGetProcAddress ); \
|
||||
QAL( LPALCGETENUMVALUE, alcGetEnumValue ); \
|
||||
QAL( LPALCGETSTRING, alcGetString ); \
|
||||
QAL( LPALCGETINTEGERV, alcGetIntegerv ); \
|
||||
QAL( LPALCCAPTUREOPENDEVICE, alcCaptureOpenDevice ); \
|
||||
QAL( LPALCCAPTURECLOSEDEVICE, alcCaptureCloseDevice ); \
|
||||
QAL( LPALCCAPTURESTART, alcCaptureStart ); \
|
||||
QAL( LPALCCAPTURESTOP, alcCaptureStop ); \
|
||||
QAL( LPALCCAPTURESAMPLES, alcCaptureSamples );
|
||||
|
||||
static cvar_t *al_driver;
|
||||
static cvar_t *al_device;
|
||||
|
||||
static void *handle;
|
||||
static ALCdevice *device;
|
||||
static ALCcontext *context;
|
||||
|
||||
#define QAL(type,func) static type q##func;
|
||||
QALC_IMP
|
||||
#undef QAL
|
||||
|
||||
#define QAL(type,func) type q##func;
|
||||
QAL_IMP
|
||||
#undef QAL
|
||||
|
||||
void QAL_Shutdown( void ) {
|
||||
if( context ) {
|
||||
qalcMakeContextCurrent( NULL );
|
||||
qalcDestroyContext( context );
|
||||
context = NULL;
|
||||
}
|
||||
if( device ) {
|
||||
qalcCloseDevice( device );
|
||||
device = NULL;
|
||||
}
|
||||
|
||||
#define QAL(type,func) q##func = NULL;
|
||||
QALC_IMP
|
||||
QAL_IMP
|
||||
#undef QAL
|
||||
|
||||
Sys_FreeLibrary( handle );
|
||||
handle = NULL;
|
||||
|
||||
al_driver->flags &= ~CVAR_SOUND;
|
||||
al_device->flags &= ~CVAR_SOUND;
|
||||
}
|
||||
|
||||
qboolean QAL_Init( void ) {
|
||||
al_driver = Cvar_Get( "al_driver", DEFAULT_OPENAL_DRIVER, CVAR_SOUND );
|
||||
al_device = Cvar_Get( "al_device", "", CVAR_SOUND );
|
||||
|
||||
Sys_LoadLibrary( al_driver->string, NULL, &handle );
|
||||
if( !handle ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#define QAL(type,func) q##func = Sys_GetProcAddress( handle, #func );
|
||||
QALC_IMP
|
||||
QAL_IMP
|
||||
#undef QAL
|
||||
|
||||
Com_DPrintf( "...opening OpenAL device: " );
|
||||
device = qalcOpenDevice( al_device->string[0] ? al_device->string : NULL );
|
||||
if( !device ) {
|
||||
goto fail;
|
||||
}
|
||||
Com_DPrintf( "ok\n" );
|
||||
|
||||
Com_DPrintf( "...creating OpenAL context: " );
|
||||
context = qalcCreateContext( device, NULL );
|
||||
if( !context ) {
|
||||
goto fail;
|
||||
}
|
||||
Com_DPrintf( "ok\n" );
|
||||
|
||||
Com_DPrintf( "...making context current: " );
|
||||
if( !qalcMakeContextCurrent( context ) ) {
|
||||
goto fail;
|
||||
}
|
||||
Com_DPrintf( "ok\n" );
|
||||
|
||||
al_driver->flags |= CVAR_SOUND;
|
||||
al_device->flags |= CVAR_SOUND;
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
Com_DPrintf( "failed\n" );
|
||||
QAL_Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
361
src/client/sound/snd_al.c
Normal file
361
src/client/sound/snd_al.c
Normal file
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
This Source File was taken from the Q2Pro Port.
|
||||
|
||||
Copyright (C) 2010 skuller.net
|
||||
2012 Some changes by the Yamagi Quake2 developers
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef USE_OPENAL
|
||||
|
||||
#include "../header/client.h"
|
||||
#include "header/local.h"
|
||||
#include "qal_api.h"
|
||||
|
||||
// translates from AL coordinate system to quake
|
||||
#define AL_UnpackVector(v) -v[1],v[2],-v[0]
|
||||
#define AL_CopyVector(a,b) ((b)[0]=-(a)[1],(b)[1]=(a)[2],(b)[2]=-(a)[0])
|
||||
|
||||
// OpenAL implementation should support at least this number of sources
|
||||
#define MIN_CHANNELS 16
|
||||
|
||||
static ALuint s_srcnums[MAX_CHANNELS];
|
||||
static int s_framecount;
|
||||
|
||||
void AL_SoundInfo( void ) {
|
||||
Com_Printf( "AL_VENDOR: %s\n", qalGetString( AL_VENDOR ) );
|
||||
Com_Printf( "AL_RENDERER: %s\n", qalGetString( AL_RENDERER ) );
|
||||
Com_Printf( "AL_VERSION: %s\n", qalGetString( AL_VERSION ) );
|
||||
Com_Printf( "AL_EXTENSIONS: %s\n", qalGetString( AL_EXTENSIONS ) );
|
||||
Com_Printf( "Number of sources: %d\n", s_numchannels );
|
||||
}
|
||||
|
||||
qboolean AL_Init( void ) {
|
||||
int i;
|
||||
|
||||
if( !QAL_Init() ) {
|
||||
Com_EPrintf( "OpenAL failed to initialize.\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for linear distance extension
|
||||
if( !qalIsExtensionPresent( "AL_EXT_LINEAR_DISTANCE" ) ) {
|
||||
Com_EPrintf( "Required AL_EXT_LINEAR_DISTANCE extension is missing.\n" );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// generate source names
|
||||
qalGetError();
|
||||
for( i = 0; i < MAX_CHANNELS; i++ ) {
|
||||
qalGenSources( 1, &s_srcnums[i] );
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i < MIN_CHANNELS ) {
|
||||
Com_EPrintf( "Required at least %d sources, but got %d.\n", MIN_CHANNELS, i );
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s_numchannels = i;
|
||||
|
||||
Com_Printf( "OpenAL initialized.\n" );
|
||||
return true;
|
||||
|
||||
fail:
|
||||
QAL_Shutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
void AL_Shutdown( void ) {
|
||||
Com_Printf( "Shutting down OpenAL.\n" );
|
||||
|
||||
if( s_numchannels ) {
|
||||
// delete source names
|
||||
qalDeleteSources( s_numchannels, s_srcnums );
|
||||
memset( s_srcnums, 0, sizeof( s_srcnums ) );
|
||||
s_numchannels = 0;
|
||||
}
|
||||
|
||||
QAL_Shutdown();
|
||||
}
|
||||
|
||||
sfxcache_t *AL_UploadSfx( sfx_t *s, wavinfo_t *s_info, byte *data ) {
|
||||
sfxcache_t *sc;
|
||||
ALsizei size = s_info->samples * s_info->width;
|
||||
ALenum format = s_info->width == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
|
||||
ALuint name;
|
||||
|
||||
if( !size ) {
|
||||
// s->error = Q_ERR_TOO_FEW; FIXME: do I want this information?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qalGetError();
|
||||
qalGenBuffers( 1, &name );
|
||||
qalBufferData( name, format, data, size, s_info->rate );
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
// s->error = Q_ERR_LIBRARY_ERROR; FIXME: do I want this info?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// allocate placeholder sfxcache
|
||||
sc = s->cache = S_Malloc( sizeof( *sc ) );
|
||||
sc->length = s_info->samples * 1000 / s_info->rate; // in msec
|
||||
sc->loopstart = s_info->loopstart;
|
||||
sc->width = s_info->width;
|
||||
sc->size = size;
|
||||
sc->bufnum = name;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
void AL_DeleteSfx( sfx_t *s ) {
|
||||
sfxcache_t *sc;
|
||||
ALuint name;
|
||||
|
||||
sc = s->cache;
|
||||
if( !sc ) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = sc->bufnum;
|
||||
qalDeleteBuffers( 1, &name );
|
||||
}
|
||||
|
||||
void AL_StopChannel( channel_t *ch ) {
|
||||
#ifdef _DEBUG
|
||||
if (s_show->integer > 1)
|
||||
Com_Printf("%s: %s\n", __func__, ch->sfx->name );
|
||||
#endif
|
||||
|
||||
// stop it
|
||||
qalSourceStop( ch->srcnum );
|
||||
qalSourcei( ch->srcnum, AL_BUFFER, AL_NONE );
|
||||
memset (ch, 0, sizeof(*ch));
|
||||
}
|
||||
|
||||
static void AL_Spatialize( channel_t *ch ) {
|
||||
vec3_t origin;
|
||||
|
||||
// anything coming from the view entity will always be full volume
|
||||
// no attenuation = no spatialization
|
||||
if( ch->entnum == -1 || ch->entnum == cl.playernum + 1 || !ch->dist_mult ) {
|
||||
VectorCopy( listener_origin, origin );
|
||||
} else if( ch->fixed_origin ) {
|
||||
VectorCopy( ch->origin, origin );
|
||||
} else {
|
||||
CL_GetEntitySoundOrigin( ch->entnum, origin );
|
||||
}
|
||||
|
||||
qalSource3f( ch->srcnum, AL_POSITION, AL_UnpackVector( origin ) );
|
||||
}
|
||||
|
||||
void AL_PlayChannel( channel_t *ch ) {
|
||||
sfxcache_t *sc = ch->sfx->cache;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (s_show->integer > 1)
|
||||
Com_Printf("%s: %s\n", __func__, ch->sfx->name );
|
||||
#endif
|
||||
|
||||
ch->srcnum = s_srcnums[ch - channels];
|
||||
qalGetError();
|
||||
qalSourcei( ch->srcnum, AL_BUFFER, sc->bufnum );
|
||||
//qalSourcei( ch->srcnum, AL_LOOPING, sc->loopstart == -1 ? AL_FALSE : AL_TRUE );
|
||||
qalSourcei( ch->srcnum, AL_LOOPING, ch->autosound ? AL_TRUE : AL_FALSE );
|
||||
qalSourcef( ch->srcnum, AL_GAIN, ch->master_vol );
|
||||
qalSourcef( ch->srcnum, AL_REFERENCE_DISTANCE, SOUND_FULLVOLUME );
|
||||
qalSourcef( ch->srcnum, AL_MAX_DISTANCE, 8192 );
|
||||
qalSourcef( ch->srcnum, AL_ROLLOFF_FACTOR, ch->dist_mult * ( 8192 - SOUND_FULLVOLUME ) );
|
||||
|
||||
AL_Spatialize( ch );
|
||||
|
||||
// play it
|
||||
qalSourcePlay( ch->srcnum );
|
||||
if( qalGetError() != AL_NO_ERROR ) {
|
||||
AL_StopChannel( ch );
|
||||
}
|
||||
}
|
||||
|
||||
void AL_StopAllChannels( void ) {
|
||||
int i;
|
||||
channel_t *ch;
|
||||
|
||||
ch = channels;
|
||||
for( i = 0; i < s_numchannels; i++, ch++ ) {
|
||||
if (!ch->sfx)
|
||||
continue;
|
||||
AL_StopChannel( ch );
|
||||
}
|
||||
}
|
||||
|
||||
static channel_t *AL_FindLoopingSound( int entnum, sfx_t *sfx ) {
|
||||
int i;
|
||||
channel_t *ch;
|
||||
|
||||
ch = channels;
|
||||
for( i = 0; i < s_numchannels; i++, ch++ ) {
|
||||
if( !ch->sfx )
|
||||
continue;
|
||||
if( !ch->autosound )
|
||||
continue;
|
||||
if( ch->entnum != entnum )
|
||||
continue;
|
||||
if( ch->sfx != sfx )
|
||||
continue;
|
||||
return ch;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void AL_AddLoopSounds( void ) {
|
||||
int i;
|
||||
int sounds[64]; // 64 is MAX_PACKET_ENTITIES in YQ2 (there's no define for it, though :/)
|
||||
channel_t *ch;
|
||||
sfx_t *sfx;
|
||||
sfxcache_t *sc;
|
||||
int num;
|
||||
entity_state_t *ent;
|
||||
|
||||
if( cls.state != ca_active || sv_paused->value || !s_ambient->value ) {
|
||||
return;
|
||||
}
|
||||
|
||||
S_BuildSoundList( sounds );
|
||||
|
||||
for( i = 0; i < cl.frame.numEntities; i++ ) {
|
||||
if (!sounds[i])
|
||||
continue;
|
||||
|
||||
sfx = S_SfxForHandle( cl.sound_precache[sounds[i]] );
|
||||
if (!sfx)
|
||||
continue; // bad sound effect
|
||||
sc = sfx->cache;
|
||||
if (!sc)
|
||||
continue;
|
||||
|
||||
num = ( cl.frame.firstEntity + i ) & (MAX_PARSE_ENTITIES-1);
|
||||
ent = &cl.entityStates[num];
|
||||
|
||||
ch = AL_FindLoopingSound( ent->number, sfx );
|
||||
if( ch ) {
|
||||
ch->autoframe = s_framecount;
|
||||
ch->end = paintedtime + sc->length;
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocate a channel
|
||||
ch = S_PickChannel(0, 0);
|
||||
if (!ch)
|
||||
continue;
|
||||
|
||||
ch->autosound = true; // remove next frame
|
||||
ch->autoframe = s_framecount;
|
||||
ch->sfx = sfx;
|
||||
ch->entnum = ent->number;
|
||||
ch->master_vol = 1;
|
||||
ch->dist_mult = SOUND_LOOPATTENUATE;
|
||||
ch->end = paintedtime + sc->length;
|
||||
|
||||
AL_PlayChannel( ch );
|
||||
}
|
||||
}
|
||||
|
||||
static void AL_IssuePlaysounds( void ) {
|
||||
playsound_t *ps;
|
||||
|
||||
// start any playsounds
|
||||
while (1) {
|
||||
ps = s_pendingplays.next;
|
||||
if (ps == &s_pendingplays)
|
||||
break; // no more pending sounds
|
||||
if (ps->begin > paintedtime)
|
||||
break;
|
||||
S_IssuePlaysound (ps);
|
||||
}
|
||||
}
|
||||
|
||||
void AL_Update( void ) {
|
||||
int i;
|
||||
channel_t *ch;
|
||||
vec_t orientation[6];
|
||||
|
||||
/*
|
||||
if( !s_active ) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
paintedtime = cl.time;
|
||||
|
||||
// set listener parameters
|
||||
qalListener3f( AL_POSITION, AL_UnpackVector( listener_origin ) );
|
||||
AL_CopyVector( listener_forward, orientation );
|
||||
AL_CopyVector( listener_up, orientation + 3 );
|
||||
qalListenerfv( AL_ORIENTATION, orientation );
|
||||
qalListenerf( AL_GAIN, s_volume->value );
|
||||
qalDistanceModel( AL_LINEAR_DISTANCE_CLAMPED );
|
||||
|
||||
// update spatialization for dynamic sounds
|
||||
ch = channels;
|
||||
for( i = 0; i < s_numchannels; i++, ch++ ) {
|
||||
if( !ch->sfx )
|
||||
continue;
|
||||
|
||||
if( ch->autosound ) {
|
||||
// autosounds are regenerated fresh each frame
|
||||
if( ch->autoframe != s_framecount ) {
|
||||
AL_StopChannel( ch );
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
ALenum state;
|
||||
|
||||
qalGetError();
|
||||
qalGetSourcei( ch->srcnum, AL_SOURCE_STATE, &state );
|
||||
if( qalGetError() != AL_NO_ERROR || state == AL_STOPPED ) {
|
||||
AL_StopChannel( ch );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (s_show->integer) {
|
||||
Com_Printf ("%.1f %s\n", ch->master_vol, ch->sfx->name);
|
||||
// total++;
|
||||
}
|
||||
#endif
|
||||
|
||||
AL_Spatialize(ch); // respatialize channel
|
||||
}
|
||||
|
||||
s_framecount++;
|
||||
|
||||
// add loopsounds
|
||||
AL_AddLoopSounds ();
|
||||
|
||||
// FIXME: About here some ogg vorbis stuff (maybe calling OGG_Stream()
|
||||
// like in S_Update()) should be done.
|
||||
|
||||
AL_IssuePlaysounds();
|
||||
}
|
||||
|
||||
#endif // USE_OPENAL
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
void S_Play ( void );
|
||||
void S_SoundList ( void );
|
||||
void S_Update_ ();
|
||||
void S_StopAllSounds ( void );
|
||||
|
||||
/* only begin attenuating sound volumes when outside the FULLVOLUME range */
|
||||
|
@ -42,9 +41,10 @@ void S_StopAllSounds ( void );
|
|||
int s_registration_sequence;
|
||||
|
||||
channel_t channels [ MAX_CHANNELS ];
|
||||
int s_numchannels;
|
||||
|
||||
qboolean snd_initialized = false;
|
||||
int sound_started = 0;
|
||||
sndstarted_t sound_started = SS_NOT;
|
||||
|
||||
dma_t dma;
|
||||
|
||||
|
@ -79,6 +79,7 @@ cvar_t *s_loadas8bit;
|
|||
cvar_t *s_khz;
|
||||
cvar_t *s_mixahead;
|
||||
cvar_t *s_show;
|
||||
cvar_t *s_ambient;
|
||||
|
||||
int s_rawend;
|
||||
portable_samplepair_t s_rawsamples [ MAX_RAW_SAMPLES ];
|
||||
|
@ -86,15 +87,8 @@ portable_samplepair_t s_rawsamples [ MAX_RAW_SAMPLES ];
|
|||
/*
|
||||
* User-setable variables
|
||||
*/
|
||||
void
|
||||
S_SoundInfo_f ( void )
|
||||
{
|
||||
if ( !sound_started )
|
||||
{
|
||||
Com_Printf( "sound system not started\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
static void DMA_SoundInfo (void) {
|
||||
Com_Printf( "%5d stereo\n", dma.channels - 1 );
|
||||
Com_Printf( "%5d samples\n", dma.samples );
|
||||
Com_Printf( "%5d samplepos\n", dma.samplepos );
|
||||
|
@ -104,6 +98,25 @@ S_SoundInfo_f ( void )
|
|||
Com_Printf( "%p dma buffer\n", dma.buffer );
|
||||
}
|
||||
|
||||
void
|
||||
S_SoundInfo_f ( void )
|
||||
{
|
||||
if ( !sound_started )
|
||||
{
|
||||
Com_Printf( "sound system not started\n" );
|
||||
return;
|
||||
}
|
||||
#if USE_OPENAL
|
||||
if(sound_started == SS_OAL) {
|
||||
AL_SoundInfo();
|
||||
} else
|
||||
#endif
|
||||
DMA_SoundInfo();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
S_Init ( void )
|
||||
{
|
||||
|
@ -116,16 +129,15 @@ S_Init ( void )
|
|||
if ( !cv->value )
|
||||
{
|
||||
Com_Printf( "not initializing.\n" );
|
||||
}
|
||||
} else {
|
||||
|
||||
else
|
||||
{
|
||||
s_volume = Cvar_Get( "s_volume", "0.7", CVAR_ARCHIVE );
|
||||
s_khz = Cvar_Get( "s_khz", "44", CVAR_ARCHIVE );
|
||||
s_loadas8bit = Cvar_Get( "s_loadas8bit", "0", CVAR_ARCHIVE );
|
||||
s_mixahead = Cvar_Get( "s_mixahead", "0.14", CVAR_ARCHIVE );
|
||||
s_show = Cvar_Get( "s_show", "0", 0 );
|
||||
s_testsound = Cvar_Get( "s_testsound", "0", 0 );
|
||||
s_ambient = Cvar_Get( "s_ambient", "1", 0);
|
||||
|
||||
Cmd_AddCommand( "play", S_Play );
|
||||
Cmd_AddCommand( "stopsound", S_StopAllSounds );
|
||||
|
@ -133,15 +145,21 @@ S_Init ( void )
|
|||
Cmd_AddCommand( "soundinfo", S_SoundInfo_f );
|
||||
Cmd_AddCommand( "ogg_init", OGG_Init );
|
||||
Cmd_AddCommand( "ogg_shutdown", OGG_Shutdown );
|
||||
|
||||
if ( !SNDDMA_Init() )
|
||||
{
|
||||
return;
|
||||
#if USE_OPENAL
|
||||
// FIXME: cvar for soundsystem to use?
|
||||
if( AL_Init() ) {
|
||||
sound_started = SS_OAL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ( SNDDMA_Init() )
|
||||
{
|
||||
sound_started = SS_DMA;
|
||||
} else {
|
||||
sound_started = SS_NOT;
|
||||
return;
|
||||
}
|
||||
|
||||
S_InitScaletable();
|
||||
|
||||
sound_started = 1;
|
||||
num_sfx = 0;
|
||||
|
||||
soundtime = 0;
|
||||
|
@ -170,6 +188,8 @@ S_Shutdown ( void )
|
|||
return;
|
||||
}
|
||||
|
||||
S_StopAllSounds();
|
||||
|
||||
/* free all sounds */
|
||||
for ( i = 0, sfx = known_sfx; i < num_sfx; i++, sfx++ )
|
||||
{
|
||||
|
@ -177,20 +197,38 @@ S_Shutdown ( void )
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
#if USE_OPENAL
|
||||
if ( sound_started == SS_OAL )
|
||||
{
|
||||
AL_DeleteSfx( sfx );
|
||||
}
|
||||
#endif
|
||||
if ( sfx->cache )
|
||||
{
|
||||
Z_Free( sfx->cache );
|
||||
}
|
||||
if ( sfx->truename )
|
||||
{
|
||||
Z_Free( sfx-> truename );
|
||||
}
|
||||
}
|
||||
|
||||
memset( known_sfx, 0, sizeof ( known_sfx ) );
|
||||
|
||||
num_sfx = 0;
|
||||
sound_started = 0;
|
||||
sound_started = SS_NOT;
|
||||
|
||||
OGG_Shutdown();
|
||||
SNDDMA_Shutdown();
|
||||
|
||||
#if USE_OPENAL
|
||||
if( sound_started == SS_OAL )
|
||||
{
|
||||
AL_Shutdown();
|
||||
} else
|
||||
#endif
|
||||
SNDDMA_Shutdown();
|
||||
|
||||
s_numchannels = 0;
|
||||
|
||||
Cmd_RemoveCommand( "soundlist" );
|
||||
Cmd_RemoveCommand( "soundinfo" );
|
||||
|
@ -399,7 +437,7 @@ S_PickChannel ( int entnum, int entchannel )
|
|||
first_to_die = -1;
|
||||
life_left = 0x7fffffff;
|
||||
|
||||
for ( ch_idx = 0; ch_idx < MAX_CHANNELS; ch_idx++ )
|
||||
for ( ch_idx = 0; ch_idx < s_numchannels; ch_idx++ )
|
||||
{
|
||||
/* channel 0 never overrides */
|
||||
if ( ( entchannel != 0 ) &&
|
||||
|
@ -430,6 +468,13 @@ S_PickChannel ( int entnum, int entchannel )
|
|||
}
|
||||
|
||||
ch = &channels [ first_to_die ];
|
||||
|
||||
#if USE_OPENAL
|
||||
if( sound_started == SS_OAL && ch->sfx )
|
||||
{
|
||||
AL_StopChannel( ch );
|
||||
}
|
||||
#endif
|
||||
memset( ch, 0, sizeof ( *ch ) );
|
||||
|
||||
return ( ch );
|
||||
|
@ -585,6 +630,13 @@ S_IssuePlaysound ( playsound_t *ps )
|
|||
return;
|
||||
}
|
||||
|
||||
sc = S_LoadSound( ps->sfx );
|
||||
if( !sc ) {
|
||||
Com_Printf( "S_IssuePlaysound: couldn't load %s\n", ps->sfx->name );
|
||||
S_FreePlaysound( ps );
|
||||
return;
|
||||
}
|
||||
|
||||
/* spatialize */
|
||||
if ( ps->attenuation == ATTN_STATIC )
|
||||
{
|
||||
|
@ -603,16 +655,15 @@ S_IssuePlaysound ( playsound_t *ps )
|
|||
VectorCopy( ps->origin, ch->origin );
|
||||
ch->fixed_origin = ps->fixed_origin;
|
||||
|
||||
S_Spatialize( ch );
|
||||
#if USE_OPENAL
|
||||
if( sound_started == SS_OAL)
|
||||
{
|
||||
AL_PlayChannel( ch );
|
||||
} else
|
||||
#endif
|
||||
S_Spatialize( ch );
|
||||
|
||||
ch->pos = 0;
|
||||
sc = S_LoadSound( ch->sfx );
|
||||
|
||||
if (!sc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ch->end = paintedtime + sc->length;
|
||||
|
||||
/* free the playsound */
|
||||
|
@ -682,6 +733,28 @@ S_RegisterSexedSound ( entity_state_t *ent, char *base )
|
|||
return ( sfx );
|
||||
}
|
||||
|
||||
static int DMA_DriftBeginofs( float timeofs ) {
|
||||
/* drift s_beginofs */
|
||||
int start = (int) ( cl.frame.servertime * 0.001f * dma.speed + s_beginofs );
|
||||
|
||||
if ( start < paintedtime )
|
||||
{
|
||||
start = paintedtime;
|
||||
s_beginofs = (int) ( start - ( cl.frame.servertime * 0.001f * dma.speed ) );
|
||||
}
|
||||
else if ( start > paintedtime + 0.3f * dma.speed )
|
||||
{
|
||||
start = (int) ( paintedtime + 0.1f * dma.speed );
|
||||
s_beginofs = (int) ( start - ( cl.frame.servertime * 0.001f * dma.speed ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
s_beginofs -= 10;
|
||||
}
|
||||
|
||||
return timeofs ? start + timeofs * dma.speed : paintedtime;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates the parms and ques the sound up if pos is NULL, the sound
|
||||
* will be dynamically sourced from the entity Entchannel 0 will never
|
||||
|
@ -693,7 +766,6 @@ S_StartSound ( vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol
|
|||
sfxcache_t *sc;
|
||||
int vol;
|
||||
playsound_t *ps, *sort;
|
||||
int start;
|
||||
|
||||
if ( !sound_started )
|
||||
{
|
||||
|
@ -708,6 +780,9 @@ S_StartSound ( vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol
|
|||
if ( sfx->name [ 0 ] == '*' )
|
||||
{
|
||||
sfx = S_RegisterSexedSound( &cl_entities [ entnum ].current, sfx->name );
|
||||
if( !sfx ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure the sound is loaded */
|
||||
|
@ -744,34 +819,12 @@ S_StartSound ( vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol
|
|||
ps->volume = vol;
|
||||
ps->sfx = sfx;
|
||||
|
||||
/* drift s_beginofs */
|
||||
start = (int) ( cl.frame.servertime * 0.001f * dma.speed + s_beginofs );
|
||||
|
||||
if ( start < paintedtime )
|
||||
{
|
||||
start = paintedtime;
|
||||
s_beginofs = (int) ( start - ( cl.frame.servertime * 0.001f * dma.speed ) );
|
||||
}
|
||||
else if ( start > paintedtime + 0.3f * dma.speed )
|
||||
{
|
||||
start = (int) ( paintedtime + 0.1f * dma.speed );
|
||||
s_beginofs = (int) ( start - ( cl.frame.servertime * 0.001f * dma.speed ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
s_beginofs -= 10;
|
||||
}
|
||||
|
||||
if ( !timeofs )
|
||||
{
|
||||
ps->begin = paintedtime;
|
||||
}
|
||||
else
|
||||
{
|
||||
ps->begin = (int) ( start + timeofs * dma.speed );
|
||||
}
|
||||
|
||||
ps->volume = fvol * 255;
|
||||
#if USE_OPENAL
|
||||
if( sound_started == SS_OAL ) {
|
||||
ps->begin = paintedtime + timeofs * 1000;
|
||||
} else
|
||||
#endif
|
||||
ps->begin = DMA_DriftBeginofs(timeofs);
|
||||
|
||||
/* sort into the pending sound list */
|
||||
for ( sort = s_pendingplays.next;
|
||||
|
@ -872,10 +925,34 @@ S_StopAllSounds ( void )
|
|||
s_playsounds [ i ].next->prev = &s_playsounds [ i ];
|
||||
}
|
||||
|
||||
#if USE_OPENAL
|
||||
if( sound_started == SS_OAL ) {
|
||||
AL_StopAllChannels();
|
||||
} else
|
||||
#endif
|
||||
S_ClearBuffer();
|
||||
|
||||
/* clear all the channels */
|
||||
memset( channels, 0, sizeof ( channels ) );
|
||||
}
|
||||
|
||||
S_ClearBuffer();
|
||||
void S_BuildSoundList( int *sounds ) {
|
||||
int i;
|
||||
int num;
|
||||
entity_state_t *ent;
|
||||
|
||||
for ( i = 0; i < cl.frame.num_entities; i++ )
|
||||
{
|
||||
num = ( cl.frame.parse_entities + i ) & ( MAX_PARSE_ENTITIES - 1 );
|
||||
ent = &cl_parse_entities [ num ];
|
||||
if( s_ambient->value == 2 && !ent->modelindex ) {
|
||||
sounds[i] = 0;
|
||||
} else if( s_ambient->value == 3 && ent->number != cl.playernum + 1) {
|
||||
sounds[i] = 0;
|
||||
} else {
|
||||
sounds[i] = ent->sound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -906,17 +983,12 @@ S_AddLoopSounds ( void )
|
|||
return;
|
||||
}
|
||||
|
||||
if ( !cl.sound_prepped )
|
||||
if ( !cl.sound_prepped || !s_ambient->value || sv_paused->value )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0; i < cl.frame.num_entities; i++ )
|
||||
{
|
||||
num = ( cl.frame.parse_entities + i ) & ( MAX_PARSE_ENTITIES - 1 );
|
||||
ent = &cl_parse_entities [ num ];
|
||||
sounds [ i ] = ent->sound;
|
||||
}
|
||||
S_BuildSoundList( sounds );
|
||||
|
||||
for ( i = 0; i < cl.frame.num_entities; i++ )
|
||||
{
|
||||
|
@ -1171,21 +1243,29 @@ S_Update ( vec3_t origin, vec3_t forward, vec3_t right, vec3_t up )
|
|||
return;
|
||||
}
|
||||
|
||||
/* rebuild scale tables if volume is modified */
|
||||
if ( s_volume->modified )
|
||||
{
|
||||
S_InitScaletable();
|
||||
}
|
||||
|
||||
VectorCopy( origin, listener_origin );
|
||||
VectorCopy( forward, listener_forward );
|
||||
VectorCopy( right, listener_right );
|
||||
VectorCopy( up, listener_up );
|
||||
|
||||
|
||||
#if USE_OPENAL
|
||||
if( sound_started == SS_OAL ) {
|
||||
AL_Update();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* rebuild scale tables if volume is modified */
|
||||
if ( s_volume->modified )
|
||||
{
|
||||
S_InitScaletable();
|
||||
}
|
||||
|
||||
/* update spatialization for dynamic sounds */
|
||||
ch = channels;
|
||||
|
||||
for ( i = 0; i < MAX_CHANNELS; i++, ch++ )
|
||||
for ( i = 0; i < s_numchannels; i++, ch++ )
|
||||
{
|
||||
if ( !ch->sfx )
|
||||
{
|
||||
|
@ -1217,7 +1297,7 @@ S_Update ( vec3_t origin, vec3_t forward, vec3_t right, vec3_t up )
|
|||
total = 0;
|
||||
ch = channels;
|
||||
|
||||
for ( i = 0; i < MAX_CHANNELS; i++, ch++ )
|
||||
for ( i = 0; i < s_numchannels; i++, ch++ )
|
||||
{
|
||||
if ( ch->sfx && ( ch->leftvol || ch->rightvol ) )
|
||||
{
|
||||
|
@ -1231,12 +1311,6 @@ S_Update ( vec3_t origin, vec3_t forward, vec3_t right, vec3_t up )
|
|||
|
||||
/* stream music */
|
||||
OGG_Stream();
|
||||
|
||||
/* mix some sound */
|
||||
if ( !sound_started )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SNDDMA_BeginPainting();
|
||||
|
||||
|
@ -1274,7 +1348,7 @@ S_Update ( vec3_t origin, vec3_t forward, vec3_t right, vec3_t up )
|
|||
|
||||
S_PaintChannels( endtime );
|
||||
|
||||
SNDDMA_Submit();
|
||||
SNDDMA_Submit();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -149,10 +149,7 @@ S_LoadSound ( sfx_t *s )
|
|||
if ( name [ 0 ] == '#' )
|
||||
{
|
||||
strcpy( namebuffer, &name [ 1 ] );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Com_sprintf( namebuffer, sizeof ( namebuffer ), "sound/%s", name );
|
||||
}
|
||||
|
||||
|
@ -199,7 +196,12 @@ S_LoadSound ( sfx_t *s )
|
|||
sc->width = info.width;
|
||||
sc->stereo = info.channels;
|
||||
|
||||
ResampleSfx( s, sc->speed, sc->width, data + info.dataofs );
|
||||
#if USE_OPENAL
|
||||
if (sound_started == SS_OAL)
|
||||
sc = AL_UploadSfx(s, &info, data + info.dataofs);
|
||||
else
|
||||
#endif
|
||||
ResampleSfx( s, sc->speed, sc->width, data + info.dataofs );
|
||||
|
||||
FS_FreeFile( data );
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ S_PaintChannels ( int endtime )
|
|||
/* paint in the channels. */
|
||||
ch = channels;
|
||||
|
||||
for ( i = 0; i < MAX_CHANNELS; i++, ch++ )
|
||||
for ( i = 0; i < s_numchannels; i++, ch++ )
|
||||
{
|
||||
ltime = paintedtime;
|
||||
|
||||
|
|
|
@ -37,9 +37,6 @@
|
|||
#include "header/local.h"
|
||||
#include "header/vorbis.h"
|
||||
|
||||
extern int sound_started; /* Sound initialization flag. */
|
||||
extern cvar_t *fs_basedir; /* Path to "music". */
|
||||
|
||||
qboolean ogg_first_init = true; /* First initialization flag. */
|
||||
qboolean ogg_started = false; /* Initialization flag. */
|
||||
int ogg_bigendian = 0;
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include "../header/client.h"
|
||||
#include "header/local.h"
|
||||
|
||||
// FIXME: this code is really fucked up, those global variables make me sick.
|
||||
// someone should clean this up one day..
|
||||
|
||||
byte *data_p;
|
||||
byte *iff_end;
|
||||
byte *last_chunk;
|
||||
|
|
|
@ -208,6 +208,9 @@ SNDDMA_Init(void)
|
|||
dmasize = (dmabackend->samples * (dmabackend->samplebits / 8));
|
||||
dmabackend->buffer = calloc(1, dmasize);
|
||||
|
||||
s_numchannels = MAX_CHANNELS;
|
||||
S_InitScaletable();
|
||||
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
Com_Printf("SDL audio initialized.\n");
|
||||
|
|
Loading…
Reference in a new issue