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
|
|
|
//*
|
|
|
|
//
|
|
|
|
#include <stdio.h>
|
2006-11-06 06:40:07 -08:00
|
|
|
#include <string.h>
|
2006-06-02 12:34:58 -07:00
|
|
|
#include "lib/framework/frame.h"
|
2006-09-23 11:38:12 -07:00
|
|
|
#include "lib/framework/frameresource.h"
|
2006-06-02 12:34:58 -07:00
|
|
|
#include "lib/gamelib/gtime.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
#include "tracklib.h"
|
|
|
|
#include "aud.h"
|
2007-03-27 11:59:03 -07:00
|
|
|
#include "audio_id.h"
|
2006-06-02 12:34:58 -07:00
|
|
|
#include "lib/framework/trig.h"
|
2007-03-16 09:20:16 -07:00
|
|
|
#include "lib/ivis_common/pietypes.h"
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
// defines
|
|
|
|
#define NO_SAMPLE - 2
|
|
|
|
#define AUDIO_SAMPLE_HEAP_INIT 1000
|
|
|
|
#define AUDIO_SAMPLE_HEAP_EXT 10
|
|
|
|
#define MAX_SAME_SAMPLES 2
|
|
|
|
#define LOWERED_VOL AUDIO_VOL_MAX / 4
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
// externs
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
// static functions
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
// global variables
|
|
|
|
static AUDIO_SAMPLE *g_psSampleList = NULL;
|
|
|
|
static AUDIO_SAMPLE *g_psSampleQueue = NULL;
|
|
|
|
static BOOL g_bAudioEnabled = FALSE;
|
|
|
|
static BOOL g_bAudioPaused = FALSE;
|
|
|
|
static BOOL g_bStopAll = FALSE;
|
2007-05-06 13:20:45 -07:00
|
|
|
static AUDIO_SAMPLE g_sPreviousSample;
|
2007-03-16 09:20:16 -07:00
|
|
|
static SDWORD g_i3DVolume = AUDIO_VOL_MAX;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL audio_Disabled( void )
|
|
|
|
{
|
|
|
|
return !g_bAudioEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2006-04-01 09:50:19 -08:00
|
|
|
BOOL audio_Init( AUDIO_CALLBACK pStopTrackCallback )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
// init audio system
|
2007-05-06 13:20:45 -07:00
|
|
|
g_sPreviousSample.iTrack = NO_SAMPLE;
|
|
|
|
g_sPreviousSample.x = SAMPLE_COORD_INVALID;
|
|
|
|
g_sPreviousSample.y = SAMPLE_COORD_INVALID;
|
|
|
|
g_sPreviousSample.z = SAMPLE_COORD_INVALID;
|
2006-08-12 09:52:37 -07:00
|
|
|
g_bAudioEnabled = sound_Init(MAX_SAME_SAMPLES);
|
|
|
|
if (g_bAudioEnabled)
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
sound_SetStoppedCallback( pStopTrackCallback );
|
|
|
|
}
|
2006-04-01 09:50:19 -08:00
|
|
|
return g_bAudioEnabled;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL audio_Shutdown( void )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample = NULL, *psSampleTemp = NULL;
|
|
|
|
BOOL bOK;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
sound_StopAll();
|
|
|
|
bOK = sound_Shutdown();
|
|
|
|
|
|
|
|
// empty sample list
|
|
|
|
psSample = g_psSampleList;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
|
|
|
psSampleTemp = psSample->psNext;
|
2007-06-05 04:46:00 -07:00
|
|
|
free(psSample);
|
2007-06-28 10:47:08 -07:00
|
|
|
psSample = psSampleTemp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// empty sample queue
|
|
|
|
psSample = g_psSampleQueue;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
|
|
|
psSampleTemp = psSample->psNext;
|
2007-06-05 04:46:00 -07:00
|
|
|
free(psSample);
|
2007-06-28 10:47:08 -07:00
|
|
|
psSample = psSampleTemp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// free sample heap
|
|
|
|
g_psSampleList = NULL;
|
|
|
|
g_psSampleQueue = NULL;
|
|
|
|
|
|
|
|
return bOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_PlayPreviousQueueTrack( void )
|
|
|
|
{
|
|
|
|
if ( g_sPreviousSample.iTrack != NO_SAMPLE )
|
|
|
|
{
|
|
|
|
audio_PlayTrack( g_sPreviousSample.iTrack );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL audio_GetPreviousQueueTrackPos( SDWORD *iX, SDWORD *iY, SDWORD *iZ )
|
|
|
|
{
|
2007-04-05 13:19:58 -07:00
|
|
|
if ( g_sPreviousSample.x == SAMPLE_COORD_INVALID || g_sPreviousSample.y == SAMPLE_COORD_INVALID
|
|
|
|
|| g_sPreviousSample.z == SAMPLE_COORD_INVALID )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
*iX = *iY = *iZ;
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
|
|
|
*iX = g_sPreviousSample.x;
|
|
|
|
*iY = g_sPreviousSample.y;
|
|
|
|
*iZ = g_sPreviousSample.z;
|
|
|
|
|
|
|
|
return TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
static void audio_AddSampleToHead( AUDIO_SAMPLE **ppsSampleList, AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
|
|
|
psSample->psNext = ( *ppsSampleList );
|
|
|
|
psSample->psPrev = NULL;
|
|
|
|
if ( (*ppsSampleList) != NULL )
|
|
|
|
{
|
|
|
|
( *ppsSampleList )->psPrev = psSample;
|
|
|
|
}
|
|
|
|
( *ppsSampleList ) = psSample;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
static void audio_AddSampleToTail( AUDIO_SAMPLE **ppsSampleList, AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSampleTail = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
if ( (*ppsSampleList) == NULL )
|
|
|
|
{
|
|
|
|
( *ppsSampleList ) = psSample;
|
2007-04-05 13:19:58 -07:00
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-04-05 13:19:58 -07:00
|
|
|
psSampleTail = ( *ppsSampleList );
|
|
|
|
while ( psSampleTail->psNext != NULL )
|
|
|
|
{
|
|
|
|
psSampleTail = psSampleTail->psNext;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
|
|
|
psSampleTail->psNext = psSample;
|
|
|
|
psSample->psPrev = psSampleTail;
|
|
|
|
psSample->psNext = NULL;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
// audio_RemoveSample Removes sample from list but doesn't free its memory
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
static void audio_RemoveSample( AUDIO_SAMPLE **ppsSampleList, AUDIO_SAMPLE *psSample )
|
|
|
|
{
|
|
|
|
if ( psSample == NULL )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( psSample == (*ppsSampleList) )
|
|
|
|
{
|
|
|
|
// first sample in list
|
|
|
|
( *ppsSampleList ) = psSample->psNext;
|
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
|
|
|
if ( psSample->psPrev != NULL )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-05 13:19:58 -07:00
|
|
|
psSample->psPrev->psNext = psSample->psNext;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-05 13:19:58 -07:00
|
|
|
if ( psSample->psNext != NULL )
|
|
|
|
{
|
|
|
|
psSample->psNext->psPrev = psSample->psPrev;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// set sample pointers NULL for safety
|
|
|
|
psSample->psPrev = NULL;
|
|
|
|
psSample->psNext = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
static BOOL audio_CheckSameQueueTracksPlaying( SDWORD iTrack )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
SDWORD iCount;
|
|
|
|
AUDIO_SAMPLE *psSample = NULL;
|
|
|
|
BOOL bOK = TRUE;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE )
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
iCount = 0;
|
|
|
|
|
|
|
|
// loop through queue sounds and check whether too many already in it
|
|
|
|
psSample = g_psSampleQueue;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
|
|
|
if ( psSample->iTrack == iTrack )
|
|
|
|
{
|
|
|
|
iCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( iCount > MAX_SAME_SAMPLES )
|
|
|
|
{
|
|
|
|
bOK = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
psSample = psSample->psNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2006-09-19 11:45:48 -07:00
|
|
|
static AUDIO_SAMPLE *audio_QueueSample( SDWORD iTrack )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE || g_bStopAll == TRUE )
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-08-23 05:58:48 -07:00
|
|
|
ASSERT( sound_CheckTrack(iTrack) == TRUE, "audio_QueueSample: track %i outside limits\n", iTrack );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
|
|
|
// reject track if too many of same ID already in queue
|
|
|
|
if ( audio_CheckSameQueueTracksPlaying(iTrack) == FALSE )
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-06-05 04:46:00 -07:00
|
|
|
psSample = malloc(sizeof(AUDIO_SAMPLE));
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( psSample == NULL )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-05 04:46:00 -07:00
|
|
|
debug(LOG_ERROR, "audio_QueueSample: Out of memory");
|
2007-04-12 10:42:15 -07:00
|
|
|
return NULL;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
memset( psSample, 0, sizeof(AUDIO_SAMPLE) ); //[check] -Q
|
|
|
|
psSample->iTrack = iTrack;
|
|
|
|
psSample->x = SAMPLE_COORD_INVALID;
|
|
|
|
psSample->y = SAMPLE_COORD_INVALID;
|
|
|
|
psSample->z = SAMPLE_COORD_INVALID;
|
|
|
|
psSample->bFinishedPlaying = FALSE;
|
|
|
|
|
|
|
|
// add to queue
|
|
|
|
audio_AddSampleToTail( &g_psSampleQueue, psSample );
|
|
|
|
|
2007-06-28 10:47:08 -07:00
|
|
|
return psSample;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_QueueTrack( SDWORD iTrack )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE || g_bStopAll == TRUE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
psSample = audio_QueueSample( iTrack );
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// * audio_QueueTrackMinDelay Will only play track if iMinDelay has elapsed since
|
|
|
|
// * track last finished
|
|
|
|
//
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_QueueTrackMinDelay( SDWORD iTrack, UDWORD iMinDelay )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2007-04-12 10:42:15 -07:00
|
|
|
AUDIO_SAMPLE *psSample;
|
2007-06-28 10:47:08 -07:00
|
|
|
UDWORD iDelay;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// Determine if at least iMinDelay time has passed since the last time this track was played
|
2007-06-28 10:47:08 -07:00
|
|
|
iDelay = sound_GetGameTime() - sound_GetTrackTimeLastFinished( iTrack );
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( !(iDelay > iMinDelay) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Construct an audio sample from requested track
|
|
|
|
psSample = audio_QueueSample( iTrack );
|
|
|
|
if ( psSample == NULL )
|
|
|
|
{
|
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-21 06:03:52 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// Set last finished tracktime to current time to prevent parallel playing of this track
|
|
|
|
sound_SetTrackTimeLastFinished( iTrack, sound_GetGameTime() );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_QueueTrackMinDelayPos( SDWORD iTrack, UDWORD iMinDelay, SDWORD iX, SDWORD iY, SDWORD iZ )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2007-04-12 10:42:15 -07:00
|
|
|
AUDIO_SAMPLE *psSample;
|
2007-06-28 10:47:08 -07:00
|
|
|
UDWORD iDelay;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// Determine if at least iMinDelay time has passed since the last time this track was played
|
2007-06-28 10:47:08 -07:00
|
|
|
iDelay = sound_GetGameTime() - sound_GetTrackTimeLastFinished( iTrack );
|
|
|
|
if ( iDelay > iMinDelay )
|
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-04-12 10:42:15 -07:00
|
|
|
|
|
|
|
// Construct an audio sample from requested track
|
|
|
|
psSample = audio_QueueSample( iTrack );
|
|
|
|
if ( psSample == NULL )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2007-06-21 06:03:52 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
psSample->x = iX;
|
|
|
|
psSample->y = iY;
|
|
|
|
psSample->z = iZ;
|
|
|
|
|
|
|
|
// Set last finished tracktime to current time to prevent parallel playing of this track
|
|
|
|
sound_SetTrackTimeLastFinished( iTrack, sound_GetGameTime() );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_QueueTrackPos( SDWORD iTrack, SDWORD iX, SDWORD iY, SDWORD iZ )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2007-04-12 10:42:15 -07:00
|
|
|
AUDIO_SAMPLE *psSample;
|
2007-06-28 10:47:08 -07:00
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// Construct an audio sample from requested track
|
2007-06-28 10:47:08 -07:00
|
|
|
psSample = audio_QueueSample( iTrack );
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( psSample == NULL )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-04-12 10:42:15 -07:00
|
|
|
|
|
|
|
psSample->x = iX;
|
|
|
|
psSample->y = iY;
|
|
|
|
psSample->z = iZ;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2006-09-19 11:45:48 -07:00
|
|
|
static void audio_UpdateQueue( void )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2007-04-12 10:42:15 -07:00
|
|
|
AUDIO_SAMPLE *psSample;
|
2007-06-28 10:47:08 -07:00
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( sound_QueueSamplePlaying() == TRUE )
|
|
|
|
{
|
|
|
|
// lower volume whilst playing queue audio
|
|
|
|
audio_Set3DVolume( LOWERED_VOL );
|
2007-04-05 13:19:58 -07:00
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
|
|
|
// set full global volume
|
|
|
|
audio_Set3DVolume( AUDIO_VOL_MAX );
|
|
|
|
|
|
|
|
// check queue for members
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( g_psSampleQueue == NULL )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
return;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// remove queue head
|
|
|
|
psSample = g_psSampleQueue;
|
|
|
|
audio_RemoveSample( &g_psSampleQueue, psSample );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// add sample to list if able to play
|
|
|
|
if ( !sound_Play2DTrack(psSample, TRUE) )
|
|
|
|
{
|
|
|
|
debug( LOG_NEVER, "audio_UpdateQueue: couldn't play sample\n" );
|
2007-06-05 04:46:00 -07:00
|
|
|
free(psSample);
|
2007-04-12 10:42:15 -07:00
|
|
|
return;
|
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
audio_AddSampleToHead( &g_psSampleList, psSample );
|
|
|
|
|
|
|
|
// update last queue sound coords
|
|
|
|
if ( psSample->x != SAMPLE_COORD_INVALID && psSample->y != SAMPLE_COORD_INVALID
|
|
|
|
&& psSample->z != SAMPLE_COORD_INVALID )
|
|
|
|
{
|
|
|
|
g_sPreviousSample.x = psSample->x;
|
|
|
|
g_sPreviousSample.y = psSample->y;
|
|
|
|
g_sPreviousSample.z = psSample->z;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2007-04-12 10:42:15 -07:00
|
|
|
void audio_Update( void )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2007-03-16 09:20:16 -07:00
|
|
|
Vector3i vecPlayer;
|
2007-06-28 10:47:08 -07:00
|
|
|
SDWORD iA;
|
|
|
|
AUDIO_SAMPLE *psSample, *psSampleTemp;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
audio_UpdateQueue();
|
|
|
|
|
|
|
|
// get player position
|
|
|
|
if ( audio_Display3D() == TRUE )
|
|
|
|
{
|
|
|
|
audio_Get3DPlayerPos( &vecPlayer.x, &vecPlayer.y, &vecPlayer.z );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
audio_Get2DPlayerPos( &vecPlayer.x, &vecPlayer.y, &vecPlayer.z );
|
|
|
|
}
|
|
|
|
|
|
|
|
sound_SetPlayerPos( vecPlayer.x, vecPlayer.y, vecPlayer.z );
|
|
|
|
audio_Get3DPlayerRotAboutVerticalAxis( &iA );
|
|
|
|
sound_SetPlayerOrientation( 0, 0, iA );
|
|
|
|
|
|
|
|
// loop through 3D sounds and remove if finished or update position
|
|
|
|
psSample = g_psSampleList;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
|
|
|
// remove finished samples from list
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( psSample->bFinishedPlaying == TRUE )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
audio_RemoveSample( &g_psSampleList, psSample );
|
|
|
|
psSampleTemp = psSample->psNext;
|
2007-06-05 04:46:00 -07:00
|
|
|
free(psSample);
|
2007-06-28 10:47:08 -07:00
|
|
|
psSample = psSampleTemp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// check looping sound callbacks for finished condition
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( psSample->psObj != NULL )
|
|
|
|
{
|
|
|
|
if ( audio_ObjectDead(psSample->psObj)
|
2007-04-12 03:31:11 -07:00
|
|
|
|| (psSample->pCallback != NULL && psSample->pCallback(psSample->psObj) == FALSE) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
sound_StopTrack( psSample );
|
|
|
|
psSample->psObj = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// update sample position
|
|
|
|
{
|
|
|
|
audio_GetObjectPos( psSample->psObj, &psSample->x, &psSample->y, &psSample->z );
|
2007-06-06 10:09:23 -07:00
|
|
|
#ifndef WZ_NOSOUND
|
2007-06-28 10:47:08 -07:00
|
|
|
sound_SetObjectPosition( psSample->iSample, psSample->x, psSample->y, psSample->z );
|
2007-06-06 10:09:23 -07:00
|
|
|
#endif
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// next sample
|
|
|
|
psSample = psSample->psNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sound_Update();
|
2007-04-12 10:42:15 -07:00
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-05 11:14:18 -07:00
|
|
|
/** Loads audio files and constructs a TRACK from them and returns their respective ID numbers
|
|
|
|
* \param szFileName the filename of the track
|
|
|
|
* \param bLoop whether the track should be looped until explicitly stopped
|
2007-04-12 03:31:11 -07:00
|
|
|
* \param iTrack[out] the track id number is returned into the variable this pointer points to
|
2007-04-05 11:14:18 -07:00
|
|
|
* \param iVol the volume this track should be played on (range is 0-100)
|
|
|
|
* \param iAudibleRadius the radius from the source of sound where it can be heard
|
|
|
|
* \return TRUE when succesfull or audio is disabled, FALSE when the file is not found or no more tracks can be loaded (i.e. the limit is reached)
|
|
|
|
*/
|
2007-06-28 10:47:08 -07:00
|
|
|
BOOL audio_SetTrackVals
|
|
|
|
(
|
2007-04-12 03:31:11 -07:00
|
|
|
const char *fileName,
|
2007-06-28 10:47:08 -07:00
|
|
|
BOOL bLoop,
|
2007-04-05 13:19:58 -07:00
|
|
|
int *iTrack,
|
2007-06-28 10:47:08 -07:00
|
|
|
int iVol,
|
2006-11-26 03:45:04 -08:00
|
|
|
int iAudibleRadius
|
2007-06-28 10:47:08 -07:00
|
|
|
)
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~
|
|
|
|
TRACK *psTrack;
|
|
|
|
//~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get track pointer from resource
|
2007-04-12 03:31:11 -07:00
|
|
|
psTrack = (TRACK*)resGetData( "WAV", fileName ); //at this point we have 4 valid entries, and 8 invalid -Q
|
2007-06-28 10:47:08 -07:00
|
|
|
if ( psTrack == NULL )
|
|
|
|
{
|
2007-04-12 03:31:11 -07:00
|
|
|
debug( LOG_NEVER, "audio_SetTrackVals: track %s resource not found\n", fileName );
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
2007-04-05 11:14:18 -07:00
|
|
|
|
|
|
|
// get current ID or spare one
|
2007-04-12 03:31:11 -07:00
|
|
|
if ( (*iTrack = audio_GetIDFromStr(fileName)) == NO_SOUND )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-05 13:19:58 -07:00
|
|
|
*iTrack = sound_GetAvailableID();
|
2007-04-05 11:14:18 -07:00
|
|
|
}
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-05 13:19:58 -07:00
|
|
|
if ( *iTrack == SAMPLE_NOT_ALLOCATED )
|
2007-04-05 11:14:18 -07:00
|
|
|
{
|
|
|
|
debug( LOG_NEVER, "audio_SetTrackVals: couldn't get spare track ID\n" );
|
|
|
|
return FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-04-05 11:14:18 -07:00
|
|
|
|
2007-04-05 13:19:58 -07:00
|
|
|
return sound_SetTrackVals( psTrack, bLoop, *iTrack, iVol, iAudibleRadius ); //now psTrack should be fully set. -Q
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_ReleaseTrack( TRACK *psTrack )
|
|
|
|
{
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sound_ReleaseTrack( psTrack );
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// * audio_CheckSame3DTracksPlaying Reject samples if too many already playing in
|
|
|
|
// * same area
|
|
|
|
//
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
static BOOL audio_CheckSame3DTracksPlaying( SDWORD iTrack, SDWORD iX, SDWORD iY, SDWORD iZ )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
SDWORD iCount, iDx, iDy, iDz, iDistSq, iMaxDistSq, iRad;
|
|
|
|
AUDIO_SAMPLE *psSample = NULL;
|
|
|
|
BOOL bOK = TRUE;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE )
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
iCount = 0;
|
|
|
|
|
|
|
|
// loop through 3D sounds and check whether too many already in earshot
|
|
|
|
psSample = g_psSampleList;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
|
|
|
if ( psSample->iTrack == iTrack )
|
|
|
|
{
|
|
|
|
iDx = iX - psSample->x;
|
|
|
|
iDy = iY - psSample->y;
|
|
|
|
iDz = iZ - psSample->z;
|
|
|
|
iDistSq = ( iDx * iDx ) + ( iDy * iDy ) + ( iDz * iDz );
|
|
|
|
iRad = sound_GetTrackAudibleRadius( iTrack );
|
|
|
|
iMaxDistSq = iRad * iRad;
|
|
|
|
if ( iDistSq < iMaxDistSq )
|
|
|
|
{
|
|
|
|
iCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( iCount > MAX_SAME_SAMPLES )
|
|
|
|
{
|
|
|
|
bOK = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
psSample = psSample->psNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
static BOOL audio_Play3DTrack( SDWORD iX, SDWORD iY, SDWORD iZ, int iTrack, void *psObj, AUDIO_CALLBACK pUserCallback )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE || g_bStopAll == TRUE )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( audio_CheckSame3DTracksPlaying(iTrack, iX, iY, iZ) == FALSE )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-06-05 04:46:00 -07:00
|
|
|
psSample = malloc(sizeof(AUDIO_SAMPLE));
|
2007-06-28 10:47:08 -07:00
|
|
|
if ( psSample == NULL )
|
|
|
|
{
|
2007-06-05 04:46:00 -07:00
|
|
|
debug(LOG_ERROR, "audio_Play3DTrack: Out of memory");
|
2007-06-28 10:47:08 -07:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-04-05 13:19:58 -07:00
|
|
|
// setup sample
|
|
|
|
memset( psSample, 0, sizeof(AUDIO_SAMPLE) ); // [check] -Q
|
|
|
|
psSample->iTrack = iTrack;
|
|
|
|
psSample->x = iX;
|
|
|
|
psSample->y = iY;
|
|
|
|
psSample->z = iZ;
|
2007-04-12 10:42:15 -07:00
|
|
|
psSample->bFinishedPlaying = FALSE;
|
2007-04-05 13:19:58 -07:00
|
|
|
psSample->psObj = psObj;
|
|
|
|
psSample->pCallback = pUserCallback;
|
|
|
|
|
|
|
|
// add sample to list if able to play
|
|
|
|
if ( !sound_Play3DTrack(psSample) )
|
|
|
|
{
|
|
|
|
debug( LOG_NEVER, "audio_Play3DTrack: couldn't play sample\n" );
|
2007-06-05 04:46:00 -07:00
|
|
|
free(psSample);
|
2007-04-05 13:19:58 -07:00
|
|
|
return FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
|
|
|
audio_AddSampleToHead( &g_psSampleList, psSample );
|
|
|
|
return TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL audio_PlayStaticTrack( SDWORD iMapX, SDWORD iMapY, int iTrack )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
SDWORD iX, iY, iZ;
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
audio_GetStaticPos( iMapX, iMapY, &iX, &iY, &iZ );
|
|
|
|
return audio_Play3DTrack( iX, iY, iZ, iTrack, NULL, NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL audio_PlayObjStaticTrack( void *psObj, int iTrack )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
SDWORD iX, iY, iZ;
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
audio_GetObjectPos( psObj, &iX, &iY, &iZ );
|
|
|
|
return audio_Play3DTrack( iX, iY, iZ, iTrack, psObj, NULL );
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL audio_PlayObjStaticTrackCallback( void *psObj, int iTrack, AUDIO_CALLBACK pUserCallback )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
SDWORD iX, iY, iZ;
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
audio_GetObjectPos( psObj, &iX, &iY, &iZ );
|
|
|
|
return audio_Play3DTrack( iX, iY, iZ, iTrack, psObj, pUserCallback );
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
BOOL audio_PlayObjDynamicTrack( void *psObj, int iTrack, AUDIO_CALLBACK pUserCallback )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
SDWORD iX, iY, iZ;
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
audio_GetObjectPos( psObj, &iX, &iY, &iZ );
|
|
|
|
return audio_Play3DTrack( iX, iY, iZ, iTrack, psObj, pUserCallback );
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2006-09-24 12:11:34 -07:00
|
|
|
BOOL audio_PlayStream( const char szFileName[], SDWORD iVol, AUDIO_CALLBACK pUserCallback )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// if audio not enabled return TRUE to carry on game without audio
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-06-05 04:46:00 -07:00
|
|
|
psSample = malloc(sizeof(AUDIO_SAMPLE));
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( psSample == NULL )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-05 04:46:00 -07:00
|
|
|
debug(LOG_ERROR, "audio_PlayStream: Out of memory");
|
2007-04-12 10:42:15 -07:00
|
|
|
return FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-06-21 06:03:52 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
memset( psSample, 0, sizeof(AUDIO_SAMPLE) );
|
|
|
|
psSample->pCallback = pUserCallback;
|
|
|
|
psSample->bFinishedPlaying = FALSE;
|
|
|
|
audio_Set3DVolume( AUDIO_VOL_MAX );
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( !sound_PlayStream(psSample, szFileName, iVol) )
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_StopObjTrack( void *psObj, int iTrack )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bStopAll == TRUE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// find sample
|
|
|
|
psSample = g_psSampleList;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
// If track has been found stop it and return
|
2007-06-28 10:47:08 -07:00
|
|
|
if ( psSample->psObj == psObj && psSample->iTrack == iTrack )
|
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
sound_StopTrack(psSample);
|
|
|
|
return;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
2007-04-15 15:46:57 -07:00
|
|
|
// get next sample from linked list
|
2007-06-28 10:47:08 -07:00
|
|
|
psSample = psSample->psNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
// audio_PlayTrack Play immediate 2D FX track
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_PlayTrack( int iTrack )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE || g_bAudioPaused == TRUE || g_bStopAll == TRUE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// Allocate a sample
|
2007-06-05 04:46:00 -07:00
|
|
|
psSample = malloc(sizeof(AUDIO_SAMPLE));
|
2007-04-12 10:42:15 -07:00
|
|
|
if ( psSample == NULL )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-06-05 04:46:00 -07:00
|
|
|
debug(LOG_ERROR, "audio_PlayTrack: Out of memory");
|
2007-06-28 10:47:08 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// setup/initialize sample
|
|
|
|
psSample->iTrack = iTrack;
|
|
|
|
psSample->bFinishedPlaying = FALSE;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
// Zero callback stuff since we don't need/want it
|
|
|
|
psSample->pCallback = NULL;
|
|
|
|
psSample->psObj = NULL;
|
2007-06-28 10:47:08 -07:00
|
|
|
|
2007-04-12 10:42:15 -07:00
|
|
|
/* iSample, psPrev, and psNext will be initialized by the
|
|
|
|
* following functions, and x, y and z will be completely
|
|
|
|
* ignored so we don't need to bother about it
|
|
|
|
*/
|
|
|
|
|
|
|
|
// add sample to list if able to play
|
|
|
|
if ( !sound_Play2DTrack(psSample, FALSE) )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-12 10:42:15 -07:00
|
|
|
debug( LOG_NEVER, "audio_PlayTrack: couldn't play sample\n" );
|
2007-06-05 04:46:00 -07:00
|
|
|
free(psSample);
|
2007-06-28 10:47:08 -07:00
|
|
|
return;
|
|
|
|
}
|
2007-04-12 10:42:15 -07:00
|
|
|
|
|
|
|
audio_AddSampleToHead( &g_psSampleList, psSample );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_PauseAll( void )
|
|
|
|
{
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_bAudioPaused = TRUE;
|
|
|
|
sound_PauseAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_ResumeAll( void )
|
|
|
|
{
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_bAudioPaused = FALSE;
|
|
|
|
sound_ResumeAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_StopAll( void )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
AUDIO_SAMPLE *psSample, *psSampleTemp;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-08-22 07:28:49 -07:00
|
|
|
debug( LOG_NEVER, "audio_StopAll called\n" );
|
2007-06-28 10:47:08 -07:00
|
|
|
g_bStopAll = TRUE;
|
|
|
|
|
|
|
|
//
|
|
|
|
// * empty list - audio_Update will free samples because callbacks have to come in
|
|
|
|
// * first
|
|
|
|
//
|
|
|
|
psSample = g_psSampleList;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
|
|
|
sound_StopTrack( psSample );
|
|
|
|
psSample = psSample->psNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
// empty sample queue
|
|
|
|
psSample = g_psSampleQueue;
|
|
|
|
while ( psSample != NULL )
|
|
|
|
{
|
|
|
|
psSampleTemp = psSample->psNext;
|
2007-06-05 04:46:00 -07:00
|
|
|
free(psSample);
|
2007-06-28 10:47:08 -07:00
|
|
|
psSample = psSampleTemp;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_psSampleQueue = NULL;
|
|
|
|
g_bStopAll = FALSE;
|
2006-08-22 07:28:49 -07:00
|
|
|
debug( LOG_NEVER, "audio_StopAll done\n" );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
2007-04-16 07:53:09 -07:00
|
|
|
SDWORD audio_GetTrackID( const char *fileName )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~
|
|
|
|
TRACK *psTrack;
|
|
|
|
//~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return SAMPLE_NOT_FOUND;
|
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
2007-04-16 07:53:09 -07:00
|
|
|
psTrack = (TRACK*)resGetData( "WAV", fileName );
|
2007-04-05 13:19:58 -07:00
|
|
|
if ( psTrack == NULL )
|
2007-06-28 10:47:08 -07:00
|
|
|
{
|
2007-04-05 13:19:58 -07:00
|
|
|
return SAMPLE_NOT_FOUND;
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
|
|
|
return sound_GetTrackID( psTrack );
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
SDWORD audio_GetAvailableID( void )
|
|
|
|
{
|
|
|
|
// return if audio not enabled
|
|
|
|
if ( g_bAudioEnabled == FALSE )
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-05 13:19:58 -07:00
|
|
|
|
|
|
|
return sound_GetAvailableID();
|
2007-06-28 10:47:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
SDWORD audio_Get3DVolume( void )
|
|
|
|
{
|
|
|
|
return g_i3DVolume;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
void audio_Set3DVolume( SDWORD iVol )
|
|
|
|
{
|
|
|
|
g_i3DVolume = iVol;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
// audio_GetMixVol iVol and audio_Get3DVolume need to be scaled by AUDIO_VOL_RANGE
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
SDWORD audio_GetMixVol( SDWORD iVol )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
SDWORD iMixVol = ( iVol * sound_GetMaxVolume() * audio_Get3DVolume() ) / ( AUDIO_VOL_RANGE * AUDIO_VOL_RANGE );
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
return iMixVol;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// * audio_GetSampleMixVol iVol, audio_Get3DVolume and sound_GetTrackVolume all need
|
|
|
|
// * to be scaled by AUDIO_VOL_RANGE
|
|
|
|
//
|
|
|
|
|
|
|
|
//*
|
|
|
|
// =======================================================================================================================
|
|
|
|
// =======================================================================================================================
|
|
|
|
//
|
|
|
|
SDWORD audio_GetSampleMixVol( AUDIO_SAMPLE *psSample, SDWORD iVol, BOOL bScale3D )
|
|
|
|
{
|
|
|
|
//~~~~~~~~~~~~
|
|
|
|
SDWORD iMixVol;
|
|
|
|
//~~~~~~~~~~~~
|
|
|
|
|
|
|
|
iMixVol = iVol * sound_GetMaxVolume() / AUDIO_VOL_RANGE;
|
|
|
|
iMixVol = iMixVol * sound_GetTrackVolume( psSample->iTrack ) / AUDIO_VOL_RANGE;
|
|
|
|
if ( bScale3D )
|
|
|
|
{
|
|
|
|
iMixVol = iMixVol * audio_Get3DVolume() / AUDIO_VOL_RANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return iMixVol;
|
|
|
|
}
|
|
|
|
|
|
|
|
//*
|
|
|
|
//
|