12 Oct 2009

This commit is contained in:
g-cont 2009-10-12 00:00:00 +04:00 committed by Alibek Omarov
parent 528c9dc420
commit cb85ddd6d4
42 changed files with 669 additions and 9031 deletions

View File

@ -1,16 +0,0 @@
<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>

View File

@ -1,16 +0,0 @@
<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

@ -406,7 +406,8 @@ int CHud::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf )
int CHud :: MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf )
{
// FIXME: needs callback to sound engine
CVAR_SET_FLOAT( "room_type", READ_SHORT());
return 1;
}

View File

@ -57,9 +57,9 @@ void CL_WriteDemoHeader( const char *name )
MSG_WriteByte( &buf, svc_serverdata );
MSG_WriteLong( &buf, PROTOCOL_VERSION );
MSG_WriteLong( &buf, cl.servercount );
MSG_WriteLong( &buf, cl.serverframetime );
MSG_WriteShort( &buf, cl.playernum );
MSG_WriteString( &buf, cl.configstrings[CS_NAME] );
MSG_WriteString( &buf, clgame.maptitle );
// configstrings
for( i = 0; i < MAX_CONFIGSTRINGS; i++ )
@ -106,6 +106,9 @@ void CL_WriteDemoHeader( const char *name )
MSG_WriteByte( &buf, svc_stufftext );
MSG_WriteString( &buf, "cmd fullupdate\n" );
MSG_WriteByte( &buf, svc_setview );
MSG_WriteWord( &buf, cl.playernum + 1 ); // reset view to client
// write it to the demo file
len = LittleLong( buf.cursize );
FS_Write( cls.demofile, &len, 4 );
@ -194,7 +197,7 @@ void CL_ReadDemoMessage( void )
if( cl_paused->value ) return;
// don't need another message yet
if( cl.time <= cl.frame.servertime )
if( cl.time < cl.frame.servertime )
return;
// init the message
@ -338,7 +341,7 @@ void CL_PlayDemo_f( void )
cls.state = ca_connected;
cls.demoplayback = true;
com.strncpy( cls.servername, Cmd_Argv(1), sizeof(cls.servername));
com.strncpy( cls.servername, Cmd_Argv(1), sizeof( cls.servername ));
// begin a playback demo
}

View File

@ -735,7 +735,7 @@ void pfnPlaySoundByIndex( int iSound, float volume, int pitch, const float *org
MsgDev( D_ERROR, "CL_PlaySoundByIndex: invalid sound handle %i\n", iSound );
return;
}
S_StartSound( org, cl.playernum + 1, CHAN_AUTO, cl.sound_precache[iSound], volume, ATTN_NORM, pitch );
S_StartSound( org, cl.refdef.viewentity, CHAN_AUTO, cl.sound_precache[iSound], volume, ATTN_NORM, pitch, 0 );
}
/*

View File

@ -570,7 +570,7 @@ void CL_CreateNewCommands( void )
int cmdnum;
// no need to create usercmds until we have a gamestate
if( cls.state < ca_connected ) return;
if( cls.demoplayback || cls.state < ca_connected ) return;
// if running less than 5fps, truncate the extra time to prevent
// unexpected moves after a hitch

View File

@ -183,7 +183,8 @@ CL_ParseSoundPacket
*/
void CL_ParseSoundPacket( sizebuf_t *msg )
{
vec3_t pos;
vec3_t pos_;
float *pos = NULL;
int channel, sound_num;
float volume, attenuation;
int flags, pitch, entnum;
@ -209,9 +210,12 @@ void CL_ParseSoundPacket( sizebuf_t *msg )
entnum = MSG_ReadBits( msg, NET_WORD );
// positioned in space
MSG_ReadPos( msg, pos );
S_StartSound( pos, entnum, channel, cl.sound_precache[sound_num], volume, attenuation, pitch );
if( flags & SND_FIXED_ORIGIN )
{
pos = pos_;
MSG_ReadPos( msg, pos );
}
S_StartSound( pos, entnum, channel, cl.sound_precache[sound_num], volume, attenuation, pitch, flags );
}
/*
@ -229,7 +233,7 @@ CL_ParseServerData
*/
void CL_ParseServerData( sizebuf_t *msg )
{
string str, title;
string str;
const char *levelshot_ext[] = { "tga", "jpg", "png" };
int i;
@ -249,7 +253,7 @@ void CL_ParseServerData( sizebuf_t *msg )
cl.servercount = MSG_ReadLong( msg );
cl.playernum = MSG_ReadShort( msg );
com.strncpy( str, MSG_ReadString( msg ), MAX_STRING );
com.strncpy( title, MSG_ReadString( msg ), MAX_STRING );
com.strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
// get splash name
Cvar_Set( "cl_levelshot_name", va( "levelshots/%s", str ));
@ -265,7 +269,7 @@ void CL_ParseServerData( sizebuf_t *msg )
}
// seperate the printfs so the server message can have a color
Msg("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
Msg( "^2%s\n", title );
Msg( "^2%s\n", clgame.maptitle );
// need to prep refresh at next oportunity
cl.video_prepped = false;

View File

@ -339,8 +339,15 @@ void CL_PredictMovement (void)
pmove = EDICT_NUM( cl.playernum + 1 )->pvClientData->current;
if( cls.demoplayback )
{
// interpolate server values
for( i = 0; i < 3; i++ )
cl.refdef.cl_viewangles[i] = EDICT_NUM( cl.refdef.viewentity )->v.viewangles[i];
}
// unpredicted pure angled values converted into axis
AngleVectors( cl.refdef.cl_viewangles, cl.axis[0], cl.axis[1], cl.axis[2] );
AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );
if( !cl_predict->value || cl.frame.ps.ed_flags & ESF_NO_PREDICTION )
{

View File

@ -494,8 +494,11 @@ void SCR_Init( void )
SCR_RegisterShaders();
UI_Init();
if( cls.state == ca_disconnected )
if( cls.state == ca_uninitialized )
{
cls.key_dest = key_menu;
UI_SetActiveMenu( UI_MAINMENU );
}
scr_init = true;
}

View File

@ -118,7 +118,6 @@ typedef struct
float predicted_step; // for stair up smoothing
uint predicted_step_time;
vec3_t axis[3]; // cl_viewangles without applied any view effects
vec3_t predicted_origin; // generated by CL_PredictMovement
vec3_t predicted_angles;
vec3_t prediction_error;
@ -219,6 +218,7 @@ typedef struct
void *hInstance; // pointer to client.dll
HUD_FUNCTIONS dllFuncs; // dll exported funcs
byte *private; // client.dll private pool
string maptitle; // display map title
union
{
@ -475,8 +475,8 @@ _inline edict_t *CL_EDICT_NUM( int n, const char *file, const int line )
// if origin is NULL, the sound will be dynamically sourced from the entity
#define S_StartStreaming if( se ) se->StartStreaming
#define S_StartSound( a,b,c,d,e,f,g ) if( se ) se->StartSound( a, b, c, d, e, f, g, true );
#define S_StartLocalSound( a,b,c,d ) if( se ) se->StartLocalSound( a, b, c, d )
#define S_StartSound if( se ) se->StartSound
#define S_StartLocalSound if( se ) se->StartLocalSound
#define S_StartBackgroundTrack if( se ) se->StartBackgroundTrack
#define S_StopBackgroundTrack if( se ) se->StopBackgroundTrack
#define S_RawSamples if( se ) se->StreamRawSamples

View File

@ -63,33 +63,6 @@ typedef struct
static console_t con;
/*
================
Con_ToggleConsole_f
================
*/
void Con_ToggleConsole_f( void )
{
if( !host.developer ) return;
if(UI_CreditsActive()) return;
Field_Clear( &g_consoleField );
g_consoleField.widthInChars = g_console_field_width;
Con_ClearNotify();
if( cls.key_dest == key_console )
{
UI_SetActiveMenu( UI_CLOSEMENU );
cls.key_dest = key_game;
}
else
{
UI_SetActiveMenu( UI_CLOSEMENU );
cls.key_dest = key_console;
}
}
/*
================
Con_ToggleChat_f
@ -140,6 +113,39 @@ void Con_ClearNotify( void )
con.times[i] = 0;
}
void Con_ClearTyping( void )
{
Field_Clear( &g_consoleField );
g_consoleField.widthInChars = g_console_field_width;
}
/*
================
Con_ToggleConsole_f
================
*/
void Con_ToggleConsole_f( void )
{
if( !host.developer ) return; // disabled
// show console only in game or by special call from menu
if( cls.state != ca_active || cls.key_dest == key_menu )
return;
Con_ClearTyping();
Con_ClearNotify();
if( cls.key_dest == key_console )
{
UI_SetActiveMenu( UI_CLOSEMENU );
cls.key_dest = key_game;
}
else
{
UI_SetActiveMenu( UI_CLOSEMENU );
cls.key_dest = key_console;
}
}
/*
================

View File

@ -12,5 +12,6 @@
#define SND_VOLUME (1<<8) // a scaled byte
#define SND_SOUNDLEVEL (1<<9) // a byte
#define SND_PITCH (1<<10) // a byte
#define SND_FIXED_ORIGIN (1<<11) // a vector
#endif//NET_SOUND_H

View File

@ -3,88 +3,89 @@
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Debug--------------------
--------------------Configuration: engine - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199C.tmp" with contents
Creating temporary file "C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP21FE.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"
/nologo /MD /W3 /GX /O2 /I "./" /I "common" /I "server" /I "client" /I "uimenu" /I "../public" /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"..\temp\engine\!release/" /Fd"..\temp\engine\!release/" /FD /c
"D:\Xash3D\src_main\engine\uimenu\ui_credits.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
Creating command line "cl.exe @"C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP21FE.tmp""
Creating temporary file "C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP21FF.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"
user32.lib msvcrt.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /out:"..\temp\engine\!release/engine.dll" /implib:"..\temp\engine\!release/engine.lib" /opt:nowin98
"\Xash3D\src_main\temp\engine\!release\cinematic.obj"
"\Xash3D\src_main\temp\engine\!release\cl_cmds.obj"
"\Xash3D\src_main\temp\engine\!release\cl_demo.obj"
"\Xash3D\src_main\temp\engine\!release\cl_effects.obj"
"\Xash3D\src_main\temp\engine\!release\cl_frame.obj"
"\Xash3D\src_main\temp\engine\!release\cl_game.obj"
"\Xash3D\src_main\temp\engine\!release\cl_input.obj"
"\Xash3D\src_main\temp\engine\!release\cl_main.obj"
"\Xash3D\src_main\temp\engine\!release\cl_parse.obj"
"\Xash3D\src_main\temp\engine\!release\cl_phys.obj"
"\Xash3D\src_main\temp\engine\!release\cl_scrn.obj"
"\Xash3D\src_main\temp\engine\!release\cl_view.obj"
"\Xash3D\src_main\temp\engine\!release\com_library.obj"
"\Xash3D\src_main\temp\engine\!release\con_keys.obj"
"\Xash3D\src_main\temp\engine\!release\con_main.obj"
"\Xash3D\src_main\temp\engine\!release\con_utils.obj"
"\Xash3D\src_main\temp\engine\!release\engfuncs.obj"
"\Xash3D\src_main\temp\engine\!release\engine.obj"
"\Xash3D\src_main\temp\engine\!release\host.obj"
"\Xash3D\src_main\temp\engine\!release\infostring.obj"
"\Xash3D\src_main\temp\engine\!release\input.obj"
"\Xash3D\src_main\temp\engine\!release\net_chan.obj"
"\Xash3D\src_main\temp\engine\!release\net_huff.obj"
"\Xash3D\src_main\temp\engine\!release\net_msg.obj"
"\Xash3D\src_main\temp\engine\!release\sv_client.obj"
"\Xash3D\src_main\temp\engine\!release\sv_cmds.obj"
"\Xash3D\src_main\temp\engine\!release\sv_frame.obj"
"\Xash3D\src_main\temp\engine\!release\sv_game.obj"
"\Xash3D\src_main\temp\engine\!release\sv_init.obj"
"\Xash3D\src_main\temp\engine\!release\sv_main.obj"
"\Xash3D\src_main\temp\engine\!release\sv_move.obj"
"\Xash3D\src_main\temp\engine\!release\sv_phys.obj"
"\Xash3D\src_main\temp\engine\!release\sv_save.obj"
"\Xash3D\src_main\temp\engine\!release\sv_world.obj"
"\Xash3D\src_main\temp\engine\!release\ui_advanced.obj"
"\Xash3D\src_main\temp\engine\!release\ui_audio.obj"
"\Xash3D\src_main\temp\engine\!release\ui_controls.obj"
"\Xash3D\src_main\temp\engine\!release\ui_credits.obj"
"\Xash3D\src_main\temp\engine\!release\ui_defaults.obj"
"\Xash3D\src_main\temp\engine\!release\ui_demos.obj"
"\Xash3D\src_main\temp\engine\!release\ui_gameoptions.obj"
"\Xash3D\src_main\temp\engine\!release\ui_gotosite.obj"
"\Xash3D\src_main\temp\engine\!release\ui_ingame.obj"
"\Xash3D\src_main\temp\engine\!release\ui_loadgame.obj"
"\Xash3D\src_main\temp\engine\!release\ui_main.obj"
"\Xash3D\src_main\temp\engine\!release\ui_menu.obj"
"\Xash3D\src_main\temp\engine\!release\ui_mods.obj"
"\Xash3D\src_main\temp\engine\!release\ui_multiplayer.obj"
"\Xash3D\src_main\temp\engine\!release\ui_network.obj"
"\Xash3D\src_main\temp\engine\!release\ui_options.obj"
"\Xash3D\src_main\temp\engine\!release\ui_performance.obj"
"\Xash3D\src_main\temp\engine\!release\ui_playersetup.obj"
"\Xash3D\src_main\temp\engine\!release\ui_qmenu.obj"
"\Xash3D\src_main\temp\engine\!release\ui_quit.obj"
"\Xash3D\src_main\temp\engine\!release\ui_savegame.obj"
"\Xash3D\src_main\temp\engine\!release\ui_singleplayer.obj"
"\Xash3D\src_main\temp\engine\!release\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
Creating command line "link.exe @"C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP21FF.tmp""
Creating temporary file "C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP2200.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
copy \Xash3D\src_main\temp\engine\!release\engine.dll "D:\Xash3D\bin\engine.dll"
]
Creating command line ""C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP199E.bat""
Creating command line ""C:\DOCUME~1\ĚČŘŔ\LOCALS~1\Temp\RSP2200.bat""
Compiling...
cl_game.c
ui_credits.c
Linking...
Creating library ..\temp\engine\!release/engine.lib and object ..\temp\engine\!release/engine.exp
<h3>Output Window</h3>
Performing Custom Build Step on \Xash3D\src_main\temp\engine\!debug\engine.dll
Performing Custom Build Step on \Xash3D\src_main\temp\engine\!release\engine.dll
‘ª®¯¨à®¢ ­® ä ©«®¢: 1.

View File

@ -234,9 +234,6 @@ typedef struct
byte *private; // server.dll private pool
byte *temppool; // for parse, save and restore edicts
edict_t *saved_edicts; // holds the client edicts during changelevel
int num_saved_edicts;
// library exports table
word *ordinals;
dword *funcs;
@ -397,8 +394,6 @@ void SV_InitEdict( edict_t *pEdict );
bool SV_CopyEdict( edict_t *out, edict_t *in );
void SV_ConfigString( int index, const char *val );
void SV_SetModel( edict_t *ent, const char *name );
void SV_PopClients( void );
void SV_PushClients( void );
void SV_CreatePhysBody( edict_t *ent );
void SV_SetPhysForce( edict_t *ent );
void SV_SetMassCentre( edict_t *ent);

View File

@ -645,43 +645,6 @@ bool SV_MapIsValid( const char *filename, const char *spawn_entity )
return result;
}
void SV_PushClients( void )
{
edict_t *in, *out;
int i;
svgame.num_saved_edicts = 0;
// hold the clients in other place
for( i = 0; i < sv_maxclients->integer; i++ )
{
in = EDICT_NUM( i + 1 );
out = svgame.saved_edicts + i;
if( SV_CopyEdict( out, in ))
svgame.num_saved_edicts++;
}
}
void SV_PopClients( void )
{
edict_t *in, *out;
int i;
// copy clients back to sv.edicts
for( i = 0; i < svgame.num_saved_edicts; i++ )
{
in = svgame.saved_edicts + i;
out = EDICT_NUM( i + 1 );
if( SV_CopyEdict( out, in ))
svgame.globals->numClients++;
if( svgame.globals->numClients > sv_maxclients->integer )
break;
}
svgame.num_saved_edicts = 0;
}
void SV_InitEdict( edict_t *pEdict )
{
Com_Assert( pEdict == NULL );
@ -1583,7 +1546,6 @@ SV_StartSound
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch )
{
int sound_idx;
vec3_t snd_origin;
bool reliable = false;
bool use_phs = false;
@ -1610,18 +1572,14 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
// use the entity origin unless it is a bmodel or explicitly specified
if( ent->v.solid == SOLID_BSP || VectorCompare( ent->v.origin, vec3_origin ))
{
VectorAverage( ent->v.mins, ent->v.maxs, snd_origin );
VectorAdd( snd_origin, ent->v.origin, snd_origin );
reliable = true; // because brush center can be out of PHS (outside from world)
use_phs = false;
}
else
{
VectorCopy( ent->v.origin, snd_origin );
reliable = false;
use_phs = true;
}
// NOTE: bsp origin for moving edicts will be done on client-side
// always sending stop sound command
if( flags & SND_STOP ) reliable = true;
@ -1640,6 +1598,50 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
if ( flags & SND_PITCH ) MSG_WriteByte( &sv.multicast, pitch );
MSG_WriteWord( &sv.multicast, ent->serialnumber );
if( reliable )
{
if( use_phs ) MSG_Send( MSG_PHS_R, ent->v.origin, ent );
else MSG_Send( MSG_ALL_R, ent->v.origin, ent );
}
else
{
if( use_phs ) MSG_Send( MSG_PHS, ent->v.origin, ent );
else MSG_Send( MSG_ALL, ent->v.origin, ent );
}
}
/*
=================
pfnEmitAmbientSound
=================
*/
void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *samp, float vol, float attn, int flags, int pitch )
{
#if 0
vec3_t snd_origin;
bool reliable = false;
bool use_phs = false;
// use the entity origin unless it is a bmodel or explicitly specified
if( ent->v.solid == SOLID_BSP || VectorCompare( ent->v.origin, vec3_origin ))
{
VectorAverage( ent->v.mins, ent->v.maxs, snd_origin );
VectorAdd( snd_origin, ent->v.origin, snd_origin );
reliable = true; // because brush center can be out of PHS (outside from world)
use_phs = false;
}
else
{
VectorCopy( ent->v.origin, snd_origin );
reliable = false;
use_phs = true;
}
// FIXME: implement
MSG_WriteWord( &sv.multicast, ent->serialnumber );
MSG_WriteCoord32( &sv.multicast, snd_origin[0] );
MSG_WriteCoord32( &sv.multicast, snd_origin[1] );
MSG_WriteCoord32( &sv.multicast, snd_origin[2] );
@ -1654,17 +1656,7 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
if( use_phs ) MSG_Send( MSG_PHS, snd_origin, ent );
else MSG_Send( MSG_ALL, snd_origin, ent );
}
}
/*
=================
pfnEmitAmbientSound
=================
*/
void pfnEmitAmbientSound( edict_t *ent, float *pos, const char *samp, float vol, float attn, int flags, int pitch )
{
// FIXME: implement
#endif
}
/*
@ -3383,7 +3375,6 @@ void SV_LoadProgs( const char *name )
svgame.globals->maxEntities = GI->max_edicts;
svgame.globals->maxClients = sv_maxclients->integer;
svgame.edicts = Mem_Alloc( svgame.mempool, sizeof( edict_t ) * svgame.globals->maxEntities );
svgame.saved_edicts = Mem_Alloc( svgame.mempool, sizeof( edict_t ) * svgame.globals->maxClients );
svgame.globals->numEntities = svgame.globals->maxClients + 1; // clients + world
svgame.globals->numClients = 0;
for( i = 0, e = svgame.edicts; i < svgame.globals->maxEntities; i++, e++ )

View File

@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "ui_local.h"
#define ART_BACKGROUND "gfx/shell/misc/ui_sub_quit"
#define ART_BACKGROUND "gfx/shell/splash2"
#define UI_CREDITS_PATH "scripts/credits.txt"
#define UI_CREDITS_MAXLINES 2048
@ -143,7 +143,7 @@ static void UI_Credits_DrawFunc( void )
if( y < 0 && !color[3] )
{
uiCredits.active = false; // end of credits
Cbuf_ExecuteText( EXEC_APPEND, "quit\n" );
UI_PopMenu();
}
}
@ -154,7 +154,7 @@ UI_Credits_KeyFunc
*/
static const char *UI_Credits_KeyFunc( int key )
{
Cbuf_ExecuteText( EXEC_APPEND, "quit\n" );
UI_PopMenu();
return uiSoundNull;
}

View File

@ -65,6 +65,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define UI_SMALL_CHAR_WIDTH 10
#define UI_SMALL_CHAR_HEIGHT 20
#define UI_MED_CHAR_WIDTH 18
#define UI_MED_CHAR_HEIGHT 26
#define UI_BIG_CHAR_WIDTH 20
#define UI_BIG_CHAR_HEIGHT 40

View File

@ -24,19 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "client.h"
#define ART_BACKGROUND "gfx/shell/splash"
#define ART_LOGO "gfx/shell/title_screen/q2e_logo"
#define ART_SINGLEPLAYER "gfx/shell/title_screen/singleplayer_n"
#define ART_SINGLEPLAYER2 "gfx/shell/title_screen/singleplayer_s"
#define ART_MULTIPLAYER "gfx/shell/title_screen/multiplayer_n"
#define ART_MULTIPLAYER2 "gfx/shell/title_screen/multiplayer_s"
#define ART_OPTIONS "gfx/shell/title_screen/options_n"
#define ART_OPTIONS2 "gfx/shell/title_screen/options_s"
#define ART_DEMOS "gfx/shell/title_screen/demos_n"
#define ART_DEMOS2 "gfx/shell/title_screen/demos_s"
#define ART_MODS "gfx/shell/title_screen/mods_n"
#define ART_MODS2 "gfx/shell/title_screen/mods_s"
#define ART_QUIT "gfx/shell/title_screen/quit_n"
#define ART_QUIT2 "gfx/shell/title_screen/quit_s"
#define ART_IDLOGO "gfx/shell/title_screen/logo_id"
#define ART_IDLOGO2 "gfx/shell/title_screen/logo_id_s"
#define ART_BLURLOGO "gfx/shell/title_screen/logo_blur"
@ -44,34 +31,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ART_COPYRIGHT "gfx/shell/title_screen/copyrights"
#define ID_BACKGROUND 0
#define ID_LOGO 1
#define ID_SINGLEPLAYER 2
#define ID_MULTIPLAYER 3
#define ID_OPTIONS 4
#define ID_DEMOS 5
#define ID_MODS 6
#define ID_QUIT 7
#define ID_CONSOLE 1
#define ID_NEWGAME 2
#define ID_CONFIGURATION 3
#define ID_SAVERESTORE 4
#define ID_MULTIPLAYER 5
#define ID_CUSTOMGAME 6
#define ID_CREDITS 7
#define ID_QUIT 8
#define ID_IDSOFTWARE 8
#define ID_TEAMBLUR 9
#define ID_COPYRIGHT 10
#define ID_ALLYOURBASE 11
#define ID_IDSOFTWARE 9
#define ID_TEAMBLUR 10
#define ID_COPYRIGHT 11
#define ID_ALLYOURBASE 12
typedef struct
{
menuFramework_s menu;
menuBitmap_s background;
menuBitmap_s logo;
menuBitmap_s singlePlayer;
menuBitmap_s multiPlayer;
menuBitmap_s options;
menuBitmap_s cinematics;
menuBitmap_s demos;
menuBitmap_s mods;
menuBitmap_s quit;
menuAction_s console;
menuAction_s newGame;
menuAction_s configuration;
menuAction_s saveRestore;
menuAction_s multiPlayer;
menuAction_s customGame;
menuAction_s credits;
menuAction_s quit;
menuBitmap_s idSoftware;
menuBitmap_s teamBlur;
@ -120,21 +108,28 @@ static void UI_Main_Callback( void *self, int event )
switch( item->id )
{
case ID_SINGLEPLAYER:
case ID_CONSOLE:
UI_SetActiveMenu( UI_CLOSEMENU );
cls.key_dest = key_console;
break;
case ID_NEWGAME:
UI_SinglePlayer_Menu();
break;
case ID_MULTIPLAYER:
UI_MultiPlayer_Menu();
break;
case ID_OPTIONS:
case ID_CONFIGURATION:
UI_Options_Menu();
break;
case ID_DEMOS:
UI_Demos_Menu();
case ID_SAVERESTORE:
UI_LoadGame_Menu(); // FIXME
break;
case ID_MODS:
case ID_CUSTOMGAME:
UI_Mods_Menu();
break;
case ID_CREDITS:
UI_Credits_Menu ();
break;
case ID_QUIT:
UI_Quit_Menu();
break;
@ -170,80 +165,71 @@ static void UI_Main_Init( void )
uiMain.background.generic.height = 768;
uiMain.background.pic = ART_BACKGROUND;
uiMain.logo.generic.id = ID_LOGO;
uiMain.logo.generic.type = QMTYPE_BITMAP;
uiMain.logo.generic.flags = QMF_INACTIVE;
uiMain.logo.generic.x = 0;
uiMain.logo.generic.y = 0;
uiMain.logo.generic.width = 1024;
uiMain.logo.generic.height = 256;
uiMain.logo.pic = ART_LOGO;
uiMain.console.generic.id = ID_CONSOLE;
uiMain.console.generic.type = QMTYPE_ACTION;
uiMain.console.generic.name = "Console";
uiMain.console.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiMain.console.generic.x = 64;
uiMain.console.generic.y = 230;
uiMain.console.generic.callback = UI_Main_Callback;
uiMain.singlePlayer.generic.id = ID_SINGLEPLAYER;
uiMain.singlePlayer.generic.type = QMTYPE_BITMAP;
uiMain.singlePlayer.generic.flags = QMF_PULSEIFFOCUS | QMF_FOCUSBEHIND;
uiMain.singlePlayer.generic.x = 285;
uiMain.singlePlayer.generic.y = 300;
uiMain.singlePlayer.generic.width = 454;
uiMain.singlePlayer.generic.height = 42;
uiMain.singlePlayer.generic.callback = UI_Main_Callback;
uiMain.singlePlayer.pic = ART_SINGLEPLAYER;
uiMain.singlePlayer.focusPic = ART_SINGLEPLAYER2;
uiMain.newGame.generic.id = ID_NEWGAME;
uiMain.newGame.generic.type = QMTYPE_ACTION;
uiMain.newGame.generic.name = "New game";
uiMain.newGame.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiMain.newGame.generic.x = 64;
uiMain.newGame.generic.y = 280;
uiMain.newGame.generic.callback = UI_Main_Callback;
uiMain.configuration.generic.id = ID_CONFIGURATION;
uiMain.configuration.generic.type = QMTYPE_ACTION;
uiMain.configuration.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiMain.configuration.generic.name = "Configuration";
uiMain.configuration.generic.x = 64;
uiMain.configuration.generic.y = 330;
uiMain.configuration.generic.callback = UI_Main_Callback;
uiMain.saveRestore.generic.id = ID_SAVERESTORE;
uiMain.saveRestore.generic.type = QMTYPE_ACTION;
uiMain.saveRestore.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
if( cls.state == ca_active )
uiMain.saveRestore.generic.name = "Save\\Load Game";
else uiMain.saveRestore.generic.name = "Load Game";
uiMain.saveRestore.generic.x = 64;
uiMain.saveRestore.generic.y = 380;
uiMain.saveRestore.generic.callback = UI_Main_Callback;
uiMain.multiPlayer.generic.id = ID_MULTIPLAYER;
uiMain.multiPlayer.generic.type = QMTYPE_BITMAP;
uiMain.multiPlayer.generic.flags = QMF_PULSEIFFOCUS | QMF_FOCUSBEHIND;
uiMain.multiPlayer.generic.x = 306;
uiMain.multiPlayer.generic.y = 342;
uiMain.multiPlayer.generic.width = 412;
uiMain.multiPlayer.generic.height = 42;
uiMain.multiPlayer.generic.type = QMTYPE_ACTION;
uiMain.multiPlayer.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiMain.multiPlayer.generic.name = "Multiplayer";
uiMain.multiPlayer.generic.x = 64;
uiMain.multiPlayer.generic.y = 430;
uiMain.multiPlayer.generic.callback = UI_Main_Callback;
uiMain.multiPlayer.pic = ART_MULTIPLAYER;
uiMain.multiPlayer.focusPic = ART_MULTIPLAYER2;
uiMain.options.generic.id = ID_OPTIONS;
uiMain.options.generic.type = QMTYPE_BITMAP;
uiMain.options.generic.flags = QMF_PULSEIFFOCUS | QMF_FOCUSBEHIND;
uiMain.options.generic.x = 367;
uiMain.options.generic.y = 384;
uiMain.options.generic.width = 290;
uiMain.options.generic.height = 42;
uiMain.options.generic.callback = UI_Main_Callback;
uiMain.options.pic = ART_OPTIONS;
uiMain.options.focusPic = ART_OPTIONS2;
uiMain.customGame.generic.id = ID_CUSTOMGAME;
uiMain.customGame.generic.type = QMTYPE_ACTION;
uiMain.customGame.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiMain.customGame.generic.name = "Custom Game";
uiMain.customGame.generic.x = 64;
uiMain.customGame.generic.y = 480;
uiMain.customGame.generic.callback = UI_Main_Callback;
uiMain.demos.generic.id = ID_DEMOS;
uiMain.demos.generic.type = QMTYPE_BITMAP;
uiMain.demos.generic.flags = QMF_PULSEIFFOCUS | QMF_FOCUSBEHIND;
uiMain.demos.generic.x = 386;
uiMain.demos.generic.y = 468;
uiMain.demos.generic.width = 252;
uiMain.demos.generic.height = 42;
uiMain.demos.generic.callback = UI_Main_Callback;
uiMain.demos.pic = ART_DEMOS;
uiMain.demos.focusPic = ART_DEMOS2;
uiMain.mods.generic.id = ID_MODS;
uiMain.mods.generic.type = QMTYPE_BITMAP;
uiMain.mods.generic.flags = QMF_PULSEIFFOCUS | QMF_FOCUSBEHIND;
uiMain.mods.generic.x = 291;
uiMain.mods.generic.y = 510;
uiMain.mods.generic.width = 442;
uiMain.mods.generic.height = 42;
uiMain.mods.generic.callback = UI_Main_Callback;
uiMain.mods.pic = ART_MODS;
uiMain.mods.focusPic = ART_MODS2;
uiMain.credits.generic.id = ID_CREDITS;
uiMain.credits.generic.type = QMTYPE_ACTION;
uiMain.credits.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiMain.credits.generic.name = "Credits";
uiMain.credits.generic.x = 64;
uiMain.credits.generic.y = 530;
uiMain.credits.generic.callback = UI_Main_Callback;
uiMain.quit.generic.id = ID_QUIT;
uiMain.quit.generic.type = QMTYPE_BITMAP;
uiMain.quit.generic.flags = QMF_PULSEIFFOCUS | QMF_FOCUSBEHIND;
uiMain.quit.generic.x = 415;
uiMain.quit.generic.y = 594;
uiMain.quit.generic.width = 194;
uiMain.quit.generic.height = 42;
uiMain.quit.generic.type = QMTYPE_ACTION;
uiMain.quit.generic.flags = QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW;
uiMain.quit.generic.name = "Quit";
uiMain.quit.generic.x = 64;
uiMain.quit.generic.y = 580;
uiMain.quit.generic.callback = UI_Main_Callback;
uiMain.quit.pic = ART_QUIT;
uiMain.quit.focusPic = ART_QUIT2;
uiMain.idSoftware.generic.id = ID_IDSOFTWARE;
uiMain.idSoftware.generic.type = QMTYPE_BITMAP;
@ -286,12 +272,13 @@ static void UI_Main_Init( void )
uiMain.allYourBase.generic.callback = UI_Main_Callback;
UI_AddItem( &uiMain.menu, (void *)&uiMain.background );
UI_AddItem( &uiMain.menu, (void *)&uiMain.logo );
UI_AddItem( &uiMain.menu, (void *)&uiMain.singlePlayer );
if( host.developer ) UI_AddItem( &uiMain.menu, (void *)&uiMain.console );
UI_AddItem( &uiMain.menu, (void *)&uiMain.newGame );
UI_AddItem( &uiMain.menu, (void *)&uiMain.configuration );
UI_AddItem( &uiMain.menu, (void *)&uiMain.saveRestore );
UI_AddItem( &uiMain.menu, (void *)&uiMain.multiPlayer );
UI_AddItem( &uiMain.menu, (void *)&uiMain.options );
UI_AddItem( &uiMain.menu, (void *)&uiMain.demos );
UI_AddItem( &uiMain.menu, (void *)&uiMain.mods );
UI_AddItem( &uiMain.menu, (void *)&uiMain.customGame );
UI_AddItem( &uiMain.menu, (void *)&uiMain.credits );
UI_AddItem( &uiMain.menu, (void *)&uiMain.quit );
UI_AddItem( &uiMain.menu, (void *)&uiMain.idSoftware );
UI_AddItem( &uiMain.menu, (void *)&uiMain.teamBlur );
@ -309,19 +296,6 @@ void UI_Main_Precache( void )
if( !re ) return;
re->RegisterShader( ART_BACKGROUND, SHADER_NOMIP );
re->RegisterShader( ART_LOGO, SHADER_NOMIP );
re->RegisterShader( ART_SINGLEPLAYER, SHADER_NOMIP );
re->RegisterShader( ART_SINGLEPLAYER2, SHADER_NOMIP );
re->RegisterShader( ART_MULTIPLAYER, SHADER_NOMIP );
re->RegisterShader( ART_MULTIPLAYER2, SHADER_NOMIP );
re->RegisterShader( ART_OPTIONS, SHADER_NOMIP );
re->RegisterShader( ART_OPTIONS2, SHADER_NOMIP );
re->RegisterShader( ART_DEMOS, SHADER_NOMIP );
re->RegisterShader( ART_DEMOS2, SHADER_NOMIP );
re->RegisterShader( ART_MODS, SHADER_NOMIP );
re->RegisterShader( ART_MODS2, SHADER_NOMIP );
re->RegisterShader( ART_QUIT, SHADER_NOMIP );
re->RegisterShader( ART_QUIT2, SHADER_NOMIP );
re->RegisterShader( ART_IDLOGO, SHADER_NOMIP );
re->RegisterShader( ART_IDLOGO2, SHADER_NOMIP );
re->RegisterShader( ART_BLURLOGO, SHADER_NOMIP );

View File

@ -993,19 +993,35 @@ void UI_Action_Init( menuAction_s *a )
}
else
{
if( a->generic.charWidth < 1 ) a->generic.charWidth = UI_SMALL_CHAR_WIDTH;
if( a->generic.charHeight < 1 ) a->generic.charHeight = UI_SMALL_CHAR_HEIGHT;
if( a->generic.charWidth < 1 ) a->generic.charWidth = UI_MED_CHAR_WIDTH;
if( a->generic.charHeight < 1 ) a->generic.charHeight = UI_MED_CHAR_HEIGHT;
}
if(!( a->generic.flags & ( QMF_LEFT_JUSTIFY|QMF_CENTER_JUSTIFY|QMF_RIGHT_JUSTIFY )))
a->generic.flags |= QMF_LEFT_JUSTIFY;
if( !a->generic.color ) a->generic.color = uiColorLtGrey;
if( !a->generic.focusColor ) a->generic.focusColor = uiColorWhite;
// if( !a->background ) a->background = UI_BACKGROUNDBOX;
if( a->generic.width < 1 || a->generic.height < 1 )
{
if( a->background )
{
shader_t handle = re->RegisterShader( a->background, SHADER_NOMIP );
re->GetParms( &a->generic.width, &a->generic.height, NULL, 0, handle );
}
else
{
if( a->generic.width < 1 )
a->generic.width = a->generic.charWidth * com.strlen( a->generic.name );
if( a->generic.height < 1 )
a->generic.height = a->generic.charHeight * 1.5;
}
}
UI_ScaleCoords( NULL, NULL, &a->generic.charWidth, &a->generic.charHeight );
if(!( a->generic.flags & (QMF_LEFT_JUSTIFY|QMF_CENTER_JUSTIFY|QMF_RIGHT_JUSTIFY)))
a->generic.flags |= QMF_LEFT_JUSTIFY;
if( !a->generic.color ) a->generic.color = uiColorWhite;
if( !a->generic.focusColor ) a->generic.focusColor = uiColorLtGrey;
if( !a->background ) a->background = UI_BACKGROUNDBOX;
UI_ScaleCoords( &a->generic.x, &a->generic.y, &a->generic.width, &a->generic.height );
}
@ -1060,7 +1076,8 @@ void UI_Action_Draw( menuAction_s *a )
shadow = (a->generic.flags & QMF_DROPSHADOW);
UI_DrawPic( a->generic.x, a->generic.y, a->generic.width, a->generic.height, uiColorWhite, a->background );
if( a->background )
UI_DrawPic( a->generic.x, a->generic.y, a->generic.width, a->generic.height, uiColorWhite, a->background );
if( a->generic.flags & QMF_GRAYED )
{

View File

@ -59,7 +59,7 @@ static void UI_Quit_Callback( void *self, int event )
switch( item->id )
{
case ID_YES:
UI_Credits_Menu();
Cbuf_ExecuteText( EXEC_APPEND, "quit\n" );
break;
case ID_NO:
UI_PopMenu();

View File

@ -1,16 +0,0 @@
<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>

View File

@ -1,16 +0,0 @@
<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

@ -33,7 +33,7 @@ typedef struct vsound_exp_s
sound_t (*RegisterSound)( const char *name );
void (*EndRegistration)( void );
void (*StartSound)( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, bool loop );
void (*StartSound)( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, int flags );
void (*StreamRawSamples)( int samples, int rate, int width, int channels, const byte *data );
bool (*AddLoopingSound)( int entnum, sound_t handle, float volume, float attn );
bool (*StartLocalSound)( const char *name, float volume, float pitch, const float *origin );

View File

@ -1,16 +0,0 @@
<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>

View File

@ -9,6 +9,15 @@
#define MAX_PLAYSOUNDS 256
#define MAX_CHANNELS 64
#define CSXROOM 29
typedef struct
{
int dwEnvironment;
float fVolume;
float fDecay;
float fDamping;
} dsproom_t;
static playSound_t s_playSounds[MAX_PLAYSOUNDS];
static playSound_t s_freePlaySounds;
@ -19,6 +28,39 @@ static listener_t s_listener;
const guid_t DSPROPSETID_EAX20_ListenerProperties = {0x306a6a8, 0xb224, 0x11d2, {0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}};
const guid_t DSPROPSETID_EAX20_BufferProperties = {0x306a6a7, 0xb224, 0x11d2, {0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}};
const dsproom_t eax_preset[CSXROOM] =
{
{ EAX_ENVIRONMENT_GENERIC, 0.0F, 0.0F, 0.0F },
{ EAX_ENVIRONMENT_ROOM, 0.417F, 0.4F, 0.666F },
{ EAX_ENVIRONMENT_BATHROOM, 0.3F, 1.499F, 0.166F },
{ EAX_ENVIRONMENT_BATHROOM, 0.4F, 1.499F, 0.166F },
{ EAX_ENVIRONMENT_BATHROOM, 0.6F, 1.499F, 0.166F },
{ EAX_ENVIRONMENT_SEWERPIPE, 0.4F, 2.886F, 0.25F },
{ EAX_ENVIRONMENT_SEWERPIPE, 0.6F, 2.886F, 0.25F },
{ EAX_ENVIRONMENT_SEWERPIPE, 0.8F, 2.886F, 0.25F },
{ EAX_ENVIRONMENT_STONEROOM, 0.5F, 2.309F, 0.888F },
{ EAX_ENVIRONMENT_STONEROOM, 0.65F, 2.309F, 0.888F },
{ EAX_ENVIRONMENT_STONEROOM, 0.8F, 2.309F, 0.888F },
{ EAX_ENVIRONMENT_STONECORRIDOR, 0.3F, 2.697F, 0.638F },
{ EAX_ENVIRONMENT_STONECORRIDOR, 0.5F, 2.697F, 0.638F },
{ EAX_ENVIRONMENT_STONECORRIDOR, 0.65F, 2.697F, 0.638F },
{ EAX_ENVIRONMENT_UNDERWATER, 1.0F, 1.499F, 0.0F },
{ EAX_ENVIRONMENT_UNDERWATER, 1.0F, 2.499F, 0.0F },
{ EAX_ENVIRONMENT_UNDERWATER, 1.0F, 3.499F, 0.0F },
{ EAX_ENVIRONMENT_GENERIC, 0.65F, 1.493F, 0.5F },
{ EAX_ENVIRONMENT_GENERIC, 0.85F, 1.493F, 0.5F },
{ EAX_ENVIRONMENT_GENERIC, 1.0F, 1.493F, 0.5F },
{ EAX_ENVIRONMENT_ARENA, 0.40F, 7.284F, 0.332F },
{ EAX_ENVIRONMENT_ARENA, 0.55F, 7.284F, 0.332F },
{ EAX_ENVIRONMENT_ARENA, 0.70F, 7.284F, 0.332F },
{ EAX_ENVIRONMENT_CONCERTHALL, 0.5F, 3.961F, 0.5F },
{ EAX_ENVIRONMENT_CONCERTHALL, 0.7F, 3.961F, 0.5F },
{ EAX_ENVIRONMENT_CONCERTHALL, 1.0F, 3.961F, 0.5F },
{ EAX_ENVIRONMENT_DIZZY, 0.2F, 17.234F, 0.666F },
{ EAX_ENVIRONMENT_DIZZY, 0.3F, 17.234F, 0.666F },
{ EAX_ENVIRONMENT_DIZZY, 0.4F, 17.234F, 0.666F },
};
cvar_t *host_sound;
cvar_t *s_alDevice;
cvar_t *s_soundfx;
@ -26,6 +68,7 @@ cvar_t *s_check_errors;
cvar_t *s_volume; // master volume
cvar_t *s_musicvolume; // background track volume
cvar_t *s_pause;
cvar_t *s_room_type;
cvar_t *s_minDistance;
cvar_t *s_maxDistance;
cvar_t *s_rolloffFactor;
@ -438,7 +481,7 @@ if origin is NULL, the sound will be dynamically sourced from the entity.
entchannel 0 will never override a playing sound.
=================
*/
void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, float vol, float attn, float pitch, bool use_loop )
void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, float vol, float attn, float pitch, int flags )
{
playSound_t *ps, *sort;
sfx_t *sfx = NULL;
@ -464,7 +507,7 @@ void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, fl
ps->sfx = sfx;
ps->entnum = entnum;
ps->entchannel = channel;
ps->use_loop = use_loop;
ps->use_loop = (flags & SND_STOP_LOOPING) ? false : true;
if( pos )
{
@ -502,7 +545,7 @@ bool S_StartLocalSound( const char *name, float volume, float pitch, const float
return false;
sfxHandle = S_RegisterSound( name );
S_StartSound( origin, al_state.clientnum, CHAN_AUTO, sfxHandle, volume, ATTN_NONE, pitch, false );
S_StartSound( origin, al_state.clientnum, CHAN_AUTO, sfxHandle, volume, ATTN_NONE, pitch, SND_STOP_LOOPING );
return true;
}
@ -552,17 +595,23 @@ S_AddEnvironmentEffects
process all effects here
=================
*/
void S_AddEnvironmentEffects( const vec3_t position )
void S_AddEnvironmentEffects( void )
{
uint eaxEnv;
if( !al_config.allow_3DMode ) return;
// if eax is enabled, apply listener environmental effects
if( si.PointContents( position ) & (CONTENTS_LAVA|CONTENTS_SLIME|CONTENTS_WATER))
if( s_listener.waterlevel > 2 )
{
eaxEnv = EAX_ENVIRONMENT_UNDERWATER;
else eaxEnv = EAX_ENVIRONMENT_GENERIC;
al_config.Set3DMode(&DSPROPSETID_EAX20_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT|DSPROPERTY_EAXLISTENER_DEFERRED, 0, &eaxEnv, sizeof(eaxEnv));
}
else
{
eaxEnv = EAX_ENVIRONMENT_GENERIC;
eaxEnv = eax_preset[bound( 0, s_room_type->integer, CSXROOM - 1 )].dwEnvironment;
}
al_config.Set3DMode( &DSPROPSETID_EAX20_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT|DSPROPERTY_EAXLISTENER_DEFERRED, 0, &eaxEnv, sizeof(eaxEnv));
}
/*
@ -596,6 +645,7 @@ void S_Update( ref_params_t *fd )
s_listener.orientation[3] = fd->up[1];
s_listener.orientation[4] = -fd->up[2];
s_listener.orientation[5] = -fd->up[0];
s_listener.waterlevel = fd->waterlevel;
palListenerfv( AL_POSITION, s_listener.position );
palListenerfv( AL_VELOCITY, s_listener.velocity );
@ -608,7 +658,7 @@ void S_Update( ref_params_t *fd )
palDopplerFactor(s_dopplerFactor->value);
palDopplerVelocity(s_dopplerVelocity->value);
S_AddEnvironmentEffects( s_listener.position );
S_AddEnvironmentEffects ();
// Stream background track
S_StreamBackgroundTrack();
@ -759,6 +809,7 @@ bool S_Init( void *hInst )
s_rolloffFactor = Cvar_Get("s_rollofffactor", "1.0", CVAR_ARCHIVE, "3d sound rolloff factor" );
s_dopplerFactor = Cvar_Get("s_dopplerfactor", "1.0", CVAR_ARCHIVE, "cutoff doppler effect value" );
s_dopplerVelocity = Cvar_Get("s_dopplervelocity", "10976.0", CVAR_ARCHIVE, "doppler effect maxvelocity" );
s_room_type = Cvar_Get( "room_type", "0", 0, "dsp room type" );
s_pause = Cvar_Get( "paused", "0", 0, "sound engine pause" );
Cmd_AddCommand( "playsound", S_PlaySound_f, "playing a specified sound file" );

View File

@ -161,6 +161,25 @@ typedef enum
DSPROPERTY_EAXLISTENER_FLAGS
} DSPROPERTY_EAX_LISTENERPROPERTY;
typedef enum
{
DSPROPERTY_EAXBUFFER_NONE,
DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
DSPROPERTY_EAXBUFFER_DIRECT,
DSPROPERTY_EAXBUFFER_DIRECTHF,
DSPROPERTY_EAXBUFFER_ROOM,
DSPROPERTY_EAXBUFFER_ROOMHF,
DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
DSPROPERTY_EAXBUFFER_OBSTRUCTION,
DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
DSPROPERTY_EAXBUFFER_OCCLUSION,
DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
DSPROPERTY_EAXBUFFER_FLAGS
} DSPROPERTY_EAX_BUFFERPROPERTY;
// or these flags with property id
#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later

View File

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

View File

@ -116,6 +116,7 @@ typedef struct
vec3_t position;
vec3_t velocity;
float orientation[6];
int waterlevel;
} listener_t;
typedef struct
@ -170,7 +171,7 @@ void S_Activate( bool active );
void S_SoundList_f( void );
bool S_CheckForErrors( void );
void S_Update( ref_params_t *fd );
void S_StartSound(const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, bool use_loop);
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, int flags );
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );
void S_StartBackgroundTrack( const char *intro, const char *loop );

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;
wavout_init = false;
wav_init = false;
}
/*
@ -336,9 +336,9 @@ si_state_t SNDDMA_InitDirect( void *hInst )
switch( s_khz->integer )
{
case 44: dma.speed = SOUND_44k; break;
case 22: dma.speed = SOUND_22k; break;
default: dma.speed = SOUND_11k; break;
case 44: dma.speed = 44100; break;
case 22: dma.speed = 22050; break;
default: dma.speed = 11025; 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 = SOUND_44k; break;
case 22: dma.speed = SOUND_22k; break;
default: dma.speed = SOUND_11k; break;
case 44: dma.speed = 44100; break;
case 22: dma.speed = 22050; break;
default: dma.speed = 11025; 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;
wavout_init = true;
wav_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 = wavout_init = 0;
dsound_init = wav_init = 0;
// init DirectSound
if( !s_wavonly->integer )
@ -560,7 +560,7 @@ int SNDDMA_Init( void *hInst )
}
snd_buffer_count = 1;
if( !dsound_init && !wavout_init )
if( !dsound_init && !wav_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( wavout_init )
else if( wav_init )
{
s = snd_sent * WAV_BUFFER_SIZE;
}
@ -651,57 +651,6 @@ 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
@ -721,7 +670,7 @@ void SNDDMA_Submit( void )
// unlock the dsound buffer
if( pDSBuf ) pDSBuf->lpVtbl->Unlock( pDSBuf, dma.buffer, locksize, NULL, 0 );
if( !wavout_init ) return;
if( !wav_init ) return;
// find which sound blocks have completed
while( 1 )

File diff suppressed because it is too large Load Diff

View File

@ -118,6 +118,22 @@ void S_ResampleSfx( sfx_t *sfx, int inrate, int inwidth, byte *data )
}
}
// return true if char 'c' is one of 1st 2 characters in pch
bool S_TestSoundChar( const char *pch, char c )
{
int i;
char *pcht = (char *)pch;
// check first 2 characters
for( i = 0; i < 2; i++ )
{
if( *pcht == c )
return true;
pcht++;
}
return false;
}
/*
===============================================================================
@ -331,50 +347,6 @@ 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
@ -399,7 +371,6 @@ 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 );
}
/*
@ -445,7 +416,7 @@ loadformat_t load_formats[] =
{ NULL, NULL }
};
sfxcache_t *S_LoadSound( sfx_t *sfx, channel_t *ch )
sfxcache_t *S_LoadSound( sfx_t *sfx )
{
byte *data;
wavinfo_t info;
@ -454,10 +425,6 @@ sfxcache_t *S_LoadSound( sfx_t *sfx, channel_t *ch )
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
@ -587,7 +554,6 @@ 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 ));
}
}
@ -596,7 +562,7 @@ void S_EndRegistration( void )
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
{
if( !sfx->name[0] ) continue;
S_LoadSound( sfx, NULL );
S_LoadSound( sfx );
}
s_registering = false;
}
@ -618,7 +584,7 @@ sound_t S_RegisterSound( const char *name )
if( !sfx ) return -1;
sfx->registration_sequence = s_registration_sequence;
if( !s_registering ) S_LoadSound( sfx, NULL );
if( !s_registering ) S_LoadSound( sfx );
return sfx - s_knownSfx;
}
@ -651,7 +617,6 @@ 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,28 +10,17 @@
#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;
vec3_t listener_right;
vec3_t listener_up;
int listener_waterlevel;
int total_channels;
int s_framecount; // for autosounds checking
int s_clientnum; // cl.playernum + 1
int soundtime; // sample PAIRS
@ -61,19 +50,6 @@ 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
@ -88,7 +64,7 @@ channel_t *S_PickChannel( int entnum, int channel )
if( entnum < 0 || channel < 0 ) return NULL; // invalid channel or entnum
for( i = 0, ch = channels; i < MAX_CHANNELS; i++, ch++ )
for( i = 0, ch = channels; i < total_channels; i++, ch++ )
{
// check if this channel is active
if( channel == CHAN_AUTO && !ch->sfx )
@ -127,6 +103,58 @@ channel_t *S_PickChannel( int entnum, int channel )
return ch;
}
int S_AlterChannel( int entnum, int chan, sfx_t *sfx, int vol, int pitch, int flags )
{
int i;
channel_t *ch;
if( S_TestSoundChar( sfx->name, '!' ))
{
// This is a sentence name.
// For sentences: assume that the entity is only playing one sentence
// at a time, so we can just shut off
// any channel that has ch->isentence >= 0 and matches the
// soundsource.
for( i = 0, ch = channels; i < total_channels; i++ )
{
if( ch->entnum == entnum && ch->entchannel == chan && ch->sfx && ch->fsentence )
{
if( flags & SND_CHANGE_PITCH )
ch->basePitch = pitch;
if( flags & SND_CHANGE_VOL )
ch->master_vol = vol;
if( flags & SND_STOP )
Mem_Set( ch, 0, sizeof( channel_t ));
return true;
}
}
// channel not found
return false;
}
// regular sound or streaming sound
for( i = 0, ch = channels; i < total_channels; i++ )
{
if( ch->entnum == entnum && ch->entchannel == chan && ch->sfx )
{
Msg( "S_StartSound: vol %i, pitch %i\n", vol, pitch );
if( flags & SND_CHANGE_PITCH )
ch->basePitch = pitch;
if( flags & SND_CHANGE_VOL )
ch->master_vol = vol;
if( flags & SND_STOP )
Mem_Set( ch, 0, sizeof( channel_t ));
return true;
}
}
return false;
}
/*
=================
S_SpatializeOrigin
@ -288,7 +316,7 @@ void S_IssuePlaysound( playsound_t *ps )
S_SpatializeChannel( ch );
ch->pos = 0;
sc = S_LoadSound( ch->sfx, ch );
sc = S_LoadSound( ch->sfx );
ch->end = paintedtime + sc->length;
// free the playsound
@ -307,7 +335,7 @@ if pos is NULL, the sound will be dynamically sourced from the entity
Entchannel 0 will never override a playing sound
====================
*/
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, float pitch, bool loop )
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, float pitch, int flags )
{
sfxcache_t *sc;
int vol, start;
@ -322,11 +350,30 @@ 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, NULL );
sc = S_LoadSound( sfx );
if( !sc ) return; // couldn't load the sound's data
vol = fvol * 255;
if( flags & (SND_STOP|SND_CHANGE_VOL|SND_CHANGE_PITCH))
{
if( S_AlterChannel( ent, chan, sfx, vol, pitch, flags ))
{
Msg( "S_AlterChannel( %s, %i, %i )\n", sfx->name, ent, chan );
return;
}
if( flags & SND_STOP ) return;
// fall through - if we're not trying to stop the sound,
// and we didn't find it (it's not playing), go ahead and start it up
}
if( pitch == 0 )
{
MsgDev( D_WARN, "S_StartSound: ( %s ) ignored, called with pitch 0\n", sfx->name );
return;
}
// allocate the playsound_t
ps = S_AllocPlaysound();
if( !ps )
@ -346,7 +393,7 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
ps->entnum = ent;
ps->entchannel = chan;
ps->attenuation = attn;
ps->use_loop = loop;
ps->use_loop = (flags & SND_STOP_LOOPING) ? false : true;
ps->volume = vol;
ps->sfx = sfx;
@ -389,7 +436,7 @@ bool S_StartLocalSound( const char *name, float volume, float pitch, const floa
return false;
sfxHandle = S_RegisterSound( name );
S_StartSound( origin, s_clientnum, CHAN_AUTO, sfxHandle, volume, ATTN_NONE, pitch, false );
S_StartSound( origin, s_clientnum, CHAN_AUTO, sfxHandle, volume, ATTN_NONE, pitch, SND_STOP_LOOPING );
return true;
}
@ -442,6 +489,8 @@ void S_StopAllSounds( void )
s_playsounds[i].next->prev = &s_playsounds[i];
}
total_channels = MAX_CHANNELS; // no statics
// clear all the channels
Mem_Set( channels, 0, sizeof( channels ));
S_ClearBuffer ();
@ -606,12 +655,12 @@ 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 );
VectorCopy( fd->right, listener_right );
VectorCopy( fd->up, listener_up );
listener_waterlevel = fd->waterlevel;
// Add looping sounds
si.AddLoopingSounds();
@ -696,9 +745,6 @@ 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 );
@ -754,8 +800,7 @@ bool S_Init( void *hInst )
paintedtime = 0;
S_StopAllSounds ();
AllocDsps();
SX_Init ();
return true;
}
@ -776,7 +821,7 @@ void S_Shutdown( void )
SNDDMA_Shutdown();
S_FreeSounds();
Mem_FreePool( &sndpool );
SX_Free ();
FreeDsps();
Mem_FreePool( &sndpool );
}

View File

@ -21,79 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "sound.h"
// 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 );
}
#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;
void S_WriteLinearBlastStereo16( void )
{
@ -118,13 +50,10 @@ void S_WriteLinearBlastStereo16( void )
void S_TransferStereo16( dword *pbuf, int endtime )
{
int lpos, lpaintedtime;
snd_vol = S_GetMasterVolume() * 256;
snd_p = (int *)PAINTBUFFER;
snd_p = (int *)paintbuffer;
lpaintedtime = paintedtime;
if( !pbuf ) return;
while( lpaintedtime < endtime )
{
// handle recirculating buffer issues
@ -174,42 +103,50 @@ 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( !pbuf ) return;
if( dma.samplebits == 16 )
{
short *out = (short *)pbuf;
while( count-- )
{
val = (*p * snd_vol) >> 8;
p += step;
val = CLIP( val );
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
}
if( dma.samplebits == 16 && dma.channels == 2 )
{
// optimized case
S_TransferStereo16( pbuf, endtime );
}
else if( dma.samplebits == 8 )
{
byte *out = (byte *)pbuf;
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;
while( count-- )
if( dma.samplebits == 16 )
{
val = (*p * snd_vol) >> 8;
p += step;
val = CLIP( val );
short *out = (short *)pbuf;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
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;
}
}
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;
}
}
}
}
@ -221,411 +158,12 @@ 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;
samplepair_t *samp;
portable_samplepair_t *samp;
int i;
if( ch->leftvol > 255 ) ch->leftvol = 255;
@ -652,7 +190,7 @@ void S_PaintChannelFrom16( channel_t *ch, sfxcache_t *sc, int count, int offset
int left, right;
int leftvol, rightvol;
signed short *sfx;
samplepair_t *samp;
portable_samplepair_t *samp;
int i;
leftvol = ch->leftvol * snd_vol;
@ -672,37 +210,67 @@ void S_PaintChannelFrom16( channel_t *ch, sfxcache_t *sc, int count, int offset
ch->pos += count;
}
void S_PaintChannels( int endtime )
void S_MixAllChannels( int endtime, int end )
{
channel_t *ch;
sfxcache_t *sc;
int i, count = 0;
int ltime;
// paint in the channels.
for( i = 0, ch = channels; i < total_channels; i++, ch++ )
{
ltime = paintedtime;
while( ltime < end )
{
if( !ch->sfx || ( !ch->leftvol && !ch->rightvol ))
break;
// max painting is to the end of the buffer
count = end - ltime;
// might be stopped by running out of data
if( ch->end - ltime < count ) count = ch->end - ltime;
sc = S_LoadSound( ch->sfx );
if( !sc ) break;
if( count > 0 && ch->sfx )
{
if( sc->width == 1 )
S_PaintChannelFrom8( ch, sc, count, ltime - paintedtime );
else S_PaintChannelFrom16( ch, sc, count, ltime - paintedtime );
ltime += count;
}
// if at end of loop, restart
if( ltime >= ch->end )
{
if( ch->autosound && ch->use_loop )
{ // autolooping sounds always go back to start
ch->pos = 0;
ch->end = ltime + sc->length;
}
else if( sc->loopstart >= 0 && ch->use_loop )
{
ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos;
}
else ch->sfx = NULL; // channel just stopped
}
}
}
}
void S_PaintChannels( int endtime )
{
playsound_t *ps;
int i, end, ltime, count = 0;
float dsp_room_gain;
float dsp_facingaway_gain;
float dsp_player_gain;
float dsp_water_gain;
int i, end;
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
@ -729,7 +297,7 @@ void S_PaintChannels( int endtime )
// clear the paint buffer
if( s_rawend < paintedtime )
{
Mem_Set( paintbuffer, 0, (end - paintedtime) * sizeof( samplepair_t ));
Mem_Set( paintbuffer, 0, (end - paintedtime) * sizeof( portable_samplepair_t ));
}
else
{
@ -745,53 +313,9 @@ void S_PaintChannels( int endtime )
paintbuffer[i-paintedtime].left = paintbuffer[i-paintedtime].right = 0;
}
// paint in the channels.
for( i = 0, ch = channels; i < MAX_CHANNELS; i++, ch++ )
{
ltime = paintedtime;
while( ltime < end )
{
if( !ch->sfx || ( !ch->leftvol && !ch->rightvol ))
break;
S_MixAllChannels( endtime, end );
// max painting is to the end of the buffer
count = end - ltime;
// might be stopped by running out of data
if( ch->end - ltime < count ) count = ch->end - ltime;
sc = S_LoadSound( ch->sfx, ch );
if( !sc ) break;
if( count > 0 && ch->sfx )
{
if( sc->width == 1 )
S_PaintChannelFrom8( ch, sc, count, ltime - paintedtime );
else S_PaintChannelFrom16( ch, sc, count, ltime - paintedtime );
ltime += count;
}
// if at end of loop, restart
if( ltime >= ch->end )
{
if( ch->autosound && ch->use_loop )
{ // autolooping sounds always go back to start
ch->pos = 0;
ch->end = ltime + sc->length;
}
else if( sc->loopstart >= 0 && ch->use_loop )
{
ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos;
}
else ch->sfx = NULL; // channel just stopped
}
}
}
SX_RoomFX( endtime, count, endtime - paintedtime );
SX_RoomFX( endtime, false, true ); // UNDONE
// transfer out according to DMA format
S_TransferPaintBuffer( end );
@ -802,8 +326,12 @@ void S_PaintChannels( int endtime )
void S_InitScaletable( void )
{
int i, j;
int scale;
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);
}
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;
}

View File

@ -1,576 +0,0 @@
//=======================================================================
// 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"
samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
int s_rawend;
static bg_track_t s_bgTrack;
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
int s_rawend;
static bg_track_t s_bgTrack;
/*
=================

View File

@ -138,10 +138,6 @@ 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

@ -1,48 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: snd_dx - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
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_direct.c"
]
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"
"\Xash3D\src_main\temp\snd_dx\!debug\s_export.obj"
"\Xash3D\src_main\temp\snd_dx\!debug\s_load.obj"
"\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\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\RSP1D19.bat""
Compiling...
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.
<h3>Results</h3>
snd_dx.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -15,66 +15,13 @@ 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;
} 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 );
} portable_samplepair_t;
typedef struct
{
@ -83,45 +30,18 @@ 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
@ -150,56 +70,28 @@ typedef struct
byte *buffer;
} dma_t;
typedef enum
typedef struct
{
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 basePitch; // base pitch percent (100% is normal pitch playback)
float pitch; // real-time pitch after any modulation or shift by dynamic data
int looping; // where to loop, -1 = no looping OBSOLETE?
int entnum; // to allow overriding a specific sound
int loopnum; // entity num that playing autosound
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
bool fsentence; // bit who indicated sentence
bool use_delay; // delayed start
} channel_t;
typedef struct
@ -234,27 +126,6 @@ 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 );
@ -267,22 +138,19 @@ void SNDDMA_Submit( void );
#define MAX_CHANNELS 64
#define MAX_RAW_SAMPLES 8192
extern portable_samplepair_t paintbuffer[];
extern channel_t channels[MAX_CHANNELS];
extern int total_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;
extern vec3_t listener_up;
extern int listener_waterlevel;
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;
@ -294,54 +162,17 @@ extern cvar_t *s_mixahead;
extern cvar_t *s_testsound;
extern cvar_t *s_primary;
extern samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
extern samplepair_t paintbuffer[];
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
float S_GetMasterVolume( void );
void S_InitScaletable( void );
sfxcache_t *S_LoadSound( sfx_t *sfx, channel_t *ch );
sfxcache_t *S_LoadSound( sfx_t *sfx );
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_load.c
bool S_TestSoundChar( const char *pch, char c );
// 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 );
@ -353,7 +184,7 @@ void S_SoundList_f( void );
void S_SoundInfo_f( void );
// if origin is NULL, the sound will be dynamically sourced from the entity
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, bool use_loop);
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, int flags );
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );
void S_StartBackgroundTrack( const char *intro, const char *loop );

View File

@ -1,16 +0,0 @@
<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>

View File

@ -1,16 +0,0 @@
<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>

View File

@ -1,16 +0,0 @@
<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>