11 Oct 2009

This commit is contained in:
g-cont 2009-10-11 00:00:00 +04:00 committed by Alibek Omarov
parent c873ab6c77
commit 528c9dc420
34 changed files with 9837 additions and 119 deletions

16
baserc/baserc.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: baserc - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
baserc.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

16
client/client.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: client - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
client.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -71,7 +71,6 @@ void CHud :: VidInit( void )
// Load Sprites
// ---------
m_iDrawPlaque = 1;
m_hsprCursor = 0;
m_hHudError = 0;
m_hHudFont = 0;

View File

@ -104,7 +104,6 @@ int CHud :: InitMessages( void )
void CHud :: UserCmd_LoadingPlaque( void )
{
ALERT( at_console, "SCR_DisablePlaque()\n" );
m_iDrawPlaque = 0; // disable plaque rendering
}
@ -127,6 +126,9 @@ int CHud :: MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf )
m_iIntermission = 0;
// enable plaque drawing
m_iDrawPlaque = 1;
// reset fog
m_fStartDist = 0;
m_fEndDist = 0;

View File

@ -257,7 +257,7 @@ void SCR_TimeRefresh_f( void )
if( Cmd_Argc() == 2 )
{
// run without page flipping
re->BeginFrame();
re->BeginFrame( &cl.refdef );
for( i = 0; i < 128; i++ )
{
cl.refdef.viewangles[1] = i / 128.0 * 360.0f;
@ -271,7 +271,7 @@ void SCR_TimeRefresh_f( void )
{
cl.refdef.viewangles[1] = i / 128.0 * 360.0f;
re->BeginFrame();
re->BeginFrame( &cl.refdef );
re->RenderFrame( &cl.refdef );
re->EndFrame();
}

View File

@ -28,6 +28,9 @@ edict_t *CL_GetEdictByIndex( int index )
MsgDev( D_ERROR, "CL_GetEntityByIndex: invalid entindex %i\n", index );
return NULL;
}
if( EDICT_NUM( index )->free )
return NULL;
return EDICT_NUM( index );
}

View File

@ -1203,9 +1203,6 @@ void CL_Frame( int time )
SCR_MakeScreenShot();
if( cls.state > ca_disconnected && cls.state < ca_active )
cl.refdef.paused = true; // force sound.dll to pause
// update audio
S_Update( &cl.refdef );

View File

@ -68,7 +68,6 @@ void V_SetupRefDef( void )
cl.refdef.time = cl.time * 0.001f;
cl.refdef.frametime = cls.frametime;
cl.refdef.demoplayback = cls.demoplayback;
cl.refdef.paused = cl_paused->integer;
cl.refdef.smoothing = cl_predict->integer;
cl.refdef.waterlevel = clent->v.waterlevel;
cl.refdef.flags = cl.render_flags;
@ -142,7 +141,7 @@ void V_RenderView( void )
clgame.globals->time = cl.time * 0.001f; // clamped
clgame.globals->frametime = cl.serverframetime * 0.001f; // !!!
if( cl.frame.valid && (cl.force_refdef || !cl_paused->integer ))
if( cl.frame.valid && (cl.force_refdef || !cl.refdef.paused ))
{
cl.force_refdef = false;
@ -165,7 +164,11 @@ bool V_PreRender( void )
// too early
if( !re ) return false;
re->BeginFrame();
if( cls.state > ca_disconnected && cls.state < ca_active )
cl.refdef.paused = true; // force audio\video to pause
else cl.refdef.paused = cl_paused->integer;
re->BeginFrame( &cl.refdef );
return true;
}

96
engine/engine.plg Normal file
View File

@ -0,0 +1,96 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199C.tmp" with contents
[
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "common" /I "server" /I "client" /I "uimenu" /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\engine\!debug/" /Fo"..\temp\engine\!debug/" /Fd"..\temp\engine\!debug/" /FD /c
"D:\Xash3D\src_main\engine\client\cl_game.c"
]
Creating command line "cl.exe @"C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199C.tmp""
Creating temporary file "C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199D.tmp" with contents
[
user32.lib msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept
"\Xash3D\src_main\temp\engine\!debug\cinematic.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_cmds.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_demo.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_effects.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_frame.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_game.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_input.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_main.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_parse.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_phys.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_scrn.obj"
"\Xash3D\src_main\temp\engine\!debug\cl_view.obj"
"\Xash3D\src_main\temp\engine\!debug\com_library.obj"
"\Xash3D\src_main\temp\engine\!debug\con_keys.obj"
"\Xash3D\src_main\temp\engine\!debug\con_main.obj"
"\Xash3D\src_main\temp\engine\!debug\con_utils.obj"
"\Xash3D\src_main\temp\engine\!debug\engfuncs.obj"
"\Xash3D\src_main\temp\engine\!debug\engine.obj"
"\Xash3D\src_main\temp\engine\!debug\host.obj"
"\Xash3D\src_main\temp\engine\!debug\infostring.obj"
"\Xash3D\src_main\temp\engine\!debug\input.obj"
"\Xash3D\src_main\temp\engine\!debug\net_chan.obj"
"\Xash3D\src_main\temp\engine\!debug\net_huff.obj"
"\Xash3D\src_main\temp\engine\!debug\net_msg.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_client.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_cmds.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_frame.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_game.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_init.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_main.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_move.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_phys.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_save.obj"
"\Xash3D\src_main\temp\engine\!debug\sv_world.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_advanced.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_audio.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_controls.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_credits.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_defaults.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_demos.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_gameoptions.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_gotosite.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_ingame.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_loadgame.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_main.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_menu.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_mods.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_multiplayer.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_network.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_options.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_performance.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_playersetup.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_qmenu.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_quit.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_savegame.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_singleplayer.obj"
"\Xash3D\src_main\temp\engine\!debug\ui_video.obj"
]
Creating command line "link.exe @"C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199D.tmp""
Creating temporary file "C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199E.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
]
Creating command line ""C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199E.bat""
Compiling...
cl_game.c
Linking...
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\engine\!debug\engine.dll
‘Ş®Ż¨ŕ®˘ ­® ä ©«®˘: 1.
<h3>Results</h3>
engine.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -172,6 +172,7 @@ bool Host_InitSound( void )
si.api_size = sizeof( vsound_imp_t );
si.GetSoundSpatialization = CL_GetEntitySoundSpatialization;
si.PointContents = CL_PointContents;
si.GetClientEdict = CL_GetEdictByIndex;
si.AddLoopingSounds = CL_AddLoopingSounds;
si.GetServerTime = CL_GetServerTime;

View File

@ -62,7 +62,6 @@ int SV_FindIndex( const char *name, int start, int end, bool create )
return i;
}
int SV_ModelIndex( const char *name )
{
return SV_FindIndex( name, CS_MODELS, MAX_MODELS, true );

View File

@ -560,14 +560,6 @@ void SV_ReadEntities( wfile_t *l )
if( sv.loadgame ) // allocate edicts
while( svgame.globals->numEntities < shdr.numEntities ) SV_AllocEdict();
else if( sv.changelevel )
{
// NOTE: we don't need allocate too many ents
// just set it number to match with old map and use
// SV_InitEdict istead of SV_AllocEdict, first SV_Physics call
// will be fixup entities count to actual
svgame.globals->numEntities = pSaveData->tableCount;
}
// set client fields on player ents
for( i = 0; i < svgame.globals->maxClients; i++ )
@ -613,6 +605,7 @@ void SV_ReadEntities( wfile_t *l )
{
if( pent->free ) SV_InitEdict( pent );
pent = SV_AllocPrivateData( pent, pTable->classname );
svgame.globals->numEntities++;
num_moveables++;
}
}

16
launch/launch.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: launch - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
launch.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

16
physic/physic.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: physic - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
physic.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -87,8 +87,8 @@ typedef struct render_exp_s
bool (*AddLightStyle)( int stylenum, vec3_t color );
void (*ClearScene)( void );
void (*BeginFrame)( void );
void (*RenderFrame)( ref_params_t *fd );
void (*BeginFrame)( const ref_params_t *fd );
void (*RenderFrame)( const ref_params_t *fd );
void (*EndFrame)( void );
// misc utilities

View File

@ -58,6 +58,7 @@ typedef struct vsound_imp_s
void (*GetSoundSpatialization)( int entnum, vec3_t origin, vec3_t velocity );
int (*PointContents)( const vec3_t point );
edict_t *(*GetClientEdict)( int index );
void (*AddLoopingSounds)( void );
int (*GetServerTime)( void );
} vsound_imp_t;

View File

@ -174,9 +174,10 @@ void CLight :: Think( void )
void CLight :: Spawn( void )
{
if (FStringNull(pev->targetname))
{ // inert light
REMOVE_ENTITY(ENT(pev));
if( FStringNull( pev->targetname ))
{
// inert light
REMOVE_ENTITY(ENT( pev ));
return;
}

16
server/server.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: server - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
server.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

1119
snd_dx/dsp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -34,13 +34,13 @@ typedef enum
cvar_t *s_wavonly;
static HWND snd_hwnd;
static bool dsound_init;
static bool wav_init;
static bool snd_firsttime = true, snd_isdirect, snd_iswave;
static bool primary_format_set;
static int snd_buffer_count = 0;
static int sample16;
static int snd_sent, snd_completed;
bool dsound_init;
bool wavout_init;
/*
=======================================================================
@ -316,7 +316,7 @@ void SNDDMA_FreeSound( void )
lpData = NULL;
lpWaveHdr = NULL;
dsound_init = false;
wav_init = false;
wavout_init = false;
}
/*
@ -336,9 +336,9 @@ si_state_t SNDDMA_InitDirect( void *hInst )
switch( s_khz->integer )
{
case 44: dma.speed = 44100; break;
case 22: dma.speed = 22050; break;
default: dma.speed = 11025; break;
case 44: dma.speed = SOUND_44k; break;
case 22: dma.speed = SOUND_22k; break;
default: dma.speed = SOUND_11k; break;
}
MsgDev( D_NOTE, "SNDDMA_InitDirect: initializing DirectSound ");
@ -409,9 +409,9 @@ si_state_t SNDDMA_InitWav( void )
switch( s_khz->integer )
{
case 44: dma.speed = 44100; break;
case 22: dma.speed = 22050; break;
default: dma.speed = 11025; break;
case 44: dma.speed = SOUND_44k; break;
case 22: dma.speed = SOUND_22k; break;
default: dma.speed = SOUND_11k; break;
}
Mem_Set( &format, 0, sizeof( format ));
@ -499,7 +499,7 @@ si_state_t SNDDMA_InitWav( void )
dma.submission_chunk = 512;
dma.buffer = (byte *)lpData;
sample16 = (dma.samplebits / 8) - 1;
wav_init = true;
wavout_init = true;
return SIS_SUCCESS;
}
@ -519,7 +519,7 @@ int SNDDMA_Init( void *hInst )
Mem_Set( &dma, 0, sizeof( dma ));
s_wavonly = Cvar_Get( "s_wavonly", "0", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "force to use WaveOutput only" );
dsound_init = wav_init = 0;
dsound_init = wavout_init = 0;
// init DirectSound
if( !s_wavonly->integer )
@ -560,7 +560,7 @@ int SNDDMA_Init( void *hInst )
}
snd_buffer_count = 1;
if( !dsound_init && !wav_init )
if( !dsound_init && !wavout_init )
{
if( snd_firsttime )
MsgDev( D_ERROR, "SNDDMA_Init: can't initialize sound device\n" );
@ -593,7 +593,7 @@ int SNDDMA_GetDMAPos( void )
pDSBuf->lpVtbl->GetCurrentPosition( pDSBuf, &mmtime.u.sample, &dwWrite );
s = mmtime.u.sample - mmstarttime.u.sample;
}
else if( wav_init )
else if( wavout_init )
{
s = snd_sent * WAV_BUFFER_SIZE;
}
@ -651,6 +651,57 @@ void SNDDMA_BeginPainting( void )
dma.buffer = (byte *)pbuf;
}
void *SNDDMA_LockBuffer( void )
{
int reps = 0;
void *pbuf = NULL, *pbuf2 = NULL;
DWORD dwSize2, dwStatus;
HRESULT hr;
if( !pDSBuf ) return dma.buffer;
// if the buffer was lost or stopped, restore it and/or restart it
if( pDSBuf->lpVtbl->GetStatus( pDSBuf, &dwStatus ) != DS_OK )
MsgDev( D_WARN, "SNDDMA_LockBuffer: couldn't get sound buffer status\n" );
if( dwStatus & DSBSTATUS_BUFFERLOST )
pDSBuf->lpVtbl->Restore( pDSBuf );
if(!( dwStatus & DSBSTATUS_PLAYING ))
pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING );
// lock the dsound buffer
dma.buffer = NULL;
reps = 0;
while(( hr = pDSBuf->lpVtbl->Lock( pDSBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0 )) != DS_OK )
{
if( hr != DSERR_BUFFERLOST )
{
MsgDev( D_ERROR, "SNDDMA_LockBuffer: lock failed with error '%s'\n", DSoundError( hr ));
S_Shutdown ();
S_Init ( snd_hwnd );
return NULL;
}
else pDSBuf->lpVtbl->Restore( pDSBuf );
if( ++reps > 100 )
{
MsgDev( D_ERROR, "SNDDMA_LockBuffer: couldn't restore buffer\n");
S_Shutdown ();
S_Init ( snd_hwnd );
return NULL;
}
}
dma.buffer = (byte *)pbuf;
return pbuf;
}
void SNDDMA_UnlockBuffer( void )
{
}
/*
==============
SNDDMA_Submit
@ -670,7 +721,7 @@ void SNDDMA_Submit( void )
// unlock the dsound buffer
if( pDSBuf ) pDSBuf->lpVtbl->Unlock( pDSBuf, dma.buffer, locksize, NULL, 0 );
if( !wav_init ) return;
if( !wavout_init ) return;
// find which sound blocks have completed
while( 1 )

6986
snd_dx/s_dsp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -331,6 +331,50 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
return true;
}
/*
=================
S_CreateMixer
=================
*/
static void S_CreateMixer( sfx_t *sfx )
{
// first time to load? Create the mixer
if( sfx->cache && !sfx->mixer )
{
mixer_t *pMixer = Z_Malloc( sizeof( mixer_t ));
pMixer->m_pData = sfx->cache;
if( sfx->cache->stereo )
{
if( sfx->cache->width == 1 )
{
Msg( "S_LoadSound: use Mix8Stereo( %s )\n", sfx->name );
pMixer->MixFunc = Mix8Stereo;
}
else
{
Msg( "S_LoadSound: use Mix16Stereo( %s )\n", sfx->name );
pMixer->MixFunc = Mix16Stereo;
}
}
else
{
if( sfx->cache->width == 1 )
{
Msg( "S_LoadSound: use Mix8Mono( %s )\n", sfx->name );
pMixer->MixFunc = Mix8Mono;
}
else
{
Msg( "S_LoadSound: use Mix16Mono( %s )\n", sfx->name );
pMixer->MixFunc = Mix16Mono;
}
}
sfx->mixer = pMixer; // done
}
}
/*
=================
S_UploadSound
@ -355,6 +399,7 @@ static void S_UploadSound( byte *data, wavinfo_t *info, sfx_t *sfx )
sc->stereo = info->channels;
S_ResampleSfx( sfx, sc->speed, sc->width, data + info->dataofs );
S_CreateMixer( sfx );
}
/*
@ -400,7 +445,7 @@ loadformat_t load_formats[] =
{ NULL, NULL }
};
sfxcache_t *S_LoadSound( sfx_t *sfx )
sfxcache_t *S_LoadSound( sfx_t *sfx, channel_t *ch )
{
byte *data;
wavinfo_t info;
@ -409,6 +454,10 @@ sfxcache_t *S_LoadSound( sfx_t *sfx )
loadformat_t *format;
bool anyformat;
// setup channel mixer
if( ch && !ch->pMixer && sfx && sfx->mixer )
ch->pMixer = sfx->mixer;
if( !sfx ) return NULL;
if( sfx->name[0] == '*' ) return NULL;
if( sfx->cache ) return sfx->cache; // see if still in memory
@ -538,6 +587,7 @@ void S_EndRegistration( void )
{
// don't need this sound
if( sfx->cache ) Mem_Free( sfx->cache );
if( sfx->mixer ) Mem_Free( sfx->mixer );
Mem_Set( sfx, 0, sizeof( *sfx ));
}
}
@ -546,7 +596,7 @@ void S_EndRegistration( void )
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
{
if( !sfx->name[0] ) continue;
S_LoadSound( sfx );
S_LoadSound( sfx, NULL );
}
s_registering = false;
}
@ -568,7 +618,7 @@ sound_t S_RegisterSound( const char *name )
if( !sfx ) return -1;
sfx->registration_sequence = s_registration_sequence;
if( !s_registering ) S_LoadSound( sfx );
if( !s_registering ) S_LoadSound( sfx, NULL );
return sfx - s_knownSfx;
}
@ -601,6 +651,7 @@ void S_FreeSounds( void )
{
if( !sfx->name[0] ) continue;
if( sfx->cache ) Mem_Free( sfx->cache );
if( sfx->mixer ) Mem_Free( sfx->mixer );
Mem_Set( sfx, 0, sizeof( *sfx ));
}

View File

@ -10,9 +10,22 @@
#define SOUND_LOOPATTENUATE 0.003
#define MAX_PLAYSOUNDS 128
// Structure used for fading in and out client sound volume.
typedef struct
{
float initial_percent;
float percent; // how far to adjust client's volume down by.
float starttime; // si.GetServerTime() when we started adjusting volume
float fadeouttime; // # of seconds to get to faded out state
float holdtime; // # of seconds to hold
float fadeintime; // # of seconds to restore
} soundfade_t;
dma_t dma;
static soundfade_t soundfade; // client sound fading
channel_t channels[MAX_CHANNELS];
bool sound_started = false;
int listener_waterlevel;
vec3_t listener_origin;
vec3_t listener_velocity;
vec3_t listener_forward;
@ -48,6 +61,19 @@ cvar_t *s_pause;
=============================================================================
*/
float S_GetMasterVolume( void )
{
float scale = 1.0f;
if( soundfade.percent != 0 )
{
scale = bound( 0.0f, soundfade.percent / 100.0f, 1.0f );
scale = 1.0f - scale;
}
return s_volume->value * scale;
}
/*
=================
S_PickChannel
@ -262,7 +288,7 @@ void S_IssuePlaysound( playsound_t *ps )
S_SpatializeChannel( ch );
ch->pos = 0;
sc = S_LoadSound( ch->sfx );
sc = S_LoadSound( ch->sfx, ch );
ch->end = paintedtime + sc->length;
// free the playsound
@ -296,7 +322,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
if( !sfx ) return;
// make sure the sound is loaded
sc = S_LoadSound( sfx );
sc = S_LoadSound( sfx, NULL );
if( !sc ) return; // couldn't load the sound's data
vol = fvol * 255;
@ -580,6 +606,7 @@ void S_Update( ref_params_t *fd )
if( s_volume->modified ) S_InitScaletable();
s_clientnum = fd->viewentity;
listener_waterlevel = fd->waterlevel;
VectorCopy( fd->simorg, listener_origin );
VectorCopy( fd->simvel, listener_velocity );
VectorCopy( fd->forward, listener_forward );
@ -669,6 +696,9 @@ void S_SoundInfo_f( void )
Msg( "sound system not started\n" );
return;
}
if( dsound_init ) Msg( "Sound Device: DirectSound\n" );
if( wavout_init ) Msg( "Sound Device: Windows WAV\n" );
Msg( "%5d channel(s)\n", dma.channels );
Msg( "%5d samples\n", dma.samples );
@ -725,6 +755,8 @@ bool S_Init( void *hInst )
S_StopAllSounds ();
AllocDsps();
return true;
}
@ -745,4 +777,6 @@ void S_Shutdown( void )
S_FreeSounds();
Mem_FreePool( &sndpool );
FreeDsps();
}

View File

@ -21,11 +21,79 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "sound.h"
#define PAINTBUFFER_SIZE 2048
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
int snd_scaletable[32][256];
int *snd_p, snd_linear_count, snd_vol;
short *snd_out;
// global sound filters
#define FILTERTYPE_NONE 0
#define FILTERTYPE_LINEAR 1
#define FILTERTYPE_CUBIC 2
#define SOUND_MIX_WET 0 // mix only samples that don't have channel set to 'dry' (default)
#define SOUND_MIX_DRY 1 // mix only samples with channel set to 'dry' (ie: music)
samplepair_t paintbuffer[(PAINTBUFFER_SIZE+1)];
samplepair_t roombuffer[(PAINTBUFFER_SIZE+1)];
samplepair_t facingbuffer[(PAINTBUFFER_SIZE+1)];
samplepair_t facingawaybuffer[(PAINTBUFFER_SIZE+1)];
samplepair_t drybuffer[(PAINTBUFFER_SIZE+1)];
// filter memory for upsampling
samplepair_t cubicfilter1[3] = {{0,0},{0,0},{0,0}};
samplepair_t cubicfilter2[3] = {{0,0},{0,0},{0,0}};
samplepair_t linearfilter1[1] = {0,0};
samplepair_t linearfilter2[1] = {0,0};
samplepair_t linearfilter3[1] = {0,0};
samplepair_t linearfilter4[1] = {0,0};
samplepair_t linearfilter5[1] = {0,0};
samplepair_t linearfilter6[1] = {0,0};
samplepair_t linearfilter7[1] = {0,0};
samplepair_t linearfilter8[1] = {0,0};
// temp paintbuffer - not included in main list of paintbuffers
samplepair_t temppaintbuffer[(PAINTBUFFER_SIZE+1)];
samplepair_t *g_curpaintbuffer;
paintbuffer_t paintbuffers[CPAINTBUFFERS];
bool g_bDspOff;
bool g_bdirectionalfx;
int snd_scaletable[SND_SCALE_LEVELS][256];
int *snd_p, snd_linear_count, snd_vol;
short *snd_out;
//===============================================================================
// Mix buffer (paintbuffer) management routines
//===============================================================================
void MIX_FreeAllPaintbuffers( void )
{
// clear paintbuffer structs
Mem_Set( paintbuffers, 0, CPAINTBUFFERS * sizeof( paintbuffer_t ));
}
bool MIX_InitAllPaintbuffers(void)
{
// clear paintbuffer structs
MIX_FreeAllPaintbuffers ();
// front, rear & dry paintbuffers
paintbuffers[IPAINTBUFFER].pbuf = paintbuffer;
paintbuffers[IROOMBUFFER].pbuf = roombuffer;
paintbuffers[IFACINGBUFFER].pbuf = facingbuffer;
paintbuffers[IFACINGAWAYBUFFER].pbuf = facingawaybuffer;
paintbuffers[IDRYBUFFER].pbuf = drybuffer;
// buffer flags
paintbuffers[IROOMBUFFER].flags = SOUND_BUSS_ROOM;
paintbuffers[IFACINGBUFFER].flags = SOUND_BUSS_FACING;
paintbuffers[IFACINGAWAYBUFFER].flags = SOUND_BUSS_FACINGAWAY;
MIX_SetCurrentPaintbuffer( IPAINTBUFFER );
return true;
}
void S_ApplyDSPEffects( int idsp, samplepair_t *pbuffront, int samplecount )
{
DSP_Process( idsp, pbuffront, samplecount );
}
void S_WriteLinearBlastStereo16( void )
{
@ -50,10 +118,13 @@ void S_WriteLinearBlastStereo16( void )
void S_TransferStereo16( dword *pbuf, int endtime )
{
int lpos, lpaintedtime;
snd_p = (int *)paintbuffer;
snd_vol = S_GetMasterVolume() * 256;
snd_p = (int *)PAINTBUFFER;
lpaintedtime = paintedtime;
if( !pbuf ) return;
while( lpaintedtime < endtime )
{
// handle recirculating buffer issues
@ -103,50 +174,42 @@ void S_TransferPaintBuffer( int endtime )
}
}
// general case
p = (int *)paintbuffer;
count = (endtime - paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
snd_vol = S_GetMasterVolume() * 256;
if( dma.samplebits == 16 && dma.channels == 2 )
{
// optimized case
S_TransferStereo16( pbuf, endtime );
}
else
{
// general case
p = (int *)paintbuffer;
count = (endtime - paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
if( !pbuf ) return;
if( dma.samplebits == 16 )
if( dma.samplebits == 16 )
{
short *out = (short *)pbuf;
while( count-- )
{
short *out = (short *)pbuf;
val = (*p * snd_vol) >> 8;
p += step;
val = CLIP( val );
while( count-- )
{
val = *p >> 8;
p += step;
if( val > 0x7fff ) val = 0x7fff;
else if( val < (short)0x8000 )
val = (short)0x8000;
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
}
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
}
else if( dma.samplebits == 8 )
{
byte *out = (byte *)pbuf;
}
else if( dma.samplebits == 8 )
{
byte *out = (byte *)pbuf;
while( count-- )
{
val = *p >> 8;
p += step;
if( val > 0x7fff ) val = 0x7fff;
else if( val < (short)0x8000 )
val = (short)0x8000;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
}
while( count-- )
{
val = (*p * snd_vol) >> 8;
p += step;
val = CLIP( val );
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
}
}
}
@ -158,12 +221,411 @@ CHANNEL MIXING
===============================================================================
*/
// pass in index -1...count+2, return pointer to source sample in either paintbuffer or delay buffer
_inline samplepair_t * S_GetNextpFilter(int i, samplepair_t *pbuffer, samplepair_t *pfiltermem)
{
// The delay buffer is assumed to precede the paintbuffer by 6 duplicated samples
if (i == -1)
return (&(pfiltermem[0]));
if (i == 0)
return (&(pfiltermem[1]));
if (i == 1)
return (&(pfiltermem[2]));
// return from paintbuffer, where samples are doubled.
// even samples are to be replaced with interpolated value.
return (&(pbuffer[(i-2)*2 + 1]));
}
// pass forward over passed in buffer and cubic interpolate all odd samples
// pbuffer: buffer to filter (in place)
// prevfilter: filter memory. NOTE: this must match the filtertype ie: filtercubic[] for FILTERTYPE_CUBIC
// if NULL then perform no filtering. UNDONE: should have a filter memory array type
// count: how many samples to upsample. will become count*2 samples in buffer, in place.
void S_Interpolate2xCubic( samplepair_t *pbuffer, samplepair_t *pfiltermem, int cfltmem, int count )
{
// implement cubic interpolation on 2x upsampled buffer. Effectively delays buffer contents by 2 samples.
// pbuffer: contains samples at 0, 2, 4, 6...
// temppaintbuffer is temp buffer, same size as paintbuffer, used to store processed values
// count: number of samples to process in buffer ie: how many samples at 0, 2, 4, 6...
// finpos is the fractional, inpos the integer part.
// finpos = 0.5 for upsampling by 2x
// inpos is the position of the sample
// xm1 = x [inpos - 1];
// x0 = x [inpos + 0];
// x1 = x [inpos + 1];
// x2 = x [inpos + 2];
// a = (3 * (x0-x1) - xm1 + x2) / 2;
// b = 2*x1 + xm1 - (5*x0 + x2) / 2;
// c = (x1 - xm1) / 2;
// y [outpos] = (((a * finpos) + b) * finpos + c) * finpos + x0;
int i, upCount = count << 1;
int a, b, c;
int xm1, x0, x1, x2;
samplepair_t *psamp0;
samplepair_t *psamp1;
samplepair_t *psamp2;
samplepair_t *psamp3;
int outpos = 0;
Assert (upCount <= PAINTBUFFER_SIZE);
// pfiltermem holds 6 samples from previous buffer pass
// process 'count' samples
for ( i = 0; i < count; i++)
{
// get source sample pointer
psamp0 = S_GetNextpFilter(i-1, pbuffer, pfiltermem);
psamp1 = S_GetNextpFilter(i, pbuffer, pfiltermem);
psamp2 = S_GetNextpFilter(i+1, pbuffer, pfiltermem);
psamp3 = S_GetNextpFilter(i+2, pbuffer, pfiltermem);
// write out original sample to interpolation buffer
temppaintbuffer[outpos++] = *psamp1;
// get all left samples for interpolation window
xm1 = psamp0->left;
x0 = psamp1->left;
x1 = psamp2->left;
x2 = psamp3->left;
// interpolate
a = (3 * (x0-x1) - xm1 + x2) / 2;
b = 2*x1 + xm1 - (5*x0 + x2) / 2;
c = (x1 - xm1) / 2;
// write out interpolated sample
temppaintbuffer[outpos].left = a/8 + b/4 + c/2 + x0;
// get all right samples for window
xm1 = psamp0->right;
x0 = psamp1->right;
x1 = psamp2->right;
x2 = psamp3->right;
// interpolate
a = (3 * (x0-x1) - xm1 + x2) / 2;
b = 2*x1 + xm1 - (5*x0 + x2) / 2;
c = (x1 - xm1) / 2;
// write out interpolated sample, increment output counter
temppaintbuffer[outpos++].right = a/8 + b/4 + c/2 + x0;
Assert( outpos <= ARRAYSIZE( temppaintbuffer ));
}
Assert(cfltmem >= 3);
// save last 3 samples from paintbuffer
pfiltermem[0] = pbuffer[upCount - 5];
pfiltermem[1] = pbuffer[upCount - 3];
pfiltermem[2] = pbuffer[upCount - 1];
// copy temppaintbuffer back into paintbuffer
for (i = 0; i < upCount; i++)
pbuffer[i] = temppaintbuffer[i];
}
// pass forward over passed in buffer and linearly interpolate all odd samples
// pbuffer: buffer to filter (in place)
// prevfilter: filter memory. NOTE: this must match the filtertype ie: filterlinear[] for FILTERTYPE_LINEAR
// if NULL then perform no filtering.
// count: how many samples to upsample. will become count*2 samples in buffer, in place.
void S_Interpolate2xLinear( samplepair_t *pbuffer, samplepair_t *pfiltermem, int cfltmem, int count )
{
int i, upCount = count<<1;
Assert (upCount <= PAINTBUFFER_SIZE);
Assert (cfltmem >= 1);
// use interpolation value from previous mix
pbuffer[0].left = (pfiltermem->left + pbuffer[0].left) >> 1;
pbuffer[0].right = (pfiltermem->right + pbuffer[0].right) >> 1;
for ( i = 2; i < upCount; i+=2)
{
// use linear interpolation for upsampling
pbuffer[i].left = (pbuffer[i].left + pbuffer[i-1].left) >> 1;
pbuffer[i].right = (pbuffer[i].right + pbuffer[i-1].right) >> 1;
}
// save last value to be played out in buffer
*pfiltermem = pbuffer[upCount - 1];
}
// upsample by 2x, optionally using interpolation
// count: how many samples to upsample. will become count*2 samples in buffer, in place.
// pbuffer: buffer to upsample into (in place)
// pfiltermem: filter memory. NOTE: this must match the filtertype ie: filterlinear[] for FILTERTYPE_LINEAR
// if NULL then perform no filtering.
// cfltmem: max number of sample pairs filter can use
// filtertype: FILTERTYPE_NONE, _LINEAR, _CUBIC etc. Must match prevfilter.
void S_MixBufferUpsample2x( int count, samplepair_t *pbuffer, samplepair_t *pfiltermem, int cfltmem, int filtertype )
{
int i, j, upCount = count<<1;
// reverse through buffer, duplicating contents for 'count' samples
for (i = upCount - 1, j = count - 1; j >= 0; i-=2, j--)
{
pbuffer[i] = pbuffer[j];
pbuffer[i-1] = pbuffer[j];
}
// pass forward through buffer, interpolate all even slots
switch (filtertype)
{
default:
break;
case FILTERTYPE_LINEAR:
S_Interpolate2xLinear(pbuffer, pfiltermem, cfltmem, count);
break;
case FILTERTYPE_CUBIC:
S_Interpolate2xCubic(pbuffer, pfiltermem, cfltmem, count);
break;
}
}
//===============================================================================
// PAINTBUFFER ROUTINES
//===============================================================================
// Set current paintbuffer to pbuf.
// The set paintbuffer is used by all subsequent mixing, upsampling and dsp routines.
// Also sets the rear paintbuffer if paintbuffer has fsurround true.
// (otherwise, rearpaintbuffer is NULL)
_inline void MIX_SetCurrentPaintbuffer(int ipaintbuffer)
{
// set front and rear paintbuffer
Assert( ipaintbuffer < CPAINTBUFFERS );
g_curpaintbuffer = paintbuffers[ipaintbuffer].pbuf;
Assert( g_curpaintbuffer != NULL );
}
// return index to current paintbuffer
_inline int MIX_GetCurrentPaintbufferIndex( void )
{
int i;
for( i = 0; i < CPAINTBUFFERS; i++ )
{
if( g_curpaintbuffer == paintbuffers[i].pbuf )
return i;
}
return 0;
}
_inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void )
{
int ipaint = MIX_GetCurrentPaintbufferIndex();
Assert( ipaint < CPAINTBUFFERS );
return &paintbuffers[ipaint];
}
int S_ConvertLoopedPosition( sfxcache_t *cache, int samplePosition )
{
// if the wave is looping and we're past the end of the sample
// convert to a position within the loop
// At the end of the loop, we return a short buffer, and subsequent call
// will loop back and get the rest of the buffer
if( cache->loopstart >= 0 && samplePosition >= cache->length )
{
// size of loop
int loopSize = cache->length - cache->loopstart;
// subtract off starting bit of the wave
samplePosition -= cache->loopstart;
if( loopSize )
{
// "real" position in memory (mod off extra loops)
samplePosition = cache->loopstart + (samplePosition % loopSize);
}
// ERROR? if no loopSize
}
return samplePosition;
}
int S_GetOutputData( sfxcache_t *cache, void **pData, int samplePosition, int sampleCount )
{
int totalSampleCount;
// handle position looping
samplePosition = S_ConvertLoopedPosition( cache, samplePosition );
// how many samples are available (linearly not counting looping)
totalSampleCount = cache->length - samplePosition;
// may be asking for a sample out of range, clip at zero
if( totalSampleCount < 0 ) totalSampleCount = 0;
// clip max output samples to max available
if( sampleCount > totalSampleCount ) sampleCount = totalSampleCount;
// byte offset in sample database
samplePosition *= cache->width;
// if we are returning some samples, store the pointer
if( sampleCount )
{
*pData = cache->data + samplePosition;
Assert( *pData );
}
return sampleCount;
}
int S_MixDataToDevice( channel_t *pChannel, int sampleCount, int outputRate, int outputOffset )
{
float inputRate, rate;
int startingOffset = outputOffset; // save this to compute total output
mixer_t *pMixer;
// shouldn't be playing this if finished, but return if we are
if( !pChannel || !pChannel->pMixer || pChannel->pMixer->m_finished )
return 0;
pMixer = pChannel->pMixer;
inputRate = ( pChannel->pitch * pChannel->pMixer->m_pData->speed );
rate = inputRate / outputRate;
// if we are terminating this wave prematurely, then make sure we detect the limit
if( pMixer->m_forcedEndSample )
{
// How many total input samples will we need?
int samplesRequired = (int)(sampleCount * rate);
// will this hit the end?
if( pMixer->m_sample + samplesRequired >= pMixer->m_forcedEndSample )
{
// yes, mark finished and truncate the sample request
pMixer->m_finished = true;
sampleCount = (int)((pMixer->m_forcedEndSample - pMixer->m_sample) / rate );
}
}
while( sampleCount > 0 )
{
bool advanceSample = true;
int availableSamples, outputSampleCount;
char *pData = NULL;
// compute number of input samples required
double end = pMixer->m_sample + rate * sampleCount;
int i, j, inputSampleCount = (int)(ceil(end) - floor(pMixer->m_sample));
double sampleFraction;
// ask the source for the data
char copyBuf[4096];
if( pMixer->m_delaySamples > 0 )
{
int num_zero_samples = min( pMixer->m_delaySamples, inputSampleCount );
int sampleSize, readBytes;
// decrement data amount
pMixer->m_delaySamples -= num_zero_samples;
sampleSize = pMixer->m_pData->width;
readBytes = sampleSize * num_zero_samples;
Assert( readBytes <= sizeof( copyBuf ));
pData = &copyBuf[0];
// now copy in some zeroes
Mem_Set( pData, 0, readBytes );
availableSamples = num_zero_samples;
advanceSample = false;
}
else
{
availableSamples = S_GetOutputData( pMixer->m_pData, (void**)&pData,
pMixer->m_sample, inputSampleCount );
}
// none available, bail out
if( !availableSamples )
{
break;
}
sampleFraction = pMixer->m_sample - floor( pMixer->m_sample );
if( availableSamples < inputSampleCount )
{
// How many samples are there given the number of input samples and the rate.
outputSampleCount = (int)ceil((availableSamples - sampleFraction) / rate);
}
else
{
outputSampleCount = sampleCount;
}
// Verify that we won't get a buffer overrun.
Assert( floor( sampleFraction + rate * ( outputSampleCount - 1 )) <= availableSamples);
// mix this data to all active paintbuffers
// save current paintbuffer
j = MIX_GetCurrentPaintbufferIndex();
for( i = 0; i < CPAINTBUFFERS; i++ )
{
if( paintbuffers[i].factive && pMixer->MixFunc )
{
// mix chan into all active paintbuffers
MIX_SetCurrentPaintbuffer(i);
pMixer->MixFunc( pChannel, pData, outputOffset,
FIX_FLOAT(sampleFraction), FIX_FLOAT(rate), outputSampleCount );
}
}
MIX_SetCurrentPaintbuffer( j );
if( advanceSample )
pMixer->m_sample += outputSampleCount * rate;
outputOffset += outputSampleCount;
sampleCount -= outputSampleCount;
}
// did we run out of samples? if so, mark finished
if( sampleCount > 0 ) pMixer->m_finished = true;
// total number of samples mixed !!! at the output clock rate !!!
return outputOffset - startingOffset;
}
void S_PaintChannelFrom8( channel_t *ch, sfxcache_t *sc, int count, int offset )
{
int data;
int *lscale, *rscale;
byte *sfx;
portable_samplepair_t *samp;
samplepair_t *samp;
int i;
if( ch->leftvol > 255 ) ch->leftvol = 255;
@ -190,7 +652,7 @@ void S_PaintChannelFrom16( channel_t *ch, sfxcache_t *sc, int count, int offset
int left, right;
int leftvol, rightvol;
signed short *sfx;
portable_samplepair_t *samp;
samplepair_t *samp;
int i;
leftvol = ch->leftvol * snd_vol;
@ -215,10 +677,32 @@ void S_PaintChannels( int endtime )
channel_t *ch;
sfxcache_t *sc;
playsound_t *ps;
int i, end, ltime, count;
int i, end, ltime, count = 0;
float dsp_room_gain;
float dsp_facingaway_gain;
float dsp_player_gain;
float dsp_water_gain;
snd_vol = s_volume->value * 256;
CheckNewDspPresets();
g_bDspOff = dsp_off->integer ? 1 : 0;
if( !g_bDspOff )
g_bdirectionalfx = dsp_facingaway->integer ? 1 : 0;
else g_bdirectionalfx = 0;
// get dsp preset gain values, update gain crossfaders,
// used when mixing dsp processed buffers into paintbuffer
// update crossfader - gain only used in MIX_ScaleChannelVolume
dsp_room_gain = DSP_GetGain( idsp_room );
// update crossfader - gain only used in MIX_ScaleChannelVolume
dsp_facingaway_gain = DSP_GetGain( idsp_facingaway );
dsp_player_gain = DSP_GetGain( idsp_player );
dsp_water_gain = DSP_GetGain( idsp_water );
while( paintedtime < endtime )
{
// if paintbuffer is smaller than DMA buffer
@ -245,7 +729,7 @@ void S_PaintChannels( int endtime )
// clear the paint buffer
if( s_rawend < paintedtime )
{
Mem_Set( paintbuffer, 0, (end - paintedtime) * sizeof( portable_samplepair_t ));
Mem_Set( paintbuffer, 0, (end - paintedtime) * sizeof( samplepair_t ));
}
else
{
@ -277,7 +761,7 @@ void S_PaintChannels( int endtime )
// might be stopped by running out of data
if( ch->end - ltime < count ) count = ch->end - ltime;
sc = S_LoadSound( ch->sfx );
sc = S_LoadSound( ch->sfx, ch );
if( !sc ) break;
if( count > 0 && ch->sfx )
@ -307,6 +791,8 @@ void S_PaintChannels( int endtime )
}
}
SX_RoomFX( endtime, count, endtime - paintedtime );
// transfer out according to DMA format
S_TransferPaintBuffer( end );
paintedtime = end;
@ -316,12 +802,8 @@ void S_PaintChannels( int endtime )
void S_InitScaletable( void )
{
int i, j;
int scale;
for( i = 0; i < 32; i++ )
{
scale = i * 8 * 256 * s_volume->value;
for( j = 0; j < 256; j++ ) snd_scaletable[i][j] = ((signed char)j) * scale;
}
s_volume->modified = false;
}
for( i = 0; i < SND_SCALE_LEVELS; i++ )
for( j = 0; j < 256; j++ )
snd_scaletable[i][j] = ((signed char)j) * i * (1<<SND_SCALE_SHIFT);
}

576
snd_dx/s_mix_chan.c Normal file
View File

@ -0,0 +1,576 @@
//=======================================================================
// Copyright XashXT Group 2009 ©
// s_mix_chan.c - channel mixer
//=======================================================================
#include "sound.h"
void SND_PaintChannelFrom8( int *volume, byte *pData8, int count )
{
int data;
int *lscale, *rscale;
int i;
lscale = snd_scaletable[volume[0] >> SND_SCALE_SHIFT];
rscale = snd_scaletable[volume[1] >> SND_SCALE_SHIFT];
for( i = 0; i < count; i++ )
{
data = pData8[i];
paintbuffer[i].left += lscale[data];
paintbuffer[i].right += rscale[data];
}
}
// Applies volume scaling (evenly) to all fl,fr,rl,rr volumes
// used for voice ducking and panning between various mix busses
// Called just before mixing wav data to current paintbuffer.
// a) if another player in a multiplayer game is speaking, scale all volumes down.
// b) if mixing to IROOMBUFFER, scale all volumes by ch.dspmix and dsp_room gain
// c) if mixing to IFACINGAWAYBUFFER, scale all volumes by ch.dspface and dsp_facingaway gain
// d) If SURROUND_ON, but buffer is not surround, recombined front/rear volumes
void MIX_ScaleChannelVolume( paintbuffer_t *ppaint, channel_t *pChannel, int volume[CCHANVOLUMES], int mixchans )
{
float scale, cone;
int i, *pvol;
int mixflag = ppaint->flags;
char wavtype = pChannel->wavtype;
pvol = &pChannel->leftvol;
// copy channel volumes into output array
for( i = 0; i < CCHANVOLUMES; i++ )
volume[i] = pvol[i];
// If mixing to the room buss, adjust volume based on channel's dspmix setting.
// dspmix is DSP_MIX_MAX (~0.78) if sound is far from player, DSP_MIX_MIN (~0.24) if sound is near player
if( mixflag & SOUND_BUSS_ROOM )
{
// get current idsp_room gain
float dsp_gain = DSP_GetGain( idsp_room );
// if dspmix is 1.0, 100% of sound goes to both IROOMBUFFER and IFACINGBUFFER
for( i = 0; i < CCHANVOLUMES; i++ )
volume[i] = (int)((float)(volume[i]) * pChannel->dspmix * dsp_gain );
}
// If mixing to facing/facingaway buss, adjust volume based on sound entity's facing direction.
// If sound directly faces player, ch->dspface = 1.0. If facing directly away, ch->dspface = -1.0.
// mix to lowpass buffer if facing away, to allpass if facing
// scale 1.0 - facing player, scale 0, facing away
scale = (pChannel->dspface + 1.0) / 2.0;
// UNDONE: get front cone % from channel to set this.
// bias scale such that 1.0 to 'cone' is considered facing. Facing cone narrows as cone -> 1.0
// and 'cone' -> 0.0 becomes 1.0 -> 0.0
cone = 0.6f;
scale = scale * ( 1 / cone );
scale = bound( 0.0f, scale, 1.0f );
// pan between facing and facing away buffers
if( !g_bdirectionalfx || wavtype != CHAR_DIRECTIONAL )
{
// if no directional fx mix 0% to facingaway buffer
// if wavtype is DOPPLER, mix 0% to facingaway buffer - DOPPLER wavs have a custom mixer
// if wavtype is OMNI, mix 0% to faceingaway buffer - OMNI wavs have no directionality
// if wavtype is DIRECTIONAL and stereo encoded, mix 0% to facingaway buffer -
// DIRECTIONAL STEREO wavs have a custom mixer
scale = 1.0;
}
if( mixflag & SOUND_BUSS_FACING )
{
// facing player
// if dspface is 1.0, 100% of sound goes to IFACINGBUFFER
for( i = 0; i < CCHANVOLUMES; i++ )
volume[i] = (int)((float)(volume[i]) * scale * (1.0 - pChannel->dspmix));
}
else if( mixflag & SOUND_BUSS_FACINGAWAY )
{
// facing away from player
// if dspface is 0.0, 100% of sound goes to IFACINGAWAYBUFFER
// get current idsp_facingaway gain
float dsp_gain = DSP_GetGain( idsp_facingaway );
for( i = 0; i < CCHANVOLUMES; i++ )
volume[i] = (int)((float)(volume[i]) * (1.0-scale) * dsp_gain * (1.0-pChannel->dspmix));
}
// NOTE: this must occur last in this routine:
for( i = 0; i < CCHANVOLUMES; i++ )
volume[i] = bound( 0, volume[i], 255 );
}
//===============================================================================
// SOFTWARE MIXING ROUTINES
//===============================================================================
// UNDONE: optimize these
// grab samples from left source channel only and mix as if mono.
// volume array contains appropriate spatialization volumes for doppler left (incoming sound)
void SW_Mix8StereoDopplerLeft( samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, *lscale, *rscale;
lscale = snd_scaletable[volume[0] >> SND_SCALE_SHIFT];
rscale = snd_scaletable[volume[1] >> SND_SCALE_SHIFT];
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += lscale[pData[sampleIndex]];
pOutput[i].right += rscale[pData[sampleIndex]];
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART( sampleFrac )<<1;
sampleFrac = FIX_FRACPART( sampleFrac );
}
}
// grab samples from right source channel only and mix as if mono.
// volume array contains appropriate spatialization volumes for doppler right (outgoing sound)
void SW_Mix8StereoDopplerRight( samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, *lscale, *rscale;
lscale = snd_scaletable[volume[0] >> SND_SCALE_SHIFT];
rscale = snd_scaletable[volume[1] >> SND_SCALE_SHIFT];
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += lscale[pData[sampleIndex+1]];
pOutput[i].right += rscale[pData[sampleIndex+1]];
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
// grab samples from left source channel only and mix as if mono.
// volume array contains appropriate spatialization volumes for doppler left (incoming sound)
void SW_Mix16StereoDopplerLeft( samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int i, sampleIndex = 0;
uint sampleFrac = inputOffset;
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += (volume[0] * (int)(pData[sampleIndex]))>>8;
pOutput[i].right += (volume[1] * (int)(pData[sampleIndex]))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART( sampleFrac )<<1;
sampleFrac = FIX_FRACPART( sampleFrac );
}
}
// grab samples from right source channel only and mix as if mono.
// volume array contains appropriate spatialization volumes for doppler right (outgoing sound)
void SW_Mix16StereoDopplerRight( samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int i, sampleIndex = 0;
uint sampleFrac = inputOffset;
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += (volume[0] * (int)(pData[sampleIndex+1]))>>8;
pOutput[i].right += (volume[1] * (int)(pData[sampleIndex+1]))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
// mix left wav (front facing) with right wav (rear facing) based on soundfacing direction
void SW_Mix8StereoDirectional( float soundfacing, samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, x;
int l, r;
signed char lb,rb;
// if soundfacing -1.0, sound source is facing away from player
// if soundfacing 0.0, sound source is perpendicular to player
// if soundfacing 1.0, sound source is facing player
int frontmix = (int)(256.0f * ((1.f + soundfacing) / 2.f)); // 0 -> 256
int rearmix = (int)(256.0f * ((1.f - soundfacing) / 2.f)); // 256 -> 0
for( i = 0; i < outCount; i++ )
{
lb = (pData[sampleIndex]); // get left byte
rb = (pData[sampleIndex+1]); // get right byte
l = ((int)lb) << 8; // convert to 16 bit. UNDONE: better dithering
r = ((int)rb) << 8;
x = ((l * frontmix) >> 8) + ((r * rearmix) >> 8);
pOutput[i].left += (volume[0] * (int)(x))>>8;
pOutput[i].right += (volume[1] * (int)(x))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART( sampleFrac )<<1;
sampleFrac = FIX_FRACPART( sampleFrac );
}
}
// mix left wav (front facing) with right wav (rear facing) based on soundfacing direction
void SW_Mix16StereoDirectional( float soundfacing, samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, x;
int l, r;
// if soundfacing -1.0, sound source is facing away from player
// if soundfacing 0.0, sound source is perpendicular to player
// if soundfacing 1.0, sound source is facing player
int frontmix = (int)(256.0f * ((1.f + soundfacing) / 2.f)); // 0 -> 256
int rearmix = (int)(256.0f * ((1.f - soundfacing) / 2.f)); // 256 -> 0
for( i = 0; i < outCount; i++ )
{
l = (int)(pData[sampleIndex]);
r = (int)(pData[sampleIndex+1]);
x = ((l * frontmix) >> 8) + ((r * rearmix) >> 8);
pOutput[i].left += (volume[0] * (int)(x))>>8;
pOutput[i].right += (volume[1] * (int)(x))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
void SW_Mix8StereoDistVar( float distmix, samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, x;
int l, r;
signed char lb, rb;
// distmix 0 - sound is near player (100% wav left)
// distmix 1.0 - sound is far from player (100% wav right)
int nearmix = (int)(256.0f * (1.0f - distmix));
int farmix = (int)(256.0f * distmix);
// if mixing at max or min range, skip crossfade (KDB: perf)
if( !nearmix )
{
for( i = 0; i < outCount; i++ )
{
rb = (pData[sampleIndex+1]); // get right byte
x = ((int)rb) << 8; // convert to 16 bit. UNDONE: better dithering
pOutput[i].left += (volume[0] * (int)(x))>>8;
pOutput[i].right += (volume[1] * (int)(x))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
return;
}
if( !farmix )
{
for( i = 0; i < outCount; i++ )
{
lb = (pData[sampleIndex]); // get left byte
x = ((int)lb) << 8; // convert to 16 bit. UNDONE: better dithering
pOutput[i].left += (volume[0] * (int)(x))>>8;
pOutput[i].right += (volume[1] * (int)(x))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
return;
}
// crossfade left/right
for( i = 0; i < outCount; i++ )
{
lb = (pData[sampleIndex]); // get left byte
rb = (pData[sampleIndex+1]); // get right byte
l = ((int)lb) << 8; // convert to 16 bit. UNDONE: better dithering
r = ((int)rb) << 8;
x = ((l * nearmix) >> 8) + ((r * farmix) >> 8);
pOutput[i].left += (volume[0] * (int)(x))>>8;
pOutput[i].right += (volume[1] * (int)(x))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
void SW_Mix16StereoDistVar( float distmix, samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, x;
int l, r;
// distmix 0 - sound is near player (100% wav left)
// distmix 1.0 - sound is far from player (100% wav right)
int nearmix = (int)( 256.0f * ( 1.0f - distmix ));
int farmix = (int)( 256.0f * distmix );
// if mixing at max or min range, skip crossfade (KDB: perf)
if( !nearmix )
{
for( i = 0; i < outCount; i++ )
{
x = pData[sampleIndex+1]; // right sample
pOutput[i].left += (volume[0] * x)>>8;
pOutput[i].right += (volume[1] * x)>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
return;
}
if( !farmix )
{
for( i = 0; i < outCount; i++ )
{
x = pData[sampleIndex]; // left sample
pOutput[i].left += (volume[0] * x)>>8;
pOutput[i].right += (volume[1] * x)>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
return;
}
// crossfade left/right
for( i = 0; i < outCount; i++ )
{
l = pData[sampleIndex];
r = pData[sampleIndex+1];
x = ((l * nearmix) >> 8) + ((r * farmix) >> 8);
pOutput[i].left += (volume[0] * x)>>8;
pOutput[i].right += (volume[1] * x)>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
void SW_Mix8Mono( samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
// UNDONE: Native code this and use adc to integrate the int/frac parts separately
// UNDONE: Optimize when not pitch shifting?
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, *lscale, *rscale;
// not using pitch shift?
if( rateScaleFix == FIX( 1 ))
{
// paintbuffer native code
if( pOutput == paintbuffer )
{
SND_PaintChannelFrom8( volume, (byte *)pData, outCount );
return;
}
}
lscale = snd_scaletable[volume[0] >> SND_SCALE_SHIFT];
rscale = snd_scaletable[volume[1] >> SND_SCALE_SHIFT];
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += lscale[pData[sampleIndex]];
pOutput[i].right += rscale[pData[sampleIndex]];
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac);
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
void SW_Mix8Stereo( samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int sampleIndex = 0;
uint sampleFrac = inputOffset;
int i, *lscale, *rscale;
lscale = snd_scaletable[volume[0] >> SND_SCALE_SHIFT];
rscale = snd_scaletable[volume[1] >> SND_SCALE_SHIFT];
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += lscale[pData[sampleIndex]];
pOutput[i].right += rscale[pData[sampleIndex+1]];
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
void SW_Mix16Mono( samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int i, sampleIndex = 0;
uint sampleFrac = inputOffset;
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += (volume[0] * (int)(pData[sampleIndex]))>>8;
pOutput[i].right += (volume[1] * (int)(pData[sampleIndex]))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac);
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
void SW_Mix16Stereo( samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
int i, sampleIndex = 0;
uint sampleFrac = inputOffset;
for( i = 0; i < outCount; i++ )
{
pOutput[i].left += (volume[0] * (int)(pData[sampleIndex]))>>8;
pOutput[i].right += (volume[1] * (int)(pData[sampleIndex+1]))>>8;
sampleFrac += rateScaleFix;
sampleIndex += FIX_INTPART(sampleFrac)<<1;
sampleFrac = FIX_FRACPART(sampleFrac);
}
}
//===============================================================================
// DISPATCHERS FOR MIXING ROUTINES
//===============================================================================
void Mix8MonoWavtype( channel_t *pChannel, samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
SW_Mix8Mono( pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
}
void Mix16MonoWavtype( channel_t *pChannel, samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
SW_Mix16Mono( pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
}
void Mix8StereoWavtype( channel_t *pChannel, samplepair_t *pOutput, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
{
switch ( pChannel->wavtype )
{
case CHAR_DOPPLER:
SW_Mix8StereoDopplerLeft( pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
SW_Mix8StereoDopplerRight( pOutput, &volume[IFRONT_LEFTD], pData, inputOffset, rateScaleFix, outCount );
break;
case CHAR_DIRECTIONAL:
SW_Mix8StereoDirectional( pChannel->dspface, pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
break;
case CHAR_DISTVARIANT:
SW_Mix8StereoDistVar( pChannel->distmix, pOutput, volume, pData, inputOffset, rateScaleFix, outCount);
break;
default:
SW_Mix8Stereo( pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
break;
}
}
void Mix16StereoWavtype( channel_t *pChannel, samplepair_t *pOutput, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
{
switch ( pChannel->wavtype )
{
case CHAR_DOPPLER:
SW_Mix16StereoDopplerLeft( pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
SW_Mix16StereoDopplerRight( pOutput, &volume[IFRONT_LEFTD], pData, inputOffset, rateScaleFix, outCount );
break;
case CHAR_DIRECTIONAL:
SW_Mix16StereoDirectional( pChannel->dspface, pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
break;
case CHAR_DISTVARIANT:
SW_Mix16StereoDistVar( pChannel->distmix, pOutput, volume, pData, inputOffset, rateScaleFix, outCount);
break;
default:
SW_Mix16Stereo( pOutput, volume, pData, inputOffset, rateScaleFix, outCount );
break;
}
}
void Mix8Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount )
{
int volume[CCHANVOLUMES];
paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();
MIX_ScaleChannelVolume( ppaint, pChannel, volume, 1 );
Mix8MonoWavtype( pChannel, ppaint->pbuf + outputOffset, volume, (byte *)pData, inputOffset, rateScaleFix, outCount );
}
void Mix8Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount )
{
int volume[CCHANVOLUMES];
paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();
MIX_ScaleChannelVolume( ppaint, pChannel, volume, 2 );
Mix8StereoWavtype( pChannel, ppaint->pbuf + outputOffset, volume, (byte *)pData, inputOffset, rateScaleFix, outCount );
}
void Mix16Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount )
{
int volume[CCHANVOLUMES];
paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();
MIX_ScaleChannelVolume( ppaint, pChannel, volume, 1 );
Mix16MonoWavtype( pChannel, ppaint->pbuf + outputOffset, volume, (short *)pData, inputOffset, rateScaleFix, outCount );
}
void Mix16Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount )
{
int volume[CCHANVOLUMES];
paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr();
MIX_ScaleChannelVolume( ppaint, pChannel, volume, 2 );
Mix16StereoWavtype( pChannel, ppaint->pbuf + outputOffset, volume, (short *)pData, inputOffset, rateScaleFix, outCount );
}

View File

@ -6,9 +6,9 @@
#include "sound.h"
#include "byteorder.h"
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
int s_rawend;
static bg_track_t s_bgTrack;
samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
int s_rawend;
static bg_track_t s_bgTrack;
/*
=================

View File

@ -118,6 +118,10 @@ SOURCE=.\s_direct.c
# End Source File
# Begin Source File
SOURCE=.\s_dsp.c
# End Source File
# Begin Source File
SOURCE=.\s_export.c
# End Source File
# Begin Source File
@ -134,6 +138,10 @@ SOURCE=.\s_mix.c
# End Source File
# Begin Source File
SOURCE=.\s_mix_chan.c
# End Source File
# Begin Source File
SOURCE=.\s_stream.c
# End Source File
# End Group

View File

@ -6,13 +6,13 @@
--------------------Configuration: snd_dx - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSPABE.tmp" with contents
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1D17.tmp" with contents
[
/nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"..\temp\snd_dx\!debug/" /Fo"..\temp\snd_dx\!debug/" /Fd"..\temp\snd_dx\!debug/" /FD /GZ /c
"D:\Xash3D\src_main\snd_dx\s_main.c"
"D:\Xash3D\src_main\snd_dx\s_direct.c"
]
Creating command line "cl.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSPABE.tmp""
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSPABF.tmp" with contents
Creating command line "cl.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1D17.tmp""
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1D18.tmp" with contents
[
winmm.lib /nologo /dll /incremental:yes /pdb:"..\temp\snd_dx\!debug/snd_dx.pdb" /debug /machine:I386 /nodefaultlib:"libcmt.lib" /out:"..\temp\snd_dx\!debug/snd_dx.dll" /implib:"..\temp\snd_dx\!debug/snd_dx.lib" /pdbtype:sept
"\Xash3D\src_main\temp\snd_dx\!debug\s_direct.obj"
@ -21,17 +21,20 @@ winmm.lib /nologo /dll /incremental:yes /pdb:"..\temp\snd_dx\!debug/snd_dx.pdb"
"\Xash3D\src_main\temp\snd_dx\!debug\s_main.obj"
"\Xash3D\src_main\temp\snd_dx\!debug\s_mix.obj"
"\Xash3D\src_main\temp\snd_dx\!debug\s_stream.obj"
"\Xash3D\src_main\temp\snd_dx\!debug\s_dsp.obj"
"\Xash3D\src_main\temp\snd_dx\!debug\s_mix_chan.obj"
]
Creating command line "link.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSPABF.tmp""
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSPAC0.bat" with contents
Creating command line "link.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1D18.tmp""
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1D19.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\snd_dx\!debug\snd_dx.dll "D:\Xash3D\bin\snd_dx.dll"
]
Creating command line ""C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSPAC0.bat""
Creating command line ""C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1D19.bat""
Compiling...
s_main.c
s_direct.c
Linking...
Creating library ..\temp\snd_dx\!debug/snd_dx.lib and object ..\temp\snd_dx\!debug/snd_dx.exp
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\snd_dx\!debug\snd_dx.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.

View File

@ -15,13 +15,66 @@ extern stdlib_api_t com;
extern vsound_imp_t si;
extern byte *sndpool;
enum
{
IPAINTBUFFER = 0,
IROOMBUFFER,
IFACINGBUFFER,
IFACINGAWAYBUFFER,
IDRYBUFFER,
CPAINTBUFFERS // count of buffers
};
enum
{
IFRONT_LEFT = 0, // NOTE: must correspond to order of leftvol...drrightvol above!
IFRONT_RIGHT,
IFRONT_LEFTD, // start of doppler right array
IFRONT_RIGHTD,
CCHANVOLUMES
};
// fixed point stuff for real-time resampling
#define FIX_BITS 28
#define FIX_SCALE (1 << FIX_BITS)
#define FIX_MASK ((1 << FIX_BITS)-1)
#define FIX_FLOAT( a ) ((int)((a) * FIX_SCALE))
#define FIX( a ) (((int)(a)) << FIX_BITS)
#define FIX_INTPART( a ) (((int)(a)) >> FIX_BITS)
#define FIX_FRACTION( a, b ) (FIX(a)/(b))
#define FIX_FRACPART( a ) ((a) & FIX_MASK)
#define CPAINTFILTERMEM 3
#define CPAINTFILTERS 4 // maximum number of consecutive upsample passes per paintbuffer
#define PAINTBUFFER_SIZE 1024 // 44k: was 512
#define PAINTBUFFER (g_curpaintbuffer)
#define CHAR_SENTENCE '!' // as one of 1st 2 chars in name, indicates sentence wav
#define CHAR_DRYMIX '#' // as one of 1st 2 chars in name, indicates wav bypasses dsp fx
#define CHAR_DOPPLER '>' // as one of 1st 2 chars in name, indicates doppler encoded stereo wav
#define CHAR_DIRECTIONAL '<' // as one of 1st 2 chars in name, indicates mono or stereo wav has direction cone
#define CHAR_DISTVARIANT '^' // as one of 1st 2 chars in name, indicates distance variant encoded stereo wav
#include "mathlib.h"
typedef struct
{
int left;
int right;
} portable_samplepair_t;
} samplepair_t;
typedef struct
{
bool factive; // if true, mix to this paintbuffer using flags
int flags; // SOUND_BUSS_ROOM, SOUND_BUSS_FACING, SOUND_BUSS_FACINGAWAY
samplepair_t *pbuf; // front stereo mix buffer, for 2 channel mixing
int ifilter; // current filter memory buffer to use for upsampling pass
// filter memory, for upsampling with linear or cubic interpolation
samplepair_t fltmem[CPAINTFILTERS][CPAINTFILTERMEM];
} paintbuffer_t;
typedef void (*MixFn)( struct channel_s *chan, char *data, int outofs, int inofs, uint rate, int count );
typedef struct
{
@ -30,18 +83,45 @@ typedef struct
int speed; // not needed, because converted on load?
int width;
int stereo;
bool sentence; // set to true if it's a sentence
byte data[1]; // variable sized
} sfxcache_t;
typedef struct mixer_s
{
double m_sample;
sfxcache_t *m_pData;
double m_forcedEndSample;
bool m_finished;
int m_delaySamples;
MixFn MixFunc;
} mixer_t;
typedef struct sfx_s
{
string name;
sfxcache_t *cache;
mixer_t *mixer;
int registration_sequence;
bool default_sound;
} sfx_t;
typedef struct voxword_s
{
int volume; // increase percent, ie: 125 = 125% increase
int pitch; // pitch shift up percent
int start; // offset start of wave percent
int end; // offset end of wave percent
int cbtrim; // end of wave after being trimmed to 'end'
int fKeepCached; // 1 if this word was already in cache before sentence referenced it
int samplefrac; // if pitch shifting, this is position into wav * 256
int timecompress; // % of wave to skip during playback (causes no pitch shift)
sfx_t *sfx; // name and cache pointer
} voxword_t;
// a playsound_t will be generated by each call to S_StartSound,
// when the mixer reaches playsound->begin, the playsound will
// be assigned to a channel
@ -70,11 +150,23 @@ typedef struct
byte *buffer;
} dma_t;
typedef struct
typedef enum
{
src_sound = 0,
src_sentence
} srctype_t;
typedef struct channel_s
{
srctype_t type;
sfx_t *sfx; // sfx number
mixer_t *pMixer; // sound mixer data
int leftvol; // 0-255 volume
int rightvol; // 0-255 volume
int dleftvol; // 0-255 front left volume - doppler outgoing wav
int drightvol; // 0-255 front right volume - doppler outgoing wav
int end; // end time in global paintsamples
int pos; // sample position in sfx
int looping; // where to loop, -1 = no looping OBSOLETE?
@ -83,8 +175,28 @@ typedef struct
int loopframe; // for stopping looping sounds
int entchannel; //
vec3_t origin; // only use if fixed_origin is set
vec3_t direction; // direction of the sound
vec_t dist_mult; // distance multiplier (attenuation/clipK)
int master_vol; // 0-255 master volume
int basePitch; // base pitch percent (100% is normal pitch playback)
float pitch; // real-time pitch after any modulation or shift by dynamic data
float dspmix; // 0 - 1.0 proportion of dsp to mix with original sound,
// based on distance
float dspface; // -1.0 - 1.0 (1.0 = facing listener)
float distmix; // 0 - 1.0 proportion based on distance from listener
// (1.0 - 100% wav right - far)
bool bdry; // if true, bypass all dsp processing for this sound (ie: music)
bool bstereowav; // if true, a stereo .wav file is the sample data source
char wavtype; // 0 default, CHAR_DOPPLER, CHAR_DIRECTIONAL, CHAR_DISTVARIANT
float radius; // Radius of this sound effect
// (spatialization is different within the radius)
bool bfirstpass; // true if this is first time sound is spatialized
float ob_gain; // gain drop if sound source obscured from listener
float ob_gain_target; // target gain while crossfading between ob_gain & ob_gain_target
float ob_gain_inc; // crossfade increment
bool delayed_start; // If true, sound had a delay and so same sound on same channel
// won't channel steal from it
bool fixed_origin; // use origin instead of fetching entnum's origin
bool autosound; // from an entity->sound, cleared each frame
bool use_loop; // don't loop default and local sounds
@ -122,6 +234,27 @@ typedef struct
#define Host_Error com.error
#define Z_Malloc( size ) Mem_Alloc( sndpool, size )
// hl2 used backward assertation if( !x )
#define Assert( x ) if(!(x)) com.abort( "assert failed at %s:%i\n", __FILE__, __LINE__ )
#define ARRAYSIZE( p ) (sizeof( p ) / sizeof( p[0] ))
#define SOUND_DMA_SPEED (dma.speed)
#define SOUND_11k 11025 // 11khz sample rate
#define SOUND_22k 22050 // 22khz sample rate
#define SOUND_44k 44100 // 44khz sample rate
#define SOUND_ALL_RATES 1 // mix all sample rates
#define SND_SCALE_BITS 7
#define SND_SCALE_SHIFT (8 - SND_SCALE_BITS)
#define SND_SCALE_LEVELS (1<<SND_SCALE_BITS)
// global paintbuffer flags
#define SOUND_BUSS_ROOM BIT( 0 ) // mix samples using channel dspmix value (based on distance from player)
#define SOUND_BUSS_FACING BIT( 1 ) // mix samples using channel dspface value (source facing)
#define SOUND_BUSS_FACINGAWAY BIT( 2 ) // mix samples using 1-dspface
// hard clip input value to -32767 <= y <= 32767
#define CLIP( x ) bound( -32767, (x), 32767 )
// initializes cycling through a DMA buffer and returns information on it
bool SNDDMA_Init( void *hInst );
int SNDDMA_GetDMAPos( void );
@ -137,6 +270,7 @@ void SNDDMA_Submit( void );
extern channel_t channels[MAX_CHANNELS];
extern int paintedtime;
extern int s_rawend;
extern int listener_waterlevel;
extern vec3_t listener_origin;
extern vec3_t listener_forward;
extern vec3_t listener_right;
@ -144,6 +278,11 @@ extern vec3_t listener_up;
extern dma_t dma;
extern playsound_t s_pendingplays;
extern bool sound_started;
extern bool dsound_init;
extern bool wavout_init;
extern bool g_bDspOff;
extern bool g_bdirectionalfx;
extern int snd_scaletable[SND_SCALE_LEVELS][256];
extern cvar_t *s_check_errors;
extern cvar_t *s_volume;
@ -155,13 +294,58 @@ extern cvar_t *s_mixahead;
extern cvar_t *s_testsound;
extern cvar_t *s_primary;
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
extern samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
extern samplepair_t paintbuffer[];
float S_GetMasterVolume( void );
void S_InitScaletable( void );
sfxcache_t *S_LoadSound( sfx_t *sfx );
sfxcache_t *S_LoadSound( sfx_t *sfx, channel_t *ch );
void S_IssuePlaysound( playsound_t *ps );
void S_PaintChannels( int endtime );
// s_mix.c
void MIX_ClearAllPaintBuffers( int SampleCount, bool clearFilters );
extern _inline void MIX_SetCurrentPaintbuffer( int ipaintbuffer );
extern _inline int MIX_GetCurrentPaintbufferIndex( void );
extern _inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void );
void MIX_ScaleChannelVolume( paintbuffer_t *ppaint, channel_t *pChannel, int volume[CCHANVOLUMES], int mixchans );
void Mix8Mono(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
void Mix16Mono(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
void Mix8Stereo(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
void Mix16Stereo(channel_t *pChannel, char *pData, int outputOffset, int inputOffset, uint rateScaleFix, int outCount);
int MIX_GetCurrentPaintbufferIndex( void );
bool MIX_InitAllPaintbuffers( void );
void MIX_FreeAllPaintbuffers( void );
void SND_MoveMouth8( channel_t *ch, int count );
void SND_CloseMouth( channel_t *ch );
void SND_InitMouth( int entnum, int entchannel );
void SND_UpdateMouth( channel_t *pChannel );
void SND_ClearMouth( channel_t *pChannel );
bool SND_IsMouth( channel_t *pChannel );
// s_dsp.c
extern cvar_t *dsp_off;
extern cvar_t *dsp_room;
extern cvar_t *dsp_water;
extern cvar_t *dsp_player;
extern cvar_t *dsp_facingaway;
extern int idsp_room;
extern int idsp_water;
extern int idsp_player;
extern int idsp_facingaway;
bool AllocDsps( void );
void FreeDsps( void );
void CheckNewDspPresets( void );
float DSP_GetGain( int idsp );
void DSP_Process( int idsp, samplepair_t *pbfront, int sampleCount );
void DSP_ClearState();
// legacy DSP Routines
void SX_Init( void );
void SX_Free( void );
void SX_RoomFX( int endtime, int fFilter, int fTimefx );
bool S_Init( void *hInst );
void S_Shutdown( void );
void S_Activate( bool active );

View File

@ -697,7 +697,7 @@ void GL_SetState( int state );
void GL_FrontFace( int front );
void R_Set2DMode( bool enable );
void R_BeginFrame( void );
void R_BeginFrame( const ref_params_t *fd );
void R_EndFrame( void );
void R_RenderScene( const ref_params_t *fd );
void R_RenderView( const ref_params_t *fd );

View File

@ -1684,7 +1684,7 @@ void R_RenderView( const ref_params_t *fd )
R_BeginFrame
===============
*/
void R_BeginFrame( void )
void R_BeginFrame( const ref_params_t *fd )
{
if( gl_finish->integer && gl_delayfinish->integer )
{
@ -1736,7 +1736,7 @@ void R_BeginFrame( void )
r_environment_color->modified = false;
}
if( r_clear->integer )
if( r_clear->integer && !fd->paused )
{
rgba_t color;
@ -1744,6 +1744,7 @@ void R_BeginFrame( void )
pglClearColor( color[0]*( 1.0/255.0 ), color[1]*( 1.0/255.0 ), color[2]*( 1.0/255.0 ), 1 );
pglClear( GL_COLOR_BUFFER_BIT );
}
// update gamma
if( r_gamma->modified )
{

16
vid_gl/vid_gl.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: vid_gl - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
vid_gl.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

16
vprogs/vprogs.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: vprogs - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
vprogs.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

16
xtools/xtools.plg Normal file
View File

@ -0,0 +1,16 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: xtools - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
xtools.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>