mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
extend the sound api slightly to ease things like cd_file and make cd_file
work as intended :)
This commit is contained in:
parent
19ef80c555
commit
d5a33c9545
7 changed files with 203 additions and 119 deletions
|
@ -55,6 +55,8 @@ typedef void (*P_S_ExtraUpdate) (void);
|
|||
typedef void (*P_S_LocalSound) (const char *s);
|
||||
typedef void (*P_S_BlockSound) (void);
|
||||
typedef void (*P_S_UnblockSound) (void);
|
||||
typedef struct sfx_s *(*P_S_LoadSound) (const char *name);
|
||||
typedef struct channel_s *(*P_S_AllocChannel) (void);
|
||||
|
||||
typedef struct snd_render_funcs_s {
|
||||
P_S_AmbientOff pS_AmbientOff;
|
||||
|
@ -73,6 +75,8 @@ typedef struct snd_render_funcs_s {
|
|||
P_S_LocalSound pS_LocalSound;
|
||||
P_S_BlockSound pS_BlockSound;
|
||||
P_S_UnblockSound pS_UnblockSound;
|
||||
P_S_LoadSound pS_LoadSound;
|
||||
P_S_AllocChannel pS_AllocChannel;
|
||||
} snd_render_funcs_t;
|
||||
|
||||
typedef struct snd_render_data_s {
|
||||
|
|
|
@ -96,6 +96,8 @@ void S_ClearPrecache (void);
|
|||
void S_BeginPrecaching (void);
|
||||
void S_EndPrecaching (void);
|
||||
|
||||
sfx_t *S_LoadSound (const char *name);
|
||||
struct channel_s *S_AllocChannel (void);
|
||||
|
||||
// ====================================================================
|
||||
// User-setable variables
|
||||
|
|
|
@ -36,28 +36,28 @@
|
|||
|
||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||
typedef struct portable_samplepair_s {
|
||||
int left;
|
||||
int right;
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct wavinfo_s {
|
||||
unsigned int rate;
|
||||
unsigned int width;
|
||||
unsigned int channels;
|
||||
unsigned int loopstart;
|
||||
unsigned int samples;
|
||||
unsigned int dataofs; // chunk starts this many bytes from file start
|
||||
unsigned int datalen; // chunk bytes
|
||||
unsigned rate;
|
||||
unsigned width;
|
||||
unsigned channels;
|
||||
unsigned loopstart;
|
||||
unsigned samples;
|
||||
unsigned dataofs; // chunk starts this many bytes from file start
|
||||
unsigned datalen; // chunk bytes
|
||||
} wavinfo_t;
|
||||
|
||||
typedef struct channel_s channel_t;
|
||||
typedef struct sfxbuffer_s sfxbuffer_t;
|
||||
struct sfxbuffer_s {
|
||||
unsigned int head; // ring buffer head position in sampels
|
||||
unsigned int tail; // ring buffer tail position in sampels
|
||||
unsigned int length; // length of buffer in samples
|
||||
unsigned int pos; // position of tail within full stream
|
||||
unsigned int bps; // bytes per sample: 1 2 4 usually
|
||||
unsigned head; // ring buffer head position in sampels
|
||||
unsigned tail; // ring buffer tail position in sampels
|
||||
unsigned length; // length of buffer in samples
|
||||
unsigned pos; // position of tail within full stream
|
||||
unsigned bps; // bytes per sample: 1 2 4 usually
|
||||
void (*paint) (channel_t *ch, sfxbuffer_t *buffer, int count);
|
||||
void (*advance) (sfxbuffer_t *buffer, unsigned int count);
|
||||
void (*setpos) (sfxbuffer_t *buffer, unsigned int pos);
|
||||
|
@ -70,9 +70,9 @@ typedef struct sfxstream_s {
|
|||
void *file;
|
||||
wavinfo_t wavinfo;
|
||||
int pos;
|
||||
void (*resample)(sfxbuffer_t *, byte *, int, void *);
|
||||
int (*read)(void *file, byte *data, int bytes, wavinfo_t *info);
|
||||
int (*seek)(void *file, int pos, wavinfo_t *info);
|
||||
void (*resample)(sfxbuffer_t *, byte *, int, void *);
|
||||
int (*read)(void *file, byte *data, int bytes, wavinfo_t *info);
|
||||
int (*seek)(void *file, int pos, wavinfo_t *info);
|
||||
sfxbuffer_t buffer;
|
||||
} sfxstream_t;
|
||||
|
||||
|
@ -85,19 +85,19 @@ typedef struct sfxblock_s {
|
|||
|
||||
// !!! if this is changed, it much be changed in asm_i386.h too !!!
|
||||
struct channel_s {
|
||||
sfx_t *sfx; // sfx number
|
||||
int leftvol; // 0-255 volume
|
||||
int rightvol; // 0-255 volume
|
||||
unsigned int end; // end time in global paintsamples
|
||||
unsigned int pos; // sample position in sfx
|
||||
unsigned int looping; // where to loop, -1 = no looping
|
||||
int entnum; // to allow overriding a specific sound
|
||||
int entchannel; //
|
||||
vec3_t origin; // origin of sound effect
|
||||
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
||||
int master_vol; // 0-255 master volume
|
||||
int phase; // phase shift between l-r in samples
|
||||
int oldphase; // phase shift between l-r in samples
|
||||
sfx_t *sfx; // sfx number
|
||||
int leftvol; // 0-255 volume
|
||||
int rightvol; // 0-255 volume
|
||||
unsigned end; // end time in global paintsamples
|
||||
unsigned pos; // sample position in sfx
|
||||
unsigned looping; // where to loop, -1 = no looping
|
||||
int entnum; // to allow overriding a specific sound
|
||||
int entchannel; //
|
||||
vec3_t origin; // origin of sound effect
|
||||
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
||||
int master_vol; // 0-255 master volume
|
||||
int phase; // phase shift between l-r in samples
|
||||
int oldphase; // phase shift between l-r in samples
|
||||
};
|
||||
|
||||
void SND_PaintChannels(unsigned int endtime);
|
||||
|
|
|
@ -75,6 +75,8 @@ static qboolean mus_enabled = false;
|
|||
|
||||
static cvar_t *bgmvolume;
|
||||
|
||||
static channel_t *cd_channel;
|
||||
static sfx_t cd_sfx;
|
||||
|
||||
/* added by Andrew, for cd_ogg */
|
||||
static cvar_t *mus_ogglist; // contain the filename of the ogglist.
|
||||
|
@ -174,6 +176,7 @@ I_OGGMus_Play (int track, qboolean looping)
|
|||
{
|
||||
plitem_t *trackmap = NULL;
|
||||
dstring_t *trackstring = dstring_new ();
|
||||
wavinfo_t *info;
|
||||
|
||||
Sys_Printf ("Entering I_OGGMus_Play\n");
|
||||
/* alrighty. grab the list, map track to filename. grab filename from data
|
||||
|
@ -192,7 +195,27 @@ I_OGGMus_Play (int track, qboolean looping)
|
|||
}
|
||||
|
||||
Sys_Printf ("Playing: %s.\n", (char *) trackmap->data);
|
||||
S_LocalSound ((char *) trackmap->data);
|
||||
if (cd_channel->sfx) {
|
||||
cd_channel->sfx->close (cd_channel->sfx);
|
||||
memset (cd_channel, 0, sizeof (*cd_channel));
|
||||
}
|
||||
|
||||
if (cd_sfx.name)
|
||||
free ((char *) cd_sfx.name);
|
||||
cd_sfx.name = strdup ((char *) trackmap->data);
|
||||
SND_Load (&cd_sfx);
|
||||
if (cd_sfx.wavinfo)
|
||||
info = cd_sfx.wavinfo (&cd_sfx);
|
||||
if (info)
|
||||
info->loopstart = 0;
|
||||
cd_channel->sfx = cd_sfx.open (&cd_sfx);
|
||||
if (cd_channel->sfx) {
|
||||
int vol = bgmvolume->value * 255;
|
||||
|
||||
cd_channel->master_vol = vol;
|
||||
cd_channel->leftvol = cd_channel->rightvol = cd_channel->master_vol;
|
||||
}
|
||||
|
||||
free (trackstring);
|
||||
playing = true;
|
||||
}
|
||||
|
@ -411,12 +434,21 @@ static void
|
|||
Mus_VolChange (cvar_t *bgmvolume)
|
||||
{
|
||||
Sys_Printf ("Entering Mus_VolChange\n");
|
||||
if (cd_channel->sfx) {
|
||||
int vol = bgmvolume->value * 255;
|
||||
|
||||
cd_channel->master_vol = vol;
|
||||
cd_channel->leftvol = cd_channel->rightvol = cd_channel->master_vol;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
I_OGGMus_Init (void)
|
||||
{
|
||||
Sys_Printf ("Entering I_OGGMus_Init\n");
|
||||
|
||||
cd_channel = S_AllocChannel ();
|
||||
|
||||
/* check list file cvar, open list file, create map, close file. */
|
||||
|
||||
mus_ogglist = Cvar_Get ("mus_ogglist", "tracklist.cfg", CVAR_NONE,
|
||||
|
|
|
@ -50,6 +50,7 @@ static __attribute__ ((unused)) const char rcsid[] =
|
|||
#include "QF/sys.h"
|
||||
#include "QF/sound.h"
|
||||
#include "QF/plugin.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "snd_render.h"
|
||||
|
||||
|
@ -65,6 +66,11 @@ cvar_t *snd_interp;
|
|||
channel_t channels[MAX_CHANNELS];
|
||||
int total_channels;
|
||||
|
||||
static channel_t *ambient_channels[NUM_AMBIENTS];
|
||||
static channel_t *dynamic_channels[MAX_DYNAMIC_CHANNELS];
|
||||
static channel_t *static_channels[MAX_CHANNELS];
|
||||
static int num_statics;
|
||||
|
||||
static qboolean snd_initialized = false;
|
||||
static int snd_blocked = 0;
|
||||
static qboolean snd_ambient = 1;
|
||||
|
@ -170,17 +176,11 @@ s_startup (void)
|
|||
|
||||
// Load a sound ===============================================================
|
||||
static sfx_t *
|
||||
s_findname (const char *name)
|
||||
s_load_sound (const char *name)
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
|
||||
if (!name)
|
||||
Sys_Error ("S_FindName: NULL");
|
||||
|
||||
if (strlen (name) >= MAX_QPATH)
|
||||
Sys_Error ("Sound name too long: %s", name);
|
||||
|
||||
// see if already loaded
|
||||
for (i = 0; i < num_sfx; i++)
|
||||
if (known_sfx[i].name && !strcmp (known_sfx[i].name, name)) {
|
||||
|
@ -209,7 +209,11 @@ s_touch_sound (const char *name)
|
|||
if (!sound_started)
|
||||
return;
|
||||
|
||||
sfx = s_findname (name);
|
||||
if (!name)
|
||||
Sys_Error ("s_touch_sound: NULL");
|
||||
|
||||
name = va ("sound/%s", name);
|
||||
sfx = s_load_sound (name);
|
||||
sfx->touch (sfx);
|
||||
}
|
||||
|
||||
|
@ -221,7 +225,11 @@ s_precache_sound (const char *name)
|
|||
if (!sound_started || nosound->int_val)
|
||||
return NULL;
|
||||
|
||||
sfx = s_findname (name);
|
||||
if (!name)
|
||||
Sys_Error ("s_precache_sound: NULL");
|
||||
|
||||
name = va ("sound/%s", name);
|
||||
sfx = s_load_sound (name);
|
||||
|
||||
// cache it in
|
||||
if (precache->int_val) {
|
||||
|
@ -233,46 +241,54 @@ s_precache_sound (const char *name)
|
|||
|
||||
//=============================================================================
|
||||
|
||||
static channel_t *
|
||||
s_alloc_channel (void)
|
||||
{
|
||||
if (total_channels < MAX_CHANNELS)
|
||||
return &channels[total_channels++];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static channel_t *
|
||||
s_pick_channel (int entnum, int entchannel)
|
||||
{
|
||||
int ch_idx, first_to_die;
|
||||
int ch_idx;
|
||||
unsigned life_left;
|
||||
channel_t *ch, *first_to_die;
|
||||
|
||||
// Check for replacement sound, or find the best one to replace
|
||||
first_to_die = -1;
|
||||
first_to_die = 0;
|
||||
life_left = 0x7fffffff;
|
||||
for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS;
|
||||
ch_idx++) {
|
||||
for (ch_idx = 0; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++) {
|
||||
ch = dynamic_channels[ch_idx];
|
||||
if (entchannel != 0 // channel 0 never overrides
|
||||
&& channels[ch_idx].entnum == entnum
|
||||
&& (channels[ch_idx].entchannel == entchannel ||
|
||||
entchannel == -1)) {
|
||||
&& ch->entnum == entnum
|
||||
&& (ch->entchannel == entchannel || entchannel == -1)) {
|
||||
// always override sound from same entity
|
||||
first_to_die = ch_idx;
|
||||
first_to_die = ch;
|
||||
break;
|
||||
}
|
||||
// don't let monster sounds override player sounds
|
||||
if (channels[ch_idx].entnum == *render_data.viewentity
|
||||
if (ch->entnum == *render_data.viewentity
|
||||
&& entnum != *render_data.viewentity
|
||||
&& channels[ch_idx].sfx)
|
||||
&& ch->sfx)
|
||||
continue;
|
||||
|
||||
if (paintedtime + life_left > channels[ch_idx].end) {
|
||||
life_left = channels[ch_idx].end - paintedtime;
|
||||
first_to_die = ch_idx;
|
||||
if (paintedtime + life_left > ch->end) {
|
||||
life_left = ch->end - paintedtime;
|
||||
first_to_die = ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (first_to_die == -1)
|
||||
if (!first_to_die)
|
||||
return NULL;
|
||||
|
||||
if (channels[first_to_die].sfx) {
|
||||
channels[first_to_die].sfx->close (channels[first_to_die].sfx);
|
||||
channels[first_to_die].sfx = NULL;
|
||||
if (first_to_die->sfx) {
|
||||
first_to_die->sfx->close (first_to_die->sfx);
|
||||
first_to_die->sfx = NULL;
|
||||
}
|
||||
|
||||
return &channels[first_to_die];
|
||||
return first_to_die;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -376,9 +392,8 @@ s_start_sound (int entnum, int entchannel, sfx_t *sfx, const vec3_t origin,
|
|||
|
||||
// if an identical sound has also been started this frame, offset the pos
|
||||
// a bit to keep it from just making the first one louder
|
||||
check = &channels[NUM_AMBIENTS];
|
||||
for (ch_idx = NUM_AMBIENTS; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS;
|
||||
ch_idx++, check++) {
|
||||
for (ch_idx = 0; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++) {
|
||||
check = dynamic_channels[ch_idx];
|
||||
if (check == target_chan)
|
||||
continue;
|
||||
if (check->sfx == sfx && !check->pos) {
|
||||
|
@ -396,17 +411,18 @@ static void
|
|||
s_stop_sound (int entnum, int entchannel)
|
||||
{
|
||||
int i;
|
||||
channel_t *ch;
|
||||
|
||||
if (!sound_started)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) {
|
||||
if (channels[i].entnum == entnum
|
||||
&& channels[i].entchannel == entchannel) {
|
||||
channels[i].end = 0;
|
||||
if (channels[i].sfx)
|
||||
channels[i].sfx->close (channels[i].sfx);
|
||||
channels[i].sfx = NULL;
|
||||
ch = dynamic_channels[i];
|
||||
if (ch->entnum == entnum && ch->entchannel == entchannel) {
|
||||
ch->end = 0;
|
||||
if (ch->sfx)
|
||||
ch->sfx->close (ch->sfx);
|
||||
ch->sfx = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -439,7 +455,7 @@ s_stop_all_sounds (qboolean clear)
|
|||
if (!sound_started)
|
||||
return;
|
||||
|
||||
total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics
|
||||
num_statics = 0;
|
||||
|
||||
for (i = 0; i < MAX_CHANNELS; i++)
|
||||
if (channels[i].sfx) {
|
||||
|
@ -468,13 +484,14 @@ s_static_sound (sfx_t *sfx, const vec3_t origin, float vol,
|
|||
if (!sound_started || !sfx)
|
||||
return;
|
||||
|
||||
if (total_channels == MAX_CHANNELS) {
|
||||
Sys_Printf ("total_channels == MAX_CHANNELS\n");
|
||||
return;
|
||||
if (!static_channels[num_statics]) {
|
||||
if (!(static_channels[num_statics] = s_alloc_channel ())) {
|
||||
Sys_Printf ("ran out of channels\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ss = &channels[total_channels];
|
||||
total_channels++;
|
||||
ss = static_channels[num_statics];
|
||||
|
||||
if (!sfx->retain (sfx))
|
||||
return;
|
||||
|
@ -497,6 +514,7 @@ s_static_sound (sfx_t *sfx, const vec3_t origin, float vol,
|
|||
|
||||
s_spatialize (ss);
|
||||
ss->oldphase = ss->phase;
|
||||
num_statics++;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -520,16 +538,17 @@ s_updateAmbientSounds (void)
|
|||
if (!l || !ambient_level->value) {
|
||||
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
|
||||
ambient_channel++) {
|
||||
if (channels[ambient_channel].sfx)
|
||||
channels[ambient_channel].sfx->close (channels[ambient_channel].sfx);
|
||||
channels[ambient_channel].sfx = NULL;
|
||||
chan = ambient_channels[ambient_channel];
|
||||
if (chan->sfx)
|
||||
chan->sfx->close (chan->sfx);
|
||||
chan->sfx = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (ambient_channel = 0; ambient_channel < NUM_AMBIENTS;
|
||||
ambient_channel++) {
|
||||
chan = &channels[ambient_channel];
|
||||
chan = ambient_channels[ambient_channel];
|
||||
if (!ambient_sfx[ambient_channel]) {
|
||||
chan->sfx = 0;
|
||||
continue;
|
||||
|
@ -611,6 +630,18 @@ s_update_ (void)
|
|||
snd_output_funcs->pS_O_Submit ();
|
||||
}
|
||||
|
||||
static inline int
|
||||
s_update_channel (channel_t *ch)
|
||||
{
|
||||
if (!ch->sfx)
|
||||
return 0;
|
||||
ch->oldphase = ch->phase; // prepare to lerp from prev to next phase
|
||||
s_spatialize (ch); // respatialize channel
|
||||
if (!ch->leftvol && !ch->rightvol)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
s_update
|
||||
|
||||
|
@ -637,43 +668,39 @@ s_update (const vec3_t origin, const vec3_t forward, const vec3_t right,
|
|||
combine = NULL;
|
||||
|
||||
// update spatialization for static and dynamic sounds
|
||||
ch = channels + NUM_AMBIENTS;
|
||||
for (i = NUM_AMBIENTS; i < total_channels; i++, ch++) {
|
||||
if (!ch->sfx)
|
||||
continue;
|
||||
ch->oldphase = ch->phase; // prepare to lerp from prev to next
|
||||
// phase
|
||||
s_spatialize (ch); // respatialize channel
|
||||
if (!ch->leftvol && !ch->rightvol)
|
||||
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++)
|
||||
s_update_channel (dynamic_channels[i]);
|
||||
|
||||
for (i = 0; i < num_statics; i++) {
|
||||
ch = static_channels[i];
|
||||
if (!s_update_channel (ch))
|
||||
continue;
|
||||
|
||||
// try to combine static sounds with a previous channel of the same
|
||||
// sound effect so we don't mix five torches every frame
|
||||
if (i >= MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS) {
|
||||
// see if it can just use the last one
|
||||
if (combine && combine->sfx == ch->sfx) {
|
||||
// see if it can just use the last one
|
||||
if (combine && combine->sfx == ch->sfx) {
|
||||
combine->leftvol += ch->leftvol;
|
||||
combine->rightvol += ch->rightvol;
|
||||
ch->leftvol = ch->rightvol = 0;
|
||||
continue;
|
||||
}
|
||||
// search for one
|
||||
for (j = 0; j < i; j++) {
|
||||
combine = static_channels[j];
|
||||
if (combine->sfx == ch->sfx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == i) {
|
||||
combine = NULL;
|
||||
} else {
|
||||
if (combine != ch) {
|
||||
combine->leftvol += ch->leftvol;
|
||||
combine->rightvol += ch->rightvol;
|
||||
ch->leftvol = ch->rightvol = 0;
|
||||
continue;
|
||||
}
|
||||
// search for one
|
||||
combine = channels + MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS;
|
||||
for (j = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; j < i; j++,
|
||||
combine++)
|
||||
if (combine->sfx == ch->sfx)
|
||||
break;
|
||||
|
||||
if (j == total_channels) {
|
||||
combine = NULL;
|
||||
} else {
|
||||
if (combine != ch) {
|
||||
combine->leftvol += ch->leftvol;
|
||||
combine->rightvol += ch->rightvol;
|
||||
ch->leftvol = ch->rightvol = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,6 +884,13 @@ s_unblock_sound (void)
|
|||
static void
|
||||
s_init (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_AMBIENTS; i++)
|
||||
ambient_channels[i] = s_alloc_channel ();
|
||||
for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++)
|
||||
dynamic_channels[i] = s_alloc_channel ();
|
||||
|
||||
snd_output_funcs = render_data.output->functions->snd_output;
|
||||
Sys_Printf ("\nSound Initialization\n");
|
||||
|
||||
|
@ -997,6 +1031,8 @@ static snd_render_funcs_t plugin_info_render_funcs = {
|
|||
s_local_sound,
|
||||
s_block_sound,
|
||||
s_unblock_sound,
|
||||
s_load_sound,
|
||||
s_alloc_channel,
|
||||
};
|
||||
|
||||
static plugin_funcs_t plugin_info_funcs = {
|
||||
|
|
|
@ -291,7 +291,6 @@ SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count)
|
|||
void
|
||||
SND_Load (sfx_t *sfx)
|
||||
{
|
||||
dstring_t *name = dstring_new ();
|
||||
dstring_t *foundname = dstring_new ();
|
||||
char *realname;
|
||||
char buf[4];
|
||||
|
@ -302,22 +301,17 @@ SND_Load (sfx_t *sfx)
|
|||
sfx->close = snd_noop;
|
||||
sfx->open = snd_open;
|
||||
|
||||
dsprintf (name, "sound/%s", sfx->name);
|
||||
_QFS_FOpenFile (name->str, &file, foundname, 1);
|
||||
_QFS_FOpenFile (sfx->name, &file, foundname, 1);
|
||||
if (!file) {
|
||||
Sys_Printf ("Couldn't load %s\n", name->str);
|
||||
dstring_delete (name);
|
||||
Sys_Printf ("Couldn't load %s\n", sfx->name);
|
||||
dstring_delete (foundname);
|
||||
return;
|
||||
}
|
||||
if (!strequal (foundname->str, name->str)) {
|
||||
if (!strequal (foundname->str, sfx->name)) {
|
||||
realname = foundname->str;
|
||||
dstring_delete (name);
|
||||
free (foundname);
|
||||
} else {
|
||||
realname = name->str;
|
||||
free (name);
|
||||
dstring_delete (foundname);
|
||||
realname = (char *) sfx->name; // won't free if realname == sfx->name
|
||||
}
|
||||
Qread (file, buf, 4);
|
||||
Qseek (file, 0, SEEK_SET);
|
||||
|
@ -341,7 +335,8 @@ SND_Load (sfx_t *sfx)
|
|||
return;
|
||||
}
|
||||
Qclose (file);
|
||||
free (realname);
|
||||
if (realname != sfx->name)
|
||||
free (realname);
|
||||
}
|
||||
|
||||
sfxbuffer_t *
|
||||
|
|
|
@ -179,8 +179,7 @@ S_PrecacheSound (const char *sample)
|
|||
{
|
||||
if (snd_render_funcs)
|
||||
return snd_render_funcs->pS_PrecacheSound (sample);
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -246,3 +245,19 @@ S_UnblockSound (void)
|
|||
if (snd_render_funcs)
|
||||
snd_render_funcs->pS_UnblockSound ();
|
||||
}
|
||||
|
||||
sfx_t *
|
||||
S_LoadSound (const char *name)
|
||||
{
|
||||
if (snd_render_funcs)
|
||||
return snd_render_funcs->pS_LoadSound (name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct channel_s *
|
||||
S_AllocChannel (void)
|
||||
{
|
||||
if (snd_render_funcs)
|
||||
return snd_render_funcs->pS_AllocChannel ();
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue