2007-01-15 12:09:25 -08:00
|
|
|
/*
|
|
|
|
This file is part of Warzone 2100.
|
|
|
|
Copyright (C) 1999-2004 Eidos Interactive
|
|
|
|
Copyright (C) 2005-2007 Warzone Resurrection Project
|
|
|
|
|
|
|
|
Warzone 2100 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.
|
|
|
|
|
|
|
|
Warzone 2100 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 Warzone 2100; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
//*
|
|
|
|
//
|
|
|
|
// Sound library-specific functions
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
|
|
|
|
// this has to be first
|
2006-06-02 12:34:58 -07:00
|
|
|
#include "lib/framework/frame.h"
|
2007-04-09 05:16:31 -07:00
|
|
|
#include "lib/framework/frameresource.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
|
|
|
# ifdef WZ_OS_MAC
|
|
|
|
# include <OpenAL/al.h>
|
|
|
|
# include <OpenAL/alc.h>
|
|
|
|
# else
|
|
|
|
# include <AL/al.h>
|
|
|
|
# include <AL/alc.h>
|
|
|
|
# endif
|
2006-08-12 03:45:49 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2006-06-16 12:10:23 -07:00
|
|
|
#include <physfs.h>
|
2006-11-06 06:40:07 -08:00
|
|
|
#include <string.h>
|
2006-06-16 12:10:23 -07:00
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "tracklib.h"
|
|
|
|
#include "audio.h"
|
2007-09-16 07:05:01 -07:00
|
|
|
#include "cdaudio.h"
|
2007-04-30 10:58:27 -07:00
|
|
|
#include "oggvorbis.h"
|
2007-12-13 15:16:03 -08:00
|
|
|
#include "openal_error.h"
|
2007-01-24 11:42:20 -08:00
|
|
|
|
2006-09-20 12:46:33 -07:00
|
|
|
#define ATTENUATION_FACTOR 0.0003f
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
ALuint current_queue_sample = -1;
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
typedef struct SAMPLE_LIST
|
|
|
|
{
|
|
|
|
struct AUDIO_SAMPLE *curr;
|
|
|
|
struct SAMPLE_LIST *next;
|
|
|
|
} SAMPLE_LIST;
|
|
|
|
|
|
|
|
static SAMPLE_LIST *active_samples = NULL;
|
|
|
|
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
static ALfloat sfx_volume = 1.0;
|
|
|
|
static ALfloat sfx3d_volume = 1.0;
|
|
|
|
|
|
|
|
static ALCdevice* device = 0;
|
|
|
|
static ALCcontext* context = 0;
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
BOOL openal_initialized = FALSE;
|
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
/** Removes the given sample from the "active_samples" linked list
|
|
|
|
* \param previous either NULL (if \c to_remove is the first item in the
|
|
|
|
* list) or the item occurring just before \c to_remove in
|
|
|
|
* the list
|
|
|
|
* \param to_remove the item to actually remove from the list
|
|
|
|
*/
|
|
|
|
static void sound_RemoveSample(SAMPLE_LIST* previous, SAMPLE_LIST* to_remove)
|
|
|
|
{
|
|
|
|
if (previous != NULL && previous != to_remove)
|
|
|
|
{
|
|
|
|
// Verify that the given two samples actually follow eachother in the list
|
|
|
|
ASSERT(previous->next == to_remove, "Sound samples don't follow eachother in the list, we're probably removing the wrong item.");
|
|
|
|
|
|
|
|
// Remove the item to remove from the linked list by skipping
|
|
|
|
// it in the pointer sequence.
|
|
|
|
previous->next = to_remove->next;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Apparently we're removing the first item from the list. So
|
|
|
|
// make the next one the list's head.
|
|
|
|
active_samples = to_remove->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-12-13 15:16:03 -08:00
|
|
|
static void PrintOpenALVersion(code_part part)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-13 15:16:03 -08:00
|
|
|
debug(part, "OpenAL Vendor: %s", alGetString(AL_VENDOR));
|
|
|
|
debug(part, "OpenAL Version: %s", alGetString(AL_VERSION));
|
|
|
|
debug(part, "OpenAL Renderer: %s", alGetString(AL_RENDERER));
|
|
|
|
debug(part, "OpenAL Extensions: %s", alGetString(AL_EXTENSIONS));
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL sound_InitLibrary( void )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-12-13 15:16:03 -08:00
|
|
|
int err;
|
2007-06-28 10:47:08 -07:00
|
|
|
ALfloat listenerVel[3] = { 0.0, 0.0, 0.0 };
|
|
|
|
ALfloat listenerOri[6] = { 0.0, 0.0, 1.0, 0.0, 1.0, 0.0 };
|
|
|
|
|
|
|
|
device = alcOpenDevice(0);
|
2007-12-13 15:16:03 -08:00
|
|
|
if(device == 0)
|
|
|
|
{
|
|
|
|
PrintOpenALVersion(LOG_ERROR);
|
2007-06-28 10:47:08 -07:00
|
|
|
debug(LOG_ERROR, "Couldn't open audio device.");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
context = alcCreateContext(device, NULL); //NULL was contextAttributes
|
|
|
|
alcMakeContextCurrent(context);
|
2006-06-02 12:34:58 -07:00
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
err = sound_GetDeviceError(device);
|
|
|
|
if (err != ALC_NO_ERROR)
|
|
|
|
{
|
|
|
|
PrintOpenALVersion(LOG_ERROR);
|
|
|
|
debug(LOG_ERROR, "Couldn't initialize audio context: %s", alcGetString(device, err));
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
openal_initialized = TRUE;
|
|
|
|
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
// Clear Error Codes
|
|
|
|
alGetError();
|
|
|
|
alcGetError(device);
|
|
|
|
|
|
|
|
// Check what version of Open AL we are using
|
2007-12-13 15:16:03 -08:00
|
|
|
PrintOpenALVersion(LOG_SOUND);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
alListener3f(AL_POSITION, 0.f, 0.f, 0.f);
|
2007-06-28 10:47:08 -07:00
|
|
|
alListenerfv( AL_VELOCITY, listenerVel );
|
|
|
|
alListenerfv( AL_ORIENTATION, listenerOri );
|
|
|
|
alDistanceModel( AL_NONE );
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_ShutdownLibrary( void )
|
|
|
|
{
|
2006-08-23 05:58:48 -07:00
|
|
|
SAMPLE_LIST * aSample = active_samples, * tmpSample = NULL;
|
|
|
|
|
|
|
|
debug(LOG_SOUND, "sound_ShutdownLibrary: starting shutdown");
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
if(context != 0) {
|
|
|
|
#ifdef WIN32
|
|
|
|
/* Ifdef'ed out the two lines below on Linux since this caused some versions
|
|
|
|
* of OpenAL to hang on exit. - Per */
|
2006-08-23 05:58:48 -07:00
|
|
|
debug(LOG_SOUND, "sound_ShutdownLibrary: make default context NULL");
|
2007-06-28 10:47:08 -07:00
|
|
|
alcMakeContextCurrent(NULL); //this should work now -Q
|
|
|
|
#endif
|
2006-08-23 05:58:48 -07:00
|
|
|
debug(LOG_SOUND, "sound_ShutdownLibrary: destroy previous context");
|
2007-06-28 10:47:08 -07:00
|
|
|
alcDestroyContext(context); // this gives a long delay on some impl.
|
|
|
|
context = 0;
|
|
|
|
}
|
2006-08-23 05:58:48 -07:00
|
|
|
debug(LOG_SOUND, "sound_ShutdownLibrary: close device");
|
2007-06-28 10:47:08 -07:00
|
|
|
if(device != 0) {
|
|
|
|
alcCloseDevice(device);
|
|
|
|
device = 0;
|
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2006-02-18 10:54:37 -08:00
|
|
|
|
2006-08-23 05:58:48 -07:00
|
|
|
while( aSample )
|
2007-12-13 15:47:46 -08:00
|
|
|
{
|
2006-08-23 05:58:48 -07:00
|
|
|
tmpSample = aSample->next;
|
|
|
|
free( aSample );
|
|
|
|
aSample = tmpSample;
|
|
|
|
}
|
2007-12-13 15:16:03 -08:00
|
|
|
active_samples = NULL;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_Update( void )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-12-13 15:16:03 -08:00
|
|
|
int err;
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-12-13 15:16:03 -08:00
|
|
|
SAMPLE_LIST* node = active_samples;
|
|
|
|
SAMPLE_LIST* previous = NULL;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
while (node != NULL)
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-12-13 15:16:03 -08:00
|
|
|
ALenum state;
|
|
|
|
|
|
|
|
alGetSourcei(node->curr->iSample, AL_SOURCE_STATE, &state);
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
// Check whether an error occurred while retrieving the state.
|
|
|
|
// If one did, the state returned is useless. So instead of
|
|
|
|
// using it continue with the next sample.
|
|
|
|
err = sound_GetError();
|
2007-12-13 15:54:28 -08:00
|
|
|
if (err == AL_NO_ERROR)
|
|
|
|
{
|
|
|
|
// Move to the next object
|
|
|
|
previous = node;
|
|
|
|
node = node->next;
|
2007-12-13 15:16:03 -08:00
|
|
|
continue;
|
2007-12-13 15:54:28 -08:00
|
|
|
}
|
2007-12-13 15:16:03 -08:00
|
|
|
|
|
|
|
switch (state)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
case AL_PLAYING:
|
2006-02-11 01:00:20 -08:00
|
|
|
case AL_PAUSED:
|
2007-12-13 15:16:03 -08:00
|
|
|
// If we haven't finished playing yet, just
|
|
|
|
// continue with the next item in the list.
|
|
|
|
|
|
|
|
// sound_SetObjectPosition(i->curr->iSample, i->curr->x, i->curr->y, i->curr->z);
|
|
|
|
|
|
|
|
// Move to the next object
|
|
|
|
previous = node;
|
|
|
|
node = node->next;
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
case AL_STOPPED:
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_FinishedCallback(node->curr);
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-12-13 15:16:03 -08:00
|
|
|
|
|
|
|
default:
|
|
|
|
// If an OpenAL source is associated with this sample, release it
|
|
|
|
if (node->curr->iSample != (ALuint)AL_INVALID)
|
|
|
|
{
|
|
|
|
alDeleteSources(1, &node->curr->iSample);
|
|
|
|
sound_GetError();
|
2006-02-11 01:00:20 -08:00
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-12-13 15:16:03 -08:00
|
|
|
// Remove the sample from the list
|
|
|
|
sound_RemoveSample(previous, node);
|
|
|
|
// Free it
|
|
|
|
free(node);
|
|
|
|
|
|
|
|
// Get a pointer to the next node, the previous pointer doesn't change
|
2007-12-13 15:47:46 -08:00
|
|
|
node = (previous != NULL) ? previous->next : active_samples;
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
break;
|
|
|
|
}
|
2007-12-13 15:16:03 -08:00
|
|
|
#endif
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
cdAudio_Update();
|
2007-06-04 03:01:52 -07:00
|
|
|
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-04 03:01:52 -07:00
|
|
|
// Reset the current error state
|
|
|
|
alcGetError(device);
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
alcProcessContext(context);
|
2007-06-04 03:01:52 -07:00
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
err = sound_GetDeviceError(device);
|
2007-06-04 03:01:52 -07:00
|
|
|
if (err != ALC_NO_ERROR)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
debug(LOG_ERROR, "Error while processing audio context: %s",
|
2007-06-04 03:01:52 -07:00
|
|
|
alGetString(err));
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-12-13 15:16:03 -08:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL sound_QueueSamplePlaying( void )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-03-16 09:20:16 -07:00
|
|
|
if ( current_queue_sample == (ALuint)AL_INVALID )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-12-13 15:16:03 -08:00
|
|
|
|
|
|
|
ALenum state;
|
|
|
|
|
|
|
|
alGetSourcei(current_queue_sample, AL_SOURCE_STATE, &state);
|
|
|
|
|
|
|
|
// Check whether an error occurred while retrieving the state.
|
|
|
|
// If one did, the state returned is useless. So instead of
|
|
|
|
// using it return false.
|
|
|
|
if (sound_GetError() != AL_NO_ERROR)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (state == AL_PLAYING)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-13 15:16:03 -08:00
|
|
|
return TRUE;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
if (current_queue_sample != (ALuint)AL_INVALID)
|
|
|
|
{
|
|
|
|
alDeleteSources(1, ¤t_queue_sample);
|
|
|
|
sound_GetError();
|
|
|
|
current_queue_sample = AL_INVALID;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-12-13 15:16:03 -08:00
|
|
|
return FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-04-30 16:52:51 -07:00
|
|
|
/** Decodes an opened OggVorbis file into an OpenAL buffer
|
|
|
|
* \param psTrack pointer to object which will contain the final buffer
|
|
|
|
* \param PHYSFS_fileHandle file handle given by PhysicsFS to the opened file
|
|
|
|
* \return on success the psTrack pointer, otherwise it will be free'd and a NULL pointer is returned instead
|
|
|
|
*/
|
|
|
|
static inline TRACK* sound_DecodeOggVorbisTrack(TRACK *psTrack, PHYSFS_file* PHYSFS_fileHandle)
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-04-30 16:52:51 -07:00
|
|
|
ALenum format;
|
|
|
|
ALuint buffer;
|
|
|
|
|
2007-05-25 07:56:18 -07:00
|
|
|
struct OggVorbisDecoderState* decoder = sound_CreateOggVorbisDecoder(PHYSFS_fileHandle, TRUE);
|
2007-04-30 16:52:51 -07:00
|
|
|
soundDataBuffer* soundBuffer;
|
|
|
|
|
2007-04-30 17:30:37 -07:00
|
|
|
soundBuffer = sound_DecodeOggVorbis(decoder, 0);
|
2007-04-30 16:52:51 -07:00
|
|
|
sound_DestroyOggVorbisDecoder(decoder);
|
|
|
|
|
|
|
|
if (soundBuffer == NULL)
|
|
|
|
{
|
|
|
|
free(psTrack);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine PCM data format
|
|
|
|
format = (soundBuffer->channelCount == 1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
|
|
|
|
|
|
|
// Create an OpenAL buffer and fill it with the decoded data
|
|
|
|
alGenBuffers(1, &buffer);
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-04-30 16:52:51 -07:00
|
|
|
alBufferData(buffer, format, soundBuffer->data, soundBuffer->size, soundBuffer->frequency);
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-04-30 16:52:51 -07:00
|
|
|
|
2007-04-30 17:30:37 -07:00
|
|
|
free(soundBuffer);
|
|
|
|
|
2007-04-30 16:52:51 -07:00
|
|
|
// save buffer name in track
|
|
|
|
psTrack->iBufferName = buffer;
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-04-30 16:52:51 -07:00
|
|
|
|
|
|
|
return psTrack;
|
|
|
|
}
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2007-04-09 05:16:31 -07:00
|
|
|
TRACK* sound_LoadTrackFromFile(const char *fileName)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-09 05:16:31 -07:00
|
|
|
TRACK* pTrack;
|
2007-04-30 09:55:53 -07:00
|
|
|
PHYSFS_file* fileHandle;
|
2007-11-26 07:16:51 -08:00
|
|
|
size_t filename_size;
|
2007-04-03 04:15:41 -07:00
|
|
|
|
2007-02-18 13:30:51 -08:00
|
|
|
// Use PhysicsFS to open the file
|
2007-04-30 09:55:53 -07:00
|
|
|
fileHandle = PHYSFS_openRead(fileName);
|
|
|
|
if (fileHandle == NULL)
|
2007-04-08 11:51:15 -07:00
|
|
|
{
|
2007-04-30 09:55:53 -07:00
|
|
|
debug(LOG_ERROR, "sound_LoadTrackFromFile: PHYSFS_openRead(\"%s\") failed with error: %s\n", fileName, PHYSFS_getLastError());
|
2007-04-08 11:51:15 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-11-26 07:16:51 -08:00
|
|
|
if (GetLastResourceFilename() == NULL)
|
|
|
|
{
|
|
|
|
// This is a non fatal error. We just can't find filename for some reason.
|
|
|
|
debug(LOG_WARNING, "sound_LoadTrackFromFile: missing resource filename?");
|
|
|
|
filename_size = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
filename_size = strlen(GetLastResourceFilename()) + 1;
|
|
|
|
}
|
|
|
|
|
2007-04-09 05:16:31 -07:00
|
|
|
// allocate track, plus the memory required to contain the filename
|
|
|
|
// one malloc call ensures only one free call is required
|
2007-11-26 07:16:51 -08:00
|
|
|
pTrack = (TRACK*)malloc(sizeof(TRACK) + filename_size);
|
2007-04-09 05:16:31 -07:00
|
|
|
if (pTrack == NULL)
|
|
|
|
{
|
|
|
|
debug( LOG_ERROR, "sound_ConstructTrack: couldn't allocate memory\n" );
|
|
|
|
abort();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize everyting (except for the filename) to zero
|
|
|
|
memset(pTrack, 0, sizeof(TRACK));
|
2007-04-18 05:40:50 -07:00
|
|
|
|
2007-11-26 07:16:51 -08:00
|
|
|
// Set filename pointer; if the filename (as returned by
|
|
|
|
// GetLastResourceFilename()) is a NULL pointer, then this will be a
|
|
|
|
// NULL pointer as well.
|
|
|
|
pTrack->fileName = filename_size ? (const char*)pTrack + sizeof(TRACK) : NULL;
|
2007-10-24 14:11:29 -07:00
|
|
|
|
2007-11-26 07:16:51 -08:00
|
|
|
// Copy the filename into the struct, if we don't have a NULL pointer
|
|
|
|
if (filename_size != 0)
|
2007-11-22 10:35:03 -08:00
|
|
|
{
|
2007-11-26 07:16:51 -08:00
|
|
|
strcpy((char*)pTrack->fileName, GetLastResourceFilename());
|
2007-11-22 10:35:03 -08:00
|
|
|
}
|
|
|
|
|
2007-02-18 13:30:51 -08:00
|
|
|
// Now use sound_ReadTrackFromBuffer to decode the file's contents
|
2007-04-30 16:52:51 -07:00
|
|
|
pTrack = sound_DecodeOggVorbisTrack(pTrack, fileHandle);
|
2007-02-18 14:16:55 -08:00
|
|
|
|
2007-04-30 09:55:53 -07:00
|
|
|
PHYSFS_close(fileHandle);
|
2007-04-09 05:16:31 -07:00
|
|
|
return pTrack;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void sound_FreeTrack( TRACK *psTrack )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-12-13 15:16:03 -08:00
|
|
|
alDeleteBuffers(1, &psTrack->iBufferName);
|
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2006-09-19 11:45:48 -07:00
|
|
|
static void sound_AddActiveSample( AUDIO_SAMPLE *psSample )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
SAMPLE_LIST *tmp = (SAMPLE_LIST *) malloc( sizeof(SAMPLE_LIST) );
|
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
// Prepend the given sample to our list of active samples
|
2007-06-28 10:47:08 -07:00
|
|
|
tmp->curr = psSample;
|
|
|
|
tmp->next = active_samples;
|
|
|
|
active_samples = tmp;
|
|
|
|
}
|
|
|
|
|
2007-12-13 15:47:46 -08:00
|
|
|
/** Routine gets rid of the psObj's sound sample and reference in active_samples.
|
|
|
|
*/
|
|
|
|
void sound_RemoveActiveSample( AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
|
|
|
SAMPLE_LIST* node = active_samples;
|
|
|
|
SAMPLE_LIST* previous = NULL;
|
|
|
|
|
|
|
|
while (node != NULL)
|
|
|
|
{
|
|
|
|
if (node->curr->psObj == psSample->psObj)
|
|
|
|
{
|
|
|
|
debug(LOG_MEMORY, "Removing object 0x%p from active_samples list 0x%p\n", psSample->psObj, node);
|
|
|
|
|
|
|
|
// Buginator: should we wait for it to finish, or just stop it?
|
|
|
|
sound_StopSample(node->curr);
|
|
|
|
|
|
|
|
sound_FinishedCallback(node->curr); //tell the callback it is finished.
|
|
|
|
|
|
|
|
if ( node->curr->iSample != (ALuint)AL_INVALID )
|
|
|
|
{
|
|
|
|
alDeleteSources(1, &node->curr->iSample);
|
|
|
|
sound_GetError();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove it from the linked list
|
|
|
|
sound_RemoveSample(previous, node);
|
|
|
|
|
|
|
|
// free the memory associated with the sample
|
|
|
|
free(node);
|
|
|
|
|
|
|
|
// Get a pointer to the next node, the previous pointer doesn't change
|
|
|
|
node = (previous != NULL) ? previous->next : active_samples;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Move to the next sample object
|
|
|
|
previous = node;
|
|
|
|
node = node->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2007-12-13 15:16:03 -08:00
|
|
|
static bool sound_SetupChannel( AUDIO_SAMPLE *psSample )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
sound_AddActiveSample( psSample );
|
|
|
|
|
2007-12-13 15:16:03 -08:00
|
|
|
return sound_TrackLooped(psSample->iTrack);
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL sound_Play2DSample( TRACK *psTrack, AUDIO_SAMPLE *psSample, BOOL bQueued )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
ALfloat zero[3] = { 0.0, 0.0, 0.0 };
|
2007-11-02 11:47:22 -07:00
|
|
|
ALfloat volume;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-11-02 11:47:22 -07:00
|
|
|
if (sfx_volume == 0.0)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
2007-11-02 15:37:20 -07:00
|
|
|
volume = ((float)psTrack->iVol / 100.0f); // each object can have OWN volume!
|
|
|
|
psSample->fVol = volume; // save computed volume
|
|
|
|
volume *= sfx_volume; // and now take into account the Users sound Prefs.
|
2007-06-28 10:47:08 -07:00
|
|
|
alGenSources( 1, &(psSample->iSample) );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcef( psSample->iSample, AL_PITCH, 1.0f );
|
2007-11-02 11:47:22 -07:00
|
|
|
alSourcef( psSample->iSample, AL_GAIN,volume );
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcefv( psSample->iSample, AL_POSITION, zero );
|
|
|
|
alSourcefv( psSample->iSample, AL_VELOCITY, zero );
|
2006-09-24 11:53:08 -07:00
|
|
|
alSourcei( psSample->iSample, AL_BUFFER, psTrack->iBufferName );
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcei( psSample->iSample, AL_SOURCE_RELATIVE, AL_TRUE );
|
2007-04-12 10:42:15 -07:00
|
|
|
alSourcei( psSample->iSample, AL_LOOPING, (sound_SetupChannel(psSample)) ? AL_TRUE : AL_FALSE );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcePlay( psSample->iSample );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-28 10:47:08 -07:00
|
|
|
if ( bQueued )
|
|
|
|
{
|
|
|
|
current_queue_sample = psSample->iSample;
|
|
|
|
}
|
|
|
|
else if ( current_queue_sample == psSample->iSample )
|
|
|
|
{
|
|
|
|
current_queue_sample = -1;
|
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL sound_Play3DSample( TRACK *psTrack, AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
ALfloat zero[3] = { 0.0, 0.0, 0.0 };
|
2007-11-02 11:47:22 -07:00
|
|
|
ALfloat volume;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-11-02 11:47:22 -07:00
|
|
|
if (sfx3d_volume == 0.0)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
2007-11-02 15:37:20 -07:00
|
|
|
|
|
|
|
volume = ((float)psTrack->iVol / 100.0); // max range is 0-100
|
|
|
|
psSample->fVol = volume; // store results for later
|
2007-06-28 10:47:08 -07:00
|
|
|
alGenSources( 1, &(psSample->iSample) );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-07-14 11:42:39 -07:00
|
|
|
// HACK: this is a workaround for a bug in the 64bit implementation of OpenAL on GNU/Linux
|
|
|
|
// The AL_PITCH value really should be 1.0.
|
|
|
|
alSourcef( psSample->iSample, AL_PITCH, 1.001 );
|
2007-11-02 11:47:22 -07:00
|
|
|
|
|
|
|
sound_SetObjectPosition( psSample );
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcefv( psSample->iSample, AL_VELOCITY, zero );
|
2006-09-24 11:53:08 -07:00
|
|
|
alSourcei( psSample->iSample, AL_BUFFER, psTrack->iBufferName );
|
2007-04-12 10:42:15 -07:00
|
|
|
alSourcei( psSample->iSample, AL_LOOPING, (sound_SetupChannel(psSample)) ? AL_TRUE : AL_FALSE );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcePlay( psSample->iSample );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2006-09-24 11:53:08 -07:00
|
|
|
BOOL sound_PlayStream( AUDIO_SAMPLE *psSample, const char szFileName[], SDWORD iVol )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2007-12-13 15:16:03 -08:00
|
|
|
void sound_StopSample(AUDIO_SAMPLE* psSample)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-12-13 15:16:03 -08:00
|
|
|
if (psSample->iSample == (ALuint)SAMPLE_NOT_ALLOCATED)
|
|
|
|
{
|
|
|
|
debug(LOG_SOUND, "sound_StopSample: sample number (%u) out of range, we probably have run out of available OpenAL sources", psSample->iSample);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tell OpenAL to stop playing the given sample
|
|
|
|
alSourceStop(psSample->iSample);
|
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_SetPlayerPos( SDWORD iX, SDWORD iY, SDWORD iZ )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-01-17 13:39:38 -08:00
|
|
|
alListener3f( AL_POSITION, iX, iY, iZ );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2007-01-07 08:28:54 -08:00
|
|
|
/** sets player's sound orientation
|
|
|
|
* \param iX pitch in degree (current function implementation ignores this)
|
|
|
|
* \param iY roll in degree (current function implementation ignores this)
|
|
|
|
* \param iZ yaw in degree
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
void sound_SetPlayerOrientation( SDWORD iX, SDWORD iY, SDWORD iZ )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
//~~~~~~~~~~~
|
|
|
|
float ori[6];
|
|
|
|
//~~~~~~~~~~~
|
|
|
|
|
2007-01-07 08:28:54 -08:00
|
|
|
// convert params to rad
|
2007-02-19 06:10:44 -08:00
|
|
|
// float pitch = (float)iX * M_PI / 180;
|
|
|
|
// float roll = (float)iY * M_PI / 180;
|
2007-01-07 08:28:54 -08:00
|
|
|
float yaw = (float)iZ * M_PI / 180;
|
|
|
|
|
|
|
|
ori[0] = -sin( yaw );
|
|
|
|
ori[1] = cos( yaw );
|
2007-06-28 10:47:08 -07:00
|
|
|
ori[2] = 0;
|
|
|
|
ori[3] = 0;
|
|
|
|
ori[4] = 0;
|
|
|
|
ori[5] = 1;
|
|
|
|
alListenerfv( AL_ORIENTATION, ori );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2007-11-02 11:47:22 -07:00
|
|
|
void sound_SetObjectPosition(AUDIO_SAMPLE *psSample)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2007-01-07 08:28:54 -08:00
|
|
|
// coordinates
|
|
|
|
float listenerX, listenerY, listenerZ, dX, dY, dZ;
|
|
|
|
|
|
|
|
// calculation results
|
|
|
|
float distance, gain;
|
2007-06-28 10:47:08 -07:00
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
2007-01-07 08:28:54 -08:00
|
|
|
// compute distance
|
|
|
|
alGetListener3f( AL_POSITION, &listenerX, &listenerY, &listenerZ );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-11-02 11:47:22 -07:00
|
|
|
dX = psSample->x - listenerX; // distances on all axis
|
|
|
|
dY = psSample->y - listenerY;
|
|
|
|
dZ = psSample->z - listenerZ;
|
2007-05-20 07:47:32 -07:00
|
|
|
distance = sqrtf(dX * dX + dY * dY + dZ * dZ); // Pythagorean theorem
|
2007-01-07 08:28:54 -08:00
|
|
|
|
2007-11-02 11:47:22 -07:00
|
|
|
// compute gain
|
|
|
|
gain = (1.0 - (distance * ATTENUATION_FACTOR)) * psSample->fVol * sfx3d_volume;
|
|
|
|
if (gain > 1.0)
|
|
|
|
{
|
|
|
|
gain = 1.0;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
if ( gain < 0.0 )
|
|
|
|
{
|
|
|
|
gain = 0.0;
|
|
|
|
}
|
2007-11-02 11:47:22 -07:00
|
|
|
alSourcef( psSample->iSample, AL_GAIN, gain );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-01-08 14:35:43 -08:00
|
|
|
// the alSource3i variant would be better, if it wouldn't provide linker errors however
|
2007-11-02 11:47:22 -07:00
|
|
|
alSource3f( psSample->iSample, AL_POSITION, (float)psSample->x,(float)psSample->x,(float)psSample->x );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_PauseSample( AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcePause( psSample->iSample );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_ResumeSample( AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
alSourcePlay( psSample->iSample );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError();
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_PauseAll( void )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_ResumeAll( void )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void sound_StopAll( void )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL sound_SampleIsFinished( AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
//~~~~~~~~~~
|
|
|
|
ALenum state;
|
|
|
|
//~~~~~~~~~~
|
|
|
|
|
|
|
|
alGetSourcei( psSample->iSample, AL_SOURCE_STATE, &state );
|
2007-12-13 15:16:03 -08:00
|
|
|
sound_GetError(); // check for an error and clear the error state for later on in this function
|
|
|
|
if (state == AL_PLAYING || state == AL_PAUSED)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-12-13 15:16:03 -08:00
|
|
|
|
|
|
|
if (psSample->iSample != (ALuint)AL_INVALID)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-12-13 15:16:03 -08:00
|
|
|
alDeleteSources(1, &(psSample->iSample));
|
|
|
|
sound_GetError();
|
|
|
|
psSample->iSample = AL_INVALID;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-12-13 15:16:03 -08:00
|
|
|
return TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
|
2007-06-25 11:09:38 -07:00
|
|
|
float sound_GetUIVolume()
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-25 11:09:38 -07:00
|
|
|
return sfx_volume;
|
2007-06-06 10:09:23 -07:00
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-06-25 11:09:38 -07:00
|
|
|
void sound_SetUIVolume(float volume)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-25 11:09:38 -07:00
|
|
|
sfx_volume = volume;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-25 11:09:38 -07:00
|
|
|
// Keep volume in the range of 0.0 - 1.0
|
|
|
|
if (sfx_volume < 0.0)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
sfx_volume = 0.0;
|
2007-06-25 11:09:38 -07:00
|
|
|
}
|
|
|
|
else if (sfx_volume > 1.0)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
sfx_volume = 1.0;
|
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-06-25 11:09:38 -07:00
|
|
|
float sound_GetEffectsVolume()
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-25 11:09:38 -07:00
|
|
|
return sfx3d_volume;
|
2007-06-06 10:09:23 -07:00
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-06-25 11:09:38 -07:00
|
|
|
void sound_SetEffectsVolume(float volume)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-25 11:09:38 -07:00
|
|
|
sfx3d_volume = volume;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-06-25 11:09:38 -07:00
|
|
|
// Keep volume in the range of 0.0 - 1.0
|
|
|
|
if (sfx3d_volume < 0.0)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
sfx3d_volume = 0.0;
|
2007-06-25 11:09:38 -07:00
|
|
|
}
|
|
|
|
else if (sfx3d_volume > 1.0)
|
|
|
|
{
|
2007-06-28 10:47:08 -07:00
|
|
|
sfx3d_volume = 1.0;
|
|
|
|
}
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|