11 Oct 2009
This commit is contained in:
parent
c873ab6c77
commit
528c9dc420
|
@ -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>
|
|
@ -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>
|
|
@ -71,7 +71,6 @@ void CHud :: VidInit( void )
|
|||
// Load Sprites
|
||||
// ---------
|
||||
|
||||
m_iDrawPlaque = 1;
|
||||
m_hsprCursor = 0;
|
||||
m_hHudError = 0;
|
||||
m_hHudFont = 0;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
File diff suppressed because it is too large
Load Diff
|
@ -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 )
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 ));
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
598
snd_dx/s_mix.c
598
snd_dx/s_mix.c
|
@ -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 = ©Buf[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);
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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;
|
||||
|
||||
/*
|
||||
=================
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
192
snd_dx/sound.h
192
snd_dx/sound.h
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
Reference in New Issue