mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
engine: client: adapt sound api to snd globals
This commit is contained in:
@@ -37,23 +37,118 @@ For more information, please refer to <http://unlicense.org/>
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
struct dma_api_s;
|
||||
struct listener_s;
|
||||
|
||||
// Forward decls (full def in engine/client/sound.h)
|
||||
struct channel_s;
|
||||
struct rawchan_s;
|
||||
struct portable_samplepair_s;
|
||||
|
||||
// Engine-owned state: client reads only. Filled by engine, passed to pfnS_Init.
|
||||
typedef struct snd_interface_state_s
|
||||
typedef struct portable_samplepair_s
|
||||
{
|
||||
const struct listener_s *listener;
|
||||
const struct channel_s *channels; // &channels[0], contiguous
|
||||
int total_channels;
|
||||
struct rawchan_s *const *raw_channels; // rawchan_t*[]
|
||||
int max_raw_channels;
|
||||
} snd_interface_state_t;
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
wavdata_t *cache;
|
||||
|
||||
int servercount;
|
||||
uint hashValue;
|
||||
struct sfx_s *hashNext;
|
||||
} sfx_t;
|
||||
|
||||
typedef struct voxword_s
|
||||
{
|
||||
sfx_t *sfx;
|
||||
uint16_t volume; // volume percent
|
||||
uint16_t pitch; // pitch shift percent (keep large for extra chipmunk fun)
|
||||
uint8_t timecompress; // percent of skipped data (speeds up playback without pitch shift)
|
||||
uint8_t start; // percent at which playback starts
|
||||
uint8_t end; // percent at which playback ends
|
||||
uint8_t flags;
|
||||
} voxword_t;
|
||||
|
||||
typedef struct channel_s
|
||||
{
|
||||
char name[16]; // keep sentence name
|
||||
sfx_t *sfx; // sfx number
|
||||
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
|
||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||
uint flags;
|
||||
short entnum; // entity soundsource
|
||||
short master_vol; // 0-255 master volume
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
short basePitch; // base pitch percent (100% is normal pitch playback)
|
||||
byte word_index;
|
||||
|
||||
// HACKHACK: count when this channel became inaudible
|
||||
// to not free it when it could be respatialized soon
|
||||
#define MAX_CHANNEL_INAUDIBLE_TIME 0.1f
|
||||
float inauduble_free_time;
|
||||
|
||||
double sample;
|
||||
double forced_end;
|
||||
wavdata_t *data;
|
||||
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
} channel_t;
|
||||
|
||||
typedef struct rawchan_s
|
||||
{
|
||||
short entnum;
|
||||
short master_vol;
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[]; // variable sized
|
||||
} rawchan_t;
|
||||
|
||||
typedef struct snd_format_s
|
||||
{
|
||||
uint speed;
|
||||
byte width;
|
||||
byte channels;
|
||||
} snd_format_t;
|
||||
|
||||
typedef struct snd_globals_s
|
||||
{
|
||||
// dma
|
||||
const char *backend_name;
|
||||
byte *buffer;
|
||||
snd_format_t format;
|
||||
qboolean initialized; // sound engine is active
|
||||
int samples; // mono samples in buffer
|
||||
int samplepos; // in mono samples
|
||||
|
||||
int paintedtime; // total samples that have been mixed at speed
|
||||
int soundtime; // total samples that have been played out to hardware at dma speed
|
||||
|
||||
// listener (client, camera, etc)
|
||||
vec3_t origin;
|
||||
vec3_t forward, right, up;
|
||||
int entnum;
|
||||
qboolean streaming; // playing AVI-file
|
||||
qboolean stream_paused; // pause only background track
|
||||
|
||||
// SoundAPI shared pointers
|
||||
channel_t *const channels;
|
||||
int max_channels;
|
||||
int total_channels;
|
||||
rawchan_t **const raw_channels;
|
||||
int max_raw_channels;
|
||||
sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
qboolean have_ambient_sfx;
|
||||
} snd_globals_t;
|
||||
|
||||
// API from engine to client (client calls these)
|
||||
typedef struct sound_api_s
|
||||
@@ -67,11 +162,11 @@ typedef struct sound_interface_s
|
||||
{
|
||||
int version;
|
||||
|
||||
qboolean (*pfnS_Init)( snd_interface_state_t *state );
|
||||
qboolean (*pfnS_Init)( snd_globals_t *globals );
|
||||
void (*pfnS_Shutdown)( void );
|
||||
void (*pfnS_UpdateSound)( void );
|
||||
/* Full paint: endtime (sample pairs), dma buffer, paintedtime in/out. Client does mix + transfer to dma.buffer. */
|
||||
void (*pfnS_PaintChannels)( int endtime, struct dma_api_s *dma, int *paintedtime );
|
||||
void (*pfnS_PaintChannels)( int endtime );
|
||||
void (*pfnS_UpdateChannel)( int ch_idx, const struct channel_s *ch, sound_t handle ); // ch=NULL -> channel freed
|
||||
void (*pfnS_UpdateRawChannel)( int raw_idx, struct rawchan_s *ch ); // ch=NULL -> channel freed
|
||||
void (*pfnS_Spatialize)( struct channel_s *ch );
|
||||
|
||||
@@ -101,11 +101,11 @@ static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and high
|
||||
{ "HUD_VoiceStatus", (void **)&clgame.dllFuncs.pfnVoiceStatus },
|
||||
{ "HUD_ChatInputPosition", (void **)&clgame.dllFuncs.pfnChatInputPosition },
|
||||
{ "HUD_GetRenderInterface", (void **)&clgame.dllFuncs.pfnGetRenderInterface }, // Xash3D ext
|
||||
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D ext
|
||||
{ "HUD_ClipMoveToEntity", (void **)&clgame.dllFuncs.pfnClipMoveToEntity }, // Xash3D ext
|
||||
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
||||
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D ext
|
||||
};
|
||||
|
||||
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
||||
|
||||
@@ -44,8 +44,6 @@ snd_globals_t snd =
|
||||
.max_raw_channels = MAX_RAW_CHANNELS,
|
||||
};
|
||||
|
||||
static snd_interface_state_t s_sndState;
|
||||
|
||||
static CVAR_DEFINE( s_volume, "volume", "0.7", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sound volume" );
|
||||
CVAR_DEFINE( s_musicvolume, "MP3Volume", "1.0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "background music volume" );
|
||||
static CVAR_DEFINE( s_mixahead, "_snd_mixahead", "0.12", FCVAR_FILTERABLE, "how much sound to mix ahead of time" );
|
||||
@@ -185,7 +183,7 @@ S_FreeChannel
|
||||
*/
|
||||
void S_FreeChannel( channel_t *ch )
|
||||
{
|
||||
S_NotifyChannelUpdate( ch - channels, NULL, -1 );
|
||||
S_NotifyChannelUpdate( ch - snd.channels, NULL, -1 );
|
||||
|
||||
// free the currently loaded word's audio cache before nuking the channel
|
||||
if( ch->words )
|
||||
@@ -735,7 +733,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
|
||||
}
|
||||
}
|
||||
|
||||
S_NotifyChannelUpdate( target_chan - channels, target_chan, handle );
|
||||
S_NotifyChannelUpdate( target_chan - snd.channels, target_chan, handle );
|
||||
|
||||
// Init client entity mouth movement vars
|
||||
SND_InitMouth( ent, chan );
|
||||
@@ -851,7 +849,7 @@ void S_RestoreSound( const vec3_t pos, int ent, int chan, sound_t handle, float
|
||||
target_chan->sample = sample;
|
||||
target_chan->forced_end = end;
|
||||
|
||||
S_NotifyChannelUpdate( target_chan - channels, target_chan, handle );
|
||||
S_NotifyChannelUpdate( target_chan - snd.channels, target_chan, handle );
|
||||
|
||||
// Init client entity mouth movement vars
|
||||
SND_InitMouth( ent, chan );
|
||||
@@ -946,7 +944,7 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
|
||||
ch->entchannel = CHAN_STATIC;
|
||||
ch->basePitch = pitch;
|
||||
|
||||
S_NotifyChannelUpdate( ch - channels, ch, handle );
|
||||
S_NotifyChannelUpdate( ch - snd.channels, ch, handle );
|
||||
SND_Spatialize( ch );
|
||||
}
|
||||
|
||||
@@ -1564,9 +1562,8 @@ static void S_UpdateChannels( void )
|
||||
endtime -= ( endtime - snd.paintedtime ) & 0x3;
|
||||
}
|
||||
|
||||
s_sndState.total_channels = total_channels;
|
||||
if( clgame.soundFuncs.pfnS_PaintChannels )
|
||||
clgame.soundFuncs.pfnS_PaintChannels( endtime, &dma, &paintedtime );
|
||||
clgame.soundFuncs.pfnS_PaintChannels( endtime );
|
||||
else
|
||||
S_PaintChannels( endtime );
|
||||
|
||||
@@ -1938,21 +1935,6 @@ static void S_VoiceRecordStop_f( void )
|
||||
Voice_RecordStop();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
S_FillSndState
|
||||
================
|
||||
*/
|
||||
static void S_FillSndState( snd_interface_state_t *st )
|
||||
{
|
||||
memset( st, 0, sizeof( *st ));
|
||||
st->listener = &s_listener;
|
||||
st->channels = channels;
|
||||
st->total_channels = total_channels;
|
||||
st->raw_channels = raw_channels;
|
||||
st->max_raw_channels = MAX_RAW_CHANNELS;
|
||||
}
|
||||
|
||||
static const sound_api_t s_clientSoundAPI = {
|
||||
CL_GetEntitySpatialization,
|
||||
S_GetSfxByHandle,
|
||||
@@ -1967,8 +1949,6 @@ static qboolean S_InitSoundAPI( void )
|
||||
{
|
||||
// make sure what sound functions is cleared
|
||||
memset( &clgame.soundFuncs, 0, sizeof( clgame.soundFuncs ));
|
||||
|
||||
S_FillSndState( &s_sndState );
|
||||
|
||||
if( clgame.dllFuncs.pfnGetSoundInterface )
|
||||
{
|
||||
@@ -2050,7 +2030,7 @@ qboolean S_Init( void )
|
||||
S_InitSoundAPI();
|
||||
|
||||
if( clgame.soundFuncs.pfnS_Init )
|
||||
clgame.soundFuncs.pfnS_Init( &s_sndState );
|
||||
clgame.soundFuncs.pfnS_Init( &snd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,129 +39,14 @@ extern poolhandle_t sndpool;
|
||||
|
||||
#define CLIP16( x ) bound( SHRT_MIN + 8, x, SHRT_MAX - 8 )
|
||||
|
||||
typedef struct portable_samplepair_s
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
wavdata_t *cache;
|
||||
|
||||
int servercount;
|
||||
uint hashValue;
|
||||
struct sfx_s *hashNext;
|
||||
} sfx_t;
|
||||
|
||||
#define FL_VOXWORD_IN_CACHE BIT( 0 ) // if set, it was loaded prior and shouldn't be freed
|
||||
|
||||
typedef struct voxword_s
|
||||
{
|
||||
sfx_t *sfx;
|
||||
uint16_t volume; // volume percent
|
||||
uint16_t pitch; // pitch shift percent (keep large for extra chipmunk fun)
|
||||
uint8_t timecompress; // percent of skipped data (speeds up playback without pitch shift)
|
||||
uint8_t start; // percent at which playback starts
|
||||
uint8_t end; // percent at which playback ends
|
||||
uint8_t flags;
|
||||
} voxword_t;
|
||||
|
||||
typedef struct snd_format_s
|
||||
{
|
||||
uint speed;
|
||||
byte width;
|
||||
byte channels;
|
||||
} snd_format_t;
|
||||
|
||||
typedef struct rawchan_s
|
||||
{
|
||||
short entnum;
|
||||
short master_vol;
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[]; // variable sized
|
||||
} rawchan_t;
|
||||
|
||||
#define FL_CHAN_USE_LOOP BIT( 0 ) // don't loop default and local sounds
|
||||
#define FL_CHAN_STATIC_SOUND BIT( 1 ) // use origin instead of fetching entnum's origin
|
||||
#define FL_CHAN_LOCAL_SOUND BIT( 2 ) // it's a local menu sound (not looped, not paused)
|
||||
#define FL_CHAN_SENTENCE_FINISHED BIT( 4 ) // if set, finished playing sentence
|
||||
#define FL_CHAN_FINISHED BIT( 5 ) // if set, finished playing single word
|
||||
|
||||
typedef struct channel_s
|
||||
{
|
||||
char name[16]; // keep sentence name
|
||||
sfx_t *sfx; // sfx number
|
||||
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
|
||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||
uint flags;
|
||||
short entnum; // entity soundsource
|
||||
short master_vol; // 0-255 master volume
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
short basePitch; // base pitch percent (100% is normal pitch playback)
|
||||
byte word_index;
|
||||
|
||||
// HACKHACK: count when this channel became inaudible
|
||||
// to not free it when it could be respatialized soon
|
||||
#define MAX_CHANNEL_INAUDIBLE_TIME 0.1f
|
||||
float inauduble_free_time;
|
||||
|
||||
double sample;
|
||||
double forced_end;
|
||||
wavdata_t *data;
|
||||
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
} channel_t;
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
typedef struct snd_globals_s
|
||||
{
|
||||
// dma
|
||||
const char *backend_name;
|
||||
byte *buffer;
|
||||
snd_format_t format;
|
||||
qboolean initialized; // sound engine is active
|
||||
int samples; // mono samples in buffer
|
||||
int samplepos; // in mono samples
|
||||
|
||||
int paintedtime; // total samples that have been mixed at speed
|
||||
int soundtime; // total samples that have been played out to hardware at dma speed
|
||||
|
||||
// listener (client, camera, etc)
|
||||
vec3_t origin;
|
||||
vec3_t forward, right, up;
|
||||
int entnum;
|
||||
qboolean streaming; // playing AVI-file
|
||||
qboolean stream_paused; // pause only background track
|
||||
|
||||
// SoundAPI shared pointers
|
||||
channel_t *const channels;
|
||||
int max_channels;
|
||||
int total_channels;
|
||||
rawchan_t **const raw_channels;
|
||||
int max_raw_channels;
|
||||
sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
qboolean have_ambient_sfx;
|
||||
} snd_globals_t;
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
|
||||
|
||||
Reference in New Issue
Block a user